[add] 注册页面,分标委在研项目

This commit is contained in:
zhaoxiao
2021-12-14 14:58:03 +08:00
parent a215332de6
commit 3343f87335
13 changed files with 1512 additions and 519 deletions
@@ -25,7 +25,6 @@
<a-table
ref="table"
rowKey="id"
:scroll="{x: 1200}"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
@@ -108,7 +107,8 @@ export default {
this.$router.push({
path: '/subBidCommittee/SubBidCommitteeDetailPage',
query: {
id: record.id
id: record.id,
abbreviation: record.abbreviation
}
})
},
@@ -19,7 +19,36 @@
<!-- 在研项目-->
<div class="under-study basic-box">
<h3 class="title">在研项目</h3>
<under-study-project-list></under-study-project-list>
<a-table
ref="table"
rowKey="id"
size="middle"
:scroll="{x: 1200}"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
class="j-table-force-nowrap">
<template slot="text" slot-scope="text">
<j-ellipsis :value="text" :length="18"></j-ellipsis>
</template>
<!-- 立项文件-->
<span slot="project-approval" class="action-span-cell" slot-scope="text, record">
<a @click="viewProjectApproval(record)">查看</a>
</span>
<!-- 征求意见-->
<span slot="advice" class="action-span-cell" slot-scope="text, record">
<a @click="viewAdvice(record)">查看</a>
</span>
<!-- 送审材料-->
<span slot="review-material" class="action-span-cell" slot-scope="text, record">
<a @click="viewReviewMaterial(record)">查看</a>
</span>
</a-table>
</div>
<!-- 分标委会议-->
@@ -34,18 +63,74 @@
<file-list ref="fileList"></file-list>
</div>
</a-card>
<committee-under-study-files-modal ref="filesModal"></committee-under-study-files-modal>
</div>
</template>
<script>
import { getSubBidCommitteeDetail } from '@api/incomePaymentsApi'
import UnderStudyProjectList from '@comp/detailPage/UnderStudyProjectList'
import { getSubBidCommitteeDetail, getCommitteeUnderStudyProject } from '@api/incomePaymentsApi'
import MeetingList from '@comp/detailPage/MeetingList'
import FileList from '@comp/detailPage/FileList'
import CommitteeUnderStudyFilesModal from '@views/subBidCommittee/modules/CommitteeUnderStudyFilesModal'
const columns = [
{
title: '序号',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: function (t, r, index) {
return parseInt(index) + 1
}
}, {
title: '项目名称',
align: 'center',
dataIndex: 'projectName',
scopedSlots: { customRender: 'text' }
}, {
title: '计划号',
align: 'center',
dataIndex: 'planNo',
scopedSlots: { customRender: 'text' }
}, {
title: '起草单位',
align: 'center',
dataIndex: 'draftCompany',
scopedSlots: { customRender: 'text' }
}, {
title: '项目进度',
align: 'center',
dataIndex: 'projectSchedule',
scopedSlots: { customRender: 'text' }
}, {
title: '立项文件',
align: 'center',
width: 100,
fixed: 'right',
dataIndex: 'FILE_LIST10',
scopedSlots: { customRender: 'project-approval' }
}, {
title: '征求意见',
align: 'center',
width: 100,
fixed: 'right',
dataIndex: 'FILE_LIST20',
scopedSlots: { customRender: 'advice' }
}, {
title: '送审材料',
align: 'center',
width: 100,
fixed: 'right',
dataIndex: 'FILE_LIST30',
scopedSlots: { customRender: 'review-material' }
}
]
export default {
name: 'SubBidCommitteeDetailPage',
components: { UnderStudyProjectList, MeetingList, FileList },
components: { MeetingList, FileList, CommitteeUnderStudyFilesModal },
data() {
return {
basicLoading: false,
@@ -53,14 +138,31 @@ export default {
committeeDetail: {},
// 文件数据
fileList: [],
// 在研项目
columns,
dataSource: [],
/* 分页参数 */
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30', '50', '100'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' 共' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
loading: false
}
},
created() {
this.getCommitteeDetail()
this.getUnderStudyProjectList()
},
methods: {
/**
* 获取分标委详情数据
* 获取基本信息、其他分发资料数据
*/
getCommitteeDetail() {
if (!this.$route.query.id) {
@@ -86,7 +188,68 @@ export default {
this.$refs.fileList.loading = false
})
})
}
},
/**
* 获取在研项目
*/
getUnderStudyProjectList() {
let param = {
abbreviation: this.$route.query.abbreviation
}
getCommitteeUnderStudyProject(param).then(res => {
if (res.success) {
this.dataSource = res.result.result.records
if (res.result.result.total) {
this.ipagination.total = res.result.result.total
} else {
this.ipagination.total = 0
}
}
})
},
/**
* 查看立项文件
* @param record
*/
viewProjectApproval(record) {
this.$refs.filesModal.title = '立项文件'
this.$refs.filesModal.dataSource = record.FILE_LIST10
this.$refs.filesModal.visible = true
},
/**
* 查看征求意见
* @param record
*/
viewAdvice(record) {
this.$refs.filesModal.title = '征求意见'
this.$refs.filesModal.dataSource = record.FILE_LIST20
this.$refs.filesModal.visible = true
},
/**
* 查看送审材料
* @param record
*/
viewReviewMaterial(record) {
this.$refs.filesModal.title = '送审材料'
this.$refs.filesModal.dataSource = record.FILE_LIST30
this.$refs.filesModal.visible = true
},
/**
* 分页变化
* @param pagination
* @param filters
* @param sorter
*/
handleTableChange(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
//TODO 筛选
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field
this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc'
}
this.ipagination = pagination
this.getUnderStudyProjectList()
},
}
}
</script>
@@ -130,6 +293,7 @@ export default {
.file-title {
display: flex;
align-items: center;
span {
margin-left: 10px;
margin-bottom: 5px;
@@ -0,0 +1,118 @@
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
:confirmLoading="confirmLoading"
switchFullscreen
@cancel="handleCancel"
cancelText="关闭">
<!-- table表格区域-->
<div>
<a-table
ref="table"
size="middle"
bordered
:columns="columns"
:dataSource="dataSource"
:pagination="false"
:loading="confirmLoading"
class="j-table-force-nowrap">
<template slot="text" slot-scope="text">
<j-ellipsis :value="text" :length="18"></j-ellipsis>
</template>
<!-- 时间戳转时间-->
<template slot="time" slot-scope="text">
<j-ellipsis :value="processingTimestamp(text)" :length="20"></j-ellipsis>
</template>
<!-- 操作-->
<span slot="action" class="action-span-cell" slot-scope="text, record">
<a @click="handleDownload(record)">下载</a>
<a @click="handlePreview(record)">查看</a>
</span>
</a-table>
</div>
<template slot="footer">
<a-button key="back" @click="handleCancel">关闭</a-button>
</template>
</j-modal>
</template>
<script>
import { downloadFile } from '@api/manage'
import Vue from 'vue'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import { processingTimestamp } from '@/utils/util'
const columns = [
{
title: '文件名',
align: 'center',
dataIndex: 'FILE_NAME',
scopedSlots: { customRender: 'text' }
}, {
title: '上传时间',
align: 'center',
dataIndex: 'CREAT_TIME',
scopedSlots: { customRender: 'time' }
}, {
title: '操作',
align: 'center',
dataIndex: 'action',
width: 160,
scopedSlots: { customRender: 'action' }
}
]
export default {
name: 'CommitteeUnderStudyFilesModal',
data() {
return {
title: '操作',
width: 800,
visible: false,
confirmLoading: false,
columns,
dataSource: []
}
},
methods: {
processingTimestamp,
/**
* 下载
* @param record
*/
handleDownload(record) {
let param = {
fileId: record.FILE_ID,
fileName: record.FILE_NAME
}
downloadFile(`/payResearchProject/payResearchProject/downLoad`, record.FILE_NAME, param)
},
/**
* 预览
* @param record
*/
handlePreview(record) {
if (record && record.FILE_ID) {
const fileFullUrl = `${ window._CONFIG['domianWebSocketURL'] }/sys/common/download/${ record.FILE_ID }?token=${ Vue.ls.get(ACCESS_TOKEN) }&fullfilename=${ record.FILE_NAME }`
let url = `${ window._CONFIG['onlinePreviewDomainURL'] }?url=${ encodeURIComponent(fileFullUrl) }`
// let url = `${window._CONFIG['onlinePreviewDomainURL']}?url=${encodeURIComponent(fileFullUrl)}`
window.open(url)
}
},
handleCancel() {
this.dataSource = []
this.visible = false
}
}
}
</script>
<style scoped lang="less">
@import '~@assets/less/common.less';
</style>
+19 -7
View File
@@ -128,16 +128,19 @@
<!-- 切换登录方式-->
<a-col :span="4">
<a-form-item>
<span @click="switchingLoginMode" class="forget-password" style="margin-left: 5px; color: #BFBFBF;">
{{ isVerificationCodeLogin ? '账号密码登录' : '手机验证码登录' }}
</span>
<div @click="handleRegister" class="forget-password" style="margin-left: 5px;">注册</div>
</a-form-item>
</a-col>
<a-col :span="3">
</a-col>
<a-col :span="5" style="text-align: right;">
<a-col :span="4">
<a-form-item>
<span @click='forgetPassword' class="forget-password" style="float: right;color: #BFBFBF;">
<div @click="switchingLoginMode" class="forget-password" style="text-align: center;">
{{ isVerificationCodeLogin ? '账号密码登录' : '手机验证码登录' }}
</div>
</a-form-item>
</a-col>
<a-col :span="4" style="text-align: right;">
<a-form-item>
<span @click='forgetPassword' class="forget-password" style="float: right;">
忘记密码 <img style='height: 14px' src='../../assets/wenhao.png' alt=''>
</span>
</a-form-item>
@@ -413,6 +416,14 @@ export default {
// 密码禁止粘贴
handleOperate() {
return false
},
/**
* 注册
*/
handleRegister() {
this.$router.push({
path: 'register'
})
}
}
}
@@ -493,6 +504,7 @@ export default {
.forget-password {
cursor: pointer;
color: #BFBFBF;
}
}
+545 -345
View File
@@ -1,281 +1,400 @@
<template>
<div class="main user-layout-register">
<h3><span>注册</span></h3>
<a-form ref="formRegister" :autoFormCreate="(form)=>{this.form = form}" id="formRegister">
<a-form-item
fieldDecoratorId="username"
:fieldDecoratorOptions="{rules: [{ required: false}, { validator: this.checkUsername }]}">
<a-input size="large" type="text" autocomplete="false" placeholder="请输入用户名"></a-input>
</a-form-item>
<a-popover placement="rightTop" trigger="click" :visible="state.passwordLevelChecked">
<template slot="content">
<div :style="{ width: '240px' }">
<div :class="['user-register', passwordLevelClass]">强度:<span>{{ passwordLevelName }}</span></div>
<a-progress :percent="state.percent" :showInfo="false" :strokeColor=" passwordLevelColor "/>
<div style="margin-top: 10px;">
<span>请至少输入 8 个字符。请不要使用容易被猜到的密码。</span>
</div>
<a-card :bordered="false" style="width: 100%;height: 100%;text-align: left;">
<div class='alteration-head logo'>
<router-link :to="{name:'dashboard'}">
<img src="~@/assets/logo.png" alt="logo">
<h1>汽车标准化工作平台</h1>
</router-link>
</div>
<div class='alteration-center'>
<div class='alteration-content' >
<a-form :form="form">
<span class='setPassword'>注册</span>
<div class="steps-box">
<a-steps :current="current">
<a-step v-for="item in steps" :key="item.title" :title="item.title"/>
</a-steps>
</div>
<!-- 设置密码部分-->
<div v-show="current === 0">
<a-row>
<a-col :span='22'>
<a-form-item
label="手机号"
:labelCol="{span: 5}"
:wrapperCol="{span: 19}"
>
<a-input
type="text"
v-decorator="['phone', validatorRules.phone]"
placeholder="请输入手机号">
</a-input>
</a-form-item>
</a-col>
<a-col :span='6'></a-col>
</a-row>
<a-row>
<a-col :span='22'>
<a-form-item
class='captcha'
label="验证码"
:labelCol="{span: 5}"
:wrapperCol="{span: 19}">
<a-input
v-decorator="['captcha', validatorRules.captcha]"
type="text"
autocomplete="new-password"
placeholder="请输入验证码">
</a-input>
<a-button
tabindex="-1"
size="default"
:disabled="state.smsSendBtn"
@click.stop.prevent="getCaptcha"
v-text="!state.smsSendBtn && '获取验证码' || (state.time+' s')"></a-button>
</a-form-item>
</a-col>
<a-col :span='6'></a-col>
</a-row>
<a-row>
<a-col :span='22'>
<a-form-item
label="新密码"
:labelCol="{span: 5}"
:wrapperCol="{span: 19}">
<a-input-password
placeholder="请输入新密码"
v-decorator="['password', validatorRules.password]"
autocomplete="new-password"
@paste.native.capture.prevent="handleOperate"
type="password">
</a-input-password>
</a-form-item>
</a-col>
<a-col :span='6'></a-col>
</a-row>
<a-row>
<a-col :span='22'>
<a-form-item
label="确认密码"
:labelCol="{span: 5}"
:wrapperCol="{span: 19}">
<a-input-password
placeholder="请输入确认密码"
v-decorator="['confirmPassword', validatorRules.confirmPassword]"
type="password"
@paste.native.capture.prevent="handleOperate"
autocomplete="new-password">
</a-input-password>
</a-form-item>
</a-col>
<a-col :span='6'></a-col>
</a-row>
</div>
</template>
<a-form-item
fieldDecoratorId="password"
:fieldDecoratorOptions="{rules: [{ required: false}, { validator: this.handlePasswordLevel }]}">
<a-input size="large" type="password" @click="handlePasswordInputClick" autocomplete="false" placeholder="至少8位密码,区分大小写"></a-input>
</a-form-item>
</a-popover>
<a-form-item
fieldDecoratorId="password2"
:fieldDecoratorOptions="{rules: [{ required: false}, { validator: this.handlePasswordCheck }]}">
<a-input size="large" type="password" autocomplete="false" placeholder="确认密码"></a-input>
</a-form-item>
<!-- <a-form-item-->
<!-- fieldDecoratorId="email">-->
<!-- <a-input size="large" type="text" placeholder="邮箱"></a-input>-->
<!-- </a-form-item>-->
<a-form-item
fieldDecoratorId="mobile"
:fieldDecoratorOptions="{rules: [{ required: false}, { validator: this.handlePhoneCheck }]}">
<a-input size="large" placeholder="11 位手机号">
<a-select slot="addonBefore" size="large" defaultValue="+86">
<a-select-option value="+86">+86</a-select-option>
<a-select-option value="+87">+87</a-select-option>
</a-select>
</a-input>
</a-form-item>
<!--<a-input-group size="large" compact>
<a-select style="width: 20%" size="large" defaultValue="+86">
<a-select-option value="+86">+86</a-select-option>
<a-select-option value="+87">+87</a-select-option>
</a-select>
<a-input style="width: 80%" size="large" placeholder="11 位手机号"></a-input>
</a-input-group>-->
<a-row :gutter="16">
<a-col class="gutter-row" :span="16">
<a-form-item
fieldDecoratorId="captcha"
:fieldDecoratorOptions="{rules: [{ required: false}, { validator: this.handleCaptchaCheck }]}">
<a-input size="large" type="text" placeholder="验证码">
<a-icon slot="prefix" type="mail" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
</a-col>
<a-col class="gutter-row" :span="8">
<a-button
class="getCaptcha"
size="large"
:disabled="state.smsSendBtn"
@click.stop.prevent="getCaptcha"
v-text="!state.smsSendBtn && '获取验证码'||(state.time+' s')"></a-button>
</a-col>
</a-row>
<a-form-item>
<a-button
size="large"
type="primary"
htmlType="submit"
class="register-button"
:loading="registerBtn"
@click.stop.prevent="handleSubmit"
:disabled="registerBtn">注册
</a-button>
<router-link class="login" :to="{ name: 'login' }">使用已有账户登录</router-link>
</a-form-item>
</a-form>
</div>
<!-- 完善信息部分-->
<div v-show="current===1">
<a-row>
<a-col :xl="12" :sm="24">
<a-form-item
label="企业名称"
:labelCol="labelCol"
:wrapperCol="wrapperCol">
<company-select placeholder="请选择企业"
v-decorator="['chargeCompany',validatorRules.chargeCompany]"
:maxLength='50'></company-select>
</a-form-item>
</a-col>
<a-col :xl="12" :sm="24">
<a-form-item
label="姓名"
:labelCol="labelCol"
:wrapperCol="wrapperCol">
<a-input
type="text"
v-decorator="['phone', validatorRules.phone]"
placeholder="请输入姓名">
</a-input>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :xl="12" :sm="24">
<a-form-item
label="性别"
:labelCol="labelCol"
:wrapperCol="wrapperCol">
<j-dict-select-tag
v-decorator="['gender']"
:triggerChange="true"
placeholder="请选择性别"
dictCode="sex"/>
</a-form-item>
</a-col>
<a-col :xl="12" :sm="24">
<a-form-item
label="职务"
:labelCol="labelCol"
:wrapperCol="wrapperCol">
<a-input
type="text"
v-decorator="['phone', validatorRules.phone]"
placeholder="请输入职务">
</a-input>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :xl="12" :sm="24">
<a-form-item
label="手机号"
:labelCol="labelCol"
:wrapperCol="wrapperCol">
<a-input
type="text"
v-decorator="['phone', validatorRules.phone]"
placeholder="请输入手机号">
</a-input>
</a-form-item>
</a-col>
<a-col :xl="12" :sm="24">
<a-form-item
label="邮箱"
:labelCol="labelCol"
:wrapperCol="wrapperCol">
<a-input
type="text"
v-decorator="['phone', validatorRules.phone]"
placeholder="请输入邮箱">
</a-input>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :xl="12" :sm="24">
<a-form-item
label="通讯地址"
:labelCol="labelCol"
:wrapperCol="wrapperCol">
<a-input
type="text"
v-decorator="['phone', validatorRules.phone]"
placeholder="请输入通讯地址">
</a-input>
</a-form-item>
</a-col>
<a-col :xl="12" :sm="24">
<a-form-item
label="邮政编码"
:labelCol="labelCol"
:wrapperCol="wrapperCol">
<a-input
type="text"
v-decorator="['phone', validatorRules.phone]"
placeholder="请输入邮政编码">
</a-input>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col>
<a-form-item label="备注" :labelCol="remarksLabelCol" :wrapperCol="remarksWrapperCol">
<a-textarea
placeholder="请输入备注"
v-decorator="['remarks']"
:auto-size="{ minRows: 3, maxRows: 6 }"
:maxLength='200'
@change="e => {e.target.value = (e.target.value + '').trim()}"/>
</a-form-item>
</a-col>
</a-row>
</div>
</a-form>
<div class="btn">
<template v-if="current === 0">
<a-button :loading="loading" type="primary" @click="toNextStep" style="margin-left:20px">下一步</a-button>
<a-button @click='cancel'>取消</a-button>
</template>
<template v-if="current === 1">
<a-button :loading="loading" type="primary" @click="submit" style="margin-left:20px">提交</a-button>
<a-button @click='prev'>上一步</a-button>
</template>
</div>
</div>
</div>
</a-card>
</template>
<script>
import {mixinDevice} from '@/utils/mixin.js'
// import {getSmsCaptcha} from '@/api/login'
import { postAction} from '@/api/manage'
import {checkOnlyUser} from '@/api/api'
import { mapActions } from 'vuex'
import { JSEncrypt } from 'jsencrypt'
import { getAction, postAction } from '@api/manage'
import { getRSAPublicKey } from '@api/login'
import CompanySelect from '@comp/company/CompanySelect'
const levelNames = {
0: '低',
1: '低',
2: '中',
3: '强'
}
const levelClass = {
0: 'error',
1: 'error',
2: 'warning',
3: 'success'
}
const levelColor = {
0: '#ff0000',
1: '#ff0000',
2: '#ff7e05',
3: '#52c41a',
}
export default {
name: 'Register',
components: {},
mixins: [mixinDevice],
data() {
return {
form: null,
state: {
time: 60,
smsSendBtn: false,
passwordLevel: 0,
passwordLevelChecked: false,
percent: 10,
progressColor: '#FF0000'
export default {
name: 'Register',
components: { CompanySelect },
mixins: [],
data() {
return {
form: this.$form.createForm(this),
loading: false,
labelCol: {
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 18 }
},
remarksLabelCol: {
xs: { span: 24 },
sm: { span: 3 }
},
remarksWrapperCol: {
xs: { span: 24 },
sm: { span: 21 }
},
validatorRules: {
phone: {
rules: [
{ required: true, message: '请输入手机号!' }, { validator: this.validatePhone }],
validateTrigger: 'blur'
},
registerBtn: false
}
},
computed: {
passwordLevelClass() {
return levelClass[this.state.passwordLevel]
},
passwordLevelName() {
return levelNames[this.state.passwordLevel]
},
passwordLevelColor() {
return levelColor[this.state.passwordLevel]
}
},
methods: {
checkUsername(rule, value, callback) {
if(!value){
callback(new Error('请输入用户名'))
}else{
var params = {
username: value,
}
checkOnlyUser(params).then((res) => {
if (res.success) {
callback()
} else {
callback('用户名已存在!')
}
})
}
},
handleEmailCheck(rule, value, callback) {
var params = {
email: value,
}
checkOnlyUser(params).then((res) => {
if (res.success) {
callback()
} else {
callback('邮箱已存在!')
}
})
},
handlePasswordLevel(rule, value, callback) {
let level = 0
let reg = /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,./]).{8,}$/
if (!reg.test(value)) {
callback(new Error('密码由8位数字、大小写字母和特殊符号组成!'))
}
// 判断这个字符串中有没有数字
if (/[0-9]/.test(value)) {
level++
}
// 判断字符串中有没有字母
if (/[a-zA-Z]/.test(value)) {
level++
}
// 判断字符串中有没有特殊符号
if (/[^0-9a-zA-Z_]/.test(value)) {
level++
}
this.state.passwordLevel = level
this.state.percent = level * 30
if (level >= 2) {
if (level >= 3) {
this.state.percent = 100
}
callback()
} else {
if (level === 0) {
this.state.percent = 10
}
callback(new Error('密码强度不够'))
}
},
handlePasswordCheck(rule, value, callback) {
let password = this.form.getFieldValue('password')
//console.log('value', value)
if (value === undefined) {
callback(new Error('请输入密码'))
}
if (value && password && value.trim() !== password.trim()) {
callback(new Error('两次密码不一致'))
}
callback()
},
handleCaptchaCheck(rule, value, callback){
if(!value){
callback(new Error('请输入验证码'))
}else{
callback()
}
},
handlePhoneCheck(rule, value, callback) {
var reg=/^1[3456789]\d{9}$/
if(!reg.test(value)){
callback(new Error('请输入正确手机号'))
}else{
var params = {
phone: value,
}
checkOnlyUser(params).then((res) => {
if (res.success) {
callback()
} else {
callback('手机号已存在!')
}
})
}
},
handlePasswordInputClick() {
if (!this.isMobile()) {
this.state.passwordLevelChecked = true
return
}
this.state.passwordLevelChecked = false
},
handleSubmit() {
this.form.validateFields((err, values) => {
if (!err) {
var register = {
username: values.username,
password: values.password,
phone: values.mobile,
smscode: values.captcha
captcha: {
rules: [{ required: true, message: '请输入验证码!' }],
validateTrigger: 'blur'
},
password: {
rules: [
{ required: true, message: '请输入新密码!' },
{
pattern: /^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,.\/]).{8,}$/,
message: '密码由8位及以上数字、大小写字母和特殊符号组成!'
}
postAction('/sys/user/register', register).then((res) => {
if (!res.success) {
this.registerFailed(res.message)
} else {
this.$router.push({name: 'registerResult', params: {...values}})
}
})
}
})
],
validateTrigger: 'blur'
},
confirmPassword: {
rules: [
{ required: true, message: '请输入确认密码!' },
{
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,./]).{8,30}$/,
message: '密码由8位及以上数字、大小写字母和特殊符号组成!'
},
{ validator: this.handlePasswordCheck }
],
validateTrigger: 'blur'
}
},
getCaptcha(e) {
e.preventDefault()
let that = this
this.form.validateFields(['mobile'], {force: true}, (err, values) => {
if (!err) {
state: {
time: 60,
smsSendBtn: false
},
userList: {},
temporaryUserInfo: null, // 临时用户数据
// 默认步骤
current: 1,
steps: [
{ title: '设置密码' },
{ title: '完善信息' }
]
}
},
created() {
document.title = '汽车标准化工作平台'
},
methods: {
...mapActions(['FirstPhoneLogin']),
/**
* 下一步
*/
toNextStep() {
this.current++
},
prev() {
this.current--
},
submit() {
let that = this
that.loading = true
this.form.validateFields((err, values) => {
if (!err) {
let params = {}
params.rsaPublicKey = this.rsaPublicKey
let encrypt = new JSEncrypt()
encrypt.setPublicKey(params.rsaPublicKey)
let url = ''
params.newPassword = encrypt.encrypt(values.password)
// 初次登录用password字段存了token
params.password = that.temporaryUserInfo.result.token
url = '/company/changePasswordWithToken'
params.verifyPassword = encrypt.encrypt(values.confirmPassword)
postAction(url, params).then((res) => {
if (res.success) {
that.loading = false
that.$router.go(-1)
} else {
this.passwordFailed(res.message)
that.loading = false
}
})
} else {
that.loading = false
}
})
},
cancel() {
this.$router.go(-1)
},
passwordFailed(err) {
this.$notification['error']({
message: '更改密码失败',
description: err,
duration: 4
})
},
validatePhone(rule, value, callback) {
if (value) {
var myreg = /^[1][3,4,5,7,8][0-9]{9}$/
if (!myreg.test(value)) {
callback('请输入正确的手机号')
} else {
callback()
}
} else {
callback()
}
},
handlePasswordCheck(rule, value, callback) {
let password = this.form.getFieldValue('password')
if (value && password && value.trim() !== password.trim()) {
callback(new Error('两次密码不一致'))
}
callback()
},
getCaptcha(e) {
e.preventDefault()
let that = this
let phone = that.form.getFieldValue('phone')
if (!phone) {
this.cmsFailed('手机号不能为空!')
return
}
this.form.validateFields(['phone'], { force: true }, (err) => {
if (!err) {
const hide = this.$message.loading('验证码发送中..', 0)
let smsParams = {
phone: phone,
// 忘记密码是2
codeType: 2
}
getAction('/company/sendVerificationCode', smsParams).then(res => {
if (!res.success) {
setTimeout(hide, 1)
this.cmsFailed(res.message)
} else {
this.state.smsSendBtn = true
let interval = window.setInterval(() => {
if (that.state.time-- <= 0) {
@@ -284,97 +403,178 @@
window.clearInterval(interval)
}
}, 1000)
const hide = this.$message.loading('验证码发送中..', 0)
const params = {
mobile: values.mobile,
smsmode: '1'
}
postAction('/sys/sms', params).then((res) => {
if (!res.success) {
this.registerFailed(res.message)
setTimeout(hide, 0)
}
setTimeout(hide, 500)
}).catch(err => {
setTimeout(hide, 1)
clearInterval(interval)
that.state.time = 60
that.state.smsSendBtn = false
this.requestFailed(err)
})
}
}
)
},
registerFailed(message) {
this.$notification['error']({
message: '注册失败',
description: message,
duration: 2,
})
},
requestFailed(err) {
this.$notification['error']({
message: '错误',
description: ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试',
duration: 4,
})
this.registerBtn = false
},
setTimeout(hide, 500)
})
this.getPublicKey()
}
})
},
watch: {
'state.passwordLevel'(val) {
console.log(val)
}
cmsFailed(err) {
this.$notification['error']({
message: '验证错误',
description: err,
duration: 4
})
},
getPublicKey() {
getRSAPublicKey().then(res => {
this.rsaPublicKey = res.result
})
},
// 密码禁止粘贴
handleOperate() {
return false
}
}
}
</script>
<style lang="less">
.user-register {
<style scoped lang="less">
/deep/ .ant-card {
width: 100%;
}
&.error {
color: #ff0000;
}
/deep/ .ant-card-body {
padding: 0 !important;
height: 100%;
background: #F0F2F5;
}
&.warning {
color: #ff7e05;
}
.alteration-center {
min-height: calc(100% - 60px);
display: flex;
justify-content: center;
align-items: center;
background: #F0F2F5;
}
&.success {
color: #52c41a;
}
.alteration-content {
//margin: auto;
width: 1000px;
flex-direction: column;
display: flex;
justify-content: center;
align-items: center;
background: #fff;
padding-bottom: 40px;
.setPassword {
font-size: 26px;
display: block;
background: #fff;
height: 60px;
text-align: center !important;
margin-top: 30px;
}
}
.user-layout-register {
.ant-input-group-addon:first-child {
background-color: #fff;
/deep/ .ant-form {
width: 700px;
}
.alteration-head {
//position: absolute;
//top: 0;
width: 100%;
background: #069F99;
height: 60px;
}
.logo {
box-shadow: none !important;
transition: background 300ms;
height: 60px;
line-height: 60px;
padding-left: 12px;
a {
color: white;
&:hover {
color: rgba(255, 255, 255, 0.8);
}
}
</style>
<style lang="less" scoped>
.user-layout-register {
& > h3 {
h1 {
margin-left: 12px;
color: #fff;
font-size: 16px;
margin-bottom: 20px;
}
.getCaptcha {
display: block;
width: 100%;
height: 40px;
}
.register-button {
width: 50%;
}
.login {
float: right;
line-height: 40px;
display: inline-block;
}
}
}
/deep/ .ant-row {
margin-bottom: 20px !important;
height: 30px;
}
/deep/ .ant-form-item-label {
height: 40px;
line-height: 40px;
}
/deep/ .ant-input {
border-radius: 30px;
height: 30px;
border: 1px solid #E6E3E3;
padding: 10px;
}
/deep/ .ant-select {
border-radius: 30px;
height: 30px;
border: 1px solid #E6E3E3;
}
/deep/ .ant-select-selection {
border: none;
border-radius: 30px;
height: 28px;
}
/deep/ .ant-select-selection__rendered {
border: none;
border-radius: 30px;
height: 28px;
line-height: 28px;
}
/deep/ .ant-btn-icon-only {
height: 30px;
width: 30px;
border-radius: 30px;
}
.btn {
padding-top: 20px;
/deep/ button {
border-radius: 30px;
margin: 0 20px;
width: 80px;
}
.ant-btn-primary {
background: #069F99;
border: none;
}
}
.captcha {
position: relative;
/deep/ button {
border: none;
color: #069F99;
position: absolute;
right: 10px;
top: -6px;
box-shadow: none;
background: none;
}
}
.steps-box {
padding: 30px 25%;
}
</style>