提交 87de109b authored 作者: lihuihui's avatar lihuihui

update

上级 9ef6a5d1
{
"name": "project-road-admin",
"name": "center-certificate",
"version": "0.0.0",
"lockfileVersion": 2,
"requires": true,
......@@ -11,6 +11,7 @@
"axios": "^0.23.0",
"blueimp-md5": "^2.19.0",
"element-ui": "^2.15.6",
"html2canvas": "^1.4.1",
"qs": "^6.10.3",
"query-string": "^7.0.1",
"vue": "^2.6.14",
......@@ -1856,6 +1857,14 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
......@@ -2147,6 +2156,14 @@
"node": ">= 8"
}
},
"node_modules/css-line-break": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
......@@ -3729,6 +3746,18 @@
"node": ">=4"
}
},
"node_modules/html2canvas": {
"version": "1.4.1",
"resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
"dependencies": {
"css-line-break": "^2.1.0",
"text-segmentation": "^1.0.3"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/http-errors": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
......@@ -5491,6 +5520,14 @@
"node": ">=8"
}
},
"node_modules/text-segmentation": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
"dependencies": {
"utrie": "^1.0.2"
}
},
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
......@@ -5739,6 +5776,14 @@
"node": ">= 0.12.0"
}
},
"node_modules/utrie": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
"dependencies": {
"base64-arraybuffer": "^1.0.2"
}
},
"node_modules/v8-compile-cache": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
......@@ -7565,6 +7610,11 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"base64-arraybuffer": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
......@@ -7781,6 +7831,14 @@
"which": "^2.0.1"
}
},
"css-line-break": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
"requires": {
"utrie": "^1.0.2"
}
},
"cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
......@@ -8929,6 +8987,15 @@
"integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=",
"dev": true
},
"html2canvas": {
"version": "1.4.1",
"resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
"integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
"requires": {
"css-line-break": "^2.1.0",
"text-segmentation": "^1.0.3"
}
},
"http-errors": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
......@@ -10281,6 +10348,14 @@
}
}
},
"text-segmentation": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
"requires": {
"utrie": "^1.0.2"
}
},
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
......@@ -10488,6 +10563,14 @@
"unescape": "^1.0.1"
}
},
"utrie": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
"requires": {
"base64-arraybuffer": "^1.0.2"
}
},
"v8-compile-cache": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
......
......@@ -14,6 +14,7 @@
"axios": "^0.23.0",
"blueimp-md5": "^2.19.0",
"element-ui": "^2.15.6",
"html2canvas": "^1.4.1",
"qs": "^6.10.3",
"query-string": "^7.0.1",
"vue": "^2.6.14",
......
......@@ -88,3 +88,7 @@ textarea:focus {
:root {
--main-color: rgba(184, 1, 64, 1);
}
.tox-notifications-container{
display: none !important;
}
\ No newline at end of file
<template>
<div class="edit-style-box">
<div class="title">{{ title }}</div>
<div class="f-type">
<template v-if="type == 1">
<el-input
type="textarea"
style="margin-top: 15px"
v-model="returnData.textValue"
placeholder="请输入"
@input="changeText"
></el-input>
</template>
<template v-if="type == 3 || type == 0">
<div class="upload-img">
<div class="btn">上传图片</div>
<UploadImage class="upload" style="width: 50px" v-model="imageUrl" @input="uploadImg"></UploadImage>
</div>
</template>
</div>
<div class="tool-select">
<div v-for="(item, index) in toolList" :key="index">
<div class="tool-item" v-if="item.name === 'fontSize'">
<div class="tit">字体大小</div>
<el-select @change="changeStyle" v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'fontColor'">
<div class="tit">字体颜色</div>
<el-color-picker @change="changeStyle" v-model="item.value"></el-color-picker>
</div>
<div class="tool-item" v-if="item.name === 'fontLineH'">
<div class="tit">字间距</div>
<el-select v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'fontFamily'">
<div class="tit">字体</div>
<el-select @change="changeStyle" v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'borderRadius'">
<div class="tit">圆角</div>
<el-select v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'bgColor'">
<div class="tit">背景颜色</div>
<el-color-picker @change="changeStyle" v-model="item.value"></el-color-picker>
</div>
<div class="tool-item" v-if="item.name === 'fontPosition'">
<div class="tit">位置</div>
<el-select v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'width'">
<div class="tit"></div>
<el-select @change="changeStyle" v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'height'">
<div class="tit"></div>
<el-select @change="changeStyle" v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'zIndex'">
<div class="tit">层级</div>
<el-select @change="changeStyle" v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
</div>
</div>
</div>
</template>
<script>
import UploadImage from '@/components/upload/UploadImage.vue'
export default {
components: {
UploadImage
},
props: {
type: { type: Number },
// 工具框大标题
title: { type: String },
// 工具框小标题
subTitle: { type: String },
// 共有多少个工具
tool: { type: Array },
// 一组数据的话工具框的下标
toolIndex: { type: Number, default: 0 },
// 输入框最多输入的长度
valueMaxLength: { type: Number, default: 10 },
// 回显的数据
echoData: {
type: Object,
default: () => {
return {}
}
},
id: { type: String },
dataFlag: { type: String },
textValue: { type: String }
},
data() {
return {
// 设置样式
toolList: [],
// 最后返回的数据
returnData: {
textValue: ''
},
// 图片的url
imageUrl: ''
}
},
mounted() {
if (this.textValue !== undefined) {
this.returnData.textValue = this.textValue
// this.$forceUpdate()
}
this.setToolData()
},
methods: {
// 文字输入
changeText() {
this.setStyleData()
const data = Object.assign({ originalData: this.toolList }, this.returnData)
data.toolIndex = this.toolIndex
data.id = this.id
data.type = this.type
this.$emit('changeText', data)
},
// 上传img
uploadImg() {
this.setStyleData()
const data = Object.assign({ originalData: this.toolList }, this.returnData)
data.toolIndex = this.toolIndex
data.id = this.id
data.url = this.imageUrl
data.type = this.type
this.$emit('imgUpload', data)
},
// 通过父组件传来的tool重组数据渲染
setToolData() {
const data = [
{
name: 'fontSize',
styleName: 'font-size',
value: '12px',
option: this.setOption(12, 30, 2, 'px')
},
{
name: 'fontColor',
styleName: 'color',
value: '#000000'
},
{
name: 'fontLineH',
styleName: 'line-height',
value: '12px',
option: this.setOption(12, 50, 1, 'px')
},
{
name: 'fontFamily',
styleName: 'font-family',
value: 'fangsong',
option: [{ value: 'fangsong', label: 'fangsong' }]
},
{
name: 'borderRadius',
styleName: 'border-radius',
value: '15px',
option: this.setOption(1, 15, 1, 'px')
},
{
name: 'bgColor',
styleName: 'background',
value: '#000000'
},
{
name: 'fontPosition',
styleName: 'padding',
value: '5px 20px',
option: [
{ value: '5px 20px', label: '居中' },
{ value: '5px 20px 5px 0', label: '居左' },
{ value: '5px 0 5px 20px', label: '居右' }
]
},
{
name: 'width',
styleName: 'width',
value: '500px',
option: this.setOption(0, 800, 1, 'px', 'auto')
},
{
name: 'height',
styleName: 'height',
value: '300px',
option: this.setOption(0, 1000, 1, 'px', 'auto')
},
{
name: 'zIndex',
styleName: 'z-index',
value: '1',
option: this.setOption(0, 50, 1)
}
]
this.toolList = this.tool.reduce((a, b) => {
const item = data.find(i => i.name === b.name)
item && a.push(Object.assign(item, b))
return a
}, [])
},
// 重新组合对象变成父组件需要的
setStyleData() {
this.returnData.style = this.toolList
.reduce((a, b) => {
a.push(`${b.styleName}: ${b.value};`)
return a
}, [])
.join()
.replace(/,/g, '')
},
// 设置option值
setOption(min, max, count, symbol = '', auto) {
const options = auto ? [{ value: 'auto', label: 'auto' }] : []
for (let i = min; i <= max; i += count) {
options.push({ value: `${i}${symbol}`, label: `${i}${symbol}` })
}
return options
},
// 改变值
changeStyle() {
this.setStyleData()
const data = Object.assign({ originalData: this.toolList }, this.returnData)
data.toolIndex = this.toolIndex
data.id = this.id
data.type = this.type
this.$emit('data', data)
}
},
computed: {
toolListWat() {
return this.toolList // 深拷贝需要监听的对象数据
},
returnDataWat() {
return this.returnData // 深拷贝需要监听的对象数据
}
}
}
</script>
<style lang="scss" scoped>
.edit-style-box {
width: 320px;
padding: 22px 23px 0;
background: rgba(248, 248, 248, 0.39);
border-radius: 16px;
margin-bottom: 60px;
position: relative;
&::before {
content: '';
width: 100%;
position: absolute;
bottom: -30px;
left: 0;
border-bottom: 1px solid #e3e3e3;
}
.title {
text-align: center;
font-size: 18px;
font-weight: bold;
line-height: 11px;
color: #333333;
}
.f-type {
padding-top: 21px;
.tit {
font-size: 14px;
line-height: 100%;
color: #333333;
}
.btn {
text-align: center;
line-height: 34px;
background: rgba(184, 1, 64, 1);
border-radius: 6px;
font-size: 14px;
color: #fff;
margin-top: 8px;
border: 1px solid rgba(184, 1, 64, 1);
cursor: pointer;
&.active {
background: rgba(237, 245, 243, 0.39);
border: 1px solid rgba(184, 1, 64, 1);
border-radius: 6px;
color: rgba(184, 1, 64, 1);
}
}
}
.tool-select {
display: flex;
padding-top: 15px;
justify-content: space-between;
flex-wrap: wrap;
.tool-item {
// min-width: 127px;
width: 127px;
margin-bottom: 20px;
// margin-right: 20px;
.tit {
font-size: 14px;
line-height: 100%;
color: #333333;
margin-bottom: 8px;
}
}
::v-deep {
.el-input__inner {
text-align: center;
}
.el-color-picker__trigger {
width: 127px;
.el-color-picker__color {
border-radius: 0;
}
.el-color-picker__icon {
opacity: 0;
}
}
}
}
}
.upload-img {
position: relative;
.btn {
// width: 321px;
height: 40px;
background: rgba(237, 245, 243, 0.39);
border: 1px solid #80d6c4;
border-radius: 8px;
font-size: 14px;
line-height: 40px;
color: #49bba2;
cursor: pointer;
text-align: center;
}
.upload {
position: absolute;
top: 0;
left: 0;
opacity: 0.00001;
::v-deep {
.el-upload {
width: 320px;
height: 40px;
}
}
}
}
</style>
<template>
<div>
<div class="edit-style-box">
<div class="close-btn" v-if="data.type != -1" @click="handleDelete">
<i class="el-icon-close"></i>
</div>
<div class="title">{{ data.title }}</div>
<div class="f-type">
<template v-if="data.type == 3 || data.type == 0">
<div class="upload-img">
<div class="btn">{{ data.url ? '替换图片' : '上传图片' }}</div>
<UploadImage class="upload" style="width: 50px" v-model="data.url" @input="uploadImg"></UploadImage>
</div>
</template>
<template v-if="data.type == 1">
<div>
<v-editor placeholder="请输入内容" v-model="data.html"></v-editor>
</div>
</template>
</div>
<div class="tool-select">
<div v-for="(item, index) in data.tool" :key="index">
<div class="tool-item" v-if="item.name === 'fontSize'">
<div class="tit">字体大小</div>
<el-select @change="changeStyle" v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'fontColor'">
<div class="tit">字体颜色</div>
<el-color-picker @change="changeStyle" v-model="item.value"></el-color-picker>
</div>
<div class="tool-item" v-if="item.name === 'fontLineH'">
<div class="tit">字间距</div>
<el-select v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'fontFamily'">
<div class="tit">字体</div>
<el-select @change="changeStyle" v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'borderRadius'">
<div class="tit">圆角</div>
<el-select v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'bgColor'">
<div class="tit">背景颜色</div>
<el-color-picker @change="changeStyle('proportion')" v-model="item.value"></el-color-picker>
</div>
<div class="tool-item" v-if="item.name === 'fontPosition'">
<div class="tit">位置</div>
<el-select v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'width'">
<div class="tit"></div>
<el-input @input="changeStyle" v-model="item.value" placeholder="请输入数字"></el-input>
</div>
<div class="tool-item" v-if="item.name === 'height'">
<div class="tit"></div>
<el-input @input="changeStyle" v-model="item.value" placeholder="请输入数字"></el-input>
</div>
<div class="tool-item" v-if="item.name === 'zIndex'">
<div class="tit">层级</div>
<el-input @input="changeStyle" v-model="item.value" placeholder="请输入数字"></el-input>
</div>
<div class="tool-item" v-if="item.name === 'proportionWidth'">
<div class="tit">宽高比</div>
<el-select @change="changeStyle('proportion')" v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
<div class="tool-item" v-if="item.name === 'proportionHeight'">
<div class="tit" style="opacity: 0">宽高比</div>
<el-select @change="changeStyle('proportion')" v-model="item.value" filterable placeholder="请选择">
<el-option v-for="opt in item.option" :key="opt.value" :label="opt.label" :value="opt.value"> </el-option>
</el-select>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import VEditor from '@/components/tinymce/Index.vue'
import UploadImage from '@/components/upload/UploadImage.vue'
export default {
components: {
UploadImage,
VEditor
},
props: {
data: { type: Object }
},
data() {
return {
// 设置样式
toolList: [],
// 最后返回的数据
returnData: {}
}
},
mounted() {
this.setToolOption()
},
methods: {
// 上传img
uploadImg() {
this.setStyleData()
this.$emit('imgUpload', this.data)
},
// 通过父组件传来的tool添加option
setToolOption() {
if (this.data.tool) {
this.data.tool = this.data.tool.map(item => {
if (item.option) {
const [min, max, count = 1, symbol = ''] = item.option
item.option = this.setOption(min, max, count, symbol)
}
return item
})
console.log(this.data.tool, '123')
}
},
// 重新组合对象变成样式
setStyleData() {
const styleData = [
{ name: 'fontSize', styleName: 'font-size', symbol: 'px' },
{ name: 'fontColor', styleName: 'color' },
{ name: 'fontLineH', styleName: 'line-height', symbol: 'px' },
{ name: 'fontFamily', styleName: 'font-family' },
{ name: 'bgColor', styleName: 'background' },
{ name: 'width', styleName: 'width', symbol: 'px' },
{ name: 'height', styleName: 'height', symbol: 'px' },
{ name: 'zIndex', styleName: 'z-index' }
]
this.data.style = this.data.tool
.reduce((a, b) => {
if (b.name === 'proportionWidth') {
a.push('width: 100%;')
} else if (b.name === 'proportionHeight') {
const certBox = document.getElementById('edit-dom-1')
const [propWidth, propHeight] = this.data.tool
a.push(`height: ${(propHeight.value / propWidth.value) * certBox.offsetWidth}px;`)
} else {
if (b.value !== '') {
const findItem = styleData.find(item => item.name === b.name)
a.push(`${findItem.styleName}: ${b.value}${findItem.symbol ? findItem.symbol : ''};`)
}
}
return a
}, [])
.join()
.replace(/,/g, '')
},
// 设置option值
setOption(min, max, count, symbol, auto) {
const options = auto ? [{ value: 'auto', label: 'auto' }] : []
for (let i = min; i <= max; i += count) {
options.push({ value: `${i}${symbol}`, label: `${i}${symbol}` })
}
return options
},
// 改变值
changeStyle(name) {
this.setStyleData()
this.$emit('data', this.data)
// if (name === 'proportion') {
// console.log(this.returnData)
// }
},
handleDelete() {
this.$emit('delete', this.data)
}
}
}
</script>
<style lang="scss" scoped>
.edit-style-box {
width: 320px;
padding: 22px 23px 0;
background: rgba(248, 248, 248, 0.39);
border-radius: 16px;
margin-bottom: 60px;
position: relative;
.close-btn {
position: absolute;
top: 15px;
right: 15px;
}
&::before {
content: '';
width: 100%;
position: absolute;
bottom: -30px;
left: 0;
border-bottom: 1px solid #e3e3e3;
}
.title {
text-align: center;
font-size: 18px;
font-weight: bold;
line-height: 11px;
color: #333333;
}
.f-type {
padding-top: 21px;
.tit {
font-size: 14px;
line-height: 100%;
color: #333333;
}
.btn {
text-align: center;
line-height: 34px;
background: rgba(184, 1, 64, 1);
border-radius: 6px;
font-size: 14px;
color: #fff;
margin-top: 8px;
border: 1px solid rgba(184, 1, 64, 1);
cursor: pointer;
&.active {
background: rgba(237, 245, 243, 0.39);
border: 1px solid rgba(184, 1, 64, 1);
border-radius: 6px;
color: rgba(184, 1, 64, 1);
}
}
}
.tool-select {
display: flex;
padding-top: 15px;
justify-content: space-between;
flex-wrap: wrap;
.tool-item {
// min-width: 127px;
width: 127px;
margin-bottom: 20px;
// margin-right: 20px;
.tit {
font-size: 14px;
line-height: 100%;
color: #333333;
margin-bottom: 8px;
}
}
::v-deep {
.el-input__inner {
text-align: center;
}
.el-color-picker__trigger {
width: 127px;
.el-color-picker__color {
border-radius: 0;
}
.el-color-picker__icon {
opacity: 0;
}
}
}
}
}
.upload-img {
position: relative;
.btn {
// width: 321px;
height: 40px;
background: rgba(237, 245, 243, 0.39);
border: 1px solid #80d6c4;
border-radius: 8px;
font-size: 14px;
line-height: 40px;
color: #49bba2;
cursor: pointer;
text-align: center;
}
.upload {
position: absolute;
top: 0;
left: 0;
opacity: 0.00001;
::v-deep {
.el-upload {
width: 320px;
height: 40px;
}
}
}
}
</style>
......@@ -2,14 +2,14 @@
<aside class="app-aside">
<nav class="nav">
<el-menu :default-active="defaultActive" :router="true">
<template v-for="item in menuList">
<template v-for="(item, index) in menuList">
<el-submenu :index="item.path" :key="item.path" v-if="item.children">
<template #title><i :class="item.icon"></i>{{ item.name }}</template>
<el-menu-item :index="subitem.path" v-for="subitem in item.children" :key="subitem.path">
{{ subitem.name }}
</el-menu-item>
</el-submenu>
<el-menu-item :index="item.path" :key="item.path" v-else>
<el-menu-item :index="item.path" :key="index" v-else>
<i :class="item.icon"></i>{{ item.name }}
</el-menu-item>
</template>
......@@ -24,10 +24,10 @@ export default {
data() {
return {
menuList: [
{ name: 'Banner管理', path: '/banner/list', icon: 'el-icon-notebook-2' },
{ name: '功能区管理', path: '/menu/list', icon: 'el-icon-user' },
{ name: '图文管理', path: '/essay/list', icon: 'el-icon-connection' },
{ name: '页面管理', path: '/pages/list', icon: 'el-icon-connection' }
{ name: '证书模板管理', path: '/template/list', icon: 'el-icon-notebook-2' },
{ name: '动态变量管理', path: '/variable/list', icon: 'el-icon-user' },
{ name: '学员管理', path: '/student/list', icon: 'el-icon-connection' },
{ name: '项目管理', path: '/project/list', icon: 'el-icon-connection' }
]
}
},
......
<template>
<div class="create-box">
<app-card :title="!$route.query.id ? '新建Banner' : '编辑Banner'">
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
style="width: 40%; margin: 0 auto"
>
<el-form-item label="标题">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="上传banner" prop="banner">
<upload-image v-model="ruleForm.picture"></upload-image>
</el-form-item>
<el-form-item label="是否发布" prop="status">
<el-switch v-model="status"></el-switch>
</el-form-item>
<el-form-item label="关联选择">
<el-button type="primary" @click="drawer = true">点击选择</el-button>
</el-form-item>
<el-form-item>
<div style="padding-top: 20px">
<el-button type="primary" @click="submitForm">确认</el-button>
<el-button @click="drawer = true">取消</el-button>
</div>
</el-form-item>
</el-form>
</app-card>
<el-drawer size="40%" :visible.sync="drawer" :direction="direction">
<div style="padding: 0 20px">
<el-tabs v-model="activeName">
<el-tab-pane label="关联图文" name="1"></el-tab-pane>
<el-tab-pane label="关联页面" name="2"></el-tab-pane>
<el-tab-pane label="跳转链接" name="3"></el-tab-pane>
</el-tabs>
</div>
</el-drawer>
</div>
</template>
<script>
import UploadImage from '@/components/upload/UploadImage.vue'
import { createBanner, getDetails, updateBanner } from '../api'
export default {
components: {
UploadImage
},
data() {
return {
activeName: '1',
status: true,
drawer: false,
direction: 'rtl',
ruleForm: {
title: '',
url: '',
picture: '',
type: '',
status: true,
relations_id: ''
},
rules: {
banner: [{ required: true, message: '请上传banner', trigger: 'blur' }],
status: [{ required: true, message: '', trigger: 'blur' }]
}
}
},
computed: {
id() {
return this.$route.query.id
}
},
methods: {
// 提交
submitForm() {
this.ruleForm.type = this.activeName
this.ruleForm.status = this.status ? 1 : 0
if (this.id) {
updateBanner(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '编辑成功',
type: 'success'
})
this.$router.go(-1)
}
})
} else {
createBanner(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '提交成功',
type: 'success'
})
this.$router.go(-1)
}
})
}
},
// 获取详情
getDetails() {
getDetails({ id: this.id }).then(res => {
this.status = !!parseInt(res.data.status)
this.ruleForm = res.data
})
}
},
mounted() {
if (this.id) {
this.getDetails()
}
}
}
</script>
<style lang="scss" scoped></style>
import httpRequest from '@/utils/axios'
/**
* 新建图文
*/
export function createEssay(data) {
return httpRequest.post('/api/road/v1/backend/doc/create', data)
}
/**
* 获取应用列表
*/
export function getAppList(params) {
return httpRequest.get('/api/road/v1/backend/doc/list', { params })
}
/**
* 更新图文
*/
export function updateEssay(data) {
return httpRequest.post('/api/road/v1/backend/doc/update', data)
}
/**
* 获取图文详情
*/
export function getDetails(params) {
return httpRequest.get('/api/road/v1/backend/doc/view', { params })
}
/**
* 删除图文
*/
export function deleteEssay(data) {
return httpRequest.post('/api/road/v1/backend/doc/delete', data)
}
// /**
// * 获取应用列表
// */
// 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)
// }
// /**
// * 停止活动
// */
// export function stopRegister(data) {
// return httpRequest.post('/api/register/v1/activity/drop', data)
// }
<template>
<div class="create-box">
<app-card :title="!$route.query.id ? '新建菜单' : '编辑菜单'">
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
style="width: 80%; margin: 0 auto"
>
<el-form-item label="封面图" prop="picture">
<upload-image v-model="ruleForm.picture"></upload-image>
</el-form-item>
<el-form-item label="标题" prop="title">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="ruleForm.comment"></el-input>
</el-form-item>
<el-form-item label="跳转链接">
<el-input v-model="ruleForm.url"></el-input>
</el-form-item>
<el-form-item label="摘要">
<el-input v-model="ruleForm.remark"></el-input>
</el-form-item>
<el-form-item label="正文" prop="content">
<v-editor v-model="ruleForm.content"></v-editor>
</el-form-item>
<el-form-item label="是否启用" prop="status">
<el-switch v-model="status"></el-switch>
</el-form-item>
<el-form-item label="关联选择">
<el-button type="primary" @click="drawer = true">点击选择</el-button>
</el-form-item>
<el-form-item>
<div style="padding-top: 20px; width: 200px; margin: 0 auto">
<el-button type="primary" @click="submitForm">确认</el-button>
<el-button @click="drawer = true">取消</el-button>
</div>
</el-form-item>
</el-form>
</app-card>
<el-drawer size="40%" :visible.sync="drawer" :direction="direction">
<div style="padding: 0 20px">
<el-tabs v-model="activeName">
<el-tab-pane label="关联图文" name="1"></el-tab-pane>
<el-tab-pane label="关联页面" name="2"></el-tab-pane>
<el-tab-pane label="跳转链接" name="3"></el-tab-pane>
</el-tabs>
</div>
</el-drawer>
</div>
</template>
<script>
import VEditor from '@/components/tinymce/Index.vue'
import UploadImage from '@/components/upload/UploadImage.vue'
import { createEssay, getDetails, updateEssay } from '../api'
export default {
components: {
UploadImage,
VEditor
},
data() {
return {
activeName: '1',
status: true,
drawer: false,
direction: 'rtl',
ruleForm: {
title: '',
comment: '',
url: '',
picture: '',
remark: '',
content: '',
status: true,
relations_id_page: '',
relations_id_banner: '',
relations_id_menu: ''
},
rules: {
title: [{ required: true, message: '请填写菜单名称', trigger: 'blur' }],
picture: [{ required: true, message: '请上传banner', trigger: 'blur' }],
status: [{ required: true, message: '', trigger: 'blur' }],
content: [{ required: true, message: '请输入正文', trigger: 'blur' }]
}
}
},
computed: {
id() {
return this.$route.query.id
}
},
methods: {
// 提交
submitForm() {
this.ruleForm.type = this.activeName
this.ruleForm.status = this.status ? 1 : 0
if (this.id) {
updateEssay(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '编辑成功',
type: 'success'
})
this.$router.go(-1)
}
})
} else {
createEssay(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '提交成功',
type: 'success'
})
this.$router.go(-1)
}
})
}
},
// 获取详情
getDetails() {
getDetails({ id: this.id }).then(res => {
this.status = !!parseInt(res.data.status)
this.ruleForm = res.data
})
}
},
mounted() {
if (this.id) {
this.getDetails()
}
}
}
</script>
<style lang="scss" scoped></style>
import httpRequest from '@/utils/axios'
/**
* 新建菜单
*/
export function createMenu(data) {
return httpRequest.post('/api/road/v1/backend/menu/create', data)
}
/**
* 获取应用列表
*/
export function getAppList(params) {
return httpRequest.get('/api/road/v1/backend/menu/list', { params })
}
/**
* 更新菜单
*/
export function updateMenu(data) {
return httpRequest.post('/api/road/v1/backend/menu/update', data)
}
/**
* 获取菜单详情
*/
export function getDetails(params) {
return httpRequest.get('/api/road/v1/backend/menu/view', { params })
}
/**
* 删除菜单
*/
export function deleteMenu(data) {
return httpRequest.post('/api/road/v1/backend/menu/delete', data)
}
// /**
// * 获取应用列表
// */
// 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)
// }
// /**
// * 停止活动
// */
// export function stopRegister(data) {
// return httpRequest.post('/api/register/v1/activity/drop', data)
// }
<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>
import httpRequest from '@/utils/axios'
/**
* 新建页面
*/
export function createPages(data) {
return httpRequest.post('/api/road/v1/backend/page/create', data)
}
/**
* 获取应用列表
*/
export function getAppList(params) {
return httpRequest.get('/api/road/v1/backend/page/list', { params })
}
/**
* 更新页面
*/
export function updatePages(data) {
return httpRequest.post('/api/road/v1/backend/page/update', data)
}
/**
* 获取页面详情
*/
export function getDetails(params) {
return httpRequest.get('/api/road/v1/backend/page/view', { params })
}
/**
* 删除页面
*/
export function deletePages(data) {
return httpRequest.post('/api/road/v1/backend/page/delete', data)
}
// /**
// * 获取应用列表
// */
// 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)
// }
// /**
// * 停止活动
// */
// export function stopRegister(data) {
// return httpRequest.post('/api/register/v1/activity/drop', data)
// }
<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>
import httpRequest from '@/utils/axios'
/**
* 获取模板列表
*/
export function getTemplateList(params) {
return httpRequest.get('/api/cert/v1/backend/template/list', { params })
}
/**
* 获取学员列表
*/
export function getStudentList(params) {
return httpRequest.get('/api/cert/v1/backend/student/list', { params })
}
/**
* 更新项目
*/
export function updateProject(data) {
return httpRequest.post('/api/cert/v1/backend/project/update', data)
}
/**
* 新建项目
*/
export function createProject(data) {
return httpRequest.post('/api/cert/v1/backend/project/create', data)
}
/**
* 获取应用列表
*/
export function getAppList(params) {
return httpRequest.get('/api/cert/v1/backend/project/list', { params })
}
/**
* 获取项目详情
*/
export function getDetails(params) {
return httpRequest.get('/api/cert/v1/backend/project/view', { params })
}
/**
* 删除项目
*/
export function deleteProject(data) {
return httpRequest.post('/api/cert/v1/backend/project/delete', data)
}
/**
* 办法证书
*/
export function projectPublish(data) {
return httpRequest.post('/api/cert/v1/backend/project/publish', data)
}
......@@ -2,7 +2,7 @@ import AppLayout from '@/components/layout/Index.vue'
const routes = [
{
path: '/banner',
path: '/project',
component: AppLayout,
children: [
{ path: 'list', component: () => import('./views/List.vue') },
......
......@@ -3,7 +3,7 @@
<app-list v-bind="tableOptions" ref="list">
<div class="line"></div>
<div class="btn-box">
<el-button type="primary" @click="$router.push({ path: '/essay/update' })">新建图文</el-button>
<el-button type="primary" @click="$router.push({ path: '/project/update' })">新建项目</el-button>
</div>
<template v-slot:filter-time>
<el-date-picker
......@@ -28,16 +28,16 @@
</el-select>
</template>
<template v-slot:table-x="{ row }">
<el-button type="text" @click="handlePublish(row)">颁发证书</el-button>
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
<el-button type="text" @click="handleDelete(row)">删除</el-button>
</template>
</app-list>
</app-card>
</template>
<script>
// 接口
import { getAppList, updateEssay, deleteEssay } from '../api'
import { getAppList, deleteProject, getTemplateList, projectPublish } from '../api'
export default {
data() {
......@@ -50,7 +50,8 @@ export default {
filterDate: '',
options: count,
createdStart: '',
createdEnd: ''
createdEnd: '',
templateList: []
}
},
computed: {
......@@ -78,16 +79,15 @@ export default {
{
type: 'input',
prop: 'title',
label: '标题:'
label: '项目名称:'
},
{
type: 'select',
prop: 'status',
label: '发布状态:',
options: [
{ value: '0', label: '未发布' },
{ value: '1', label: '已发布' }
]
prop: 'template_id',
label: '证书模板:',
labelKey: 'title',
valueKey: 'id',
options: this.templateList
},
{
slots: 'filter-time',
......@@ -96,23 +96,33 @@ export default {
],
columns: [
{ label: 'id', prop: 'id', align: 'center' },
{ label: '封面图', slots: 'picture', align: 'center', width: '170px' },
{ label: '标题', prop: 'title', align: 'center' },
{ label: '摘要', prop: 'remark', align: 'center' },
{ label: '备注', prop: 'comment', align: 'center' },
{
label: '发布状态',
slots: 'release-status',
align: 'center'
},
{ label: '项目名称', prop: 'title', align: 'center' },
{ label: '关联人数', prop: 'students_count', align: 'center' },
{ label: '关联证书模板', prop: 'template_id_name', align: 'center' },
{ label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '排序', slots: 'sort-select', align: 'center' },
{ label: '操作', slots: 'table-x', align: 'center' }
]
}
}
},
methods: {
// 办法证书
handlePublish(row) {
projectPublish({ id: row.id }).then(res => {
if (res.code === 0) {
this.$message({
message: '颁发成功',
type: 'success'
})
}
})
},
// 证书模板
getTemplateList() {
getTemplateList({ 'per-page': 100 }).then(res => {
this.templateList = res.data.list
})
},
// 时间搜索
changeDate() {
if (this.filterDate) {
......@@ -124,25 +134,11 @@ export default {
// this.$refs.list.refetch(true)
}
},
// 更新发布状态
updateStatus(row) {
const params = row
params.status = row.status ? '1' : '0'
updateEssay(row).then(res => {
if (res.code === 0) {
this.$message({
message: '修改成功',
type: 'success'
})
this.$refs.list.refetch(true)
}
})
},
handleEdit(row) {
this.$router.push({ path: '/essay/update', query: { id: row.id } })
this.$router.push({ path: '/project/update', query: { id: row.id } })
},
handleDelete(row) {
deleteEssay({ id: row.id }).then(res => {
deleteProject({ id: row.id }).then(res => {
if (res.code === 0) {
this.$message({
message: '删除成功',
......@@ -152,6 +148,9 @@ export default {
}
})
}
},
mounted() {
this.getTemplateList()
}
}
</script>
......
<template>
<div class="create-box">
<app-card :title="!$route.query.id ? '新建项目' : '编辑项目'">
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="110px"
class="demo-ruleForm"
style="width: 80%; margin: 0 auto"
>
<el-form-item label="项目名称" prop="title">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="关联证书模板" prop="template">
<el-select filterable v-model="ruleForm.template_id" placeholder="请选择">
<el-option v-for="item in templateList" :key="item.id" :label="item.title" :value="item.id"> </el-option>
</el-select>
</el-form-item>
<el-form-item label="关联学员">
<el-card class="box-card">
<div slot="header" class="clearfix">
<el-button type="primary" @click="drawer = true">选择学员</el-button>
</div>
<app-list v-bind="tableOptions" ref="list">
<template v-slot:table-x="{ row }">
<el-button type="text" @click="handleDelete(row)">删除</el-button>
</template>
</app-list>
</el-card>
</el-form-item>
<el-form-item>
<div style="padding-top: 20px; width: 200px; margin: 0 auto">
<el-button type="primary" @click="submitForm">确认</el-button>
<el-button @click="drawer = true">取消</el-button>
</div>
</el-form-item>
</el-form>
</app-card>
<el-drawer size="80%" :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>
<div style="padding-left: 30px"><el-button type="primary" @click="drawer = false">确认</el-button></div>
</el-drawer>
</div>
</template>
<script>
import { getDetails, updateProject, getTemplateList, getStudentList, createProject } from '../api'
export default {
components: {},
data() {
return {
drawer: false,
direction: 'rtl',
ruleForm: {
title: '',
template_id: ''
},
rules: {
title: [{ required: true, message: '请填写菜单名称', trigger: 'blur' }],
template: [{ required: true, message: '请选择证书模板', trigger: 'blur' }]
},
templateList: [],
studentTableOptions: []
}
},
computed: {
id() {
return this.$route.query.id
},
// 列表配置
selectTableOptions() {
return {
limit: 10,
remote: {
httpRequest: getStudentList,
params: this.form,
callback: res => {
// 选中后不在列表展示
const filterData = []
res.forEach(element => {
if (!this.studentTableOptions.find(item => item.id === element.id)) {
filterData.push(element)
}
})
return filterData
}
},
filters: [
{
type: 'input',
label: '姓名:',
props: 'name'
},
{
type: 'input',
label: '手机号:',
props: 'mobile'
}
],
columns: [
{ type: 'selection', prop: 'selection', align: 'center' },
{ label: 'id', prop: 'id', align: 'center' },
{ label: '姓名', prop: 'name', align: 'center' },
{ label: '手机号', prop: 'mobile', align: 'center' },
{ label: '邮箱', prop: 'email', align: 'center' },
{ label: '编号', prop: 'number', align: 'center' },
{ label: '创建时间', prop: 'created_time', align: 'center' }
]
}
},
tableOptions() {
return {
columns: [
{ label: 'id', prop: 'id', align: 'center' },
{ label: '姓名', prop: 'name', align: 'center' },
{ label: '手机号', prop: 'mobile', align: 'center' },
{ label: '邮箱', prop: 'email', align: 'center' },
{ label: '编号', prop: 'number', align: 'center' },
{ label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '操作', slots: 'table-x', align: 'center' }
],
data: this.studentTableOptions
}
}
},
methods: {
// 删除绑定的学员
handleDelete(row) {
const findIndex = this.studentTableOptions.findIndex(item => row.id === item.id)
if (findIndex !== -1) {
this.studentTableOptions.splice(findIndex, 1)
}
},
// 选择学员
selectionChange(selection) {
this.studentTableOptions = selection
},
// 证书模板
getTemplateList() {
getTemplateList({ 'per-page': 100 }).then(res => {
this.templateList = res.data.list
})
},
// 提交
submitForm() {
const params = this.ruleForm
params.students_id = this.studentTableOptions
.reduce((a, b) => {
a.push(b.id)
return a
}, [])
.toString(',')
if (this.id) {
updateProject(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '编辑成功',
type: 'success'
})
this.$router.go(-1)
}
})
} else {
createProject(params).then(res => {
if (res.code === 0) {
this.$message({
message: '提交成功',
type: 'success'
})
this.$router.go(-1)
}
})
}
},
// 获取详情
getDetails() {
getDetails({ id: this.id }).then(res => {
this.ruleForm = res.data
this.studentTableOptions = res.data.students.reduce((a, b) => {
a.push(b.student)
return a
}, [])
})
}
},
mounted() {
if (this.id) {
this.getDetails()
}
this.getTemplateList()
}
}
</script>
<style lang="scss" scoped></style>
import httpRequest from '@/utils/axios'
/**
* 新建学员
*/
export function createStudent(data) {
return httpRequest.post('/api/cert/v1/backend/student/create', data)
}
/**
* 获取应用列表
*/
export function getAppList(params) {
return httpRequest.get('/api/cert/v1/backend/student/list', { params })
}
/**
* 导入
*/
export function importPeople(data) {
return httpRequest({
url: '/api/cert/v1/backend/student/import',
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' },
timeout: 900000,
data,
withCredentials: true
})
}
/**
* 更新学员
*/
export function updateStudent(data) {
return httpRequest.post('/api/cert/v1/backend/student/update', data)
}
/**
* 获取详情
*/
export function getDetails(params) {
return httpRequest.get('/api/cert/v1/backend/student/view', { params })
}
/**
* 删除学员
*/
export function deleteStudent(data) {
return httpRequest.post('/api/cert/v1/backend/student/delete', data)
}
/**
* 获取项目列表
*/
export function getProjectList(params) {
return httpRequest.get('/api/cert/v1/backend/project/list', { params })
}
/**
* 获取模板列表
*/
export function getTemplateList(params) {
return httpRequest.get('/api/cert/v1/backend/template/list', { params })
}
<template>
<el-dialog v-bind="$attrs" v-on="$listeners">
<el-form :model="form" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="关联项目">
<el-select @change="$forceUpdate()" filterable multiple v-model="form.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>
<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="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"
style="color: #c01c40"
>
<i class="el-icon-download"></i>人员模板.xlsx</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, getProjectList } from '../api'
export default {
data() {
return {
options: [],
form: {
projects_id: []
},
file: '',
activityOption: [],
stepOption: [],
fileList: []
}
},
computed: {},
mounted() {
this.getProjectList()
},
methods: {
// 获取项目列表
getProjectList() {
getProjectList().then(res => {
this.options = res.data.list.filter(item => item.status !== '2')
})
},
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.$emit('cancel')
}
}
}
</script>
<style lang="scss" scoped>
.file-import {
::v-deep {
.el-upload-dragger {
width: 260px !important;
}
}
}
</style>
......@@ -2,7 +2,7 @@ import AppLayout from '@/components/layout/Index.vue'
const routes = [
{
path: '/essay',
path: '/student',
component: AppLayout,
children: [
{ path: 'list', component: () => import('./views/List.vue') },
......
......@@ -3,54 +3,55 @@
<app-list v-bind="tableOptions" ref="list">
<div class="line"></div>
<div class="btn-box">
<el-button type="primary" @click="$router.push({ path: '/menu/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="downloadRecords">导出学员</el-button>
</div>
<template v-slot:filter-time>
<el-date-picker
v-model="filterDate"
@change="changeDate"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
<template v-slot:filter-name>
<el-input v-model="form.name" placeholder="请输入内容"></el-input>
</template>
<template v-slot:picture="{ row }">
<div :style="`background-image:url(${row.picture});background-size: cover;width:50px;height:40px;`"></div>
<template v-slot:filter-mobile>
<el-input v-model="form.mobile" placeholder="请输入内容"></el-input>
</template>
<template v-slot:release-status="{ row }">
<el-switch v-model="row.status" @change="updateStatus(row)"> </el-switch>
<template v-slot:filter-project>
<el-input v-model="form.project" placeholder="请输入内容"></el-input>
</template>
<template v-slot:sort-select="{ row }">
<el-select v-model="row.sort" placeholder="请选择" @change="updateStatus(row)">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
<template v-slot:filter-template>
<el-input v-model="form.template" placeholder="请输入内容"></el-input>
</template>
<template v-slot:table-x="{ row }">
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
<el-button type="text" @click="handleDelete(row)">删除</el-button>
</template>
</app-list>
<import-people
@cancel="importDialogVisible = false"
width="400px"
:visible.sync="importDialogVisible"
></import-people>
</app-card>
</template>
<script>
import importPeople from '../components/importPeople.vue'
// 接口
import { getAppList, updateMenu, deleteMenu } from '../api'
import { getAppList, deleteStudent, getTemplateList, getProjectList } from '../api'
export default {
components: {
importPeople
},
data() {
const count = []
for (let i = 0; i < 100; i++) {
count.push({ value: i, options: i })
}
return {
value1: '',
filterDate: '',
options: count,
createdStart: '',
createdEnd: ''
importDialogVisible: false,
form: {
name: '',
mobile: '',
project_id: '',
template_id: ''
},
templateList: [],
projectList: []
}
},
computed: {
......@@ -60,88 +61,85 @@ export default {
limit: 10,
remote: {
httpRequest: getAppList,
params: {
title: '',
status: '',
created_time_start: this.createdStart,
created_time_end: this.createdEnd
},
callback: res => {
res.map(item => {
item.status = !!parseInt(item.status)
return item
})
return res
}
params: this.form
},
filters: [
{
type: 'input',
prop: 'title',
label: '标题:'
slots: 'filter-name',
label: '姓名:'
},
{
type: 'input',
slots: 'filter-mobile',
label: '手机号:'
},
{
type: 'select',
prop: 'status',
label: '发布状态:',
options: [
{ value: '0', label: '未发布' },
{ value: '1', label: '已发布' }
]
prop: 'project_id',
label: '所属项目:',
labelKey: 'title',
valueKey: 'id',
options: this.projectList
},
{
slots: 'filter-time',
label: '创建时间:'
type: 'select',
prop: 'template_id',
label: '证书模板:',
labelKey: 'title',
valueKey: 'id',
options: this.templateList
}
],
columns: [
{ label: 'id', prop: 'id', align: 'center' },
{ label: '菜单图标', slots: 'picture', align: 'center', width: '50px' },
{ label: '菜单名称', prop: 'title', align: 'center' },
{ label: '备注', prop: 'comment', align: 'center' },
{
label: '发布状态',
slots: 'release-status',
align: 'center'
},
{ label: '姓名', prop: 'name', align: 'center' },
{ label: '手机号', prop: 'mobile', align: 'center' },
{ label: '邮箱', prop: 'email', align: 'center' },
{ label: '编号', prop: 'number', align: 'center' },
{ label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '排序', slots: 'sort-select', align: 'center' },
{ label: '操作', slots: 'table-x', align: 'center' }
]
}
}
},
methods: {
// 时间搜索
changeDate() {
if (this.filterDate) {
this.createdStart = this.filterDate[0]
this.createdEnd = this.filterDate[1]
} else {
this.createdStart = ''
this.createdEnd = ''
// this.$refs.list.refetch(true)
}
// 项目列表
getProjectList() {
getProjectList().then(res => {
this.projectList = res.data.list
})
},
// 更新发布状态
updateStatus(row) {
const params = row
params.status = row.status ? '1' : '0'
updateMenu(row).then(res => {
if (res.code === 0) {
this.$message({
message: '修改成功',
type: 'success'
})
this.$refs.list.refetch(true)
// 证书模板
getTemplateList() {
getTemplateList({ 'per-page': 100 }).then(res => {
this.templateList = res.data.list
})
},
// 导出
downloadRecords() {
const formParams = []
Object.keys(this.form).forEach(item => {
if (this.form[item]) {
formParams.push(`${item}=${this.form[item]}`)
}
})
window.open(
`${window.location.origin}/api/cert/v1/backend/student/download?${formParams.join().replace(/,/g, '&')}`
)
},
// 编辑
handleEdit(row) {
this.$router.push({ path: '/menu/update', query: { id: row.id } })
const find = row.projects.find(item => item.status === '3' || item.status === '1')
if (find) {
this.$message(find.status === '1' ? '学员已有生成中证书禁止编辑' : '学员已有证书已生成禁止编辑')
return false
}
this.$router.push({ path: '/student/update', query: { id: row.id } })
},
// 删除
handleDelete(row) {
deleteMenu({ id: row.id }).then(res => {
deleteStudent({ id: row.id }).then(res => {
if (res.code === 0) {
this.$message({
message: '删除成功',
......@@ -151,6 +149,10 @@ export default {
}
})
}
},
mounted() {
this.getTemplateList()
this.getProjectList()
}
}
</script>
......
<template>
<div class="create-box">
<app-card :title="!$route.query.id ? '新建菜单' : '编辑菜单'">
<app-card :title="!$route.query.id ? '新建学员' : '编辑学员'">
<el-form
:model="ruleForm"
:rules="rules"
......@@ -9,67 +9,92 @@
class="demo-ruleForm"
style="width: 40%; margin: 0 auto"
>
<el-form-item label="菜单名称" prop="title">
<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-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item label="电话号" prop="mobile">
<el-input v-model="ruleForm.mobile"></el-input>
</el-form-item>
<el-form-item label="身份证号">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="地址">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="单位">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="职位">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="编号">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="ruleForm.comment"></el-input>
<el-form-item label="国籍">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="省份">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="菜单图标" prop="picture">
<upload-image v-model="ruleForm.picture"></upload-image>
<el-form-item label="城市">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="是否启用" prop="status">
<el-switch v-model="status"></el-switch>
<el-form-item label="行业">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item label="关联选择">
<el-button type="primary" @click="drawer = true">点击选择</el-button>
<el-form-item label="微信">
<el-input v-model="ruleForm.title"></el-input>
</el-form-item>
<el-form-item>
<div style="padding-top: 20px">
<el-button type="primary" @click="submitForm">确认</el-button>
<el-button @click="drawer = true">取消</el-button>
<el-button @click="$router.go(-1)">取消</el-button>
</div>
</el-form-item>
</el-form>
</app-card>
<el-drawer size="40%" :visible.sync="drawer" :direction="direction">
<div style="padding: 0 20px">
<el-tabs v-model="activeName">
<el-tab-pane label="关联图文" name="1"></el-tab-pane>
<el-tab-pane label="关联页面" name="2"></el-tab-pane>
<el-tab-pane label="跳转链接" name="3"></el-tab-pane>
</el-tabs>
</div>
</el-drawer>
</div>
</template>
<script>
import UploadImage from '@/components/upload/UploadImage.vue'
import { createMenu, getDetails, updateMenu } from '../api'
import { createStudent, getDetails, updateStudent, getProjectList } from '../api'
export default {
components: {
UploadImage
// UploadImage
},
data() {
return {
activeName: '1',
status: true,
drawer: false,
direction: 'rtl',
options: [],
ruleForm: {
title: '',
url: '',
picture: '',
type: '',
status: true,
relations_id: '',
comment: ''
projects_id: [],
name: '',
mobile: '',
id_number: '',
email: '',
address: '',
company: '',
position: '',
number: '',
country: '',
province: '',
city: '',
industry: '',
wechat: ''
},
rules: {
title: [{ required: true, message: '请填写菜单名称', trigger: 'blur' }],
picture: [{ required: true, message: '请上传banner', trigger: 'blur' }],
status: [{ required: true, message: '', trigger: 'blur' }]
name: [{ required: true, message: '请填写姓名', trigger: 'blur' }],
mobile: [{ required: true, message: '请填写电话', trigger: 'blur' }]
}
}
},
......@@ -81,10 +106,9 @@ export default {
methods: {
// 提交
submitForm() {
this.ruleForm.type = this.activeName
this.ruleForm.status = this.status ? 1 : 0
this.ruleForm.projects_id = this.ruleForm.projects_id.toString(',')
if (this.id) {
updateMenu(this.ruleForm).then(res => {
updateStudent(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '编辑成功',
......@@ -94,7 +118,7 @@ export default {
}
})
} else {
createMenu(this.ruleForm).then(res => {
createStudent(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '提交成功',
......@@ -108,8 +132,19 @@ export default {
// 获取详情
getDetails() {
getDetails({ id: this.id }).then(res => {
this.status = !!parseInt(res.data.status)
this.ruleForm = res.data
this.ruleForm.projects_id = res.data.projects.reduce((a, b) => {
if (b.status !== '2') {
a.push(b.project_id)
}
return a
}, [])
})
},
// 获取项目列表
getProjectList() {
getProjectList().then(res => {
this.options = res.data.list.filter(item => item.status !== '2')
})
}
},
......@@ -117,6 +152,7 @@ export default {
if (this.id) {
this.getDetails()
}
this.getProjectList()
}
}
</script>
......
import httpRequest from '@/utils/axios'
/**
* 新建banner
* 获取动态变量列表
*/
export function createBanner(data) {
return httpRequest.post('/api/road/v1/backend/banner/create', data)
export function getParamsList(params) {
return httpRequest.get('/api/cert/v1/backend/param/list', { params })
}
/**
* 创建模板
*/
export function createTemplate(data) {
return httpRequest.post('/api/cert/v1/backend/template/create', data)
}
/**
* 获取应用列表
*/
export function getAppList(params) {
return httpRequest.get('/api/road/v1/backend/banner/list', { params })
return httpRequest.get('/api/cert/v1/backend/template/list', { params })
}
/**
* 更新banner
* 获取详情
*/
export function updateBanner(data) {
return httpRequest.post('/api/road/v1/backend/banner/update', data)
export function getDetails(params) {
return httpRequest.get('/api/cert/v1/backend/template/view', { params })
}
/**
* 获取banner详情
* 更新模板
*/
export function getDetails(params) {
return httpRequest.get('/api/road/v1/backend/banner/view', { params })
export function updateTemplate(data) {
return httpRequest.post('/api/cert/v1/backend/template/update', data)
}
/**
* 更新banner
*/
export function updateBanner(data) {
return httpRequest.post('/api/cert/v1/backend/template/update', data)
}
/**
......
<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>
<template>
<div class="edit-cert-box">
<div @click="toImage">111</div>
<div class="tool-left">
<div style="padding-right: 20px; border-right: 1px solid #e3e3e3">
<editStyle @data="changeStyle" :data="certBoxEditStyle"></editStyle>
<template v-for="(item, index) in certElement">
<div v-if="item.show" :key="index" @click="domShow(item.id)">
<editStyle @delete="deleteEdit" @imgUpload="imgUpload" @data="changeStyle" :data="item"></editStyle>
</div>
</template>
</div>
<div class="tool-btn">
<el-button type="primary" @click="dialogVisible = true">添加元素</el-button>
</div>
</div>
<div class="tool-right">
<div :style="certBoxEditStyle.style" id="edit-dom-1" ref="imageTofile">
<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="item.show ? 'edit-img active' : 'edit-img'"
@click="domShow(item.id)"
>
<div v-if="item.url" style="width: 100%; height: 100%">
<div class="pop"></div>
<img style="width: 100%; display: block; height: 100%" :src="item.url" />
</div>
</div>
<div
:style="item.style"
v-if="item.type === 1"
:class="item.show ? 'text active' : 'text'"
:key="item.id"
:id="item.id"
@click="domShow(item.id)"
>
<div class="pop"></div>
<div v-html="item.html"></div>
</div>
</template>
</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 html2canvas from 'html2canvas'
import editStyle from '@/components/base/EditStyle.vue'
import { getParamsList } from '../api'
import drag from '@/utils/drag.js'
import { uploadBlob } from '@/utils/blob'
export default {
components: {
editStyle
},
data() {
return {
htmlUrl: '',
// 动态id
dynamicId: 1,
// 动态变量
paramValue: '',
// 动态变量选项
paramOptions: [],
// 添加dom弹窗
dialogVisible: false,
// 选择添加那个类型的dom
selectElement: 0,
// 证书大小设置
certBoxEditStyle: {
type: '-1',
title: '证书设置',
tool: [
{ name: 'proportionWidth', value: 1, option: [1, 20, 1] },
{ name: 'proportionHeight', value: 1, option: [1, 20, 1] },
{ name: 'bgColor', value: '#ffffff' }
],
style: ''
},
// 所有添加的dom元素
certElement: [],
isShowFlag: true
}
},
computed: {},
mounted() {
document.querySelector('.app-aside').style.display = 'none'
document.onclick = () => {
if (this.certElement.length && this.isShowFlag) {
this.certElement.map(item => {
item.show = false
return item
})
}
}
this.setCertBox()
},
methods: {
// 删除工具
deleteEdit(data) {
const index = this.certElement.findIndex(item => item.id === data.id)
this.certElement.splice(index, 1)
},
// 吧html生成图片
toImage() {
html2canvas(this.$refs.imageTofile, {
backgroundColor: null,
useCORS: true
}).then(canvas => {
// const url = canvas.toDataURL('image/png')
// this.htmlUrl = url
canvas.toBlob(function (blob) {
console.log(blob, 'blob')
uploadBlob(blob).then(res => {
console.log(res, '123123')
})
})
})
},
domShow(id) {
this.isShowFlag = false
setTimeout(() => {
this.certElement.map(item => {
item.show = false
return item
})
const index = this.certElement.findIndex(item => item.id === id)
if (this.certElement[index]) {
this.certElement[index].show = true
}
this.isShowFlag = true
}, 100)
},
// 图片上传后
imgUpload(data) {
// 图片上传后开启拖拽
this.dragInit(data.id)
},
// 添加元素
addElement() {
setTimeout(() => {
this.dynamicId++
const certBox = document.getElementById('edit-dom-1')
// 添加图片
if (this.selectElement === 0) {
this.certElement.push({
type: this.selectElement,
title: '上传图片',
tool: [
{ name: 'width', value: certBox.offsetWidth },
{ name: 'height', value: '' },
{ name: 'zIndex', value: '1' }
],
url: '',
show: true,
id: `edit-dom-${this.dynamicId}`
})
this.dialogVisible = false
} else if (this.selectElement === 1) {
this.certElement.push({
title: '文字',
type: this.selectElement,
tool: [{ name: 'zIndex', value: '1' }],
html: '请输入内容',
show: true,
id: `edit-dom-${this.dynamicId}`
})
// 添加成功后添加拖拽
setTimeout(() => {
this.dragInit(`edit-dom-${this.dynamicId}`)
}, 1000)
this.dialogVisible = false
}
}, 100)
},
// 动态变量获取
getParamOptions() {
getParamsList().then(res => {
this.paramOptions = res.data.list
})
},
// 设置证书模型
setCertBox() {
const certBox = document.getElementById('edit-dom-1')
const [propWidth, propHeight] = this.certBoxEditStyle.tool
certBox.style.height = (propHeight.value / propWidth.value) * certBox.offsetWidth + 'px'
},
// 样式改变
changeStyle(data) {
this.$forceUpdate()
},
// 初始化拖拽
dragInit(id) {
const dom = document.getElementById(id)
this.$nextTick(() => {
drag(dom, document.getElementById('#edit-dom-1'), res => {
dom.style.top = res.top
dom.style.left = res.left
const index = this.certElement.findIndex(item => item.id === id)
this.certElement[index].top = res.top
this.certElement[index].left = res.left
})
})
}
}
}
</script>
<style lang="scss" scoped>
.edit-cert-box {
display: flex;
padding-top: 30px;
}
.tool-left {
min-width: 340px;
margin-right: 20px;
.tool-btn {
display: flex;
justify-content: center;
}
}
.tool-right {
flex: 1;
#edit-dom-1 {
position: relative;
border: 1px solid rgb(227, 227, 227);
overflow: hidden;
.text {
position: absolute;
top: 0;
left: 0;
&.active {
.pop {
&::after {
content: '';
width: 100%;
height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 3px dashed red;
box-sizing: border-box;
}
}
}
.pop {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
}
}
}
.edit-img {
position: absolute;
top: 0;
left: 0;
&.active {
.pop {
&::after {
content: '';
width: 100%;
height: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 3px dashed red;
box-sizing: border-box;
}
}
}
.pop {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
}
</style>
......@@ -2,7 +2,7 @@ import AppLayout from '@/components/layout/Index.vue'
const routes = [
{
path: '/menu',
path: '/template',
component: AppLayout,
children: [
{ path: 'list', component: () => import('./views/List.vue') },
......
......@@ -3,7 +3,7 @@
<app-list v-bind="tableOptions" ref="list">
<div class="line"></div>
<div class="btn-box">
<el-button type="primary" @click="$router.push({ path: '/banner/update' })">新建Banner</el-button>
<el-button type="primary" @click="$router.push({ path: '/template/update' })">新建模板</el-button>
</div>
<template v-slot:filter-time>
<el-date-picker
......@@ -16,17 +16,9 @@
>
</el-date-picker>
</template>
<template v-slot:picture="{ row }">
<div :style="`background-image:url(${row.picture});background-size: cover;width:200px;height:100px;`"></div>
</template>
<template v-slot:release-status="{ row }">
<el-switch v-model="row.status" @change="updateStatus(row)"> </el-switch>
</template>
<template v-slot:sort-select="{ row }">
<el-select v-model="row.sort" placeholder="请选择" @change="updateStatus(row)">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</template>
<template v-slot:table-x="{ row }">
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
<el-button type="text" @click="handleDelete(row)">删除</el-button>
......@@ -89,6 +81,15 @@ export default {
{ value: '1', label: '已发布' }
]
},
{
type: 'select',
prop: 'project',
label: '项目:',
options: [
{ value: '0', label: '未发布' },
{ value: '1', label: '已发布' }
]
},
{
slots: 'filter-time',
label: '创建时间:'
......@@ -96,15 +97,13 @@ export default {
],
columns: [
{ label: 'id', prop: 'id', align: 'center' },
{ label: '标题', prop: 'title', align: 'center' },
{ label: '图片', slots: 'picture', align: 'center', width: '200px' },
{
label: '发布状态',
slots: 'release-status',
align: 'center'
},
{ label: '模板标题', prop: 'title', align: 'center' },
// {
// label: '是否启用',
// slots: 'release-status',
// align: 'center'
// },
{ label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '排序', slots: 'sort-select', align: 'center' },
{ label: '操作', slots: 'table-x', align: 'center' }
]
}
......@@ -137,7 +136,7 @@ export default {
})
},
handleEdit(row) {
this.$router.push({ path: '/banner/update', query: { id: row.id } })
this.$router.push({ path: '/template/update', query: { id: row.id } })
},
handleDelete(row) {
deleteBanner({ id: row.id }).then(res => {
......
<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 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: 1,
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>
import httpRequest from '@/utils/axios'
/**
* 新建变量
*/
export function createVariable(data) {
return httpRequest.post('/api/cert/v1/backend/param/create', data)
}
/**
* 获取应用列表
*/
export function getAppList(params) {
return httpRequest.get('/api/cert/v1/backend/param/list', { params })
}
/**
* 更新
*/
export function updateVariable(data) {
return httpRequest.post('/api/cert/v1/backend/param/update', data)
}
/**
* 删除页面
*/
export function deleteVariable(data) {
return httpRequest.post('/api/cert/v1/backend/param/delete', data)
}
......@@ -2,7 +2,7 @@ import AppLayout from '@/components/layout/Index.vue'
const routes = [
{
path: '/pages',
path: '/variable',
component: AppLayout,
children: [
{ path: 'list', component: () => import('./views/List.vue') },
......
......@@ -3,7 +3,7 @@
<app-list v-bind="tableOptions" ref="list">
<div class="line"></div>
<div class="btn-box">
<el-button type="primary" @click="$router.push({ path: '/pages/update' })">新建页面</el-button>
<el-button type="primary" @click="$router.push({ path: '/variable/update' })">新建变量</el-button>
</div>
<template v-slot:filter-time>
<el-date-picker
......@@ -16,17 +16,6 @@
>
</el-date-picker>
</template>
<template v-slot:picture="{ row }">
<div :style="`background-image:url(${row.picture});background-size: cover;width:50px;height:40px;`"></div>
</template>
<template v-slot:release-status="{ row }">
<el-switch v-model="row.status" @change="updateStatus(row)"> </el-switch>
</template>
<template v-slot:sort-select="{ row }">
<el-select v-model="row.sort" placeholder="请选择" @change="updateStatus(row)">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</template>
<template v-slot:table-x="{ row }">
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
<el-button type="text" @click="handleDelete(row)">删除</el-button>
......@@ -37,7 +26,7 @@
<script>
// 接口
import { getAppList, updatePages, deletePages } from '../api'
import { getAppList, deleteVariable } from '../api'
export default {
data() {
......@@ -61,33 +50,16 @@ export default {
remote: {
httpRequest: getAppList,
params: {
title: '',
status: '',
key: '',
created_time_start: this.createdStart,
created_time_end: this.createdEnd
},
callback: res => {
res.map(item => {
item.status = !!parseInt(item.status)
return item
})
return res
}
},
filters: [
{
type: 'input',
prop: 'title',
label: '标题:'
},
{
type: 'select',
prop: 'status',
label: '发布状态:',
options: [
{ value: '0', label: '未发布' },
{ value: '1', label: '已发布' }
]
prop: 'key',
label: '变量名称:'
},
{
slots: 'filter-time',
......@@ -96,16 +68,8 @@ export default {
],
columns: [
{ label: 'id', prop: 'id', align: 'center' },
{ label: '页面类型', prop: 'type_name', align: 'center' },
{ label: '页面模板', prop: 'layout_name', align: 'center' },
{ label: '标题', prop: 'title', align: 'center' },
{
label: '发布状态',
slots: 'release-status',
align: 'center'
},
{ label: '变量名称', prop: 'key', align: 'center' },
{ label: '创建时间', prop: 'created_time', align: 'center' },
{ label: '排序', slots: 'sort-select', align: 'center' },
{ label: '操作', slots: 'table-x', align: 'center' }
]
}
......@@ -120,28 +84,15 @@ export default {
} else {
this.createdStart = ''
this.createdEnd = ''
// this.$refs.list.refetch(true)
}
},
// 更新发布状态
updateStatus(row) {
const params = row
params.status = row.status ? '1' : '0'
updatePages(row).then(res => {
if (res.code === 0) {
this.$message({
message: '修改成功',
type: 'success'
})
this.$refs.list.refetch(true)
}
})
},
// 编辑
handleEdit(row) {
this.$router.push({ path: '/pages/update', query: { id: row.id } })
this.$router.push({ path: '/variable/update', query: { id: row.id, key: row.key, value: row.value } })
},
// 删除
handleDelete(row) {
deletePages({ id: row.id }).then(res => {
deleteVariable({ id: row.id }).then(res => {
if (res.code === 0) {
this.$message({
message: '删除成功',
......
......@@ -8,26 +8,18 @@
class="demo-ruleForm"
style="width: 50%; margin: 0 auto"
>
<el-form-item label="页面类型">
<el-radio-group v-model="ruleForm.type">
<el-radio label="1">首页展示区</el-radio>
<el-radio label="2">二级列表页</el-radio>
</el-radio-group>
<el-form-item label="变量名称:">
<el-input v-model="ruleForm.key"></el-input>
</el-form-item>
<el-form-item label="页面模板">
<el-radio-group v-model="ruleForm.layout">
<el-radio label="1">左图又文字</el-radio>
<el-radio label="2">上图下文</el-radio>
<el-radio label="3">文本</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="页面名称" prop="title">
<el-input v-model="ruleForm.title"></el-input>
<el-form-item label="变量字段:">
<el-select v-model="ruleForm.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>
<el-form-item>
<div style="padding-top: 20px">
<el-button type="primary" @click="submitForm">确认</el-button>
<el-button @click="drawer = true">取消</el-button>
<el-button @click="$router.go(-1)">取消</el-button>
</div>
</el-form-item>
</el-form>
......@@ -36,15 +28,29 @@
</template>
<script>
import { createPages, getDetails, updatePages } from '../api'
import { createVariable, updateVariable } from '../api'
export default {
data() {
return {
ruleForm: {
type: '1',
layout: '1',
title: ''
}
key: '',
value: ''
},
options: [
{ 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: {
......@@ -56,7 +62,7 @@ export default {
// 提交
submitForm() {
if (this.id) {
updatePages(this.ruleForm).then(res => {
updateVariable(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '编辑成功',
......@@ -66,7 +72,7 @@ export default {
}
})
} else {
createPages(this.ruleForm).then(res => {
createVariable(this.ruleForm).then(res => {
if (res.code === 0) {
this.$message({
message: '提交成功',
......@@ -76,18 +82,15 @@ export default {
}
})
}
},
// 获取详情
getDetails() {
getDetails({ id: this.id }).then(res => {
this.status = !!parseInt(res.data.status)
this.ruleForm = res.data
})
}
},
mounted() {
if (this.id) {
this.getDetails()
this.ruleForm = {
id: this.id,
key: this.$route.query.key,
value: this.$route.query.value
}
}
}
}
......
......@@ -3,7 +3,7 @@ import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [{ path: '*', redirect: '/banner/list' }]
const routes = [{ path: '*', redirect: '/template/list' }]
const router = new VueRouter({
mode: 'history',
......
import { uploadFile, getSignature } from '@/api/base'
import md5 from 'blueimp-md5'
export function uploadBlob(blob) {
const fileName = `${Math.random().toString(36).slice(-8)}.png`
let fileUrl = ''
const key = 'upload/certificate/' + md5(fileName + new Date().getTime()) + fileName.substr(fileName.lastIndexOf('.'))
return new Promise((resolve, reject) => {
getSignature().then(response => {
const { accessid, policy, signature, host } = response
const data = { key, OSSAccessKeyId: accessid, policy, signature, success_action_status: '200', file: blob }
fileUrl = `${host}/${key}`
uploadFile(data).then(res => {
resolve(fileUrl)
})
})
})
}
export default function dragFun(dragBox, binding, call) {
dragBox.onmousedown = eDown => {
// 算出鼠标相对元素的位置
const disX = eDown.clientX - dragBox.offsetLeft
const disY = eDown.clientY - dragBox.offsetTop
let getPosition = {}
let isMove = false
document.onmousemove = e => {
// 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
const left = e.clientX - disX
const top = e.clientY - disY
// console.log(dragBox, '12312312')
// const right = binding.clientWidth - dragBox.clientWidth
// const bottom = binding.clientHeight - dragBox.clientHeight
// if (left < 0 || top < 0 || right < left || bottom < top) {
// return
// }
dragBox.style.left = left + 'px'
dragBox.style.top = top + 'px'
getPosition = {
top: top,
left: left
}
isMove = true
}
document.onmouseup = () => {
// 鼠标弹起来的时候不再移动
document.onmousemove = null
// 预防鼠标弹起来后还会循环(即预防鼠标放上去的时候还会移动)
document.onmouseup = null
if (isMove) {
isMove = false
call(getPosition)
}
}
}
}
......@@ -14,11 +14,11 @@ export default defineConfig({
cert: fs.readFileSync(path.join(__dirname, './https/dev.ezijing.com.pem'))
},
proxy: {
'/api/road': {
target: 'https://project-road-backend-api.ezijing.com',
'/api/cert': {
target: 'https://cert-backend-api.ezijing.com',
// target: 'http://localhost-activity-backend.ezijing.com',
changeOrigin: true,
rewrite: path => path.replace(/^\/api\/road/, '')
rewrite: path => path.replace(/^\/api\/cert/, '')
},
'/api': 'https://project-api.ezijing.com'
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论