提交 cec39af2 authored 作者: lihuihui's avatar lihuihui

开发完成

上级 9ddd1b41
......@@ -4,7 +4,9 @@ module.exports = {
},
extends: ['plugin:vue/essential', 'standard'],
rules: {
'vue/no-mutating-props': 'off', // 暂时关闭
'vue/comment-directive': 'off',
'vue/multi-word-component-names': 'off',
'space-before-function-paren': 'off'
}
}
......@@ -7,8 +7,11 @@
"": {
"version": "0.0.0",
"dependencies": {
"@tinymce/tinymce-vue": "^3.2.8",
"axios": "^0.23.0",
"blueimp-md5": "^2.19.0",
"element-ui": "^2.15.6",
"qs": "^6.10.3",
"query-string": "^7.0.1",
"vue": "^2.6.14",
"vue-router": "^3.5.2",
......@@ -642,6 +645,14 @@
"node": ">= 8.0.0"
}
},
"node_modules/@tinymce/tinymce-vue": {
"version": "3.2.8",
"resolved": "https://registry.npmjs.org/@tinymce/tinymce-vue/-/tinymce-vue-3.2.8.tgz",
"integrity": "sha512-jEz+NZ0g+FZFz273OEUWz9QkwPMyjc5AJYyxOgu51O1Y5UaJ/6IUddXTX6A20mwCleEv5ebwNYdalviafx4fnA==",
"peerDependencies": {
"vue": "^2.4.3"
}
},
"node_modules/@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
......@@ -1859,6 +1870,11 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
"node_modules/blueimp-md5": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
"integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w=="
},
"node_modules/bowser": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz",
......@@ -1929,7 +1945,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
......@@ -3474,8 +3489,7 @@
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"node_modules/functional-red-black-tree": {
"version": "1.0.1",
......@@ -3496,7 +3510,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
......@@ -3628,7 +3641,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1"
},
......@@ -3670,7 +3682,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
......@@ -4446,7 +4457,6 @@
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
"integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
......@@ -4836,10 +4846,9 @@
}
},
"node_modules/qs": {
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
"integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
"dev": true,
"version": "6.10.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
"integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
"dependencies": {
"side-channel": "^1.0.4"
},
......@@ -5136,7 +5145,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
......@@ -6462,6 +6470,12 @@
"picomatch": "^2.2.2"
}
},
"@tinymce/tinymce-vue": {
"version": "3.2.8",
"resolved": "https://registry.npmjs.org/@tinymce/tinymce-vue/-/tinymce-vue-3.2.8.tgz",
"integrity": "sha512-jEz+NZ0g+FZFz273OEUWz9QkwPMyjc5AJYyxOgu51O1Y5UaJ/6IUddXTX6A20mwCleEv5ebwNYdalviafx4fnA==",
"requires": {}
},
"@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
......@@ -7549,6 +7563,11 @@
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
"blueimp-md5": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
"integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w=="
},
"bowser": {
"version": "1.9.4",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz",
......@@ -7603,7 +7622,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"dev": true,
"requires": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
......@@ -8719,8 +8737,7 @@
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"functional-red-black-tree": {
"version": "1.0.1",
......@@ -8738,7 +8755,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
"dev": true,
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
......@@ -8842,7 +8858,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"requires": {
"function-bind": "^1.1.1"
}
......@@ -8871,8 +8886,7 @@
"has-symbols": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
"dev": true
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
},
"has-tostringtag": {
"version": "1.0.0",
......@@ -9465,8 +9479,7 @@
"object-inspect": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
"integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
"dev": true
"integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg=="
},
"object-keys": {
"version": "1.1.1",
......@@ -9756,10 +9769,9 @@
"dev": true
},
"qs": {
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
"integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
"dev": true,
"version": "6.10.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
"integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
"requires": {
"side-channel": "^1.0.4"
}
......@@ -9991,7 +10003,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"dev": true,
"requires": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
......
......@@ -10,8 +10,11 @@
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src"
},
"dependencies": {
"@tinymce/tinymce-vue": "^3.2.8",
"axios": "^0.23.0",
"blueimp-md5": "^2.19.0",
"element-ui": "^2.15.6",
"qs": "^6.10.3",
"query-string": "^7.0.1",
"vue": "^2.6.14",
"vue-router": "^3.5.2",
......
......@@ -34,3 +34,8 @@ export function uploadFile(data) {
export function getPermissions(params) {
return httpRequest.get('/api/permissions/api/v1/user/permissions', { params })
}
// 获取可访问的所有项目
export function getCommonMap() {
return httpRequest.get('/api/register/v1/util/common-map')
}
......@@ -190,8 +190,8 @@ export default {
let params = this.params
// 翻页参数设置
if (this.hasPagination) {
params.page = (this.page.currentPage - 1).toString()
params.page_size = this.page.size.toString()
params.page = (this.page.currentPage).toString()
params['per-page'] = this.page.size.toString()
}
// 接口请求之前
if (beforeRequest) {
......@@ -205,9 +205,9 @@ export default {
this.loading = true
httpRequest(params)
.then(res => {
const { data = [], page_info: pageInfo = {} } = res || {}
this.page.total = parseInt(pageInfo.total_number || '')
this.dataList = callback ? callback(data) : data
const { data = [] } = res || {}
this.page.total = res.data.total
this.dataList = callback ? callback(data.list) : data.list
})
.catch(() => {
this.page.total = 0
......
......@@ -24,8 +24,8 @@ export default {
data() {
return {
menuList: [
{ name: '报名管理', path: '/register', icon: 'el-icon-notebook-2' },
{ name: '人员管理', path: '/test', icon: 'el-icon-user' }
{ name: '活动列表', path: '/activity/list', icon: 'el-icon-notebook-2' },
{ name: '报名列表', path: '/register/list', icon: 'el-icon-user' }
]
}
},
......
......@@ -12,7 +12,7 @@ export default {
data() {
return {
init: {
min_height: 600,
min_height: 400,
max_height: 600,
menubar: false,
statusbar: false,
......
import httpRequest from '@/utils/axios'
/**
* 获取应用列表
*/
export function getAppList(params) {
return httpRequest.get('/api/register/v1/activity/index', { params })
}
/**
* 新建报名
*/
export function createRegister(data) {
return httpRequest.post('/api/register/v1/activity/create', data)
}
/**
* 报名详情
*/
export function getRegisterDetail(params) {
return httpRequest.get('/api/register/v1/activity/view', { params })
}
/**
* 更新报名
*/
export function updateRegister(data) {
return httpRequest.post('/api/register/v1/activity/update', data)
}
/**
* 删除报名
*/
export function deleteRegister(data) {
return httpRequest.post('/api/register/v1/activity/delete', data)
}
<template>
<div>
<el-form ref="form" :rules="rules" :model="data" label-width="100px">
<el-form-item label="按钮文案:" prop="title">
<el-input v-model="data.title"></el-input>
</el-form-item>
<el-form-item label="页面展示:" prop="desc">
<v-editor v-model="data.desc"></v-editor>
</el-form-item>
</el-form>
</div>
</template>
<script>
import VEditor from '@/components/tinymce/Index.vue'
export default {
components: { VEditor },
props: {
data: { type: Object, default: () => {} }
},
data() {
return {
form: {
edit: '',
btnText: ''
},
rules: {
title: [
{ required: true, message: '请填写按钮文案', trigger: 'change' }
],
desc: [
{ required: true, message: '请填写页面内容', trigger: 'change' }
]
}
}
},
methods: {
submitForm() {
let flag = false
this.$refs.form.validate(valid => {
if (valid) {
flag = true
}
})
return flag
}
}
}
</script>
<style lang="scss">
.tox-notifications-container{
display: none !important;
}
</style>
<template>
<div class="form-box">
<el-form ref="form" :rules="rules" :model="data" size="mini" label-width="100px">
<div class="form-set-info">
<div class="sub-title">信息设置</div>
<el-checkbox-group v-model="checkList" @change="checkboxChange">
<div class="field-list" v-for="(item, index) in fieldList" :key="index">
<div class="field-list_title">{{ item.title }}</div>
<div class="field-list_content">
<el-checkbox style="margin:0 90px 10px 10px" :disabled="cItem.disabled ? cItem.disabled : false" :label="cItem.key" v-for="cItem in item.fields" :key="cItem.key">
<div class="checkbox">
{{ cItem.label }}&nbsp;&nbsp;&nbsp;必填:
<el-radio @change="checkboxChange" v-model="cItem.required" :disabled="cItem.disabled ? cItem.disabled : false" label="1"></el-radio>
<el-radio @change="checkboxChange" v-model="cItem.required" :disabled="cItem.disabled ? cItem.disabled : false" label="2"></el-radio>
</div>
</el-checkbox>
</div>
</div>
</el-checkbox-group>
</div>
<div class="form-set-pay">
<div class="sub-title">缴费设置</div>
<el-form-item label="缴费功能:">
<el-radio v-model="data.can_pay" :label="1">开启</el-radio>
<el-radio v-model="data.can_pay" :label="0">关闭</el-radio>
</el-form-item>
<template v-if="!!(data.can_pay)">
<el-form-item label="价格:" prop="pay_price">
<el-input style="width: 20%" v-model="data.pay_price"></el-input>
</el-form-item>
<el-form-item label="开票功能:">
<el-radio v-model="data.can_invoice" :label="1">开启</el-radio>
<el-radio v-model="data.can_invoice" :label="0">关闭</el-radio>
</el-form-item>
<el-form-item label="单位优惠:">
<el-radio v-model="data.can_company" :label="1">开启</el-radio>
<el-radio v-model="data.can_company" :label="0">关闭</el-radio>
</el-form-item>
<el-form-item label="跳转:">
<el-radio v-model="data.can_jump" :label="1">开启</el-radio>
<el-radio v-model="data.can_jump" :label="0">关闭</el-radio>
</el-form-item>
<template v-if="!!(data.can_jump)">
<el-form-item label="跳转链接:" prop="jump_url">
<el-input style="width: 20%" v-model="data.jump_url"></el-input>
</el-form-item>
</template>
<el-form-item label="跳过支付:">
<el-radio v-model="data.can_skip_pay" :label="1">开启</el-radio>
<el-radio v-model="data.can_skip_pay" :label="0">关闭</el-radio>
</el-form-item>
<el-form-item label="跳过文案:" prop="skip_pay_title" v-if="!!(data.can_skip_pay)">
<el-input style="width: 20%" v-model="data.skip_pay_title"></el-input>
</el-form-item>
<el-form-item label="支付平台:" prop="shop_id">
<el-select v-model="data.shop_id" placeholder="请选择">
<el-option v-for="item in shopMap" :key="item.key" :label="item.value" :value="item.key"> </el-option>
</el-select>
</el-form-item>
</template>
</div>
<div class="form-set-page">
<div class="sub-title">页面设置</div>
<el-form-item label="标题:" prop="title">
<el-input style="width: 20%" v-model="data.title"></el-input>
</el-form-item>
<el-form-item label="页面头部:" prop="desc">
<v-editor v-model="data.desc"></v-editor>
</el-form-item>
</div>
</el-form>
</div>
</template>
<script>
import VEditor from '@/components/tinymce/Index.vue'
export default {
components: { VEditor },
props: { data: { type: Object, default: () => {} } },
data() {
return {
rules: {
title: { required: true, message: '请填写标题', trigger: 'change' },
pay_price: { required: true, message: '请填写支付金额', trigger: 'change' },
jump_url: { required: true, message: '请填写跳转链接', trigger: 'change' },
shop_id: { required: true, message: '请选择支付平台', trigger: 'change' },
skip_pay_title: { required: true, message: '请填写跳过支付文案', trigger: 'change' }
},
options: [],
checkList: [],
fieldList: [
{
title: '个人信息',
fields: [
{ key: 'name', label: '姓名', required: '1', disabled: true },
{ key: 'mobile', label: '电话', required: '1', disabled: true },
{ key: 'gender', label: '性别', required: '1' },
{ key: 'email', label: '邮箱', required: '1' },
{ key: 'company', label: '公司', required: '1' },
{ key: 'position', label: '职位', required: '1' },
{ key: 'number', label: '编号', required: '1' },
{ key: 'country', label: '国籍', required: '1' },
{ key: 'provinces', label: '省份', required: '1' },
{ key: 'city', label: '城市', required: '1' },
{ key: 'address', label: '地址', required: '1' },
{ key: 'fixed_telephone', label: '固话', required: '1' },
{ key: 'industry', label: '行业', required: '1' },
{ key: 'id_number', label: '身份证号码', required: '1' }
]
},
{
title: '社交信息',
fields: [
{ key: 'wechat', label: '微信', required: '1' },
{ key: 'qq', label: 'QQ', required: '1' },
{ key: 'ding', label: '钉钉', required: '1' },
{ key: 'weibo', label: '微博', required: '1' }
]
},
{
title: '入住信息',
fields: [
{ key: 'check_in_time', label: '入住时间', required: '1' },
{ key: 'check_out_time', label: '离店时间', required: '1' },
{ key: 'room_type', label: '房型', required: '1' },
{ key: 'breakfast', label: '早餐', required: '1' }
]
}
]
}
},
computed: {
shopMap() {
return this.$store.state.commonMap.details_shop_map
}
},
mounted() {
this.setInfoFields()
},
methods: {
// 信息设置数据回显
setInfoFields() {
this.fieldList = this.fieldList.reduce((a, b) => {
b.fields.map(item => {
const findData = this.data.user_fields.find(fData => fData.key === item.key)
if (findData) {
this.checkList.push(findData.key)
item.required = findData.required ? '1' : '2'
}
return item
})
a.push(b)
return a
}, [])
},
// 信息设置选择后 吧选择的编程后台需要的数据
checkboxChange() {
this.data.user_fields = this.fieldList.reduce((a, b) => {
b.fields.forEach(item => {
const findData = this.checkList.find(fData => fData === item.key)
if (findData) {
a.push({ key: item.key, required: !!(item.required === '1'), enable_edit: true })
}
})
return a
}, [])
},
submitForm() {
let flag = false
this.$refs.form.validate(valid => {
if (valid) {
this.checkboxChange()
flag = true
}
})
return flag
}
}
}
</script>
<style lang="scss" scoped>
.sub-title {
line-height: 100%;
font-size: 16px;
font-weight: bold;
color: #333333;
border-left: 3px solid rgba(184, 1, 64, 1);
padding-left: 7px;
margin-bottom: 25px;
}
.form-box {
padding-top: 15px;
}
::v-deep {
.form-set-info {
.el-form-item__content {
display: flex;
align-items: center;
}
.el-icon-remove-outline {
font-size: 22px;
margin-left: 10px;
color: rgba(214, 214, 214, 1);
cursor: pointer;
}
.required {
margin-left: 15px;
}
}
}
.form-set-pay {
border-bottom: 1px solid #d6d6d6;
padding: 25px 0 15px;
}
.form-set-page {
padding: 25px 0 15px;
border-bottom: 1px solid #d6d6d6;
}
.form-set-info {
border-bottom: 1px solid #d6d6d6;
padding-bottom: 30px;
.field-list {
margin-bottom: 30px;
.field-list_title {
font-size: 16px;
font-weight: bold;
line-height: 100%;
color: #333333;
}
.field-list_content {
padding-top: 15px;
.checkbox {
display: flex;
align-items: center;
}
}
}
}
</style>
<template>
<div>
<el-form ref="form" :inline="true" :rules="rules" :model="form">
<el-form-item label="活动名称:" prop="name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="人数限制:" prop="max_number">
<el-input v-model="form.max_number"></el-input>
</el-form-item>
<el-form-item label="关联项目:" prop="project_id">
<el-select v-model="form.project_id" placeholder="请选择">
<el-option v-for="item in projectMap" :key="item.key" :label="item.value" :value="item.key"> </el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间:" prop="activity_time">
<el-date-picker
v-model="form.activity_time"
type="datetime"
@change="activityDateChange"
placeholder="选择日期时间">
</el-date-picker>
</el-form-item>
<el-form-item label="报名时间:" prop="time">
<el-date-picker
@change="dateChange"
v-model="form.time"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
props: {
form: { type: Object, default: () => {} }
},
data() {
return {
rules: {
name: { required: true, message: '请填写活动标题', trigger: 'change' },
max_number: { required: true, message: '请填写最大参与人数', trigger: 'change' },
project_id: { required: true, message: '请关联项目', trigger: 'change' },
time: { required: true, message: '请选择时间', trigger: 'change' },
activity_time: { required: true, message: '请选择时间', trigger: 'change' }
}
}
},
computed: {
projectMap() {
return this.$store.state.commonMap.project_map || {}
}
},
methods: {
submitForm() {
let flag = false
this.$refs.form.validate(valid => {
if (valid) {
flag = true
}
})
return flag
},
// 日期改变的时候。吧日期转成后台需要的格式
dateChange(date) {
this.form.start_time = this.setDate(date[0])
this.form.end_time = this.setDate(date[1])
},
setDate(val) {
const d = new Date(val)
const date = `${d.getFullYear()}-${this.toDo(d.getMonth() + 1)}-${this.toDo(d.getDate())} ${this.toDo(
d.getHours()
)}:${this.toDo(d.getMinutes())}:${this.toDo(d.getSeconds())}`
return date
},
toDo(n) {
return n < 10 ? `0${n}` : n
},
activityDateChange() {
this.form.activity_time = this.setDate(this.form.activity_time)
}
}
}
</script>
<style lang="scss" scoped>
</style>
......@@ -2,9 +2,12 @@ import AppLayout from '@/components/layout/Index.vue'
const routes = [
{
path: '/test',
path: '/activity',
component: AppLayout,
children: [{ path: '', component: () => import('./views/List.vue') }]
children: [
{ path: 'list', component: () => import('./views/List.vue') },
{ path: 'create', component: () => import('./views/Create.vue') }
]
}
]
......
<template>
<div class="create-box">
<div class="title">新建活动</div>
<div class="create-top">
<div class="sub-title">基本设置</div>
<set-basic :form="basicForm" ref="basicInfo" class="set-basic"></set-basic>
</div>
<div class="create-bottom">
<div class="sub-title">展示设置</div>
<div class="create-bottom_mian">
<el-tabs v-model="activeName">
<el-tab-pane
:name="`${index}`"
:label="`第${index + 1}步`"
v-for="(item, index) in stepPageInfo"
:key="index"
>
<display-page ref="display" :data="item" v-if="item.type == '1'" :key="index"></display-page>
<form-page ref="display" :data="item" v-if="item.type == '2'" :key="index"></form-page>
</el-tab-pane>
</el-tabs>
</div>
<div class="create-bottom_btn">
<el-button type="primary" style="margin-right: 80px">暂存配置</el-button>
<el-button type="primary" @click="handleAddPageClick">添加步骤</el-button>
<el-button @click="handleRemovePageClick">删除步骤</el-button>
</div>
</div>
<!-- 添加页面弹窗 -->
<el-dialog title="添加步骤" :visible.sync="dialogAddPageVisible" width="25%" center>
<div class="add-page_select">
<div class="label">步骤类型:</div>
<el-select v-model="dialogAddPageValue" placeholder="请选择">
<el-option v-for="item in dialogAddPageOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogAddPageVisible = false">取 消</el-button>
<el-button type="primary" @click="handleDialogAddPageClick">确 定</el-button>
</div>
</el-dialog>
<el-button type="primary" @click="handleCreate" style="display: block; margin: 30px auto" v-if="!$route.query.id"
>生成活动</el-button
>
<el-button type="primary" @click="handleUpdate" style="display: block; margin: 30px auto" v-else>确认</el-button>
</div>
</template>
<script>
import SetBasic from '../components/SetBasic.vue'
import FormPage from '../components/FormType.vue'
import DisplayPage from '../components/DisplayType.vue'
import { createRegister, getRegisterDetail, updateRegister } from '../api'
export default {
components: { SetBasic, FormPage, DisplayPage },
data() {
return {
// 添加步骤弹窗
dialogAddPageVisible: false,
dialogAddPageValue: '1',
dialogAddPageOptions: [
{ value: '1', label: '展示类型' },
{ value: '2', label: '表单类型' }
],
// 步骤页面
activeName: '0',
stepPageInfo: [
{
type: 1,
order: 1,
title: '',
desc: ''
}
],
basicForm: {
name: '',
max_number: '',
project_id: '',
time: '',
start_time: '',
end_time: '',
activity_time: ''
}
}
},
created() {
if (this.$route.query.id) {
this.getRegisterDetail()
}
},
methods: {
// 新建
handleCreate() {
if (this.isBaseicForm() && this.isDisplayModulesValidate() === -1) {
const params = Object.assign(this.basicForm, { details: this.stepPageInfo })
console.log(params, '123')
params.details.map(item => {
if (parseInt(item.type) === 2) {
item.user_fields = JSON.stringify(item.user_fields)
}
return item
})
createRegister(params).then(res => {
this.$message({
message: '创建成功',
type: 'success'
})
this.$router.push({ path: '/activity/list' })
})
}
},
// 编辑
handleUpdate() {
const params = Object.assign(this.basicForm, { details: this.stepPageInfo })
params.id = this.$route.query.id
params.details.map(item => {
if (parseInt(item.type) === 2) {
item.user_fields = JSON.stringify(item.user_fields)
}
return item
})
updateRegister(params).then(res => {
this.$message({
message: '更新成功',
type: 'success'
})
this.$router.push({ path: '/activity/list' })
})
},
// 点击添加页面按钮
handleAddPageClick() {
const index = this.isDisplayModulesValidate()
if (index === -1) {
this.dialogAddPageVisible = true
}
},
// 添加页面 && 跳转到添加的页面
handleDialogAddPageClick() {
// order字段递增
const order = this.stepPageInfo[this.stepPageInfo.length - 1].order + 1
// 展示类型页面数据结构
const displayData = {
type: 1,
order: order,
title: '',
desc: ''
}
// 表单类型页面数据结构
const FormData = {
type: 2,
order: order,
title: '',
desc: '',
can_pay: 0,
pay_price: '0.00',
can_invoice: 0,
can_company: 0,
can_jump: 0,
jump_url: '',
shop_id: '',
pay_type: '2',
can_skip_pay: 0,
user_fields: [
{ key: 'name', required: true, enable_edit: true },
{ key: 'mobile', required: true, enable_edit: true }
]
}
this.stepPageInfo.push(parseInt(this.dialogAddPageValue) === 1 ? displayData : FormData)
this.dialogAddPageVisible = false
this.activeName = (this.stepPageInfo.length - 1).toString()
},
// 校验展示设置有没有未填写字段,有的话跳转到未填的表单
isDisplayModulesValidate() {
const index = this.$refs.display.findIndex(item => (item.submitForm ? !item.submitForm() : false))
if (index !== -1) {
this.activeName = index.toString()
}
return index
},
// 校验必填字段有没有未填写
// 删除页面
handleRemovePageClick() {
if (this.stepPageInfo.length > 1) {
this.stepPageInfo = this.stepPageInfo.filter((item, index) => index !== parseInt(this.activeName))
this.activeName = (this.activeName === '0' ? '0' : this.activeName - 1).toString()
}
},
// 点击提交钮判断基本信息是否填写
isBaseicForm() {
return this.$refs.basicInfo.submitForm()
},
// 编辑
getRegisterDetail() {
getRegisterDetail({ id: this.$route.query.id }).then(res => {
const arrDate = []
Object.keys(this.basicForm).forEach(item => {
this.basicForm[item] = res.data[item]
if (item === 'start_time' || item === 'end_time') {
arrDate.push(res.data[item])
}
this.basicForm.time = arrDate
})
this.stepPageInfo = res.data.details.map(item => {
if (parseInt(item.type) === 2) {
item.user_fields = JSON.parse(item.user_fields)
}
return item
})
console.log(this.basicForm)
console.log(res)
})
}
}
}
</script>
<style lang="scss" scoped>
.create-box {
padding: 20px;
.title {
font-size: 18px;
line-height: 100%;
color: #333333;
margin-bottom: 20px;
}
.create-top {
background: #fff;
padding: 30px 30px 15px;
.set-basic {
margin-top: 20px;
}
}
.sub-title {
line-height: 100%;
font-size: 16px;
font-weight: bold;
color: #333333;
border-left: 3px solid rgba(184, 1, 64, 1);
padding-left: 7px;
}
.create-bottom {
background: #fff;
padding: 30px 30px 15px;
margin-top: 20px;
.create-bottom_mian {
margin-top: 30px;
}
}
.add-page_select {
display: flex;
align-items: center;
justify-content: center;
.label {
margin-right: 5px;
}
}
}
.create-bottom_btn {
margin-top: 15px;
}
</style>
<template>
<app-card class="register-box">
<app-list v-bind="tableOptions" ref="list">
<div class="line"></div>
<div class="btn-box">
<el-button type="primary" @click="$router.push({ path: '/activity/create' })">新建活动</el-button>
<!-- <el-button type="primary">表头设置</el-button> -->
</div>
<template v-slot:table-x="{ row }">
<el-button type="text" v-if="!row.isEdit" @click="handleUpdate(row)">编辑</el-button>
<el-button type="text" v-if="!row.isEdit" @click="deleteRegister(row)">删除</el-button>
<el-button type="text" @click="onRemove(row)">复制活动链接</el-button>
</template>
</app-list>
</app-card>
</template>
<script>
// 接口
import { getAppList, deleteRegister } from '../api'
export default {
data() {
return {
value1: ''
}
},
computed: {
projectMap() {
return this.$store.state.commonMap.project_map
},
// 列表配置
tableOptions() {
return {
hasPagination: true,
limit: 10,
remote: {
httpRequest: getAppList,
params: { name: '' },
beforeRequest: this.beforeRequest,
callback: data => {
data.map(item => {
const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24)
if (getDaysDiffBetweenDates(new Date(), new Date(item.start_time)) < 0) {
item.isEdit = true
}
item.project_id = this.projectMap.find(project => project.key === item.project_id).value
return item
})
return data
}
},
filters: [
{
type: 'input',
prop: 'name',
label: '活动名称'
},
{
type: 'input',
prop: 'id',
label: '活动id'
},
{
type: 'select',
prop: 'project_id',
options: this.projectMap,
labelKey: 'value',
valueKey: 'key',
label: '项目筛选'
}
],
columns: [
{ label: 'id', prop: 'id', align: 'center' },
{ label: '活动名称', prop: 'name', align: 'center' },
{ label: '报名人数', prop: 'join_number', align: 'center' },
{ label: '活动日期', prop: 'activity_time', align: 'center' },
{ label: '报名开始日期', prop: 'start_time', align: 'center' },
{ label: '报名结束日期', prop: 'end_time', align: 'center' },
{ label: '关联项目', prop: 'project_id', align: 'center' },
{ label: '操作', slots: 'table-x', align: 'center' }
]
}
}
},
mounted() {
},
methods: {
beforeRequest(params, isReset) {
// 重置
if (isReset) {
params.price_min = ''
params.price_max = ''
}
params.status = this.activeName === '0' ? '' : this.activeName
params.price_zone = `${params.price_min || ''},${params.price_max || ''}`
return params
},
handleClick() {
this.$refs.list.refetch(true)
},
handleUpdate(row) {
this.$router.push({ path: '/activity/create', query: { id: row.id } })
},
deleteRegister(row) {
deleteRegister({ id: row.id }).then(
this.$refs.list.refetch(true)
)
}
}
}
</script>
<style lang="scss">
.register-box {
.el-form-item {
margin-right: 20px !important;
}
.line {
// border-top: 1px solid #D6D6D6;
height: 1px;
background: #d6d6d6;
margin: 8px 0 23px;
box-sizing: border-box;
}
.btn-box {
margin-bottom: 16px;
}
}
</style>
const routes = [
{
path: '/401',
component: () => import('./views/401.vue')
},
{
name: 'browser',
path: '/browser',
component: () => import('./views/browser.vue')
}
]
export { routes }
差异被折叠。
<template>
<div class="container">
<div class="box">
<h1 class="tips">你的浏览器版本较低,请升级你的浏览器。</h1>
<div class="list">
<ul>
<li v-for="item in browserList" :key="item.name">
<a :href="item.href" target="_blank">
<img :src="item.logoUrl" />
<p class="t1">{{ item.name }}</p>
<p class="t2">{{ item.company }}</p>
</a>
</li>
</ul>
</div>
</div>
<p class="ua">{{ UA }}</p>
</div>
</template>
<script>
export default {
data() {
const UA = window.navigator.userAgent
const isIe = window.ActiveXObject || 'ActiveXObject' in window
return {
UA,
isIe,
browserList: [
{
name: 'Chrome',
company: 'Google',
href: 'https://www.google.cn/chrome',
logoUrl: 'https://webapp-pub.ezijing.com/website/base/images/chrome.png'
},
{
name: 'Edge',
company: 'Microsoft',
href: 'https://www.microsoft.com/edge',
logoUrl: 'https://webapp-pub.ezijing.com/website/base/images/edge.png'
},
{
name: 'Firefox',
company: 'Mozilla Foundation',
href: 'https://download.mozilla.org',
logoUrl: 'https://webapp-pub.ezijing.com/website/base/images/firefox.png'
}
]
}
},
beforeMount() {
!this.isIe && this.$router.replace('/')
}
}
</script>
<style lang="scss" scoped>
.container {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.box {
width: 700px;
background-color: #f4f5f7;
border-radius: 10px;
}
.tips {
margin: 30px;
font-size: 24px;
color: #172b4d;
text-align: center;
}
ul {
margin: 0;
padding: 0;
display: flex;
list-style: none;
li {
flex: 1;
padding: 40px;
text-align: center;
}
img {
width: 100px;
}
p {
margin: 0;
text-align: center;
}
.t1 {
color: #e25600;
}
.t2 {
color: #aaa;
text-decoration: none;
}
a {
text-decoration: none;
}
}
.ua {
font-size: 12px;
margin: 20px;
}
</style>
import httpRequest from '@/utils/axios'
/**
* 获取商品列表
* 获取应用列表
*/
export function getGoodsList(data) {
return httpRequest.post('/api/shop/commodity/spu/search', data).then({})
export function getAppList(params) {
return httpRequest.get('/api/register/v1/records/index', { params })
}
/**
* 删除报名步骤
*/
export function deletePay(data) {
return httpRequest.post('/api/register/v1/records/delete-pay', data)
}
/**
* 删除报名记录
*/
export function deleteJoin(data) {
return httpRequest.post('/api/register/v1/records/delete-join', data)
}
/**
* 导入
*/
export function importPeople(data) {
return httpRequest({
url: '/api/register/v1/records/import',
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' },
timeout: 900000,
data,
withCredentials: true
})
}
/**
* 获取应用列表
*/
export function getActivityList() {
return httpRequest.get('/api/register/v1/records/activity-list')
}
/**
* 报名记录详情
*/
export function getRecordsDetail(params) {
return httpRequest.get('/api/register/v1/records/view', { params })
}
/**
* 报名记录-缴费弹窗
*/
export function getPayList(params) {
return httpRequest.get('/api/register/v1/records/pay-list', { params })
}
/**
* 获取二维码
*/
export function recordsQr(data) {
return httpRequest.post('/api/register/v1/records/qr', data)
}
/**
* 保存报名记录信息
*/
export function updateRecords(data) {
return httpRequest.post('/api/register/v1/records/update', data)
}
<template>
<div class="pay-list">
<div class="item" v-for="(item, index) in checkList" :key="index">
<div class="title">{{ item.title }}</div>
<div class="checkbox">
<el-checkbox-group v-model="item.form">
<el-checkbox
:disabled="item.isDisabled"
v-for="opt in item.option"
:key="opt.id"
style="margin-bottom: 15px"
:label="opt.id"
>{{ opt.user_name }}</el-checkbox
>
</el-checkbox-group>
<el-button type="primary" @click="recordsQr(index)">生成支付链接</el-button>
</div>
</div>
</div>
</template>
<script>
import { getPayList, recordsQr } from '../api.js'
export default {
data() {
return {
checkList: []
}
},
mounted() {
this.getPayList()
},
methods: {
getPayList() {
getPayList({ join_id: this.$route.query.id }).then(res => {
this.checkList = res.data.reduce((a, b) => {
const datas = { title: b[0].title }
datas.option = []
datas.form = []
b.forEach(item => {
const params = { user_name: item.user_name, id: item.id, isDisabled: !!parseInt(item.pay_status) }
!parseInt(item.pay_status) && datas.form.push(item.id)
datas.option.push(params)
})
a.push(datas)
return a
}, [])
console.log(this.checkList, 'list')
})
},
recordsQr(index) {
console.log(this.checkList[index].form, 'form')
recordsQr({ pay_record_ids: this.checkList[index].form.join() }).then(res => {
this.copyToClipboard(res.data.url)
})
},
copyToClipboard(str) {
const el = document.createElement('textarea')
el.value = str
el.setAttribute('readonly', '')
el.style.position = 'absolute'
el.style.left = '-9999px'
document.body.appendChild(el)
const selected = document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false
el.select()
document.execCommand('copy')
document.body.removeChild(el)
if (selected) {
document.getSelection().removeAllRanges()
document.getSelection().addRange(selected)
}
this.$message({
message: '已复制',
type: 'success'
})
}
}
}
</script>
<style lang="scss" scoped>
.pay-list {
display: flex;
justify-content: center;
.item {
margin-right: 40px;
.title {
font-weight: bold;
color: #333333;
font-size: 18px;
margin-bottom: 10px;
}
}
.checkbox {
width: 100px;
}
}
</style>
<template>
<div>
<el-form ref="form" :inline="true" :model="form">
<template v-for="(item, index) in dataList">
<el-form-item :label="item.name" v-if="item.type === 'input'" :key="index">
<el-input :disabled="item.enable_edit" v-model="form[item.key]"></el-input>
</el-form-item>
<el-form-item :label="item.name" v-if="item.type === 'radio'" :key="index">
<el-radio :key="cIndex" v-for="(opt, cIndex) in item.optionList" v-model="form[item.key]" :label="opt.id">{{
opt.option
}}</el-radio>
</el-form-item>
<el-form-item :label="item.name" v-if="item.type === 'select'" :key="index">
<el-select v-model="value" placeholder="请选择">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</el-form-item>
</template>
</el-form>
<el-button type="primary" @click="onSubmit">确认修改</el-button>
</div>
</template>
<script>
import { updateRecords } from '../api.js'
export default {
props: {
infoData: { type: Object, default: () => {} }
},
data() {
return {
dataList: [],
allFormList: [
{
type: 'input',
name: '姓名',
placeholder: '请输入姓名',
required: true,
key: 'name',
value: '',
enable_edit: false
},
{
type: 'input',
name: '电话',
placeholder: '请输入电话',
required: true,
key: 'mobile',
value: '',
enable_edit: true
},
{
type: 'radio',
name: '性别',
key: 'gender',
required: true,
value: '',
optionList: [
{ id: '0', option: '未知' },
{ id: '1', option: '男' },
{ id: '2', option: '女' }
]
},
{
type: 'input',
name: '邮箱',
placeholder: '请输入邮箱',
required: true,
key: 'email',
value: '',
enable_edit: true
},
{
type: 'input',
name: '公司',
placeholder: '请输入公司',
required: true,
key: 'company',
value: '',
enable_edit: true
},
{
type: 'input',
name: '职位',
placeholder: '请输入职位',
required: true,
key: 'position',
value: '',
enable_edit: true
},
{
type: 'input',
name: '身份证号码',
placeholder: '请输入身份证号码',
required: true,
key: 'id_number',
value: '',
enable_edit: true
},
{
type: 'input',
name: '编号',
placeholder: '请输入编号',
required: true,
key: 'number',
value: '',
enable_edit: true
},
{
type: 'input',
name: '国籍',
placeholder: '请输入国籍',
required: true,
key: 'country',
value: '',
enable_edit: true
},
{
type: 'input',
name: '省份',
placeholder: '请输入省份',
required: true,
key: 'provinces',
value: '',
enable_edit: true
},
{
type: 'input',
name: '城市',
placeholder: '请输入城市',
required: true,
key: 'city',
value: '',
enable_edit: true
},
{
type: 'input',
name: '地址',
placeholder: '请输入地址',
required: true,
key: 'address',
value: '',
enable_edit: true
},
{
type: 'input',
name: '固话',
placeholder: '请输入固话',
required: true,
key: 'fixed_telephone',
value: '',
enable_edit: true
},
{
type: 'input',
name: '行业',
placeholder: '请输入行业',
required: true,
key: 'industry',
value: '',
enable_edit: true
},
{ type: 'input', name: 'QQ', placeholder: '请输入QQ', required: true, key: 'qq', value: '', enable_edit: true },
{
type: 'input',
name: '微信',
placeholder: '请输入微信',
required: true,
key: 'wechat',
value: '',
enable_edit: true
},
{
type: 'input',
name: '钉钉',
placeholder: '请输入钉钉',
required: true,
key: 'ding',
value: '',
enable_edit: true
},
{
type: 'input',
name: '微博',
placeholder: '请输入微博',
required: true,
key: 'weibo',
value: '',
enable_edit: true
},
{
type: 'select',
name: '早餐',
key: 'breakfast',
placeholder: '请选择早餐',
rue: '',
value: '',
required: true,
optionList: ['有', '无'],
showPicker: false
},
{
type: 'select',
name: '房型',
key: 'room_type',
placeholder: '请选择房型',
required: true,
value: '',
enable_edit: true,
optionList: ['温馨大床房', '豪华标准间', '豪华套房'],
showPicker: false
},
{
type: 'datetime',
name: '入住时间',
key: 'check_in_time',
placeholder: '请选择入住时间',
required: true,
value: '',
enable_edit: true,
optionList: [],
showPicker: false
},
{
type: 'datetime',
name: '离店时间',
key: 'check_out_time',
placeholder: '请选择离店时间',
required: true,
value: '',
enable_edit: true,
optionList: [],
showPicker: false
}
],
form: {
name: '',
mobile: '',
gender: '',
email: '',
company: '',
position: '',
id_number: '',
number: '',
country: '',
provinces: '',
city: '',
address: '',
fixed_telephone: '',
industry: '',
qq: '',
wechat: '',
ding: '',
weibo: '',
breakfast: '',
room_type: '',
check_in_time: '',
check_out_time: ''
},
options: []
}
},
mounted() {
this.setForm()
},
methods: {
setForm() {
const formData = []
console.log(this.infoData)
Object.keys(this.infoData).forEach(item => {
if (this.infoData[item] !== '') {
const find = this.allFormList.find(cItem => cItem.key === item)
if (find) {
this.form[item] = this.infoData[item]
formData.push(find)
}
}
})
this.dataList = formData
console.log(this.dataList, 'fordata')
},
onSubmit() {
this.form.id = this.$route.query.id
updateRecords(this.form).then(res => {
this.$message({
message: '修改成功',
type: 'success'
})
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template>
<el-dialog v-bind="$attrs" v-on="$listeners" center>
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="活动名称" prop="activity_id">
<el-select @change="change" v-model="form.activity_id" placeholder="请选择">
<el-option v-for="(item, index) in activityOption" :label="item.name" :value="item.id" :key="index"></el-option>
</el-select>
</el-form-item>
<el-form-item label="步骤名称" prop="activity_detail_id">
<el-select v-model="form.activity_detail_id" placeholder="请选择">
<el-option v-for="(item, index) in stepOption" :label="item.title" :value="item.id" :key="index"></el-option>
</el-select>
</el-form-item>
</el-form>
<el-upload
style="text-align: center"
class="file-import"
ref="upload"
action="#"
:auto-upload="false"
:file-list="fileList"
:limit="1"
:before-upload="beforeUpload"
:http-request="fetchFileUpload"
accept=".xls,.xlsx"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
<div style="text-align: center">
<a
:href="file"
download="试题模板.xlsx"
style="color: #c01c40"
>
<i class="el-icon-download"></i>试题模板.xlsx</a
>
<!-- <a href="https://webapp-pub.oss-cn-beijing.aliyuncs.com/qbs/question.xlsx" :download="试题模版"></a> -->
</div>
<div style="text-align: center; margin-top: 15px">
<el-button size="mini" @click="cancel">取消</el-button>
<el-button type="primary" size="mini" @click="submitUpload" style="margin-right: 5px"> 确认提交</el-button>
</div>
</el-dialog>
</template>
<script>
import { splitStrLast } from '@/utils/util'
import { importPeople, getActivityList } from '../api'
export default {
data() {
return {
form: {
activity_id: '',
activity_detail_id: ''
},
rules: {
activity_id: [
{ required: true, message: '请选择', trigger: 'change' }
],
activity_detail_id: [
{ required: true, message: '请选择', trigger: 'change' }
]
},
file: '',
activityOption: [],
stepOption: [],
fileList: []
}
},
computed: {
activeProject() {
return this.$store.state.activeProject || {}
}
},
mounted() {
this.getActivityList()
},
methods: {
change() {
this.form.activity_detail_id = ''
this.stepOption = this.activityOption.find(item => item.id === this.form.activity_id).details
},
getActivityList() {
getActivityList().then(res => {
this.activityOption = res.data.activity_list
this.file = res.data.file
})
},
beforeUpload(file) {
const suffix = splitStrLast(file.name, '.')
if (!['xlsx', 'xls'].includes(suffix)) {
this.$message.error('只能上传excel文件')
return false
} else {
return true
}
},
fetchFileUpload(data) {
importPeople({ file: data.file, activity_id: this.form.activity_id, activity_detail_id: this.form.activity_detail_id }).then(res => {
if (res.code === 0) {
this.$message.success('导入数据成功')
history.go(0)
}
})
},
submitUpload() {
this.$refs.upload.submit()
},
cancel() {
this.$router.push({
name: 'teacher'
})
}
}
}
</script>
<template>
<div>
<el-dialog v-bind="$attrs" v-on="$listeners" title="表头设置" width="500px" :close-on-click-modal="false">
<p class="tips">上下拖动表头名称可调整表头顺序</p>
<ul class="column-options-list">
<li>
<div class="name">表头名称</div>
<div class="actions">隐藏/显示</div>
</li>
<!-- <draggable v-model="editableColumns"> -->
<li v-for="(item, index) in tabelField" :key="index">
<div class="name">{{ item.label }}</div>
<div class="actions"><el-switch v-model="item.visible"></el-switch></div>
</li>
<!-- </draggable> -->
</ul>
<template #footer>
<el-button type="text" @click="$emit('closeSetHeader')">取消</el-button>
<el-button type="primary" @click="$emit('handleConfirm')">保存</el-button>
</template>
</el-dialog>
</div>
</template>
<script>
export default {
props: {
tabelField: { type: Array }
},
data() {
return {
columnsOptionsVisible: false
}
},
mounted() {
},
methods: {
// handleSubmit() {
// window.localStorage.registerTabelField = JSON.stringify(this.tabelField)
// this.$emit('closeSetHeader')
// }
}
}
</script>
<style lang="scss">
.table-list {
height: 100%;
display: flex;
flex-direction: column;
box-sizing: border-box;
}
.table-list-hd {
display: flex;
}
.table-list-filter {
flex: 1;
}
.table-list-bd {
flex: 1;
}
.table-list-ft {
display: flex;
align-items: center;
justify-content: space-between;
}
.table-list-pagination {
padding: 10px 0;
text-align: right;
}
.el-table-column--selection .cell {
padding: 0 14px !important;
}
.more-filter-drawer {
height: 100%;
display: flex;
flex-direction: column;
padding: 0 20px 20px;
box-sizing: border-box;
}
.more-filter {
flex: 1;
overflow-y: auto;
}
.more-filter-buttons {
display: flex;
.el-button {
flex: 1;
}
}
.column-options-list {
// padding: 20px 0;
list-style: none;
li {
padding: 10px 0;
display: flex;
justify-content: space-between;
background-color: #fff;
// border: 1px solid rgba(0, 0, 0, 0.125);
// margin-bottom: -1px;
cursor: move;
// &:hover {
// background-color: #ebf1ff;
// }
}
}
</style>
......@@ -4,7 +4,10 @@ const routes = [
{
path: '/register',
component: AppLayout,
children: [{ path: '', component: () => import('./views/List.vue') }]
children: [
{ path: 'list', component: () => import('./views/List.vue') },
{ path: 'detail', component: () => import('./views/Detail.vue') }
]
}
]
......
<template>
<div class="create-box">
<div class="title">新建报名</div>
<div class="create-top">
<div class="sub-title">基本设置</div>
<set-basic class="set-basic"></set-basic>
</div>
<div class="create-bottom">
<div class="sub-title">展示设置</div>
<div class="create-bottom_mian">
<el-tabs @tab-click="handleClick" v-model="activeName">
<el-tab-pane :name="`${index}`" :label="`第${index + 1}步`" v-for="(item, index) in stepPageInfo" :key="index">
<display-page ref="display" v-if="item.type == '1'" :key="index"></display-page>
<form-page ref="display" v-if="item.type == '2'" :key="index"></form-page>
</el-tab-pane>
</el-tabs>
</div>
<div class="create-bottom_btn">
<el-button type="primary" style="margin-right:80px">暂存配置</el-button>
<el-button type="primary" @click="handleAddPageClick">添加步骤</el-button>
<el-button @click="handleRemovePageClick">删除步骤</el-button>
</div>
</div>
<!-- 添加页面弹窗 -->
<el-dialog title="添加步骤" :visible.sync="dialogAddPageVisible" width="25%" center>
<div class="add-page_select">
<div class="label">步骤类型:</div>
<el-select v-model="dialogAddPageValue" placeholder="请选择">
<el-option v-for="item in dialogAddPageOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogAddPageVisible = false">取 消</el-button>
<el-button type="primary" @click="handleDialogAddPageClick">确 定</el-button>
</div>
</el-dialog>
<el-button type="primary" @click="handleAddPageClick" style="display:block;margin:30px auto">生成报名</el-button>
</div>
</template>
<script>
import SetBasic from '../components/SetBasic.vue'
import FormPage from '../components/FormType.vue'
import DisplayPage from '../components/DisplayType.vue'
export default {
components: { SetBasic, FormPage, DisplayPage },
data() {
return {
// 添加步骤弹窗
dialogAddPageVisible: false,
dialogAddPageValue: '1',
dialogAddPageOptions: [
{ value: '1', label: '展示类型' },
{ value: '2', label: '表单类型' }
],
// 步骤页面
activeName: '0',
stepPageInfo: [
{
type: '1',
index: 0
}
]
}
},
methods: {
handleClick(tab, event) {
// console.log(tab, event)
},
handleAddPageClick() {
this.isDisplayPageForm()
},
// 添加页面 && 跳转到添加的页面
handleDialogAddPageClick() {
this.stepPageInfo.push({ type: this.dialogAddPageValue, index: this.stepPageInfo.length })
this.dialogAddPageVisible = false
this.activeName = (this.stepPageInfo.length - 1).toString()
},
// 点击添加步骤按钮判断
isDisplayPageForm() {
const isFormValue = this.$refs.display.findIndex(item => item.submitForm ? !item.submitForm() : false)
if (isFormValue === -1) {
this.dialogAddPageVisible = true
} else {
this.activeName = isFormValue.toString()
}
},
// 删除页面
handleRemovePageClick() {
if (this.stepPageInfo.length > 1) {
this.stepPageInfo = this.stepPageInfo.filter((item, index) => index !== parseInt(this.activeName))
this.activeName = (this.activeName === '0' ? '0' : this.activeName - 1).toString()
}
}
}
}
</script>
<style lang="scss" scoped>
.create-box {
padding: 20px;
.title {
font-size: 18px;
line-height: 100%;
color: #333333;
margin-bottom: 20px;
}
.create-top {
background: #fff;
padding: 30px 30px 15px;
.set-basic {
margin-top: 20px;
}
}
.sub-title {
line-height: 100%;
font-size: 16px;
font-weight: bold;
color: #333333;
border-left: 3px solid rgba(184, 1, 64, 1);
padding-left: 7px;
}
.create-bottom {
background: #fff;
padding: 30px 30px 15px;
margin-top: 20px;
.create-bottom_mian {
margin-top: 30px;
}
}
.add-page_select{
display: flex;
align-items: center;
justify-content: center;
.label{
margin-right: 5px;
}
}
}
.create-bottom_btn{
margin-top: 15px;
}
</style>
<template>
<div class="detail-box">
<div class="title">报名详情</div>
<div class="detail-top">
<div class="sub-title">基本信息</div>
<set-basic v-if="Object.keys(infoData).length" :infoData="infoData" class="set-basic"></set-basic>
</div>
<div class="detail-bottom" v-if="tableData.length">
<div class="sub-title">人员信息</div>
<el-form ref="form" :inline="true" :model="form" label-width="80px" style="margin-top: 20px">
<el-form-item label="姓名">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="电话">
<el-input v-model="form.mobile"></el-input>
</el-form-item>
<el-form-item v-for="(item, index) in payStatus" :key="index" :label="item.title">
<el-radio v-model="item.value" label="0">未支付</el-radio>
<el-radio v-model="item.value" label="1">已支付</el-radio>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getRecordsDetail">搜索</el-button>
</el-form-item>
</el-form>
<div class="line"></div>
<div class="tabel-list">
<div class="table-list_btns">
<el-button type="primary" @click="dialogVisible = true">全部人员缴费</el-button>
<el-button type="primary" @click="columnsOptionsVisible = true">表头筛选</el-button>
</div>
<el-table :data="tableData" style="width: 100%">
<el-table-column type="expand">
<template slot-scope="props">
<div class="demo-table-expand">
<div class="li" v-for="(item, index) in props.row.pay_records" :key="index">
<div class="item">
步骤名称:<span>{{ item.title }}</span>
</div>
<div class="item">
归属人名称:<span>{{ item.belong_user_name }}</span>
</div>
<div class="item">
归属人id:<span>{{ item.belong_user_id }}</span>
</div>
<div class="item">
缴费状态:<span>{{ parseInt(item.pay_status) ? '已支付' : '未支付' }}</span>
</div>
<!-- <div class="btn" v-if="!parseInt(item.pay_status)" @click="deletePay(item.id)">移除</div> -->
</div>
</div>
</template>
</el-table-column>
<template v-for="item in tabelField">
<el-table-column v-if="item.visible" :label="item.label" :prop="item.key" :key="item.key"></el-table-column>
</template>
<el-table-column label="操作">
<template slot-scope="scope">
<!-- <el-button type="text" @click="$router.push({ path: '/register/detail', query: { id: scope.row.id } })"
>详情</el-button
> -->
<el-button type="text" v-if="!scope.row.isDelete" @click="deleteJoin(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
<pay></pay>
</el-dialog>
<set-tabel-heade
@handleConfirm="handleConfirm"
@closeSetHeader="columnsOptionsVisible = false"
:visible.sync="columnsOptionsVisible"
:tabelField="tabelField"
></set-tabel-heade>
</div>
</template>
<script>
import SetBasic from '../components/SetBasic.vue'
import Pay from '../components/Pay.vue'
import { getRecordsDetail } from '../api.js'
import setTabelHeade from '../components/setTabelHeade.vue'
export default {
components: { SetBasic, Pay, setTabelHeade },
data() {
return {
infoData: {},
payStatus: [],
columnsOptionsVisible: false,
dialogVisible: false,
value1: '',
form: {
name: '',
mobile: '',
pay_status: ''
},
tabelField: [
{ visible: true, key: 'id', label: '活动步骤ID' },
{ visible: true, key: 'activity_id', label: '活动ID' },
{ visible: true, key: 'user_id', label: '用户ID' },
{ visible: true, key: 'activity_name', label: '活动名称' },
{ visible: true, key: 'join_time', label: '报名时间' },
{ visible: true, key: 'mobile', label: '电话' },
{ visible: true, key: 'name', label: '姓名' },
{ visible: true, key: 'gender', label: '性别' },
{ visible: true, key: 'email', label: '邮箱' },
{ visible: true, key: 'company', label: '公司' },
{ visible: true, key: 'position', label: '职位' },
{ visible: true, key: 'id_number', label: '身份证号码' },
{ visible: true, key: 'number', label: '编号' },
{ visible: true, key: 'country', label: '国籍' },
{ visible: true, key: 'provinces', label: '省份' },
{ visible: true, key: 'city', label: '城市' },
{ visible: true, key: 'address', label: '地址' },
{ visible: true, key: 'fixed_telephone', label: '固话' },
{ visible: true, key: 'industry', label: '行业' },
{ visible: true, key: 'code', label: '验证码' },
{ visible: true, key: 'wechat', label: '微信' },
{ visible: true, key: 'qq', label: 'QQ' },
{ visible: true, key: 'ding', label: '钉钉' },
{ visible: true, key: 'weibo', label: '微博' },
{ visible: true, key: 'check_in_time', label: '入住时间' },
{ visible: true, key: 'check_out_time', label: '离店时间' },
{ visible: true, key: 'room_type', label: '房型' },
{ visible: true, key: 'breakfast', label: '早餐' }
],
tableData: []
}
},
mounted() {
if (window.localStorage.registerDetailTabelField) {
this.tabelField = JSON.parse(window.localStorage.registerDetailTabelField)
}
this.getRecordsDetail()
},
methods: {
// data
getRecordsDetail() {
const params = { join_id: this.$route.query.id }
Object.keys(this.form).forEach(item => {
if (this.form[item] !== '') {
params[item] = this.form[item]
}
})
if (this.payStatus.length) {
this.payStatus.reduce((a, b) => {
params[`pay_status[${b.id}]`] = b.value
return a
}, {})
}
getRecordsDetail(params).then(res => {
this.infoData = res.data.info
if (!this.payStatus.length) {
this.payStatus = res.data.activity_details.map(item => {
item.value = '0'
return item
})
}
this.tableData = res.data.records.list.map(item => {
const findData = item.pay_records.find(pay => pay.pay_status === '1')
item.isDelete = !!findData
item.gender = parseInt(item.gender) ? (parseInt(item.gender) === 1 ? '男' : '女') : '未知'
Object.keys(item).forEach(cItem => {
item[cItem] = item[cItem] === '' ? '-' : item[cItem]
})
return item
})
})
},
// 表头保存
handleConfirm() {
window.localStorage.registerDetailTabelField = JSON.stringify(this.tabelField)
this.columnsOptionsVisible = false
}
}
}
</script>
<style lang="scss" scoped>
.detail-box {
.sub-title {
line-height: 100%;
font-size: 16px;
font-weight: bold;
color: #333333;
border-left: 3px solid rgba(184, 1, 64, 1);
padding-left: 7px;
}
.title {
font-size: 18px;
line-height: 100%;
color: #333333;
margin-bottom: 20px;
}
.detail-top {
background: #fff;
padding: 30px 30px 15px;
.set-basic {
margin-top: 20px;
}
}
.detail-bottom {
background: #fff;
padding: 30px 30px 15px;
margin-top: 20px;
.create-bottom_mian {
margin-top: 30px;
}
}
}
.demo-table-expand {
padding: 26px 0 0 20px;
.li {
margin-bottom: 26px;
display: flex;
.item {
font-size: 14px;
color: rgba(153, 153, 153, 1);
margin-right: 67px;
span {
color: rgba(102, 102, 102, 1);
}
}
.btn {
font-size: 14px;
color: rgba(186, 1, 62, 1);
cursor: pointer;
}
}
}
.line {
// border-top: 1px solid #D6D6D6;
height: 1px;
background: #d6d6d6;
margin: 8px 0 23px;
box-sizing: border-box;
}
</style>
import httpRequest from '@/utils/axios'
/**
* 获取商品列表
*/
export function getGoodsList(data) {
return httpRequest.post('/api/shop/commodity/spu/search', data).then({})
}
<template>
<app-card>
<app-list v-bind="tableOptions" ref="list" @selection-change="handleSelectionChange">
<template #header-aside>
<el-button type="primary">新增</el-button>
</template>
<template v-slot:table-x="{ row }">
<el-button type="text">编辑</el-button>
<el-button type="text" @click="onRemove(row)">删除</el-button>
</template>
</app-list>
</app-card>
</template>
<script>
// 接口
// import { getGoodsList } from '../api'
export default {
data() {
return {}
},
computed: {
// 列表配置
tableOptions() {
return {
// remote: {
// httpRequest: getGoodsList,
// params: { shop_id: this.shopId, spu_id: '', spu_name: '', group_id: '', price_min: '', price_max: '' },
// beforeRequest: this.beforeRequest
// },
filters: [
{
type: 'input',
prop: 'spu_name',
placeholder: '商品名称'
},
{
type: 'select',
prop: 'group_id',
options: this.groupList,
labelKey: 'group_name',
valueKey: 'group_id',
placeholder: '商品分组'
},
{ prop: 'price_zone', slots: 'filter-price' }
],
columns: [
{ label: '日期', prop: 'date', minWidth: 140 },
{ label: '姓名', prop: 'name', align: 'center', minWidth: 140 },
{ label: '地址', prop: 'address', minWidth: 120 },
{ label: '操作', slots: 'table-x', align: 'right', width: 150 }
],
data: [
{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
},
{
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
},
{
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
},
{
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}
]
}
}
},
methods: {
beforeRequest(params, isReset) {
// 重置
if (isReset) {
params.price_min = ''
params.price_max = ''
}
params.status = this.activeName === '0' ? '' : this.activeName
params.price_zone = `${params.price_min || ''},${params.price_max || ''}`
return params
},
handleClick() {
this.$refs.list.refetch(true)
},
// 编辑
handleUpdate(row) {
this.$router.push({ name: 'goodsEdit', params: { id: row.spu_id } })
},
// 删除
onRemove() {
this.$confirm('商品删除请谨慎操作,确定删除?', '删除商品', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(this.handleRemove)
},
// 删除
handleRemove() {
// const data = this.multipleSelection.map(item => ({ spu_id: item.spu_id }))
// deleteGoods({ shop_id: this.shopId, data }).then(res => {
// this.$refs.list.refetch(true)
// })
},
// 推广
handlePromote(row) {
this.shareUrl = `${import.meta.env.VITE_H5_PREVIEW_URL}/buy?shop_id=${row.shop_id}&spu_id=${row.spu_id}`
this.shareDialogVisible = true
},
// 复制
handleCopy(row) {
this.$router.push({ name: 'goodsAdd', query: { id: row.spu_id } })
},
// 选择
handleSelectionChange(value) {
this.multipleSelection = value
},
// 上架
handleUpdateStatus(status) {
// const data = this.multipleSelection.map(item => ({ spu_id: item.spu_id, status }))
// updateGoodsStatus({ shop_id: this.shopId, data }).then(res => {
// this.$refs.list.refetch()
// })
}
}
}
</script>
<style lang="scss">
.filter-price {
.el-input {
width: 140px;
}
}
</style>
......@@ -3,7 +3,7 @@ import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [{ path: '*', redirect: '/test' }]
const routes = [{ path: '*', redirect: '/activity/list' }]
const router = new VueRouter({
mode: 'history',
......
import Vue from 'vue'
import Vuex from 'vuex'
import { getUser, logout, getPermissions } from '@/api/base'
import { getUser, logout, getPermissions, getCommonMap } from '@/api/base'
Vue.use(Vuex)
......@@ -15,9 +15,20 @@ const store = new Vuex.Store({
},
setPermissions(state, permissions) {
state.permissions = permissions
},
setCommonMap(state, commonMap) {
state.commonMap = commonMap
}
},
actions: {
// 获取所有项目列表
getCommonMap({ commit }) {
getCommonMap().then(res => {
const data = res.data
// 所有项目列表
commit('setCommonMap', data)
})
},
getPermissions({ commit }) {
getPermissions({ type: 2 }).then(res => {
if (res.data && res.data.items) {
......@@ -59,5 +70,7 @@ const store = new Vuex.Store({
})
// 获取权限列表
// store.dispatch('getPermissions')
// 初始化获取项目列表
store.dispatch('getCommonMap')
export default store
import axios from 'axios'
import queryString from 'query-string'
// import queryString from 'query-string'
import qs from 'qs'
import { Message } from 'element-ui'
import router from '../router'
const httpRequest = axios.create({
timeout: 60000,
withCredentials: true
// headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
withCredentials: true,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
// 请求拦截
......@@ -27,7 +28,7 @@ httpRequest.interceptors.request.use(
}
if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
config.data = queryString.stringify(config.data)
config.data = qs.stringify(config.data)
}
if (config.headers['Content-Type'] === 'multipart/form-data') {
const formData = new window.FormData()
......
/**
* 文件下载
* @param {string} fileUrl 文件下载地址
* @param {string} fileName 文件名
* @returns {null}
*/
export function funDownload(fileUrl, fileName) {
// console.log(fileUrl)
const elink = document.createElement('a') // 创建一个a标签
elink.download = fileName // 设置a标签的下载属性
elink.style.display = 'none' // 将a标签设置为隐藏
elink.href = fileUrl // 把之前处理好的地址赋给a标签的href
document.body.appendChild(elink) // 将a标签添加到body中
elink.click() // 执行a标签的点击方法
// URL.revokeObjectURL(elink.href) // 下载完成释放URL 对象
document.body.removeChild(elink) // 移除a标签
}
/**
* 分割字符串,取得尾部
* @param {string} str 字符串
* @param {string} split 分割符
* @returns {string}
*/
export function splitStrLast(str, split) {
const fileNameArr = str.split(split)
const last = fileNameArr[fileNameArr.length - 1]
return last
}
......@@ -14,6 +14,11 @@ export default defineConfig({
cert: fs.readFileSync(path.join(__dirname, './https/dev.ezijing.com.pem'))
},
proxy: {
'/api/register': {
target: 'http://localhost-activity-backend.ezijing.com',
changeOrigin: true,
rewrite: path => path.replace(/^\/api\/register/, '')
},
'/api': 'https://project-api.ezijing.com'
}
},
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论