index.tsx 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  1. import {
  2. computed,
  3. defineComponent,
  4. nextTick,
  5. onMounted,
  6. reactive,
  7. ref
  8. } from 'vue';
  9. import styles from './index.module.less';
  10. // import infoTitle from '../images/info-title.png';
  11. import {
  12. Button,
  13. CountDown,
  14. Field,
  15. Form,
  16. Picker,
  17. Popup,
  18. Radio,
  19. RadioGroup,
  20. Tag,
  21. showToast
  22. } from 'vant';
  23. import OWxTip from '@/components/m-wx-tip';
  24. // import MProtocol from '@/components/m-protocol';
  25. import MImgCode from '@/components/m-img-code';
  26. import { browser, checkPhone } from '@/helpers/utils';
  27. import request from '@/helpers/request';
  28. import { useStudentRegisterStore } from '@/store/modules/student-register-store';
  29. // import { setLoginInit, state } from '@/state';
  30. // import iconGift from '../images/icon-gift.png';
  31. import { useRoute, useRouter } from 'vue-router';
  32. import MSticky from '@/components/m-sticky';
  33. // import registerBgIcon from '../images/register-bg.png';
  34. import vipGiftIcon from '../images/vip-gift-icon.png';
  35. // import agreeYes from '../images/agree-yes.png';
  36. // import agreeNo from '../images/agree-no.png';
  37. import MMessageTip from '@/components/m-message-tip';
  38. import SelectStudent from '../modal/select-student';
  39. const classList: any = [];
  40. for (let i = 1; i <= 40; i++) {
  41. classList.push({ text: i + '班', value: i });
  42. }
  43. export default defineComponent({
  44. name: 'register-new',
  45. emits: ['close', 'submit'],
  46. setup() {
  47. const route = useRoute();
  48. const studentRegisterStore = useStudentRegisterStore();
  49. // 初始化学校编号
  50. studentRegisterStore.setShoolId(route.query.sId as any);
  51. const countDownRef = ref();
  52. const gradeList = computed(() => {
  53. let tempList: any = [];
  54. const five = [
  55. { text: '一年级', value: 1 },
  56. { text: '二年级', value: 2 },
  57. { text: '三年级', value: 3 },
  58. { text: '四年级', value: 4 },
  59. { text: '五年级', value: 5 }
  60. ];
  61. const one = [{ text: '六年级', value: 6 }];
  62. const three = [
  63. { text: '七年级', value: 7 },
  64. { text: '八年级', value: 8 },
  65. { text: '九年级', value: 9 }
  66. ];
  67. if (forms.gradeYear === 'FIVE_YEAR_SYSTEM') {
  68. tempList.push([...five]);
  69. } else if (forms.gradeYear === 'SIX_YEAR_SYSTEM') {
  70. tempList.push([...five, ...one]);
  71. } else if (forms.gradeYear === 'THREE_YEAR_SYSTEM') {
  72. tempList.push([...three]);
  73. } else if (forms.gradeYear === 'FORE_YEAR_SYSTEM') {
  74. tempList.push([...one, ...three]);
  75. } else {
  76. tempList.push([...five, ...one, ...three]);
  77. }
  78. return tempList;
  79. });
  80. const forms = reactive({
  81. countDownStatus: true,
  82. countDownTime: 1000 * 120, // 倒计时时间
  83. modelValue: false, // 是否选中协议
  84. imgCodeStatus: false,
  85. gradeNumText: '',
  86. currentClassText: '',
  87. multi_user_limit: 1, // 限制注册学生数量
  88. gradeStatus: false,
  89. classStatus: false,
  90. loading: false,
  91. schoolId: route.query.sId as any,
  92. showSelectStudent: false, // 选择学生
  93. studentList: [], // 手机号关联学生列表
  94. studentItem: {} as any, // 选择的学生
  95. isRegister: 'create' as 'create' | 'update' | '', // 是否注册学生
  96. isTipRegister: true, // 是否显示名字不一致 - 默认显示
  97. isChangeSchool: false, // 是否切换学校
  98. details: {} as any,
  99. gradeYear: null,
  100. schoolType: null,
  101. giftVipDay: null as any,
  102. showTips: false,
  103. showButton: false,
  104. showMessage: '请使用微信打开',
  105. gradePopupShow: false,
  106. gradePopupIndex: [] as any, // 年级下拉索引
  107. classPopupShow: false,
  108. classPopupIndex: [] as any // 班级下拉索引
  109. });
  110. const otherParams = reactive({
  111. showOtherSchool: false,
  112. showCloseButton: true, // 是否显示关闭按钮
  113. showOtherMessage: '',
  114. /** limit 超限制,change 更换学生,nickname 名称不一致 */
  115. otherType: '' as 'limit' | 'change' | 'nickname',
  116. showCancelButton: true,
  117. cancelButtonColor: '',
  118. cancelButtonText: '取消',
  119. showConfirmButton: true,
  120. confirmButtonColor: '',
  121. confirmButtonText: '确定',
  122. messageAlign: 'left' as 'center' | 'left' | 'right'
  123. });
  124. const isAgree = ref(false);
  125. const studentInfo = reactive({
  126. autoRegister: true,
  127. multiUser: true, // 是否为多用户
  128. client_id: 'cooleshow-student',
  129. client_secret: 'cooleshow-student',
  130. extra: {
  131. nickname: '',
  132. currentGradeNum: '',
  133. currentClass: '',
  134. gender: 1,
  135. registerType: '', // 报名类型
  136. giftVipDay: 0 // 赠送会员天数
  137. },
  138. grant_type: 'password',
  139. loginType: 'SMS',
  140. password: '',
  141. username: ''
  142. });
  143. const onCodeSend = () => {
  144. forms.countDownStatus = false;
  145. nextTick(() => {
  146. countDownRef.value.start();
  147. });
  148. };
  149. // 格式化提示状态
  150. const changeTipStatus = (register: boolean, school: boolean) => {
  151. forms.isTipRegister = register;
  152. forms.isChangeSchool = school;
  153. };
  154. const onSendCode = () => {
  155. // 发送验证码
  156. if (!checkPhone(studentInfo.username)) {
  157. return showToast('请输入正确的手机号码');
  158. }
  159. forms.imgCodeStatus = true;
  160. };
  161. // const getUserInfos = async () => {
  162. // if (
  163. // studentInfo.password.length !== 6 ||
  164. // !checkPhone(studentInfo.username)
  165. // ) {
  166. // return;
  167. // }
  168. // try {
  169. // const { data } = await request.get(
  170. // `/edu-app/open/student/studentInfo?mobile=${studentInfo.username}&code=${studentInfo.password}&type=REGISTER`
  171. // );
  172. // if (data) {
  173. // if (!studentInfo.extra.nickname) {
  174. // studentInfo.extra.nickname = data.nickname;
  175. // }
  176. // if (!studentInfo.extra.currentGradeNum) {
  177. // studentInfo.extra.currentGradeNum = data.currentGradeNum;
  178. // }
  179. // if (!studentInfo.extra.currentClass) {
  180. // studentInfo.extra.currentClass = data.currentClass;
  181. // }
  182. // // if (!studentInfo.extra.gender) {
  183. // studentInfo.extra.gender =
  184. // studentInfo.extra.gender !== data.gender
  185. // ? data.gender
  186. // : studentInfo.extra.gender;
  187. // // studentInfo.username = data.nickname;
  188. // classList.forEach((i: any) => {
  189. // if (i.value === data.currentClass) {
  190. // forms.currentClassText = i.text;
  191. // }
  192. // });
  193. // const tempGrade: any = gradeList.value[0] || [];
  194. // tempGrade?.forEach((i: any) => {
  195. // if (i.value === data.currentGradeNum) {
  196. // forms.gradeNumText = i.text;
  197. // }
  198. // });
  199. // }
  200. // } catch {
  201. // //
  202. // }
  203. // };
  204. const getUserInfos = async () => {
  205. if (
  206. studentInfo.password.length !== 6 ||
  207. !checkPhone(studentInfo.username)
  208. ) {
  209. return;
  210. }
  211. try {
  212. const { data } = await request.get(
  213. `/edu-app/open/student/studentInfo?mobile=${studentInfo.username}&code=${studentInfo.password}&type=REGISTER`
  214. );
  215. forms.studentList = data || [];
  216. if (forms.studentList.length > 0) {
  217. const firstStudent: any = forms.studentList[0];
  218. forms.studentItem = firstStudent;
  219. studentInfo.extra.nickname = firstStudent.nickname;
  220. const tempGrade: any = gradeList.value[0] || [];
  221. tempGrade?.forEach((i: any) => {
  222. if (i.value === firstStudent.currentGradeNum) {
  223. // forms.instrumentCode = i.instrumentCode;
  224. forms.gradeNumText = i.text;
  225. studentInfo.extra.currentGradeNum = firstStudent.currentGradeNum;
  226. // if (forms.schoolInstrumentSetType === 'CLASS') {
  227. // forms.classList = i.classList;
  228. // }
  229. }
  230. });
  231. classList.forEach((i: any) => {
  232. if (i.value === firstStudent.currentClass) {
  233. forms.currentClassText = i.text;
  234. studentInfo.extra.currentClass = firstStudent.currentClass;
  235. }
  236. });
  237. studentInfo.extra.gender = firstStudent.gender;
  238. forms.isRegister = 'update';
  239. changeTipStatus(true, false);
  240. } else {
  241. forms.isRegister = 'create';
  242. changeTipStatus(false, false);
  243. forms.studentItem = [];
  244. }
  245. } catch {
  246. //
  247. }
  248. };
  249. const validatePhone = computed(() => {
  250. return checkPhone(studentInfo.username) ? true : false;
  251. });
  252. const onFinished = () => {
  253. forms.countDownStatus = true;
  254. countDownRef.value.reset();
  255. };
  256. //
  257. const checkSubmit = () => {
  258. const { extra } = studentInfo;
  259. if (
  260. forms.studentItem.nickname !== extra.nickname &&
  261. forms.isTipRegister
  262. ) {
  263. otherParams.showOtherMessage =
  264. '学生姓名与上次提交信息不一致,请确认修改学生信息或创建新的学生账号';
  265. otherParams.showOtherSchool = true;
  266. otherParams.showCancelButton = true;
  267. otherParams.showCloseButton = true;
  268. otherParams.cancelButtonColor =
  269. 'linear-gradient( 224deg, #3FE1E6 0%, #00CDD4 100%)';
  270. otherParams.cancelButtonText = '新建学生';
  271. otherParams.confirmButtonColor =
  272. 'linear-gradient( 305deg, #40C8FF 0%, #3192FF 100%)';
  273. otherParams.confirmButtonText = '修改信息';
  274. otherParams.otherType = 'nickname';
  275. otherParams.messageAlign = 'left';
  276. return true;
  277. }
  278. // 判断新建学员是否上限了
  279. if (
  280. forms.isRegister === 'create' &&
  281. forms.studentList.length >= forms.multi_user_limit
  282. ) {
  283. otherParams.showOtherMessage = `同一手机号最多创建${forms.multi_user_limit}个学生`;
  284. otherParams.showOtherSchool = true;
  285. otherParams.showCancelButton = false;
  286. otherParams.showCloseButton = true;
  287. otherParams.confirmButtonColor =
  288. 'linear-gradient( 305deg, #40C8FF 0%, #3192FF 100%)';
  289. otherParams.confirmButtonText = '我知道了';
  290. otherParams.otherType = 'limit';
  291. otherParams.messageAlign = 'center';
  292. return true;
  293. }
  294. // 判断是否为同一个学校
  295. if (
  296. forms.studentItem.schoolId &&
  297. forms.studentItem.schoolId !== forms.details.id &&
  298. !forms.isChangeSchool &&
  299. forms.isRegister === 'update'
  300. ) {
  301. otherParams.showOtherMessage = `您已绑定【${
  302. forms.studentItem?.schoolName || ''
  303. }】,提交后将更换到【
  304. <span style="color: #2B85FF">${forms.details.name || ''}</span>
  305. 】,是否确认提交?`;
  306. otherParams.showOtherSchool = true;
  307. otherParams.showCancelButton = true;
  308. otherParams.showCloseButton = false;
  309. otherParams.cancelButtonColor = '';
  310. otherParams.cancelButtonText = '取消';
  311. otherParams.confirmButtonColor = '';
  312. otherParams.confirmButtonText = '确定';
  313. otherParams.otherType = 'change';
  314. otherParams.messageAlign = 'left';
  315. return true;
  316. }
  317. return false;
  318. };
  319. const onSubmit = async () => {
  320. try {
  321. if (checkForm() || checkSubmit()) return;
  322. forms.loading = true;
  323. // await request.get('/edu-app/open/student/schoolQuery', {
  324. // params: {
  325. // schoolId: forms.schoolId,
  326. // mobile: studentInfo.username
  327. // }
  328. // });
  329. // const { extra, ...res } = studentInfo;
  330. const { extra, loginType, autoRegister, password, multiUser, ...res } =
  331. studentInfo;
  332. let tLoginType = loginType,
  333. tAutoRegister = autoRegister,
  334. tPassword = password,
  335. tMultiUser = multiUser;
  336. if (forms.isRegister === 'update') {
  337. tLoginType = 'TOKEN';
  338. tAutoRegister = false;
  339. tPassword = forms.studentItem.token;
  340. tMultiUser = false;
  341. }
  342. const result = await request.post('/edu-app/userlogin', {
  343. hideLoading: false,
  344. requestType: 'form',
  345. data: {
  346. loginType: tLoginType,
  347. autoRegister: tAutoRegister,
  348. password: tPassword,
  349. multiUser: tMultiUser,
  350. ...res,
  351. extra: JSON.stringify({
  352. ...extra,
  353. schoolId: forms.schoolId
  354. })
  355. }
  356. });
  357. if (result.code === 5435 || result.code === 5436) {
  358. forms.showTips = true;
  359. forms.showMessage = '报名信息更新,请刷新后重新提交';
  360. forms.showButton = true;
  361. } else {
  362. const { extra, username } = studentInfo;
  363. const registerResult = await request.post(
  364. '/edu-app/student/register',
  365. {
  366. data: {
  367. schoolId: forms.schoolId,
  368. clientType: 'STUDENT',
  369. ...extra,
  370. mobile: username,
  371. newRegUser: forms.isRegister === 'create' ? true : false
  372. }
  373. }
  374. );
  375. if (registerResult !== 200) {
  376. if (result.code === 5435 || result.code === 5436) {
  377. forms.showTips = true;
  378. forms.showMessage = '报名信息更新,请刷新后重新提交';
  379. forms.showButton = true;
  380. }
  381. return;
  382. }
  383. setTimeout(() => {
  384. showToast('报名成功');
  385. }, 100);
  386. setTimeout(() => {
  387. if (browser().weixin) {
  388. // 关闭微信
  389. (window as any).WeixinJSBridge.call('closeWindow');
  390. }
  391. }, 1000);
  392. }
  393. } catch {
  394. // 重置信息 - 如果是新建则不提示
  395. changeTipStatus(forms.isRegister === 'create' ? false : true, false);
  396. } finally {
  397. forms.loading = false;
  398. }
  399. };
  400. const checkForm = () => {
  401. if (!checkPhone(studentInfo.username)) {
  402. showToast('请输入正确的手机号码');
  403. return true;
  404. } else if (!studentInfo.password) {
  405. showToast('请输入验证码');
  406. return true;
  407. } else if (!studentInfo.extra.nickname) {
  408. showToast('请输入学生姓名');
  409. return true;
  410. } else if (!studentInfo.extra.currentGradeNum) {
  411. showToast('请选择所在年级');
  412. return true;
  413. } else if (!studentInfo.extra.currentClass) {
  414. showToast('请选择所在班级');
  415. return true;
  416. }
  417. return false;
  418. };
  419. const getRegisterGoods = async () => {
  420. try {
  421. const { data } = await request.get('/edu-app/open/school/detail', {
  422. params: {
  423. id: forms.schoolId
  424. },
  425. noAuthorization: true // 是否请求接口的时候添加toekn
  426. });
  427. forms.giftVipDay = data.giftVipDay;
  428. forms.schoolType = data.schoolType;
  429. forms.gradeYear = data.gradeYear;
  430. forms.details = data;
  431. studentInfo.extra.giftVipDay = data.giftVipDay;
  432. studentInfo.extra.registerType = data.registerType;
  433. if (browser().weixin) {
  434. if (data.status === 0) {
  435. forms.showTips = true;
  436. forms.showMessage = '二维码已经失效,详情请咨询学校老师';
  437. forms.showButton = false;
  438. }
  439. } else {
  440. forms.showTips = true;
  441. }
  442. } catch {}
  443. };
  444. onMounted(async () => {
  445. try {
  446. // 获取支付类型
  447. const { data } = await request.get(
  448. '/edu-app/open/paramConfig/queryByParamNameList',
  449. {
  450. requestType: 'form',
  451. params: {
  452. paramNames: 'multi_user_limit'
  453. }
  454. }
  455. );
  456. if (data && Array.isArray(data)) {
  457. data.forEach((item: any) => {
  458. if (item.paramName === 'multi_user_limit') {
  459. forms.multi_user_limit = item.paramValue
  460. ? Number(item.paramValue)
  461. : 1;
  462. }
  463. });
  464. }
  465. await getRegisterGoods();
  466. } catch {}
  467. });
  468. /** 手机号变更时清空验证码信息,用户信息 */
  469. const phoneChangeEmptyInfo = () => {
  470. studentInfo.password = '';
  471. studentInfo.extra.nickname = '';
  472. studentInfo.extra.currentGradeNum = '';
  473. studentInfo.extra.currentClass = '';
  474. studentInfo.extra.gender = 1;
  475. forms.currentClassText = '';
  476. forms.gradeNumText = '';
  477. forms.studentList = []; // 手机号关联学生列表
  478. forms.studentItem = {}; // 选择的学生
  479. forms.isRegister = 'create'; // 是否注册学生
  480. forms.isTipRegister = true; // 是否显示名字不一致 - 默认显示
  481. forms.isChangeSchool = false; // 是否切换学校
  482. };
  483. return () => (
  484. <div class={styles.registerModal}>
  485. {/* {forms.giftVipDay ? (
  486. <div class={styles.memberNumer}>
  487. <img src={iconGift} class={styles.iconGift} />
  488. <p>
  489. 现在报名立即赠送乐器AI学练工具有效期{' '}
  490. <span>{forms.giftVipDay}</span> 天
  491. </p>
  492. </div>
  493. ) : (
  494. ''
  495. )} */}
  496. <div class={styles.studentRegisterContainer}>
  497. <div
  498. class={[
  499. styles.studentSection,
  500. styles.studentSectionForm,
  501. styles.noSendDay
  502. ]}>
  503. <div class={styles.title3}></div>
  504. <Form labelAlign="left" class={styles.registerForm}>
  505. <Field
  506. clearable={false}
  507. label="联系方式(直接监护人)"
  508. placeholder="请输入手机号码"
  509. type="tel"
  510. required
  511. autocomplete="off"
  512. inputAlign="right"
  513. class={styles.username}
  514. v-model={studentInfo.username}
  515. border={false}
  516. maxlength={11}
  517. onUpdate:modelValue={() => {
  518. phoneChangeEmptyInfo();
  519. }}>
  520. {{
  521. label: () => (
  522. <div>
  523. 联系方式
  524. <p class={styles.tips}>(直接监护人)</p>
  525. </div>
  526. )
  527. }}
  528. </Field>
  529. <div class={['van-hairline--bottom', styles.fieldTipsGroup]}>
  530. <div class={[styles.fieldTips]}>
  531. 手机号是音乐数字课堂的唯一登录账户
  532. </div>
  533. </div>
  534. <Field
  535. center
  536. clearable={false}
  537. required
  538. inputAlign="right"
  539. label="验证码"
  540. placeholder="请输入验证码"
  541. autocomplete="off"
  542. type="number"
  543. v-model={studentInfo.password}
  544. maxlength={6}
  545. onUpdate:modelValue={(val: any) => {
  546. getUserInfos();
  547. }}>
  548. {{
  549. button: () =>
  550. forms.countDownStatus ? (
  551. <span
  552. class={[
  553. styles.codeText,
  554. !validatePhone.value ? styles.codeTextDisabled : ''
  555. ]}
  556. onClick={onSendCode}>
  557. 获取验证码
  558. </span>
  559. ) : (
  560. <CountDown
  561. ref={(el: any) => (countDownRef.value = el)}
  562. auto-start={false}
  563. class={styles.countDown}
  564. time={forms.countDownTime}
  565. onFinish={onFinished}
  566. format="ss秒后重试"
  567. />
  568. )
  569. }}
  570. </Field>
  571. </Form>
  572. </div>
  573. <div
  574. class={[
  575. styles.studentSection,
  576. styles.studentSectionForm,
  577. Number(forms.giftVipDay) > 0 && styles.noSendDay
  578. ]}>
  579. <div class={styles.title1}></div>
  580. <Form labelAlign="left" class={styles.registerForm}>
  581. {/* 大于等于2,则可以切换学生 */}
  582. {forms.studentList.length > 1 && (
  583. <div
  584. class={[
  585. styles.selectStudentGroup,
  586. forms.showSelectStudent && styles.selectStudentGroupChecked
  587. ]}
  588. onClick={() => (forms.showSelectStudent = true)}>
  589. <i
  590. class={[
  591. styles.studentIcon,
  592. !forms.studentItem.userId && styles.studentIconAdd
  593. ]}></i>
  594. <span>
  595. {forms.studentItem.userId
  596. ? forms.studentItem.nickname
  597. : '新增学生'}
  598. </span>
  599. </div>
  600. )}
  601. <Field
  602. clearable={false}
  603. label="学生姓名"
  604. placeholder="请输入学生姓名"
  605. autocomplete="off"
  606. maxlength={14}
  607. v-model={studentInfo.extra.nickname}
  608. required
  609. input-align="right"
  610. />
  611. <Field
  612. clearable={false}
  613. label="学生性别"
  614. placeholder="请选择性别"
  615. autocomplete="off"
  616. required
  617. input-align="right"
  618. // v-model={studentInfo.extra.nickname}
  619. >
  620. {{
  621. input: () => (
  622. <RadioGroup
  623. checked-color="#ffcb75"
  624. v-model={studentInfo.extra.gender}
  625. direction="horizontal">
  626. <Tag
  627. size="large"
  628. type="primary"
  629. color={
  630. !(studentInfo.extra.gender === 1)
  631. ? '#F5F6FA'
  632. : 'linear-gradient( 135deg, #31C7FF 0%, #007AFE 100%)'
  633. }
  634. textColor={
  635. !(studentInfo.extra.gender === 1) ? '#626264' : '#fff'
  636. }
  637. class={styles.radioSection}
  638. round>
  639. <Radio class={styles.radioItem} name={1}></Radio>男
  640. </Tag>
  641. <Tag
  642. size="large"
  643. type="primary"
  644. color={
  645. !(studentInfo.extra.gender === 0)
  646. ? '#F5F6FA'
  647. : 'linear-gradient( 135deg, #31C7FF 0%, #007AFE 100%)'
  648. }
  649. textColor={
  650. !(studentInfo.extra.gender === 0) ? '#626264' : '#fff'
  651. }
  652. class={styles.radioSection}
  653. round>
  654. <Radio class={styles.radioItem} name={0}></Radio>女
  655. </Tag>
  656. </RadioGroup>
  657. )
  658. }}
  659. </Field>
  660. <Field
  661. clearable={false}
  662. label="所在年级"
  663. placeholder="请选择年级"
  664. isLink
  665. readonly
  666. clickable={false}
  667. modelValue={forms.gradeNumText}
  668. onClick={() => {
  669. forms.gradePopupIndex = [studentInfo.extra.currentGradeNum];
  670. forms.gradeStatus = true;
  671. }}
  672. required
  673. input-align="right"
  674. />
  675. <Field
  676. clearable={false}
  677. label="所在班级"
  678. placeholder="请选择班级"
  679. isLink
  680. readonly
  681. clickable={false}
  682. modelValue={forms.currentClassText}
  683. onClick={() => {
  684. forms.classPopupIndex = [studentInfo.extra.currentClass];
  685. forms.classStatus = true;
  686. }}
  687. required
  688. input-align="right"
  689. />
  690. {studentInfo.extra.registerType === 'GIFT_VIP_DAY' &&
  691. forms.giftVipDay &&
  692. Number(forms.giftVipDay) > 0 ? (
  693. <div class={styles.giftTips}>
  694. <img src={vipGiftIcon} />
  695. <span>
  696. 注册成功即可获得乐器AI学练工具<i>{forms.giftVipDay}</i>
  697. 天有效期
  698. </span>
  699. </div>
  700. ) : null}
  701. </Form>
  702. </div>
  703. </div>
  704. {/* <div class={styles.agreeColumn}>
  705. <img src={isAgree.value ? agreeYes : agreeNo} onClick={() => (isAgree.value = !isAgree.value)} />
  706. <p onClick={(e: MouseEvent) => {
  707. e.stopPropagation();
  708. router.push('/preview-protocol');
  709. }}>我已阅读并同意<i>《音乐数字课堂学生端》</i>注册协议</p>
  710. </div> */}
  711. {/* <MProtocol
  712. center
  713. v-model:modelValue={forms.modelValue}
  714. prototcolType="REGISTER"
  715. /> */}
  716. <MSticky position="bottom">
  717. <div class={styles.paymentContainer}>
  718. <div class={styles.traditionBtn}>
  719. <Button
  720. type="primary"
  721. class={styles.submitBtn}
  722. color="linear-gradient( 135deg, #31C7FF 0%, #007AFE 100%)"
  723. round
  724. onClick={() => onSubmit()}
  725. disabled={forms.loading}
  726. loading={forms.loading}>
  727. 提交注册
  728. </Button>
  729. </div>
  730. </div>
  731. </MSticky>
  732. {forms.imgCodeStatus ? (
  733. <MImgCode
  734. v-model:value={forms.imgCodeStatus}
  735. phone={studentInfo.username}
  736. type="REGISTER"
  737. onClose={() => {
  738. forms.imgCodeStatus = false;
  739. }}
  740. onSendCode={onCodeSend}
  741. />
  742. ) : null}
  743. {/* 年级 */}
  744. <Popup
  745. v-model:show={forms.gradeStatus}
  746. position="bottom"
  747. round
  748. safeAreaInsetBottom
  749. lazyRender={false}
  750. class={'popupBottomSearch'}
  751. onOpen={() => {
  752. forms.gradePopupShow = true;
  753. }}
  754. onClosed={() => {
  755. forms.gradePopupShow = false;
  756. }}>
  757. {forms.gradePopupShow && (
  758. <Picker
  759. showToolbar
  760. v-model={forms.gradePopupIndex}
  761. columns={gradeList.value as any}
  762. onCancel={() => (forms.gradeStatus = false)}
  763. onConfirm={(val: any) => {
  764. const selectedOption = val.selectedOptions[0];
  765. studentInfo.extra.currentGradeNum = selectedOption.value;
  766. forms.gradeNumText = selectedOption.text;
  767. forms.gradeStatus = false;
  768. }}
  769. />
  770. )}
  771. </Popup>
  772. {/* 班级 */}
  773. <Popup
  774. v-model:show={forms.classStatus}
  775. position="bottom"
  776. round
  777. class={'popupBottomSearch'}
  778. onOpen={() => {
  779. forms.classPopupShow = true;
  780. }}
  781. onClosed={() => {
  782. forms.classPopupShow = false;
  783. }}>
  784. {forms.classPopupShow && (
  785. <Picker
  786. showToolbar
  787. v-model={forms.classPopupIndex}
  788. columns={classList}
  789. onCancel={() => (forms.classStatus = false)}
  790. onConfirm={(val: any) => {
  791. const selectedOption = val.selectedOptions[0];
  792. studentInfo.extra.currentClass = selectedOption.value;
  793. forms.currentClassText = selectedOption.text;
  794. forms.classStatus = false;
  795. }}
  796. />
  797. )}
  798. </Popup>
  799. {/* 是否在微信中打开 */}
  800. <OWxTip
  801. v-model:show={forms.showTips}
  802. message={forms.showMessage}
  803. showButton={forms.showButton}
  804. buttonText="刷新"
  805. onConfirm={async () => {
  806. forms.showTips = false;
  807. await getRegisterGoods();
  808. studentInfo.password = '';
  809. window.scrollTo({
  810. top: 0,
  811. behavior: 'smooth'
  812. });
  813. }}
  814. />
  815. <MMessageTip
  816. show={otherParams.showOtherSchool}
  817. showCloseButton={otherParams.showCloseButton}
  818. messageAlign={otherParams.messageAlign}
  819. message={otherParams.showOtherMessage}
  820. showCancelButton={otherParams.showCancelButton}
  821. cancelButtonColor={otherParams.cancelButtonColor}
  822. cancelButtonText={otherParams.cancelButtonText}
  823. confirmButtonColor={otherParams.confirmButtonColor}
  824. confirmButtonText={otherParams.confirmButtonText}
  825. onClose={() => (otherParams.showOtherSchool = false)}
  826. onCancel={() => {
  827. otherParams.showOtherSchool = false;
  828. if (otherParams.otherType === 'nickname') {
  829. forms.isRegister = 'create'; // 新建
  830. changeTipStatus(false, false);
  831. onSubmit();
  832. } else if (otherParams.otherType === 'limit') {
  833. }
  834. }}
  835. onConfirm={() => {
  836. otherParams.showOtherSchool = false;
  837. // 名字
  838. if (otherParams.otherType === 'nickname') {
  839. forms.isRegister = 'update'; // 修改
  840. changeTipStatus(false, false);
  841. // 直接注册
  842. onSubmit();
  843. } else if (otherParams.otherType === 'change') {
  844. // 学校更换
  845. forms.isChangeSchool = true;
  846. // 直接注册
  847. onSubmit();
  848. } else if (otherParams.otherType === 'limit') {
  849. // 人数超限制
  850. changeTipStatus(
  851. forms.isRegister === 'create' && !forms.studentItem.userId
  852. ? false
  853. : true,
  854. false
  855. );
  856. }
  857. }}
  858. />
  859. <Popup
  860. v-model:show={forms.showSelectStudent}
  861. round
  862. position="bottom"
  863. safeAreaInsetBottom
  864. closeable>
  865. <SelectStudent
  866. studentItem={forms.studentItem}
  867. list={forms.studentList}
  868. onClose={() => (forms.showSelectStudent = false)}
  869. onConfirm={(val: any) => {
  870. forms.studentItem = val;
  871. if (val.userId) {
  872. const firstStudent = val;
  873. studentInfo.extra.nickname = firstStudent.nickname;
  874. const tempGrade: any = gradeList.value[0] || [];
  875. tempGrade?.forEach((i: any) => {
  876. if (i.value === firstStudent.currentGradeNum) {
  877. // forms.instrumentCode = i.instrumentCode;
  878. forms.gradeNumText = i.text;
  879. studentInfo.extra.currentGradeNum =
  880. firstStudent.currentGradeNum;
  881. // if (forms.schoolInstrumentSetType === 'CLASS') {
  882. // forms.classList = i.classList;
  883. // }
  884. }
  885. });
  886. classList.forEach((i: any) => {
  887. if (i.value === firstStudent.currentClass) {
  888. forms.currentClassText = i.text;
  889. studentInfo.extra.currentClass = firstStudent.currentClass;
  890. }
  891. });
  892. studentInfo.extra.gender = firstStudent.gender;
  893. forms.isRegister = 'update';
  894. changeTipStatus(true, false);
  895. } else {
  896. forms.isRegister = 'create';
  897. changeTipStatus(false, false);
  898. studentInfo.extra.nickname = '';
  899. studentInfo.extra.currentGradeNum = '';
  900. studentInfo.extra.currentClass = '';
  901. studentInfo.extra.gender = 1;
  902. forms.currentClassText = '';
  903. forms.gradeNumText = '';
  904. }
  905. }}
  906. />
  907. </Popup>
  908. </div>
  909. );
  910. }
  911. });