index.tsx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. import {
  2. Popup,
  3. Field,
  4. Form,
  5. CellGroup,
  6. Button,
  7. Toast,
  8. Picker,
  9. DatetimePicker,
  10. Overlay
  11. } from 'vant'
  12. import ImgCode from '@/components/col-img-code'
  13. import { defineComponent, onMounted, reactive } from 'vue'
  14. import styles from './index.module.less'
  15. import bg from './images/bg.png'
  16. import rejectLogo from './images/rejectLogo.png'
  17. import rejectSchool from './images/rejest-school.png'
  18. import subTitle from './images/subTitle.png'
  19. import centerLogo from './images/center.png'
  20. import studentText from './images/studentText.png'
  21. import { useRoute, useRouter } from 'vue-router'
  22. import icon_arrow from './images/icon_arrow.png'
  23. import rejectBtn from './images/rejectBtn.png'
  24. import studentSuccess from './images/studentSuccess.png'
  25. import request from '@/helpers/request'
  26. import dayjs from 'dayjs'
  27. import { getHttpOrigin, removeAuth, setAuth } from '@/helpers/utils'
  28. import { state } from '@/helpers/helpState'
  29. import { setLogin } from '@/state'
  30. export default defineComponent({
  31. name: 'tenantStudentRejest',
  32. setup() {
  33. const route = useRoute()
  34. const router = useRouter()
  35. const forms = reactive({
  36. gender: '',
  37. name: '',
  38. phone: '',
  39. subjectId: '',
  40. subjectName: '',
  41. tenantGroupName: '',
  42. tenantGroupId: '',
  43. birthdate: '',
  44. code: '',
  45. genderName: '',
  46. tenantId: route.query.tenantId
  47. })
  48. const data = reactive({
  49. birthdate: new Date(dayjs().year(), dayjs().month() + 1, dayjs().date()),
  50. schoolName: route.query.name || '',
  51. id: route.query.tenantId,
  52. tenantGroupId: route.query.tenantGroupId,
  53. userSchoolName: '',
  54. cityName: '', // 所属城市
  55. showArea: false,
  56. checked: true,
  57. success: false,
  58. areaList: {} as any,
  59. sendMsg: '获取验证码',
  60. imgCodeStatus: false,
  61. subjectList: [],
  62. searchStatus: false,
  63. openStatus: false,
  64. dateState: false,
  65. tenantGroupList: [] as any,
  66. tenantGroupStatus: false,
  67. genderState: false,
  68. genderList: [
  69. { text: '男', value: '1' },
  70. { text: '女', value: '0' }
  71. ],
  72. showSuccess: false,
  73. secondConfirm: false,
  74. minDate: new Date(1980, 0, 1),
  75. maxDate: new Date()
  76. })
  77. const handleSubmit = async () => {
  78. try {
  79. if (!forms.name) {
  80. Toast('请输入姓名')
  81. return
  82. }
  83. if (!forms.gender) {
  84. Toast('请选择性别')
  85. return
  86. }
  87. if (!forms.birthdate) {
  88. Toast('请选择出生年月')
  89. return
  90. }
  91. if (!forms.phone) {
  92. Toast('请输入手机号')
  93. return
  94. }
  95. if (!forms.code) {
  96. Toast('请输入验证码')
  97. return
  98. }
  99. if (!forms.subjectId) {
  100. Toast('请选择声部')
  101. return
  102. }
  103. if (!forms.tenantGroupId) {
  104. Toast('请选择小组')
  105. return
  106. }
  107. const loginCode = route.query.taId ? true : false
  108. const res = await request.post('/api-tenant/open/student/save', {
  109. data: { ...forms, loginCode },
  110. hideLoading: true
  111. })
  112. if (res.code == 200) {
  113. if (loginCode) {
  114. onLogin(res.data)
  115. } else {
  116. data.showSuccess = true
  117. }
  118. }
  119. if (res.code == 5004) {
  120. data.secondConfirm = true
  121. data.userSchoolName = res.msg
  122. }
  123. } catch {
  124. //
  125. }
  126. }
  127. const onLogin = async code => {
  128. try {
  129. if (!code) {
  130. Toast('注册失败,请重新注册')
  131. return
  132. }
  133. const res = await request.post('/api-auth/smsLogin', {
  134. requestType: 'form',
  135. data: {
  136. clientId: 'student',
  137. clientSecret: 'student',
  138. phone: forms.phone,
  139. smsCode: code
  140. }
  141. })
  142. const { authentication } = res.data
  143. setAuth(authentication.token_type + ' ' + authentication.access_token)
  144. const userCash = await request.get(
  145. '/api-student/student/queryUserInfo',
  146. {
  147. initRequest: true // 初始化接口
  148. }
  149. )
  150. setLogin(userCash.data)
  151. router.replace({
  152. path: '/train-tool',
  153. query: {
  154. ...route.query
  155. }
  156. })
  157. } catch {
  158. //
  159. }
  160. }
  161. const getSubjectList = async () => {
  162. try {
  163. const res = await request.get('/api-tenant/open/subject/queryPage', {
  164. params: { page: 1, rows: 9999, queryType: 'list' }
  165. })
  166. const rows = res.data.rows || []
  167. const tempList: any = []
  168. rows.forEach((item: any) => {
  169. // if (item.parentSubjectId > 0) {
  170. tempList.push({
  171. text: item.name,
  172. value: item.id
  173. })
  174. // }
  175. })
  176. data.subjectList = tempList
  177. // res.data.rows.map((item: any) => {
  178. // return {
  179. // text: item.name,
  180. // value: item.id
  181. // }
  182. // }) || []
  183. } catch (e) {
  184. console.log(e)
  185. }
  186. }
  187. const confirmSubject = (val: any) => {
  188. forms.subjectName = val.text
  189. forms.subjectId = val.value
  190. data.searchStatus = false
  191. }
  192. const confirmTenant = (val: any) => {
  193. console.log(val, 'confirmTenant')
  194. forms.tenantGroupName = val.text
  195. forms.tenantGroupId = val.value
  196. data.tenantGroupStatus = false
  197. }
  198. const confirmDate = (val: any) => {
  199. forms.birthdate = dayjs(val).format('YYYY-MM-DD')
  200. data.dateState = false
  201. }
  202. const tenantGroupList = async () => {
  203. try {
  204. const res = await request.post('/api-tenant/open/tenantGroup/page', {
  205. data: {
  206. page: 1,
  207. rows: 999,
  208. tenantId: data.id
  209. }
  210. })
  211. data.tenantGroupList =
  212. res.data.rows.map((item: any) => {
  213. return {
  214. text: item.name,
  215. value: item.id
  216. }
  217. }) || []
  218. } catch {
  219. //
  220. }
  221. }
  222. onMounted(() => {
  223. removeAuth()
  224. if (data.tenantGroupId) {
  225. forms.tenantGroupId = data.tenantGroupId as any
  226. }
  227. tenantGroupList()
  228. getSubjectList()
  229. })
  230. const confirmGender = (val: any) => {
  231. if (val.value) {
  232. forms.gender = val.value
  233. forms.genderName = val.text
  234. } else {
  235. forms.gender = ''
  236. forms.genderName = ''
  237. }
  238. data.genderState = false
  239. }
  240. /** 发送验证码 */
  241. const onSendSms = async () => {
  242. if (!forms.phone) {
  243. Toast('请输入手机号码')
  244. return
  245. }
  246. if (!/^1[3456789]\d{9}$/.test(forms.phone)) {
  247. Toast('手机号码格式不正确')
  248. return
  249. }
  250. // await request.post('/api-student/code/sendSmsCode', {
  251. // requestType: 'form',
  252. // data: {
  253. // mobile: forms.phone,
  254. // type: 'REGISTER'
  255. // }
  256. // })
  257. // onCountDown()
  258. // setTimeout(() => {
  259. // Toast('验证码已发送')
  260. // }, 100)
  261. data.imgCodeStatus = true
  262. }
  263. const onCountDown = () => {
  264. data.sendMsg = '60s'
  265. let count = 60
  266. const timer = setInterval(() => {
  267. count--
  268. data.sendMsg = `${count}s`
  269. if (count <= 0) {
  270. data.sendMsg = '获取验证码'
  271. clearInterval(timer)
  272. }
  273. }, 1000)
  274. }
  275. const downApp = () => {
  276. window.open(getHttpOrigin() + '/student/#/download')
  277. data.showSuccess = false
  278. }
  279. const submitSecond = async () => {
  280. try {
  281. await request.post('/api-tenant/open/student/save', {
  282. data: { ...forms, updateTenant: true },
  283. hideLoading: true
  284. })
  285. data.showSuccess = true
  286. data.secondConfirm = false
  287. } catch (e) {
  288. console.log(e)
  289. }
  290. }
  291. return () => (
  292. <>
  293. <div class={styles.videoClass}>
  294. {/* <ColHeader
  295. class={styles.classHeader}
  296. border={false}
  297. isFixed={false}
  298. background="#fff"
  299. /> */}
  300. <div class={styles.resjetStudentWrap}>
  301. <img src={rejectLogo} class={styles.rejectLogo} alt="" />
  302. <img src={studentText} class={styles.studentText} alt="" />
  303. <img src={bg} class={styles.bgWrap} alt="" />
  304. <div class={styles.schoolNameWrap}>
  305. <img src={rejectSchool} class={styles.rejectSchool} alt="" />
  306. <p>{data.schoolName}</p>
  307. </div>
  308. <img class={styles.centerLogo} src={centerLogo} alt="" />
  309. <div class={styles.infoWrap}>
  310. <div class={styles.infoWrapCore}>
  311. <img src={subTitle} class={styles.subTitle} alt="" />
  312. <Form onSubmit={() => handleSubmit()}>
  313. <CellGroup class={styles.group} border={false}>
  314. <Field
  315. class={styles.noArrow}
  316. inputAlign="right"
  317. label="姓名"
  318. placeholder="请输入姓名"
  319. maxlength={14}
  320. v-model={forms.name}
  321. // onUpdate: modelValue={(val: string) => {
  322. // forms.nickname = val.trim();
  323. // }}
  324. />
  325. <Field
  326. readonly
  327. inputAlign="right"
  328. label="性别"
  329. placeholder="请选择性别"
  330. v-model={forms.genderName}
  331. onClick={() => {
  332. data.genderState = true
  333. }}
  334. // onUpdate: modelValue={(val: string) => {
  335. // forms.nickname = val.trim();
  336. // }}
  337. >
  338. {{
  339. button: () => (
  340. <img
  341. style={{
  342. display: 'block',
  343. width: '12px',
  344. height: '12px'
  345. }}
  346. src={icon_arrow}
  347. />
  348. )
  349. }}
  350. </Field>
  351. <Field
  352. readonly
  353. inputAlign="right"
  354. label="出生日期"
  355. placeholder="请选择出生日期"
  356. maxlength={20}
  357. v-model={forms.birthdate}
  358. onClick={() => {
  359. data.dateState = true
  360. }}
  361. // onUpdate: modelValue={(val: string) => {
  362. // forms.nickname = val.trim();
  363. // }}
  364. >
  365. {{
  366. button: () => (
  367. <img
  368. style={{
  369. display: 'block',
  370. width: '12px',
  371. height: '12px'
  372. }}
  373. src={icon_arrow}
  374. />
  375. )
  376. }}
  377. </Field>
  378. <Field
  379. inputAlign="right"
  380. label="手机号"
  381. class={styles.noArrow}
  382. maxlength={11}
  383. placeholder="手机号码"
  384. v-model={forms.phone}
  385. />
  386. <div class={styles.tips}>
  387. 手机号码为酷乐秀机构版登录账号
  388. </div>
  389. <Field
  390. class={styles.inputCode}
  391. inputAlign="left"
  392. label="验证码"
  393. labelWidth={0}
  394. v-model={forms.code}
  395. maxlength={6}
  396. >
  397. {{
  398. button: () => (
  399. <Button
  400. disabled={data.sendMsg.includes('s')}
  401. class={styles.sendBtn}
  402. onClick={() => onSendSms()}
  403. >
  404. {data.sendMsg}
  405. </Button>
  406. )
  407. }}
  408. </Field>
  409. <Field
  410. border={false}
  411. inputAlign="right"
  412. label="声部"
  413. placeholder="请选择声部"
  414. readonly
  415. v-model={forms.subjectName}
  416. onClick={() => (data.searchStatus = true)}
  417. >
  418. {{
  419. button: () => (
  420. <img
  421. style={{
  422. display: 'block',
  423. width: '12px',
  424. height: '12px'
  425. }}
  426. src={icon_arrow}
  427. />
  428. )
  429. }}
  430. </Field>
  431. {data.tenantGroupId ? (
  432. ''
  433. ) : (
  434. <Field
  435. border={false}
  436. inputAlign="right"
  437. label="小组"
  438. placeholder="请选择小组"
  439. readonly
  440. v-model={forms.tenantGroupName}
  441. onClick={() => (data.tenantGroupStatus = true)}
  442. >
  443. {{
  444. button: () => (
  445. <img
  446. style={{
  447. display: 'block',
  448. width: '12px',
  449. height: '12px'
  450. }}
  451. src={icon_arrow}
  452. />
  453. )
  454. }}
  455. </Field>
  456. )}
  457. </CellGroup>
  458. </Form>
  459. </div>
  460. <img
  461. src={rejectBtn}
  462. onClick={() => {
  463. handleSubmit()
  464. }}
  465. class={styles.rejectBtn}
  466. alt=""
  467. />
  468. </div>
  469. </div>
  470. <Popup
  471. show={data.searchStatus}
  472. position="bottom"
  473. round
  474. columns-field-names={{ text: '' }}
  475. safe-area-inset-bottom
  476. onClose={() => (data.searchStatus = false)}
  477. onClosed={() => (data.openStatus = false)}
  478. >
  479. <Picker
  480. columns={data.subjectList}
  481. onCancel={() => {
  482. data.searchStatus = false
  483. }}
  484. onConfirm={confirmSubject}
  485. ></Picker>
  486. </Popup>
  487. <Popup
  488. show={data.tenantGroupStatus}
  489. position="bottom"
  490. round
  491. columns-field-names={{ text: '' }}
  492. safe-area-inset-bottom
  493. onClose={() => (data.tenantGroupStatus = false)}
  494. onClosed={() => (data.openStatus = false)}
  495. >
  496. <Picker
  497. columns={data.tenantGroupList}
  498. onCancel={() => {
  499. data.tenantGroupStatus = false
  500. }}
  501. onConfirm={confirmTenant}
  502. ></Picker>
  503. </Popup>
  504. <Popup
  505. show={data.dateState}
  506. position="bottom"
  507. round
  508. columns-field-names={{ text: '' }}
  509. safe-area-inset-bottom
  510. onClose={() => (data.dateState = false)}
  511. onClosed={() => (data.dateState = false)}
  512. >
  513. <DatetimePicker
  514. min-date={data.minDate}
  515. max-date={data.maxDate}
  516. type="date"
  517. v-model={data.birthdate}
  518. onCancel={() => {
  519. data.dateState = false
  520. }}
  521. onConfirm={confirmDate}
  522. ></DatetimePicker>
  523. </Popup>
  524. <Popup
  525. show={data.genderState}
  526. position="bottom"
  527. round
  528. columns-field-names={{ text: '' }}
  529. safe-area-inset-bottom
  530. onClose={() => (data.genderState = false)}
  531. onClosed={() => (data.genderState = false)}
  532. >
  533. <Picker
  534. columns={data.genderList}
  535. onCancel={() => {
  536. data.genderState = false
  537. }}
  538. onConfirm={confirmGender}
  539. ></Picker>
  540. </Popup>
  541. <Overlay show={data.showSuccess} z-index={1000}>
  542. <div class={styles.showWrap}>
  543. <img class={styles.showWrapTop} src={studentSuccess} alt="" />
  544. <h2>恭喜您已成功登记为</h2>
  545. <h4>
  546. {data.schoolName} <span>【学员】</span>{' '}
  547. </h4>
  548. <p>请下载酷乐秀机构版APP进行学习</p>
  549. <div class={styles.downApp} onClick={downApp}>
  550. 立即下载
  551. </div>
  552. </div>
  553. </Overlay>
  554. <Popup
  555. show={data.secondConfirm}
  556. position="center"
  557. round
  558. onClose={() => (data.secondConfirm = false)}
  559. onClosed={() => (data.secondConfirm = false)}
  560. >
  561. <div class={styles.secondWrap}>
  562. <h2>提示</h2>
  563. <p>
  564. 当前账号已存在 <span>【{data.userSchoolName}】</span>{' '}
  565. ,是否确认更换到
  566. <span>{data.schoolName}</span>
  567. 吗?
  568. </p>
  569. <div class={styles.buttonWrap}>
  570. <div
  571. class={styles.closeBtn}
  572. onClick={() => {
  573. data.secondConfirm = false
  574. }}
  575. >
  576. {' '}
  577. 取消
  578. </div>
  579. <div class={styles.submitBtn} onClick={submitSecond}>
  580. 确定
  581. </div>
  582. </div>
  583. </div>
  584. </Popup>
  585. {data.imgCodeStatus ? (
  586. <ImgCode
  587. v-model:value={data.imgCodeStatus}
  588. phone={forms.phone}
  589. registerType="REGISTER"
  590. onClose={() => {
  591. data.imgCodeStatus = false
  592. }}
  593. onSendCode={onCountDown}
  594. />
  595. ) : null}
  596. </div>
  597. </>
  598. )
  599. }
  600. })