index.tsx 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. import { defineComponent, nextTick, onMounted, reactive, ref } from 'vue';
  2. import styles from './index.module.less';
  3. import {
  4. Button,
  5. Cell,
  6. CellGroup,
  7. CountDown,
  8. Field,
  9. Popup,
  10. showToast
  11. } from 'vant';
  12. import banner from './images/banner.png';
  13. import iconSchool from './images/icon-school.png';
  14. import iconTips from './images/icon-tips.png';
  15. import bannerPopup from './images/banner-popup.png';
  16. import MSticky from '@/components/m-sticky';
  17. import MProtocol from '@/components/m-protocol';
  18. import { useRoute, useRouter } from 'vue-router';
  19. import request from '@/helpers/request';
  20. import { checkPhone } from '@/helpers/utils';
  21. import { EShoolStaffType } from '@/helpers/constant';
  22. import MImgCode from '@/components/m-img-code';
  23. export default defineComponent({
  24. name: 'school-register',
  25. setup() {
  26. const route = useRoute();
  27. const router = useRouter();
  28. const forms = reactive({
  29. id: route.query.id,
  30. imgCodeStatus: false,
  31. type: (route.query.type || '') as string,
  32. username: '',
  33. nameReg: /^[\u4E00-\u9FA5]+$/,
  34. phone: '',
  35. isAgree: false,
  36. smsCode: '',
  37. registerStatus: false,
  38. countDownStatus: true,
  39. schoolDetail: {} as any,
  40. countDownTime: 1000 * 120 // 倒计时时间
  41. });
  42. const countDownRef = ref();
  43. const getDetail = async () => {
  44. try {
  45. const { data } = await request.get('/api-web/open/school/cooperation', {
  46. params: {
  47. id: forms.id
  48. }
  49. });
  50. forms.schoolDetail = data || {};
  51. } catch {
  52. //
  53. }
  54. };
  55. const onSubmit = async () => {
  56. // console.log(forms.isAgree, 'forms.isAgree');
  57. // if (!forms.isAgree) {
  58. // showToast('请阅读并同意注册协议');
  59. // return;
  60. // }
  61. if (!forms.username) {
  62. showToast('请输入真实姓名');
  63. return;
  64. }
  65. if (!forms.nameReg.test(forms.username)) {
  66. showToast('姓名必须为中文');
  67. return;
  68. }
  69. if (!checkPhone(forms.phone)) {
  70. showToast('请输入正确的手机号');
  71. return;
  72. }
  73. if (!forms.smsCode) {
  74. showToast('请输入验证码');
  75. return;
  76. }
  77. try {
  78. const res = await request.post('/api-web/open/school/staffSave', {
  79. hideLoading: false,
  80. data: {
  81. schoolId: forms.id,
  82. userType: forms.type,
  83. username: forms.username,
  84. mobile: forms.phone,
  85. smsCode: forms.smsCode
  86. }
  87. });
  88. if (res.code === 999) {
  89. setTimeout(() => {
  90. showToast('您已注册');
  91. // router.push('/download');
  92. }, 100);
  93. } else {
  94. forms.registerStatus = true;
  95. }
  96. } catch {
  97. //
  98. }
  99. };
  100. const onDownload = () => {
  101. forms.registerStatus = false;
  102. router.push('/download');
  103. };
  104. const onCodeSend = () => {
  105. forms.countDownStatus = false;
  106. nextTick(() => {
  107. countDownRef.value.start();
  108. });
  109. };
  110. const onSendCode = () => {
  111. // 发送验证码
  112. if (!checkPhone(forms.phone)) {
  113. return showToast('请输入正确的手机号码');
  114. }
  115. forms.imgCodeStatus = true;
  116. };
  117. const onFinished = () => {
  118. forms.countDownStatus = true;
  119. countDownRef.value.reset();
  120. };
  121. onMounted(() => {
  122. if (!forms.id) {
  123. showToast('链接有误');
  124. return;
  125. }
  126. document.title = EShoolStaffType[forms.type] + '注册';
  127. getDetail();
  128. });
  129. return () => (
  130. <div class={styles['school-register']}>
  131. <div class={styles.banner}>
  132. <img src={banner} alt="banner" />
  133. <div class={styles.bannerContainer}>
  134. <div class={styles.bannerTitle}>
  135. {EShoolStaffType[forms.type]}注册
  136. </div>
  137. <div class={styles.bannerSchool}>
  138. <img src={iconSchool} class={styles.iconSchool} />
  139. <p class={styles.schoolName}>
  140. {forms.schoolDetail?.cooperation?.name}
  141. </p>
  142. </div>
  143. </div>
  144. </div>
  145. <CellGroup inset>
  146. <Field
  147. labelAlign="top"
  148. class="border"
  149. v-model={forms.username}
  150. placeholder="请填写您的真实姓名"
  151. autocomplete="off"
  152. maxlength={8}>
  153. {{
  154. label: () => (
  155. <>
  156. 真实姓名<i class={styles.required}>*</i>
  157. </>
  158. )
  159. }}
  160. </Field>
  161. <Field
  162. labelAlign="top"
  163. v-model={forms.phone}
  164. placeholder="请填写您的手机号码"
  165. autocomplete="off"
  166. maxlength={11}>
  167. {{
  168. label: () => (
  169. <>
  170. 手机号码<i class={styles.required}>*</i>
  171. </>
  172. )
  173. }}
  174. </Field>
  175. <Cell border={false}>
  176. <div class={styles.tips}>
  177. <img src={iconTips} class={styles.iconTips} />
  178. 提示:手机号码将成为您管乐迷学校端登录账户
  179. </div>
  180. </Cell>
  181. <Field
  182. labelAlign="top"
  183. class="border"
  184. v-model={forms.smsCode}
  185. placeholder="请输入验证码"
  186. autocomplete="off"
  187. maxlength={6}>
  188. {{
  189. label: () => (
  190. <>
  191. 验证码<i class={styles.required}>*</i>
  192. </>
  193. ),
  194. button: () =>
  195. forms.countDownStatus ? (
  196. <span class={styles.codeText} onClick={onSendCode}>
  197. 获取验证码
  198. </span>
  199. ) : (
  200. <CountDown
  201. ref={(e: any) => (countDownRef.value = e)}
  202. auto-start={false}
  203. time={forms.countDownTime}
  204. onFinish={onFinished}
  205. format="ss秒"
  206. />
  207. )
  208. }}
  209. </Field>
  210. </CellGroup>
  211. {/* <MSticky position="bottom"> */}
  212. {/* <MProtocol
  213. style={{ textAlign: 'center' }}
  214. v-model:modelValue={forms.isAgree}
  215. /> */}
  216. <div
  217. class={['btnGroupFixed']}
  218. style={{
  219. 'margin-top': '18px'
  220. }}>
  221. <Button round block type="primary" onClick={onSubmit}>
  222. 提交
  223. </Button>
  224. </div>
  225. {/* </MSticky> */}
  226. <Popup
  227. v-model:show={forms.registerStatus}
  228. class={styles.popup}
  229. closeOnClickOverlay={false}>
  230. <div class={styles.popupContainer}>
  231. <img src={bannerPopup} class={styles.bannerPopup} />
  232. <h3>注册成功</h3>
  233. <div class={styles.popupContent}>
  234. 恭喜您在{forms.schoolDetail?.cooperation?.name}成功注册为
  235. <span>【{EShoolStaffType[forms.type]}】</span>
  236. ,请下载管乐迷学校端App进行乐团管理吧~
  237. </div>
  238. <Button
  239. type="primary"
  240. round
  241. class={styles.popupBtn}
  242. onClick={onDownload}>
  243. 立即下载
  244. </Button>
  245. </div>
  246. </Popup>
  247. {forms.imgCodeStatus ? (
  248. <MImgCode
  249. v-model:value={forms.imgCodeStatus}
  250. phone={forms.phone}
  251. onClose={() => {
  252. forms.imgCodeStatus = false;
  253. }}
  254. onSendCode={onCodeSend}
  255. />
  256. ) : null}
  257. </div>
  258. );
  259. }
  260. });