123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592 |
- 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
- } from 'vant'
- import { defineComponent, onMounted, reactive } 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'
- export default defineComponent({
- name: 'companion-teacher-register',
- setup() {
- const route = useRoute()
- const state = reactive({
- showPicker: false,
- showSubject: false,
- submitStatus: false,
- showEducation: false,
- id: route.query.id,
- name: route.query.name,
- pattern: /^1(3|4|5|6|7|8|9)\d{9}$/,
- columns: [] as any,
- pickerType: null, // 下拉类型
- 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,
- checkPhone: false,
- checked: true,
- columnSubject: [] as any,
- countDownStatus: true, // 是否发送验证码
- countDownTime: 120, // 倒计时时间
- countDownRef: null as any, // 倒计时实例
- imgCodeStatus: false
- })
- const onSubmit = async () => {
- if (!state.checked) {
- showToast('请阅读并同意协议')
- return
- }
- state.btnLoading = true
- try {
- const forms = state.forms
- await request.post('/api-school/open/schoolTeacherStudent/registerTeacher', {
- data: {
- ...forms,
- subjectIds: forms.subjectIds.join(','),
- schoolId: state.id
- }
- })
- state.submitStatus = true
- } 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) => {
- showDialog({
- title: '提示',
- message: '您是否删除选中的声部',
- confirmButtonColor: '#ff8057',
- showCancelButton: true
- }).then(() => {
- state.selectSubjects.splice(index, 1)
- const tempSubjectIds: any = []
- state.selectSubjects.forEach((subject: any) => {
- tempSubjectIds.push(subject.value)
- })
- state.forms.subjectIds = tempSubjectIds
- state.forms.showSubjectIds = tempSubjectIds.join(',')
- })
- }
- // 选择声部
- const onConfirmSubject = (val: any) => {
- const selected = val.selectedOptions[0]
- let isCheck = false
- state.selectSubjects.forEach((subject: any) => {
- if (subject.value === selected.value) {
- isCheck = true
- }
- })
- // 判断是否有选择一样的数据
- if (isCheck) {
- state.showSubject = false
- return
- }
- state.selectSubjects.push(val.selectedOptions[0])
- const tempSubjectIds: any = []
- state.selectSubjects.forEach((subject: any) => {
- tempSubjectIds.push(subject.value)
- })
- state.forms.subjectIds = tempSubjectIds
- state.forms.showSubjectIds = tempSubjectIds.join(',')
- state.showSubject = false
- }
- // 选择学历
- const onConfirmEduction = (val: any) => {
- const selectedOptions = val.selectedOptions[0]
- state.forms.educationBackground = selectedOptions.value
- state.showEducation = false
- }
- const onSendCode = () => {
- // 发送验证码
- 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('信息获取失败,请联系老师')
- }
- 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/orchestraSubjectConfig/pageByOrchestraId',
- {
- data: {
- page: 1,
- rows: 50
- }
- }
- )
- const rows = data.rows || []
- const tempSubjects: any = []
- rows.forEach((item: any) => {
- tempSubjects.push({
- text: item.name,
- value: item.subjectId
- })
- })
- state.columnSubject = tempSubjects
- } catch {
- showDialog({
- message: '信息获取失败,请联系老师',
- theme: 'round-button',
- confirmButtonColor: '#64A9FF'
- })
- }
- })
- const onPreview = () => {
- window.open(window.location.origin + '/#/preview-protocol', '_blank')
- }
- 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="form" class={styles.form}>
- <CellGroup inset class={styles['cell-group']}>
- <Field
- required
- label="真实姓名"
- v-model={state.forms.realName}
- rules={[{ required: true, message: '请填写真实姓名' }]}
- name="realName"
- placeholder="请填写真实姓名"
- maxlength="50"
- ></Field>
- <Field
- required
- label="手机号码"
- v-model={state.forms.phone}
- rules={[
- { required: true, message: '请输入手机号码' },
- { pattern: state.pattern, message: '输入手机号码有误' }
- ]}
- name="phone"
- placeholder="请输入手机号码"
- maxlength={11}
- type="tel"
- ></Field>
- <Field
- required
- 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>
- <div class={styles.phoneTips}>
- <Icon name="warning" size="16" />
- 提示:手机号码将成为您管乐团老师端登录账号
- </div>
- <Field
- required
- 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
- required
- label="性别"
- name="gender"
- rules={[{ required: true, message: '请选择性别' }]}
- >
- {{
- input: () => (
- <RadioGroup
- checked-color="#FF8057"
- v-model={state.forms.gender}
- direction="horizontal"
- >
- <Tag
- size="large"
- type="primary"
- plain={!(state.forms.gender === 1)}
- color="#FF8057"
- class={styles.radioSection}
- >
- <Radio class={styles.radioItem} name={1}></Radio>男
- </Tag>
- <Tag
- size="large"
- type="primary"
- plain={!(state.forms.gender === 0)}
- color="#FF8057"
- class={styles.radioSection}
- >
- <Radio class={styles.radioItem} name={0}></Radio>女
- </Tag>
- </RadioGroup>
- )
- }}
- </Field>
- <Field
- required
- label="身份证照片正面"
- v-model={state.forms.idcardFrontImg}
- readonly
- name="idcardFrontImg"
- rules={[{ required: true, message: '请上传身份证正面', trigger: 'onChange' }]}
- placeholder="请上传身份证正面"
- >
- {{
- input: () => (
- <OUpload
- style={{ width: '100%' }}
- tips="上传身份证正面"
- v-model:modelValue={state.forms.idcardFrontImg}
- />
- )
- }}
- </Field>
- <Field
- required
- label="身份证照片反面"
- v-model={state.forms.idcardBackImg}
- readonly
- name="idcardBackImg"
- rules={[{ required: true, message: '请上传身份证反面', trigger: 'onChange' }]}
- placeholder="请上传身份证反面"
- >
- {{
- input: () => (
- <OUpload
- style={{ width: '100%' }}
- tips="上传身份证反面"
- v-model:modelValue={state.forms.idcardBackImg}
- />
- )
- }}
- </Field>
- <Field
- required
- 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={state.checkPhone ? '#aaa' : '#323233'} size="16"></Icon>
- )
- }}
- </Field>
- <Field
- required
- label="毕业学校"
- v-model={state.forms.graduateSchool}
- rules={[{ required: true, message: '请输入毕业学校' }]}
- name="graduateSchool"
- placeholder="请输入毕业学校"
- ></Field>
- <Field
- required
- 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={state.checkPhone ? '#aaa' : '#323233'} size="16"></Icon>
- )
- }}
- </Field>
- <Field
- required
- 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={state.checkPhone ? '#aaa' : '#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>
- </CellGroup>
- <div class={styles.protocol}>
- <Checkbox
- v-model={state.checked}
- icon-size="16"
- style="margin-right: 6px"
- checked-color="#FF8057"
- ></Checkbox>
- <span
- onClick={() => {
- state.checked = !state.checked
- }}
- >
- 请认真阅读并勾选
- </span>
- <span class={styles.c} onClick={onPreview}>
- 《乐团伴学老师注册协议》
- </span>
- </div>
- <Button
- size="large"
- block
- round
- class={styles['btn-submit']}
- color="#FF8057"
- loading={state.btnLoading}
- native-type="submit"
- >
- 完成
- </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>
- <Picker
- showToolbar
- columns={state.columnSubject}
- onCancel={() => (state.showSubject = false)}
- onConfirm={onConfirmSubject}
- />
- </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}
- onClose={() => {
- state.imgCodeStatus = false
- }}
- onSendCode={onCodeSend}
- />
- ) : null}
- </div>
- )
- }
- })
|