123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- <template>
- <div class="fx-column">
- <div class="notice pb40">*账号信息安全与您本人息息相关,请如实填写</div>
- <div class="fx-column" style="height: 420px; overflow-y:scroll">
- <el-form ref="form" :model="formData" :rules="formRules" :validate-on-rule-change="false" label-position="right"
- label-width="70px">
- <el-row :gutter="20">
- <el-col :span="24">
- <el-form-item prop="username" label="姓 名">
- <el-input type="text" v-model="formData.username" placeholder="请输入姓名"></el-input>
- </el-form-item>
- </el-col>
- <!-- 暂时不需要学年,学年从年级上选择 -->
- <el-col v-if="false" :span="10">
- <el-form-item prop="year" label="学 年">
- <el-select v-model="formData.year" placeholder="请选择学年">
- <el-option v-for="(y, idx) in yearOptions" :key="idx" :label="y" :value="y"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="isFrontTeacher?14:24">
- <el-form-item prop="schoolId" label="学 校">
- <el-select v-model="formData.schoolId" placeholder="请选择学校" @change="handleSchoolChange" class="width100">
- <el-option-group v-for="(g, index) in groupedSchoolOptions" :key="index" :label="g.label">
- <el-option v-for="(sc,idx) in g.options" :key="idx" :label="sc.schoolName"
- :value="sc.schoolId"></el-option>
- </el-option-group>
- </el-select>
- </el-form-item>
- </el-col>
- <el-col v-if="isFrontTeacher" :span="10">
- <el-form-item prop="subjectid" label="科 目">
- <el-select v-model="formData.subjectid" placeholder="请选择科目" class="width100">
- <el-option v-for="(sj,idx) in subjectOptions" :key="idx" :label="sj.label"
- :value="sj.value"></el-option>
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="12">
- <el-form-item v-if="isFrontStudent" prop="sno" label="学 号">
- <el-input type="text" v-model="formData.sno" placeholder="请输入学号"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="12">
- <el-form-item v-if="isFrontStudent" prop="clazzId" label="班 级">
- <el-cascader
- v-model="formData.clazzId"
- :disabled="!formData.schoolId"
- :placeholder="formData.schoolId?'选择年级-班级':'请先选择学校'"
- :options="classTree"
- ></el-cascader>
- </el-form-item>
- </el-col>
- </el-row>
- <template v-if="isFrontTeacher">
- <!-- 这里的name另外定义了一个,因为内部for循环+v-model方式会引发循环赋值(uni-app的实现问题) -->
- <el-form-item prop="gradeClass" label="年级组">
- <el-cascader
- v-model="formData.gradeClass"
- :disabled="!formData.schoolId"
- :options="classTree"
- :placeholder="formData.schoolId?'选择年级组':'请先选择学校'"
- :props="{multiple:true}"
- class="width100"
- ></el-cascader>
- </el-form-item>
- <el-row :gutter="20">
- <el-col :span="6">
- <el-form-item prop="isHeadteacher" label="班主任">
- <el-switch v-model="formData.isHeadteacher"></el-switch>
- </el-form-item>
- </el-col>
- <el-col :span="18">
- <el-form-item v-if="formData.isHeadteacher" prop="headteacherClassId" label="带 班" required>
- <el-cascader
- :disabled="!formData.schoolId"
- :options="classTree"
- v-model="formData.headteacherClassId"
- :placeholder="formData.schoolId?'选择年级-班级':'请先选择学校'"
- :props="{emitPath: false}"
- class="width100"
- ></el-cascader>
- </el-form-item>
- </el-col>
- </el-row>
- </template>
- <el-row :gutter="20">
- <el-col :span="11">
- <el-form-item prop="phoneNumber" label="手机号">
- <el-input type="text" v-model="formData.phoneNumber" placeholder="请输入手机号码"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="13">
- <el-form-item prop="code" label="验证码">
- <div class="fx-row fx-bet-cen">
- <el-input type="text" v-model="formData.code" placeholder="请输入验证码" class="fx-1"></el-input>
- <el-button
- type="primary"
- class="mx-send"
- :class="{'inactive':countdown>0}"
- @click="handleSendSms"
- >{{ countdown > 0 ? `(${countdown})秒` : '获取' }}
- </el-button>
- </div>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <div class="fx-row fx-cen-cen pt20 pb40">
- <el-button type="primary" @click="handleSubmit" style="width: 180px" round v-loading="loading">保存</el-button>
- </div>
- </div>
- </div>
- </template>
- <script>
- import auth from '@/utils/auth'
- import config from '@/common/mx-config.js'
- import transferMixin from '@/components/mx-transfer-mixin.js'
- import userValidateMixin from '@/views/components/user-validation-mixin.js'
- import { getSubjectsList } from '@/api/webApi/system'
- import { getAllGradeClasses } from '@/api/webApi/grade'
- import { getAreaSchoolAndYears, improveUserInfo, sendSms, validateSms } from '@/api/login'
- import { mapGetters } from 'vuex'
- export default {
- mixins: [transferMixin, userValidateMixin],
- data() {
- return {
- formData: {
- username: '',
- // sex: '',
- // region: '',
- year: '',
- gradeId: '',
- clazzId: '',
- subjectid: '',
- phoneNumber: '',
- code: '',
- schoolId: '',
- gradeClass: null,
- //
- sno: '',
- isHeadteacher: false,
- headteacherClassId: ''
- },
- // 选项
- loading: false,
- countdown: 0,
- timer: null,
- sexOptions: config.form.sexOptions,
- schoolOptions: [],
- yearOptions: [],
- subjectOptions: [],
- yesOrNoOptions: config.form.yesOrNoOptions
- }
- },
- computed: {
- ...mapGetters(['isFrontTeacher', 'isFrontStudent']),
- formRules() {
- return this.extractUserRules(this.formData)
- },
- groupedSchoolOptions() {
- return this.schoolOptions.groupBy(
- (sc) => sc.area,
- 'label',
- 'options'
- )
- }
- },
- mounted() {
- this.loadData()
- },
- beforeDestroy() {
- this.releaseTimer()
- },
- methods: {
- loadData() {
- // 初始可加载学校、学年、科目数据
- getAreaSchoolAndYears().then((res) => {
- this.schoolOptions = res.data.schools
- this.yearOptions = res.data.years
- })
- getSubjectsList().then((res) => {
- this.subjectOptions = res.rows.map((s) => ({
- label: s.subjectname,
- value: s.subjectid
- }))
- })
- },
- reloadClassTree() {
- if (!this.formData.schoolId) return
- getAllGradeClasses({
- schoolId: this.formData.schoolId
- }).then((res) => {
- this.formData.gradeClass = {}
- this.rawClassTree = res.data
- // 挂载动态属性,用于表单校验
- this.rawClassTree.forEach(
- (grade) => (this.formData.gradeClass[grade.name] = [])
- )
- })
- },
- handleSchoolChange(e) {
- this.reloadClassTree()
- },
- handleSendSms() {
- if (this.countdown > 0) return // in lock
- this.$refs.form.clearValidate() // 需要传空数组
- this.$refs.form.validateField(['phoneNumber'], (err) => {
- if (err) return
- this.beginCountDown()
- sendSms({
- mobile: this.formData.phoneNumber,
- smsType: 1
- }).then((res) => {
- this.msgSuccess('验证码已发送')
- })
- })
- },
- handleSubmit() {
- this.$refs.form.validate().then((_) => {
- this.loading = true
- const validateData = {
- mobile: this.formData.phoneNumber,
- code: this.formData.code
- }
- validateSms(validateData)
- .then((_) => {
- // 从formData到提交结构还需要轻微转换
- const postData = this.formDataToPostData(
- this.formData,
- this.rawClassTree
- )
- console.log(
- 'sms code valid & will post data',
- postData
- )
- improveUserInfo(postData)
- .then((res) => {
- // reset login token
- auth.setToken(res.data.token)
- this.$store.dispatch('GetInfo').then((_) => {
- // to index page
- this.$emit('completed')
- })
- })
- .finally(() => this.loading = false)
- })
- .finally(() => this.loading = false)
- })
- },
- beginCountDown() {
- this.releaseTimer()
- this.countdown = 90
- this.timer = setInterval((_) => {
- if (this.countdown == 0) {
- this.releaseTimer()
- } else {
- this.countdown -= 1
- }
- }, 1000)
- },
- releaseTimer() {
- if (this.timer) {
- clearInterval(this.timer)
- this.timer = null
- }
- }
- }
- }
- </script>
- <style scoped>
- .notice {
- color: #f88f7b;
- font-size: 26 rpx;
- text-align: center;
- }
- .mx-send {
- width: 60px;
- margin-left: 10px;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .mx-send.inactive {
- background-color: #aaaaaa;
- border-color: #aaaaaa;
- }
- </style>
|