index.tsx 32 KB

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