Kaynağa Gözat

添加学校详情

lex 1 yıl önce
ebeveyn
işleme
a4ac04898b

+ 9 - 2
src/views/studentList/api.ts

@@ -28,7 +28,6 @@ export const getStudentList = (params: any) => {
   });
 };
 
-
 /**
  * 修改学生信息
  */
@@ -38,7 +37,6 @@ export const resetStudentInfo = (params: any) => {
   });
 };
 
-
 /**
  * 获取学生课后训练
  */
@@ -50,3 +48,12 @@ export const getStudentAfterWork = (params: any) => {
   });
 };
 
+/**
+ * 获取学校详情
+ */
+export const schoolDetail = (params: any) => {
+  return request.get('/edu-app/open/school/detail', {
+    data: params,
+    params
+  });
+};

+ 46 - 12
src/views/studentList/index.tsx

@@ -16,14 +16,17 @@ import CSelect from '@/components/CSelect';
 import Pagination from '@/components/pagination';
 import add from './images/add.png';
 import { useRoute, useRouter } from 'vue-router';
-import { getStudentList } from './api';
+import { getStudentList, schoolDetail } from './api';
 import { classGroupList } from '@/views/classList/api';
 import AddStudentModel from './modals/addStudentModel';
-import Studentguide from '@/custom-plugins/guide-page/student-guide'
+import Studentguide from '@/custom-plugins/guide-page/student-guide';
 import TheEmpty from '/src/components/TheEmpty';
+import NoticeModal from './modals/noticeModal';
+import { useUserStore } from '/src/store/modules/users';
 export default defineComponent({
   name: 'student-studentList',
   setup(props, { emit }) {
+    const userStore = useUserStore();
     const state = reactive({
       searchForm: {
         keyword: '',
@@ -45,12 +48,13 @@ export default defineComponent({
       },
       tableList: [] as any,
       classList: [],
-      addStudentVisible: false
+      addStudentVisible: false,
+      activeRow: {} as any
     });
     const route = useRoute();
     const router = useRouter();
     const showGuide = ref(false);
-    const message = useMessage()
+    const message = useMessage();
     const search = () => {
       state.pagination.page = 1;
       getList();
@@ -168,7 +172,7 @@ export default defineComponent({
         {
           title: '操作',
           key: 'id',
-          width:300,
+          width: 300,
           render(row: any, index: number) {
             return (
               <>
@@ -289,15 +293,36 @@ export default defineComponent({
         </div>
         <NButton
           {...{ id: 'student-0' }}
-          onClick={() => {
-            state.addStudentVisible = true;
+          onClick={async () => {
+            // state.addStudentVisible = true;
+            try {
+              if (state.activeRow.id) {
+                state.addStudentVisible = true;
+              } else {
+                const { schoolInfos } = userStore.getUserInfo;
+                const schoolId =
+                  schoolInfos.length > 0 ? schoolInfos[0].id : null;
+                if (schoolId) {
+                  const { data } = await schoolDetail({ id: schoolId });
+                  state.activeRow = data;
+
+                  state.addStudentVisible = true;
+                }
+              }
+              //
+            } catch {
+              //
+            }
           }}
           class={styles.addBtn}
           type="primary"
           v-slots={{
             icon: () => (
               <>
-                <NImage class={styles.addBtnIcon} previewDisabled src={add}></NImage>
+                <NImage
+                  class={styles.addBtnIcon}
+                  previewDisabled
+                  src={add}></NImage>
               </>
             )
           }}>
@@ -305,8 +330,8 @@ export default defineComponent({
         </NButton>
         <div class={styles.tableWrap}>
           <NDataTable
-             v-slots={{
-              empty:()=><TheEmpty></TheEmpty>
+            v-slots={{
+              empty: () => <TheEmpty></TheEmpty>
             }}
             class={styles.classTable}
             loading={state.loading}
@@ -320,14 +345,23 @@ export default defineComponent({
             sync
           />
         </div>
-        {state.addStudentVisible ? (
+        {/* {state.addStudentVisible ? (
           <div v-model:show={state.addStudentVisible} class="n-modal-mask">
             <AddStudentModel
               onClose={() => {
                 state.addStudentVisible = false;
               }}></AddStudentModel>
           </div>
-        ) : null}
+        ) : null} */}
+        <NModal
+          v-model:show={state.addStudentVisible}
+          showIcon={false}
+          style={{ width: '400px' }}>
+          <NoticeModal
+            data={state.activeRow}
+            onClose={() => (state.addStudentVisible = false)}
+          />
+        </NModal>
         {showGuide.value ? <Studentguide></Studentguide> : null}
       </div>
     );

BIN
src/views/studentList/modals/images/1.png


BIN
src/views/studentList/modals/images/2.png


BIN
src/views/studentList/modals/images/3.png


BIN
src/views/studentList/modals/images/4.png


BIN
src/views/studentList/modals/images/5.png


BIN
src/views/studentList/modals/images/6.png


BIN
src/views/studentList/modals/images/icon-close.png


BIN
src/views/studentList/modals/images/icon-download.png


+ 180 - 0
src/views/studentList/modals/noticeModal.module.less

@@ -0,0 +1,180 @@
+.noticeBack {
+  border-radius: 0 !important;
+  box-shadow: none;
+  padding-top: 32Px;
+  padding-bottom: 32Px;
+}
+
+.noticeModal {
+  position: relative;
+  background: linear-gradient(136deg, #AEDFFC 0%, #AEDFFC 50%, #FCD5EE 100%);
+  border-radius: 0 !important;
+  box-shadow: none;
+  padding-bottom: 32Px;
+  overflow: hidden;
+
+  .bg {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+  }
+
+  .header {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+  }
+
+  .schoolLogo {
+    width: 30Px;
+    height: 30Px;
+    margin-right: 6Px;
+    padding: 2Px;
+    background-color: #fff;
+    border-radius: 50%;
+  }
+
+  .schoolName {
+    position: absolute;
+    top: 70Px;
+    width: 100%;
+    text-align: center;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .studentCore {
+    position: relative;
+    z-index: 2;
+    // top: 127Px;
+    background: #FFFFFF;
+    border-radius: 12Px;
+    width: 370Px;
+    padding: 0 15Px 180Px;
+    margin: 127Px 15Px 0;
+
+    .book {
+      padding: 30Px 0 15Px;
+      width: 100%;
+    }
+
+    .title {
+      font-weight: bold;
+    }
+
+    font-size: 12Px;
+    color: #333;
+    line-height: 20Px;
+
+    .content {
+      padding-top: 10Px;
+
+      .smallTitle {
+        color: #2481D3;
+        font-weight: bold;
+      }
+    }
+
+    .content1 {
+      text-indent: 2em;
+    }
+
+    .lastContent {
+      font-weight: bold;
+      padding-top: 10Px;
+    }
+
+    .schoolInfo {
+      padding-top: 30Px;
+      color: #333333;
+      text-align: right;
+    }
+  }
+
+  .bottom_d {
+    position: absolute;
+    bottom: 20Px;
+    left: 0;
+    z-index: 1;
+    width: 100%;
+  }
+
+  .bottom {
+    position: absolute;
+    bottom: 20Px;
+    left: 0;
+    z-index: 3;
+    width: 100%;
+  }
+
+
+  .qrCodeContainer {
+    position: absolute;
+    bottom: 46Px;
+    z-index: 4;
+    left: 0;
+    width: 100%;
+    text-align: center;
+
+    .codewrap {
+      width: 103Px;
+      height: 102Px;
+      background: url(./images/1.png) no-repeat;
+      position: relative;
+      background-size: 103Px 102Px;
+      margin: 0 auto;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+
+      img {
+        width: 84Px !important;
+        height: 84Px !important;
+      }
+    }
+
+    .codewrapSubmit {
+      margin-top: 11Px;
+      padding: 3Px 31Px 2Px;
+      background: linear-gradient(121deg, #FFD892 0%, #FFCB75 100%);
+      border-radius: 18Px;
+      font-size: 16Px;
+      font-weight: 500;
+      color: #5B2C03;
+      line-height: 22Px;
+      display: inline-block;
+    }
+  }
+
+
+}
+
+.downBtn {
+  margin: 10Px auto 0;
+  width: 150Px;
+  height: 42Px;
+  background: linear-gradient(291deg, #02baff 0%, #007afe 100%);
+  border-radius: 30Px;
+  line-height: 42Px;
+  font-size: 18Px;
+  font-weight: 600;
+  text-align: center;
+  color: #fff;
+  cursor: pointer;
+}
+
+.btnGroup {
+  position: fixed;
+  top: 40Px;
+  left: 50%;
+  width: 42Px;
+  transform: translate(220Px, 0);
+
+  img {
+    width: 100%;
+    cursor: pointer;
+  }
+}

+ 280 - 0
src/views/studentList/modals/noticeModal.tsx

@@ -0,0 +1,280 @@
+import { defineComponent, onMounted, reactive, ref } from 'vue';
+import styles from './noticeModal.module.less';
+// import p1 from './images/1.png'
+import p2 from './images/2.png';
+import p3 from './images/3.png';
+import p4 from './images/4.png';
+import p5 from './images/5.png';
+import p6 from './images/6.png';
+import iconClose from './images/icon-close.png';
+import iconDownload from './images/icon-download.png';
+import TheQrCode from '@/components/TheQrCode';
+import html2canvas from 'html2canvas';
+import { vaildUrl } from '@/utils/urlUtils';
+import dayjs from 'dayjs';
+
+export default defineComponent({
+  name: 'notice-modal',
+  props: {
+    data: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  emits: ['close'],
+  setup(props, { emit }) {
+    const data = reactive({
+      uploading: false
+    });
+
+    const extraConfig = ref({} as any);
+
+    const url = ref(
+      vaildUrl() + `/classroom-app/#/student-register?sId=${props.data.id}`
+    );
+    if (props.data.registerType != 'BUG_GOODS') {
+      url.value =
+        vaildUrl() + `/classroom-app/#/register-member?sId=${props.data.id}`;
+    }
+
+    const imgs = reactive({
+      saveLoading: false,
+      image: null as any,
+      shareLoading: false
+    });
+    const downImg = () => {
+      if (imgs.saveLoading) {
+        return;
+      }
+      imgs.saveLoading = true;
+      // 判断是否已经生成图片
+      if (imgs.image) {
+        saveImg();
+      } else {
+        const container: any = document.getElementById(`preview-container`);
+
+        html2canvas(container, {
+          allowTaint: true,
+          useCORS: true,
+          backgroundColor: null
+        })
+          .then(async canvas => {
+            const url = canvas.toDataURL('image/png');
+            imgs.image = url;
+            saveImg();
+          })
+          .catch(() => {
+            imgs.saveLoading = false;
+          });
+      }
+    };
+
+    const saveImg = async () => {
+      // showLoadingToast({ message: '图片生成中...', forbidClick: true });
+      setTimeout(() => {
+        imgs.saveLoading = false;
+      }, 100);
+      const link = document.createElement('a');
+      link.setAttribute('download', '报名图片' + '.png');
+      // 添加时间戳,防止浏览器缓存图片
+      // console.log(imgUrl,'imgUrl')
+
+      link.href = imgs.image;
+      link.click();
+      // const res = await promisefiyPostMessage({
+      //   api: 'savePicture',
+      //   content: {
+      //     base64: imgs.image
+      //   }
+      // });
+      // if (res?.content?.status === 'success') {
+      //   showSuccessToast('保存成功');
+      // } else {
+      //   showFailToast('保存失败');
+      // }
+    };
+
+    onMounted(() => {
+      const extraConfigS = props.data.extraConfig
+        ? JSON.parse(props.data.extraConfig)
+        : {};
+      const content = extraConfigS.content.replace(/\n/gi, '<br />');
+      extraConfig.value = {
+        ...extraConfigS,
+        content
+      };
+    });
+    return () => (
+      <div class={styles.noticeBack}>
+        <div class={styles.noticeModal} id="preview-container">
+          <img src={p5} class={styles.bg} />
+          <img src={p4} class={styles.header} />
+          <img src={p2} class={styles.bottom} />
+          <img src={p6} class={styles.bottom_d} />
+
+          <div class={styles.schoolName}>
+            <img
+              class={styles.schoolLogo}
+              crossorigin="anonymous"
+              src={props.data.logo + `?some=${new Date().getTime()}`}
+            />
+            <span>{props.data.name}</span>
+          </div>
+
+          <div class={styles.studentCore}>
+            <img src={p3} class={styles.book} />
+
+            <div class={styles.title}>尊敬的家长:</div>
+            <div class={styles.content1}>
+              为贯彻落实县“十四五”教育发展规划、教育部《基础教育课程教学改革深化行动方案》等文件精神,推进教育部“实施国家教育数字化战略行动”,促进信息技术与音乐课堂器乐教学练的深度融合,推动数字化在拓展音乐教学时空、共享优质资源、优化课程内容与教学过程、优化学生学习方式、精准开展教学评价等方面广泛应用,学校决定自本学期开展,开展“器乐课堂数字化建设”,现将有关安排通知如下:
+            </div>
+            <div class={styles.content}>
+              <p class={styles.smallTitle}>
+                一、音乐课已经学了唱歌,为什么还要学习器乐
+              </p>
+              <p class={styles.smallContnet}>
+                通过器乐来学习音乐,能全面培养学生的读谱、视唱、听音、节奏、和声、欣赏、创作等综合音乐素养。
+              </p>
+            </div>
+
+            <div class={styles.content}>
+              <p class={styles.smallTitle}>
+                二、器乐课堂的小乐器有哪些种类和优势
+              </p>
+              <p class={styles.smallContnet}>
+                通常有竖笛、排箫、葫芦丝、陶笛等,具有携带方便、轻巧、好存放、简单易学、应用灵活、价格低等优势。
+              </p>
+            </div>
+
+            <div class={styles.content}>
+              <p class={styles.smallTitle}>
+                三、我校器乐课堂数字化准备开设的乐器安排
+              </p>
+              <p
+                class={styles.smallContnet}
+                v-html={extraConfig.value.content}></p>
+            </div>
+
+            <div class={styles.content}>
+              <p class={styles.smallTitle}>
+                四、为什么要进行器乐课堂数字化建设
+              </p>
+              <p class={styles.smallContnet}>
+                在器乐的学练中,涉及乐理、指法、节奏、音准等多项音乐专业知识,借助数字化可以让学生人人随时学练,解决学生课后面临不会练、家长无法辅助、老师无法及时给予指导的专业性问题,让外行人都看得懂;
+              </p>
+            </div>
+
+            <div class={styles.content}>
+              <p class={styles.smallTitle}>五、建设器乐课堂数字化的优势</p>
+              <p class={styles.smallContnet}>
+                1.能帮助学生增强专注力与记忆力,提高阅读与理解能力,培养审美与情商,舒缓与释放情绪,有助于培养学生的身心健康;
+                <br />
+                2.让学生能够较好地适应接下来中考或高考的政策调整;
+              </p>
+            </div>
+
+            <div class={styles.content}>
+              <p class={styles.smallTitle}>六、如何实施器乐课堂数字化建设</p>
+              <p class={styles.smallContnet}>
+                1.器乐课堂数字化建设的标准为:家校互联互通、课上课后学练同频;
+                <br />
+                2.由硬件环境、技术环境、数字化音乐资源、师生数字化素养培养等构成,需长期持续性建设;
+                <br />
+                3.基于校情,学校借助北京知勉公益基金会提供的专业技术资源,依托学校现有音乐教室场地设备,进行数字化资源建设与升级,并安排音乐教师持续进行数字化素养培训;
+                <br />
+                4.实施后,音乐老师在课上使用数字化工具进行器乐授课,学生借助数字化工具进行学习,课后,学生在家使用乐器数字化工具进行练习。
+              </p>
+            </div>
+
+            <div class={styles.content}>
+              <p class={styles.smallTitle}>
+                七、实施的年级、参加原则、职责分工
+              </p>
+              <p class={styles.smallContnet}>
+                1.以音乐课堂为建设主体,面向全体学生实施器乐课堂数字化教学练;
+                <br />
+                2.学校负责协调解决家校互联互通的问题;
+                <br />
+                3.家长负责解决乐器、数字化学练等工具,遵循家长自愿参与的原则;
+              </p>
+            </div>
+
+            <div class={styles.content}>
+              <p class={styles.smallTitle}>
+                八、什么是数字化学练工具,准备途径,参考价格
+              </p>
+              <p class={styles.smallContnet}>
+                指具有数字化乐谱与课件、测评音视频云储存、五线谱与演奏指法跟播、电子节拍/校音、选段练习、原音/伴奏切换、速度调整等数字化学练工具(软件),通过手机或平板IPAD使用。
+                家长可自行在手机应用市场中准备,不限品牌、型号及价格,准备前应了解软件是否支持课堂乐器学练及以上功能。也可通过基金会提供的渠道准备,参考价格为290元/年。
+              </p>
+            </div>
+            <div class={styles.content}>
+              <p class={styles.smallTitle}>九、课堂乐器准备的途径、参考要求</p>
+              <p class={styles.smallContnet}>
+                家长可自行在网店、琴行准备,课堂乐器的要求为:
+                不限品牌、型号及价格,也可通过基金会提供的渠道准备,参考价格为
+                {extraConfig.value.price || 0}元/支。
+              </p>
+            </div>
+            <div class={styles.content}>
+              <p class={styles.smallTitle}>十、工作安排</p>
+              <p class={styles.smallContnet}>
+                1.我校定于
+                {dayjs(extraConfig.value.valueteachTime).format(
+                  'YYYY年MM月DD日'
+                )}
+                正式开展器乐课堂数字化教学; <br />
+                2.
+                {dayjs(extraConfig.value.buildStartTime).format(
+                  'YYYY年MM月DD日'
+                )}
+                —{dayjs(extraConfig.value.buildEndTime).format('MM月DD日')}
+                间进行家长互联互通部署(另行通知);
+                <br />
+                3.请家长在开课前为学生准备好课堂乐器和数字化学练工具,通过基金会渠道准备的家长可扫码进行工具准备;
+                <br />
+                4.如有疑问可向本班音乐教师咨询。
+              </p>
+            </div>
+
+            <div class={[styles.content1, styles.lastContent]}>
+              器乐课堂数字建设将遵循“立足本校实际,符合学生特点,注重课效课质”,为孩子成长搭建快乐的音乐家园,让我们的孩子以音乐为友,与器乐同行,在艺术特色的引领下茁壮成长,愿我们的孩子们都能奏出美妙的音乐!再次感谢家长朋友们对学校工作的大力支持!
+            </div>
+
+            <div class={styles.schoolInfo}>
+              <p>{props.data.name}</p>
+              <p>{dayjs().format('YYYY年MM月DD日')}</p>
+            </div>
+          </div>
+
+          <div class={styles.qrCodeContainer}>
+            <div class={styles.codewrap}>
+              <TheQrCode margin={0} text={url.value} size={84} />
+              {/* <img src={codewrap} class={styles.codewrapBg} alt="" /> */}
+            </div>
+            <div class={styles.codewrapSubmit}>请扫码报名</div>
+          </div>
+        </div>
+
+        <div class={styles.btnGroup}>
+          <img
+            src={iconClose}
+            class={styles.iconClose}
+            onClick={() => emit('close')}
+          />
+          <img
+            src={iconDownload}
+            class={styles.iconDownload}
+            onClick={downImg}
+          />
+          {/* <div class={styles.iconClose} onClick={downImg}>
+
+          </div>
+          <div class={styles.downBtn} onClick={downImg}>
+            下载图片
+          </div> */}
+        </div>
+      </div>
+    );
+  }
+});