Quellcode durchsuchen

feat: 添加音乐数字课堂学生注册页面

TIANYONG vor 1 Jahr
Ursprung
Commit
54c448cd95

+ 8 - 0
src/router/router-root.ts

@@ -17,6 +17,14 @@ export default [
     }
   },
   {
+    path: '/register-new',
+    name: 'register-new',
+    component: () => import('@/views/student-register/register-new'),
+    meta: {
+      title: '音乐数字课堂学生注册'
+    }
+  },
+  {
     path: '/goods-list',
     component: () => import('@/views/student-register/shop-mall/goods-list'),
     meta: {

BIN
src/views/student-register/images/agree-no.png


BIN
src/views/student-register/images/agree-yes.png


BIN
src/views/student-register/images/register-bg.png


BIN
src/views/student-register/images/vip-gift-icon.png


+ 166 - 0
src/views/student-register/register-new/index.module.less

@@ -0,0 +1,166 @@
+.registerModal {
+  background: linear-gradient( 180deg, #D0EFFD 0%, #DBF4FF 100%);
+  overflow-x: hidden;
+  overflow-y: scroll;
+  min-height: 100vh;
+}
+
+.headBg {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 195px;
+}
+
+.memberNumer {
+  margin: 12px 12px 0;
+  background: linear-gradient(90deg, #FF8633 0%, #FFB047 100%);
+  border-radius: 10px;
+  padding: 12px 0 12px 16px;
+  display: flex;
+  align-items: center;
+  font-size: 14px;
+  color: #fff;
+  font-weight: bold;
+
+  .iconGift {
+    width: 20px;
+    height: 20px;
+    margin-right: 6px;
+  }
+}
+
+.infoTitle {
+  width: 315px;
+  height: 31px;
+  display: block;
+  margin: 14px auto 10px;
+}
+
+.registerForm {
+  background: #FFFFFF;
+  border-radius: 16px;
+  margin: 82px 14px 0;
+  overflow: hidden;
+
+  .tips {
+    display: inline-block;
+    padding-left: 5px;
+    padding-top: 4px;
+    font-size: 12px;
+    font-weight: 400;
+    color: #666;
+    line-height: 17px;
+  }
+
+  :global {
+    .van-cell {
+      padding: 18px 14px;
+      &:after {
+        border-bottom: 1px solid #F2F2F2;
+      }
+    }
+
+    .van-field__label {
+      width: fit-content;
+      font-size: 16px;
+      color: #666666;
+      line-height: 22px;
+      margin-bottom: 0;
+    }
+
+    .van-field__control {
+      font-size: 16px;
+    }
+  }
+
+  .codeText {
+    color: #FFCF7C;
+    font-size: 14px;
+    font-weight: 600;
+
+    &.codeTextDisabled {
+      color: #ccc;
+    }
+  }
+}
+
+.submitBtn {
+  margin: 25px;
+  width: calc(100% - 50px);
+  height: 44px;
+  border-radius: 40px;
+  font-size: 18px;
+  font-weight: 600;
+  color: #fff !important;
+  line-height: 25px;
+}
+
+.radioSection {
+  position: relative;
+  min-width: 32px;
+  justify-content: center;
+  width: 52px;
+  height: 24px;
+  background: linear-gradient( 135deg, #31C7FF 0%, #007AFE 100%);
+  border-radius: 6px;
+  margin-left: 12px;
+}
+
+.radioItem {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  opacity: 0;
+}
+
+.radioSection+.radioSection {
+  margin-left: 12px;
+}
+
+.giftTips {
+  background: #E8F8FF;
+  border-radius: 8px;
+  display: flex;
+  align-items: center;
+  font-size: 13px;
+  font-weight: 500;
+  color: #2B85FF;
+  margin: 14px;
+  padding: 6px 4px 6px 10px;
+  > img {
+    width: 18px;
+    height: 18px;
+    margin-right: 6px;
+  }
+  i {
+    font-style: normal;
+    font-size: 15px;
+    color: #F62C2C;
+    display: inline-block;
+    margin: 0 3px;
+  }
+}
+
+.agreeColumn {
+  margin: 16px 14px;
+  display: flex;
+  align-items: center;
+  > img {
+    width: 14px;
+    height: 14px;
+    margin-right: 6px;
+  }
+  > p {
+    font-size: 13px;
+    color: #3C3C3C;
+    i {
+      font-style: normal;
+      color: #247FFA;
+      display: inline-block;
+    }
+  }
+}

+ 488 - 0
src/views/student-register/register-new/index.tsx

@@ -0,0 +1,488 @@
+import {
+  computed,
+  defineComponent,
+  nextTick,
+  onMounted,
+  reactive,
+  ref
+} from 'vue';
+import styles from './index.module.less';
+// import infoTitle from '../images/info-title.png';
+import {
+  Button,
+  CountDown,
+  Field,
+  Form,
+  Picker,
+  Popup,
+  Radio,
+  RadioGroup,
+  Tag,
+  showToast
+} from 'vant';
+import OWxTip from '@/components/m-wx-tip';
+import MProtocol from '@/components/m-protocol';
+import MImgCode from '@/components/m-img-code';
+import { browser, checkPhone } from '@/helpers/utils';
+import request from '@/helpers/request';
+import { useStudentRegisterStore } from '@/store/modules/student-register-store';
+import { setLoginInit, state } from '@/state';
+import iconGift from '../images/icon-gift.png';
+import { useRoute, useRouter } from 'vue-router';
+import MSticky from '@/components/m-sticky';
+import registerBgIcon from "../images/register-bg.png";
+import vipGiftIcon from "../images/vip-gift-icon.png";
+import agreeYes from '../images/agree-yes.png';
+import agreeNo from '../images/agree-no.png';
+
+const classList: any = [];
+for (let i = 1; i <= 40; i++) {
+  classList.push({ text: i + '班', value: i });
+}
+
+export default defineComponent({
+  name: 'register-new',
+  emits: ['close', 'submit'],
+  setup(props, { emit }) {
+    const route = useRoute();
+    const router = useRouter();
+    const studentRegisterStore = useStudentRegisterStore();
+    // 初始化学校编号
+    studentRegisterStore.setShoolId(route.query.sId as any);
+    const countDownRef = ref();
+    const gradeList = computed(() => {
+      let tempList: any = [];
+      const five = [
+        { text: '一年级', value: 1 },
+        { text: '二年级', value: 2 },
+        { text: '三年级', value: 3 },
+        { text: '四年级', value: 4 },
+        { text: '五年级', value: 5 }
+      ];
+      const one = [{ text: '六年级', value: 6 }];
+      const three = [
+        { text: '七年级', value: 7 },
+        { text: '八年级', value: 8 },
+        { text: '九年级', value: 9 }
+      ];
+      if (forms.gradeYear === 'FIVE_YEAR_SYSTEM') {
+        tempList.push([...five]);
+      } else if (forms.gradeYear === 'SIX_YEAR_SYSTEM') {
+        tempList.push([...five, ...one]);
+      } else if (forms.gradeYear === 'THREE_YEAR_SYSTEM') {
+        tempList.push([...three]);
+      } else if (forms.gradeYear === 'FORE_YEAR_SYSTEM') {
+        tempList.push([...one, ...three]);
+      } else {
+        tempList.push([...five, ...one, ...three]);
+      }
+      return tempList;
+    });
+    const forms = reactive({
+      countDownStatus: true,
+      countDownTime: 1000 * 120, // 倒计时时间
+      modelValue: false, // 是否选中协议
+      imgCodeStatus: false,
+      gradeNumText: '',
+      currentClassText: '',
+      gradeStatus: false,
+      classStatus: false,
+      loading: false,
+      schoolId: route.query.sId as any,
+      gradeYear: null,
+      schoolType: null,
+      giftVipDay: null,
+      showTips: false,
+      showButton: false,
+      showMessage: '请使用微信打开'
+    });
+    const isAgree = ref(false);
+    const studentInfo = reactive({
+      autoRegister: true,
+      client_id: 'cooleshow-student',
+      client_secret: 'cooleshow-student',
+      extra: {
+        nickname: '',
+        currentGradeNum: '',
+        currentClass: '',
+        gender: 1,
+        registerType: '', // 报名类型
+        giftVipDay: 0 // 赠送会员天数
+      },
+      grant_type: 'password',
+      loginType: 'SMS',
+      password: '',
+      username: ''
+    });
+
+    const onCodeSend = () => {
+      forms.countDownStatus = false;
+      nextTick(() => {
+        countDownRef.value.start();
+      });
+    };
+
+    const onSendCode = () => {
+      // 发送验证码
+      if (!checkPhone(studentInfo.username)) {
+        return showToast('请输入正确的手机号码');
+      }
+      forms.imgCodeStatus = true;
+    };
+
+    const validatePhone = computed(() => {
+      return checkPhone(studentInfo.username) ? true : false;
+    });
+
+    const onFinished = () => {
+      forms.countDownStatus = true;
+      countDownRef.value.reset();
+    };
+
+    const onSubmit = async () => {
+      try {
+        if (checkForm()) return;
+        forms.loading = true;
+        await request.get('/edu-app/open/student/schoolQuery', {
+          params: {
+            schoolId: forms.schoolId,
+            mobile: studentInfo.username
+          }
+        });
+        const { extra, ...res } = studentInfo;
+        const result = await request.post('/edu-app/userlogin', {
+          hideLoading: false,
+          requestType: 'form',
+          data: {
+            ...res,
+            extra: JSON.stringify({
+              ...extra,
+              schoolId: forms.schoolId
+            })
+          }
+        });
+        if (result.code === 5436) {
+          forms.showTips = true;
+          forms.showMessage = '二维码已经失效,详情请咨询学校老师';
+          forms.showButton = false;
+        } else if (result.code === 5435) {
+          forms.showTips = true;
+          forms.showMessage = '报名信息更新,请刷新后重新提交';
+          forms.showButton = true;
+        } else {
+          setTimeout(() => {
+            showToast('报名成功');
+            router.push('/download');
+          }, 100);
+        }
+      } catch {
+      } finally {
+        forms.loading = false;
+      }
+    };
+
+    const checkForm = () => {
+      if (!studentInfo.extra.nickname) {
+        showToast('请输入学生姓名');
+        return true;
+      } else if (!studentInfo.extra.currentGradeNum) {
+        showToast('请选择所在年级');
+        return true;
+      } else if (!studentInfo.extra.currentClass) {
+        showToast('请选择所在班级');
+        return true;
+      } else if (!checkPhone(studentInfo.username)) {
+        showToast('请输入正确的手机号码');
+        return true;
+      } else if (!studentInfo.password) {
+        showToast('请输入验证码');
+        return true;
+      } else if (isAgree.value) {
+        showToast('请先同意注册协议');
+        return true;
+      }
+      return false;
+    };
+
+    const getRegisterGoods = async () => {
+      try {
+        const { data } = await request.get('/edu-app/open/school/detail', {
+          params: {
+            id: forms.schoolId
+          },
+          noAuthorization: true // 是否请求接口的时候添加toekn
+        });
+
+        forms.giftVipDay = data.giftVipDay;
+        forms.schoolType = data.schoolType;
+        forms.gradeYear = data.gradeYear;
+        studentInfo.extra.giftVipDay = data.giftVipDay;
+        studentInfo.extra.registerType = data.registerType;
+
+        if (browser().weixin) {
+          if (data.registerType !== 'GIFT_VIP_DAY' || data.status === 0) {
+            forms.showTips = true;
+            forms.showMessage = '二维码已经失效,详情请咨询学校老师';
+            forms.showButton = false;
+          }
+        } else {
+          // forms.showTips = true;
+        }
+      } catch {}
+    };
+
+    onMounted(() => {
+      getRegisterGoods();
+    });
+    return () => (
+      <div class={styles.registerModal}>
+        {forms.giftVipDay ? (
+          <div class={styles.memberNumer}>
+            <img src={iconGift} class={styles.iconGift} />
+
+            <p>
+              现在报名立即赠送乐器AI学练工具有效期{' '}
+              <span>{forms.giftVipDay}</span> 天
+            </p>
+          </div>
+        ) : (
+          ''
+        )}
+        
+        <img class={styles.headBg} src={registerBgIcon} />
+        <Form labelAlign="top" class={styles.registerForm}>
+        <Field
+            clearable
+            label="联系方式"
+            placeholder="请输入手机号码"
+            type="tel"
+            autocomplete="off"
+            v-model={studentInfo.username}
+            required
+            input-align="right"
+            maxlength={11}>
+            {{
+              label: () => (
+                <div>
+                  联系方式
+                  {/* (直接监护人) */}
+                  <p class={styles.tips}>(直接监护人)</p>
+                </div>
+              )
+            }}
+          </Field>   
+          <Field
+            center
+            clearable
+            label="验证码"
+            placeholder="请输入验证码"
+            autocomplete="off"
+            type="number"
+            v-model={studentInfo.password}
+            required
+            input-align="right"
+            maxlength={6}>
+            {{
+              button: () =>
+                forms.countDownStatus ? (
+                  <span
+                    class={[
+                      styles.codeText,
+                      !validatePhone.value ? styles.codeTextDisabled : ''
+                    ]}
+                    onClick={onSendCode}>
+                    获取验证码
+                  </span>
+                ) : (
+                  <CountDown
+                    ref={(el: any) => (countDownRef.value = el)}
+                    auto-start={false}
+                    time={forms.countDownTime}
+                    onFinish={onFinished}
+                    format="ss秒"
+                  />
+                )
+            }}
+          </Field>                 
+          <Field
+            clearable
+            label="学生姓名"
+            placeholder="请输入学生姓名"
+            autocomplete="off"
+            maxlength={14}
+            v-model={studentInfo.extra.nickname}
+            required
+            input-align="right"
+          />
+          <Field
+            clearable
+            label="学生性别"
+            placeholder="请选择性别"
+            autocomplete="off"
+            required
+            input-align="right"
+            // v-model={studentInfo.extra.nickname}
+          >
+            {{
+              input: () => (
+                <RadioGroup
+                  checked-color="#ffcb75"
+                  v-model={studentInfo.extra.gender}
+                  direction="horizontal">
+                  <Tag
+                    size="large"
+                    type="primary"
+                    color={
+                      !(studentInfo.extra.gender === 1) ? '#F5F6FA' : 'linear-gradient( 135deg, #31C7FF 0%, #007AFE 100%)'
+                    }
+                    textColor={
+                      !(studentInfo.extra.gender === 1) ? '#626264' : '#fff'
+                    }
+                    class={styles.radioSection}
+                    round>
+                    <Radio class={styles.radioItem} name={1}></Radio>男
+                  </Tag>
+                  <Tag
+                    size="large"
+                    type="primary"
+                    color={
+                      !(studentInfo.extra.gender === 0) ? '#F5F6FA' : 'linear-gradient( 135deg, #31C7FF 0%, #007AFE 100%)'
+                    }
+                    textColor={
+                      !(studentInfo.extra.gender === 0) ? '#626264' : '#fff'
+                    }
+                    class={styles.radioSection}
+                    round>
+                    <Radio class={styles.radioItem} name={0}></Radio>女
+                  </Tag>
+                </RadioGroup>
+              )
+            }}
+          </Field>
+          <Field
+            clearable
+            label="所在年级"
+            placeholder="请选择年级"
+            isLink
+            readonly
+            clickable={false}
+            modelValue={forms.gradeNumText}
+            onClick={() => (forms.gradeStatus = true)}
+            required
+            input-align="right"
+          />
+          <Field
+            clearable
+            label="所在班级"
+            placeholder="请选择班级"
+            isLink
+            readonly
+            clickable={false}
+            modelValue={forms.currentClassText}
+            onClick={() => (forms.classStatus = true)}
+            required
+            input-align="right"
+          />
+          <div class={styles.giftTips}>
+            <img src={vipGiftIcon} />
+            <span>注册成功即可获得乐器AI学练工具<i>{forms.giftVipDay}</i>天有效期</span>
+          </div>
+        </Form>
+        {/* <div class={styles.agreeColumn}>
+          <img src={isAgree.value ? agreeYes : agreeNo} onClick={() => (isAgree.value = !isAgree.value)} />
+          <p onClick={(e: MouseEvent) => {
+                    e.stopPropagation();
+                    router.push('/preview-protocol');
+              }}>我已阅读并同意<i>《音乐数字课堂学生端》</i>注册协议</p>
+        </div> */}
+        {/* <MProtocol
+          center
+          v-model:modelValue={forms.modelValue}
+          prototcolType="REGISTER"
+        /> */}
+
+        <MSticky position="bottom">
+          <Button
+            type="primary"
+            class={styles.submitBtn}
+            color="linear-gradient( 135deg, #31C7FF 0%, #007AFE 100%)"
+            block
+            onClick={onSubmit}
+            disabled={forms.loading}
+            loading={forms.loading}>
+            确认
+          </Button>
+        </MSticky>
+
+        {forms.imgCodeStatus ? (
+          <MImgCode
+            v-model:value={forms.imgCodeStatus}
+            phone={studentInfo.username}
+            type="REGISTER"
+            onClose={() => {
+              forms.imgCodeStatus = false;
+            }}
+            onSendCode={onCodeSend}
+          />
+        ) : null}
+
+        {/* 年级 */}
+        <Popup
+          v-model:show={forms.gradeStatus}
+          position="bottom"
+          round
+          safeAreaInsetBottom
+          lazyRender={false}
+          class={'popupBottomSearch'}>
+          <Picker
+            showToolbar
+            columns={gradeList.value as any}
+            onCancel={() => (forms.gradeStatus = false)}
+            onConfirm={(val: any) => {
+              const selectedOption = val.selectedOptions[0];
+              studentInfo.extra.currentGradeNum = selectedOption.value;
+              forms.gradeNumText = selectedOption.text;
+              forms.gradeStatus = false;
+            }}
+          />
+        </Popup>
+        {/* 班级 */}
+        <Popup
+          v-model:show={forms.classStatus}
+          position="bottom"
+          round
+          class={'popupBottomSearch'}>
+          <Picker
+            showToolbar
+            columns={classList}
+            onCancel={() => (forms.classStatus = false)}
+            onConfirm={(val: any) => {
+              const selectedOption = val.selectedOptions[0];
+              studentInfo.extra.currentClass = selectedOption.value;
+              forms.currentClassText = selectedOption.text;
+              forms.classStatus = false;
+            }}
+          />
+        </Popup>
+        {/* 是否在微信中打开 */}
+        <OWxTip
+          v-model:show={forms.showTips}
+          message={forms.showMessage}
+          showButton={forms.showButton}
+          buttonText="刷新"
+          onConfirm={async () => {
+            forms.showTips = false;
+            await getRegisterGoods();
+
+            studentInfo.password = '';
+
+            window.scrollTo({
+              top: 0,
+              behavior: 'smooth'
+            });
+          }}
+        />
+      </div>
+    );
+  }
+});