master
xy 3 years ago
parent 855df48e57
commit 641213d436

@ -32,6 +32,7 @@
"tinymce": "^5.10.7",
"view-design": "^4.7.0",
"vue": "2.6.10",
"vue-amap": "^0.5.10",
"vue-count-to": "^1.0.13",
"vue-router": "3.0.6",
"vuedraggable": "^2.24.3",

@ -12,7 +12,7 @@
securityJsCode: '0d59d0a3fa5483849b52b0edc4bc97ec',
}
</script>
<script type="text/javascript" src='https://webapi.amap.com/maps?v=1.4.11&key=795a757114c371f42cee1f8efa527684&plugin=AMap.PlaceSearch'></script>
<script type="text/javascript" src='https://webapi.amap.com/maps?v=1.4.11&key=795a757114c371f42cee1f8efa527684&plugin=AMap.PlaceSearch,AMap.MarkerClusterer'></script>
<script src="https://webapi.amap.com/ui/1.0/main.js?v=1.0.11"></script>
</head>
<body>

@ -65,3 +65,11 @@ export function relationDestroy(params) {
params
})
}
export function clone (params) {
return request({
method: 'get',
url: '/api/admin/custom-form/clone-table',
params
})
}

@ -24,17 +24,22 @@ export default {
watch: {
map(newVal) {
if(!newVal) return
let info = {
...newVal,
latitude: newVal.location.lat,
longitude: newVal.location.lng,
}
let res = ''
if(typeof this.resultFormat === 'string') {
res = newVal[this.resultFormat]
res = info[this.resultFormat]
}
if(this.resultFormat instanceof Array) {
res = this.resultFormat.map(i => newVal[i])?.toString()
res = this.resultFormat.map(i => info[i])?.toString()
}
if(typeof this.resultFormat === 'object' && (!this.resultFormat instanceof Array)) {
let obj = {}
for(let key in this.resultFormat) {
obj[key] = newVal[this.resultFormat[key]]
obj[key] = info[this.resultFormat[key]]
}
res = obj;
}

@ -149,7 +149,7 @@ export default {
},
btnWidth: {
type: Number,
default: 200,
default: 220,
},
//
@ -204,10 +204,9 @@ export default {
return metrics.width;
},
initLoad() {
if (this.height) return;
let clientHeight = document.documentElement.clientHeight;
let lxheader = document
.querySelector(".v-header")
.getBoundingClientRect();
let lxheader = document.querySelector(".v-header")?.getBoundingClientRect();
let lxHeader_height = lxheader.height + 25; //
let paginationHeight = 37; //
let topHeight = 50; //

@ -0,0 +1,59 @@
import Vue from 'vue';
export const defineDirective = () => {
Vue.directive('draggable', {
bind (el, binding) {
//是否移动端
if(/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) {
return
}
document.onselectstart = () => false
let dom = el
el.onmousedown = e => {
e.stopPropagation();
e.preventDefault();
//鼠标按下,计算当前元素距离可视区的距离
let disX = e.clientX - dom.offsetLeft;
let disY = e.clientY - dom.offsetTop;
document.onmousemove = e => {
binding.value(true)
e.stopPropagation();
//通过事件委托,计算移动的距离
let l = e.clientX - disX;
let t = e.clientY - disY;
//移动当前元素
dom.style.left = l + "px"
dom.style.top = t + "px"
}
document.onmouseup = e => {
e.stopPropagation();
document.onmousemove = null;
document.onmouseup = null;
let content = dom.getBoundingClientRect()
let {x,y} = content
let bkg = { width: window.innerWidth, height: window.innerHeight }
if(x < 0){
dom.style.left = 0 + "px"
}
if(x > (bkg.width - content.width)){
dom.style.left = (bkg.width - content.width) + "px"
}
if(y < 0){
dom.style.top = 0 + "px"
}
if(y > (bkg.height - content.height)){
dom.style.top = (bkg.height - content.height) + "px"
}
};
el.onclick = e => {
binding.value(false)
}
//return false不加的话可能导致黏连就是拖到一个地方时div粘在鼠标上不下来相当于onmouseup失效
//return false;
};
},
})
}

@ -89,7 +89,32 @@ Vue.prototype.$integrateData = (target,value) => {
}
}
}
// 高德地图
import AMap from 'vue-amap';
Vue.use(AMap);
// 初始化vue-amap
AMap.initAMapApiLoader({
// 高德的key
key: '795a757114c371f42cee1f8efa527684',
// 插件集合 (插件按需引入)
plugin: ['AMap.Autocomplete','AMap.Geocoder','AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView', 'AMap.ToolBar', 'AMap.MapType',
'AMap.PolyEditor', 'AMap.CircleEditor', 'AMap.DistrictSearch','AMap.CircleMarker','AMap.Polyline','AMap.MarkerClusterer'
// 'AMap.Object3DLayer', 'AMap.Object3D'
]
});
//高德的安全密钥
window._AMapSecurityConfig = {
securityJsCode: '0d59d0a3fa5483849b52b0edc4bc97ec',
}
// 解决地图刷新显示不出来
const amapKeys = Object.keys(localStorage).filter(key => key.match(/^_AMap_/))
amapKeys.forEach(key => {
// console.log(key)
localStorage.removeItem(key)
})
import { defineDirective } from './draggable';
defineDirective();
new Vue({
el: '#app',
router,

@ -1,112 +1,107 @@
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
/**
* Note: sub-menu only appear when route children.length >= 1
* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
*
* hidden: true if set true, item will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu
* if not set alwaysShow, when item has more than one children route,
* it will becomes nested mode, otherwise not show the root menu
* redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
* name:'router-name' the name is used by <keep-alive> (must set!!!)
* meta : {
roles: ['admin','editor'] control the page roles (you can set multiple roles)
title: 'title' the name show in sidebar and breadcrumb (recommend set)
icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
activeMenu: '/example/list' if set path, the sidebar will highlight the path you set
}
*/
/**
* constantRoutes
* a base page that does not have permission requirements
* all roles can be accessed
*/
export const constantRoutes = [{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/test',
component: () => import('@/views/component/test.vue'),
hidden: true
},
{
path: '/info',
component: Layout,
children: [{
path: 'password',
component: () => import('@/views/system/password'),
name: '密码修改',
meta: {
title: '密码修改'
}
}],
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: '系统首页',
component: () => import('@/views/dashboard/index'),
meta: {
title: '系统首页',
icon: 'dashboard'
}
}, ]
}
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
/**
* Note: sub-menu only appear when route children.length >= 1
* Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
*
* hidden: true if set true, item will not show in the sidebar(default is false)
* alwaysShow: true if set true, will always show the root menu
* if not set alwaysShow, when item has more than one children route,
* it will becomes nested mode, otherwise not show the root menu
* redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
* name:'router-name' the name is used by <keep-alive> (must set!!!)
* meta : {
roles: ['admin','editor'] control the page roles (you can set multiple roles)
title: 'title' the name show in sidebar and breadcrumb (recommend set)
icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
activeMenu: '/example/list' if set path, the sidebar will highlight the path you set
}
*/
/**
* constantRoutes
* a base page that does not have permission requirements
* all roles can be accessed
*/
export const constantRoutes = [{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/info',
component: Layout,
children: [{
path: 'password',
component: () => import('@/views/system/password'),
name: '密码修改',
meta: {
title: '密码修改'
}
}],
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: '系统首页',
component: () => import('@/views/dashboard/index'),
meta: {
title: '系统首页',
icon: 'dashboard'
}
}, ]
}
]
/**
* asyncRoutes
* the routes that need to be dynamically loaded based on user roles
*/
export const asyncRoutes = [
// 404 page must be placed at the end !!!
{
path: '*',
redirect: '/404',
hidden: true
}
]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({
y: 0
}),
routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
/**
* asyncRoutes
* the routes that need to be dynamically loaded based on user roles
*/
export const asyncRoutes = [
// 404 page must be placed at the end !!!
{
path: '*',
redirect: '/404',
hidden: true
}
]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({
y: 0
}),
routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router

@ -1,5 +1,7 @@
import { save, index, destroy } from "@/api/system/customFormField";
import { Message } from "element-ui";
import {index} from "@/api/system/customFormField";
import {show,save} from "@/api/system/customForm";
import {Message} from "element-ui";
const state = {
formList: [], //更个表单配置信息
copyFormListId: [], //备份原始的字段id数组,以做删除
@ -37,31 +39,50 @@ const mutations = {
};
const actions = {
submit: ({ state, commit }) => {
submit: ({ state, commit }, tableId) => {
return new Promise((resolve, reject) => {
state.formList.forEach((item,index) => {
item.sort = index + 1
})
let formListId = state.formList.filter((i) => !!i.id).map((i) => i.id);
let deleteIds = state.copyFormListId.filter(
(i) => !formListId.includes(i)
);
let promiseAll = [
...state.formList.map((i) => save(i)),
...deleteIds.map((i) => destroy({ id: i })),
];
Promise.all(promiseAll)
.then((res) => {
show({ id: tableId }).then(res => {
state.formList.forEach((item,index) => {
item.sort = index + 1
})
res.fields = state.formList
save(res).then(res1 => {
Message({
type: "success",
message: "保存成功",
});
resolve(res);
type: 'success',
message: res1.msg
})
resolve(res1)
}).catch(err1 => {
reject(err1)
})
.catch((err) => {
reject(err);
});
});
}).catch(err => {
reject(err)
})
})
// return new Promise((resolve, reject) => {
// state.formList.forEach((item,index) => {
// item.sort = index + 1
// })
// let formListId = state.formList.filter((i) => !!i.id).map((i) => i.id);
// let deleteIds = state.copyFormListId.filter(
// (i) => !formListId.includes(i)
// );
// let promiseAll = [
// ...state.formList.map((i) => save(i)),
// ...deleteIds.map((i) => destroy({ id: i })),
// ];
// Promise.all(promiseAll)
// .then((res) => {
// Message({
// type: "success",
// message: "保存成功",
// });
// resolve(res);
// })
// .catch((err) => {
// reject(err);
// });
// });
},
getFormList: ({ state, commit }, custom_form_id) => {
return new Promise((resolve, reject) => {

@ -0,0 +1,123 @@
<template>
<div>
<el-dialog
top="8vh"
title="资产历史"
:visible.sync="dialogVisible"
width="680px"
>
<el-scrollbar style="height: 58vh">
<el-form
ref="elForm"
:model="form"
label-width="80px"
size="small"
label-position="right"
>
<el-form-item prop="riqi" label="日期" required>
<el-date-picker v-model="form.riqi"></el-date-picker>
</el-form-item>
<el-form-item prop="neirong" label="内容">
<my-tinymce v-model="form.neirong"></my-tinymce>
</el-form-item>
<el-form-item prop="tupian" label="图片">
<el-upload
ref="upload"
:action="action"
:file-list="tupian"
:headers="{
Authorization: `Bearer ${getToken()}`,
}"
:auto-upload="false"
multiple
list-type="picture"
:on-success="successHandle"
:before-upload="uploadBefore"
:on-remove="removeHande"
>
<el-button slot="trigger" size="mini" type="primary">选取图片</el-button>
<el-button style="margin-left: 10px;" size="mini" type="success" @click="$refs['upload'].submit()"></el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过500kb</div>
</el-upload>
</el-form-item>
</el-form>
</el-scrollbar>
<template #footer>
<el-button size="mini" @click="hide"> </el-button>
<el-button size="mini" type="warning" plain @click="init"> </el-button>
<el-button size="mini" type="primary" @click="submit"> </el-button>
</template>
</el-dialog>
</div>
</template>
<script>
import { save } from "@/api/system/baseForm";
import { getToken } from "@/utils/auth";
export default {
data() {
return {
action: process.env.VUE_APP_UPLOAD_API,
dialogVisible: false,
asset_id: "",
form: {
riqi: "",
neirong: "",
tupian: "",
},
tupian: [],
};
},
methods: {
//
successHandle(response, file, fileList) {
this.fileList = fileList;
},
removeHande(file, fileList) {
this.fileList = fileList;
},
uploadBefore(file) {
console.log(file);
if (file.size / 1000 > 50 * 1024) {
this.$message({
type: "warning",
message: "上传图片大小超过50M",
});
return false;
}
},
getToken,
show() {
this.dialogVisible = true;
},
hide() {
this.dialogVisible = false;
},
setAssetId(id) {
this.asset_id = id;
},
init() {
for (let key in this.form) {
if (this.form[key] instanceof Array) {
this.form[key] = [];
} else {
this.form[key] = "";
}
}
this.$refs["elForm"].clearValidate();
},
submit () {
let promiseAll = [];
}
},
computed: {},
};
</script>
<style scoped lang="scss"></style>

@ -13,16 +13,206 @@
@back="$router.back()"
>
</el-page-header>
<el-row :gutter="20">
<el-col :span="14">
<el-card v-if="detail.id_assets_picture_files_file_id_relation" style="margin-bottom: 20px;">
<div class="el-descriptions__header el-descriptions__title">图集</div>
<el-carousel trigger="click" height="150px">
<el-carousel-item v-for="item in detail.id_assets_picture_files_file_id_relation">
<el-image
style="width: 100%; height: 100%;"
:src="item.url"
:preview-src-list="picList"
fit="contain"></el-image>
</el-carousel-item>
</el-carousel>
</el-card>
<el-card>
<el-descriptions title="详情" :column="2" :label-style="{'font-weight': '600'}">
<el-descriptions-item v-for="item in fields" :label="item.name">{{
contentFormat(item)
}}</el-descriptions-item>
</el-descriptions>
</el-card>
</el-col>
<el-col :span="10" >
<el-card>
<div class="el-descriptions__header el-descriptions__title">资产历史</div>
<el-timeline>
<el-timeline-item
v-for="(activity, index) in activities"
:key="index"
:icon="activity.icon"
:type="activity.type"
:color="activity.color"
:size="activity.size"
:timestamp="activity.timestamp">
{{activity.content}}
</el-timeline-item>
</el-timeline>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
import { show } from "@/api/system/baseForm"
import { show as formShow } from "@/api/system/customForm";
import { getparameter } from '@/api/system/dictionary'
import { listdept } from '@/api/system/department'
export default {
data() {
return {}
return {
picList: [],
detail: {},
fields: [],
relation: [],
customForm: {
customFormId: "",
tableName: "",
},
activities: [{
content: '支持使用图标',
timestamp: '2018-04-12 20:46',
size: 'large',
type: 'primary',
icon: 'el-icon-more'
}, {
content: '支持自定义颜色',
timestamp: '2018-04-03 20:46',
color: '#0bbd87'
}, {
content: '支持自定义尺寸',
timestamp: '2018-04-03 20:46',
size: 'large'
}, {
content: '默认样式的节点',
timestamp: '2018-04-03 20:46'
}]
}
},
methods: {
async getFields () {
if (this.$route.meta.params?.custom_form) {
let decode = decodeURIComponent(this.$route.meta.params?.custom_form);
try {
let custom_form = JSON.parse(decode);
this.customForm.customFormId = custom_form.custom_form_id;
this.customForm.tableName = custom_form.table_name;
} catch (err) {
console.warn(err);
}
}
const res = await formShow({ id: this.customForm.customFormId }, false);
this.fields = res.fields.sort((a,b) => a.sort - b.sort)
this.relation = res.relation
//
//
let baseTable = new Map([
['departments', async () => {
const res = await listdept()
return res
}],
['admins',[]]
])
let { fields, relation } = this
if (
!fields ||
!relation ||
!fields instanceof Array ||
!relation instanceof Array
) {
throw new Error("fields或relation格式错误");
}
fields.sort((a,b) => a.sort - b.sort).forEach(i => {
i._relations = relation.find(
(j) => j.link_table_name.split("_")[1] === i.field
);
if (i.select_item && typeof i.select_item === "object") {
let keys = Object.keys(i.select_item);
i._params = keys.map((key) => {
return {
key,
value: /^\d*$/.test(i.select_item[key])
? Number(i.select_item[key])
: i.select_item[key],
};
});
}
if (i.edit_input === 'file' || i.edit_input === 'files') {
return
}
if (i._relations) {
if (baseTable.get(i._relations.link_table_name)) {
baseTable
.get(i._relations.link_table_name)()
.then((res) => {
i._params = res.data;
});
} else {
i._params = i._relations.parameter_id
? getparameter({ id: i._relations.parameter_id }, false).then(
(res) => {
i._params = res.detail;
}
)
: this.index({
table_name: i._relations.link_table_name,
page: 1,
page_size: 9999,
}).then((res) => {
i._params = res.data;
});
}
}
});
const detail = await show({
id: this.$route.query.id,
table_name: this.customForm.tableName
})
this.detail = detail
this.picList = detail?.id_assets_picture_files_file_id_relation?.map(i => i.url)
}
},
computed: {
contentFormat() {
return function (i) {
let { _relations } = i;
if (_relations && _relations.link_table_name) {
if (_relations.link_relation === "hasOne" || _relations.link_relation === "newHasOne") {
return (
this.detail[_relations.link_with_name]?.name ||
this.detail[_relations.link_with_name]?.no ||
this.detail[_relations.link_with_name]?.value
);
}
if (_relations.link_relation === "hasMany" || _relations.link_relation === "newHasMany") {
return this.detail[_relations.link_with_name]
?.map((o) => o?.original_name || o?.name || o?.no || o?.value)
?.toString();
}
return
}
if (i._params && i._params.length > 0) {
return i._params.find(j => j.value == this.detail[i.field])?.key;
}
return this.detail[i.field]
};
}
},
methods: {},
computed: {}
created() {
this.getFields()
}
}
</script>

@ -1,8 +1,9 @@
<script>
import { save, show, index } from "@/api/system/baseForm";
import { save, show, index, destroy } from "@/api/system/baseForm";
import { getparameter } from "@/api/system/dictionary";
import { domMap } from "@/const/inputType";
import { addPropsMap } from "@/const/addProps";
import { deepCopy } from "@/utils";
export default {
props: {
formInfo: {
@ -13,144 +14,172 @@ export default {
},
render(h) {
return h(
"Modal",
"el-dialog",
{
props: {
top: "8vh",
title: "新增",
value: this.dialogVisible,
width: 80,
visible: this.dialogVisible,
width: "750px",
},
on: {
"on-visible-change": (val) => {
"update:visible": (val) => {
this.dialogVisible = val;
},
},
},
[
h(
"el-form",
"el-scrollbar",
{
class: "form-body",
ref: "elForm",
props: {
model: this.form,
labelWidth: "80px",
rules: this.rules,
labelPosition: "right",
size: "small",
style: {
height: "58vh",
},
},
(() => {
let dom = [];
this.formInfo.filter(i => i.form_show).forEach((i, index) => {
dom.push(
h(
"el-form-item",
{
class: "form-body__item",
ref: `elFormItem${i.field}`,
style: {
width: "100%",
},
props: {
label: i.name,
prop: i.field,
required:
i.validation instanceof Array
? !!i.validation.find((i) => i === "required")
: false,
},
},
this.$scopedSlots[i.field]
? this.$scopedSlots[i.field]({ fieldInfo: i, form: this.form, file: this.file })
: [
[
h(
"el-form",
{
class: "form-body",
ref: "elForm",
style: {
"padding-right": "12px",
},
props: {
model: this.form,
labelWidth: "80px",
rules: this.rules,
labelPosition: "right",
size: "small",
},
},
(() => {
let dom = [];
this.formInfo
.filter((i) => i.form_show)
.forEach((i, index) => {
dom.push(
h(
domMap.get(i.edit_input),
"el-form-item",
{
ref: `elEdit_${i.field}`,
ref: `elFormItem${i.field}`,
style: {
width: "100%",
},
props: {
...addPropsMap.get(i.edit_input),
...this.extraProps(i),
placeholder: i.help,
value: this.form[i.field],
},
attrs: {
placeholder: i.help || `请填写${i.name}`,
label: i.name,
prop: i.field,
required:
i.validation instanceof Array
? !!i.validation.find((i) => i === "required")
: false,
},
on: {
[this.getEventType(i.edit_input)]: (e) => {
if (i.field) {
this.form[i.field] = e;
this.form = Object.assign({}, this.form);
}
},
},
scopedSlots:
i.edit_input === "file" ||
i.edit_input === "files"
? {
file: (scope) => {
let { file } = scope;
return [
h("div", {}, [
h("i", {
class: {
"el-icon-circle-check":
file.status === "success",
"el-icon-loading":
file.status === "uploading",
},
style: {
color:
file.status === "success"
? "green"
: "",
},
}),
h(
"a",
{
attrs: {
href: file.url,
download: file.name,
},
class: {
"uploaded-a":
file.status === "success",
},
style: {
'padding': '0 4px'
},
},
file.name
),
]),
h("i", {
class: "el-icon-close",
on: {
["click"]: () =>
this.fileRemoveHandler(
file,
i.field
),
},
}),
];
},
}
: "",
},
this.optionsRender(h, i)
),
]
)
);
});
return dom;
})()
this.$scopedSlots[i.field]
? this.$scopedSlots[i.field]({
fieldInfo: i,
form: this.form,
file: this.file,
})
: [
h(
domMap.get(i.edit_input),
{
ref: `elEdit_${i.field}`,
style: {
width: "100%",
},
props: {
...addPropsMap.get(i.edit_input),
...this.extraProps(i),
placeholder: i.help,
value: this.form[i.field],
},
attrs: {
placeholder: i.help || `请填写${i.name}`,
},
on: {
[this.getEventType(i.edit_input)]: (
e
) => {
if (i.field) {
this.form[i.field] = e;
this.form = Object.assign(
{},
this.form
);
}
},
},
scopedSlots:
i.edit_input === "file" ||
i.edit_input === "files"
? {
file: (scope) => {
let { file } = scope;
return [
h("div", {}, [
h("i", {
class: {
"el-icon-circle-check":
file.status ===
"success",
"el-icon-loading":
file.status ===
"uploading",
},
style: {
color:
file.status ===
"success"
? "green"
: "",
},
}),
h(
"a",
{
attrs: {
href: file.url,
download: file.name,
},
class: {
"uploaded-a":
file.status ===
"success",
},
style: {
padding: "0 4px",
},
},
file.name
),
]),
h("i", {
class: "el-icon-close",
on: {
["click"]: () =>
this.fileRemoveHandler(
file,
i.field
),
},
}),
];
},
}
: "",
},
this.optionsRender(h, i)
),
]
)
);
});
return dom;
})()
),
]
),
h("template", { slot: "footer" }, [
h(
@ -202,6 +231,7 @@ export default {
type: "add",
dialogVisible: false,
form: {},
originalForm: {},
rules: {},
file: {},
};
@ -224,13 +254,20 @@ export default {
if (info.edit_input === "checkbox" || info.edit_input === "radio") {
return info._params && info._params instanceof Array
? info._params.map((i) =>
h("el-option", {
props: {
label: i.key || i.value || i.name || i.no || i.mingcheng || i.id,
value: info._relations ? i[info._relations.foreign_key] : i.value,
},
})
)
h("el-option", {
props: {
label:
i.name ||
i.mingcheng ||
i.label ||
i.key ||
i.value ||
i.id ||
i.no,
value: i.id || i.value,
},
})
)
: [];
}
if (info.edit_input === "file" || info.edit_input === "files") {
@ -344,29 +381,36 @@ export default {
async getDetail() {
const res = await show({ id: this.id, table_name: this.tableName });
this.$integrateData(this.form, res);
this.form = Object.assign({}, this.form);
this.formInfo.forEach((i) => {
if (i && (i.edit_input === "file" || i.edit_input === 'files')) {
res[i._relations.link_with_name] ? (
this.file[i.field] = res[i._relations.link_with_name] instanceof Array ? res[i._relations.link_with_name].map(i => {
return {
name: i?.original_name,
url: i?.url,
response: i
}
}) : [{
name: res[i._relations.link_with_name]?.original_name,
url: res[i._relations.link_with_name]?.url,
response: res[i._relations.link_with_name]
}]
) : this.file[i.field] = []
if (i && (i.edit_input === "file" || i.edit_input === "files")) {
res[i._relations.link_with_name]
? (this.file[i.field] =
res[i._relations.link_with_name] instanceof Array
? res[i._relations.link_with_name].map((i) => {
return {
name: i?.name,
url: i?.url,
response: i,
};
})
: [
{
name: res[i._relations.link_with_name]?.name,
url: res[i._relations.link_with_name]?.url,
response: res[i._relations.link_with_name],
},
])
: (this.file[i.field] = []);
}
this.form = Object.assign({}, this.form);
this.originalForm = deepCopy(res);
});
},
submit() {
let promiseAll = [];
if (this.type === "add") {
if (this.form.hasOwnProperty("id")) {
delete this.form.id;
@ -382,26 +426,123 @@ export default {
}
this.$refs["elForm"].validate((validate) => {
if (validate) {
let copyForm = deepCopy(this.form);
this.formInfo.forEach((info) => {
if (info.edit_input === "files") {
this.form[info.field] = this.file[info.field].map(
(i) => i?.response?.id
);
if (
info._relations?.link_relation === "newHasMany" ||
info._relations?.link_relation === "hasMany"
) {
if (this.originalForm[info._relations.link_with_name]) {
this.originalForm[info._relations.link_with_name].map((i) => {
promiseAll.push(
destroy({
id: i.id,
table_name: info._relations.link_table_name,
})
);
});
}
}
if (info.edit_input === "file") {
this.form[info.field] = this.file[info.field][0]?.response?.id;
if (copyForm[info._relations?.link_with_name]?.length > 0) {
delete copyForm[info.field];
}
});
console.log(this.form);
save(Object.assign(this.form, { table_name: this.tableName })).then(
(res) => {
this.$Message.success({
content: `${this.type === "add" ? "新增" : "编辑"}成功`,
});
this.$emit("refresh");
this.hidden();
if (
info._relations?.link_relation === "newHasMany" ||
info._relations?.link_relation === "hasMany"
) {
if (info.edit_input === "files") {
copyForm[info._relations.link_with_name] = this.file[
info.field
]?.map((i) => {
let copyRelation = i?.response ? deepCopy(i?.response) : "";
delete copyRelation.id;
return {
upload_id: i?.response?.id,
...copyRelation,
};
});
} else {
copyForm[info._relations.link_with_name] = copyForm[
info.field
]?.map((i) => {
let copyRelation = info._params.find(
(param) => param[info._relations?.foreign_key] === i
)
? deepCopy(
info._params.find(
(param) => param[info._relations?.foreign_key] === i
)
)
: "";
delete copyRelation.id;
return {
[info._relations.foreign_key]: i,
...copyRelation,
};
});
}
delete copyForm[info.field];
}
if (
info._relations?.link_relation === "newHasOne" ||
info._relations?.link_relation === "hasOne"
) {
if (info.edit_input === "file") {
copyForm[info._relations.link_with_name] = [
{
upload_id: this.file[info.field]?.response?.id,
...this.file[info.field],
},
];
} else {
let copyRelation = deepCopy(
info._params.find(
(param) => param.id == this.form[info.field]
)
);
if (copyRelation) {
delete copyRelation.id;
copyForm[info._relations.link_with_name] = [
{
id: this.form[info._relations?.link_with_name]?.id,
[info.field === "shenhebumen"
? "dept_id"
: info._relations.foreign_key]: this.form[info.field],
...copyRelation,
},
];
}
}
delete copyForm[info.field];
}
if (!copyForm[info._relations?.link_with_name]) {
delete copyForm[info._relations?.link_with_name];
}
// if (info._relations?.link_with_name) {
// if (info.edit_input === "files" || info.edit_input === "file") {
// this.form[info._relations.link_with_name] = this.file[info.field].map(i => i?.response);
// delete this.form[info.field]
// } else {
// this.form[info._relations.link_with_name] = this.form[info.field] instanceof Array ? this.form[info.field].map(i => {
// return info._params.find(param => i === param[info._relations.foreign_key])
// }) : [info._params.find(param => this.form[info.field] === param[info._relations.foreign_key])]
// delete this.form[info.field]
// }
// }
});
promiseAll.push(
save(Object.assign(copyForm, { table_name: this.tableName }))
);
Promise.all(promiseAll).then((res) => {
this.$Message.success({
content: `${this.type === "add" ? "新增" : "编辑"}成功`,
});
this.$emit("refresh");
this.hidden();
});
}
});
},
@ -434,6 +575,10 @@ export default {
if (i.edit_input === "checkbox") {
this.form[i.field] = [];
}
if (i._relations) {
this.form[i._relations?.link_with_name] = [];
}
}
});
@ -447,12 +592,14 @@ export default {
this.$nextTick(() => this.getDetail());
}
} else {
this.file = {};
this.id = "";
this.type = "";
this.init();
this.$refs["elForm"].clearValidate();
delete this.form.id;
for (let key in this.file) {
this.file[key] = [];
}
}
},
},
@ -465,7 +612,6 @@ export default {
}
</style>
<style scoped lang="scss">
.uploaded-a {
color: red;
text-decoration: none;

@ -1,6 +1,6 @@
<template>
<div>
<el-dialog :visible.sync="dialogVisible" title="数据导入" width="740px">
<el-dialog :visible.sync="dialogVisible" title="数据导入" width="70%">
<div class="title">模板下载</div>
<el-button
style="margin-top: 10px"
@ -54,7 +54,7 @@ export default {
},
data() {
return {
action: `${process.env.VUE_APP_BASE_API}/api/admin/base-form/excel-show`,
action: `${process.env.VUE_APP_BASE_API}api/admin/base-form/excel-show`,
dialogVisible: false,
headers: [],
@ -126,6 +126,7 @@ export default {
return {
key: i.field,
title: i.name,
width: 200
};
});
}

@ -0,0 +1,665 @@
<template>
<div>
<div class="search-bar">
<el-select
v-model="nowCity"
size="small"
placeholder="请选择区域"
@change="areaPick"
>
<el-option
v-for="item in wxAreas"
:value="item"
:label="item"
></el-option>
</el-select>
</div>
<div class="search" v-draggable="(status) => (dragging = status)">
<transition name="fade">
<div
class="search-btn"
v-if="!searchShow"
@click="dragging ? '' : (searchShow = true)"
>
查询
</div>
</transition>
<transition name="fade">
<div class="search-list" v-if="searchShow">
<div class="search-list__close" @click="searchShow = false">
<i class="el-icon-arrow-right"></i>
</div>
<div
style="
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
margin-bottom: 10px;
"
>
<Input
v-model="select.name"
style="width: 65px; margin-right: 10px"
placeholder="地块名称"
/>
<Button type="primary" @click="$refs['table'].getTableData(true)"
>查询</Button
>
</div>
<div>
<xy-table
ref="table"
:height="360"
:action="index"
:table-item="table"
:req-opt="select"
@row-click="pickRow"
></xy-table>
</div>
</div>
</transition>
</div>
<div class="map" id="map" :style="{ height: mapHeight + 'px' }"></div>
<div ref="infoWindow" id="infoWindow" v-show="isShowInfoWindow">
<div>
<div v-for="item in form">
<p>{{ item.name }}</p>
<p>{{ contentFormat(item) }}</p>
</div>
</div>
</div>
</div>
</template>
<script>
import { index } from "@/api/system/baseForm";
import { show } from "@/api/system/customForm";
import { listdept } from "@/api/system/department";
import { getparameter } from "@/api/system/dictionary";
export default {
data() {
return {
dragging: false,
searchShow: false,
select: {
table_name: "assets",
},
customForm: {
customFormId: "",
tableName: "",
},
form: [],
table: [],
list: [],
mapHeight: 0,
center: [119.597897, 31.723247],
isShowInfoWindow: false,
openData: {},
infoWindow: null,
district: null,
cluster: null,
polygons: [],
markerList: [],
nowCity: "",
wxAreas: [
"锡山区",
"惠山区",
"滨湖区",
"梁溪区",
"新吴区",
"江阴市",
"宜兴市",
],
};
},
methods: {
index,
areaPick(e) {
this.areaBG(e);
},
pickRow({ row }) {
this.isShowInfoWindow = true;
this.openData = row;
if (row.zichanweizhi) {
let lat, lng;
[lng, lat] = row.zichanweizhi.split(",");
this.map.panTo([lng, lat]);
this.infoWindow.open(this.map, [lng, lat]);
} else {
this.map.panTo(this.center);
this.infoWindow.open(this.map, this.center);
}
},
async getList() {
const res = await index({
page: 1,
page_size: 9999,
...this.select,
});
this.list = res.data;
},
addCluster () {
if (this.cluster) {
this.cluster.setMap(null);
}
this.cluster = new AMap.MarkerClusterer(this.map, this.markerList, {
gridSize: 50, //
renderClusterMarker: this.renderClusterMarker, //
renderMarker: this.renderMarker, //
});
},
renderClusterMarker (context) {
let factor = Math.pow(context.count / this.list.length, 1 / 18);
let div = document.createElement('div');
let Hue = 180 - factor * 180;
let bgColor = 'hsla(' + Hue + ',100%,40%,0.7)';
let fontColor = 'hsla(' + Hue + ',100%,90%,1)';
let borderColor = 'hsla(' + Hue + ',100%,40%,1)';
let shadowColor = 'hsla(' + Hue + ',100%,90%,1)';
div.style.backgroundColor = bgColor;
let size = Math.round(30 + Math.pow(context.count / this.list.length, 1 / 5) * 20);
div.style.width = div.style.height = size + 'px';
div.style.border = 'solid 1px ' + borderColor;
div.style.borderRadius = size / 2 + 'px';
div.style.boxShadow = '0 0 5px ' + shadowColor;
div.innerHTML = context.count;
div.style.lineHeight = size + 'px';
div.style.color = fontColor;
div.style.fontSize = '14px';
div.style.textAlign = 'center';
context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2));
context.marker.setContent(div)
},
renderMarker (context) {
let content = '<div style="background-color: hsla(180, 100%, 50%, 0.3); height: 18px; width: 18px; border: 1px solid hsl(180, 100%, 40%); border-radius: 12px; box-shadow: hsl(180, 100%, 50%) 0px 0px 3px;"></div>';
let offset = new AMap.Pixel(-9, -9);
context.marker.setContent(content)
context.marker.setOffset(offset)
},
setMapMarker() {
this.map.remove(this.markerList);
this.markerList = [];
this.list.forEach((item) => {
if (item.zichanweizhi) {
let lat, lng;
[lng, lat] = item.zichanweizhi.split(",");
let marker = new AMap.Marker({
icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
position: [Number(lng), Number(lat)],
offset: new AMap.Pixel(-13, -30),
});
let markerContent = document.createElement("div");
markerContent.setAttribute("class", "map-marker");
markerContent.onclick = () => {
this.pickRow({ row: item });
};
let markerImg = document.createElement("img");
markerImg.src =
"//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png";
let markerSpan = document.createElement("span");
markerSpan.setAttribute("class", "map-marker__text");
markerSpan.innerText =
item.dikuaimingcheng.length > 4
? item.dikuaimingcheng.slice(0,2) + ".." + item.dikuaimingcheng.slice(item.dikuaimingcheng.length - 2)
: item.dikuaimingcheng;
markerContent.appendChild(markerImg);
markerContent.appendChild(markerSpan);
marker.setContent(markerContent);
this.markerList.push(marker);
}
});
this.map.add(this.markerList);
this.addCluster();
},
init() {
let winHeight = document
.querySelector(".app-main")
?.getBoundingClientRect()?.height;
this.mapHeight = winHeight - 50 - 20;
this.map = new AMap.Map("map", {
center: this.center,
mapStyle: "amap://styles/bfb1bb3feb0db7082367abca96b8d214", //
zoom: this.zoom
});
//
let adcode = ["320200"];
this.areaBG(adcode);
this.infoWindow = new AMap.InfoWindow({
isCustom: true,
autoMove: true,
avoid: [20, 20, 20, 20],
content: this.$refs.infoWindow,
closeWhenClickMap: true,
offset: new AMap.Pixel(-10, -10),
});
},
//
areaBG(adcode) {
AMap.service("AMap.DistrictSearch", () => {
let opts = {
subdistrict: 1, //
extensions: "all", //
level: "city", //
// adcode:'320200'
};
// DistrictSearch
let district = new AMap.DistrictSearch(opts);
district.setLevel("district");
//
district.search(`${adcode}`, (status, result) => {
//
this.map.remove(this.polygons);
this.polygons = [];
//
let bounds = result.districtList[0].boundaries;
if (bounds) {
for (let i = 0, l = bounds.length; i < l; i++) {
// polygon
let polygon = new AMap.Polygon({
map: this.map,
strokeWeight: 1,
path: bounds[i],
fillOpacity: 0.2,
fillColor: "#3579c788",
strokeColor: "#3579c7",
});
this.polygons.push(polygon);
this.map.setFitView(polygon);
}
}
});
});
},
async getFormDetail() {
if (this.$route.meta.params?.custom_form) {
let decode = decodeURIComponent(this.$route.meta.params?.custom_form);
try {
let custom_form = JSON.parse(decode);
this.customForm.customFormId = custom_form.custom_form_id;
this.customForm.tableName = custom_form.table_name;
this.select.table_name = custom_form.table_name;
} catch (err) {
console.warn(err);
}
}
const res = await show({ id: this.customForm.customFormId }, false);
//
//
let baseTable = new Map([
[
"departments",
async () => {
const res = await listdept();
return res;
},
],
["admins", []],
]);
let { fields, relation } = res;
let fieldRes = fields.sort((a, b) => a.sort - b.sort);
if (
!fields ||
!relation ||
!fields instanceof Array ||
!relation instanceof Array
) {
throw new Error("fields或relation格式错误");
}
fieldRes?.forEach((i, index) => {
i._relations = relation.find(
(j) => j.link_table_name.split("_")[1] === i.field
);
if (i.select_item && typeof i.select_item === "object") {
let keys = Object.keys(i.select_item);
i._params = keys.map((key) => {
return {
key,
value: /^\d*$/.test(i.select_item[key])
? Number(i.select_item[key])
: i.select_item[key],
};
});
}
if (i.edit_input === "file" || i.edit_input === "files") {
return;
}
if (i._relations) {
if (baseTable.get(i._relations.link_table_name)) {
baseTable
.get(i._relations.link_table_name)()
.then((res) => {
i._params = res.data;
});
} else {
i._params = i._relations.parameter_id
? getparameter({ id: i._relations.parameter_id }, false).then(
(res) => {
i._params = res.detail;
}
)
: this.index({
table_name: i._relations.link_table_name,
page: 1,
page_size: 9999,
}).then((res) => {
i._params = res.data;
});
}
}
});
this.form = fieldRes || [];
this.form
?.filter((i) => i.list_show)
.forEach((i) => {
let linkOb = {};
if (i.edit_input === "richtext") {
linkOb.customFn = (row) => {
return (
<div
style={{ "max-height": "55px", overflow: "scroll" }}
domPropsInnerHTML={row[i.field]}
></div>
);
};
}
if (
i.select_item &&
typeof i.select_item === "object" &&
!(i.select_item instanceof Array)
) {
let keys = Object.keys(i.select_item);
linkOb.customFn = (row) => {
let paramMap = new Map();
keys.forEach((key) => {
paramMap.set(i.select_item[key], key);
});
return <span>{paramMap.get(row[i.field]?.toString())}</span>;
};
}
if (i._relations) {
let { link_relation, foreign_key, link_with_name } = i._relations;
if (link_relation === "newHasOne" || link_relation === "hasOne") {
linkOb.customFn = (row) => {
if (i.edit_input === "file") {
return (
<a
download={row[link_with_name]?.original_name}
href={row[link_with_name]?.url}
>
{row[link_with_name]?.original_name}
</a>
);
} else {
return (
<span>
{row[link_with_name]?.name ||
row[link_with_name]?.no ||
row[link_with_name]?.value}
</span>
);
}
};
}
if (link_relation === "hasMany" || link_relation === "newHasMany") {
linkOb.customFn = (row) => {
if (i.edit_input === "files") {
return (
<div style="display: flex;flex-direction: column;">
{row[link_with_name]?.map((o) => (
<a>{o?.original_name || o?.name}</a>
))}
</div>
);
} else {
return (
<div>
{row[link_with_name]?.map((o) => (
<p>
{o?.name ||
o?.no ||
o?.value ||
o?.biaoti ||
o?.mingcheng}
</p>
))}
</div>
);
}
};
}
}
this.table.push(
Object.assign(
{
prop: i.field,
label: i.name,
width: i.width,
fixed: i.is_fixed,
},
linkOb
)
);
});
this.table.unshift({
type: "index",
width: 60,
label: "序号",
});
},
},
computed: {
contentFormat() {
return function (i) {
if (i._params && i._params.length > 0) {
return i._params.find(
(param) => param.value == this.openData[i.field]
)?.key;
}
if (i._relations) {
let { link_relation, foreign_key, link_with_name, link_table_name } = i._relations;
if (link_table_name && link_relation) {
if (link_relation === "hasOne" || link_relation === "newHasOne") {
return (
this.openData[link_with_name]?.name ||
this.openData[link_with_name]?.no ||
this.openData[link_with_name]?.value
);
}
if (link_relation === "hasMany" || link_relation === "newHasMany") {
return this.openData[link_with_name]
?.map((o) => o?.original_name || o?.name || o?.no || o?.value)
?.toString();
}
}
}
return this.openData[i.field] || '/';
};
},
},
created() {
this.getFormDetail();
},
async mounted() {
this.init();
await this.getList();
this.setMapMarker();
},
};
</script>
<style scoped lang="scss">
.search-bar {
padding: 10px 0;
}
.search {
min-width: 50px;
min-height: 50px;
position: fixed;
top: 115px;
left: 85px;
z-index: 99;
&-btn {
color: #fff;
width: 50px;
height: 50px;
background: $primaryColor;
filter: drop-shadow(2px 2px 5px #000000aa);
transition: all 0.3s;
border-radius: 50px;
text-align: center;
line-height: 50px;
cursor: pointer;
font-weight: bold;
position: absolute;
top: 0;
left: 0;
&:hover {
transform: scale(1.1, 1.1);
}
}
&-list {
max-width: 500px;
border-radius: 6px;
filter: drop-shadow(2px 2px 5px #00000055);
background: #fff;
padding: 10px;
position: relative;
&__close {
zoom: 0.85;
width: 40px;
height: 40px;
border-radius: 40px 0 0 40px;
text-align: center;
line-height: 40px;
font-size: 22px;
background: #fff;
cursor: pointer;
transform: translateY(-50%);
position: absolute;
top: 10%;
left: -24px;
}
}
}
#map {
border-radius: 4px;
filter: drop-shadow(2px 2px 5px #00000033);
}
.fade-enter-active {
animation: fade-in 0.6s cubic-bezier(0.39, 0.575, 0.565, 1) both;
}
@keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.fade-leave-active {
animation: fade-out 0.4s ease-out both;
}
@keyframes fade-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
</style>
<style lang="scss">
#infoWindow {
min-width: 140px;
max-height: 240px;
overflow-y: scroll;
position: relative;
filter: drop-shadow(2px 2px 5px #00000055);
border-radius: 4px;
background: #fff;
padding: 20px;
animation: fade-in 0.4s forwards;
&::-webkit-scrollbar {
width: 4px;
}
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#infoWindow > div {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 10px;
& > div > p:nth-child(1) {
font-weight: 600;
padding-bottom: 6px;
}
& > div > p:nth-child(2) {
white-space: nowrap;
}
}
::v-deep #infoWindow .el-icon-close {
position: absolute;
top: 5px;
right: 5px;
cursor: pointer;
}
.showInfo {
text-align: center;
cursor: pointer;
color: $primaryColor;
}
.map-marker {
display: flex;
flex-direction: column;
align-items: center;
&__text {
background: #fff;
zoom: 0.75;
padding: 2px 6px;
border-radius: 4px;
white-space: nowrap;
filter: drop-shadow(2px 2px 5px #00000055);
}
}
</style>

@ -248,8 +248,12 @@
:table-item="table"
@detail="
(row) => {
$refs['drawer'].setId(row.id);
$refs['drawer'].show();
$router.push({
path: '/assetsDetail',
query: {
id: row.id
}
})
}
"
@editor="
@ -260,6 +264,14 @@
}
"
>
<template #assetsHistory="row">
<Button
size="small"
type="primary"
@click="$refs['assetsHistory'].setAssetId(row.id),$refs['assetsHistory'].show()"
>历史</Button
>
</template>
</xy-table>
<dialoger
@ -280,6 +292,7 @@
ref="imports"
@refresh="$refs['xyTable'].getTableData()"
></imports>
<assetsHistory ref="assetsHistory"></assetsHistory>
</div>
</template>
@ -300,6 +313,7 @@ import LxHeader from "@/components/LxHeader/index.vue";
import headerContent from "@/components/LxHeader/XyContent.vue";
import drawer from "@/views/component/drawer.vue";
import imports from "./imports.vue";
import assetsHistory from "@/views/assets/assetsHistory.vue";
export default {
components: {
LxHeader,
@ -307,6 +321,8 @@ export default {
headerContent,
drawer,
imports,
assetsHistory
},
mixins: [authMixin],
provide: {
@ -411,16 +427,7 @@ export default {
['admins',[]]
])
let { fields, relation } = res;
let fieldRes = (await fieldIndex(
{
page: 1,
page_size: 999,
custom_form_id: this.customForm.customFormId,
sort_name: "sort",
sort_type: "asc",
},
false
)).data;
let fieldRes = fields.sort((a,b) => a.sort - b.sort)
if (
!fields ||
!relation ||
@ -431,27 +438,37 @@ export default {
}
console.log(fieldRes)
fieldRes?.forEach((i, index) => {
i._relations = relation.find((j) => j.local_key === i.field);
if (i.select_item && typeof i.select_item === 'object') {
let keys = Object.keys(i.select_item)
i._params = keys.map(key => {
i._relations = relation.find(
(j) => j.link_table_name.split("_")[1] === i.field
);
if (i.select_item && typeof i.select_item === "object") {
let keys = Object.keys(i.select_item);
i._params = keys.map((key) => {
return {
key,
value: i.select_item[key]
}
})
value: /^\d*$/.test(i.select_item[key])
? Number(i.select_item[key])
: i.select_item[key],
};
});
}
if (i.edit_input === 'file' || i.edit_input === 'files') {
return
}
if (i._relations) {
if (baseTable.get(i._relations.link_table_name)) {
baseTable.get(i._relations.link_table_name)().then(res => i._params = res)
baseTable
.get(i._relations.link_table_name)()
.then((res) => {
i._params = res.data;
});
} else {
i._params = i._relations.parameter_id
? getparameter({ id: i._relations.parameter_id },false).then((res) => {
i._params = res.detail;
})
? getparameter({ id: i._relations.parameter_id }, false).then(
(res) => {
i._params = res.detail;
}
)
: this.index({
table_name: i._relations.link_table_name,
page: 1,
@ -462,32 +479,41 @@ export default {
}
}
});
this.form = fields;
console.log(111, this.form);
this.table = this.form
this.form = fieldRes || [];
this.form
?.filter((i) => i.list_show)
.map((i) => {
.forEach((i) => {
let linkOb = {};
if (i.select_item && typeof i.select_item === 'object') {
let keys = Object.keys(i.select_item)
linkOb.customFn = row => {
let paramMap = new Map()
keys.forEach(key => {
paramMap.set(i.select_item[key],key)
})
if (i.edit_input === "richtext") {
linkOb.customFn = (row) => {
return (
<span>
{ paramMap.get(row[i.field]?.toString()) }
</span>
)
}
<div
style={{ "max-height": "55px","overflow": "scroll" }}
domPropsInnerHTML={row[i.field]}
></div>
);
};
}
if (
i.select_item &&
typeof i.select_item === "object" &&
!(i.select_item instanceof Array)
) {
let keys = Object.keys(i.select_item);
linkOb.customFn = (row) => {
let paramMap = new Map();
keys.forEach((key) => {
paramMap.set(i.select_item[key], key);
});
return <span>{paramMap.get(row[i.field]?.toString())}</span>;
};
}
if (i._relations) {
let { link_relation, foreign_key, link_with_name } = i._relations
if (link_relation === 'newHasOne' || link_relation === 'hasOne') {
linkOb.customFn = row => {
let { link_relation, foreign_key, link_with_name } = i._relations;
if (link_relation === "newHasOne" || link_relation === "hasOne") {
linkOb.customFn = (row) => {
if (i.edit_input === "file") {
return (
<a
@ -500,35 +526,55 @@ export default {
} else {
return (
<span>
{ row[link_with_name]?.name ||
{row[link_with_name]?.name ||
row[link_with_name]?.no ||
row[link_with_name]?.value }
row[link_with_name]?.value}
</span>
);
}
}
};
}
if (link_relation === "hasMany" || link_relation === 'newHasMany') {
if (link_relation === "hasMany" || link_relation === "newHasMany") {
linkOb.customFn = (row) => {
return (
<div>
{row[link_with_name]?.map((o) => (
<span>{o?.name || o?.no || o?.value}</span>
))}
</div>
);
if (i.edit_input === "files") {
return (
<div style="display: flex;flex-direction: column;">
{row[link_with_name]?.map((o) => (
<a>
{ o?.original_name || o?.name }
</a>
))}
</div>
)
} else {
return (
<div>
{row[link_with_name]?.map((o) => (
<p>
{o?.name ||
o?.no ||
o?.value ||
o?.biaoti ||
o?.mingcheng}
</p>
))}
</div>
);
}
};
}
}
return Object.assign(
{
prop: i.field,
label: i.name,
width: i.width,
fixed: i.is_fixed,
},
linkOb
this.table.push(
Object.assign(
{
prop: i.field,
label: i.name,
width: i.width,
fixed: i.is_fixed,
},
linkOb
)
);
});
this.table.unshift({

@ -1,32 +0,0 @@
<template>
<div>
123
<avue-input-map :params="mapparams" placeholder="请选择地图" v-model="mapform"></avue-input-map>
<xyTinymce v-model="content"></xyTinymce>
</div>
</template>
<script>
import AvueMap from 'avue-plugin-map'
import xyTinymce from "@/components/XyTinymce/index.vue";
export default{
components: {
AvueMap,
xyTinymce
},
data(){
return{
mapparams: {
zoom: 11,
},
mapform: [],
content:''
}
},
}
</script>
<style>
</style>

@ -234,7 +234,7 @@ export default {
},
submit() {
this.$store.dispatch("form/submit").then((res) => {
this.$store.dispatch("form/submit",this.custom_form_id).then((res) => {
setTimeout(() => {
update({ id: this.custom_form_id })
.then((res) => {

@ -3,12 +3,28 @@
<!-- 查询配置 -->
<div>
<div ref="lxHeader">
<LxHeader icon="md-apps" text="自定义表单" style="margin-bottom: 10px; border: 0px; margin-top: 15px">
<LxHeader
icon="md-apps"
text="自定义表单"
style="margin-bottom: 10px; border: 0px; margin-top: 15px"
>
<div slot="content"></div>
<slot>
<div>
<Button type="primary" style="margin-left: 10px" @click="$refs['xyTable'].getTableData()"></Button>
<Button type="primary" style="margin-left: 10px" @click="$refs['addForm'].type = 'add',$refs['addForm'].show()">新增</Button>
<Button
type="primary"
style="margin-left: 10px"
@click="$refs['xyTable'].getTableData()"
>查询</Button
>
<Button
type="primary"
style="margin-left: 10px"
@click="
($refs['addForm'].type = 'add'), $refs['addForm'].show()
"
>新增</Button
>
</div>
</slot>
</LxHeader>
@ -22,20 +38,48 @@
:destroy-action="destroy"
:border="true"
:table-item="table"
@editor="row => {
$refs['addForm'].setType('editor');
$refs['addForm'].setId(row.id);
$refs['addForm'].show();
}">
@editor="
(row) => {
$refs['addForm'].setType('editor');
$refs['addForm'].setId(row.id);
$refs['addForm'].show();
}
"
>
<template #setting="scope">
<Button type="primary"
size="small"
style="margin-right: 6px;"
@click="$refs['formEditor'].set(['custom_form_id','custom_form'],[scope.row.id,scope.row]),$refs['formEditor'].show()">字段</Button>
<Button type="primary"
size="small"
style="margin-right: 6px;"
@click="$refs['linkWith'].set(['tableName','copyTable'],[scope.row.table_name,deepCopy(scope.row)]),$refs['linkWith'].show();">关联</Button>
<Button
type="primary"
size="small"
style="margin-right: 6px"
@click="
$refs['formEditor'].set(
['custom_form_id', 'custom_form'],
[scope.row.id, scope.row]
),
$refs['formEditor'].show()
"
>字段</Button
>
<Button
type="primary"
size="small"
style="margin-right: 6px"
@click="
$refs['linkWith'].set(
['tableName', 'copyTable'],
[scope.row.table_name, deepCopy(scope.row)]
),
$refs['linkWith'].show()
"
>关联</Button
>
<Button
type="primary"
size="small"
style="margin-right: 6px"
@click="clone(scope)"
>克隆</Button
>
</template>
</xy-table>
@ -46,7 +90,7 @@
</template>
<script>
import { index,destroy } from '@/api/system/customForm'
import { index, destroy, clone } from "@/api/system/customForm";
import { authMixin } from "@/mixin/authMixin";
import LxHeader from "@/components/LxHeader/index.vue";
@ -55,50 +99,101 @@ import formEditor from "@/views/system/components/formEditor.vue";
import linkWith from "@/views/system/components/linkWith.vue";
import { deepCopy } from "@/utils";
export default {
components:{
LxHeader,addForm,formEditor,linkWith
components: {
LxHeader,
addForm,
formEditor,
linkWith,
},
mixins: [authMixin],
data() {
return {
select:{
page:1,
page_size:10
inputValue: "",
select: {
page: 1,
page_size: 10,
},
list:[],
table:[
list: [],
table: [
{
type: 'index',
label:'编号',
width:100
type: "index",
label: "编号",
width: 100,
},
{
prop:'table_name',
label:'表名',
prop: "table_name",
label: "表名",
//width:180,
sortable:'custom',
sortable: "custom",
},
{
prop:'name',
label:'名称',
// width:200,
sortable:'custom',
prop: "name",
label: "名称",
// width:200,
sortable: "custom",
},
]
}
],
};
},
methods: {
deepCopy,
index,destroy,
index,
destroy,
clone ({ row }) {
const h = this.$createElement;
this.$msgbox({
title: "表克隆",
message: h("div", [
h("span", `克隆表:${row.name}`)
]),
showCancelButton: true,
beforeClose: (action, instance, done) => {
if (action === "confirm") {
instance.confirmButtonLoading = true;
instance.confirmButtonText = "执行中...";
clone({
table_name: row.table_name
}).then(res => {
instance.confirmButtonLoading = false;
done();
this.$refs['xyTable'].getTableData()
this.$message({
type: 'success',
message: '克隆成功'
})
}).catch(err => {
instance.confirmButtonLoading = false;
})
} else {
done();
}
},
}).then((action) => {
});
},
},
computed: {},
mounted() {
}
}
mounted() {},
};
</script>
<style scoped lang="scss">
.form-input {
display: block;
background-color: #fff;
border-radius: 4px;
border: 1px solid #dcdfe6;
color: #606266;
line-height: 2;
transition: all 0.2s;
padding: 0 15px;
margin-top: 10px;
&:hover {
border-color: #c0c4cc;
}
&:focus {
outline: none;
border-color: #0077cc;
}
}
</style>

Loading…
Cancel
Save