index.tsx 32 KB

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