提交 32fbd88c authored 作者: 王鹏飞's avatar 王鹏飞

新增报名申请

上级 d28035fc
......@@ -5,10 +5,10 @@ module.exports = {
// apiBaseURL: '//demo-login.ezijing.com/',
webpack: {
externals: {
'CKEDITOR': 'window.CKEDITOR',
'Base64': 'window.Base64',
'md5': 'window.md5',
'regeneratorRuntime': 'window.regeneratorRuntime'
CKEDITOR: 'window.CKEDITOR',
Base64: 'window.Base64',
md5: 'window.md5',
regeneratorRuntime: 'window.regeneratorRuntime'
},
devServer: {
proxy: {
......@@ -31,10 +31,8 @@ module.exports = {
}
}
},
ProvidePlugin: {
},
ProvidePlugin: {},
others: {
projectId: '1006'
}
}
......@@ -6,16 +6,14 @@ module.exports = {
isEnableToIphoneDebugger: false,
webpack: {
externals: {
'CKEDITOR': 'window.CKEDITOR',
'Base64': 'window.Base64',
'md5': 'window.md5',
'regeneratorRuntime': 'window.regeneratorRuntime'
CKEDITOR: 'window.CKEDITOR',
Base64: 'window.Base64',
md5: 'window.md5',
regeneratorRuntime: 'window.regeneratorRuntime'
}
},
ProvidePlugin: {
},
ProvidePlugin: {},
others: {
projectId: '1006'
}
}
......@@ -7,16 +7,14 @@ module.exports = {
isEnableToIphoneDebugger: true,
webpack: {
externals: {
'CKEDITOR': 'window.CKEDITOR',
'Base64': 'window.Base64',
'md5': 'window.md5',
'regeneratorRuntime': 'window.regeneratorRuntime'
CKEDITOR: 'window.CKEDITOR',
Base64: 'window.Base64',
md5: 'window.md5',
regeneratorRuntime: 'window.regeneratorRuntime'
}
},
ProvidePlugin: {
},
ProvidePlugin: {},
others: {
projectId: '1006'
}
}
......@@ -234,6 +234,14 @@
"@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-syntax-jsx": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz",
"integrity": "sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g==",
"requires": {
"@babel/helper-plugin-utils": "^7.10.4"
}
},
"@babel/plugin-transform-arrow-functions": {
"version": "7.10.4",
"resolved": "https://registry.npm.taobao.org/@babel/plugin-transform-arrow-functions/download/@babel/plugin-transform-arrow-functions-7.10.4.tgz",
......@@ -340,22 +348,37 @@
}
},
"@ezijing/vue-form": {
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/@ezijing/vue-form/-/vue-form-0.1.15.tgz",
"integrity": "sha512-ZBjXlCVQdX4sJPom/PhprzXvjohO5vrfKECk0+T0o50zeQ1xV51aeFXBGLwTaQH7Rcsbk4OLyYe/HEyTuTIs7Q==",
"requires": {
"axios": "^0.19.0",
"element-ui": "^2.13.0"
}
},
"@ezijing/vue-passport": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@ezijing/vue-passport/-/vue-passport-0.1.5.tgz",
"integrity": "sha512-jYiBx3b0a1UxpgDEEu+A8rPovZhUeztmokbDZ7N2W5XWB60S3dPdaEx3D7xPpcQokxlNbXUQPqdSSGh/Elqwfw==",
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@ezijing/vue-form/-/vue-form-2.0.6.tgz",
"integrity": "sha512-tTS4/ilJ7KGtsrvR6131UaZxlYzEGBV09FPSioaRGcxjzBbxS4DgwHVvY3AJIeCJWVmXkP5uPgFxVCNTbc5OQA==",
"requires": {
"axios": "^0.19.0",
"element-ui": "^2.13.0",
"md5": "^2.2.1"
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
"@vue/babel-preset-jsx": "^1.1.2",
"axios": "^0.20.0",
"core-js": "^3.6.5",
"element-ui": "^2.13.2",
"qs": "^6.9.4",
"vue": "^2.6.11"
},
"dependencies": {
"axios": {
"version": "0.20.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
"integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"core-js": {
"version": "3.6.5",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
"integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA=="
},
"follow-redirects": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
}
}
},
"@types/anymatch": {
......@@ -480,6 +503,76 @@
}
}
},
"@vue/babel-helper-vue-jsx-merge-props": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.0.0.tgz",
"integrity": "sha512-6tyf5Cqm4m6v7buITuwS+jHzPlIPxbFzEhXR5JGZpbrvOcp1hiQKckd305/3C7C36wFekNTQSxAtgeM0j0yoUw=="
},
"@vue/babel-plugin-transform-vue-jsx": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.1.2.tgz",
"integrity": "sha512-YfdaoSMvD1nj7+DsrwfTvTnhDXI7bsuh+Y5qWwvQXlD24uLgnsoww3qbiZvWf/EoviZMrvqkqN4CBw0W3BWUTQ==",
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.2.0",
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
"html-tags": "^2.0.0",
"lodash.kebabcase": "^4.1.1",
"svg-tags": "^1.0.0"
}
},
"@vue/babel-preset-jsx": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.1.2.tgz",
"integrity": "sha512-zDpVnFpeC9YXmvGIDSsKNdL7qCG2rA3gjywLYHPCKDT10erjxF4U+6ay9X6TW5fl4GsDlJp9bVfAVQAAVzxxvQ==",
"requires": {
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
"@vue/babel-plugin-transform-vue-jsx": "^1.1.2",
"@vue/babel-sugar-functional-vue": "^1.1.2",
"@vue/babel-sugar-inject-h": "^1.1.2",
"@vue/babel-sugar-v-model": "^1.1.2",
"@vue/babel-sugar-v-on": "^1.1.2"
}
},
"@vue/babel-sugar-functional-vue": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.1.2.tgz",
"integrity": "sha512-YhmdJQSVEFF5ETJXzrMpj0nkCXEa39TvVxJTuVjzvP2rgKhdMmQzlJuMv/HpadhZaRVMCCF3AEjjJcK5q/cYzQ==",
"requires": {
"@babel/plugin-syntax-jsx": "^7.2.0"
}
},
"@vue/babel-sugar-inject-h": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.1.2.tgz",
"integrity": "sha512-VRSENdTvD5htpnVp7i7DNuChR5rVMcORdXjvv5HVvpdKHzDZAYiLSD+GhnhxLm3/dMuk8pSzV+k28ECkiN5m8w==",
"requires": {
"@babel/plugin-syntax-jsx": "^7.2.0"
}
},
"@vue/babel-sugar-v-model": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.1.2.tgz",
"integrity": "sha512-vLXPvNq8vDtt0u9LqFdpGM9W9IWDmCmCyJXuozlq4F4UYVleXJ2Fa+3JsnTZNJcG+pLjjfnEGHci2339Kj5sGg==",
"requires": {
"@babel/plugin-syntax-jsx": "^7.2.0",
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
"@vue/babel-plugin-transform-vue-jsx": "^1.1.2",
"camelcase": "^5.0.0",
"html-tags": "^2.0.0",
"svg-tags": "^1.0.0"
}
},
"@vue/babel-sugar-v-on": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.1.2.tgz",
"integrity": "sha512-T8ZCwC8Jp2uRtcZ88YwZtZXe7eQrJcfRq0uTFy6ShbwYJyz5qWskRFoVsdTi9o0WEhmQXxhQUewodOSCUPVmsQ==",
"requires": {
"@babel/plugin-syntax-jsx": "^7.2.0",
"@vue/babel-plugin-transform-vue-jsx": "^1.1.2",
"camelcase": "^5.0.0"
}
},
"@vue/component-compiler-utils": {
"version": "3.2.0",
"resolved": "https://registry.npm.taobao.org/@vue/component-compiler-utils/download/@vue/component-compiler-utils-3.2.0.tgz?cache=0&sync_timestamp=1595427694165&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcomponent-compiler-utils%2Fdownload%2F%40vue%2Fcomponent-compiler-utils-3.2.0.tgz",
......@@ -2569,8 +2662,7 @@
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npm.taobao.org/camelcase/download/camelcase-5.3.1.tgz",
"integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA=",
"dev": true
"integrity": "sha1-48mzFWnhBoEd8kL3FXJaH0xJQyA="
},
"caniuse-lite": {
"version": "1.0.30001125",
......@@ -2600,11 +2692,6 @@
"integrity": "sha1-kAlISfCTfy7twkJdDSip5fDLrZ4=",
"dev": true
},
"charenc": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
},
"chokidar": {
"version": "3.4.2",
"resolved": "https://registry.npm.taobao.org/chokidar/download/chokidar-3.4.2.tgz?cache=0&sync_timestamp=1596728935229&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fchokidar%2Fdownload%2Fchokidar-3.4.2.tgz",
......@@ -3251,11 +3338,6 @@
"which": "^2.0.1"
}
},
"crypt": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
"integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
},
"crypto-browserify": {
"version": "3.12.0",
"resolved": "https://registry.npm.taobao.org/crypto-browserify/download/crypto-browserify-3.12.0.tgz",
......@@ -5679,6 +5761,11 @@
}
}
},
"html-tags": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz",
"integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos="
},
"html-webpack-plugin": {
"version": "4.4.1",
"resolved": "https://registry.npm.taobao.org/html-webpack-plugin/download/html-webpack-plugin-4.4.1.tgz",
......@@ -6160,7 +6247,8 @@
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npm.taobao.org/is-buffer/download/is-buffer-1.1.6.tgz",
"integrity": "sha1-76ouqdqg16suoTqXsritUf776L4="
"integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=",
"dev": true
},
"is-callable": {
"version": "1.2.1",
......@@ -6645,6 +6733,11 @@
"resolved": "https://registry.npm.taobao.org/lodash/download/lodash-4.17.20.tgz?cache=0&sync_timestamp=1597336097104&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz",
"integrity": "sha1-tEqbYpe8tpjxxRo1RaKzs2jVnFI="
},
"lodash.kebabcase": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
"integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY="
},
"loglevel": {
"version": "1.7.0",
"resolved": "https://registry.npm.taobao.org/loglevel/download/loglevel-1.7.0.tgz?cache=0&sync_timestamp=1598447642950&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Floglevel%2Fdownload%2Floglevel-1.7.0.tgz",
......@@ -6710,16 +6803,6 @@
"object-visit": "^1.0.0"
}
},
"md5": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
"integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
"requires": {
"charenc": "0.0.2",
"crypt": "0.0.2",
"is-buffer": "~1.1.6"
}
},
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npm.taobao.org/md5.js/download/md5.js-1.3.5.tgz",
......@@ -11445,11 +11528,15 @@
"resolved": "https://registry.npm.taobao.org/q/download/q-1.5.1.tgz",
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
},
"qrcode.vue": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-1.7.0.tgz",
"integrity": "sha512-R7t6Y3fDDtcU7L4rtqwGUDP9xD64gJhIwpfjhRCTKmBoYF6SS49PIJHRJ048cse6OI7iwTwgyy2C46N9Ygoc6g=="
},
"qs": {
"version": "6.9.4",
"resolved": "https://registry.npm.taobao.org/qs/download/qs-6.9.4.tgz",
"integrity": "sha1-kJCykNH5FyjTwi5UhDykSupatoc=",
"dev": true
"integrity": "sha1-kJCykNH5FyjTwi5UhDykSupatoc="
},
"query-string": {
"version": "4.3.4",
......@@ -13415,6 +13502,11 @@
}
}
},
"svg-tags": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
"integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q="
},
"swiper": {
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-5.4.5.tgz",
......
......@@ -67,8 +67,7 @@
"webpack-merge": "^4.2.2"
},
"dependencies": {
"@ezijing/vue-form": "^0.1.15",
"@ezijing/vue-passport": "^0.1.5",
"@ezijing/vue-form": "^2.0.6",
"animate.css": "^4.1.0",
"axios": "^0.19.2",
"cross-env": "^7.0.2",
......@@ -78,17 +77,18 @@
"lodash": "^4.17.15",
"npm": "^6.14.8",
"promise.prototype.finally": "^3.1.2",
"qrcode.vue": "^1.7.0",
"regenerator": "^0.14.4",
"swiper": "^5.4.5",
"tween.js": "^16.6.0",
"vue": "^2.6.11",
"vue-awesome-swiper": "^4.1.1",
"vue-i18n": "^8.16.0",
"vue-loader": "^15.9.1",
"vue-meta-info": "^0.1.7",
"vue-router": "^3.1.6",
"vue-scrollmagic": "^1.2.0",
"vue-template-compiler": "^2.6.11",
"vuex": "^3.1.3",
"swiper": "^5.4.5",
"vue-awesome-swiper": "^4.1.1"
"vuex": "^3.1.3"
}
}
import axios from 'axios'
import _ from 'lodash'
import qs from 'qs'
export default class API {
constructor (config) {
constructor(config) {
/* 创建一个 自定义配置axios实例 */
// 让ajax携带cookie
axios.defaults.withCredentials = true
......@@ -22,31 +23,23 @@ export default class API {
}
/* 获取当前Vue创建实例 */
getVueInstance () {
getVueInstance() {
return window.G.$instance_vue
}
/* 重新封装 请求时的执行函数 */
_request (_config = {}) {
_request(_config = {}) {
/* 具体执行请求成功后业务逻辑前,先执行该方法 */
const beforeSuccess = _config.beforeSuccess ? _config.beforeSuccess : this._reqSuccess
/* 具体执行请求失败后业务逻辑前,先执行该方法 */
const beforeFail = _config.beforeFail ? _config.beforeFail : this._reqFail
const headers = {}
_config.headers = _.assignIn(_config.headers, headers)
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
_config.headers = _.assignIn(headers, _config.headers)
/* 判别 传输方式 */
if (_config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
let str = ''
const _obj = _config.data || _config.params
for (const key in _obj) {
str += key + '=' + _obj[key] + '&'
}
str = str.substr(0, str.length - 1)
if (_config.data) {
_config.data = str
} else {
_config.params = str
}
_config.data = qs.stringify(_config.data)
}
if (_config.headers['Content-Type'] === 'multipart/form-data') {
let fr = new FormData() // eslint-disable-line
......@@ -57,8 +50,7 @@ export default class API {
_config.data = fr
}
/* 创建并根据参数发起请求 */
return this._axios(_config)
.then(beforeSuccess.bind(this), beforeFail.bind(this))
return this._axios(_config).then(beforeSuccess.bind(this), beforeFail.bind(this))
}
/**
......@@ -66,7 +58,7 @@ export default class API {
* 注意:如果不能满足需求,可在接口定义处重新实现
* @param {[object]} res 返回数据
*/
_reqSuccess (res) {
_reqSuccess(res) {
const { status, data } = res
let err = null
if (status === 200) {
......@@ -82,7 +74,7 @@ export default class API {
* 注意:如果不能满足需求,可在接口定义处重新实现
* @param {[object]} res 如果未到达 response 阶段,则无res.response
*/
_reqFail (res) {
_reqFail(res) {
let err = null
if (res.code === 'ECONNABORTED') {
err = new Error('网络超时,请稍后重试')
......@@ -97,22 +89,22 @@ export default class API {
}
/* 重新实现 get请求 */
get (url, data, config) {
get(url, data, config) {
return this._request(_.assignIn({ url, method: 'GET', params: data }, config))
}
/* 重新实现 post请求 */
post (url, data, config) {
post(url, data, config) {
return this._request(_.assignIn({ url, method: 'POST', data: data }, config))
}
/* 重新实现 put请求 */
put (url, data, config) {
put(url, data, config) {
return this._request(_.assignIn({ url, method: 'PUT', data: data }, config))
}
/* 重新实现 delete请求 */
delete (url, data, config) {
delete(url, data, config) {
return this._request(_.assignIn({ url, method: 'DELETE', params: data }, config))
}
}
import BaseAPI from '@/api/base_api'
const httpRequest = new BaseAPI(webConf)
const projectId = webConf.others.projectId
/**
* 获取用户信息
*/
export function getUser() {
return httpRequest.get('/passport/account/get-user-info')
}
/**
* 修改用户信息
*/
export function updateUser(data) {
return httpRequest.post('/usercenter/user/update-user', data)
}
/**
* 修改密码
*/
export function updatePassword(data) {
return httpRequest.post('/usercenter/user/update-pwd', data)
}
/**
* 发送验证码
*/
export function sendCode(data) {
return httpRequest.post('/usercenter/user/send-code', data)
}
/**
* 获取报名信息
*/
export function getApplication(params) {
return httpRequest.get(`/enrollment/v1.0/application-materials/${projectId}`, params)
}
/**
* 获取报名审核状态
*/
export function getApplicationStatus() {
return httpRequest.get(`/enrollment/v1.0/application-materials/profile/${projectId}`)
}
/**
* 获取支付二维码
*/
export function getOrder(params) {
return httpRequest.get(
`/enrollment/v1.0/application-materials/payment-records/request/${projectId}/APPLICATION_FEE`,
params
)
}
/**
* 检查支付状态
*/
export function checkPay(id, params) {
return httpRequest.get(
`/enrollment/v1.0/application-materials/payment-records/check-status/${projectId}/APPLICATION_FEE/${id}`,
params
)
}
/**
* 写推荐信
*/
export function addLetter(userId, letterId, data) {
return httpRequest.post(
`/enrollment/v1.0/application-materials/reco-letters/submit/${projectId}/${userId}/${letterId}/put`,
data,
{
headers: { 'Content-Type': 'application/json' }
}
)
}
/**
* 更换推荐人
*/
export function updateProvider(letterId, data) {
return httpRequest.post(
`/enrollment/v1.0/application-materials/reco-letters/change-provider/${projectId}/${letterId}/put`,
data,
{
headers: { 'Content-Type': 'application/json' }
}
)
}
/**
* 再次邀请
*/
export function sendToProvider(letterId) {
return httpRequest.get(
`/enrollment/v1.0/application-materials/reco-letters/send-invitation-to-provider/${projectId}/${letterId}`
)
}
......@@ -188,3 +188,7 @@ textarea {
user-select: text !important;
cursor: pointer;
}
:root {
--main-color: #e27f4d;
}
......@@ -8,12 +8,12 @@ export default class Before {
}
async update(to, from, next) {
const isLogin = await this.isLogin()
if (to.meta && to.meta.userRole) {
const isLogin = await this.isLogin()
if (isLogin) {
next()
} else {
next({ path: '/apply/for' })
next({ path: '/login' })
}
} else {
next()
......@@ -22,13 +22,10 @@ export default class Before {
/* 获取用户信息 */
isLogin() {
if (window.G.UserInfo && Object.keys(window.G.UserInfo.data).length > 0) {
return true
}
return cAction.Test.getInfo()
.then(res => {
if (res.code === 0) {
window.G.UserInfo = res
window.G.UserInfo = res.data
return true
} else {
return false
......
<template>
<el-button v-bind="$attrs" :disabled="currentDisabled" @click="start">{{ curretnValue }}</el-button>
</template>
<script>
export default {
name: 'Countdown',
props: {
step: { type: Number, default: 1000 },
disabled: { type: Boolean, default: false },
seconds: { type: Number, default: 60 },
defaultValue: { type: String, default: '获取验证码' }
},
data() {
return {
currentDisabled: false,
currentSeconds: 0,
timer: null
}
},
watch: {
disabled: {
immediate: true,
handler(value) {
this.currentDisabled = value
}
}
},
computed: {
curretnValue() {
const longTime = this.seconds - this.currentSeconds
return longTime < this.seconds ? `${longTime}秒后重发` : this.defaultValue
}
},
methods: {
genTimer() {
this.clearTimer()
this.timer = setInterval(() => {
this.currentSeconds++
if (this.currentSeconds === this.seconds) {
this.stop()
}
}, this.step)
},
clearTimer() {
this.timer && clearInterval(this.timer)
},
start() {
this.currentDisabled = true
this.genTimer()
this.$emit('start')
},
stop() {
this.clearTimer()
this.currentSeconds = 0
this.currentDisabled = false
this.$emit('stop')
}
}
}
</script>
<template>
<div
class="slider"
:class="{'ts-slider': navigation && (tempRoute.meta && !tempRoute.meta.details), 'bg_fff': tempRoute.meta && tempRoute.meta.details}"
:class="{
'ts-slider': navigation && tempRoute.meta && !tempRoute.meta.details,
bg_fff: tempRoute.meta && tempRoute.meta.details
}"
>
<div class="slider-body">
<div class="slider-icon" v-show="tempRoute.meta && !tempRoute.meta.details">
......@@ -19,97 +22,53 @@
></el-image>
</div>
<div class="slider-banner">
<template v-for="(item, index) in sidebar" >
<div :key="index" class="tab-item" v-if="item.path != '/apply'">
<div v-if="!item.hidden">
<template
v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"
>
<app-link
v-if="onlyOneChild.meta"
:to="resolvePath(onlyOneChild.path, item.path)"
class="app-link"
>
<span class="tab-link">{{onlyOneChild.meta.title}}</span>
</app-link>
</template>
</div>
<div v-for="item in navList" :key="item.path" class="tab-item">
<div class="app-link" :class="{ 'router-link-active': $route.path.includes(item.path) }">
<router-link tag="span" :to="item.path" class="tab-link">{{ item.title }}</router-link>
</div>
</template>
</div>
</div>
</div>
</div>
</template>
<script>
import AppLink from './Link.vue'
import path from 'path'
import { isExternal } from '@/utils/validate'
import { dyHeight } from '@/pages/homepage/mixins/index.js'
export default {
mixins: [dyHeight],
components: {
AppLink
},
data() {
this.onlyOneChild = null
return {
tempRoute: {}
tempRoute: {},
navList: [
{ title: '首页', path: '/index' },
{ title: '专业设置', path: '/profession' },
{ title: '报名申请', path: '/my' },
{ title: '最新动态', path: '/news' },
{ title: '联系我们', path: '/contact' }
]
}
},
watch: {
$route() {
this.infoRouer()
}
},
computed: {
sidebar() {
return this.$router.options.routes
$route: {
immediate: true,
handler() {
this.infoRouer()
}
}
},
methods: {
hasOneShowingChild(children = [], parent) {
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
} else {
this.onlyOneChild = item
return true
}
})
if (showingChildren.length === 1) {
return true
}
if (showingChildren.length === 0) {
this.onlyOneChild = { ...parent, path: '', noShowingChildren: true }
return true
}
return false
},
resolvePath(routePath, basePath) {
if (isExternal(routePath)) {
return routePath
}
if (isExternal(basePath)) {
return basePath
}
return path.resolve(basePath, routePath)
},
infoRouer() {
this.tempRoute = Object.assign({}, this.$route)
}
},
mounted() {
this.infoRouer()
}
}
</script>
<style lang="scss" scoped>
.logo-new-2{
.logo-new-2 {
width: 217px;
}
.logo-new-1{
.logo-new-1 {
width: 221px;
}
.slider {
......@@ -141,7 +100,7 @@ export default {
.app-link {
color: #fff;
&.router-link-active .tab-link {
color: #E27F4D !important;
color: #e27f4d !important;
}
}
......
<template>
<component :is="type" v-bind="linkProps(to)">
<slot />
</component>
</template>
<script>
import { isExternal } from '@/utils/validate'
export default {
props: {
to: {
type: String,
required: true
}
},
computed: {
isExternal() {
return isExternal(this.to)
},
type() {
if (this.isExternal) {
return 'a'
}
return 'router-link'
}
},
methods: {
linkProps(to) {
if (this.isExternal) {
return {
href: to,
target: '_blank',
rel: 'noopener'
}
}
return {
to: to
}
}
}
}
</script>
......@@ -2,7 +2,8 @@ import Vue from 'vue' // 引入vue框架
import router from './router'
import VueI18n from 'vue-i18n' // 使用 国际化
import createI18n from './assets/languages' // 国际化定义
import VueForm from '@ezijing/vue-form'
import '@ezijing/vue-form/dist/vue-form.css'
import App from './app.vue' // 初始化 vue页面
import './style.scss' // 公共样式
import MetaInfo from 'vue-meta-info'
......@@ -16,6 +17,8 @@ import './assets/css/animate.min.css'
import VueLazyComponent from '@xunlei/vue-lazy-component'
import './icons/index.js'
Vue.use(VueForm)
Vue.use(VueLazyComponent)
/* 兼容处理 start */
/* 处理低版本浏览器支持axios finally问题 */
......@@ -45,7 +48,6 @@ const before = createBefore()
router.beforeEach(async (to, from, next) => {
await store.dispatch('generateRoutes')
before.update(to, from, next)
next()
})
window.G.$instance_vue = new Vue({
......
......@@ -59,7 +59,7 @@ export default {
},
goback() {
this.$router.push({
name: 'apply-for'
name: 'apply'
})
},
transferKeep(item) {
......
......@@ -59,7 +59,7 @@ export default {
},
goback() {
this.$router.push({
name: 'apply-for'
name: 'apply'
})
},
transferKeep(item) {
......@@ -73,7 +73,7 @@ export default {
type: 'success'
})
this.$router.push({
name: 'apply-for'
name: 'apply'
})
} else {
this.$message.error(res.msg)
......
<template>
<div class="letter">
<header class="header">
<div class="inner">
<div class="logo">
<router-link to="/"
><img src="https://zws-imgs-pub.ezijing.com/static/public/a0671ced04ce75b04f2e491b555b412d.png"
/></router-link>
</div>
</div>
</header>
<nav class="nav"><h1 class="title">康博斯威尔大学蒙台梭利硕士项目推荐信</h1></nav>
<section class="content">
<el-form
:model="ruleForm"
:rules="rules"
ref="form"
label-width="100px"
:label-position="labelPosition"
@submit.native.prevent
style="max-width: 680px"
>
<el-form-item label="姓名" prop="provider_name">
<el-input v-model.trim="ruleForm.provider_name"></el-input>
</el-form-item>
<el-form-item label="推荐信内容" prop="letter_content">
<el-input type="textarea" :autosize="{ minRows: 6 }" v-model.trim="ruleForm.letter_content"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="provider_phone_number">
<el-input v-model.trim="ruleForm.provider_phone_number"></el-input>
</el-form-item>
<el-form-item label="工作单位" prop="provider_company_name">
<el-input v-model.trim="ruleForm.provider_company_name"></el-input>
</el-form-item>
<el-form-item label="职务" prop="provider_job_title">
<el-input v-model.trim="ruleForm.provider_job_title"></el-input>
</el-form-item>
</el-form>
<div class="buttons">
<el-button type="primary" @click="handleSubmit">确认提交</el-button>
</div>
</section>
<el-dialog title="推荐信提交成功" :visible.sync="dialogVisible" :center="true" width="348px">
<div style="text-align: center"><img src="../../assets/images/icon_success.png" /></div>
<template #footer>
<el-button type="primary" @click="toHome">了解项目</el-button>
</template>
</el-dialog>
</div>
</template>
<script>
import * as api from '@/api/my'
export default {
name: 'LetterIndex',
data() {
return {
ruleForm: {
provider_name: '',
letter_content: '',
provider_phone_number: '',
provider_company_name: '',
provider_job_title: ''
},
rules: {
provider_name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
letter_content: [{ required: true, message: '请输入推荐信内容', trigger: 'blur' }],
provider_phone_number: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
provider_company_name: [{ required: true, message: '请输入工作单位', trigger: 'blur' }],
provider_job_title: [{ required: true, message: '请输入职务', trigger: 'blur' }]
},
dialogVisible: false,
clientWidth: 0
}
},
computed: {
userId() {
return this.$route.params.userId
},
letterId() {
return this.$route.params.letterId
},
labelPosition() {
return this.clientWidth < 768 ? 'top' : 'left'
}
},
methods: {
// 提交
handleSubmit() {
this.$refs.form.validate().then(() => {
this.handleAddRequest()
})
},
// 提交推荐信
handleAddRequest() {
api.addLetter(this.userId, this.letterId, this.ruleForm).then(response => {
console.log(response)
const { error, message } = response
if (error.toString() === '0') {
this.dialogVisible = true
} else {
this.$message.error(message)
}
})
},
toHome() {
this.$router.push('/')
},
getClientWidth() {
this.clientWidth = document.body.clientWidth
}
},
mounted() {
this.getClientWidth()
window.addEventListener('resize', this.getClientWidth)
},
destroyed() {
window.removeEventListener('resize', this.getClientWidth)
}
}
</script>
<style lang="scss" scoped>
.letter {
.header {
background-color: #fff;
.inner {
max-width: 1000px;
margin: 0 auto;
}
.logo {
padding: 14px 0;
}
}
.nav {
background-color: #af1b40;
.title {
font-size: 24px;
font-weight: 600;
color: #fff;
line-height: 60px;
text-align: center;
}
}
.content {
max-width: 1000px;
margin: 20px auto;
padding: 20px;
background-color: #fff;
box-sizing: border-box;
}
::v-deep .el-input {
max-width: 270px;
}
::v-deep .el-form--label-top {
.el-form-item__label {
line-height: 20px;
}
.el-input {
max-width: 100%;
}
}
::v-deep .el-input__inner,
::v-deep .el-textarea__inner {
border-radius: 0;
}
.buttons {
border-top: 1px solid #f1f1f1;
padding: 20px 100px;
}
@media (max-width: 767px) {
.logo {
text-align: center;
}
.buttons {
padding: 20px 0;
.el-button {
width: 100%;
display: block;
}
}
}
}
</style>
<template>
<div class="my">
<div class="card">
<div class="result">
<div class="result-left"><img src="../../../assets/images/my_icon.png" />招生办反馈</div>
<div class="result-right">{{ result.submit_status_desc || '未收到报名信息' }}</div>
</div>
</div>
<div class="card" style="min-height: 360px">
<ul class="nav">
<li @click="toApplication"><img src="../../../assets/images/my_01.png" /></li>
<li @click="toInterview"><img src="../../../assets/images/my_02.png" /></li>
<li @click="toAdmission"><img src="../../../assets/images/my_03.png" /></li>
</ul>
<div class="progress">
<el-steps :active="activeProgress" finish-status="success" align-center>
<el-step v-for="(item, index) in 3" :key="index">
<template #title>{{ getProgressStatusText(index) }}</template>
</el-step>
</el-steps>
</div>
</div>
</div>
</template>
<script>
import * as api from '@/api/my'
export default {
name: 'AppHome',
data() {
return {
material: {},
progress: {},
submissionStage: {
0: ['FILLING', 'PREPAYMENT'],
1: ['INTERVIEW_APPLICATION', 'AUDITION', 'INTERVIEW', 'PAYMENT'],
2: ['REGISTRATION'],
3: ['CLOSED']
},
result: {}
}
},
computed: {
activeProgress() {
for (const key in this.submissionStage) {
const list = this.submissionStage[key]
if (list.includes(this.material.submission_stage)) {
return parseInt(key)
}
}
return 0
}
},
methods: {
// 获取进度值
getProgressStatusText(index) {
if (this.activeProgress === index) {
return '进行中'
} else {
return this.activeProgress > index ? '已完成' : '待进行'
}
},
// 获取报名信息
getApplication() {
api.getApplication().then(response => {
const { data, error, message } = response
if (error.toString() === '0') {
const { material, progress } = data
this.material = material
this.progress = progress
} else {
this.$message.error(message)
}
})
},
// 获取报名审核状态
getApplicationStatus() {
api.getApplicationStatus().then(response => {
this.result = response.data
})
},
// 报名申请
toApplication() {
this.$router.push('/my/application')
},
// 申请面试
toInterview() {
if (this.activeProgress < 1) {
this.$message.warning('请完成报名申请并缴报名费')
return
}
this.$router.push('/my/interview')
},
// 办理入学
toAdmission() {
if (this.activeProgress < 2) {
this.$message.warning('请等待面试结果')
return
}
this.$router.push('/my/admission')
}
},
beforeMount() {
this.getApplication()
this.getApplicationStatus()
}
}
</script>
<style lang="scss" scoped>
.card {
background: #fff;
border-radius: 5px;
}
.card + .card {
margin-top: 10px;
}
.nav {
display: flex;
justify-content: space-between;
padding: 40px 70px 20px;
li {
position: relative;
width: 180px;
height: 120px;
}
a {
color: currentColor;
}
.cover {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
font-weight: 600;
color: #fff;
text-align: center;
background-color: rgba(0, 0, 0.5);
}
}
.result {
min-height: 40px;
padding: 0 20px;
display: flex;
align-items: center;
}
.result-left {
line-height: 14px;
color: var(--main-color);
img {
margin-right: 10px;
}
}
.result-right {
padding-left: 40px;
color: #666;
}
.progress {
margin: 0 40px;
}
</style>
<template>
<app-layout>
<vue-form
:menus="menus"
:default-active="currentActive"
@page-change="handlePageChange"
@success="handleSuccess"
@error="handleError"
@back="$router.push('/my')"
>
<!-- 首页 -->
<app-home v-if="currentActive === 'account'" />
<template #content>
<!-- 基本信息 -->
<app-info v-if="currentActive === 'account_info'" />
<!-- 密码修改 -->
<app-password v-if="currentActive === 'account_password'" />
</template>
</vue-form>
</app-layout>
</template>
<script>
import AppLayout from '../layout.vue'
import AppHome from './home.vue'
import AppInfo from './info.vue'
import AppPassword from './password.vue'
export default {
components: { AppLayout, AppHome, AppInfo, AppPassword },
data() {
return {
menus: [
{
id: 'account',
title: '个人信息',
children: [
{ id: 'account_info', title: '基本信息' },
{ id: 'account_password', title: '密码修改' }
]
}
],
currentActive: 'account'
}
},
watch: {
$route: {
immediate: true,
handler(route) {
const { query = {} } = route
this.currentActive = query.active || 'account'
}
}
},
methods: {
handlePageChange(value) {
this.currentActive = value
this.$router.push({ path: this.$route.path, query: { active: value } })
console.log('页面切换了', value)
},
handleSuccess(data) {
console.log('提交成功了', data)
this.$message({ type: 'success', message: data.message })
},
handleError(data) {
console.log('提交失败了', data)
this.$message({ type: 'error', message: data.message })
}
}
}
</script>
<template>
<div>
<el-form
:model="ruleForm"
:rules="rules"
ref="form"
label-width="100px"
@submit.native.prevent
style="max-width: 680px"
>
<el-form-item label="姓名" prop="real_name">
<el-input v-model.trim="ruleForm.real_name"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="mobile">
<el-input v-model.trim="ruleForm.mobile"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">确认修改</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import * as api from '@/api/my'
export default {
name: 'MyInfo',
data() {
return {
ruleForm: {
real_name: '',
mobile: ''
},
rules: {
real_name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
mobile: [{ required: true, message: '请输入手机号', trigger: 'blur' }]
}
}
},
methods: {
getUser() {
api.getUser().then(response => {
const data = response.data
this.ruleForm.real_name = data.realname
this.ruleForm.mobile = data.mobile
})
},
// 提交
handleSubmit() {
this.$refs.form.validate().then(this.handleRequest)
},
// 接口请求
handleRequest() {
this.loading = true
api.updateUser(this.ruleForm).then(response => {
response.code === 0 ? this.handleSuccess(response) : this.$message.error(response.msg)
this.loading = false
})
},
// 成功
handleSuccess(response) {
this.$alert('基本信息修改成功', {
type: 'success',
confirmButtonText: '返回报名系统',
callback: action => {
this.$router.push('/my')
}
})
}
},
beforeMount() {
this.getUser()
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-input {
max-width: 270px;
}
</style>
<template>
<div>
<el-form :model="ruleForm" :rules="rules" ref="form" label-width="100px" @submit.native.prevent>
<el-form-item label="手机号" prop="account">
<el-input v-model.trim="ruleForm.account"></el-input>
</el-form-item>
<el-form-item prop="code" label="验证码">
<el-input v-model.trim="ruleForm.code" placeholder="请输入验证码">
<countdown
slot="suffix"
size="mini"
:disabled="disabledSend"
@start="sendCodeRequest"
ref="countdown"
></countdown>
</el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model.trim="ruleForm.password"></el-input>
</el-form-item>
<el-form-item label="确认密码" prop="passwordR">
<el-input type="password" v-model.trim="ruleForm.passwordR"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">确认修改</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import * as api from '@/api/my'
import countdown from '@/components/countdown.vue'
export default {
name: 'MyPassword',
components: { countdown },
data() {
const validatePass = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'))
} else if (value !== this.ruleForm.password) {
callback(new Error('两次输入密码不一致!'))
} else {
callback()
}
}
return {
ruleForm: { account: '', code: '', password: '', passwordR: '' },
rules: {
account: [{ required: true, message: '请输入手机号', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }],
password: [
{ required: true, message: '请输入新密码', trigger: 'blur' },
{ min: 6, max: 20, message: '长度为6-20个字符', trigger: 'blur' }
],
passwordR: [
{ required: true, message: '请输入新密码', trigger: 'blur' },
{ validator: validatePass, trigger: 'blur' }
]
}
}
},
computed: {
disabledSend() {
const value = this.ruleForm.account
return !(/^1[3-9]\d{9}$/.test(value) || /@/.test(value))
}
},
methods: {
// 提交
handleSubmit() {
this.$refs.form.validate().then(this.handleRequest)
},
// 接口请求
handleRequest() {
this.loading = true
api.updatePassword(this.ruleForm).then(response => {
response.code === 0 ? this.handleSuccess(response) : this.$message.error(response.msg)
this.loading = false
})
},
// 成功
handleSuccess(response) {
this.$alert('密码修改成功,快去登录吧', '提示', {
type: 'success',
confirmButtonText: '去登录',
callback: action => {
this.$router.push('/login')
}
})
},
// 验证码
sendCodeRequest() {
api
.sendCode({ account: this.ruleForm.account })
.then(response => {
console.log(response)
if (response.code === 0) {
this.$message({ type: 'success', message: '验证码已发送' })
} else {
// 停止计时
this.$refs.countdown.stop()
this.$message({ type: 'error', message: response.msg })
}
})
.catch(this.$refs.countdown.stop)
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-input {
max-width: 270px;
}
</style>
import xy from './xy'
import xfjn from './xfjn'
export default function(_this) {
return {
id: 'admission',
title: '入学办理',
children: [xy(_this), xfjn]
}
}
export default {
id: 'admission_xfjn',
title: '学费缴纳',
html: `
<p><strong>一、对公收款银行信息:</strong></p>
<p>户名:清控紫荆( 北京)教育科技股份有限公司</p>
<p>帐号:694485289</p>
<p>开户行:中国民生银行股份有限公司北京魏公村支行</p>
<p style="margin-top:30px;"><strong>二、支付宝收款账户信息:</strong></p>
<p>支付宝账号:service@ezijing.com</p>
<p>支付宝户名:清控紫荆(北京)教育科技股份有限公司</p>
`
}
export default function(_this) {
return {
id: 'admission_xy',
title: '入学协议',
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const { attachments = [], submission_stage: submissionStage = 'FILLING' } = data.data.material
const stageList = [
'FILLING',
'PREPAYMENT',
'INTERVIEW_APPLICATION',
'AUDITION',
'INTERVIEW',
'PAYMENT',
'REGISTRATION',
'CLOSED'
]
this.form.options.disabled = stageList.findIndex(item => item === submissionStage) > 6
const ADMISSION_AGREEMENT = attachments.filter(item => {
return item.file_type_id === 'ADMISSION_AGREEMENT'
})
return { ADMISSION_AGREEMENT }
}
},
form: {
next: { to: { query: { active: 'admission_xfjn' } } },
hasButton: false,
options: {},
items: [
{
type: 'v-upload',
required: true,
model: 'ADMISSION_AGREEMENT',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'ADMISSION_AGREEMENT' }
},
prepend: `
<p>第一步:点击下载按键获取入学协议</p>
<p><a href="https://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/pc/cu/%E5%85%A5%E5%AD%A6%E5%8D%8F%E8%AE%AE%EF%BC%88%E8%AF%B7%E4%B8%8B%E8%BD%BD%E6%A8%A1%E6%9D%BF%E5%A1%AB%E5%86%99%E5%90%8E%E4%B8%8A%E4%BC%A0%E7%85%A7%E7%89%87%EF%BC%89.docx" target="_blank" download>下载入学协议</a></p>
<p>第二步:申请者可将签字后的入学协议原件扫描或拍照后提交。学员应仔细阅读《入学协议》以及课程介绍,如对入学协议或课程有异议,请第一时间与课程顾问咨询确认。请用A4纸打印后,在入学协议上签上姓名和日期,内容需显示完整、格式整齐、字迹清晰可辨。点击下方按钮,上传文件</p>
`
}
]
}
}
}
<template>
<app-layout>
<vue-form
:menus="menus"
:default-active="currentActive"
@page-change="handlePageChange"
@success="handleSuccess"
@error="handleError"
@back="$router.push('/my')"
@prev="handlePrev"
@next="handleNext"
@uploaded="getApplication"
>
</vue-form>
<el-dialog
title="办理入学资料提交成功"
:visible.sync="dialogVisible"
:center="true"
:close-on-click-modal="false"
width="348px"
>
<div class="dialog-tips">
<p>请确认是否已缴费,如未缴费点击下方缴费按钮 <br />(已缴费,请忽略)</p>
<div class="icon"><img src="../../../assets/images/icon_success.png" /></div>
</div>
<template #footer>
<el-button type="primary" @click="toPay">立即缴费</el-button>
<el-button type="primary" @click="dialogVisible = false">忽略</el-button>
</template>
</el-dialog>
</app-layout>
</template>
<script>
import AppLayout from '../layout.vue'
import getMenu from './form'
import * as api from '@/api/my'
export default {
components: { AppLayout },
data() {
const menus = getMenu(this)
return {
menus: [menus],
currentActive: 'admission_xy',
dialogVisible: false,
detail: null
}
},
watch: {
$route: {
immediate: true,
handler(route) {
const { query = {} } = route
this.currentActive = query.active || 'admission_xy'
}
},
showSubmitedDialog(value) {
this.dialogVisible = value
}
},
computed: {
isSubmited() {
if (this.detail) {
return !!this.detail.material.attachments.find(item => item.file_type_id === 'ADMISSION_AGREEMENT')
}
return false
},
showSubmitedDialog() {
return this.isSubmited && this.currentActive === 'admission_xy'
}
},
methods: {
// 获取报名信息
getApplication() {
api.getApplication().then(response => {
const { data, error, message } = response
if (error.toString() === '0') {
this.detail = data
} else {
this.$message.error(message)
}
})
},
handlePageChange(value) {
this.currentActive = value
this.$router.push({ path: this.$route.path, query: { active: value } })
console.log('页面切换了', value)
},
handleSuccess(data) {
console.log('提交成功了', data)
this.$message({ type: 'success', message: data.message })
},
handleError(data) {
console.log('提交失败了', data)
this.$message({ type: 'error', message: data.message })
},
handlePrev(to) {
this.$router.push(to)
},
handleNext(to) {
this.$router.push(to)
},
toPay() {
this.dialogVisible = false
this.$router.push({ path: '/my/admission', query: { active: 'admission_xfjn' } })
}
},
beforeMount() {
this.getApplication()
}
}
</script>
<style lang="scss" scoped>
.dialog-tips {
text-align: center;
p {
color: #262626;
line-height: 20px;
}
.icon {
margin-top: 20px;
text-align: center;
}
}
</style>
<template>
<el-dialog
title="您当前完成进度如下:"
width="348px"
:center="true"
:close-on-click-modal="false"
:visible.sync="dialogVisible"
@open="handleOpen"
@close="handleClose"
>
<div>
<ul v-if="detail">
<li
v-for="item in currentOptions"
:class="progress[item.code].progress === 1 ? 'is-success' : 'is-error'"
:key="item.code"
>
<span class="name">{{ item.title }}</span>
<span class="line"></span>
<span class="status">{{ progress[item.code].progress === 1 ? '已完成' : '未完成' }}</span>
<span class="view" @click="handleView(item.view.to)">立即查看</span>
</li>
</ul>
</div>
<template #footer>
<el-button type="primary" @click="dialogVisible = false">我知道啦</el-button>
</template>
</el-dialog>
</template>
<script>
import * as api from '@/api/my'
export default {
props: { value: { type: Boolean, default: false }, type: { type: Number, default: 0 } },
data() {
return {
dialogVisible: false,
detail: null,
progress: {},
options: [
[
{
title: '个人资料',
code: 'applicaitonInfo',
view: { to: { path: '/my/application', query: { active: 'application_info' } } }
},
{
title: '推荐信',
code: 'applicationTjx',
view: { to: { path: '/my/application', query: { active: 'application_tjx' } } }
},
{
title: '无犯罪证明',
code: 'applicationWfzzm',
view: { to: { path: '/my/application', query: { active: 'application_wfzzm' } } }
}
],
[
{
title: '学位证书',
code: 'interviewXwzs',
view: { to: { path: '/my/interview', query: { active: 'interview_byz' } } }
},
{
title: '成绩单',
code: 'interviewCjd',
view: { to: { path: '/my/interview', query: { active: 'interview_cjd' } } }
},
{
title: '2寸照片',
code: 'interviewZp',
view: { to: { path: '/my/interview', query: { active: 'interview_zp' } } }
},
{
title: '推荐信',
code: 'interviewTjx',
view: { to: { path: '/my/application', query: { active: 'application_tjx' } } }
}
]
]
}
},
watch: {
value: {
immediate: true,
handler(value) {
this.dialogVisible = value
}
}
},
computed: {
currentOptions() {
return this.options[this.type]
}
},
methods: {
// 获取报名信息
getApplication() {
api.getApplication(this.$route.query).then(response => {
const { data, error, message } = response
if (error.toString() === '0') {
const { progress } = data
this.detail = data
const fillingMissedRequiredList = progress.FILLING.attachments.missed_required_list
// 个人资料
const applicaitonInfo = { progress: 0 }
const infoRequriedList = ['basic_info', 'educations', 'careers', 'answers']
for (const key of infoRequriedList) {
if (progress.FILLING[key].progress < 1) {
applicaitonInfo.progress = 0
break
}
applicaitonInfo.progress = 1
}
if (applicaitonInfo.progress === 1 && !fillingMissedRequiredList.ID_CARD_PHOTO) {
applicaitonInfo.progress = 1
} else {
applicaitonInfo.progress = 0
}
// 推荐信
const applicationTjx = { progress: 0 }
applicationTjx.progress = progress.FILLING.reco_letters.progress
// 无犯罪证明
const applicationWfzzm = { progress: 0 }
applicationWfzzm.progress = fillingMissedRequiredList.NO_CRIMINAL_CERT ? 0 : 1
const missedRequiredList = progress.INTERVIEW_APPLICATION.attachments.missed_required_list
// 学位证书
const interviewXwzs = { progress: 0 }
interviewXwzs.progress = missedRequiredList.DEGREE_CERT_CN ? 0 : 1
// 成绩单
const interviewCjd = { progress: 0 }
interviewCjd.progress = missedRequiredList.REPORT_CARD_CN || missedRequiredList.REPORT_CARD_EN ? 0 : 1
// 2寸照片
const interviewZp = { progress: 0 }
interviewZp.progress = missedRequiredList.PERSONAL_PHOTO_FOR_ID ? 0 : 1
// 推荐信
const interviewTjx = { progress: 0 }
interviewTjx.progress = progress.INTERVIEW_APPLICATION.reco_letters.progress
this.progress = {
applicaitonInfo,
applicationTjx,
applicationWfzzm,
interviewXwzs,
interviewCjd,
interviewZp,
interviewTjx
}
} else {
this.$message.error(message)
}
})
},
handleView(to) {
this.dialogVisible = false
this.$router.push(to)
},
handleOpen() {
this.getApplication()
},
handleClose() {
this.$emit('input', this.dialogVisible)
}
}
}
</script>
<style lang="scss" scoped>
li {
padding: 10px 0;
display: flex;
align-items: center;
}
.name {
width: 80px;
text-align: right;
}
.line {
width: 40px;
height: 1px;
margin: 0 10px;
background-color: #ccc;
}
.is-success {
.status {
color: #33c011;
}
}
.is-error {
.status {
color: #af1b40;
}
}
.view {
margin-left: 40px;
color: #57acff;
text-decoration: underline;
cursor: pointer;
}
</style>
/**
* 申请声明
*/
export default function(_this) {
return {
id: 'application_declare',
title: '申请声明',
visible() {
return _this.visible
},
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const { submission_stage: submissionStage = 'FILLING' } = data.data.material
const isSubmited = submissionStage !== 'FILLING'
this.form.options.disabled = isSubmited
if (isSubmited) {
return { isAgree: [1] }
}
return { isAgree: [] }
}
},
update: {
action: `/api/enrollment/v1.0/application-materials/submit/${webConf.others.projectId}`,
callback() {
_this.getApplication()
this.form.options.disabled = true
_this.$router.push({ path: this.$route.path, query: { active: 'application_pay' } })
},
errorCallback() {
_this.completeVisible = true
}
},
form: {
prev: { to: { query: { active: 'application_wfzzm' } } },
submitText: '提交报名申请',
model: { isAgree: [] },
options: {},
items: [
{
type: 'v-checkbox',
values: [{ label: '同意', value: 1 }],
model: 'isAgree',
rules: [{ required: true, message: '请阅读协议', trigger: 'change' }],
prepend:
'<p>本人自愿申请紫荆-康博斯威尔大学蒙台梭利方向教育硕士项目,所有申请表格内填写的内容属实,本科学士学位证书属实,没有弄虚作假的行为。如有虚假,愿承担一切法 律责任。</p>'
}
]
}
}
}
import info from './info'
import tjx from './tjx'
import wfzsm from './wfzzm'
import declare from './declare'
export default function(_this) {
return {
id: 'application',
title: '报名申请',
children: [
info(_this),
tjx(_this),
wfzsm(_this),
declare(_this),
{
id: 'application_pay',
title: '缴报名费',
show: false,
visible() {
return _this.visible
}
}
]
}
}
import first from './info/first'
import profile from './info/profile'
import education from './info/education'
import career from './info/career'
import honor from './info/honor'
import training from './info/training'
import answer from './info/answer'
export default function(_this) {
return {
id: 'application_info',
title: '个人资料',
tabs: [first(_this), profile(_this), education(_this), career(_this), answer(_this), training(_this), honor(_this)]
}
}
/**
* 学习目的
*/
export default function(_this) {
return {
id: 'application_info_answer',
title: '学习目的',
required: true,
visible() {
return _this.visible
},
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const { answers = [], submission_stage: submissionStage = 'FILLING' } = data.data.material
this.form.options.disabled = submissionStage !== 'FILLING'
const [first = {}, second = {}] = answers
return {
qid1: first.qid || '1',
question1: first.question || '个人描述(60-1000字)中文或者英文',
answer1: first.answer,
qid2: second.qid || '2',
question2:
second.question ||
'申请紫荆教育康博斯威尔大学教育硕士的原因?以及您的职业或个人发展的预期目标(60-1000字)中文或者英文',
answer2: second.answer
}
}
},
update: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}/put`,
beforeRequest(data) {
return {
answers: [
{ qid: data.qid1, question: data.question1, answer: data.answer1 },
{ qid: data.qid2, question: data.question2, answer: data.answer2 }
]
}
}
},
form: {
prev: { to: { query: { active: 'application_info', tab: 'application_info_career' } }, isSubmit: true },
next: { to: { query: { active: 'application_info', tab: 'application_info_training' } }, isSubmit: true },
options: {},
items: [
{
type: 'v-input',
label: '个人描述(60-1000字)中文或者英文',
model: 'answer1',
attrs: { type: 'textarea', rows: '8', maxlength: '1000', style: 'width:100%' },
rules: [
{ required: true, message: '请输入', trigger: 'blur' },
{ min: 60, max: 1000, message: '长度在 60 到 1000 个字符', trigger: 'blur' }
]
},
{
type: 'v-input',
label: '申请紫荆教育康博斯威尔大学教育硕士的原因?以及您的职业或个人发展的预期目标(60-1000字)中文或者英文',
model: 'answer2',
attrs: { type: 'textarea', rows: '8', maxlength: '1000', style: 'width:100%' },
rules: [
{ required: true, message: '请输入', trigger: 'blur' },
{ min: 60, max: 1000, message: '长度在 60 到 1000 个字符', trigger: 'blur' }
]
}
]
}
}
}
/**
* 工作经验
*/
export default function(_this) {
return {
id: 'application_info_career',
title: '工作经验',
required: true,
visible() {
return _this.visible
},
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
let { careers: list = [], submission_stage: submissionStage = 'FILLING' } = data.data.material
this.form.options.disabled = submissionStage !== 'FILLING'
list = list.map(item => {
const { start_date: startDate, end_date: endDate } = item
if (startDate) {
item.dates = [startDate, endDate]
}
return item
})
return list.length ? list : [{}]
}
},
update: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}/put`,
beforeRequest(data) {
const careers = data.map(item => {
const [startDate, endDate] = item.dates
item.start_date = startDate
item.end_date = endDate
return [
'start_date',
'end_date',
'company_name_cn',
'industry',
'dept_cn',
'position_cn',
'job_desc_cn'
].reduce((result, key) => {
result[key] = item[key]
return result
}, {})
})
return { careers }
}
},
form: {
prev: { to: { query: { active: 'application_info', tab: 'application_info_education' } }, isSubmit: true },
next: { to: { query: { active: 'application_info', tab: 'application_info_answer' } }, isSubmit: true },
hasAdd: true,
options: { labelWidth: '140px' },
items: [
{
type: 'v-datepicker',
label: '工作时间',
model: 'dates',
attrs: {
type: 'monthrange',
rangeSeparator: '至',
startPlaceholder: '请选择开始时间',
endPlaceholder: '请选择结束时间',
valueFormat: 'yyyy-MM'
},
rules: [{ required: true, message: '请选择工作时间', trigger: 'blur' }]
},
{
type: 'v-input',
label: '工作单位',
model: 'company_name_cn',
attrs: { placeholder: '请输入工作单位' },
rules: [{ required: true, message: '请输入工作单位', trigger: 'blur' }]
},
{
type: 'v-select',
values: [
{ label: '互联网/电子商务', value: '1 ' },
{ label: '基金/证券/期货/投资', value: '2 ' },
{ label: '保险', value: '3 ' },
{ label: '银行', value: '4 ' },
{ label: '信托/担保/拍卖/典当', value: '5 ' },
{ label: '计算机软件', value: '6 ' },
{ label: 'IT服务(系统/数据/维护)', value: '7 ' },
{ label: '电子技术/半导体/集成电路', value: '8 ' },
{ label: '计算机硬件', value: '9 ' },
{ label: '通信/电信/网络设备', value: '10' },
{ label: '通信/电信运营、增值服务', value: '11' },
{ label: '网络游戏', value: '12' },
{ label: '房地产/建筑/建材/工程', value: '13' },
{ label: '家居/室内设计/装饰装潢', value: '14' },
{ label: '物业管理/商业中心', value: '15' },
{ label: '专业服务/咨询(财会/法律/人力资源等)', value: '16' },
{ label: '广告/会展/公关', value: '17' },
{ label: '中介服务', value: '18' },
{ label: '检验/检测/认证', value: '19' },
{ label: '外包服务', value: '20' },
{ label: '快速消费品(食品/饮料/烟酒/日化)', value: '21' },
{ label: '耐用消费品(服饰/纺织/皮革/家具/家电)', value: '22' },
{ label: '贸易/进出口', value: '23' },
{ label: '零售/批发', value: '24' },
{ label: '租赁服务', value: '25' },
{ label: '教育/培训/院校', value: '26' },
{ label: '礼品/玩具/工艺美术/收藏品/奢侈品', value: '27' },
{ label: '汽车/摩托车', value: '28' },
{ label: '大型设备/机电设备/重工业', value: '29' },
{ label: '加工制造(原料加工/模具)', value: '30' },
{ label: '仪器仪表及工业自动化', value: '31' },
{ label: '印刷/包装/造纸', value: '32' },
{ label: '办公用品及设备', value: '33' },
{ label: '医药/生物工程', value: '34' },
{ label: '医疗设备/器械', value: '35' },
{ label: '航空/航天研究与制造', value: '36' },
{ label: '交通/运输,物流/仓储', value: '37' },
{ label: '医疗/护理/美容/保健/卫生服务', value: '38' },
{ label: '酒店/餐饮,旅游/度假,媒体/出版/影视/文化传播', value: '39' },
{ label: '娱乐/体育/休闲', value: '40' },
{ label: '能源/矿产/采掘/冶炼', value: '41' },
{ label: '石油/石化/化工,电气/电力/水利', value: '42' },
{ label: '环保', value: '43' },
{ label: '政府/公共事业/非盈利机构', value: '44' },
{ label: '学术/科研,农/林/牧/渔跨领域经营', value: '45' },
{ label: '其他', value: '90' }
],
label: '行业类别',
model: 'industry',
rules: [{ required: true, message: '请选择行业类别', trigger: 'change' }]
},
{
type: 'v-input',
label: '工作部门',
model: 'dept_cn',
attrs: { placeholder: '请输入工作部门' },
rules: [{ required: true, message: '请输入工作部门', trigger: 'blur' }]
},
{
type: 'v-input',
label: '工作职位',
model: 'position_cn',
attrs: { placeholder: '请输入工作职位' },
rules: [{ required: true, message: '请输入工作职位', trigger: 'blur' }]
},
{
type: 'v-input',
label: '工作描述',
model: 'job_desc_cn',
attrs: {
type: 'textarea',
placeholder: '请输入工作描述',
rows: '8',
maxlength: '3000'
},
rules: [{ required: true, message: '请输入工作描述', trigger: 'blur' }]
}
]
}
}
}
/**
* 教育背景
*/
export default function(_this) {
return {
id: 'application_info_education',
title: '教育背景',
required: true,
visible() {
return _this.visible
},
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
let { educations: list = [], submission_stage: submissionStage = 'FILLING' } = data.data.material
this.form.options.disabled = submissionStage !== 'FILLING'
list = list.map(item => {
const { start_date: startDate, end_date: endDate } = item
if (startDate) {
item.dates = [startDate, endDate]
}
return item
})
return list.length ? list : [{}]
}
},
update: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}/put`,
beforeRequest(data) {
const educations = data.map(item => {
const [startDate, endDate] = item.dates
item.start_date = startDate
item.end_date = endDate
return ['start_date', 'end_date', 'school_name_cn', 'major_cn', 'degree'].reduce((result, key) => {
result[key] = item[key]
return result
}, {})
})
return { educations }
}
},
form: {
prev: { to: { query: { active: 'application_info', tab: 'application_info_profile' } }, isSubmit: true },
next: { to: { query: { active: 'application_info', tab: 'application_info_career' } }, isSubmit: true },
hasAdd: true,
options: { labelWidth: '140px' },
items: [
{
type: 'v-datepicker',
label: '教育时间',
model: 'dates',
attrs: {
type: 'monthrange',
rangeSeparator: '至',
startPlaceholder: '请选择开始时间',
endPlaceholder: '请选择结束时间',
valueFormat: 'yyyy-MM'
},
rules: [{ required: true, message: '请选择教育时间', trigger: 'blur' }]
},
{
type: 'v-input',
label: '学校名称',
model: 'school_name_cn',
rules: [{ required: true, message: '请输入学校名称', trigger: 'blur' }]
},
{
type: 'v-input',
label: '专业名称',
model: 'major_cn',
rules: [{ required: true, message: '请输入专业名称', trigger: 'blur' }]
},
{
type: 'v-select',
values: [
{ value: '专科' },
{ value: '本科' },
{ value: '本科/学士' },
{ value: '硕士研究生' },
{ value: '研究生/硕士' },
{ value: '博士研究生' },
{ value: '研究生/博士' },
{ value: '其他' }
],
label: '学历/学位',
model: 'degree',
rules: [{ required: true, message: '请选择学历/学位', trigger: 'change' }]
}
]
}
}
}
/**
* 个人信息
*/
export default function(_this) {
return {
id: 'application_info_first',
title: '个人信息',
required: true,
visible() {
return this.tabActive === 'application_info_first'
},
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const {
basic_info: basicInfo = {},
attachments = [],
submission_stage: submissionStage = 'FILLING'
} = data.data.material
this.form.options.disabled = submissionStage !== 'FILLING'
const attachment = attachments.reduce(
(result, item) => {
const types = ['ID_CARD_FRONT', 'ID_CARD_BACK', 'HK_ID_CARD', 'PASSPORT', 'OTHER_ID_CARD_PHOTO']
types.forEach(type => {
if (item.file_type_id === type) {
result[type].push(item)
}
})
return result
},
{ ID_CARD_FRONT: [], ID_CARD_BACK: [], HK_ID_CARD: [], PASSPORT: [], OTHER_ID_CARD_PHOTO: [] }
)
return Object.assign({}, basicInfo, attachment)
}
},
update: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}/put`,
beforeRequest(data) {
const basicInfo = ['phone_number', 'email', 'id_type'].reduce((result, key) => {
result[key] = data[key]
return result
}, {})
return { basic_info: basicInfo }
}
},
form: {
hasButton: false,
next: { to: { query: { active: 'application_info', tab: 'application_info_profile' } }, isSubmit: true },
options: { labelWidth: '140px' },
items: [
{
type: 'v-input',
label: '手机号',
model: 'phone_number',
attrs: { placeholder: '请输入手机号' },
rules: [{ required: true, message: '请输入手机号', trigger: 'blur' }]
},
{
type: 'v-input',
label: '邮箱',
model: 'email',
attrs: { placeholder: '请输入邮箱' },
rules: [{ required: true, message: '请输入邮箱', trigger: 'blur' }]
},
{
type: 'v-select',
values: [{ value: '居民身份证' }, { value: '港澳台身份证' }, { value: '护照' }, { value: '其他' }],
label: '证件类型',
model: 'id_type',
attrs: { placeholder: '请选择证件类型' },
rules: [{ required: true, message: '请选择证件类型', trigger: 'change' }]
},
// 身份证照片(背面)
{
type: 'v-upload',
label: '身份证人像面',
model: 'ID_CARD_BACK',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'ID_CARD_BACK' },
limit: 1,
accept: 'image/*',
image: 'https://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/pc/cu/id_card_back.png'
},
rules: [{ type: 'array', required: true, message: '请上传身份证照片人像面', trigger: 'change' }],
isShow(data) {
return data.id_type === '居民身份证'
}
},
// 身份证照片(正面)
{
type: 'v-upload',
label: '身份证国徽面',
model: 'ID_CARD_FRONT',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'ID_CARD_FRONT' },
limit: 1,
accept: 'image/*',
image: 'https://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/pc/cu/id_card_front.png'
},
rules: [{ type: 'array', required: true, message: '请上传身份证照片国徽面', trigger: 'change' }],
isShow(data) {
return data.id_type === '居民身份证'
}
},
// 港澳台身份证
{
type: 'v-upload',
label: '港澳台身份证',
model: 'HK_ID_CARD',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'HK_ID_CARD' },
limit: 1,
accept: 'image/*'
},
rules: [{ type: 'array', required: true, message: '请上传港澳台身份证', trigger: 'change' }],
isShow(data) {
return data.id_type === '港澳台身份证'
}
},
// 护照
{
type: 'v-upload',
label: '护照',
model: 'PASSPORT',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'PASSPORT' },
limit: 1,
accept: 'image/*'
},
rules: [{ type: 'array', required: true, message: '请上传护照', trigger: 'change' }],
isShow(data) {
return data.id_type === '护照'
}
},
// 其他证件
{
type: 'v-upload',
label: '其他证件',
model: 'OTHER_ID_CARD_PHOTO',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'OTHER_ID_CARD_PHOTO' },
limit: 1,
accept: 'image/*'
},
rules: [{ type: 'array', required: true, message: '请上传其他证件', trigger: 'change' }],
isShow(data) {
return data.id_type === '其他'
}
}
]
}
}
}
/**
* 荣誉奖励
*/
export default function(_this) {
return {
id: 'application_info_honor',
title: '荣誉奖励',
visible() {
return _this.visible
},
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const { honors: list = [], submission_stage: submissionStage = 'FILLING' } = data.data.material
this.form.options.disabled = submissionStage !== 'FILLING'
return list.length ? list : [{}]
}
},
update: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}/put`,
beforeRequest(data) {
const honors = data.map(item => {
return ['time', 'title', 'institution_cn'].reduce((result, key) => {
result[key] = item[key]
return result
}, {})
})
return { honors }
}
},
form: {
prev: { to: { query: { active: 'application_info', tab: 'application_info_training' } }, isSubmit: true },
next: { to: { query: { active: 'application_tjx' } }, isSubmit: true },
hasAdd: true,
options: { labelWidth: '140px' },
items: [
{
type: 'v-datepicker',
label: '获取时间',
model: 'time',
attrs: { type: 'date', valueFormat: 'yyyy-MM-dd', placeholder: '请选择获取时间' },
rules: [{ required: true, message: '请选择获取时间', trigger: 'blur' }]
},
{
type: 'v-input',
label: '荣誉奖励',
model: 'title',
attrs: { placeholder: '请输入荣誉奖励' },
rules: [{ required: true, message: '请输入荣誉奖励', trigger: 'blur' }]
},
{
type: 'v-input',
label: '证书颁发机构',
model: 'institution_cn',
rules: [{ required: true, message: '请输入证书颁发机构', trigger: 'blur' }]
}
]
}
}
}
/**
* 个人信息
*/
export default function(_this) {
return {
id: 'application_info_profile',
title: '个人信息',
required: true,
visible() {
return _this.visible
},
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const {
basic_info: basicInfo = {},
attachments = [],
submission_stage: submissionStage = 'FILLING'
} = data.data.material
this.form.options.disabled = submissionStage !== 'FILLING'
const attachment = attachments.reduce(
(result, item) => {
const types = ['ID_CARD_FRONT', 'ID_CARD_BACK', 'HK_ID_CARD', 'PASSPORT', 'OTHER_ID_CARD_PHOTO']
types.forEach(type => {
if (item.file_type_id === type) {
result[type].push(item)
}
})
return result
},
{ ID_CARD_FRONT: [], ID_CARD_BACK: [], HK_ID_CARD: [], PASSPORT: [], OTHER_ID_CARD_PHOTO: [] }
)
return Object.assign({}, basicInfo, attachment)
}
},
update: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}/put`,
beforeRequest(data) {
// let [province, city] = data.city.split('-')
// data.address_province = province
// data.address_city = city
const basicInfo = [
'phone_number',
'email',
'id_type',
'id_number',
'real_name_cn',
'gender',
'nationality',
'birthday',
'address_province',
'address_city',
'we_chat_account',
'mailing_address',
'emergency_contact_name',
'emergency_contacts_phone'
].reduce((result, key) => {
result[key] = data[key]
return result
}, {})
return { basic_info: basicInfo }
}
},
form: {
prev: { to: { query: { active: 'application_info', tab: 'application_info_first' } } },
next: { to: { query: { active: 'application_info', tab: 'application_info_education' } }, isSubmit: true },
options: { labelWidth: '140px' },
items: [
{
type: 'v-input',
label: '手机号',
model: 'phone_number',
attrs: { disabled: false, placeholder: '请输入手机号' },
rules: [{ required: true, message: '请输入手机号', trigger: 'blur' }]
},
{
type: 'v-input',
label: '邮箱',
model: 'email',
attrs: { disabled: false, placeholder: '请输入邮箱' },
rules: [{ required: true, message: '请输入邮箱', trigger: 'blur' }],
hint: '(后续报名信息将发送至此邮箱,请认真填写)'
},
{
type: 'v-select',
values: [{ value: '居民身份证' }, { value: '港澳台身份证' }, { value: '护照' }, { value: '其他' }],
label: '证件类型',
model: 'id_type',
attrs: { disabled: false, placeholder: '请选择证件类型' },
rules: [{ required: true, message: '请选择证件类型', trigger: 'change' }]
},
// 身份证照片(背面)
{
type: 'v-upload',
label: '身份证人像面',
model: 'ID_CARD_BACK',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'ID_CARD_BACK' },
limit: 1,
image: 'https://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/pc/cu/id_card_back.png'
},
rules: [{ type: 'array', required: true, message: '请上传身份证照片人像面', trigger: 'change' }],
isShow(data) {
return data.id_type === '居民身份证'
}
},
// 身份证照片(正面)
{
type: 'v-upload',
label: '身份证国徽面',
model: 'ID_CARD_FRONT',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'ID_CARD_FRONT' },
limit: 1,
image: 'https://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/pc/cu/id_card_front.png'
},
rules: [{ type: 'array', required: true, message: '请上传身份证照片国徽面', trigger: 'change' }],
isShow(data) {
return data.id_type === '居民身份证'
}
},
// 港澳台身份证
{
type: 'v-upload',
label: '港澳台身份证',
model: 'HK_ID_CARD',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'HK_ID_CARD' },
limit: 1
},
rules: [{ type: 'array', required: true, message: '请上传港澳台身份证', trigger: 'change' }],
isShow(data) {
return data.id_type === '港澳台身份证'
}
},
// 护照
{
type: 'v-upload',
label: '护照',
model: 'PASSPORT',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'PASSPORT' },
limit: 1
},
rules: [{ type: 'array', required: true, message: '请上传护照', trigger: 'change' }],
isShow(data) {
return data.id_type === '护照'
}
},
// 其他证件
{
type: 'v-upload',
label: '其他证件',
model: 'OTHER_ID_CARD_PHOTO',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'OTHER_ID_CARD_PHOTO' },
limit: 1
},
rules: [{ type: 'array', required: true, message: '请上传其他证件', trigger: 'change' }],
isShow(data) {
return data.id_type === '其他'
}
},
{
type: 'v-input',
label: '证件号码',
model: 'id_number',
attrs: { disabled: false, placeholder: '请输入证件号码' },
rules: [{ required: true, message: '请输入证件号码', trigger: 'blur' }]
},
{
type: 'v-input',
label: '姓名',
model: 'real_name_cn',
attrs: { placeholder: '请输入姓名' },
rules: [{ required: true, message: '请输入姓名', trigger: 'blur' }]
},
{
type: 'v-radio',
values: [
{ label: '男', value: '男' },
{ label: '女', value: '女' }
],
label: '性别',
model: 'gender',
rules: [{ required: true, message: '请选择性别', trigger: 'change' }]
},
{
type: 'v-input',
label: '国籍',
model: 'nationality',
attrs: { placeholder: '请输入国籍' },
rules: [{ required: true, message: '请输入国籍', trigger: 'blur' }]
},
{
type: 'v-datepicker',
label: '出生日期',
model: 'birthday',
attrs: { type: 'date', placeholder: '请选择出生日期', valueFormat: 'yyyy-MM-dd' },
rules: [{ required: true, message: '请选择出生日期', trigger: 'blur' }]
},
{
type: 'v-input',
label: '居住省',
model: 'address_province',
attrs: { placeholder: '请输入居住省' },
rules: [{ required: true, message: '请输入居住省', trigger: 'blur' }]
},
{
type: 'v-input',
label: '居住市',
model: 'address_city',
attrs: { placeholder: '请输入居住市' },
rules: [{ required: true, message: '请输入居住市', trigger: 'blur' }]
},
// {
// type: 'city-v-select',
// label: '现居住城市',
// model: 'city',
// separator: '-',
// rules: [{ required: true, message: '请选择居住城市', trigger: 'blur' }]
// },
{
type: 'v-input',
label: '微信号',
model: 'we_chat_account',
attrs: { placeholder: '请输入微信号' },
rules: [{ required: true, message: '请输入微信号', trigger: 'blur' }]
},
{
type: 'v-input',
label: '邮寄地址',
model: 'mailing_address',
attrs: { placeholder: '请输入邮寄地址' },
rules: [{ required: true, message: '请输入邮寄地址', trigger: 'blur' }]
},
{
type: 'v-input',
label: '紧急联系人',
model: 'emergency_contact_name',
attrs: { placeholder: '请输入紧急联系人' },
rules: [{ required: true, message: '请输入紧急联系人', trigger: 'blur' }]
},
{
type: 'v-input',
label: '紧急联系电话',
model: 'emergency_contacts_phone',
attrs: { placeholder: '请输入紧急联系电话' },
rules: [{ required: true, message: '请输入紧急联系电话', trigger: 'blur' }]
}
]
}
}
}
/**
* 所受培训
*/
export default function(_this) {
return {
id: 'application_info_training',
title: '所受培训',
visible() {
return _this.visible
},
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
let { trainings: list = [], submission_stage: submissionStage = 'FILLING' } = data.data.material
this.form.options.disabled = submissionStage !== 'FILLING'
list = list.map(item => {
const { start_date: startDate, end_date: endDate } = item
if (startDate) {
item.dates = [startDate, endDate]
}
return item
})
return list.length ? list : [{}]
}
},
update: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}/put`,
beforeRequest(data) {
const trainings = data.map(item => {
const [startDate, endDate] = item.dates
item.start_date = startDate
item.end_date = endDate
return ['start_date', 'end_date', 'institution_cn', 'course_cn'].reduce((result, key) => {
result[key] = item[key]
return result
}, {})
})
return { trainings }
}
},
form: {
prev: { to: { query: { active: 'application_info', tab: 'application_info_answer' } }, isSubmit: true },
next: { to: { query: { active: 'application_info', tab: 'application_info_honor' } }, isSubmit: true },
hasAdd: true,
options: { labelWidth: '140px' },
items: [
{
type: 'v-datepicker',
label: '培训时间',
model: 'dates',
attrs: {
type: 'monthrange',
rangeSeparator: '至',
startPlaceholder: '请选择开始时间',
endPlaceholder: '请选择结束时间',
valueFormat: 'yyyy-MM'
},
rules: [{ required: true, message: '请选择培训时间', trigger: 'blur' }]
},
{
type: 'v-input',
label: '培训机构',
model: 'institution_cn',
rules: [{ required: true, message: '请输入培训机构', trigger: 'blur' }]
},
{
type: 'v-input',
label: '课程名称',
model: 'course_cn',
rules: [{ required: true, message: '请输入课程名称', trigger: 'blur' }]
}
]
}
}
}
/**
* 推荐信
*/
export default function(_this) {
return {
id: 'application_tjx',
title: '推荐信',
visible() {
return _this.visible
},
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const { submission_stage: submissionStage = 'FILLING' } = data.data.material
const stageList = [
'FILLING',
'PREPAYMENT',
'INTERVIEW_APPLICATION',
'AUDITION',
'INTERVIEW',
'PAYMENT',
'REGISTRATION',
'CLOSED'
]
this.form.options.disabled = stageList.findIndex(item => item === submissionStage) > 3
const list = data.data.material.reco_letters || []
return list.length ? list : [{}, {}, {}]
}
},
update: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}/put`,
beforeRequest(data) {
// const recoLetters = data.map(item => {
// return ['provider_name', 'provider_phone_number', 'provider_email', 'provider_relationship'].reduce(
// (result, key) => {
// result[key] = item[key]
// return result
// },
// {}
// )
// })
return { reco_letters: data }
}
},
form: {
minlength: 3,
prev: { to: { query: { active: 'application_info', tab: 'application_info_honor' } }, isSubmit: true },
next: { to: { query: { active: 'application_wfzzm' } }, isSubmit: true },
hasAdd: true,
disabled(data) {
return !!data.letter_content
},
aside: {
prepend: {
html: '<p style="color:#33C011;">推荐人已完成</p>',
visible(data) {
return !!data.letter_content
}
},
buttons: [
{
text: '再次邀请',
visible(data) {
const editable = ['PREPAYMENT', 'INTERVIEW_APPLICATION', 'AUDITION'].includes(
_this.detail.material.submission_stage
)
return data.id && !data.letter_content && editable
},
onClick(data) {
_this.sendToProvider(data)
}
},
{
text: '更换推荐人',
visible(data) {
const editable = ['PREPAYMENT', 'INTERVIEW_APPLICATION', 'AUDITION'].includes(
_this.detail.material.submission_stage
)
return data.id && !data.letter_content && editable
},
onClick(data) {
_this.changeProvider(data)
}
}
]
},
options: { labelWidth: '140px' },
items: [
{
type: 'v-input',
label: '推荐人姓名',
model: 'provider_name',
attrs: { placeholder: '请输入推荐人姓名' },
rules: [{ required: true, message: '请输入推荐人姓名', trigger: 'blur' }]
},
{
type: 'v-input',
label: '推荐人电话',
model: 'provider_phone_number',
attrs: { placeholder: '请输入推荐人电话' },
rules: [{ required: true, message: '请输入推荐人电话', trigger: 'blur' }]
},
{
type: 'v-input',
label: '推荐人邮箱',
model: 'provider_email',
attrs: { placeholder: '请输入推荐人邮箱' },
rules: [{ required: true, message: '请输入推荐人邮箱', trigger: 'blur' }]
},
{
type: 'v-select',
values: [
{ value: '老师/导师' },
{ value: '领导' },
{ value: '同学' },
{ value: '同事' },
{ value: '亲属' },
{ value: '朋友' },
{ value: '其他' }
],
label: '与推荐人关系',
model: 'provider_relationship',
rules: [{ required: true, message: '请选择与推荐人关系', trigger: 'change' }]
}
]
}
}
}
export default function(_this) {
return {
id: 'application_wfzzm',
title: '无犯罪证明',
visible() {
return _this.visible
},
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const { attachments = [], submission_stage: submissionStage = 'FILLING' } = data.data.material
this.form.options.disabled = submissionStage !== 'FILLING'
const NO_CRIMINAL_CERT = attachments.filter(item => {
return item.file_type_id === 'NO_CRIMINAL_CERT'
})
return { NO_CRIMINAL_CERT }
}
},
form: {
prev: { to: { query: { active: 'application_tjx' } } },
next: { to: { query: { active: 'application_declare' } } },
hasButton: false,
options: {},
items: [
{
type: 'v-upload',
required: true,
model: 'NO_CRIMINAL_CERT',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'NO_CRIMINAL_CERT' },
limit: 1,
accept: 'image/*'
},
prepend: `
<p>第一步:点击下载按键获取无犯罪证明模板</p>
<p><a href="https://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/pc/cu/%E6%97%A0%E7%8A%AF%E7%BD%AA%E8%AE%B0%E5%BD%95%E8%AF%81%E6%98%8E.docx" target="_blank" download>下载模板</a></p>
<p>第二步:打印文件后填写内容并签字上传至电脑,点击下方按钮上传文件</p>
`
}
]
}
}
}
<template>
<app-layout>
<vue-form
:menus="menus"
:default-active="currentActive"
:tab-active="tabActive"
@page-change="handlePageChange"
@tab-change="handleTabChange"
@success="handleSuccess"
@error="handleError"
@back="$router.push('/my')"
@prev="handlePrev"
@next="handleNext"
v-if="detail"
>
<template #aside-append v-if="visible">
<div class="aside-preview" @click="dialogVisible = true">预览全部</div>
</template>
<!-- 报名缴费 -->
<template #content v-if="currentActive === 'application_pay'">
<app-pay />
</template>
</vue-form>
<el-dialog title="预览全部" :visible.sync="dialogVisible" width="790px" class="dialog-preview">
<app-preview :hasEdit="true" @edit="handlePreviewEdit" v-if="dialogVisible" />
</el-dialog>
<app-complete v-model="completeVisible"></app-complete>
</app-layout>
</template>
<script>
import AppLayout from '../layout.vue'
import getMenu from './form'
import AppPay from './pay.vue'
import AppPreview from './preview.vue'
import AppComplete from './complete.vue'
import * as api from '@/api/my'
export default {
components: { AppLayout, AppPay, AppPreview, AppComplete },
data() {
const menus = getMenu(this)
return {
menus: [menus],
currentActive: 'application_info',
tabActive: 'application_info_profile',
dialogVisible: false,
detail: null,
completeVisible: false
}
},
watch: {
$route: {
immediate: true,
handler(route) {
const { query = {} } = route
this.currentActive = query.active || 'application_info'
this.tabActive = query.tab || 'application_info_profile'
}
}
},
computed: {
visible() {
return this.currentActive !== 'application_info' || this.tabActive !== 'application_info_first'
}
},
methods: {
// 获取报名信息
getApplication() {
api.getApplication().then(response => {
const { data, error, message } = response
if (error.toString() === '0') {
this.detail = data
if (
!data.progress.FILLING.attachments ||
data.progress.FILLING.attachments.missed_required_list.ID_CARD_PHOTO
) {
this.tabActive = 'application_info_first'
}
const { submission_stage: submissionStage = 'FILLING' } = data.material
if (submissionStage !== 'FILLING') {
this.menus[0].children.forEach(item => {
if (item.id === 'application_pay') {
item.show = true
}
})
}
} else {
this.$message.error(message)
}
})
},
handlePageChange(value) {
this.currentActive = value
this.$router.push({ path: this.$route.path, query: { active: value } })
},
handleTabChange(value) {
this.tabActive = value
const query = Object.assign({}, this.$route.query, { tab: value })
this.$router.push({ query })
},
handleSuccess(data) {
console.log('提交成功了', data)
this.$message({ type: 'success', message: '提交成功' })
},
handleError(data) {
console.log('提交失败了', data)
this.$message({ type: 'error', message: data.message })
},
handlePrev(to) {
this.$router.push(to)
},
handleNext(to) {
this.$router.push(to)
},
handlePreviewEdit(to) {
this.$router.push(to)
this.dialogVisible = false
},
// 更换推荐人
changeProvider(data) {
api.updateProvider(data.id, data).then(response => {
const { error, message } = response
if (error.toString() === '0') {
this.$message({ type: 'success', message })
} else {
this.$message.error(message)
}
})
},
// 再次邀请推荐
sendToProvider(data) {
api.sendToProvider(data.id).then(response => {
const { error, message } = response
if (error.toString() === '0') {
this.$message({ type: 'success', message })
} else {
this.$message.error(message)
}
})
}
},
beforeMount() {
this.getApplication()
}
}
</script>
<style lang="scss" scoped>
::v-deep .aside-preview {
margin-top: -20px;
padding-left: 64px;
font-size: 14px;
font-weight: 700;
line-height: 44px;
color: #222;
cursor: pointer;
}
.dialog-preview {
::v-deep .el-dialog__body {
padding: 0;
}
}
</style>
<template>
<div class="pay">
<div class="pic">
<img src="../../../assets/images/my_pay_01.png" />
</div>
<div class="pay-hd">
<h1>欢迎您</h1>
<p class="t1">
申请紫荆-康博斯威尔大学蒙台梭利方向教育学硕士项目,本项目的注册费、申请费共计<span>700</span>元,请扫描二维码缴费以完成报名。
</p>
<p class="t1" v-if="isPass">
因面试未通过需重新申请紫荆-康博斯威尔大学蒙台梭利方向教育学硕士项目,本项目的注册费、申请费共计<span>700</span>元,请扫描二维码缴费以完成报名。
</p>
</div>
<div class="qrcode-error" v-if="qrcodeError">
生成二维码失败请刷新<i class="el-icon-refresh-left" @click="refreshQrcode" title="刷新"></i>
</div>
<div class="qrcode" v-else>
<qrcode-vue :value="qrcodeValue" size="100"></qrcode-vue>
<span @click="refreshQrcode">刷新</span>
</div>
<div class="pay-ft">
<p class="t2">注释:再提交700元申请费后,申请人还需上传并提交如下文件。</p>
<p class="t2">①本科学位证书、②本科中、英文成绩单各一份、③个人证件照(2寸、免冠、白底)</p>
<p class="t2">该申请费不退,请慎重缴费!</p>
</div>
<el-dialog
title="报名费缴费成功"
:visible.sync="dialogVisible"
:center="true"
:close-on-click-modal="false"
width="348px"
>
<div class="dialog-pay">
<p>请填写申请面试的材料,材料齐全后<br />招生办老师将给您致电预约面试日期与时间</p>
<div class="icon"><img src="../../../assets/images/icon_success.png" /></div>
</div>
<template #footer>
<el-button type="primary" @click="toInterview">立即预约</el-button>
</template>
</el-dialog>
</div>
</template>
<script>
import QrcodeVue from 'qrcode.vue'
import * as api from '@/api/my'
export default {
name: 'AppPay',
components: { QrcodeVue },
data() {
return {
isPass: false,
order: { id: '', payment_url: '' },
qrcodeError: false,
dialogVisible: false,
timer: null
}
},
computed: {
// 二维码地址
qrcodeValue() {
return this.order.payment_url
},
// 支付成功
paySuccess() {
return this.order.payment_status === 'SUCCESS'
}
},
methods: {
// 获取报名信息
async getApplication() {
await api.getApplication().then(response => {
const { payment_records: paymentRecords = [] } = response.data.material
if (paymentRecords && paymentRecords.length) {
// 获取支付成功的订单
const orderPaySuccess = paymentRecords.find(item => {
return item.bill_type === 'APPLICATION_FEE' && item.payment_status === 'SUCCESS'
})
if (orderPaySuccess) {
this.order = orderPaySuccess
this.dialogVisible = true
return
}
// 获取最后一个订单
const [lastPayment] = paymentRecords.reverse()
this.order = lastPayment
}
})
},
// 获取订单
async getOrder() {
if (this.paySuccess) {
return
}
await api.getOrder({ payment_method: 'WX_PAY_QR' }).then(response => {
const { data, error, message } = response
this.qrcodeError = error.toString() === '1'
if (error.toString() === '0') {
this.order = data
} else {
this.$message.error(message)
}
})
},
// 刷新二维码
refreshQrcode() {
this.getOrder()
},
// 检查支付状态
async checkPay() {
if (this.paySuccess) {
this.timer && clearInterval(this.timer)
return
}
const userId = window.G.UserInfo.id
await api.checkPay(this.order.id, { user_id: userId }).then(response => {
if (response.data.payment_status === 'SUCCESS') {
this.timer && clearInterval(this.timer)
this.dialogVisible = true
}
})
},
setCheckPayTimer() {
this.timer && clearInterval(this.timer)
this.timer = setInterval(this.checkPay, 3000)
},
// 申请面试
toInterview() {
this.$router.push('/my/interview')
}
},
async mounted() {
await this.getApplication()
await this.getOrder()
this.setCheckPayTimer()
},
destroyed() {
this.timer && clearInterval(this.timer)
}
}
</script>
<style lang="scss" scoped>
.pay {
max-width: 562px;
margin: 0 auto;
}
.pic {
text-align: center;
}
.pay-hd {
h1 {
padding: 10px 0;
font-size: 24px;
font-weight: 500;
color: #222;
line-height: 1;
text-align: center;
}
}
.qrcode {
padding: 20px 0;
text-align: center;
span {
margin-top: 10px;
font-size: 12px;
color: #999;
cursor: pointer;
}
}
.qrcode-error {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
width: 100px;
height: 100px;
padding: 10px;
margin: 20px auto;
color: var(--main-color);
border-style: dashed;
border-width: 1px;
border-color: var(--main-color);
box-sizing: border-box;
text-align: center;
i {
margin-top: 10px;
cursor: pointer;
}
}
.t1 {
font-size: 14px;
color: #303030;
line-height: 20px;
text-align: center;
span {
color: #ffa448;
}
}
.t2 {
font-size: 12px;
color: #999;
line-height: 20px;
}
.dialog-pay {
text-align: center;
p {
color: #262626;
line-height: 20px;
}
.icon {
margin-top: 20px;
text-align: center;
}
}
</style>
<template>
<div class="preview" v-loading="loading">
<template v-if="!loading">
<div class="preview-hd">
<el-steps align-center :active="options.length">
<template v-for="item in options">
<el-step
:title="item.title"
:status="progress.FILLING[item.code].progress === 1 ? 'success' : 'error'"
:key="item.code"
></el-step>
</template>
</el-steps>
</div>
<div class="preivew-bd">
<div
class="preview-item"
v-for="item in options"
:key="item.code"
:class="progress.FILLING[item.code].progress === 1 ? 'is-success' : 'is-error'"
>
<div class="preview-item-hd">
<div class="title">
{{ item.title }}
<template v-if="progress.FILLING[item.code].progress === 1">(已完善)</template>
<template v-else>(待完善)</template>
</div>
<div class="line"></div>
<el-button plain size="small" @click="handleEdit(item.edit.to)" v-if="hasEdit">编辑</el-button>
</div>
<div class="preview-item-bd">
<template v-if="item.computed">
<div v-html="item.computed(material[item.code])"></div>
</template>
<template v-else-if="item.isMultiple">
<div class="group" v-for="(data, index) in material[item.code]" :key="index">
<dl
v-for="subitem in item.items"
:key="subitem.code"
v-show="subitem.visible ? subitem.visible() : true"
>
<dt>{{ subitem.label }}</dt>
<dd>
<template v-if="subitem.computed">
<div v-html="subitem.computed(data)"></div>
</template>
<template v-else>{{ data[subitem.code] }}</template>
</dd>
</dl>
</div>
</template>
<template v-else>
<div class="group">
<dl v-for="subitem in item.items" :key="subitem.code">
<dt>{{ subitem.label }}</dt>
<dd>
<template v-if="subitem.computed">
<div v-html="subitem.computed(material[item.code])"></div>
</template>
<template v-else>{{ material[item.code][subitem.code] }}</template>
</dd>
</dl>
</div>
</template>
</div>
</div>
</div>
</template>
</div>
</template>
<script>
import * as api from '@/api/my'
// 行业类别
const industryList = [
{ label: '互联网/电子商务', value: '1 ' },
{ label: '基金/证券/期货/投资', value: '2 ' },
{ label: '保险', value: '3 ' },
{ label: '银行', value: '4 ' },
{ label: '信托/担保/拍卖/典当', value: '5 ' },
{ label: '计算机软件', value: '6 ' },
{ label: 'IT服务(系统/数据/维护)', value: '7 ' },
{ label: '电子技术/半导体/集成电路', value: '8 ' },
{ label: '计算机硬件', value: '9 ' },
{ label: '通信/电信/网络设备', value: '10' },
{ label: '通信/电信运营、增值服务', value: '11' },
{ label: '网络游戏', value: '12' },
{ label: '房地产/建筑/建材/工程', value: '13' },
{ label: '家居/室内设计/装饰装潢', value: '14' },
{ label: '物业管理/商业中心', value: '15' },
{ label: '专业服务/咨询(财会/法律/人力资源等)', value: '16' },
{ label: '广告/会展/公关', value: '17' },
{ label: '中介服务', value: '18' },
{ label: '检验/检测/认证', value: '19' },
{ label: '外包服务', value: '20' },
{ label: '快速消费品(食品/饮料/烟酒/日化)', value: '21' },
{ label: '耐用消费品(服饰/纺织/皮革/家具/家电)', value: '22' },
{ label: '贸易/进出口', value: '23' },
{ label: '零售/批发', value: '24' },
{ label: '租赁服务', value: '25' },
{ label: '教育/培训/院校', value: '26' },
{ label: '礼品/玩具/工艺美术/收藏品/奢侈品', value: '27' },
{ label: '汽车/摩托车', value: '28' },
{ label: '大型设备/机电设备/重工业', value: '29' },
{ label: '加工制造(原料加工/模具)', value: '30' },
{ label: '仪器仪表及工业自动化', value: '31' },
{ label: '印刷/包装/造纸', value: '32' },
{ label: '办公用品及设备', value: '33' },
{ label: '医药/生物工程', value: '34' },
{ label: '医疗设备/器械', value: '35' },
{ label: '航空/航天研究与制造', value: '36' },
{ label: '交通/运输,物流/仓储', value: '37' },
{ label: '医疗/护理/美容/保健/卫生服务', value: '38' },
{ label: '酒店/餐饮,旅游/度假,媒体/出版/影视/文化传播', value: '39' },
{ label: '娱乐/体育/休闲', value: '40' },
{ label: '能源/矿产/采掘/冶炼', value: '41' },
{ label: '石油/石化/化工,电气/电力/水利', value: '42' },
{ label: '环保', value: '43' },
{ label: '政府/公共事业/非盈利机构', value: '44' },
{ label: '学术/科研,农/林/牧/渔跨领域经营', value: '45' },
{ label: '其他', value: '90' }
]
export default {
name: 'Preview',
props: {
hasEdit: { type: Boolean, default: false },
hasContent: { type: Boolean, default: false }
},
data() {
return {
loading: false,
material: {},
progress: {},
options: [
{
title: '个人资料',
code: 'basic_info',
edit: {
to: { path: '/my/application', query: { active: 'application_info', tab: 'application_info_profile' } }
},
items: [
{ label: '姓名', code: 'real_name_cn' },
{
label: '现居住城市',
code: 'address_city',
computed(data) {
return `${data.address_province}-${data.address_city}`
}
},
{ label: '证件类型', code: 'id_type' },
{ label: '证件号码', code: 'id_number' },
{ label: '手机', code: 'phone_number' },
{ label: '邮箱', code: 'email' },
{ label: '性别', code: 'gender' },
{ label: '国籍', code: 'nationality' },
{ label: '生日', code: 'birthday' },
{ label: '微信号', code: 'we_chat_account' },
{ label: '邮寄地址', code: 'mailing_address' },
{ label: '紧急联系人', code: 'emergency_contact_name' },
{ label: '紧急联系人电话', code: 'emergency_contacts_phone' }
]
},
{
title: '教育背景',
code: 'educations',
edit: {
to: { path: '/my/application', query: { active: 'application_info', tab: 'application_info_education' } }
},
isMultiple: true,
items: [
{
label: '教育时间',
code: 'start_date',
computed(data) {
return `${data.start_date}${data.end_date}`
}
},
{ label: '专业名称', code: 'major_cn' },
{ label: '学校名称', code: 'school_name_cn' },
{ label: '学历/学位', code: 'degree' }
]
},
{
title: '工作经验',
code: 'careers',
edit: {
to: { path: '/my/application', query: { active: 'application_info', tab: 'application_info_career' } }
},
isMultiple: true,
items: [
{
label: '工作时间',
code: 'start_date',
computed(data) {
return `${data.start_date}${data.end_date}`
}
},
{ label: '工作单位', code: 'company_name_cn' },
{
label: '行业类别',
code: 'industry',
computed(data) {
const found = industryList.find(item => item.value === data.industry)
return found.label
}
},
{ label: '工作部门', code: 'dept_cn' },
{ label: '工作职位', code: 'position_cn' },
{ label: '工作描述', code: 'job_desc_cn' }
]
},
{
title: '学习目的',
code: 'answers',
edit: {
to: { path: '/my/application', query: { active: 'application_info', tab: 'application_info_answer' } }
},
computed(data = []) {
const result = data.map(item => {
return `<dl><dt>${item.question}</dt><dd>${item.answer}</dd></dl>`
})
return `<div class="answers">${result.join('')}</div>`
}
},
{
title: '所受培训',
code: 'trainings',
edit: {
to: { path: '/my/application', query: { active: 'application_info', tab: 'application_info_training' } }
},
isMultiple: true,
items: [
{
label: '培训时间',
code: 'start_date',
computed(data) {
return `${data.start_date}${data.end_date}`
}
},
{ label: '培训机构', code: 'institution_cn' },
{ label: '课程名称', code: 'course_cn' }
]
},
{
title: '荣誉奖励',
code: 'honors',
edit: {
to: { path: '/my/application', query: { active: 'application_info', tab: 'application_info_honor' } }
},
isMultiple: true,
items: [
{ label: '获取时间', code: 'time' },
{ label: '荣誉奖励', code: 'title' },
{ label: '证书颁发机构', code: 'institution_cn' }
]
},
{
title: '推荐信',
code: 'reco_letters',
edit: { to: { path: '/my/application', query: { active: 'application_tjx' } } },
isMultiple: true,
items: [
{ label: '推荐人姓名', code: 'provider_name' },
{ label: '推荐人电话', code: 'provider_phone_number' },
{ label: '推荐人邮箱', code: 'provider_email' },
{ label: '与推荐人关系', code: 'provider_relationship' },
{
label: '推荐信内容',
code: 'letter_content',
visible: () => {
return this.hasContent
}
}
]
},
{
title: '无犯罪证明',
code: 'attachments',
edit: { to: { path: '/my/application', query: { active: 'application_wfzzm' } } },
computed(data) {
const found = data.find(item => item.file_type_id === 'NO_CRIMINAL_CERT')
return found ? `<img src="${found.oss_sign_url}" style="max-width:300px;margin:10px 0;">` : ''
}
}
]
}
},
methods: {
// 获取报名信息
getApplication() {
this.loading = true
api.getApplication(this.$route.query).then(response => {
const { data, error, message } = response
if (error.toString() === '0') {
const { material, progress } = data
this.material = material
const missedRequiredList = progress.FILLING.attachments.missed_required_list
progress.FILLING.attachments.progress = missedRequiredList.NO_CRIMINAL_CERT ? 0 : 1
this.progress = progress
} else {
this.$message.error(message)
}
this.loading = false
})
},
handleEdit(to) {
this.$emit('edit', to)
// this.$router.push(to)
}
},
beforeMount() {
this.getApplication()
}
}
</script>
<style lang="scss" scoped>
.preview {
max-width: 750px;
min-height: 80vh;
padding: 20px;
margin: 0 auto;
background-color: #fff;
}
.preview-hd {
padding: 20px 0;
::v-deep .el-step__title {
font-size: 12px;
}
}
.preview-item {
margin: 20px;
}
.is-success {
color: #37a912;
.line {
background: linear-gradient(90deg, #37a912 0%, rgba(255, 218, 218, 0) 100%);
}
}
.is-error {
color: #da2a56;
.line {
background: linear-gradient(90deg, #da2a56 0%, rgba(255, 218, 218, 0) 100%);
}
}
.preview-item-hd {
display: flex;
align-items: center;
.title {
font-size: 18px;
font-weight: 600;
}
.line {
flex: 1;
height: 4px;
margin: 0 20px;
}
}
.preview-item-bd {
.group {
padding: 20px 0;
display: flex;
flex-wrap: wrap;
}
.group + .group {
border-top: 1px solid #f1f1f1;
}
dl {
flex: 50%;
display: flex;
margin-bottom: 10px;
font-size: 14px;
color: #222;
}
dt {
font-weight: bold;
}
dd {
flex: 1;
word-break: break-all;
}
}
</style>
<style lang="scss">
.preview {
.answers {
padding: 20px 0;
dl {
margin-bottom: 10px;
font-size: 14px;
color: #222;
& + dl {
margin-top: 20px;
}
}
dt {
font-weight: bold;
margin-bottom: 5px;
}
dd {
word-break: break-all;
}
}
}
</style>
export default {
id: 'interview_byz',
title: '学位证书',
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const { attachments = [], submission_stage: submissionStage = 'FILLING' } = data.data.material
const stageList = [
'FILLING',
'PREPAYMENT',
'INTERVIEW_APPLICATION',
'AUDITION',
'INTERVIEW',
'PAYMENT',
'REGISTRATION',
'CLOSED'
]
this.form.options.disabled = stageList.findIndex(item => item === submissionStage) > 2
const DEGREE_CERT_CN = attachments.filter(item => {
return item.file_type_id === 'DEGREE_CERT_CN'
})
return { DEGREE_CERT_CN }
}
},
form: {
next: { to: { query: { active: 'interview_cjd' } } },
hasButton: false,
options: {},
items: [
{
type: 'v-upload',
required: true,
model: 'DEGREE_CERT_CN',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'DEGREE_CERT_CN' },
accept: 'image/*'
},
append: '注意事项:需要将证书原件扫描或拍照后提交,请确保证书内容清晰可辨。'
}
]
}
}
export default {
id: 'interview_cjd',
title: '成绩单(中+英)',
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const { attachments = [], submission_stage: submissionStage = 'FILLING' } = data.data.material
const stageList = [
'FILLING',
'PREPAYMENT',
'INTERVIEW_APPLICATION',
'AUDITION',
'INTERVIEW',
'PAYMENT',
'REGISTRATION',
'CLOSED'
]
this.form.options.disabled = stageList.findIndex(item => item === submissionStage) > 2
return attachments.reduce(
(result, item) => {
if (item.file_type_id === 'REPORT_CARD_CN') {
result.REPORT_CARD_CN.push(item)
}
if (item.file_type_id === 'REPORT_CARD_EN') {
result.REPORT_CARD_EN.push(item)
}
return result
},
{ REPORT_CARD_CN: [], REPORT_CARD_EN: [] }
)
}
},
form: {
prev: { to: { query: { active: 'interview_byz' } } },
next: { to: { query: { active: 'interview_zp' } } },
hasButton: false,
options: { 'label-position': 'top' },
hint: `
<p>成绩单:中英文成绩单各上传一个文件</p>
<p>注意事项:需要将证书原件扫描或拍照后提交,请确保证书内容清晰可辨。</p>
`,
items: [
{
type: 'v-upload',
label: '中文成绩单',
required: true,
model: 'REPORT_CARD_CN',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'REPORT_CARD_CN' },
accept: 'image/*'
}
},
{
type: 'v-upload',
label: '英文成绩单',
required: true,
model: 'REPORT_CARD_EN',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'REPORT_CARD_EN' },
accept: 'image/*'
}
}
]
}
}
import byz from './byz'
import cjd from './cjd'
import zp from './zp'
export default function(_this) {
return {
id: 'interview',
title: '申请面试',
children: [byz, cjd, zp(_this)]
}
}
export default function(_this) {
return {
id: 'interview_zp',
title: '2寸照片',
get: {
action: `/api/enrollment/v1.0/application-materials/${webConf.others.projectId}`,
callback(data) {
const { attachments = [], submission_stage: submissionStage = 'FILLING' } = data.data.material
const stageList = [
'FILLING',
'PREPAYMENT',
'INTERVIEW_APPLICATION',
'AUDITION',
'INTERVIEW',
'PAYMENT',
'REGISTRATION',
'CLOSED'
]
this.form.options.disabled = stageList.findIndex(item => item === submissionStage) > 2
const PERSONAL_PHOTO_FOR_ID = attachments.filter(item => {
return item.file_type_id === 'PERSONAL_PHOTO_FOR_ID'
})
return { PERSONAL_PHOTO_FOR_ID }
}
},
update: {
action: `/api/enrollment/v1.0/application-materials/submit/${webConf.others.projectId}`,
beforeRequest(data) {
return { submission_stage: 'INTERVIEW_APPLICATION' }
},
callback() {
this.form.options.disabled = true
_this.dialogVisible = true
_this.getApplication()
},
errorCallback() {
_this.completeVisible = true
}
},
form: {
prev: { to: { query: { active: 'interview_cjd' } } },
submitText: '申请面试',
model: { submission_stage: 'INTERVIEW_APPLICATION' },
options: {},
items: [
{
type: 'v-upload',
model: 'PERSONAL_PHOTO_FOR_ID',
attrs: {
action: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/put`,
deleteAction: `/api/enrollment/v1.0/application-materials/attachments/${webConf.others.projectId}/delete`,
data: { file_type: 'PERSONAL_PHOTO_FOR_ID' },
accept: 'image/*'
},
prepend: '2寸照片:以电子版的形式上传文件',
append: '注意事项:需要将证书原件扫描或拍照后提交,请确保证书内容清晰可辨。'
}
]
}
}
}
<template>
<app-layout>
<vue-form
:menus="menus"
:default-active="currentActive"
@page-change="handlePageChange"
@success="handleSuccess"
@error="handleError"
@back="$router.push('/my')"
@prev="handlePrev"
@next="handleNext"
>
</vue-form>
<app-complete :type="1" v-model="completeVisible"></app-complete>
<el-dialog
title="资料提交成功"
:visible.sync="dialogVisible"
:center="true"
:close-on-click-modal="false"
width="348px"
>
<div class="dialog-tips">
<p>请注意接听康博斯威尔大学招办老师的邀约电话</p>
<div class="icon"><img src="../../../assets/images/icon_success.png" /></div>
</div>
<template #footer>
<el-button type="primary" @click="dialogVisible = false">我知道啦</el-button>
</template>
</el-dialog>
</app-layout>
</template>
<script>
import AppLayout from '../layout.vue'
import getMenu from './form'
import AppComplete from '../application/complete.vue'
import * as api from '@/api/my'
export default {
components: { AppLayout, AppComplete },
data() {
const menus = getMenu(this)
return {
menus: [menus],
currentActive: 'interview_byz',
completeVisible: false,
dialogVisible: false,
detail: null
}
},
watch: {
$route: {
immediate: true,
handler(route) {
const { query = {} } = route
this.currentActive = query.active || 'interview_byz'
}
},
showSubmitedDialog(value) {
this.dialogVisible = value
}
},
computed: {
isSubmited() {
const stageList = [
'FILLING',
'PREPAYMENT',
'INTERVIEW_APPLICATION',
'AUDITION',
'INTERVIEW',
'PAYMENT',
'REGISTRATION',
'CLOSED'
]
if (this.detail) {
return stageList.findIndex(item => item === this.detail.material.submission_stage) > 2
}
return false
},
showSubmitedDialog() {
return this.isSubmited && this.currentActive === 'interview_zp'
}
},
methods: {
// 获取报名信息
getApplication() {
api.getApplication().then(response => {
const { data, error, message } = response
if (error.toString() === '0') {
this.detail = data
} else {
this.$message.error(message)
}
})
},
handlePageChange(value) {
this.currentActive = value
this.$router.push({ path: this.$route.path, query: { active: value } })
console.log('页面切换了', value)
},
handleSuccess(data) {
this.getApplication()
console.log('提交成功了', data)
this.$message({ type: 'success', message: data.message })
},
handleError(data) {
console.log('提交失败了', data)
this.$message({ type: 'error', message: data.message })
},
handlePrev(to) {
this.$router.push(to)
},
handleNext(to) {
this.$router.push(to)
}
},
beforeMount() {
this.getApplication()
}
}
</script>
<style lang="scss" scoped>
.dialog-tips {
text-align: center;
p {
color: #262626;
line-height: 20px;
}
.icon {
margin-top: 20px;
text-align: center;
}
}
</style>
<template>
<div class="layout">
<div class="layout-hd">
<slot name="header">
<h1 class="title">在线报名</h1>
</slot>
</div>
<div class="layout-bd">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: {},
data() {
return {}
}
}
</script>
<style lang="scss" scoped>
.layout {
width: 1000px;
margin: 0 auto;
margin-top: 120px;
}
.layout-hd {
.title {
padding: 20px 0;
font-size: 18px;
line-height: 1;
color: var(--main-color);
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: var(--main-color);
}
}
.layout-bd {
margin: 20px 0;
}
::v-deep .v-layout-aside {
min-height: 410px;
}
</style>
......@@ -59,7 +59,7 @@ export default {
},
goback() {
this.$router.push({
name: 'apply-for'
name: 'apply'
})
},
transferKeep(item) {
......@@ -73,7 +73,7 @@ export default {
type: 'success'
})
this.$router.push({
name: 'apply-for'
name: 'apply'
})
} else {
this.$message.error(res.msg)
......
import Layout from '@/layout/index.vue'
import Layout from '@/components/layout/index.vue'
export const constantRoutes = [
{
path: '/redirect',
component: Layout,
hidden: true,
children: [
{
path: '/redirect/:path(.*)',
component: () => import('@/pages/redirect/index.vue')
}
]
},
{ path: '*', redirect: '/index' },
{
path: '/',
component: Layout,
redirect: '/home-page',
redirect: '/index',
children: [
{
path: 'home-page',
path: 'index',
component: () => import('@/pages/homepage/index.vue'),
meta: {
title: '首页'
},
name: 'home-page'
}
]
},
// 专业设置
{
path: '/major-set',
path: '/profession',
component: Layout,
children: [{ name: 'major-set', path: '', component: () => import('@/pages/major-set/index.vue') }]
},
// 最新动态
{
path: '/news',
component: Layout,
children: [
{ name: 'recent-news', path: '', component: () => import('@/pages/recent-news/index.vue') },
{
path: 'index',
component: () => import('@/pages/major-set/index.vue'),
meta: {
title: '专业设置'
},
name: 'major-set'
name: 'details-recent-news',
path: 'news/:id',
component: () => import('@/pages/details-news/index.vue'),
meta: { title: '最新动态', details: true }
}
]
},
// 联系我们
{
path: '/apply',
name: 'contact-us',
path: '/contact',
component: Layout,
children: [{ path: '', component: () => import('@/pages/contact-us/index.vue') }]
},
// 在线报名
{
path: '/my',
component: Layout,
meta: { title: '在线报名', details: true, userRole: true },
children: [
{
path: 'for',
component: () => import('@/pages/apply-for/index.vue'),
meta: {
details: true,
title: '报名申请'
},
name: 'apply-for'
},
{
path: 'for/register',
hidden: true,
component: () => import('@/pages/register/index.vue'),
meta: {
title: '注册',
details: true
},
name: 'register'
name: 'apply',
path: '',
component: () => import(/* webpackChunkName: "my-account" */ '@/pages/my/account/index.vue'),
meta: { userRole: true }
},
{
path: 'for/forgetPsw',
hidden: true,
component: () => import('@/pages/forgetPsw/index.vue'),
meta: {
title: '忘记密码',
details: true
},
name: 'forgetPsw'
path: 'application',
component: () => import(/* webpackChunkName: "my-application" */ '@/pages/my/application/index.vue'),
meta: { userRole: true }
},
{
path: 'for/apply',
hidden: true,
component: () => import('@/pages/apply/index.vue'),
meta: {
title: '在线报名',
details: true,
userRole: true
},
name: 'apply'
path: 'interview',
component: () => import(/* webpackChunkName: "my-interview" */ '@/pages/my/interview/index.vue'),
meta: { userRole: true }
},
{
path: 'for/login',
hidden: true,
component: () => import('@/pages/login/index.vue'),
meta: {
title: '登录',
details: true
},
name: 'login'
path: 'admission',
component: () => import(/* webpackChunkName: "my-admission" */ '@/pages/my/admission/index.vue'),
meta: { userRole: true }
}
]
},
// 推荐信
{
path: '/letter',
component: () => import(/* webpackChunkName: "letter" */ '@/pages/letter/index.vue')
},
{
path: '/application-materials/reco-letters/submit/:projectId/:userId/:letterId',
component: () => import(/* webpackChunkName: "letter" */ '@/pages/letter/index.vue')
},
// 登录
{
path: '/recent',
path: '/login',
component: Layout,
children: [
{
path: 'news',
component: () => import('@/pages/recent-news/index.vue'),
meta: {
title: '最新动态'
},
name: 'recent-news'
},
name: 'login',
path: '',
component: () => import(/* webpackChunkName: "passport" */ '@/pages/login/index.vue'),
meta: { details: true }
}
]
},
// 注册
{
path: '/register',
component: Layout,
children: [
{
path: 'news/:id',
meta: {
title: '最新动态',
details: true
},
hidden: true,
name: 'details-recent-news',
component: () => import('@/pages/details-news/index.vue')
name: 'register',
path: '',
component: () => import(/* webpackChunkName: "passport" */ '@/pages/register/index.vue'),
meta: { details: true }
}
]
},
// 忘记密码
{
path: '/contact',
path: '/password',
component: Layout,
children: [
{
path: 'us',
component: () => import('@/pages/contact-us/index.vue'),
meta: {
title: '联系我们'
},
name: 'contact-us'
name: 'forgetPsw',
path: '',
component: () => import(/* webpackChunkName: "passport" */ '@/pages/forgetPsw/index.vue'),
meta: { details: true }
}
]
},
{
path: '/preview',
props: { hasContent: true },
component: () => import(/* webpackChunkName: "preview" */ '@/pages/my/application/preview.vue')
},
{
path: '/complete',
component: () => import(/* webpackChunkName: "complete" */ '@/pages/my/application/complete.vue')
}
// { path: '*', redirect: '/404', hidden: true }
]
export default {
constantRoutes
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论