This commit is contained in:
liuye
2022-06-28 09:15:35 +08:00
14 changed files with 91 additions and 3454 deletions

View File

@@ -1,54 +0,0 @@
<template>
<section class="AppMassNotification">
<keep-alive :include="['List']">
<component ref="component" :is="component" :instance="instance" :params="params" :dict="dict" @change="onChange"/>
</keep-alive>
</section>
</template>
<script>
import List from "./components/List.vue";
import Add from "./components/Add.vue";
export default {
name: "AppMassNotification",
label: "群发通知",
props: {
instance: Function,
dict: Object,
},
components: {Add, List},
data() {
return {
component: "List",
params: {},
include: [],
}
},
methods: {
onChange(data) {
if (data.type === "Add") {
this.component = "Add";
this.params = data.params;
}
if (data.type === "List") {
this.component = "List";
this.params = data.params;
this.$nextTick(() => {
if (data.isRefresh) {
this.$refs.component.getTableData();
}
});
}
},
},
}
</script>
<style lang="scss" scoped>
.AppMassNotification {
height: 100%;
}
</style>

View File

@@ -1,425 +0,0 @@
<template>
<section class="Add">
<ai-detail v-if="!params.id">
<template slot="title">
<ai-title title="群发通知" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title>
</template>
<template slot="content">
<ai-card>
<template #title>
<div class="ai-card__title">
<h2>条件选择</h2>
</div>
</template>
<template #content>
<el-form class="ai-form" :rules="rules" ref="form" :model="form" label-width="100px" label-position="right">
<el-form-item label="地区选择" style="width: 100%">
<ai-area-get v-model="areaId" :root="areaRootId" :instance="instance" @select="handleAreaSelect" multiple size="small" placeholder="全部地区"/>
</el-form-item>
<!-- <el-form-item label="用户选择" prop="name" style="width: 100%">
<el-input size="small" v-model="form.name" placeholder="请选择" disabled>
<ai-wechat-selecter slot="append" :isMultiple="false" refs="addTags" :instance="instance" v-model="users" @change="getSelectPerson">
<el-button size="small" type="info">选择成员</el-button>
</ai-wechat-selecter>
</el-input>
</el-form-item> -->
<el-form-item label="标签选择" style="width: 100%">
<div class="tags" v-for="items in subTags" :key="items.id">
<div class="tag_title">{{ items.name }}</div>
<div class="tag_item">
<el-checkbox-group v-model="tags">
<el-checkbox v-for="item in items.tagList" :key="item.id" :label="item.id">{{ item.name }}</el-checkbox>
</el-checkbox-group>
</div>
</div>
</el-form-item>
</el-form>
</template>
</ai-card>
<ai-card title="群发消息设置">
<template #content>
<el-form class="ai-form" ref="form" :rules="rules" :model="form" label-width="110px" label-position="right">
<el-form-item class="el-form-item__textarea" label="群发内容" prop="content" style="width: 100%">
<el-input type="textarea" placeholder="请输入…" v-model="form.content" maxlength="1000" :rows="5" show-word-limit></el-input>
</el-form-item>
<el-form-item label="群发方式" prop="sendType" style="width: 50%">
<el-radio v-model="form.sendType" label="0">立即发送</el-radio>
<el-radio v-model="form.sendType" label="1">定时发送</el-radio>
</el-form-item>
<el-form-item label="群发时间" prop="sendTime" style="width: 50%" v-if="form.sendType == 1">
<el-date-picker size="small"
v-model="form.sendTime"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
placeholder="选择日期时间">
</el-date-picker>
</el-form-item>
<!-- 图片 -->
<el-form-item label="图片" style="width: 100%">
<ai-uploader :instance="instance" isWechat v-model="imgList" acceptType=".jpg,.png,.jpeg" :limit="1" url="/app/wxcp/upload/uploadFile?type=image"></ai-uploader>
</el-form-item>
<!-- 视频 -->
<el-form-item label="视频" style="width: 100%">
<ai-uploader :instance="instance" fileType="file" isWechat acceptType=".mp4" v-model="videoList" :limit="1" url="/app/wxcp/upload/uploadFile?type=video"></ai-uploader>
</el-form-item>
<!-- 附件 -->
<el-form-item label="附件" style="width: 100%">
<ai-uploader :instance="instance" fileType="file" isWechat v-model="filesList" :limit="1" url="/app/wxcp/upload/uploadFile?type=file"></ai-uploader>
</el-form-item>
</el-form>
</template>
</ai-card>
</template>
<template #footer>
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="confirm">确认发送</el-button>
</template>
</ai-detail>
<ai-detail class="add" v-if="params.id">
<template slot="title">
<ai-title title="群发通知详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title>
</template>
<template slot="content">
<ai-card title="详情">
<template #content>
<ai-wrapper>
<ai-info-item label="创建者" :value="data.userName" isLine></ai-info-item>
<ai-info-item label="发送类型" :value="data.sendType" isLine>{{ data.sendType | format }}</ai-info-item>
<ai-info-item label="发送时间" :value="data.sendTime" isLine v-if="data.sendType == 1"></ai-info-item>
</ai-wrapper>
<ai-wrapper v-for="item in data.fileList" :key="item.id">
<ai-info-item label="群发内容" :value="item.content" isLine v-if="item.contentType == 'text'"></ai-info-item>
</ai-wrapper>
<ai-wrapper v-for="item in data.fileList" :key="item.id">
<ai-info-item label="图片" isLine v-if="item.contentType == 'image'">
<ai-uploader v-model="images" :instance="instance" :limit="1" disabled/>
</ai-info-item>
</ai-wrapper>
<ai-wrapper v-for="item in data.fileList" :key="item.id">
<ai-info-item label="视频" isLine v-if="item.contentType == 'video'">
<video :src="item.accessUrl" style="width: 100%; height:100%; object-fit: fill;" muted controls="controls"></video>
</ai-info-item>
</ai-wrapper>
<ai-wrapper v-for="item in data.fileList" :key="item.id">
<ai-info-item label="附件" isLine v-if="item.contentType == 'file'">
<ai-file-list :fileList="fileDownLoad"></ai-file-list>
</ai-info-item>
</ai-wrapper>
</template>
</ai-card>
</template>
</ai-detail>
</section>
</template>
<script>
import {mapState} from "vuex";
import AiDvWrapper from '../../../../project/dvui/layout/AiDvWrapper/AiDvWrapper.vue';
export default {
components: { AiDvWrapper },
name: 'Add',
props: {
instance: Function,
dict: Object,
params: Object
},
data () {
return {
isShow: false,
data: {},
form: {
areaId: '',
tag: '',
sendType: '0',
sendTime: '',
content: '',
contentType: 'text',
fileList: [
{
accessAppid: "",
accessDesc: "",
accessImgurl: "",
accessTitle: "",
accessUrl: "",
content: "",
contentType: "",
createdA: 0,
mediaId: ""
}
],
},
tags: [],
subTags: {},
areaId: [],
areaName: [],
imgList: [],
videoList: [],
filesList: [],
fileDownLoad: [],
areaRootId: '',
users: [],
images: [],
rules: {
content: [{ required: true, message: '请输入群发内容'}],
sendType: [{ required: true, message: '请选择群发方式' }],
sendTime: [{ required: true, message: '请选择群发时间' }],
},
}
},
computed: {
tagsChange() {
if(this.tags.length) {
return this.form.tag = this.tags.toString();
}
},
areaid() {
return this.form.areaId = this.areaId.toString();
},
...mapState(['user'])
},
created () {
if (this.params.id) {
this.getInfo()
} else {
this.getSubTags()
}
this.areaRootId = [this.user.info.areaId.substr(0, 6),'000000'].join("")
},
filters: {
format(value) {
if(value == 0) {
return '立即发送'
} else if(value == 1) {
return '定时发送'
}
}
},
methods: {
handleAreaSelect(v) {
this.areaName = v?.[0]?.label
},
getSelectPerson(val) {
this.form.name = val[0].name;
this.form.phone = val[0].phone;
this.form.userId = val[0].sysUserId
this.form.wxUserId = val[0].id
},
// 标签
getSubTags () {
this.instance.post(`/app/wxcp/wxcorptag/listAll`).then(res => {
if (res?.data) {
this.subTags = res.data.records
}
})
},
getInfo () {
this.instance.post(`/app/pushmessage/detail?id=${this.params.id}`).then(res => {
if (res?.data) {
this.data = res.data
this.images = [{ url: res.data.fileList.filter(e=> e.contentType == "image")[0]?.accessUrl }]
this.fileDownLoad = [{ url:res.data.fileList.filter(e=> e.contentType == "file")[0]?.accessUrl }]
}
})
},
confirm () {
this.$refs.form.validate((valid) => {
if (valid) {
this.form.fileList = []
let contentList = {
content: this.form.content,
contentType: 'text'
}
this.form.fileList.push(contentList)
if(this.imgList.length) {
let item = {
contentType: 'image',
mediaId: this.imgList[0].media.mediaId,
accessUrl: this.imgList[0].url
}
this.form.fileList.push(item)
}
if(this.videoList.length) {
let item = {
contentType: 'video',
mediaId: this.videoList[0].media.mediaId,
accessUrl: this.videoList[0].url
}
this.form.fileList.push(item)
}
if(this.filesList.length) {
let item = {
contentType: 'file',
mediaId: this.filesList[0].media.mediaId,
accessUrl: this.filesList[0].url
}
this.form.fileList.push(item)
}
this.instance.post(`/app/pushmessage/addOrUpdate`, {
...this.form
}).then(res => {
if (res.code == 0) {
this.$message.success('提交成功')
setTimeout(() => {
this.cancel(true)
}, 600)
}
})
}
})
},
cancel (isRefresh) {
this.$emit('change', {
type: 'List',
isRefresh: isRefresh ? true : false
})
}
}
}
</script>
<style scoped lang="scss">
.Add {
height: 100%;
}
.ai-card__title {
display: flex;
align-items: center;
h2 {
margin-right: 20px;
color: #222222;
font-size: 16px;
font-weight: 700;
}
span {
color: #888888;
font-size: 14px;
}
}
.appletss {
display: flex;
flex-wrap: wrap;
.applets-item {
display: flex;
align-items: center;
width: 400px;
height: 60px;
margin-right: 8px;
margin-bottom: 8px;
padding: 0 17px;
background: #FFFFFF;
border-radius: 2px;
border: 1px solid #D0D4DC;
cursor: pointer;
&:hover {
border-color: #2266FF;
}
::v-deep {
.el-radio__label {
display: none;
}
}
img {
width: 40px;
height: 40px;
margin: 0 8px 0 13px;
}
span {
color: #222222;
font-size: 12px;
}
.el-radio {
margin: 0;
}
&.applets-active {
border-color: #2266FF;
}
}
}
.tips {
position: relative;
top: 2px;
padding-left: 8px;
color: #222222;
font-size: 14px;
}
.el-form-item-item__textarea {
position: relative;
}
.el-form-item__btn {
position: absolute;
bottom: 12px;
left: 12px;
line-height: 1;
z-index: 1;
color: #2266FF;
font-size: 14px;
user-select: none;
background: #fff;
cursor: pointer;
}
.tags {
// padding: 10px;
.tag_title {
font-weight: 600;
}
.tag_item {
margin: 5px 0;
span {
display: inline-block;
// padding: 5px 10px;
width: 80px;
text-align: center;
height: 30px;
line-height: 30px;
background: #DDD;
color: #333;
border-radius: 4px;
margin-right: 8px;
}
.active {
background: #53bcea;
color: #FFFFFF;
}
}
}
</style>

View File

@@ -1,208 +0,0 @@
<template>
<ai-list class="List">
<template #title>
<ai-title title="群发通知" isShowBottomBorder></ai-title>
</template>
<template #content>
<ai-search-bar>
<template #left>
<el-button type="primary" icon="iconfont iconAdd" @click="toAdd('')">添加</el-button>
</template>
</ai-search-bar>
<ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size"
@getList="getTableData" show-overflow-tooltip :col-configs="colConfigs" :dict="dict">
<!-- <el-table-column slot="type" width="240px" label="消息内容" align="center">
<template slot-scope="{ row }">
<el-popover
placement="bottom"
width="400"
:visible-arrow="false"
popper-class="wechat-message__container"
trigger="hover">
<div class="count row-content" slot="reference" v-if="row.content">{{ row.content }}</div>
<div class="message-info">
<h2 :style="{marginBottom: row.accessUrl ? '16px' : '0'}">{{ row.content }}</h2>
<div class="message-info__wrapper" v-if="row.accessUrl">
<img v-if="row.contentType == 'image'" :src="row.accessUrl">
<video style="width:40px; height: 40px;" v-if="row.contentType == 'video'" :src="row.accessUrl"></video>
<img src="../../../../examples/assets/file.png" v-if="row.contentType == 'file'" width="40" height="40"/>
<div class="message-info__wrapper--right">
<h3 v-if="row.contentType === 'image'">{{ row.media.file.name }}</h3>
<h3 v-if="row.contentType === 'video'">{{ row.media.file.name }}</h3>
<p v-if="row.contentType === 'image'">{{ row.media.file.fileSizeStr }}</p>
<p v-if="row.contentType === 'video'">{{ row.media.file.fileSizeStr }}</p>
</div>
</div>
</div>
</el-popover>
</template>
</el-table-column> -->
<el-table-column slot="options" label="操作" align="center">
<template slot-scope="{ row }">
<el-button type="text" @click="toAdd(row.id)">详情</el-button>
<!-- <el-button type="text" @click="handleDelete(row.id)">删除</el-button> -->
</template>
</el-table-column>
</ai-table>
</template>
</ai-list>
</template>
<script>
import { mapState } from 'vuex'
export default {
name: "List",
props: {
dict: Object,
instance: Function,
params: Object,
},
data() {
return {
tableData: [],
page: {current: 1, size: 10, total: 0,pages: 0},
id: '',
}
},
created() {
this.getTableData()
},
computed: {
colConfigs() {
let conType = {
text: "文本",
image: "图片",
video: "视频",
file: "附件"
}
return [
{ prop: "fileList", label: '消息类型', align: "center", width: "250px", formart: v => v?.map(e=> conType[e.contentType]).toString() },
{ prop: "fileList", label: '消息类容', align: "center", width: "250px", formart: v => v?.filter(e=> e.contentType == 'text')[0].content },
// { slot: 'type' },
{ prop: "sendType", label: '发送类型', align: "center", width: "250px", formart: v => v == 0 ? '立即发送' : '定时发送'},
{ prop: "createTime", label: '创建时间', align: "center", width: "250px"},
{ prop: "sendTime", label: '发送时间', align: "center", width: "250px"},
{ prop: "userName", label: '创建人', align: "center", width: "250px", },
{ slot: "options" ,},
]
},
...mapState(['user'])
},
methods: {
getTableData() {
this.instance.post(`/app/pushmessage/list?`, null, {
params: {
...this.page,
}
}).then(res => {
console.log(res);
if (res?.data) {
this.tableData = res.data.records
this.page.total = res.data.total
}
})
},
mapType (type) {
return {
'image': '图片',
'video': '视频',
'file': '文件',
'text': '文本'
}[type]
},
toAdd(id) {
this.$emit('change', {
type: 'Add',
params: {
id: id || '',
},
})
}
},
}
</script>
<style lang="scss" scoped>
.List {
height: 100%;
background: #f3f4f5;
.count {
cursor: pointer;
color: #2266FF;
font-size: 14px;
&:hover {
opacity: 0.6;
}
}
}
img, video {
width: 40px;
height: 40px;
margin-right: 10px;
object-fit: cover;
}
.message-info {
padding: 8px;
min-height: 116px;
h2 {
color: #222222;
font-weight: 500;
font-size: 14px;
}
.message-info__wrapper {
display: flex;
align-items: center;
width: 368px;
height: 60px;
padding: 10px;
background: #FFFFFF;
border-radius: 2px;
border: 1px solid #D0D4DC;
.message-info__wrapper--right {
flex: 1;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
h3 {
width: 100%;
color: #222222;
font-size: 14px;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
font-weight: normal;
}
img, video {
width: 40px;
height: 40px;
margin-right: 10px;
object-fit: cover;
}
p {
margin-top: 6px;
font-size: 14px;
color: #888888;
}
}
}
.row-content {
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
</style>

91
package.json Normal file
View File

@@ -0,0 +1,91 @@
{
"name": "cw-webapps",
"version": "2.0.0",
"private": false,
"author": "kubbo",
"main": "lib/cw-webapps.common.js",
"scripts": {
"dev": "vue-cli-service serve",
"lib": "vue-cli-service build --no-clean --target lib --dest lib packages/index.js&&npm unpublish --force&&npm publish",
"lib:core": "vue-cli-service build --target lib --dest core/dist core/index.js --name dvcp-core&&npm unpublish dvcp-core --force&&npm publish core/",
"lib:project": "node project/build.js",
"lib:all": "node project/allProject.js&&npm unpublish --workspaces --force&&npm publish --workspaces",
"ui": "npm i dvcp-ui@latest"
},
"workspaces": [
"project/*"
],
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@jiaminghi/data-view": "^2.10.0",
"bin-code-editor": "^0.9.0",
"dayjs": "^1.8.35",
"dvcp-ui": "^1.42.2",
"echarts": "^5.1.2",
"mp4box": "^0.4.1",
"print-js": "^1.0.63",
"serialize-javascript": "^6.0.0",
"sortablejs": "^1.12.0",
"vue-draggable-resizable": "^2.3.0",
"vue-json-editor": "^1.4.3",
"vue-okr-tree": "^1.0.10",
"vue-ruler-tool": "^1.2.4",
"vuedraggable": "^2.24.3"
},
"publishConfig": {
"registry": "http://192.168.1.87:4873/"
},
"devDependencies": {
"@babel/plugin-proposal-logical-assignment-operators": "^7.10.4",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
"@babel/plugin-proposal-optional-chaining": "^7.10.4",
"@vue/cli-plugin-babel": "^3.6.0",
"@vue/cli-plugin-eslint": "^3.6.0",
"@vue/cli-service": "^3.6.0",
"axios": "^0.19.2",
"babel-eslint": "^10.1.0",
"core-js": "^2.6.11",
"element-ui": "^2.13.2",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"image-webpack-loader": "^6.0.0",
"inquirer": "^6.5.2",
"node-sass": "npm:sass@^1.43.4",
"readline": "^1.3.0",
"sass-loader": "^7.1.0",
"uglifyjs-webpack-plugin": "^2.2.0",
"v-viewer": "^1.6.4",
"vue": "^2.6.11",
"vue-router": "^3.3.4",
"vue-template-compiler": "^2.6.11",
"vuex": "^3.5.1",
"vuex-persistedstate": "^2.7.1"
},
"vetur": {
"attributes": "./attributes.json"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}

View File

@@ -1,92 +0,0 @@
<template>
<div class="swiper">
<el-carousel height="100%" indicator-position="none">
<el-carousel-item v-for="(item, index) in data" :key="index">
<img :src="item.img">
<div class="swiper-content" v-if="item.title">
<h2>{{ item.title }}</h2>
<p>{{ item.content }}</p>
</div>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
export default {
name: 'AiSwiper',
props: {
data: {
type: Array,
default: () => []
},
width: {
type: String,
default: '100%'
},
heigth: {
type: String,
default: '100%'
}
},
data () {
return {
}
},
mounted () {
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.swiper {
width: 100%;
height: 100%;
padding: 20px 0 0;
::v-deep .el-carousel {
height: 100%;
}
img {
width: 100%;
height: 100%;
}
.swiper-content {
position: absolute;
bottom: 0;
left: 0;
z-index: 1;
width: 100%;
padding: 10px;
text-align: center;
background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, #000000 100%);
h2 {
margin-bottom: 4px;
color: #fff;
text-align: center;
font-size: 18px;
}
p {
line-height: 22px;
white-space: pre-line;
color: #B6DFFF;
font-size: 14px;
text-align: center;
}
}
}
</style>

View File

@@ -1,345 +0,0 @@
<template>
<div class="render-element" style="width: 100%; height: 100%;">
<ai-dv-display v-if="data.type === 'display'" :title="data.title" :list="values"></ai-dv-display>
<ai-dv-panel
style="height: 100%; width: 100%;"
v-if="data.type !== 'display'"
:title="data.title"
:border="data.border || ''">
<AiDvSummary v-if="data.type === 'summary'" :summaryTitle="data.summaryTitle" :key="`summary${index}`" :type="data.display" :data="values"/>
<AiSwiper v-else-if="data.type === 'swiper'" :heigth="'100%'" :data="values"/>
<dv-scroll-board
v-if="data.type === 'table'"
:class="'dvScrollBoard' + theme"
:config="formatTable(values, data.isShowIndex, data.rowNum)"
:key="data.height"
:theme="theme"
:style="{height: data.height + 'px', width: '100%'}"/>
<ai-echart
v-else-if="data.type === 'barChart1'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="data.config"/>
<ai-echart
v-else-if="data.type === 'barChart2'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:theme="theme"
:key="`chart${index}`"
:data="values"
:ops="data.config"/>
<ai-echart
v-else-if="data.type === 'barChart3'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="data.config"/>
<ai-echart
v-else-if="data.type === 'barChart5'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="data.config"/>
<ai-echart
v-else-if="data.type === 'barChart7'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="data.config"/>
<ai-echart
v-else-if="data.type === 'barChart8'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="data.config"/>
<ai-echart
v-else-if="data.type === 'barChart9'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="data.config"/>
<ai-echart
v-else-if="data.type === 'lineChart1'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="lineChart1"/>
<ai-echart
v-else-if="data.type === 'lineChart2'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="lineChart2"/>
<ai-echart
v-else-if="data.type === 'lineChart3'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="data.config"/>
<ai-echart
v-else-if="data.type === 'lineChart4'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="data.config"/>
<ai-echart
v-else-if="data.type === 'lineChart5'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="lineChart5"/>
<ai-echart
v-else-if="data.type === 'pieChart'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="pieChart"/>
<ai-echart
v-else-if="data.type === 'pieChart1'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="pieChart1"/>
<ai-echart
v-else-if="data.type === 'pieChart3'"
style="height: 100%; width: 100%;"
:ref="'chart' + index"
:key="`chart${index}`"
:theme="theme"
:data="values"
:ops="pieChart3"/>
<ai-map :markers="values" v-else-if="data.type=='map'" :mask="data.mask === '1'" :areaId="data.areaId || user.info.areaId"
:map-style="`amap://styles/${data.mapStyle}`" :pulseLines="data.pulseLines==1" :map.sync="map" :lib.sync="lib"/>
<ai-monitor :src="data.src" v-else-if="data.type === 'monitor'" :type="data.monitorType"></ai-monitor>
<video style="width: 100%; height: 100%; object-fit: fill;" loop :src="data.src" autoplay v-else-if="data.type === 'video'"></video>
<AiDvPartyOrg style="width: 100%; height: 100%;" v-else-if="data.type === 'partyOrg'" :instance="instance"></AiDvPartyOrg>
</ai-dv-panel>
</div>
</template>
<script>
import {mapState} from 'vuex'
import AiSwiper from './AiSwiper.vue'
import pieChart from 'dvcp-dv-ui/components/AiEchart/template/pie/pieChart2'
import pieChart1 from 'dvcp-dv-ui/components/AiEchart/template/pie/pieChart1'
import pieChart3 from 'dvcp-dv-ui/components/AiEchart/template/pie/pieChart3'
import lineChart1 from 'dvcp-dv-ui/components/AiEchart/template/line/lineChart1'
import lineChart2 from 'dvcp-dv-ui/components/AiEchart/template/line/lineChart2'
import lineChart5 from 'dvcp-dv-ui/components/AiEchart/template/line/lineChart5'
export default {
name: 'RenderElement',
props: ['data', 'index', 'theme', 'instance'],
components: {
AiSwiper
},
data() {
return {
lineChart1,
lineChart2,
lineChart5,
pieChart,
pieChart1,
pieChart3,
map: null,
lib: null
}
},
computed: {
...mapState(['user']),
values() {
return this.data?.[this.data.dataType]?.map(e => {
return {...e, lng: e['经度'], lat: e['纬度'], label: e['地区名称']}
}) || []
}
},
methods: {
formatTable(data, isShowIndex, rowNum) {
if (!data.length) {
return {
header: [],
data: []
}
}
let rows = []
const header = data.map(v => {
return v[Object.keys(v)[0]]
})
Object.keys(data[0]).forEach((item, index) => {
if (index !== 0) {
rows.push(item)
}
})
return {
header: header,
data: rows.map(item => {
return data.map(v => {
return v[item]
})
}),
headerBGC: 'transparent',
evenRowBGC: 'transparent',
oddRowBGC: 'rgba(0, 133, 255, 0.2)',
headerHeight: 42,
rowNum: rowNum || 7,
index: isShowIndex === '1',
waitTime: 8000,
carousel: 'page',
indexHeader: '排名',
align: ['center', 'center', 'center', 'center', 'center']
}
},
handleMapClick(count = 0) {
let {lib: AMap, map} = this
if (AMap) {
let infoWin = new AMap.InfoWindow({content: ""})
map.clearMap()
let markers = this.values.filter(e=>e.lng).map(e => {
return new AMap.Marker({
map,
label: e.label,
icon: e.icon,
position: [e.lng, e.lat]
}).on('click', ({target}) => {
map.clearInfoWindow()
markers?.map(m => m.getIcon() == e.selectedIcon && m.setIcon(e.icon))
target.setIcon(e.selectedIcon)
infoWin.setContent([
`<div class="infoWin">`,
`<b>${e.label}</b>`,
`<div>累计成交金额:${e['累计成交金额(万)']}万元</div>`,
`<div>金融产品:${e['金融产品(万)']}万元</div>`,
`<div>融资需求:${e['融资需求(万)']}万元</div>`,
'</div>'
].join(''))
infoWin.open(map, [e.lng, e.lat])
})
})
map.setFitView(markers)
} else if (count < 10) {
console.log("正在加载...%s", count)
setTimeout(() => this.handleMapClick(++count), 1000)
}
}
},
mounted() {
if (this.data.type == 'map') {
this.handleMapClick()
}
}
}
</script>
<style lang="scss" scoped>
.render-element {
::v-deep .dvScrollBoard1 {
.header {
background: rgba(0, 0, 0, 0.1) !important;
.header-item {
color: #FFBB73 !important;
font-size: 16px !important;
font-weight: 600;
}
}
.rows {
font-size: 16px;
font-weight: 600;
color: #FFFFFF;
line-height: 21px;
text-shadow: 0px 2px 4px rgba(117, 9, 9, 0.5);
background: linear-gradient(180deg, #FFF6C7 0%, #FF9A02 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
& > div:nth-of-type(2n - 1) {
background-color: transparent !important;
}
& > div:nth-of-type(2n) {
background-color: rgba(0, 0, 0, 0.1) !important;
}
.index {
color: #fff;
text-shadow: none;
background: #BD4921 !important;
-webkit-background-clip: inherit;
-webkit-text-fill-color: #fff;
}
}
}
::v-deep.amap-info-contentContainer {
.amap-info-content {
background: #0A3257;
border: 1px solid #7BE5FF;
padding: 16px;
font-family: PingFangSC-Semibold, PingFang SC;
.infoWin {
& > b {
display: block;
font-size: 18px;
font-weight: 600;
color: #FFFFFF;
margin-bottom: 13px;
}
& > div {
font-size: 16px;
font-weight: 400;
color: #7BE5FF;
& + div {
margin-top: 8px;
}
}
}
}
.amap-info-sharp {
border-top-color: #0A3257;
&:after {
border-top-color: #7BE5FF;
filter: none;
}
}
}
}
</style>

View File

@@ -1,88 +0,0 @@
<template>
<section class="AiDataPanel">
<b class="item-title" v-text="label"/>
<div class="num-bg">
<span ref="num" class="num" v-text="num"/>
</div>
</section>
</template>
<script>
import {gsap} from 'gsap'
export default {
name: "AiDataPanel",
props: {
label: {default: "标题"},
value: {default: 0}
},
data() {
return {
num: 0
}
},
methods: {
animation() {
let demo = {num: Math.max(this.value - 30, 0)}
gsap.to(demo, 1, {
num: this.value, onUpdate: () => {
this.num = demo.num?.toFixed(0)
}
})
}
},
mounted() {
this.animation()
}
}
</script>
<style lang="scss" scoped>
.AiDataPanel {
flex: 1;
width: 172px;
height: 160px;
display: flex;
flex-direction: column;
align-items: center;
background: #000;
& + .AiDataPanel {
margin-left: 16px;
}
.item-title {
font-size: 24px;
line-height: 32px;
background-image: -webkit-linear-gradient(bottom, #35BEFF, #EBF9FF, #FFFFFF);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-top: 30px;
}
.num-bg {
width: 100%;
height: 160px;
background-image: url(https://cdn.cunwuyun.cn/dvcp/dv/dianjiang/number-bg.png);
background-size: 100% 100%;
position: relative;
margin-top: -76px;
.num {
position: absolute;
left: 0;
bottom: 30px;
width: 100%;
text-align: center;
height: 50px;
font-size: 40px;
font-family: D-DIN-Bold, D-DIN;
font-weight: bold;
line-height: 54px;
background-image: -webkit-linear-gradient(bottom, #35BEFF, #EBF9FF, #FFFFFF);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
}
</style>

View File

@@ -1,30 +0,0 @@
<template>
<section class="AiStaData">
<ai-data-panel v-for="op in data" :key="op[key]"
:label="op[label]" :value="op[key]"/>
</section>
</template>
<script>
import AiDataPanel from "./AiDataPanel";
export default {
name: "AiStaData",
components: {AiDataPanel},
props: {
data: {default: () => []},
key: {default: "id"},
label: {default: "label"},
}
}
</script>
<style lang="scss" scoped>
.AiStaData {
width: 100%;
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;
}
</style>

View File

@@ -1,66 +0,0 @@
<template>
<div class="doc-circulation">
<keep-alive :include="['List']">
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
</keep-alive>
</div>
</template>
<script>
import List from './components/List'
import Add from './components/Add'
export default {
name: 'AppForm',
label: '配置表单',
props: {
instance: Function,
dict: Object
},
data () {
return {
component: 'List',
params: {},
include: []
}
},
components: {
Add,
List
},
mounted () {
},
methods: {
onChange (data) {
if (data.type === 'Add') {
this.component = 'Add'
this.params = data.params
}
if (data.type === 'list') {
this.component = 'List'
this.params = data.params
this.$nextTick(() => {
if (data.isRefresh) {
this.$refs.component.getList()
}
})
}
}
}
}
</script>
<style lang="scss">
.doc-circulation {
height: 100%;
background: #F3F6F9;
overflow: auto;
}
</style>

View File

@@ -1,281 +0,0 @@
<template>
<ai-detail class="form-add" :class="[currIndex === 1 ? 'form-add__active' : '']">
<ai-title title="表单配置" slot="title" isShowBottomBorder isShowBack @onBackClick="cancel(false)"></ai-title>
<template #content>
<div class="ai-step">
<div class="ai-step__item"
:class="[currIndex >= index ? 'ai-step__item--active' : '']"
v-for="(item, index) in statusList"
:key="index">
<div class="ai-step__item--icon" v-if="currIndex <= index">
<i v-if="currIndex === index"></i>
</div>
<div class="el-icon-success" v-if="currIndex > index">
</div>
<span>{{ item }}</span>
</div>
</div>
<basic-info ref="basicInfo" v-model="basicInfo" v-show="currIndex === 0" :dict="dict" :instance="instance"></basic-info>
<form-layout :appType="basicInfo.appType" :currIndex="currIndex" class="form-config__wrapper" v-model="tableInfos" ref="form" v-show="currIndex === 1" :dict="dict" :instance="instance"></form-layout>
<form-config
ref="config"
:showListFields="showListFields"
:btns="btns"
:fuzzyQueryFields="fuzzyQueryFields"
:tableInfos="tableInfos"
:orderFields="orderFields"
v-if="currIndex === 2">
</form-config>
</template>
<template #footer>
<el-button @click="cancel">取消</el-button>
<el-button @click="back" v-if="currIndex > 0">上一步</el-button>
<el-button @click="next" type="primary">{{ currIndex === 2 ? '完成' : '下一步' }}</el-button>
</template>
</ai-detail>
</template>
<script>
import BasicInfo from './BasicInfo.vue'
import FormLayout from './FormLayout.vue'
import FormConfig from './FormConfig.vue'
export default {
name: 'add',
props: {
instance: Function,
dict: Object,
params: Object,
type: String
},
components: {
FormLayout,
BasicInfo,
FormConfig
},
data () {
return {
currIndex: 0,
basicInfo: {
saasPlatformId: '',
menuLeve1Style: '',
saasPlatformName: '',
menuLevel1Name: '',
menuLevel3Name: '',
menuLevel2Name: '',
appType: ''
},
orderFields: [],
showListFields: [],
fuzzyQueryFields: [],
btns: [],
btnKeys: ['insertEnable', 'importEnable', 'exportEnalbe', 'editEnable', 'deleteEnable', 'batchDelEnable'],
configInfo: {
btns: [],
orderType: '0',
fieldName: ''
},
info: {},
tableInfos: [],
statusList: ['基础设置', '表单设计', '列表设计']
}
},
mounted () {
if (this.params.id) {
this.getInfo()
}
},
methods: {
cancel (isRefresh) {
this.$emit('change', {
type: 'list',
isRefresh: isRefresh ? true : false,
isQuote: this.params.isQuote ? true : false
})
},
confirm () {
},
back () {
this.currIndex = this.currIndex - 1
},
confirmBasicInfo () {
return this.$refs.basicInfo.validate()
},
getInfo () {
this.instance.post(`/app/appapplicationinfo/queryDetailById?id=${this.params.id}`).then(res => {
if (res.code === 0) {
this.info = res.data
this.basicInfo = {
saasPlatformId: res.data.saasPlatformId,
menuLeve1Style: res.data.menuLeve1Style,
saasPlatformName: res.data.saasPlatformName,
menuLevel1Name: res.data.menuLevel1Name,
menuLevel3Name: res.data.menuLevel3Name,
menuLevel2Name: res.data.menuLevel2Name,
appType: res.data.appType,
corpId: res.data.corpId,
corpName: res.data.corpName
}
this.fuzzyQueryFields = res.data.fuzzyQueryFields
this.tableInfos = res.data.tableInfos
this.showListFields = res.data.showListFields
this.orderFields = res.data.orderFields
this.btns = Object.keys(res.data).filter(v => {
return this.btnKeys.indexOf(v) > -1 && res.data[v] === '1'
})
}
})
},
submit (info) {
this.instance.post(`/app/appapplicationinfo/addOrUpdate`, {
...this.info,
...this.basicInfo,
tableInfos: this.tableInfos,
...info.btns,
id: this.params.id,
applicationName: this.basicInfo.menuLevel3Name || this.basicInfo.menuLevel2Name,
fuzzyQueryFields: info.fuzzyQueryFields,
orderType: info.orderType,
orderFields: info.orderFields,
showListFields: info.showListFields
}).then(res => {
if (res.code === 0) {
this.$message.success(this.params.id ? '编辑成功' : '添加成功')
this.cancel(true)
}
})
},
next () {
if (this.currIndex === 0) {
if (!this.$refs.basicInfo.validate()) return
}
if (this.currIndex === 1) {
this.$refs.form.onConfirm()
}
if (this.currIndex === 2) {
const info = this.$refs.config.validate()
if (!info) return
this.submit(info)
return false
}
this.currIndex = this.currIndex + 1
}
}
}
</script>
<style lang="scss" scoped>
.form-add {
&.form-add__active {
::v-deep .ai-detail__content--wrapper {
max-width: 100%!important;
height: 100%!important;
background: #F5F6F9;
}
.form-config__wrapper {
height: calc(100% - 52px);
overflow-y: hidden;
}
::v-deep .ai-detail__content {
height: calc(100% - 114px)!important;
padding: 0!important;
overflow: hidden!important;
}
}
.ai-step {
display: flex;
align-items: center;
justify-content: center;
margin-top: 4px;
margin-bottom: 24px;
.ai-step__item {
display: flex;
position: relative;
align-items: center;
margin-right: 216px;
&.ai-step__item--active {
span {
color: #2266FF;
}
.ai-step__item--icon {
display: flex;
align-items: center;
justify-content: center;
border-color: #2266FF;
i {
width: 12px;
height: 12px;
border-radius: 50%;
background: #2266FF;
}
}
}
&:after {
position: absolute;
top: 50%;
right: -208px;
width: 200px;
height: 2px;
background: #D0D4DC;
content: ' ';
transform: translateY(-50%);
}
&:last-child {
margin-right: 0;
&::after {
display: none;
}
}
.ai-step__item--icon {
width: 24px;
height: 24px;
margin-right: 8px;
border-radius: 50%;
background: #FFFFFF;
border: 2px solid #D0D4DC;
}
.el-icon-success {
width: 24px;
height: 24px;
font-size: 24px;
margin-right: 8px;
color: #2266FF;
border-radius: 50%;
}
span {
color: #666666;
font-size: 14px;
}
}
}
}
</style>

View File

@@ -1,151 +0,0 @@
<template>
<div class="basicInfo">
<el-form ref="form" :model="form" label-width="110px" label-position="right">
<ai-card title="基本信息">
<template #content>
<div class="ai-form">
<el-form-item label="所属平台" prop="saasPlatformId" style="width: 100%;" :rules="[{ required: true, message: '请选择所属平台', trigger: 'change' }]">
<el-select
size="small"
style="width: 100%;"
placeholder="请选择所属平台"
clearable
@change="onChange"
v-model="form.saasPlatformId">
<el-option
v-for="(item, index) in sassList"
:key="index"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form.saasPlatformId" style="width: 100%;" label="所属企业" prop="corpId" :rules="[{ required: true, message: '请选择所属企业', trigger: 'change' }]">
<ai-select
v-model="form.corpId"
placeholder="请选择所属企业"
clearable
@change="onCompanyChange"
:selectList="companyList">
</ai-select>
</el-form-item>
<el-form-item style="width: 100%;" label="一级菜单名称" prop="menuLevel1Name" :rules="[{ required: true, message: '请输入一级菜单名称', trigger: 'change' }]">
<el-input size="small" placeholder="请输入一级菜单名称" :maxlength="8" v-model="form.menuLevel1Name"></el-input>
</el-form-item>
<el-form-item style="width: 100%;" label="二级菜单名称" prop="menuLevel2Name" :rules="[{ required: true, message: '请输入二级菜单名称', trigger: 'change' }]">
<el-input size="small" placeholder="请输入二级菜单名称" :maxlength="8" v-model="form.menuLevel2Name"></el-input>
</el-form-item>
<el-form-item style="width: 100%;" label="三级菜单名称" prop="menuLevel3Name">
<el-input size="small" placeholder="请输入三级菜单名称" :maxlength="8" v-model="form.menuLevel3Name"></el-input>
</el-form-item>
<el-form-item style="width: 100%;" label="应用类型" prop="appType">
<ai-select
v-model="form.appType"
placeholder="请选择应用类型"
clearable
:selectList="dict.getDict('diyAppType')">
</ai-select>
</el-form-item>
</div>
</template>
</ai-card>
</el-form>
</div>
</template>
<script>
export default {
name: 'basicInfo',
model: {
prop: 'value',
event: 'change',
},
props: {
instance: Function,
dict: Object,
value: Object
},
data () {
return {
form: {
saasPlatformId: '',
menuLeve1Style: '',
saasPlatformName: '',
menuLevel1Name: '',
menuLevel2Name: '',
menuLevel3Name: '',
appType: '',
corpId: '',
corpName: ''
},
companyList: [],
sassList: []
}
},
watch: {
value (v) {
this.form = JSON.parse(JSON.stringify(v))
if (this.form.saasPlatformId) {
this.getCompanyList()
}
}
},
created () {
this.dict.load('diyAppType')
},
mounted () {
this.getSassList()
this.form = JSON.parse(JSON.stringify(this.value))
},
methods: {
onChange (e) {
this.form.saasPlatformName = this.sassList.filter(v => v.id === e)[0].name
this.form.saasPlatformId && this.getCompanyList()
},
validate () {
let result = false
this.$refs.form.validate(valid => {
result = valid
})
this.$emit('change', this.form)
return result
},
onCompanyChange (e) {
this.form.corpName = this.companyList.filter(v => v.dictValue === e)[0].dictName
},
getCompanyList () {
this.instance.post(`/app/appCorp/page?current=1&size=1000&saasId=${this.form.saasPlatformId}`).then(res => {
if (res.data.records.length) {
this.companyList = res.data.records.map(v => {
return {
dictValue: v.corpId,
dictName: v.name
}
})
}
})
},
getSassList () {
this.instance.post(`/app/appSaas/listAll`).then(res => {
if (res.data) {
this.sassList = res.data
}
})
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@@ -1,244 +0,0 @@
<template>
<div class="basicInfo">
<ai-card title="搜索字段" class="search-wrapper">
<template #content>
<el-checkbox-group v-model="queryFields">
<el-checkbox
:label="`${item.fieldDbName}~${item.fieldName}`"
v-for="(item, index) in tableInfos"
:key="index">
{{ item.fieldName }}
</el-checkbox>
</el-checkbox-group>
</template>
</ai-card>
<ai-card title="表格字段">
<template #content>
<div class="ai-table">
<div class="el-table el-table--border ai-header__border">
<el-scrollbar>
<table cellspacing="0" cellpadding="0" border="0" class="el-table__body">
<draggable element="thead" animation="500" class="el-table__header is-leaf ai-table__header" :sort="true" v-model="showFields">
<th v-for="(item, index) in showFields" style="background: #f3f4f5; text-align: center;" class="ai-table__header" :key="index">{{ item.fieldName }}</th>
</draggable>
<tbody element="tbody">
<tr>
<td @click="handleShow(index, item.isShow)" v-for="(item, index) in showFields" :key="index">{{ item.isShow ? '已显示' : '已隐藏' }}</td>
</tr>
</tbody>
</table>
</el-scrollbar>
</div>
</div>
</template>
</ai-card>
<ai-card title="排序和操作按钮">
<template #content>
<el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right">
<el-form-item label="排序字段" prop="field">
<el-select
size="small"
placeholder="默认按创建时间排序"
clearable
v-model="form.field">
<el-option
v-for="(filed, index) in tableInfos"
:key="index"
:label="filed.fieldName"
:value="`${filed.fieldDbName}~${filed.fieldName}`">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="排序类型" prop="orderType" :rules="[{ required: true, message: '请输入排序类型', trigger: 'change' }]">
<el-radio-group v-model="form.orderType">
<el-radio label="asc">升序</el-radio>
<el-radio label="desc">降序</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="按钮配置" prop="btns" style="width: 100%;" :rules="[{ required: true, message: '请输入按钮配置', trigger: 'change' }]">
<el-checkbox-group v-model="form.btns">
<el-checkbox label="insertEnable">添加</el-checkbox>
<el-checkbox label="importEnable">导入</el-checkbox>
<el-checkbox label="exportEnalbe">导出</el-checkbox>
<el-checkbox label="editEnable">编辑</el-checkbox>
<el-checkbox label="deleteEnable">删除</el-checkbox>
<el-checkbox label="batchDelEnable">批量删除</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
</template>
</ai-card>
</div>
</template>
<script>
import draggable from 'vuedraggable'
export default {
name: 'configForm',
props: {
tableInfos: Array,
btns: Array,
showListFields: Array,
orderFields: Array,
fuzzyQueryFields: Array
},
components: {
draggable
},
data () {
return {
queryFields: [],
tableData: [{}],
btnKeys: ['insertEnable', 'importEnable', 'exportEnalbe', 'editEnable', 'deleteEnable', 'batchDelEnable'],
form: {
btns: [],
orderType: 'asc',
field: ''
},
showFields: []
}
},
mounted () {
const showIds = this.showListFields.map(v => v.fieldDbName)
this.showFields = JSON.parse(JSON.stringify(this.tableInfos)).map(item => {
item.isShow = showIds.indexOf(item.fieldDbName) > -1 ? true : false
return item
})
if (!this.showListFields.length) {
this.showFields.map(v => {
v.isShow = true
return v
})
}
this.tableInfos.map(item => {
this.tableData[0][item.fieldDbName] = '删除'
})
if (this.btns.length) {
this.form.btns = this.btns
}
const tableInfosIds = this.tableInfos.map(v => v.fieldDbName)
if (this.orderFields.length) {
let arr = this.orderFields.filter(v => {
return tableInfosIds.indexOf(v.fieldDbName) > -1
}).map(item => {
return `${item.fieldDbName}~${item.fieldName}`
})
if (arr.length) {
this.form.field = arr[0]
}
}
if (this.fuzzyQueryFields.length) {
this.queryFields = this.fuzzyQueryFields.filter(v => {
return tableInfosIds.indexOf(v.fieldDbName) > -1
}).map(item => {
return `${item.fieldDbName}~${item.fieldName}`
})
}
},
methods: {
validate () {
let result = false
this.$refs.form.validate(valid => {
result = valid
})
if (!result) {
return false
}
const btns = {}
this.btnKeys.forEach(item => {
btns[item] = this.form.btns.indexOf(item) > -1 ? 1 : 0
})
return {
btns,
orderFields: [{
fieldName: this.form.field.split('~')[1],
fieldDbName: this.form.field.split('~')[0],
orderType: this.form.orderType
}],
showListFields: this.showFields.filter(v => v.isShow).map((v, index) => {
return {
fieldName: v.fieldName,
fieldDbName: v.fieldDbName,
showListIndex: index
}
}),
fuzzyQueryFields: this.queryFields.map(v => {
return {
fieldName: v.split('~')[1],
fieldDbName: v.split('~')[0]
}
})
}
},
handleShow (index, isShow) {
const total = this.showFields.map(v => v.isShow).filter(v => !!v)
if (total.length <= 1 && isShow) {
return this.$message.error('表格列数不能小于1')
}
this.$set(this.showFields[index], 'isShow', !isShow)
}
}
}
</script>
<style scoped lang="scss">
.basicInfo {
.search-wrapper {
::v-deep .el-checkbox-group {
display: flex;
flex-wrap: wrap;
.el-checkbox {
width: 16.66%;
margin-bottom: 10px;
}
}
}
}
.ai-table {
.el-table--border {
border: 1px solid #d0d4dc;
border-bottom: none;
border-right: none;
}
table {
min-width: 100%;
}
th, tr {
min-width: 100px;
cursor: move;
}
tr {
td {
cursor: pointer;
color: #26f;
text-align: center;
user-select: none;
&:hover {
opacity: 0.7;
}
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,272 +0,0 @@
export const components = [
{
type: 'info',
tips: '(不能重复添加同一元素)',
label: '信息',
children: [
{
type: 'name',
fieldName: '姓名',
fieldTips: '请输入姓名',
fixedLabel: '姓名',
disable: '0',
grid: 0.5,
defaultValue: '',
icon: 'icontext_box',
mustFill: '1',
maxLength: 20
},
{
type: 'idNumber',
fieldName: '身份证号',
fixedLabel: '身份证号',
fieldTips: '请输入身份证号',
defaultValue: '',
icon: 'icontext_area',
mustFill: '1',
maxLength: 20,
disable: '0',
grid: 0.5
},
{
type: 'phone',
fieldName: '联系方式',
fixedLabel: '联系方式',
fieldTips: '请输入联系方式',
defaultValue: '',
icon: 'icontext_area',
mustFill: '1',
maxLength: 20,
disable: '0',
grid: 0.5
},
{
type: 'area',
fieldName: '地区',
fixedLabel: '地区',
fieldTips: '请选择地区',
defaultValue: '',
icon: 'icontext_area',
mustFill: '1',
areaPattern: '',
disable: '0',
grid: 0.5
}
]
},
{
type: 'options',
tips: '(可重复添加)',
label: '选项',
children: [
{
type: 'radio',
fieldName: '单选',
fixedLabel: '单选',
fieldTips: '请选择',
grid: 0.5,
icon: 'iconradio',
mustFill: '1',
disable: '0',
defaultValue: '',
options: [
{
label: '选项1',
value: ''
},
{
label: '选项2',
value: ''
}
],
title: ''
},
{
type: 'checkbox',
fieldName: '多选',
fixedLabel: '多选',
fieldTips: '请选择',
icon: 'iconcheck_box',
mustFill: '1',
grid: 0.5,
disable: '0',
defaultValue: [],
options: [
{
label: '选项1',
value: ''
},
{
label: '选项2',
value: ''
}
],
title: ''
},
{
type: 'select',
fieldName: '单下拉框',
fixedLabel: '单下拉框',
grid: 0.5,
fieldTips: '请选择',
icon: 'iconSelect',
mustFill: '1',
defaultValue: '',
disable: '0',
options: [
{
label: '选项1',
value: ''
},
{
label: '选项2',
value: ''
}
],
title: ''
},
{
type: 'onOff',
fieldName: '开关',
fixedLabel: '开关',
grid: 0.5,
fieldTips: '请选择开关',
icon: 'iconSelect',
mustFill: '1',
defaultValue: '0',
disable: '0',
title: ''
},
{
type: 'date',
fieldName: '日期',
fixedLabel: '日期',
grid: 0.5,
datetimePattern: 'yyyy-MM-dd',
fieldTips: '请选择日期',
icon: 'iconSelect',
mustFill: '1',
disable: '0',
title: ''
},
{
type: 'time',
fieldName: '时间',
fixedLabel: '时间',
grid: 0.5,
datetimePattern: 'HH:mm:ss',
fieldTips: '请选择时间',
icon: 'iconSelect',
mustFill: '1',
disable: '0',
title: ''
},
{
type: 'datetime',
fieldName: '日期时间',
fixedLabel: '日期时间',
grid: 0.5,
datetimePattern: 'yyyy-MM-dd HH:mm:ss',
fieldTips: '请选择日期时间',
icon: 'iconSelect',
mustFill: '1',
disable: '0',
title: ''
}
]
},
{
type: 'input',
tips: '(可重复添加)',
label: '填空',
children: [
{
type: 'input',
fieldName: '单行填空',
fieldTips: '请输入',
fixedLabel: '单行填空',
disable: '0',
grid: 0.5,
defaultValue: '',
icon: 'icontext_box',
mustFill: '1',
maxLength: 50
},
{
type: 'textarea',
fieldName: '多行填空',
fixedLabel: '多行填空',
fieldTips: '请输入',
lineNumber: 4,
defaultValue: '',
icon: 'icontext_area',
mustFill: '1',
maxLength: 500,
disable: '0',
grid: 1
},
{
type: 'number',
fieldName: '数字输入',
fixedLabel: '数字输入',
fieldTips: '请输入数字',
defaultValue: '',
icon: 'icontext_area',
mustFill: '1',
maxValue: 10000,
decimalPlaces: 0,
minValue: 0,
maxLength: 500,
disable: '0',
grid: 0.5
},
{
type: 'rtf',
fieldName: '富文本',
fixedLabel: '富文本',
fieldTips: '请输入',
defaultValue: '',
icon: 'icontext_area',
mustFill: '1',
maxLength: 5000,
disable: '0',
grid: 1
}
]
},
{
type: 'annex',
tips: '(可重复添加)',
label: '附件',
children: [
{
type: 'upload',
fieldTips: '请上传',
fieldName: '上传附件',
fixedLabel: '上传附件',
disable: '0',
fileChoseSize: 10,
fileMaxCount: 9,
defaultValue: '',
icon: 'iconpic',
mustFill: '1',
grid: 1
}
]
},
{
type: 'layout',
tips: '(可重复添加)',
label: '分组',
children: [
{
type: 'group',
fieldName: '卡片',
fixedLabel: '卡片',
icon: 'iconpic',
groupName: '分组标题',
column: []
}
]
}
];