123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826 |
- import { areas } from '@/helpers/area'
- import request from '@/helpers/request'
- import {
- CellGroup,
- Form,
- Field,
- RadioGroup,
- Tag,
- Icon,
- Checkbox,
- Radio,
- Button,
- showToast,
- showDialog,
- showLoadingToast,
- closeToast,
- Picker,
- Popup,
- CountDown,
- CheckboxGroup,
- Sticky
- } from 'vant'
- import { defineComponent, onMounted, reactive, ref } from 'vue'
- import { useRoute } from 'vue-router'
- import styles from './companion-teacher-register.module.less'
- import ImgCode from '@/components/o-img-code'
- import schoolLogo from './images/school-logo.png'
- import iconClose from './images/icon-close.png'
- import topBanner1 from './images/top-banner1.png'
- import { checkPhone } from '@/helpers/validate'
- import OUpload from '@/components/o-upload'
- import router from '@/router'
- import dayjs from 'dayjs'
- import { browser, getUrlCode } from '@/helpers/utils'
- import qs from 'query-string'
- export default defineComponent({
- name: 'companion-teacher-register',
- setup() {
- const route = useRoute()
- const state = reactive({
- showPicker: false,
- showSubject: false,
- submitStatus: false,
- showEducation: false,
- checkPhone: true,
- id: route.query.id,
- name: route.query.name,
- t: route.query.t as any, // 过期时间
- qrCodeStatus: false, // 二维码是否失效
- qrCodeMessage: '',
- pattern: /^1(3|4|5|6|7|8|9)\d{9}$/,
- columns: [] as any,
- pickerType: null, // 下拉类型
- popupSelectSubjects: [] as any,
- selectSubjects: [] as any, // 选中的声部
- forms: {
- realName: '',
- phone: null,
- gender: 1,
- idCardNo: null,
- cityCode: null,
- cityCodeName: '',
- provinceCode: null,
- showSubjectIds: '',
- subjectIds: [],
- smsValidCode: '',
- educationBackground: '', // 学历
- graduateSchool: null, // 毕业学校
- idcardFrontImg: '',
- idcardBackImg: '' // 身份证反面照
- },
- btnLoading: false,
- checked: true,
- columnSubject: [] as any,
- countDownStatus: true, // 是否发送验证码
- countDownTime: 120, // 倒计时时间
- countDownRef: null as any, // 倒计时实例
- imgCodeStatus: false,
- showPopup: false,
- code: '' // 授权码
- })
- const onSubmit = async () => {
- if (state.qrCodeStatus) {
- showDialog({
- title: '提示',
- message: state.qrCodeMessage,
- theme: 'round-button',
- confirmButtonColor: '#ff8057'
- })
- return
- }
- if (!state.checked) {
- showToast('请阅读并同意协议')
- return
- }
- state.btnLoading = true
- try {
- const forms = state.forms
- await request.post('/api-school/open/schoolTeacherStudent/registerTeacher', {
- data: {
- ...forms,
- code: state.code,
- subjectIds: forms.subjectIds.join(','),
- schoolId: state.id
- }
- })
- // state.submitStatus = true
- window.location.href =
- 'https://mp.weixin.qq.com/s?__biz=MzkxMDMwOTI5Nw==&mid=2247485261&idx=1&sn=70c79a832a609bf9fae01c9e90fb4f69&chksm=c12c2593f65bac85d26362bca470f6abc2bfc087d9f4dcf87c00094420bdf5a3acb1b870199b#rd'
- } catch {
- // showToast('保存失败,请重试')
- }
- state.btnLoading = false
- }
- const onConfirm = (val: any) => {
- const selectedOptions = val.selectedOptions[1]
- state.forms.cityCode = selectedOptions.code
- state.forms.cityCodeName = selectedOptions.name
- const selectedFirst = val.selectedOptions[0]
- state.forms.provinceCode = selectedFirst.code
- state.showPicker = false
- }
- const onSubjectRemove = (item: any, index: any) => {
- console.log(item)
- showDialog({
- title: '提示',
- message: '您是否删除选中的声部',
- confirmButtonColor: '#ff8057',
- showCancelButton: true
- }).then(() => {
- state.selectSubjects.splice(index, 1)
- const tIndex = state.popupSelectSubjects.findIndex((s: any) => s === item.value)
- state.popupSelectSubjects.splice(tIndex, 1)
- // const tempSubjectIds: any = []
- // state.selectSubjects.forEach((subject: any) => {
- // tempSubjectIds.push(subject.value)
- // })
- state.forms.subjectIds = state.popupSelectSubjects
- state.forms.showSubjectIds = state.popupSelectSubjects.join(',')
- })
- }
- // 选择声部
- const onConfirmSubject = () => {
- const tempSubjects: any = []
- state.columnSubject.forEach((item: any) => {
- if (state.popupSelectSubjects.includes(item.value)) {
- tempSubjects.push(item)
- }
- })
- state.selectSubjects = tempSubjects
- state.forms.subjectIds = state.popupSelectSubjects || []
- state.forms.showSubjectIds = state.popupSelectSubjects.join(',')
- state.showSubject = false
- }
- // 选择学历
- const onConfirmEduction = (val: any) => {
- const selectedOptions = val.selectedOptions[0]
- state.forms.educationBackground = selectedOptions.value
- state.showEducation = false
- }
- const onSendCode = () => {
- // 发送验证码
- console.log(state.forms.phone)
- if (!checkPhone(state.forms.phone as any)) {
- return showToast('请输入正确的手机号码')
- }
- state.imgCodeStatus = true
- }
- const onCodeSend = () => {
- state.countDownStatus = false
- const clearTimer = setInterval(() => {
- state.countDownTime = state.countDownTime - 1
- if (state.countDownTime <= 0) {
- state.countDownTime = 120
- state.countDownStatus = true
- clearInterval(clearTimer)
- }
- }, 1000)
- }
- const onFinished = () => {
- state.countDownStatus = true
- // ;(this.$refs.countDownRef as any).reset()
- }
- onMounted(async () => {
- if (!state.id) {
- showToast('信息获取失败,请联系伴学指导')
- }
- // 判断是否是微信,只能微信中打开
- if (!browser().weixin) {
- state.showPopup = true
- return
- } else {
- //授权
- const code = getUrlCode()
- if (!code) {
- const newUrl =
- window.location.origin +
- window.location.pathname +
- '#' +
- route.path +
- '?' +
- qs.stringify({
- ...route.query
- })
- getAppIdAndCode(newUrl)
- return
- } else {
- state.code = code
- }
- }
- // t: route.query.t, // 过期时间
- try {
- const res = await request.post('/api-school/open/schoolTeacherStudent/queryQrCodeStatus', {
- data: {
- schoolId: state.id,
- qrCodeEffectiveStartTime: state.t
- ? dayjs(Number(state.t)).format('YYYY-MM-DD HH:mm:ss')
- : null
- }
- })
- if (res.code === 999) {
- showDialog({
- title: '提示',
- message: res.message,
- theme: 'round-button',
- confirmButtonColor: '#ff8057'
- })
- state.qrCodeStatus = true
- state.qrCodeMessage = res.message
- }
- } catch (e: any) {
- //
- console.log(e)
- }
- try {
- const tempareas: any = []
- areas.forEach((item) => {
- const temp = {
- name: item.name,
- code: item.code,
- areas: [] as any
- }
- if (item.areas && item.areas.length > 0) {
- item.areas.forEach((child) => {
- temp.areas.push({
- name: child.name,
- code: child.code
- })
- })
- }
- tempareas.push(temp)
- })
- state.columns = tempareas || []
- const { data } = await request.post('/api-school/open/subjectBasicConfig/page', {
- data: {
- page: 1,
- rows: 50
- }
- })
- const rows = data.rows || []
- const tempSubjects: any = []
- rows.forEach((item: any) => {
- tempSubjects.push({
- text: item.subjectName,
- value: item.subjectId
- })
- })
- state.columnSubject = tempSubjects
- } catch {
- showDialog({
- message: '信息获取失败,请联系伴学指导',
- theme: 'round-button',
- confirmButtonColor: '#ff8057'
- })
- }
- })
- const onPreview = (type: any) => {
- if (type === 'REGISTER') {
- window.open(
- window.location.origin + window.location.pathname + '#/preview-protocol',
- '_blank'
- )
- } else if (type === 'PRIVACY') {
- window.open(
- window.location.origin + window.location.pathname + '#/privacyProtocol',
- '_blank'
- )
- } else if (type === 'WITHDRAW') {
- //
- window.open(window.location.origin + window.location.pathname + '#/cashProtocol', '_blank')
- }
- }
- const formRef = ref()
- const checkchangePhone = async () => {
- try {
- await formRef.value?.validate('phone')
- state.checkPhone = false
- getTeacherDetails()
- } catch {
- //
- }
- }
- const getAppIdAndCode = async (url?: string) => {
- try {
- const { data } = await request.get('/api-school/open/paramConfig/wechatAppId')
- // 判断是否有微信appId
- if (data) {
- closeToast()
- goAuth(data, url)
- }
- } catch {
- //
- }
- }
- const goAuth = (wxAppId: string, urlString?: string) => {
- // 用户授权
- console.log(urlString || window.location.href, 'urlString || window.location.href')
- const urlNow = encodeURIComponent(urlString || window.location.href)
- console.log(urlNow, 'urlNow')
- const scope = 'snsapi_base' //snsapi_userinfo //静默授权 用户无感知
- const appid = wxAppId || 'wx8654c671631cfade'
- const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${urlNow}&response_type=code&scope=${scope}&state=STATE&connect_redirect=1#wechat_redirect`
- window.location.replace(url)
- }
- // 反显数据
- const getTeacherDetails = async () => {
- try {
- if (!state.forms.phone) return
- const { data } = await request.post(
- '/api-school/open/teacher/detail/' + state.forms.phone,
- {
- requestType: 'form',
- data: {
- phone: state.forms.phone
- }
- }
- )
- // 判断是否有数据
- if (!data) return
- const subjects = data.subjectId
- ? data.subjectId.split(',').map((subject: any) => Number(subject))
- : []
- state.popupSelectSubjects = subjects || []
- // 显示声部
- subjects.forEach((subject: any) => {
- const item = state.columnSubject.find((item: any) => item.value === subject)
- if (item) {
- state.selectSubjects.push(item)
- }
- })
- let cityCodeName = ''
- state.columns.forEach((p: any) => {
- if (p.areas && p.areas.length > 0) {
- p.areas.forEach((c: any) => {
- if (c.code === Number(data.cityCode)) {
- cityCodeName = c.name
- }
- })
- }
- })
- state.forms = {
- realName: data.realName,
- phone: data.phone,
- gender: data.gender,
- idCardNo: data.idCardNo,
- cityCode: data.cityCode,
- cityCodeName: cityCodeName,
- provinceCode: data.provinceCode,
- showSubjectIds: data.subjectId,
- subjectIds: subjects as any,
- smsValidCode: '',
- educationBackground: data.educationBackground || '', // 学历
- graduateSchool: data.graduateSchool, // 毕业学校
- idcardFrontImg: data.idcardFrontImg || '',
- idcardBackImg: data.idcardBackImg || '' // 身份证反面照
- }
- } catch {
- //
- }
- }
- return () => (
- <div class={styles.register}>
- <div class={styles.title}>
- <p class={styles.tips}>
- <img src={schoolLogo} />
- <span>{state.name}</span>
- </p>
- </div>
- <Form validateFirst scrollToError onSubmit={onSubmit} ref={formRef} class={styles.form}>
- <CellGroup inset class={styles['cell-group']}>
- <Field
- label="手机号码"
- v-model={state.forms.phone}
- rules={[
- { required: true, message: '请输入手机号码' },
- { pattern: state.pattern, message: '输入手机号码有误' }
- ]}
- name="phone"
- placeholder="请输入手机号码"
- maxlength={11}
- onBlur={checkchangePhone}
- type="tel"
- ></Field>
- <div class={styles.phoneTips}>
- <Icon name="warning" size="16" />
- 提示:手机号将成为您管乐团伴学指导端登录账号
- </div>
- <Field
- label="真实姓名"
- v-model={state.forms.realName}
- rules={[{ required: true, message: '请填写真实姓名' }]}
- name="realName"
- placeholder="请填写真实姓名"
- maxlength="5"
- ></Field>
- <Field
- label="身份证号码"
- v-model={state.forms.idCardNo}
- rules={[
- { required: true, message: '请输入身份证号' },
- {
- pattern:
- /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/,
- message: '请输入正确的身份证号'
- }
- ]}
- name="idCardNo"
- maxlength={18}
- placeholder="请输入身份证号码"
- ></Field>
- <Field label="性别" name="gender" rules={[{ required: true, message: '请选择性别' }]}>
- {{
- input: () => (
- <RadioGroup
- checked-color="#FF8057"
- v-model={state.forms.gender}
- direction="horizontal"
- >
- <Tag
- size="large"
- type="primary"
- color={!(state.forms.gender === 1) ? '#EAEAEA' : '#FF8057'}
- textColor={!(state.forms.gender === 1) ? '#AAA' : '#FFF'}
- class={styles.radioSection}
- round
- >
- <Radio class={styles.radioItem} name={1}></Radio>男
- </Tag>
- <Tag
- size="large"
- type="primary"
- color={!(state.forms.gender === 0) ? '#EAEAEA' : '#FF8057'}
- textColor={!(state.forms.gender === 0) ? '#AAA' : '#FFF'}
- class={styles.radioSection}
- round
- >
- <Radio class={styles.radioItem} name={0}></Radio>女
- </Tag>
- </RadioGroup>
- )
- }}
- </Field>
- <div class={[styles.fieldGroup, 'van-hairline--bottom']}>
- <Field
- label="身份证照片正面"
- v-model={state.forms.idcardFrontImg}
- readonly
- border={false}
- name="idcardFrontImg"
- rules={[{ required: true, message: '请上传身份证正面', trigger: 'onChange' }]}
- placeholder="请上传身份证正面"
- >
- {{
- input: () => (
- <OUpload
- style={{ width: '100%' }}
- tips="上传身份证正面"
- bucket="gyt"
- path="/user/"
- v-model:modelValue={state.forms.idcardFrontImg}
- />
- )
- }}
- </Field>
- <Field
- label={'上传身份证反面'}
- labelClass={styles.fieldTitle}
- v-model={state.forms.idcardBackImg}
- readonly
- border={false}
- name="idcardBackImg"
- rules={[{ required: true, message: '请上传身份证反面', trigger: 'onChange' }]}
- placeholder="请上传身份证反面"
- >
- {{
- input: () => (
- <OUpload
- style={{ width: '100%' }}
- tips="上传身份证反面"
- bucket="gyt"
- path="/user/"
- v-model:modelValue={state.forms.idcardBackImg}
- />
- )
- }}
- </Field>
- </div>
- <Field
- label="学历"
- v-model={state.forms.educationBackground}
- readonly
- name="educationBackground"
- onClick={() => {
- state.showEducation = true
- }}
- rules={[{ required: true, message: '请选择学历', trigger: 'onChange' }]}
- placeholder="请选择学历"
- >
- {{
- 'right-icon': () => <Icon name="arrow" color={'#323233'} size="16"></Icon>
- }}
- </Field>
- <Field
- label="毕业学校"
- v-model={state.forms.graduateSchool}
- rules={[{ required: true, message: '请输入毕业学校' }]}
- name="graduateSchool"
- placeholder="请输入毕业学校"
- ></Field>
- <Field
- label="所在城市"
- v-model={state.forms.cityCodeName}
- readonly
- name="cityCodeName"
- onClick={() => {
- state.showPicker = true
- }}
- rules={[{ required: true, message: '请选择所在城市', trigger: 'onChange' }]}
- placeholder="请选择所在城市"
- >
- {{
- 'right-icon': () => <Icon name="arrow" color={'#323233'} size="16"></Icon>
- }}
- </Field>
- <Field
- label="声部(可多选)"
- v-model={state.forms.showSubjectIds}
- readonly
- name="showSubjectIds"
- onClick={() => {
- state.showSubject = true
- }}
- rules={[{ required: true, message: '请选择声部', trigger: 'onChange' }]}
- placeholder="请选择声部"
- >
- {{
- 'right-icon': () => <Icon name="arrow" color={'#323233'} size="16"></Icon>,
- input: () => (
- <>
- {state.forms.subjectIds.length <= 0 ? (
- <div class={styles.subjectPlaceholder} style="color:#c8c9cc">
- 请选择声部
- </div>
- ) : (
- ''
- )}
- {state.forms.subjectIds.length > 0 ? (
- <div>
- {state.selectSubjects.map((item: any, index: any) => (
- <Tag
- closeable
- size="medium"
- color="#FF8057"
- onClose={() => onSubjectRemove(item, index)}
- >
- {item.text}
- </Tag>
- ))}
- </div>
- ) : (
- ''
- )}
- </>
- )
- }}
- </Field>
- <Field
- label="验证码"
- v-model={state.forms.smsValidCode}
- name="smsValidCode"
- rules={[{ required: true, message: '请输入验证码', trigger: 'onChange' }]}
- placeholder="请输入验证码"
- maxlength={6}
- type="tel"
- >
- {{
- button: () =>
- state.countDownStatus ? (
- <Button type="primary" round size="small" color="#ff8057" onClick={onSendCode}>
- 发送验证码
- </Button>
- ) : (
- <Button
- type="default"
- round
- size="small"
- disabled
- style={{ minWidth: '60px' }}
- onClick={onSendCode}
- >
- {state.countDownTime + 's'}
- </Button>
- )
- }}
- </Field>
- </CellGroup>
- <div class={styles.protocol}>
- <Checkbox
- v-model={state.checked}
- icon-size="16"
- style="margin-right: 6px"
- checked-color="#FF8057"
- ></Checkbox>
- <div>
- <span
- onClick={() => {
- state.checked = !state.checked
- }}
- >
- 请认真阅读并勾选
- </span>
- <span class={styles.c} onClick={() => onPreview('REGISTER')}>
- 《管乐团用户注册协议》
- </span>
- 、
- <span class={styles.c} onClick={() => onPreview('PRIVACY')}>
- 《隐私协议》
- </span>
- 、
- <span class={styles.c} onClick={() => onPreview('WITHDRAW')}>
- 《共享经济平台注册经营者协议》
- </span>
- </div>
- </div>
- <Button
- size="large"
- block
- round
- class={styles['btn-submit']}
- color="#FF8057"
- loading={state.btnLoading}
- native-type="submit"
- disabled={state.btnLoading}
- >
- 完成
- </Button>
- </Form>
- {/* 城市 */}
- <Popup v-model:show={state.showPicker} position="bottom" round>
- <Picker
- showToolbar
- columns={state.columns}
- onCancel={() => (state.showPicker = false)}
- onConfirm={onConfirm}
- columnsFieldNames={{ text: 'name', value: 'code', children: 'areas' }}
- />
- </Popup>
- <Popup
- v-model:show={state.showSubject}
- position="bottom"
- round
- safeAreaInsetBottom
- closeable
- >
- {/* <Picker
- showToolbar
- columns={state.columnSubject}
- onCancel={() => (state.showSubject = false)}
- onConfirm={onConfirmSubject}
- /> */}
- <div class={styles.filterTitle}>全部声部</div>
- <div class={styles.searchResult} style={{ maxHeight: '45vh', overflowY: 'auto' }}>
- <CheckboxGroup
- class={[styles.childContent, styles['radio-group']]}
- modelValue={state.popupSelectSubjects}
- onUpdate:modelValue={(val) => {
- console.log(val)
- state.popupSelectSubjects = val
- }}
- >
- {state.columnSubject.map((item: any) => (
- <Checkbox key={item.value} name={item.value} class={styles.radio}>
- <Tag
- class={[styles.item, 'van-ellipsis']}
- plain={state.popupSelectSubjects.includes(item.value)}
- type="primary"
- size="large"
- >
- {item.text}
- </Tag>
- </Checkbox>
- ))}
- </CheckboxGroup>
- <Sticky position="bottom" offsetBottom={0}>
- <div class={['btnGroup']}>
- <Button type="primary" round block onClick={onConfirmSubject}>
- 确 认
- </Button>
- </div>
- </Sticky>
- </div>
- </Popup>
- {/* 学历 */}
- {/* 学历分为专科、本科、硕士、博士、其他 */}
- <Popup v-model:show={state.showEducation} position="bottom" round>
- <Picker
- showToolbar
- columns={[
- { text: '专科', value: '专科' },
- { text: '本科', value: '本科' },
- { text: '硕士', value: '硕士' },
- { text: '博士', value: '博士' },
- { text: '其他', value: '其他' }
- ]}
- onCancel={() => (state.showEducation = false)}
- onConfirm={onConfirmEduction}
- />
- </Popup>
- <Popup v-model:show={state.submitStatus} round style="width: 75%" closeOnClickOverlay>
- <div class={styles.stautsS}>
- {/* <img
- class={styles['icon-close']}
- src={iconClose}
- onClick={() => {
- state.submitStatus = false
- window.location.href =
- window.location.origin + '/orchestra-student/#/download?type=teacher'
- }}
- /> */}
- <img src={topBanner1} class={styles['submit-img']} />
- <div class={styles['submit-container']}>
- <p class={styles['submit-title']}>恭喜您已成功登记为</p>
- <p class={styles['submit-o']}>
- {state.name} <br />
- <span>【伴学指导】</span>
- </p>
- <p class={styles['submit-tips']}>请下载管乐团伴学指导端APP进行授课</p>
- <Button
- type="primary"
- color="#FF8057"
- block
- round
- onClick={() => {
- state.submitStatus = false
- window.location.href =
- window.location.origin + '/orchestra-student/#/download?type=teacher'
- }}
- >
- 立即下载
- </Button>
- </div>
- </div>
- </Popup>
- {state.imgCodeStatus ? (
- <ImgCode
- v-model:value={state.imgCodeStatus}
- phone={state.forms.phone as any}
- type="REGISTER"
- onClose={() => {
- state.imgCodeStatus = false
- }}
- onSendCode={onCodeSend}
- />
- ) : null}
- <Popup
- v-model:show={state.showPopup}
- round
- style={{ width: '88%' }}
- closeOnClickOverlay={false}
- class={styles.wxPopupDialog}
- >
- <div class={styles.popupContainer}>
- <p class={styles.title1}>温馨提示</p>
- <p class={styles.popupTips}>请使用微信打开</p>
- </div>
- </Popup>
- </div>
- )
- }
- })
|