提交 9bdb11c5 authored 作者: lihuihui's avatar lihuihui

update

上级 7711251b
...@@ -86,9 +86,12 @@ textarea:focus { ...@@ -86,9 +86,12 @@ textarea:focus {
} }
:root { :root {
--main-color: rgba(184, 1, 64, 1); --main-color: #1655B2;
}
.breadcrumb{
padding-bottom: 20px;
font-size: 16px;
font-weight: bold;
color: rgba(0,0,0,1);
line-height: 100%;
} }
.tox-notifications-container{
display: none !important;
}
\ No newline at end of file
$--color-primary: rgba(184, 1, 64, 1); $--color-primary: #1655B2;
/* 改变 icon 字体路径变量,必需 */ /* 改变 icon 字体路径变量,必需 */
$--font-path: 'element-ui/lib/theme-chalk/fonts'; $--font-path: 'element-ui/lib/theme-chalk/fonts';
......
...@@ -255,18 +255,18 @@ export default { ...@@ -255,18 +255,18 @@ export default {
.btn { .btn {
text-align: center; text-align: center;
line-height: 34px; line-height: 34px;
background: rgba(184, 1, 64, 1); background: #1655B2;
border-radius: 6px; border-radius: 6px;
font-size: 14px; font-size: 14px;
color: #fff; color: #fff;
margin-top: 8px; margin-top: 8px;
border: 1px solid rgba(184, 1, 64, 1); border: 1px solid #1655B2;
cursor: pointer; cursor: pointer;
&.active { &.active {
background: rgba(237, 245, 243, 0.39); background: rgba(237, 245, 243, 0.39);
border: 1px solid rgba(184, 1, 64, 1); border: 1px solid #1655B2;
border-radius: 6px; border-radius: 6px;
color: rgba(184, 1, 64, 1); color: #1655B2;
} }
} }
} }
......
...@@ -24,10 +24,10 @@ export default { ...@@ -24,10 +24,10 @@ export default {
data() { data() {
return { return {
menuList: [ menuList: [
{ name: '证书模板管理', path: '/template/list', icon: 'el-icon-notebook-2' }, { name: '证书模板管理', path: '/template/list', icon: 'el-icon-tickets' },
{ name: '动态变量管理', path: '/variable/list', icon: 'el-icon-user' }, { name: '动态变量管理', path: '/variable/list', icon: 'el-icon-set-up' },
{ name: '学员管理', path: '/student/list', icon: 'el-icon-connection' }, { name: '学员管理', path: '/student/list', icon: 'el-icon-user' },
{ name: '项目管理', path: '/project/list', icon: 'el-icon-connection' } { name: '项目管理', path: '/project/list', icon: 'el-icon-copy-document' }
] ]
} }
}, },
......
...@@ -266,7 +266,7 @@ export default { ...@@ -266,7 +266,7 @@ export default {
font-size: 16px; font-size: 16px;
font-weight: bold; font-weight: bold;
color: #333333; color: #333333;
border-left: 3px solid rgba(184, 1, 64, 1); border-left: 3px solid #1655B2;
padding-left: 7px; padding-left: 7px;
margin-bottom: 25px; margin-bottom: 25px;
} }
......
...@@ -95,10 +95,10 @@ export default { ...@@ -95,10 +95,10 @@ export default {
} }
], ],
columns: [ columns: [
{ label: 'id', prop: 'id', align: 'center' },
{ label: '项目名称', prop: 'title', align: 'center' }, { label: '项目名称', prop: 'title', align: 'center' },
{ label: '关联人数', prop: 'students_count', align: 'center' },
{ label: '关联证书模板', prop: 'template_id_name', align: 'center' }, { label: '关联证书模板', prop: 'template_id_name', align: 'center' },
{ label: '关联人数', prop: 'students_count', align: 'center' },
{ label: 'id', prop: 'id', align: 'center' },
{ label: '创建时间', prop: 'created_time', align: 'center' }, { label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '操作', slots: 'table-x', align: 'center' } { label: '操作', slots: 'table-x', align: 'center' }
] ]
......
...@@ -7,38 +7,43 @@ ...@@ -7,38 +7,43 @@
ref="ruleForm" ref="ruleForm"
label-width="110px" label-width="110px"
class="demo-ruleForm" class="demo-ruleForm"
style="width: 80%; margin: 0 auto" style="width: 550px"
> >
<el-form-item label="项目名称" prop="title"> <el-form-item label="项目名称" prop="title">
<el-input v-model="ruleForm.title"></el-input> <el-input placeholder="请填写项目名称" v-model="ruleForm.title"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="关联证书模板" prop="template"> <el-form-item label="关联证书模板" prop="template">
<el-select filterable v-model="ruleForm.template_id" placeholder="请选择"> <el-select filterable v-model="ruleForm.template_id" placeholder="请选择证书模板" style="width: 440px">
<el-option v-for="item in templateList" :key="item.id" :label="item.title" :value="item.id"> </el-option> <el-option v-for="item in templateList" :key="item.id" :label="item.title" :value="item.id"> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="关联学员"> <el-form-item label="关联学员">
<el-card class="box-card"> <div class="select-btn" @click="drawer = true" style="margin-bottom: 10px">
<div slot="header" class="clearfix"> <i class="el-icon-plus"></i>
<el-button type="primary" @click="drawer = true">选择学员</el-button> <div class="text">选择图文</div>
</div> </div>
<app-list v-bind="tableOptions" ref="list"> <app-list v-bind="tableOptions" ref="list">
<template v-slot:table-x="{ row }"> <template v-slot:table-x="{ row }">
<el-button type="text" @click="handleDelete(row)">删除</el-button> <el-button type="text" @click="handleDelete(row)">删除</el-button>
</template> </template>
</app-list> </app-list>
</el-card>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<div style="padding-top: 20px; width: 200px; margin: 0 auto"> <div>
<el-button type="primary" @click="submitForm">确认</el-button> <el-button type="primary" @click="submitForm">确认</el-button>
<el-button @click="drawer = true">取消</el-button> <el-button @click="drawer = true" style="margin-left:20px;">取消</el-button>
</div> </div>
</el-form-item> </el-form-item>
</el-form> </el-form>
</app-card> </app-card>
<el-drawer size="80%" :visible.sync="drawer" :direction="direction" :destroy-on-close="true"> <el-drawer size="60%" :visible.sync="drawer" :direction="direction" :destroy-on-close="true">
<app-list v-if="drawer" @selection-change="selectionChange" v-bind="selectTableOptions" ref="list" style="padding: 0 30px 0"> <app-list
v-if="drawer"
@selection-change="selectionChange"
v-bind="selectTableOptions"
ref="list"
style="padding: 0 30px 0; height: auto"
>
</app-list> </app-list>
<div style="padding-left: 30px"><el-button type="primary" @click="drawer = false">确认</el-button></div> <div style="padding-left: 30px"><el-button type="primary" @click="drawer = false">确认</el-button></div>
</el-drawer> </el-drawer>
...@@ -113,12 +118,10 @@ export default { ...@@ -113,12 +118,10 @@ export default {
tableOptions() { tableOptions() {
return { return {
columns: [ columns: [
{ label: 'id', prop: 'id', align: 'center' },
{ label: '姓名', prop: 'name', align: 'center' }, { label: '姓名', prop: 'name', align: 'center' },
{ label: '手机号', prop: 'mobile', align: 'center' }, { label: '手机号', prop: 'mobile', align: 'center' },
{ label: '邮箱', prop: 'email', align: 'center' }, { label: '邮箱', prop: 'email', align: 'center' },
{ label: '编号', prop: 'number', align: 'center' }, { label: '编号', prop: 'number', align: 'center' },
{ label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '操作', slots: 'table-x', align: 'center' } { label: '操作', slots: 'table-x', align: 'center' }
], ],
data: this.studentTableOptions data: this.studentTableOptions
...@@ -135,7 +138,12 @@ export default { ...@@ -135,7 +138,12 @@ export default {
}, },
// 选择学员 // 选择学员
selectionChange(selection) { selectionChange(selection) {
this.studentTableOptions = selection selection.forEach(item => {
const find = this.studentTableOptions.find(i => i.id === item.id)
if (!find) {
this.studentTableOptions.push(item)
}
})
}, },
// 证书模板 // 证书模板
getTemplateList() { getTemplateList() {
...@@ -194,4 +202,23 @@ export default { ...@@ -194,4 +202,23 @@ export default {
} }
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped>
.select-btn {
display: flex;
justify-content: space-between;
align-items: center;
height: 32px;
border: 1px solid rgba(0, 0, 0, 0.15);
padding: 0 17px;
width: fit-content;
cursor: pointer;
i {
color: #363636;
}
.text {
font-size: 14px;
color: #161616;
margin-left: 5px;
}
}
</style>
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<a <a
href="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/pages/highway/road/%E4%BA%BA%E5%91%98%E6%A8%A1%E6%9D%BF.xlsx" href="https://webapp-pub.oss-cn-beijing.aliyuncs.com/project/pages/highway/road/%E4%BA%BA%E5%91%98%E6%A8%A1%E6%9D%BF.xlsx"
download="人员模板.xlsx" download="人员模板.xlsx"
style="color: #c01c40" style="color: #1655B2"
> >
<i class="el-icon-download"></i>人员模板.xlsx</a <i class="el-icon-download"></i>人员模板.xlsx</a
> >
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<app-list v-bind="tableOptions" ref="list"> <app-list v-bind="tableOptions" ref="list">
<div class="line"></div> <div class="line"></div>
<div class="btn-box"> <div class="btn-box">
<el-button type="primary" @click="$router.push({ path: '/student/update' })">新增学员</el-button> <el-button type="primary" @click="$router.push({ path: '/student/update' })">+ 添加学员</el-button>
<el-button type="primary" @click="importDialogVisible = true">批量导入</el-button> <el-button type="primary" @click="importDialogVisible = true">批量导入</el-button>
<el-button type="primary" @click="downloadRecords">导出学员</el-button> <el-button type="primary" @click="downloadRecords">导出学员</el-button>
</div> </div>
......
<template> <template>
<div class="create-box"> <div class="create-box">
<app-card :title="!$route.query.id ? '新建学员' : '编辑学员'"> <app-card :title="!$route.query.id ? '添加学员' : '编辑信息'">
<el-form <el-form
:model="ruleForm" :model="ruleForm"
:rules="rules" :rules="rules"
ref="ruleForm" ref="ruleForm"
label-width="100px" label-width="100px"
class="demo-ruleForm" class="demo-ruleForm"
style="width: 40%; margin: 0 auto" style="display: flex; flex-wrap: wrap"
> >
<el-form-item label="关联项目">
<el-select @change="$forceUpdate()" filterable multiple v-model="ruleForm.projects_id" placeholder="请选择">
<el-option v-for="item in options" :key="item.id" :label="item.title" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="姓名" prop="name"> <el-form-item label="姓名" prop="name">
<el-input v-model="ruleForm.name"></el-input> <el-input v-model="ruleForm.name"></el-input>
</el-form-item> </el-form-item>
...@@ -56,6 +51,11 @@ ...@@ -56,6 +51,11 @@
<el-form-item label="微信"> <el-form-item label="微信">
<el-input v-model="ruleForm.title"></el-input> <el-input v-model="ruleForm.title"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="关联项目">
<el-select @change="$forceUpdate()" filterable multiple v-model="ruleForm.projects_id" placeholder="请选择">
<el-option v-for="item in options" :key="item.id" :label="item.title" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item> <el-form-item>
<div style="padding-top: 20px"> <div style="padding-top: 20px">
<el-button type="primary" @click="submitForm">确认</el-button> <el-button type="primary" @click="submitForm">确认</el-button>
......
<template>
<div>
<div class="step-two-box">
<div class="content-left">
<template>
<edit-style
@data="editStyle"
@imgUpload="imgUploadInit"
@changeText="changeText"
v-for="(item, index) in toolList"
:key="index"
v-bind="item"
:toolIndex="index"
></edit-style>
<!-- <div class="upload-img">
<div class="btn">上传图片</div>
<UploadImage class="upload" style="width: 50px" v-model="imgParams.url" @input="uploadImg"></UploadImage>
</div> -->
</template>
<div class="btn" @click="dialogVisible = true">添加元素</div>
</div>
<div class="content-right">
<div class="cert-box" id="edit-dom-1">
<template v-for="item in certElement">
<div
:style="item.style"
v-if="item.type === 3 || item.type === 0"
:key="item.id"
:id="item.id"
class="edit-img"
>
<div class="pop"></div>
<img style="width: 100%; display: block; height: 100%" :src="item.url" />
</div>
<div v-if="item.type === 1 || item.type === 2" class="text" :key="item.id" :id="item.id">
{{ !item.textValue ? '请输入' : item.textValue }}
</div>
</template>
</div>
<div style="display: flex; padding: 30px; justify-content: center">
<el-button type="primary" @click="confirm">确 定</el-button>
</div>
</div>
</div>
<el-dialog title="添加元素" :visible.sync="dialogVisible" width="30%" :destroy-on-close="true">
<div style="display: flex; justify-content: center">
<el-radio-group v-model="selectElement">
<el-radio :label="0">图片</el-radio>
<el-radio :label="1">文字</el-radio>
<el-radio :label="2">动态变量</el-radio>
<el-radio :label="3">背景图片</el-radio>
</el-radio-group>
</div>
<div style="display: flex; justify-content: center; padding: 30px" v-if="selectElement === 2">
<el-select v-model="paramValue" placeholder="请选择">
<el-option v-for="item in paramOptions" :key="item.key" :label="item.key" :value="item.key"> </el-option>
</el-select>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="addElement">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import EditStyle from '@/components/base/EditStyle.vue'
import drag from '@/utils/drag.js'
import { getParamsList } from '../api'
export default {
components: {
EditStyle
},
props: {
data: {
type: Object
}
},
data() {
return {
// 动态变量
paramValue: '',
// 动态变量选项
paramOptions: [],
// 动态id
dynamicId: 1,
// 添加dom弹窗
dialogVisible: false,
// 选择添加那个类型的dom
selectElement: 0,
// 样式修改工具
toolList: [
{
title: '证书尺寸设置',
tool: [
{ name: 'width', value: '500px' },
{ name: 'height', value: '300px' },
{ name: 'bgColor', value: '#ffffff' }
],
id: 'edit-dom-1'
}
],
certElement: []
}
},
computed: {},
mounted() {
if (this.$route.query.id) {
this.toolList = this.data.toolList.map(item => {
const findItem = this.data.certElement.find(i => i.id === item.id)
if (findItem) {
item.tool = findItem.originalData
}
if (item.type === 1) {
item.textValue = findItem.textValue
}
return item
})
// 动态id
const lastId = this.data.certElement[this.data.certElement.length - 1].id
this.dynamicId = parseInt(lastId.substring(lastId.length - 1)) + 1
this.certElement = this.data.certElement
// 编辑的时候改变dom位置
this.certElement.forEach(item => {
this.$nextTick(() => {
const dom = document.getElementById(item.id)
dom.style = item.style
dom.style.top = item.top + 'px'
dom.style.left = item.left + 'px'
dom.setAttribute('data-top', item.top)
dom.setAttribute('data-left', item.left)
})
this.dragInit(item.id)
})
}
console.log(this.data, '123')
this.getParamOptions()
},
methods: {
// 动态变量获取
getParamOptions() {
getParamsList().then(res => {
this.paramOptions = res.data.list
})
},
// 提交
confirm() {
const domBox = document.getElementById('edit-dom-1')
const getColor = getComputedStyle(domBox).backgroundColor
const getRgb = getColor
.substring(getColor.indexOf('(') + 1, getColor.indexOf(')'))
.replace(/\s*/g, '')
.split(',')
const copyCertElement = JSON.parse(JSON.stringify(this.certElement)).map(item => {
item.originalData.map(i => {
delete i.option
return i
})
return item
})
const params = {
elements: [],
bg_width: domBox.offsetWidth,
bg_height: domBox.offsetHeight,
bg_color: JSON.stringify({ r: getRgb[0], g: getRgb[1], b: getRgb[2] }),
info: JSON.stringify({ toolList: this.toolList, certElement: copyCertElement })
}
this.certElement.forEach(item => {
const dom = document.getElementById(item.id)
const top = dom.getAttribute('data-top')
const left = dom.getAttribute('data-left')
const findW = item.originalData.find(data => data.name === 'width').value
const findH = item.originalData.find(data => data.name === 'height').value
const findZIndex = item.originalData.find(data => data.name === 'zIndex').value
if (item.type === 0 || item.type === 3) {
params.elements.push({
type: 'image',
key: item.url,
width: findW === 'auto' ? dom.offsetWidth + '' : findW,
height: findH === 'auto' ? dom.offsetHeight + '' : findH,
dst_x: top === null ? 0 + '' : top,
dst_y: left === null ? 0 + '' : left,
index: findZIndex + ''
})
} else {
const findS = item.originalData.find(data => data.name === 'fontSize').value
const findF = item.originalData.find(data => data.name === 'fontFamily').value
params.elements.push({
type: item.type === 1 ? 'static_text' : 'dynamic_text',
key: item.textValue || '',
view_width: findW === 'auto' ? dom.offsetWidth + 'px' : findW,
view_height: findH === 'auto' ? dom.offsetHeight + 'px' : findH,
view_x: top === null ? 0 : top,
view_y: left === null ? 0 : left,
dst_x: top === null ? 0 + '' : top,
dst_y: left === null ? 0 + '' : left,
size: findS,
font: findF,
index: findZIndex
})
}
})
params.elements = JSON.stringify(params.elements)
this.$emit('submit', params)
},
// 图片上传后初始化
imgUploadInit(data) {
// 背景图
if (data.type === 3) {
const findElement = this.certElement.findIndex(item => item.type === 3)
if (findElement !== -1) {
this.certElement[findElement].url = data.url
} else {
this.certElement.push(data)
}
this.dragInit(data.id)
} else {
// 普通图片
const findElement = this.certElement.findIndex(item => item.id === data.id)
if (findElement !== -1) {
this.certElement[findElement].url = data.url
} else {
this.certElement.push(data)
}
this.dragInit(data.id)
}
},
// 初始化拖拽
dragInit(id) {
this.$nextTick(() => {
const dom = document.getElementById(id)
drag(dom, document.getElementById('#edit-dom-1'), res => {
dom.style.top = res.top
dom.style.left = res.left
// 记录拖拽后的位置
dom.setAttribute('data-top', res.top)
dom.setAttribute('data-left', res.left)
const index = this.certElement.findIndex(item => item.id === id)
this.certElement[index].top = res.top
this.certElement[index].left = res.left
})
})
},
// 样式改变后赋值给dom
editStyle(data) {
const getDom = document.getElementById(data.id)
getDom.style = data.style
const index = this.certElement.findIndex(item => item.id === data.id)
if (index !== -1) {
delete data.textValue
this.certElement[index] = { ...this.certElement[index], ...data }
}
// 位置单独赋值
const getAttrTop = getDom.getAttribute('data-top')
const getAttrLeft = getDom.getAttribute('data-left')
getDom.style.top = getAttrTop === null ? 0 : getAttrTop + 'px'
getDom.style.left = getAttrLeft === null ? 0 : getAttrLeft + 'px'
},
// 改变文字后
changeText(data) {
const index = this.certElement.findIndex(item => item.id === data.id)
this.certElement[index] = data
this.$forceUpdate()
},
// 添加元素
addElement() {
const textTool = [
{ name: 'width', value: '100px' },
{ name: 'height', value: '35px' },
{ name: 'fontSize', value: '12px' },
{ name: 'fontFamily', value: 'simhei.ttf' },
{ name: 'fontColor', value: '#000000' },
{ name: 'zIndex', value: '1' }
]
switch (this.selectElement) {
case 0:
// 添加图片
this.dynamicId++
// 生成工具栏
this.toolList.push({
type: this.selectElement,
title: '图片',
tool: [
{ name: 'width', value: 'auto' },
{ name: 'height', value: 'auto' },
{ name: 'zIndex', value: '1' }
],
id: `edit-dom-${this.dynamicId}`
})
this.dialogVisible = false
break
case 1:
// 添加文字
this.dynamicId++
this.toolList.push({
type: this.selectElement,
title: '文字',
tool: textTool,
id: `edit-dom-${this.dynamicId}`
})
// 吧文字添加到画板上
this.certElement.push({
type: this.selectElement,
id: `edit-dom-${this.dynamicId}`,
originalData: textTool
})
// 给文字加拖拽
this.dragInit(`edit-dom-${this.dynamicId}`)
this.dialogVisible = false
break
case 2:
if (this.paramValue === '') {
this.$message('请选择变量')
} else {
this.dynamicId++
this.toolList.push({
type: this.selectElement,
title: this.paramValue,
tool: textTool,
id: `edit-dom-${this.dynamicId}`
})
// 吧文字添加到画板上
this.certElement.push({
type: this.selectElement,
textValue: this.paramValue,
originalData: textTool,
id: `edit-dom-${this.dynamicId}`
})
// 给文字加拖拽
this.dragInit(`edit-dom-${this.dynamicId}`)
this.dialogVisible = false
}
break
case 3:
// 添加背景图
// 判断填没填加背景图
if (this.certElement.find(item => item.type === 3) === undefined) {
this.dynamicId++
this.toolList.push({
type: this.selectElement,
title: '背景图',
tool: [
{ name: 'width', value: 'auto' },
{ name: 'height', value: 'auto' },
{ name: 'zIndex', value: '1' }
],
id: `edit-dom-${this.dynamicId}`
})
this.dialogVisible = false
} else {
this.$message('背景图只能添加一张')
}
break
}
}
}
}
</script>
<style lang="scss" scoped>
.step-two-box {
margin-bottom: 20px;
display: flex;
padding: 20px;
min-height: 500px;
.btn {
width: 321px;
height: 40px;
background: rgba(184, 1, 64, 0.19);
border: 1px solid rgba(184, 1, 64, 1);
border-radius: 8px;
font-size: 14px;
line-height: 40px;
color: rgba(184, 1, 64, 1);
cursor: pointer;
text-align: center;
}
.tool-box {
// border-left: 1px solid #dedede;
// border-right: 1px solid #dedede;
padding: 30px 30px 0;
}
.content-right {
border-left: 1px solid #dedede;
margin-left: 30px;
flex: 1;
}
.cert-box {
width: 500px;
height: 300px;
border: 1px solid #dedede;
margin: 0 auto;
overflow: hidden;
position: relative;
background: rgb(255, 255, 255);
}
.edit-img {
position: absolute;
top: 0;
left: 0;
width: fit-content;
.pop {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
}
.text {
position: absolute;
top: 0;
left: 0;
border: 1px dashed #ccc;
width: 100px;
height: 35px;
font-size: 12px;
color: #000;
overflow: hidden;
}
}
</style>
...@@ -20,16 +20,20 @@ ...@@ -20,16 +20,20 @@
<el-switch v-model="row.status" @change="updateStatus(row)"> </el-switch> <el-switch v-model="row.status" @change="updateStatus(row)"> </el-switch>
</template> </template>
<template v-slot:table-x="{ row }"> <template v-slot:table-x="{ row }">
<el-button type="text" @click="handleView(row)">预览</el-button>
<el-button type="text" @click="handleEdit(row)">编辑</el-button> <el-button type="text" @click="handleEdit(row)">编辑</el-button>
<el-button type="text" @click="handleDelete(row)">删除</el-button> <el-button type="text" @click="handleDelete(row)">删除</el-button>
</template> </template>
</app-list> </app-list>
<div class="img-view" v-if="imgViewShow" @click="imgViewShow = false">
<img :src="imgView" alt="" />
</div>
</app-card> </app-card>
</template> </template>
<script> <script>
// 接口 // 接口
import { getAppList, updateBanner, deleteBanner } from '../api' import { getAppList, updateBanner, deleteBanner, getDetails } from '../api'
export default { export default {
data() { data() {
...@@ -38,6 +42,8 @@ export default { ...@@ -38,6 +42,8 @@ export default {
count.push({ value: i, options: i }) count.push({ value: i, options: i })
} }
return { return {
imgViewShow: false,
imgView: '',
value1: '', value1: '',
filterDate: '', filterDate: '',
options: count, options: count,
...@@ -96,13 +102,9 @@ export default { ...@@ -96,13 +102,9 @@ export default {
} }
], ],
columns: [ columns: [
{ label: '模板名称', prop: 'title', align: 'center' },
{ label: 'id', prop: 'id', align: 'center' }, { label: 'id', prop: 'id', align: 'center' },
{ label: '模板标题', prop: 'title', align: 'center' }, { label: '规则编号', prop: 'rule', align: 'center' },
// {
// label: '是否启用',
// slots: 'release-status',
// align: 'center'
// },
{ label: '创建时间', prop: 'created_time', align: 'center' }, { label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '操作', slots: 'table-x', align: 'center' } { label: '操作', slots: 'table-x', align: 'center' }
] ]
...@@ -148,6 +150,12 @@ export default { ...@@ -148,6 +150,12 @@ export default {
this.$refs.list.refetch(true) this.$refs.list.refetch(true)
} }
}) })
},
handleView(row) {
getDetails({ id: row.id }).then(res => {
this.imgView = 'data:image/png;base64,' + res.data.image.replace(/\\r\\n/g, '')
this.imgViewShow = true
})
} }
} }
} }
...@@ -169,4 +177,20 @@ export default { ...@@ -169,4 +177,20 @@ export default {
margin-bottom: 16px; margin-bottom: 16px;
} }
} }
.img-view {
position: fixed;
top: 0;
left: 0;
z-index: 9999;
width: 100%;
height: 100%;
background: rgba($color: #000000, $alpha: 0.5);
img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 50%;
}
}
</style> </style>
<template>
<div class="create-box">
<app-card :title="!$route.query.id ? '新建模板' : '编辑模板'">
<el-steps :active="active" finish-status="success">
<el-step title="步骤 1"></el-step>
<el-step title="步骤 2"></el-step>
</el-steps>
<div class="step-one" v-if="active === 0">
<el-form ref="form" :model="form" style="width: 50%;margin: 0 auto;" label-width="100px">
<el-form-item label="模板名称">
<el-input v-model="form.title"></el-input>
</el-form-item>
<el-form-item label="编号生成规则">
<el-radio-group v-model="form.rule">
<el-radio label="0">规则一</el-radio>
<el-radio label="1">规则二</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="active = 1">下一步</el-button>
<el-button @click="$router.go(-1)">取消</el-button>
</el-form-item>
</el-form>
</div>
<div class="step-two" v-if="active === 1">
<stepTwo @submit="submit" :data="step2Data"></stepTwo>
</div>
</app-card>
</div>
</template>
<script>
import stepTwo from '../components/stepTwo.vue'
import { createTemplate, getDetails, updateTemplate } from '../api'
// import UploadImage from '@/components/upload/UploadImage.vue'
// import { createBanner, getDetails, updateBanner } from '../api'
export default {
components: {
stepTwo
// UploadImage
},
data() {
return {
active: 0,
form: {
title: '',
rule: '0'
},
step2Data: {}
}
},
computed: {
id() {
return this.$route.query.id
}
},
methods: {
submit(data) {
if (this.$route.query.id) {
data.id = this.$route.query.id
updateTemplate(Object.assign(this.form, data)).then(res => {
this.$message({
message: '修改成功',
type: 'success'
})
this.$router.go(-1)
})
} else {
createTemplate(Object.assign(this.form, data)).then(res => {
this.$message({
message: '提交成功',
type: 'success'
})
this.$router.go(-1)
})
}
},
getDetails() {
getDetails({ id: this.id }).then(res => {
const data = res.data
this.form = {
title: data.title,
rule: data.rule
}
this.step2Data = JSON.parse(data.info)
})
}
},
mounted() {
if (this.id) {
this.getDetails()
}
}
}
</script>
<style lang="scss" scoped></style>
<template>
<div>
<el-form :disabled="!!$route.query.type" 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 :disabled="!!$route.query.type" 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
}
},
mounted() {
console.log(this.data, 'display')
}
}
</script>
<style lang="scss">
.tox-notifications-container {
display: none !important;
}
</style>
<template>
<div class="form-box">
<el-form ref="form" :disabled="!!$route.query.type" :rules="rules" :model="data" size="mini" label-width="150px">
<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_import" :label="1">开启</el-radio>
<el-radio v-model="data.can_import" :label="0">关闭</el-radio>
</el-form-item>
<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="缴费方式:" prop="pay_type">
<el-select v-model="data.pay_type" multiple>
<el-option v-for="item in payType" :key="item.key" :label="item.value" :value="item.key"></el-option>
</el-select>
</el-form-item>
<el-form-item label="线下支付联系方式:" prop="offline_info" v-if="data.pay_type.includes('3')">
<el-input style="width: 20%" v-model="data.offline_info"></el-input>
</el-form-item>
<el-form-item label="线下支付信息:" prop="offline_more_info" v-if="data.pay_type.includes('3')">
<v-editor style="width: 500px" :maxHeight="200" :disabled="!!$route.query.type" v-model="data.offline_more_info"></v-editor>
</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="单位优惠金额:" prop="company_price" v-if="data.can_company">
<el-input style="width: 20%" v-model="data.company_price"></el-input>
</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 :disabled="!!$route.query.type" 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 {
payType: [
{ key: '1', value: '微信' },
{ key: '2', value: '支付宝' },
{ key: '3', value: '线下支付' }
],
rules: {
title: { required: true, message: '请填写标题', trigger: 'blur' },
pay_price: [
{ required: true, message: '请填写支付金额', trigger: 'blur' },
{
trigger: 'blur',
min: 0,
validator(rule, value, callback) {
if (Number(value) > 0) {
callback()
} else {
callback(new Error('支付金额不能小于等于0元'))
}
}
}
],
jump_url: { required: true, message: '请填写跳转链接', trigger: 'blur' },
shop_id: { required: true, message: '请选择支付平台', trigger: 'change' },
skip_pay_title: { required: true, message: '请填写跳过支付文案', trigger: 'blur' },
pay_type: { required: true, message: '请填选择缴费方式', trigger: 'change' },
company_price: [
{ required: true, message: '请填写单位优惠金额', trigger: 'blur' },
{
trigger: 'blur',
min: 0,
validator(rule, value, callback) {
if (Number(value) > 0) {
callback()
} else {
callback(new Error('优惠金额不能小于等于0元'))
}
}
}
]
},
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
},
payTypeMap() {
return this.data.pay_type
}
},
created() {},
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
}, [])
this.data.pay_type = this.data.pay_type.toString()
},
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" :disabled="!!$route.query.type" :inline="true" :rules="rules" :model="form">
<el-form-item label="页面标题:" prop="title">
<el-input v-model="form.title"></el-input>
</el-form-item>
<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="选择日期时间"
:picker-options="pickerOptions"
>
</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: {
title: { required: true, message: '请填写页面标题', trigger: 'blur' },
name: { required: true, message: '请填写活动标题', trigger: 'blur' },
max_number: [
{ required: true, message: '请填写最大参与人数', trigger: 'blur' },
{
trigger: 'blur',
min: 1,
message: '最大人数限制不能小于1人',
validator(rule, value, callback) {
if (parseInt(Number(value)) && Number(value) >= 1) {
callback()
} else {
callback(new Error('最大人数限制不能小于1人'))
}
}
}
],
project_id: { required: true, message: '请关联项目', trigger: 'change' },
time: { required: true, message: '请选择时间', trigger: 'change' },
activity_time: { required: true, message: '请选择时间', trigger: 'change' }
},
pickerOptions: {
disabledDate(v) {
return v.getTime() < new Date().getTime() - 86400000
}
}
}
},
computed: {
projectMap() {
return this.$store.state.commonMap.project_map || {}
}
},
mounted() {
console.log(this.form)
},
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>
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<app-list v-bind="tableOptions" ref="list"> <app-list v-bind="tableOptions" ref="list">
<div class="line"></div> <div class="line"></div>
<div class="btn-box"> <div class="btn-box">
<el-button type="primary" @click="$router.push({ path: '/variable/update' })">新建变量</el-button> <el-button type="primary" @click="dialogVisible = true">+ 添加</el-button>
</div> </div>
<template v-slot:filter-time> <template v-slot:filter-time>
<el-date-picker <el-date-picker
...@@ -21,13 +21,41 @@ ...@@ -21,13 +21,41 @@
<el-button type="text" @click="handleDelete(row)">删除</el-button> <el-button type="text" @click="handleDelete(row)">删除</el-button>
</template> </template>
</app-list> </app-list>
<el-dialog title="添加动态变量" :visible.sync="dialogVisible" width="600px">
<el-form
:model="ruleForm"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
style="width: 80%; margin: 0 auto"
>
<el-form-item label="变量名称:">
<el-input v-model="ruleForm.key"></el-input>
</el-form-item>
<el-form-item label="变量字段:">
<el-select v-model="ruleForm.value" placeholder="请选择">
<el-option v-for="item in infoOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<!-- <el-form-item>
<div style="padding-top: 20px">
<el-button type="primary" @click="submitForm">确认</el-button>
<el-button @click="$router.go(-1)">取消</el-button>
</div>
</el-form-item> -->
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="submitForm">确 定</el-button>
</span>
</el-dialog>
</app-card> </app-card>
</template> </template>
<script> <script>
// 接口 // 接口
import { getAppList, deleteVariable } from '../api' import { getAppList, deleteVariable, createVariable, updateVariable } from '../api'
export default { export default {
data() { data() {
const count = [] const count = []
...@@ -39,7 +67,27 @@ export default { ...@@ -39,7 +67,27 @@ export default {
filterDate: '', filterDate: '',
options: count, options: count,
createdStart: '', createdStart: '',
createdEnd: '' createdEnd: '',
dialogVisible: false,
ruleForm: {
key: '',
value: ''
},
infoOptions: [
{ label: '姓名', value: 'name' },
{ label: '电话', value: 'mobile' },
{ label: '身份证号码', value: 'id_number' },
{ label: '邮箱', value: 'email' },
{ label: '地址', value: 'address' },
{ label: '单位', value: 'company' },
{ label: '职位', value: 'position' },
{ label: '编号', value: 'number' },
{ label: '国籍', value: 'country' },
{ label: '省份', value: 'province' },
{ label: '城市', value: 'city' },
{ label: '行业', value: 'industry' },
{ label: '微信', value: 'wechat' }
]
} }
}, },
computed: { computed: {
...@@ -67,15 +115,45 @@ export default { ...@@ -67,15 +115,45 @@ export default {
} }
], ],
columns: [ columns: [
{ label: 'id', prop: 'id', align: 'center' }, { label: '变量名称', prop: 'key' },
{ label: '变量名称', prop: 'key', align: 'center' }, {
{ label: '创建时间', prop: 'created_time', align: 'center' }, label: '关联变量',
{ label: '操作', slots: 'table-x', align: 'center' } prop: 'key2',
computed: res => {
return this.infoOptions.find(item => res.row.value === item.value).label
}
},
{ label: 'id', prop: 'id' },
{ label: '创建时间', prop: 'created_time' },
{ label: '操作', slots: 'table-x' }
] ]
} }
} }
}, },
methods: { methods: {
submitForm() {
if (this.id) {
updateVariable(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '编辑成功',
type: 'success'
})
this.dialogVisible = false
}
})
} else {
createVariable(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '提交成功',
type: 'success'
})
this.dialogVisible = false
}
})
}
},
// 时间搜索 // 时间搜索
changeDate() { changeDate() {
if (this.filterDate) { if (this.filterDate) {
...@@ -88,7 +166,12 @@ export default { ...@@ -88,7 +166,12 @@ export default {
}, },
// 编辑 // 编辑
handleEdit(row) { handleEdit(row) {
this.$router.push({ path: '/variable/update', query: { id: row.id, key: row.key, value: row.value } }) this.ruleForm = {
id: row.id,
key: row.key,
value: row.value
}
this.dialogVisible = true
}, },
// 删除 // 删除
handleDelete(row) { handleDelete(row) {
...@@ -106,10 +189,12 @@ export default { ...@@ -106,10 +189,12 @@ export default {
} }
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
.register-box { .register-box {
.el-form-item { ::v-deep {
margin-right: 20px !important; .el-form-item {
margin-right: 20px !important;
}
} }
.line { .line {
// border-top: 1px solid #D6D6D6; // border-top: 1px solid #D6D6D6;
...@@ -122,4 +207,11 @@ export default { ...@@ -122,4 +207,11 @@ export default {
margin-bottom: 16px; margin-bottom: 16px;
} }
} }
::v-deep {
.el-dialog__body {
border-top: 1px solid #f0f0f0 !important;
border-bottom: 1px solid #f0f0f0 !important;
margin: 10px 0;
}
}
</style> </style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论