提交 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">
<svg width="251" height="294">
<g fill="none" fill-rule="evenodd">
<path
d="M0 129.023v-2.084C0 58.364 55.591 2.774 124.165 2.774h2.085c68.574 0 124.165 55.59 124.165 124.165v2.084c0 68.575-55.59 124.166-124.165 124.166h-2.085C55.591 253.189 0 197.598 0 129.023"
fill="#E4EBF7"
></path>
<path d="M41.417 132.92a8.231 8.231 0 1 1-16.38-1.65 8.231 8.231 0 0 1 16.38 1.65" fill="#FFF"></path>
<path d="M38.652 136.36l10.425 5.91M49.989 148.505l-12.58 10.73" stroke="#FFF" stroke-width="2"></path>
<path
d="M41.536 161.28a5.636 5.636 0 1 1-11.216-1.13 5.636 5.636 0 0 1 11.216 1.13M59.154 145.261a5.677 5.677 0 1 1-11.297-1.138 5.677 5.677 0 0 1 11.297 1.138M100.36 29.516l29.66-.013a4.562 4.562 0 1 0-.004-9.126l-29.66.013a4.563 4.563 0 0 0 .005 9.126M111.705 47.754l29.659-.013a4.563 4.563 0 1 0-.004-9.126l-29.66.013a4.563 4.563 0 1 0 .005 9.126"
fill="#FFF"
></path>
<path
d="M114.066 29.503V29.5l15.698-.007a4.563 4.563 0 1 0 .004 9.126l-15.698.007v-.002a4.562 4.562 0 0 0-.004-9.122M185.405 137.723c-.55 5.455-5.418 9.432-10.873 8.882-5.456-.55-9.432-5.418-8.882-10.873.55-5.455 5.418-9.432 10.873-8.882 5.455.55 9.432 5.418 8.882 10.873"
fill="#FFF"
></path>
<path d="M180.17 143.772l12.572 7.129M193.841 158.42L178.67 171.36" stroke="#FFF" stroke-width="2"></path>
<path
d="M185.55 171.926a6.798 6.798 0 1 1-13.528-1.363 6.798 6.798 0 0 1 13.527 1.363M204.12 155.285a6.848 6.848 0 1 1-13.627-1.375 6.848 6.848 0 0 1 13.626 1.375"
fill="#FFF"
></path>
<path
d="M152.988 194.074a2.21 2.21 0 1 1-4.42 0 2.21 2.21 0 0 1 4.42 0zM225.931 118.217a2.21 2.21 0 1 1-4.421 0 2.21 2.21 0 0 1 4.421 0zM217.09 153.051a2.21 2.21 0 1 1-4.421 0 2.21 2.21 0 0 1 4.42 0zM177.84 109.842a2.21 2.21 0 1 1-4.422 0 2.21 2.21 0 0 1 4.421 0zM196.114 94.454a2.21 2.21 0 1 1-4.421 0 2.21 2.21 0 0 1 4.421 0zM202.844 182.523a2.21 2.21 0 1 1-4.42 0 2.21 2.21 0 0 1 4.42 0z"
stroke="#FFF"
stroke-width="2"
></path>
<path
stroke="#FFF"
stroke-width="2"
d="M215.125 155.262l-1.902 20.075-10.87 5.958M174.601 176.636l-6.322 9.761H156.98l-4.484 6.449M175.874 127.28V111.56M221.51 119.404l-12.77 7.859-15.228-7.86V96.668"
></path>
<path
d="M180.68 29.32C180.68 13.128 193.806 0 210 0c16.193 0 29.32 13.127 29.32 29.32 0 16.194-13.127 29.322-29.32 29.322-16.193 0-29.32-13.128-29.32-29.321"
fill="#A26EF4"
></path>
<path
d="M221.45 41.706l-21.563-.125a1.744 1.744 0 0 1-1.734-1.754l.071-12.23a1.744 1.744 0 0 1 1.754-1.734l21.562.125c.964.006 1.74.791 1.735 1.755l-.071 12.229a1.744 1.744 0 0 1-1.754 1.734"
fill="#FFF"
></path>
<path
d="M215.106 29.192c-.015 2.577-2.049 4.654-4.543 4.64-2.494-.014-4.504-2.115-4.489-4.693l.04-6.925c.016-2.577 2.05-4.654 4.543-4.64 2.494.015 4.504 2.116 4.49 4.693l-.04 6.925zm-4.53-14.074a6.877 6.877 0 0 0-6.916 6.837l-.043 7.368a6.877 6.877 0 0 0 13.754.08l.042-7.368a6.878 6.878 0 0 0-6.837-6.917zM167.566 68.367h-3.93a4.73 4.73 0 0 1-4.717-4.717 4.73 4.73 0 0 1 4.717-4.717h3.93a4.73 4.73 0 0 1 4.717 4.717 4.73 4.73 0 0 1-4.717 4.717"
fill="#FFF"
></path>
<path
d="M168.214 248.838a6.611 6.611 0 0 1-6.61-6.611v-66.108a6.611 6.611 0 0 1 13.221 0v66.108a6.611 6.611 0 0 1-6.61 6.61"
fill="#5BA02E"
></path>
<path
d="M176.147 248.176a6.611 6.611 0 0 1-6.61-6.61v-33.054a6.611 6.611 0 1 1 13.221 0v33.053a6.611 6.611 0 0 1-6.61 6.611"
fill="#92C110"
></path>
<path
d="M185.994 293.89h-27.376a3.17 3.17 0 0 1-3.17-3.17v-45.887a3.17 3.17 0 0 1 3.17-3.17h27.376a3.17 3.17 0 0 1 3.17 3.17v45.886a3.17 3.17 0 0 1-3.17 3.17"
fill="#F2D7AD"
></path>
<path
d="M81.972 147.673s6.377-.927 17.566-1.28c11.729-.371 17.57 1.086 17.57 1.086s3.697-3.855.968-8.424c1.278-12.077 5.982-32.827.335-48.273-1.116-1.339-3.743-1.512-7.536-.62-1.337.315-7.147-.149-7.983-.1l-15.311-.347s-3.487-.17-8.035-.508c-1.512-.113-4.227-1.683-5.458-.338-.406.443-2.425 5.669-1.97 16.077l8.635 35.642s-3.141 3.61 1.219 7.085"
fill="#FFF"
></path>
<path
d="M75.768 73.325l-.9-6.397 11.982-6.52s7.302-.118 8.038 1.205c.737 1.324-5.616.993-5.616.993s-1.836 1.388-2.615 2.5c-1.654 2.363-.986 6.471-8.318 5.986-1.708.284-2.57 2.233-2.57 2.233"
fill="#FFC6A0"
></path>
<path
d="M52.44 77.672s14.217 9.406 24.973 14.444c1.061.497-2.094 16.183-11.892 11.811-7.436-3.318-20.162-8.44-21.482-14.496-.71-3.258 2.543-7.643 8.401-11.76M141.862 80.113s-6.693 2.999-13.844 6.876c-3.894 2.11-10.137 4.704-12.33 7.988-6.224 9.314 3.536 11.22 12.947 7.503 6.71-2.651 28.999-12.127 13.227-22.367"
fill="#FFB594"
></path>
<path
d="M76.166 66.36l3.06 3.881s-2.783 2.67-6.31 5.747c-7.103 6.195-12.803 14.296-15.995 16.44-3.966 2.662-9.754 3.314-12.177-.118-3.553-5.032.464-14.628 31.422-25.95"
fill="#FFC6A0"
></path>
<path
d="M64.674 85.116s-2.34 8.413-8.912 14.447c.652.548 18.586 10.51 22.144 10.056 5.238-.669 6.417-18.968 1.145-20.531-.702-.208-5.901-1.286-8.853-2.167-.87-.26-1.611-1.71-3.545-.936l-1.98-.869zM128.362 85.826s5.318 1.956 7.325 13.734c-.546.274-17.55 12.35-21.829 7.805-6.534-6.94-.766-17.393 4.275-18.61 4.646-1.121 5.03-1.37 10.23-2.929"
fill="#FFF"
></path>
<path
d="M78.18 94.656s.911 7.41-4.914 13.078"
stroke="#E4EBF7"
stroke-width="1.051"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M87.397 94.68s3.124 2.572 10.263 2.572c7.14 0 9.074-3.437 9.074-3.437"
stroke="#E4EBF7"
stroke-width=".932"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M117.184 68.639l-6.781-6.177s-5.355-4.314-9.223-.893c-3.867 3.422 4.463 2.083 5.653 4.165 1.19 2.082.848 1.143-2.083.446-5.603-1.331-2.082.893 2.975 5.355 2.091 1.845 6.992.955 6.992.955l2.467-3.851z"
fill="#FFC6A0"
></path>
<path
d="M105.282 91.315l-.297-10.937-15.918-.027-.53 10.45c-.026.403.17.788.515.999 2.049 1.251 9.387 5.093 15.799.424.287-.21.443-.554.431-.91"
fill="#FFB594"
></path>
<path
d="M107.573 74.24c.817-1.147.982-9.118 1.015-11.928a1.046 1.046 0 0 0-.965-1.055l-4.62-.365c-7.71-1.044-17.071.624-18.253 6.346-5.482 5.813-.421 13.244-.421 13.244s1.963 3.566 4.305 6.791c.756 1.041.398-3.731 3.04-5.929 5.524-4.594 15.899-7.103 15.899-7.103"
fill="#5C2552"
></path>
<path
d="M88.426 83.206s2.685 6.202 11.602 6.522c7.82.28 8.973-7.008 7.434-17.505l-.909-5.483c-6.118-2.897-15.478.54-15.478.54s-.576 2.044-.19 5.504c-2.276 2.066-1.824 5.618-1.824 5.618s-.905-1.922-1.98-2.321c-.86-.32-1.897.089-2.322 1.98-1.04 4.632 3.667 5.145 3.667 5.145"
fill="#FFC6A0"
></path>
<path
stroke="#DB836E"
stroke-width="1.145"
stroke-linecap="round"
stroke-linejoin="round"
d="M100.843 77.099l1.701-.928-1.015-4.324.674-1.406"
></path>
<path
d="M105.546 74.092c-.022.713-.452 1.279-.96 1.263-.51-.016-.904-.607-.882-1.32.021-.713.452-1.278.96-1.263.51.016.904.607.882 1.32M97.592 74.349c-.022.713-.452 1.278-.961 1.263-.509-.016-.904-.607-.882-1.32.022-.713.452-1.279.961-1.263.51.016.904.606.882 1.32"
fill="#552950"
></path>
<path
d="M91.132 86.786s5.269 4.957 12.679 2.327"
stroke="#DB836E"
stroke-width="1.145"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M99.776 81.903s-3.592.232-1.44-2.79c1.59-1.496 4.897-.46 4.897-.46s1.156 3.906-3.457 3.25"
fill="#DB836E"
></path>
<path
d="M102.88 70.6s2.483.84 3.402.715M93.883 71.975s2.492-1.144 4.778-1.073"
stroke="#5C2552"
stroke-width="1.526"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M86.32 77.374s.961.879 1.458 2.106c-.377.48-1.033 1.152-.236 1.809M99.337 83.719s1.911.151 2.509-.254"
stroke="#DB836E"
stroke-width="1.145"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M87.782 115.821l15.73-3.012M100.165 115.821l10.04-2.008"
stroke="#E4EBF7"
stroke-width="1.051"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M66.508 86.763s-1.598 8.83-6.697 14.078"
stroke="#E4EBF7"
stroke-width="1.114"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M128.31 87.934s3.013 4.121 4.06 11.785"
stroke="#E4EBF7"
stroke-width="1.051"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M64.09 84.816s-6.03 9.912-13.607 9.903"
stroke="#DB836E"
stroke-width=".795"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M112.366 65.909l-.142 5.32s5.993 4.472 11.945 9.202c4.482 3.562 8.888 7.455 10.985 8.662 4.804 2.766 8.9 3.355 11.076 1.808 4.071-2.894 4.373-9.878-8.136-15.263-4.271-1.838-16.144-6.36-25.728-9.73"
fill="#FFC6A0"
></path>
<path
d="M130.532 85.488s4.588 5.757 11.619 6.214"
stroke="#DB836E"
stroke-width=".75"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M121.708 105.73s-.393 8.564-1.34 13.612"
stroke="#E4EBF7"
stroke-width="1.051"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M115.784 161.512s-3.57-1.488-2.678-7.14"
stroke="#648BD8"
stroke-width="1.051"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M101.52 290.246s4.326 2.057 7.408 1.03c2.842-.948 4.564.673 7.132 1.186 2.57.514 6.925 1.108 11.772-1.269-.104-5.551-6.939-4.01-12.048-6.763-2.582-1.39-3.812-4.757-3.625-8.863h-9.471s-1.402 10.596-1.169 14.68"
fill="#CBD1D1"
></path>
<path
d="M101.496 290.073s2.447 1.281 6.809.658c3.081-.44 3.74.485 7.479 1.039 3.739.554 10.802-.07 11.91-.9.415 1.108-.347 2.077-.347 2.077s-1.523.608-4.847.831c-2.045.137-5.843.293-7.663-.507-1.8-1.385-5.286-1.917-5.77-.243-3.947.958-7.41-.288-7.41-.288l-.16-2.667z"
fill="#2B0849"
></path>
<path d="M108.824 276.19h3.116s-.103 6.751 4.57 8.62c-4.673.624-8.62-2.32-7.686-8.62" fill="#A4AABA"></path>
<path
d="M57.65 272.52s-2.122 7.47-4.518 12.396c-1.811 3.724-4.255 7.548 5.505 7.548 6.698 0 9.02-.483 7.479-6.648-1.541-6.164.268-13.296.268-13.296H57.65z"
fill="#CBD1D1"
></path>
<path
d="M51.54 290.04s2.111 1.178 6.682 1.178c6.128 0 8.31-1.662 8.31-1.662s.605 1.122-.624 2.18c-1 .862-3.624 1.603-7.444 1.559-4.177-.049-5.876-.57-6.786-1.177-.831-.554-.692-1.593-.138-2.078"
fill="#2B0849"
></path>
<path
d="M58.533 274.438s.034 1.529-.315 2.95c-.352 1.431-1.087 3.127-1.139 4.17-.058 1.16 4.57 1.592 5.194.035.623-1.559 1.303-6.475 1.927-7.306.622-.831-4.94-2.135-5.667.15"
fill="#A4AABA"
></path>
<path
d="M100.885 277.015l13.306.092s1.291-54.228 1.843-64.056c.552-9.828 3.756-43.13.997-62.788l-12.48-.64-22.725.776s-.433 3.944-1.19 9.921c-.062.493-.677.838-.744 1.358-.075.582.42 1.347.318 1.956-2.35 14.003-6.343 32.926-8.697 46.425-.116.663-1.227 1.004-1.45 2.677-.04.3.21 1.516.112 1.785-6.836 18.643-10.89 47.584-14.2 61.551l14.528-.014s2.185-8.524 4.008-16.878c2.796-12.817 22.987-84.553 22.987-84.553l3-.517 1.037 46.1s-.223 1.228.334 2.008c.558.782-.556 1.117-.39 2.233l.39 1.784s-.446 7.14-.892 11.826c-.446 4.685-.092 38.954-.092 38.954"
fill="#7BB2F9"
></path>
<path
d="M77.438 220.434c1.146.094 4.016-2.008 6.916-4.91M107.55 223.931s2.758-1.103 6.069-3.862"
stroke="#648BD8"
stroke-width="1.051"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M108.459 220.905s2.759-1.104 6.07-3.863"
stroke="#648BD8"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M76.099 223.557s2.608-.587 6.47-3.346M87.33 150.82c-.27 3.088.297 8.478-4.315 9.073M104.829 149.075s.11 13.936-1.286 14.983c-2.207 1.655-2.975 1.934-2.975 1.934M101.014 149.63s.035 12.81-1.19 24.245M94.93 174.965s7.174-1.655 9.38-1.655M75.671 204.754c-.316 1.55-.64 3.067-.973 4.535 0 0-1.45 1.822-1.003 3.756.446 1.934-.943 2.034-4.96 15.273-1.686 5.559-4.464 18.49-6.313 27.447-.078.38-4.018 18.06-4.093 18.423M77.043 196.743a313.269 313.269 0 0 1-.877 4.729M83.908 151.414l-1.19 10.413s-1.091.148-.496 2.23c.111 1.34-2.66 15.692-5.153 30.267M57.58 272.94h13.238"
stroke="#648BD8"
stroke-width="1.051"
stroke-linecap="round"
stroke-linejoin="round"
></path>
<path
d="M117.377 147.423s-16.955-3.087-35.7.199c.157 2.501-.002 4.128-.002 4.128s14.607-2.802 35.476-.31c.251-2.342.226-4.017.226-4.017"
fill="#192064"
></path>
<path
d="M107.511 150.353l.004-4.885a.807.807 0 0 0-.774-.81c-2.428-.092-5.04-.108-7.795-.014a.814.814 0 0 0-.784.81l-.003 4.88c0 .456.371.82.827.808a140.76 140.76 0 0 1 7.688.017.81.81 0 0 0 .837-.806"
fill="#FFF"
></path>
<path
d="M106.402 149.426l.002-3.06a.64.64 0 0 0-.616-.643 94.135 94.135 0 0 0-5.834-.009.647.647 0 0 0-.626.643l-.001 3.056c0 .36.291.648.651.64 1.78-.04 3.708-.041 5.762.012.36.009.662-.279.662-.64"
fill="#192064"
></path>
<path
d="M101.485 273.933h12.272M102.652 269.075c.006 3.368.04 5.759.11 6.47M102.667 263.125c-.009 1.53-.015 2.98-.016 4.313M102.204 174.024l.893 44.402s.669 1.561-.224 2.677c-.892 1.116 2.455.67.893 2.231-1.562 1.562.893 1.116 0 3.347-.592 1.48-.988 20.987-1.09 34.956"
stroke="#648BD8"
stroke-width="1.051"
stroke-linecap="round"
stroke-linejoin="round"
></path>
</g>
</svg>
<p class="tips">很抱歉,你暂时无权限访问...</p>
<a :href="loginUrl"><el-button round type="primary">重新登录</el-button></a>
</div>
</template>
<script>
export default {
computed: {
loginUrl() {
return `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(window.location.origin)}`
}
}
}
</script>
<style lang="scss" scoped>
.container {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.tips {
margin: 30px;
font-size: 24px;
color: #313131;
}
</style>
<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>
<template>
<app-card class="register-box">
<app-list v-bind="tableOptions" border ref="list" @selection-change="handleSelectionChange">
<div class="line"></div>
<div class="btn-box">
<el-button type="primary">新建报名</el-button>
<el-button type="primary">表头设置</el-button>
<el-form ref="form" :inline="true" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.activity_name"></el-input>
</el-form-item>
<el-form-item label="项目ID">
<el-input v-model="form.activity_project_id"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-select v-model="form.gender" placeholder="请选择性别" clearable>
<el-option label="未知" value="0"></el-option>
<el-option label="男" value="1"></el-option>
<el-option label="女" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="人员类型">
<el-select v-model="form.user_type" placeholder="请选择人员类型" clearable>
<el-option label="普通成员" value="1"></el-option>
<el-option label="归属人" value="2"></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="活动时间">
<el-date-picker
v-model="form.date"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
</el-form-item> -->
<el-form-item>
<el-button type="primary" @click="handleScreen">搜索</el-button>
<el-button @click="handleReset">重置</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="downloadRecords">导出人员</el-button>
<el-button type="primary" @click="importDialogVisible = true">导入人员</el-button>
<el-button type="primary" @click="columnsOptionsVisible = true">表头筛选</el-button>
</div>
<template v-slot:filter-date>
<div class="filter-date">
<span style="color:#606266" class="demonstration">报名时间&nbsp;&nbsp;&nbsp;</span>
<el-date-picker
v-model="value1"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</div>
<!-- <question-type-treeselect v-model="params.paper_category" @change="refetchList"></question-type-treeselect> -->
</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>
<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 style="display:flex; justify-content: center;padding-top:30px">
<el-pagination
layout="prev, pager, next"
:page-size="page.size"
:current-page="page.currentPage"
@current-change="pageSizeChange"
:total="page.total">
</el-pagination>
</div>
</div>
<import-people width="30%" :visible.sync="importDialogVisible"></import-people>
<set-tabel-heade
@closeSetHeader="columnsOptionsVisible = false"
@handleConfirm="handleConfirm"
:visible.sync="columnsOptionsVisible"
:tabelField="tabelField"
></set-tabel-heade>
</app-card>
</template>
<script>
import importPeople from '../components/importPeople.vue'
import setTabelHeade from '../components/setTabelHeade.vue'
// 接口
// import { getGoodsList } from '../api'
import { getAppList, deletePay, deleteJoin } from '../api'
export default {
components: { importPeople, setTabelHeade },
data() {
return {
value1: ''
page: {
currentPage: 1,
total: 0,
size: 10
},
// :visible.sync="columnsOptionsVisible"
columnsOptionsVisible: false,
importDialogVisible: false,
form: {
activity_name: '',
user_type: '',
gender: '',
activity_project_id: ''
},
tableData: [],
// tabelField: {
// id: '活动步骤ID',
// activity_id: '活动ID',
// type: '类型',
// order: '序号',
// constent: '展示类型的富文本信息',
// can_pay: '缴费功能',
// can_invoice: '发票功能',
// pay_type: '缴费方式',
// pay_price: '价格',
// can_company: '单位优惠',
// can_jump: '跳转功能',
// jump_url: '跳转地址',
// shop_id: '商铺id',
// can_skip_pay: '跳过支付',
// skip_pay_title: '跳过支付文案'
// },
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: '早餐' }
]
}
},
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',
label: '报名名称'
},
{
type: 'input',
prop: 'spu_name2',
label: '报名id'
},
{
type: 'select',
prop: 'group_id',
options: [],
labelKey: 'group_name',
valueKey: 'group_id',
label: '项目筛选'
},
{ prop: 'price_zone', slots: 'filter-date' }
],
columns: [
{ label: '序号', prop: 'date', align: 'center' },
{ label: 'id', prop: 'date', align: 'center' },
{ label: '日期', prop: 'date', align: 'center' },
{ label: '报名名称', prop: 'name', align: 'center' },
{ label: '报名时间', prop: 'date', align: 'center' },
{ label: '结束时间', prop: 'date', align: 'center' },
{ label: '创建时间', prop: 'date', align: 'center' },
{ label: '关联项目', prop: 'date', align: 'center' },
{ label: '操作', slots: 'table-x', align: 'center' }
],
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 弄'
}
]
}
mounted() {
this.getAppList()
if (window.localStorage.registerTabelField) {
this.tabelField = JSON.parse(window.localStorage.registerTabelField)
}
},
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
pageSizeChange(value) {
this.page.currentPage = value
this.handleScreen()
// this.page.size = value
},
handleClick() {
this.$refs.list.refetch(true)
// 重置
handleReset() {
Object.keys(this.form).forEach(item => {
this.form[item] = ''
})
this.getAppList()
},
// 编辑
handleUpdate(row) {
this.$router.push({ name: 'goodsEdit', params: { id: row.spu_id } })
// 搜索
handleScreen() {
const params = {}
Object.keys(this.form).forEach(item => {
if (this.form[item] !== '') {
params[item] = this.form[item]
}
})
this.getAppList(params)
},
// 删除
onRemove() {
this.$confirm('商品删除请谨慎操作,确定删除?', '删除商品', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(this.handleRemove)
// 列表
getAppList(form = {}) {
form['per-page'] = this.page.size
form.page = this.page.currentPage
getAppList(form).then(res => {
this.page.total = res.data.total
this.tableData = res.data.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
})
})
},
// 删除
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)
// })
// 删除步骤(人员信息)
deletePay(id) {
deletePay({ pay_id: id }).then(res => {
this.$message({
message: '移除成功',
type: 'success'
})
this.getAppList()
})
},
// 推广
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
// 删除报名记录
deleteJoin(id) {
deleteJoin({ join_id: id }).then(res => {
this.$message({
message: '删除成功',
type: 'success'
})
this.getAppList()
})
},
// 复制
handleCopy(row) {
this.$router.push({ name: 'goodsAdd', query: { id: row.spu_id } })
// 编辑
handleUpdate(row) {
this.$router.push({ name: 'goodsEdit', params: { id: row.spu_id } })
},
// 选择
handleSelectionChange(value) {
this.multipleSelection = value
// 导出
downloadRecords() {
window.open(`${window.location.origin}/api/register/v1/records/download`)
},
// 上架
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()
// })
// 表头保存
handleConfirm() {
window.localStorage.registerTabelField = JSON.stringify(this.tabelField)
this.columnsOptionsVisible = false
}
}
}
</script>
<style lang="scss">
.register-box{
.el-form-item{
.register-box {
.el-form-item {
margin-right: 20px !important;
}
.line{
.line {
// border-top: 1px solid #D6D6D6;
height: 1px;
background: #d6d6d6;
margin: 8px 0 23px;
box-sizing: border-box;
}
.btn-box{
margin-bottom: 16px;
.tabel-list {
.table-list_btns {
margin-bottom: 20px;
}
}
}
.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;
}
}
}
</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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论