master
xy 3 years ago
parent c7c0f49393
commit 5eafcdcbba

@ -49,3 +49,19 @@ export function realTableIndex() {
url: '/api/admin/custom-form/real-table-index' url: '/api/admin/custom-form/real-table-index'
}) })
} }
export function realTableShow(params) {
return request({
method: "get",
url: '/api/admin/custom-form/real-table-show',
params
})
}
export function relationDestroy(params) {
return request({
method: 'get',
url: '/api/admin/custom-form/relation-destroy',
params
})
}

@ -17,7 +17,6 @@ export default {
//() //()
let temp = JSON.parse(JSON.stringify(this.auths)) let temp = JSON.parse(JSON.stringify(this.auths))
if(temp.indexOf('search') !== -1){ if(temp.indexOf('search') !== -1){
console.log(temp.indexOf('search'))
temp.splice(temp.indexOf('search'),1) temp.splice(temp.indexOf('search'),1)
temp.unshift('search') temp.unshift('search')
} }

@ -895,7 +895,7 @@ export default {
</af-table-column> </af-table-column>
); );
})} })}
{$scopedSlots.btns ? $scopedSlots.btns() : this.isCreateAuthBtns()} { this.auths.length > 0 ? this.isCreateAuthBtns() : '' }
</el-table> </el-table>
) : ( ) : (
<el-table ref="table" v-loading={this.loading} height={this.height ?? this.tableHeight} /> <el-table ref="table" v-loading={this.loading} height={this.height ?? this.tableHeight} />

@ -89,6 +89,7 @@ Vue.prototype.$integrateData = (target,value) => {
} }
} }
} }
new Vue({ new Vue({
el: '#app', el: '#app',
router, router,

@ -127,7 +127,6 @@ export function generaMenu(routes, data) {
title: item.name, title: item.name,
id: item.id, id: item.id,
roles: ['admin'], roles: ['admin'],
auths:item.has_auth_node_tags,
params, params,
icon: item.icon icon: item.icon

@ -60,85 +60,89 @@ export default {
: false, : false,
}, },
}, },
[ this.$scopedSlots[i.field]
h( ? this.$scopedSlots[i.field]({ fieldInfo: i, form: this.form })
domMap.get(i.edit_input), : [
{ h(
ref: `elEdit_${i.field}`, domMap.get(i.edit_input),
style: { {
width: "100%", ref: `elEdit_${i.field}`,
}, style: {
props: { width: "100%",
...addPropsMap.get(i.edit_input), },
...this.extraProps(i), props: {
placeholder: i.help, ...addPropsMap.get(i.edit_input),
value: this.form[i.field], ...this.extraProps(i),
}, placeholder: i.help,
attrs: { value: this.form[i.field],
placeholder: i.help || `请填写${i.name}`, },
}, attrs: {
on: { placeholder: i.help || `请填写${i.name}`,
[this.getEventType(i.edit_input)]: (e) => { },
console.log(1111, e); on: {
if (i.field) { [this.getEventType(i.edit_input)]: (e) => {
this.form[i.field] = e; if (i.field) {
this.form = Object.assign({}, this.form); this.form[i.field] = e;
} this.form = Object.assign({}, this.form);
}, }
}, },
scopedSlots: ['visible-change']:_ => i._params.set()
i.edit_input === "file" || i.edit_input === "files" },
? { scopedSlots:
file: (scope) => { i.edit_input === "file" ||
let { file } = scope; i.edit_input === "files"
? {
console.log(111, file); file: (scope) => {
return [ let { file } = scope;
h("div", {}, [ return [
h("i", { h("div", {}, [
class: { h("i", {
"el-icon-circle-check": class: {
file.status === "success", "el-icon-circle-check":
"el-icon-loading": file.status === "success",
file.status === "uploading", "el-icon-loading":
}, file.status === "uploading",
style: { },
"color": file.status === "success" ? "green" : "" style: {
} color:
}), file.status === "success"
h( ? "green"
"a", : "",
{ },
attrs: { }),
href: file.url, h(
download: file.name, "a",
}, {
class: { attrs: {
"uploaded-a": href: file.url,
file.status === "success", download: file.name,
} },
}, class: {
file.name "uploaded-a":
) file.status === "success",
]), },
h("i", { },
class: "el-icon-close", file.name
on: {
["click"]: () =>
this.fileRemoveHandler(
file,
i.field
), ),
}, ]),
}), h("i", {
]; class: "el-icon-close",
}, on: {
} ["click"]: () =>
: "", this.fileRemoveHandler(
}, file,
this.optionsRender(h, i) i.field
), ),
] },
}),
];
},
}
: "",
},
this.optionsRender(h, i)
),
]
) )
); );
} }
@ -202,7 +206,7 @@ export default {
}, },
//on //on
getEventType(info) { getEventType(info) {
if (info.type === "checkbox") { if (info === "checkbox") {
return "change"; return "change";
} }
return "input"; return "input";
@ -211,12 +215,12 @@ export default {
// //
optionsRender(h, info) { optionsRender(h, info) {
if (info.edit_input === "checkbox" || info.edit_input === "radio") { if (info.edit_input === "checkbox" || info.edit_input === "radio") {
return info._paramters && info._paramters instanceof Array return info._params.get() && info._params.get() instanceof Array
? info._paramters.map((i) => ? info._params.get().map((i) =>
h("el-option", { h("el-option", {
props: { props: {
label: i.name || i.no || i.value || i.id, label: i.name || i.no || i.value || i.id,
value: i.id, value: i[info._relations.foreign_key],
}, },
}) })
) )
@ -287,13 +291,13 @@ export default {
this.file[info.field] = fileList; this.file[info.field] = fileList;
}; };
props.onError = (err,file,fileList) => { props.onError = (err, file, fileList) => {
this.file[info.field] = fileList; this.file[info.field] = fileList;
this.$message({ this.$message({
type: "warning", type: "warning",
message: err message: err,
}) });
} };
} }
return props; return props;
}, },

@ -3,42 +3,100 @@
<!-- 查询配置 --> <!-- 查询配置 -->
<div> <div>
<div ref="lxHeader"> <div ref="lxHeader">
<LxHeader icon="md-apps" :text="title || customForm.tableName" style="margin-bottom: 10px; border: 0px; margin-top: 15px"> <LxHeader
icon="md-apps"
:text="title || customForm.tableName"
style="margin-bottom: 10px; border: 0px; margin-top: 15px"
>
<div slot="content"></div> <div slot="content"></div>
<slot> <slot>
<header-content :auths="auths_auth_mixin"> <header-content :auths="auths_auth_mixin">
<template #search> <template #search>
<div style="display: flex"> <div style="display: flex">
<Select v-model="select.filter[0].key" style="width: 100px;" placeholder="搜索条目"> <Select
<Option v-for="item in form" :key="item.id" :value="item.field">{{ item.name }}</Option> v-model="select.filter[0].key"
style="width: 100px"
placeholder="搜索条目"
>
<Option
v-for="item in form"
:key="item.id"
:value="item.field"
>{{ item.name }}</Option
>
</Select> </Select>
<Select v-model="select.filter[0].op" style="width: 100px;margin-left: 10px;" placeholder="搜索条件"> <Select
<Option v-for="item in op" :key="item.value" :value="item.value">{{ item.label }}</Option> v-model="select.filter[0].op"
style="width: 100px; margin-left: 10px"
placeholder="搜索条件"
>
<Option
v-for="item in op"
:key="item.value"
:value="item.value"
>{{ item.label }}</Option
>
</Select> </Select>
<template v-if="select.filter[0].op !== 'range' && !columnArrTest(select.filter[0].key)"> <template
<Input v-model="select.filter[0].value" style="width: 150px;margin-left: 10px;" placeholder="请填写关键词"/> v-if="
select.filter[0].op !== 'range' &&
!columnArrTest(select.filter[0].key)
"
>
<Input
v-model="select.filter[0].value"
style="width: 150px; margin-left: 10px"
placeholder="请填写关键词"
/>
</template> </template>
<template v-else-if="select.filter[0].op !== 'range' && columnArrTest(select.filter[0].key)"> <template
<Select v-model="select.filter[0].value" style="width: 150px;margin-left: 10px;" placeholder="请选择关键词"> v-else-if="
<Option v-for="item in getColumnParams(select.filter[0].key)" :key="item.id" :value="item.id">{{ item.value || item.name || item.no || item.id }}</Option> select.filter[0].op !== 'range' &&
columnArrTest(select.filter[0].key)
"
>
<Select
v-model="select.filter[0].value"
style="width: 150px; margin-left: 10px"
placeholder="请选择关键词"
>
<Option
v-for="item in getColumnParams(select.filter[0].key)"
:key="item.id"
:value="item.id"
>{{
item.value || item.name || item.no || item.id
}}</Option
>
</Select> </Select>
</template> </template>
<template v-else> <template v-else>
<Input :value="select.filter[0].value.split(',')[0]" <Input
style="width: 150px;margin-left: 10px;" :value="select.filter[0].value.split(',')[0]"
placeholder="范围开始关键词" style="width: 150px; margin-left: 10px"
@input="(e)=>inputStartHandler(e,select.filter[0])"/> placeholder="范围开始关键词"
<span style="margin-left: 10px;display: flex;align-items: center;"></span> @input="(e) => inputStartHandler(e, select.filter[0])"
<Input :value="select.filter[0].value.split(',')[1]" />
style="width: 150px;margin-left: 10px;" <span
placeholder="范围结束关键词" style="
@input="(e)=>inputEndHandler(e,select.filter[0])"/> margin-left: 10px;
display: flex;
align-items: center;
"
></span
>
<Input
:value="select.filter[0].value.split(',')[1]"
style="width: 150px; margin-left: 10px"
placeholder="范围结束关键词"
@input="(e) => inputEndHandler(e, select.filter[0])"
/>
</template> </template>
<Button <Button
style="margin-left: 10px" style="margin-left: 10px"
type="primary" type="primary"
@click="$refs['xyTable'].getTableData(true)" @click="$refs['xyTable'].getTableData(true)"
>查询</Button >查询</Button
> >
<xy-selectors <xy-selectors
@ -48,38 +106,103 @@
> >
<template> <template>
<div class="select"> <div class="select">
<div class="select__item" v-for="(item,index) in select.filter" :key="`${item.value}-${index}`"> <div
<p>条件{{index+1}}</p> class="select__item"
<Select v-model="item.key" style="width: 100px;" placeholder="搜索条目"> v-for="(item, index) in select.filter"
<Option v-for="item in form" :key="item.id" :value="item.field">{{ item.name }}</Option> :key="`${item.value}-${index}`"
>
<p>条件{{ index + 1 }}</p>
<Select
v-model="item.key"
style="width: 100px"
placeholder="搜索条目"
>
<Option
v-for="item in form"
:key="item.id"
:value="item.field"
>{{ item.name }}</Option
>
</Select> </Select>
<Select v-model="item.op" style="width: 100px;margin-left: 10px;" placeholder="搜索条件"> <Select
<Option v-for="item in op" :key="item.value" :value="item.value">{{ item.label }}</Option> v-model="item.op"
style="width: 100px; margin-left: 10px"
placeholder="搜索条件"
>
<Option
v-for="item in op"
:key="item.value"
:value="item.value"
>{{ item.label }}</Option
>
</Select> </Select>
<template v-if="item.op !== 'range' && !columnArrTest(item.key)"> <template
<Input v-model="item.value" style="width: 150px;margin-left: 10px;" placeholder="请填写关键词"/> v-if="
item.op !== 'range' && !columnArrTest(item.key)
"
>
<Input
v-model="item.value"
style="width: 150px; margin-left: 10px"
placeholder="请填写关键词"
/>
</template> </template>
<template v-else-if="item.op !== 'range' && columnArrTest(item.key)"> <template
<Select v-model="item.value" style="width: 150px;margin-left: 10px;" placeholder="请选择关键词"> v-else-if="
<Option v-for="item in getColumnParams(item.key)" :key="item.id" :value="item.id">{{ item.value || item.name || item.no || item.id }}</Option> item.op !== 'range' && columnArrTest(item.key)
"
>
<Select
v-model="item.value"
style="width: 150px; margin-left: 10px"
placeholder="请选择关键词"
>
<Option
v-for="item in getColumnParams(item.key)"
:key="item.id"
:value="item.id"
>{{
item.value || item.name || item.no || item.id
}}</Option
>
</Select> </Select>
</template> </template>
<template v-else> <template v-else>
<Input :value="item.value.split(',')[0]" <Input
style="width: 150px;margin-left: 10px;" :value="item.value.split(',')[0]"
placeholder="范围开始关键词" style="width: 150px; margin-left: 10px"
@input="(e)=>inputStartHandler(e,item)"/> placeholder="范围开始关键词"
<span style="margin-left: 10px;"></span> @input="(e) => inputStartHandler(e, item)"
<Input :value="item.value.split(',')[1]" />
style="width: 150px;margin-left: 10px;" <span style="margin-left: 10px"></span>
placeholder="范围结束关键词" <Input
@input="(e)=>inputEndHandler(e,item)"/> :value="item.value.split(',')[1]"
style="width: 150px; margin-left: 10px"
placeholder="范围结束关键词"
@input="(e) => inputEndHandler(e, item)"
/>
</template> </template>
<el-button v-if="index !== 0" size="small" type="danger" icon="el-icon-delete" circle style="margin-left: 10px;" @click="select.filter.splice(index,1)"></el-button> <el-button
v-if="index !== 0"
size="small"
type="danger"
icon="el-icon-delete"
circle
style="margin-left: 10px"
@click="select.filter.splice(index, 1)"
></el-button>
</div> </div>
</div> </div>
<div class="add-btn"> <div class="add-btn">
<el-button size="small" type="primary" icon="el-icon-plus" circle @click="select.filter.push({key: '',op: '',value: ''})"></el-button> <el-button
size="small"
type="primary"
icon="el-icon-plus"
circle
@click="
select.filter.push({ key: '', op: '', value: '' })
"
></el-button>
<span>新增一条</span> <span>新增一条</span>
</div> </div>
</template> </template>
@ -89,22 +212,22 @@
<template #create> <template #create>
<Button <Button
type="primary" type="primary"
@click="$refs['dialog'].setType('add'),$refs['dialog'].show()" @click="
>新增</Button $refs['dialog'].setType('add'), $refs['dialog'].show()
"
>新增</Button
> >
</template> </template>
<template #import> <template #import>
<Button <Button type="primary" @click="$refs['imports'].show()"
type="primary" >导入</Button
@click="$refs['imports'].show()"
>导入</Button
> >
</template> </template>
<template #export> <template #export>
<Button <Button
type="primary" type="primary"
@click="exportExcel(new Date().getTime().toString())" @click="exportExcel(new Date().getTime().toString())"
>导出</Button >导出</Button
> >
</template> </template>
</header-content> </header-content>
@ -120,30 +243,50 @@
ref="xyTable" ref="xyTable"
:border="true" :border="true"
:action="index" :action="index"
:req-opt="Object.assign(select,selectForm)" :req-opt="select"
:destroy-req-opt="select" :destroy-req-opt="select"
:table-item="table" :table-item="table"
@detail="row => { @detail="
$refs['drawer'].setId(row.id); (row) => {
$refs['drawer'].show(); $refs['drawer'].setId(row.id);
}" $refs['drawer'].show();
@editor="row => { }
$refs['dialog'].setId(row.id); "
$refs['dialog'].setType('editor'); @editor="
$refs['dialog'].show(); (row) => {
}"> $refs['dialog'].setId(row.id);
$refs['dialog'].setType('editor');
$refs['dialog'].show();
}
"
>
</xy-table> </xy-table>
<dialoger :table-name="customForm.tableName" :form-info="form" ref="dialog" @refresh="$refs['xyTable'].getTableData()"></dialoger> <dialoger
<drawer :table-name="customForm.tableName" :form-info="form" ref="drawer"></drawer> :table-name="customForm.tableName"
<imports :table-name="customForm.tableName" :form-info="form" ref="imports" @refresh="$refs['xyTable'].getTableData()"></imports> :form-info="form"
ref="dialog"
@refresh="$refs['xyTable'].getTableData()"
>
</dialoger>
<drawer
:table-name="customForm.tableName"
:form-info="form"
ref="drawer"
></drawer>
<imports
:table-name="customForm.tableName"
:form-info="form"
ref="imports"
@refresh="$refs['xyTable'].getTableData()"
></imports>
</div> </div>
</template> </template>
<script> <script>
import { index as fieldIndex } from "@/api/system/customFormField"; import { index as fieldIndex } from "@/api/system/customFormField";
import { authMixin } from "@/mixin/authMixin"; import { authMixin } from "@/mixin/authMixin";
import { index,destroy } from "@/api/system/baseForm"; import { index, destroy } from "@/api/system/baseForm";
import { op } from "@/const/op"; import { op } from "@/const/op";
import { download } from "@/utils/downloadRequest"; import { download } from "@/utils/downloadRequest";
import { getparameter } from "@/api/system/dictionary"; import { getparameter } from "@/api/system/dictionary";
@ -151,20 +294,23 @@ import { show } from "@/api/system/customForm";
import * as XLSX from "xlsx"; import * as XLSX from "xlsx";
import { saveAs } from "file-saver"; import { saveAs } from "file-saver";
import dialoger from './dialog.vue'; import dialoger from "./dialog.vue";
import LxHeader from "@/components/LxHeader/index.vue"; import LxHeader from "@/components/LxHeader/index.vue";
import headerContent from "@/components/LxHeader/XyContent.vue"; import headerContent from "@/components/LxHeader/XyContent.vue";
import drawer from "@/views/component/drawer.vue"; import drawer from "@/views/component/drawer.vue";
import imports from "./imports.vue" import imports from "./imports.vue";
export default { export default {
components:{ components: {
LxHeader, LxHeader,
dialoger, dialoger,
headerContent, headerContent,
drawer, drawer,
imports imports,
}, },
mixins: [authMixin], mixins: [authMixin],
provide: {
formStore: () => this.form,
},
data() { data() {
return { return {
title: "", title: "",
@ -175,183 +321,237 @@ export default {
{ {
key: "", key: "",
op: "", op: "",
value: "" value: "",
} },
] ],
}, },
selectForm: [],
form: [], form: [],
table: [], table: [],
customForm: { customForm: {
customFormId: "", customFormId: "",
tableName: "" tableName: "",
} },
} };
}, },
methods: { methods: {
index,destroy,download, index,
destroy,
download,
reset() { reset() {
this.select.filter.splice(1) this.select.filter.splice(1);
this.select.filter[0] = { this.select.filter[0] = {
key: "", key: "",
op: "", op: "",
value: "" value: "",
} };
}, },
async exportExcel(sheetName) { async exportExcel(sheetName) {
const res = await index(Object.assign(this.select,{ page: 1,page_size: 9999})) const res = await index(
if(res.data){ Object.assign(this.select, { page: 1, page_size: 9999 })
let headers = this.form.map(i => { );
if (res.data) {
let headers = this.form.map((i) => {
return { return {
key: i.field, key: i.field,
title: i.name title: i.name,
} };
}) });
const data = res.data.map(row => headers.map(header => row[header.key])); const data = res.data.map((row) =>
data.unshift(headers.map(header => header.title)); headers.map((header) => row[header.key])
);
data.unshift(headers.map((header) => header.title));
const wb = XLSX.utils.book_new(); const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet(data); const ws = XLSX.utils.aoa_to_sheet(data);
XLSX.utils.book_append_sheet(wb, ws, sheetName); XLSX.utils.book_append_sheet(wb, ws, sheetName);
const wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' }); const wbout = XLSX.write(wb, {
saveAs(new Blob([wbout], { type: 'application/octet-stream' }), `${sheetName}.xlsx`); bookType: "xlsx",
bookSST: true,
type: "array",
});
saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
`${sheetName}.xlsx`
);
} }
}, },
//target //target
inputStartHandler(e,target) { inputStartHandler(e, target) {
let temp = target?.value.split(',')[1] let temp = target?.value.split(",")[1];
target.value = `${e},${temp ? temp : ""}` target.value = `${e},${temp ? temp : ""}`;
}, },
inputEndHandler(e,target) { inputEndHandler(e, target) {
let temp = target?.value.split(',')[0] let temp = target?.value.split(",")[0];
target.value = `${temp ? temp : ""},${e}` target.value = `${temp ? temp : ""},${e}`;
}, },
async getFormDetail() { async getFormDetail() {
const res = await show({ id: this.customForm.customFormId },false) if (this.$route.meta.params?.custom_form) {
this.title = res.name let decode = decodeURIComponent(this.$route.meta.params?.custom_form);
},
async getField() {
if(this.$route.meta.params?.custom_form) {
let decode = decodeURIComponent(this.$route.meta.params?.custom_form)
try { try {
let custom_form = JSON.parse(decode) let custom_form = JSON.parse(decode);
this.customForm.customFormId = custom_form.custom_form_id this.customForm.customFormId = custom_form.custom_form_id;
this.customForm.tableName = custom_form.table_name this.customForm.tableName = custom_form.table_name;
this.select.table_name = custom_form.table_name this.select.table_name = custom_form.table_name;
}catch (err) { } catch (err) {
console.warn(err) console.warn(err);
} }
} }
const res = await fieldIndex({ const res = await show({ id: this.customForm.customFormId }, false);
page: 1, this.title = res.name;
page_size: 999,
custom_form_id: this.customForm.customFormId, //
sort_name: 'sort', let { fields, relation } = res;
sort_type: 'asc', if (
}) !fields ||
if(res.data && res.data instanceof Array) { !relation ||
res.data.forEach(i => { !fields instanceof Array ||
if (i.field) { !relation instanceof Array
if ( ) {
(i.edit_input === "checkbox" || i.edit_input === "radio" || i.edit_input === "select") && throw new Error("fields或relation格式错误");
i.parameter_id
) {
getparameter({ id: i.parameter_id }).then((res) => {
i._paramters = res.detail ?? [];
});
}
if (
(i.edit_input === "checkbox" || i.edit_input === "radio" || i.edit_input === "select") &&
i.link_table_name
) {
index({
page: 1,
page_size: 999,
table_name: i.link_table_name,
}).then((res) => {
i._paramters = res.data ?? [];
});
}
}
})
} }
this.form = res.data fields.forEach((i, index) => {
this.selectForm = '' i._relations = relation.find((j) => j.local_key === i.field);
this.table = res.data.map(i => { i._params = {
let linkOb = {} value: [],
load: false,
get: () => i._params.value,
set: () => {
if(i._params.load) return
i._relations.parameter_id
? getparameter({ id: i._relations.parameter_id },false).then((res) => {
i._params.value = res.detail;
})
: this.index({
table_name: i._relations.link_table_name,
page: 1,
page_size: 9999,
}).then((res) => {
i._params.value = res.data;
});
i._params.load = true
},
};
});
this.form = fields;
console.log(111, this.form);
// if(res.fields && res.fields instanceof Array) {
// res.fields.forEach(i => {
// if (i.field) {
// if (
// (i.edit_input === "checkbox" || i.edit_input === "radio" || i.edit_input === "select") &&
// i.parameter_id
// ) {
// getparameter({ id: i.parameter_id }).then((res) => {
// i._paramters = res.detail ?? [];
// });
// }
// if (
// (i.edit_input === "checkbox" || i.edit_input === "radio" || i.edit_input === "select") &&
// i.link_table_name
// ) {
// index({
// page: 1,
// page_size: 999,
// table_name: i.link_table_name,
// }).then((res) => {
// i._paramters = res.data ?? [];
// });
// }
// }
// })
// }
// this.form = res.fields
this.table = res.fields
?.filter((i) => i.list_show)
.map((i) => {
let linkOb = {};
if(i.parameter_id) { if (i.parameter_id) {
linkOb.customFn = row => { linkOb.customFn = (row) => {
return ( return <span>{row[i.link_with_name]?.value}</span>;
<span>{ row[i.link_with_name]?.value }</span> };
)
} }
} if (i.link_table_name) {
if(i.link_table_name) { if (i.link_relation === "hasOne") {
if(i.link_relation === 'hasOne') { linkOb.customFn = (row) => {
linkOb.customFn = row => { if (i.edit_input === "file") {
if(i.edit_input === 'file') { return (
return ( <a
<a download={row[i.link_with_name]?.original_name} href={ row[i.link_with_name]?.url }>{ row[i.link_with_name]?.original_name }</a> download={row[i.link_with_name]?.original_name}
) href={row[i.link_with_name]?.url}
}else{ >
return ( {row[i.link_with_name]?.original_name}
<span>{ row[i.link_with_name]?.name || row[i.link_with_name]?.no || row[i.link_with_name]?.value }</span> </a>
) );
} } else {
return (
<span>
{row[i.link_with_name]?.name ||
row[i.link_with_name]?.no ||
row[i.link_with_name]?.value}
</span>
);
}
};
} }
} if (i.link_relation === "hasMany") {
if(i.link_relation === 'hasMany') { linkOb.customFn = (row) => {
linkOb.customFn = row => { return (
return ( <div>
<div> {row[i.link_with_name]?.map((o) => (
{ row[i.link_with_name]?.map(o => (<span>{ o?.name || o?.no || o?.value }</span>)) } <span>{o?.name || o?.no || o?.value}</span>
</div> ))}
) </div>
);
};
} }
} }
} return Object.assign(
return Object.assign({ {
prop: i.field, prop: i.field,
label: i.name, label: i.name,
width: i.width, width: i.width,
fixed: i.is_fixed fixed: i.is_fixed,
},linkOb) },
}) linkOb
);
});
this.table.unshift({ this.table.unshift({
type: 'index', type: "index",
width: 60, width: 60,
label: '序号' label: "序号",
}) });
} },
}, },
computed: { computed: {
columnArrTest() { columnArrTest() {
return function (field) { return function (field) {
return this.form.find(i => i.field === field) ? this.form.find(i => i.field === field).search_input === 'checkbox' : false return this.form.find((i) => i.field === field)
} ? this.form.find((i) => i.field === field).search_input === "checkbox"
: false;
};
}, },
getColumnParams() { getColumnParams() {
return function (field) { return function (field) {
return this.form.find(i => i.field === field) ? this.form.find(i => i.field === field)._paramters : [] return this.form.find((i) => i.field === field)
} ? this.form.find((i) => i.field === field)._paramters
: [];
};
}, },
}, },
created() { created() {
this.getField() this.getFormDetail();
this.getFormDetail() },
} };
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.select { .select {
&__item { &__item {
& > p { & > p {
display: inline-block; display: inline-block;
width: 80px; width: 80px;
@ -370,7 +570,6 @@ export default {
margin-top: 10px; margin-top: 10px;
& > span { & > span {
padding: 0 10px; padding: 0 10px;
} }
} }

@ -17,84 +17,6 @@
<el-form-item required prop="field" label="字段标识"> <el-form-item required prop="field" label="字段标识">
<el-input v-model="selectedForm.field"></el-input> <el-input v-model="selectedForm.field"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="关联方式">
<el-select
v-model="linkType"
clearable
:popper-append-to-body="false"
placeholder="请选择关联方式"
style="width: 100%"
>
<el-option
v-for="(item, index) in ['关联表', '数据字典']"
:key="index"
:label="item"
:value="item"
></el-option>
</el-select>
</el-form-item>
<el-form-item
prop="parameter_id"
label="数据字典"
v-show="linkType === '数据字典'"
>
<el-select
v-model="selectedForm.parameter_id"
clearable
:popper-append-to-body="false"
placeholder="请选择数据字典"
style="width: 100%"
>
<el-option
v-for="item in parameters"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item
prop="link_table_name"
label="关联表"
v-show="linkType === '关联表'"
>
<el-select
v-model="selectedForm.link_table_name"
clearable
:popper-append-to-body="false"
placeholder="请选择关联表"
style="width: 100%"
>
<el-option
v-for="item in forms"
:key="item.id"
:label="item.name"
:value="item.table_name"
></el-option>
</el-select>
</el-form-item>
<el-form-item
prop="link_relation"
label="关联类型"
v-show="linkType === '关联表' || linkType === '数据字典'"
>
<el-select
v-model="selectedForm.link_relation"
:popper-append-to-body="false"
placeholder="请选择关联类型"
style="width: 100%"
>
<el-option
v-for="item in [
{ value: 'hasOne', label: '一对一' },
{ value: 'hasMany', label: '一对多' },
]"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item prop="help" label="帮助文字"> <el-form-item prop="help" label="帮助文字">
<el-input <el-input
v-model="selectedForm.help" v-model="selectedForm.help"
@ -119,13 +41,20 @@
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="是否显示" prop="list_show"> <el-form-item label="列表是否显示" prop="list_show">
<el-switch <el-switch
v-model="selectedForm.list_show" v-model="selectedForm.list_show"
:active-value="1" :active-value="1"
:inactive-value="0" :inactive-value="0"
></el-switch> ></el-switch>
</el-form-item> </el-form-item>
<el-form-item label="表单是否显示" prop="list_show">
<el-switch
v-model="selectedForm.form_show"
:active-value="1"
:inactive-value="0"
></el-switch>
</el-form-item>
<el-form-item label="是否固定" prop="is_fix"> <el-form-item label="是否固定" prop="is_fix">
<el-select <el-select
v-model="selectedForm.is_fix" v-model="selectedForm.is_fix"
@ -257,10 +186,7 @@ export default {
const res = await formIndex({ page: 1, page_size: 999 }); const res = await formIndex({ page: 1, page_size: 999 });
this.forms = [...res.data,...resReal.map(i => { return { name: i,table_name: i } })]; this.forms = [...res.data,...resReal.map(i => { return { name: i,table_name: i } })];
}, },
async getParameters() {
const res = await listparameter({ page: 1, page_size: 999 });
this.parameters = res.data;
},
saveField() { saveField() {
this.$store.commit("form/SPLICE_FORM_LIST", { this.$store.commit("form/SPLICE_FORM_LIST", {
@ -275,20 +201,8 @@ export default {
computed: { computed: {
...mapState("form", ["selectedForm", "formList", "selectedIndex"]), ...mapState("form", ["selectedForm", "formList", "selectedIndex"]),
}, },
watch: {
selectedForm(newVal) {
if (newVal?.parameter_id) {
this.linkType = "数据字典";
} else if (newVal?.link_table_name) {
this.linkType = "关联表";
} else {
this.linkType = "";
}
},
},
created() { created() {
this.getForms(); this.getForms();
this.getParameters();
this.debouncedInputHandler = debounce((e) => { this.debouncedInputHandler = debounce((e) => {
if (e) { if (e) {

@ -203,8 +203,7 @@ export default {
validation: "", validation: "",
select_item: "", select_item: "",
list_show: 1, list_show: 1,
link_table_name: "", form_show: 1,
link_relation: "",
is_fix: "", is_fix: "",
width: "" width: ""
}; };

@ -41,14 +41,28 @@ export default {
} }
}, },
}, },
computed: {}, computed: {
hiddenClass() {
let classArr = []
if(!this.config.list_show && this.config.form_show) {
classArr.push('no-list-show')
}
if(!this.config.form_show && this.config.list_show) {
classArr.push('no-form-show')
}
if(!this.config.list_show && !this.config.form_show) {
classArr.push('no-all-show')
}
return classArr;
}
},
render(h) { render(h) {
return h( return h(
"div", "div",
{ {
class: this.config.list_show ? "" : "no-list-show", class: this.hiddenClass,
style: { style: {
opacity: this.config.list_show ? 1 : 0.5, opacity: (this.config.list_show && this.config.form_show) ? 1 : 0.5,
filter: filter:
this.index === this.$store.state.form.selectedIndex this.index === this.$store.state.form.selectedIndex
? "drop-shadow(0 0 2px #0077CCFF) drop-shadow(0 0 8px #449FD9FF)" ? "drop-shadow(0 0 2px #0077CCFF) drop-shadow(0 0 8px #449FD9FF)"
@ -72,7 +86,29 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.no-list-show { .no-list-show {
&::after { &::after {
content: "隐藏"; content: "列表隐藏";
color: red;
font-size: 12px;
position: absolute;
right: 10px;
top: 0;
}
}
.no-form-show {
&::after {
content: "表单隐藏";
color: red;
font-size: 12px;
position: absolute;
right: 10px;
top: 0;
}
}
.no-all-show {
&::after {
content: "表单、列表隐藏";
color: red; color: red;
font-size: 12px; font-size: 12px;

@ -0,0 +1,318 @@
<template>
<div>
<el-dialog title="关联" :visible.sync="dialogVisible" width="66%">
<template>
<el-button size="small" type="primary" icon="el-icon-plus" @click="list.push({ link_table_name: '',local_key: '',foreign_key: '',link_relation: '' })"></el-button>
<xy-table
style="margin-top: 10px;"
:auths="[]"
size="small"
:is-page="false"
:list="list"
:table-item="table"
>
</xy-table>
</template>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="dialogVisible = false"
> </el-button
>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import { realTableShow, realTableIndex, save, show, relationDestroy } from "@/api/system/customForm";
import {listparameter} from "@/api/system/dictionary";
export default {
data() {
return {
id: '',
copyTable: {},
dialogVisible: false,
tableName: "",
localFields: {},
realTables: [],
foreignFields: [],
parameters: [], //
list: [],
table: [
{
prop: "local_key",
label: "关联本地字段",
customFn: (row) => {
return (
<el-select size="mini"
value={ row.local_key }
on={{
['change']:e => {
row.local_key = e
}
}}>
{
this.localFields.map(i => {
return (
<el-option value={ i.field } label={ i.name }></el-option>
)
})
}
</el-select>
);
},
},
{
prop: 'link_table',
label: '关联表',
customFn: (row) => {
return (
<el-select size="mini"
clearable={true}
value={row.link_table_name}
on={{
['change']:async e => {
if(row.parameter_id) {
this.$message({
type: 'warning',
message: `${row.local_key || ''}已选择关联数据字典`
})
return
}
row.link_table_name = e
if (e) {
this.foreignFields = await this.getFields(e)
}
}
}}>
{
this.realTables.map(i => {
return (
<el-option value={i} label={i}></el-option>
)
})
}
</el-select>
);
},
},
{
prop: 'parameter_id',
label: '关联数据字典',
customFn: (row) => {
return (
<el-select size="mini"
clearable={true}
value={row.parameter_id}
on={{
['change']:async e => {
if(row.link_table_name) {
this.$message({
type: 'warning',
message: `${row.local_key || ''}已选择关联表`
})
return
}
row.parameter_id = e
if (e) {
this.foreignFields = await this.getFields('parameters')
}
}
}}>
{
this.parameters.map(i => {
return (
<el-option value={i.id} label={i.name}></el-option>
)
})
}
</el-select>
);
},
},
{
prop: "foreign_key",
label: "关联表字段",
customFn: (row) => {
return (
<el-select size="mini"
value={row.foreign_key}
on={{
['change']:e => {
row.foreign_key = e
}
}}>
{(() => {
let dom = [];
for (let key in this.foreignFields) {
dom.push(<el-option label={key} value={key}></el-option>);
}
return dom;
})()}
</el-select>
);
},
},
{
prop: 'link_relation',
label: '关联方式',
customFn: (row) => {
return (
<el-select size="mini"
value={row.link_relation}
on={{
['change']:e => {
row.link_relation = e
}
}}>
{
[
{ value: 'newHasOne', label: '一对一' },
{ value: 'newHasMany', label: '一对多' },
].map(i => {
return (
<el-option value={i.value} label={i.label}></el-option>
)
})
}
</el-select>
);
},
},
{
prop: 'operate',
label: '操作',
align: 'left',
customFn:(row, scope) => {
return [(
<el-button type='primary'
size="mini"
style={{
'margin-right': '6px'
}}
on={{
['click']:e => {
console.log(row)
this.copyTable.relation = [row]
save(this.copyTable).then(res => {
this.getDetail()
})
}
}}> </el-button>
),(
<el-popover width="180"
trigger="hover"
scopedSlots={{
"default": () => {
return (
<div>
<p style={{'padding-bottom':'10px'}}>确定要删除吗</p>
<div style={{"text-align":"right","margin":"0"}}>
<el-button size="mini"
type="text"
on={{
['click']:e => {
}
}}>取消</el-button>
<el-button type="primary"
size="mini"
on={{
['click']:() => {
if(row.id){
relationDestroy({ id: row.id }).then(res => {
this.getDetail()
})
} else {
this.list.splice(scope.$index, 1)
}
}
}}>确定</el-button>
</div>
</div>
)
},
"reference":() => {
return (
<el-button
type="danger"
size="mini"
>
删除
</el-button>
)
}
}}>
</el-popover>
)]
}
}
],
};
},
methods: {
show() {
this.dialogVisible = true;
},
hide() {
this.dialogVisible = false;
},
set(key = [], value = []) {
if (key instanceof Array) {
key.forEach((key, index) => {
this[key] = value[index] ?? "";
});
}
if (typeof key === "string") {
this[key] = value;
}
},
async getParameters() {
const res = await listparameter({ page: 1, page_size: 999 });
this.parameters = res.data;
},
async getFields(tableName) {
const res = await realTableShow({ table_name: tableName });
console.log(res);
return res || {};
},
async getRealTables() {
const res = await realTableIndex();
this.realTables = res;
},
async getDetail() {
const res = await show({ id: this.copyTable?.id })
this.localFields = res.fields || []
this.list = res.relation.map(i => {
return i
})
},
submit(scope) {
console.log(scope)
}
},
computed: {},
watch: {
async dialogVisible(newVal) {
if (newVal) {
//this.localFields = await this.getFields(this.tableName);
await this.getDetail();
}
},
},
created() {
this.getParameters();
this.getRealTables();
},
};
</script>
<style scoped lang="scss"></style>

@ -30,13 +30,18 @@
<template #setting="scope"> <template #setting="scope">
<Button type="primary" <Button type="primary"
size="small" size="small"
style="margin-right: 6px;"
@click="$refs['formEditor'].set(['custom_form_id','custom_form'],[scope.row.id,scope.row]),$refs['formEditor'].show()">字段</Button> @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>
</template> </template>
</xy-table> </xy-table>
<addForm ref="addForm" @refresh="$refs['xyTable'].getTableData()"></addForm> <addForm ref="addForm" @refresh="$refs['xyTable'].getTableData()"></addForm>
<formEditor ref="formEditor"></formEditor> <formEditor ref="formEditor"></formEditor>
<linkWith ref="linkWith"></linkWith>
</div> </div>
</template> </template>
@ -47,9 +52,11 @@ import { authMixin } from "@/mixin/authMixin";
import LxHeader from "@/components/LxHeader/index.vue"; import LxHeader from "@/components/LxHeader/index.vue";
import addForm from "./components/addForm.vue"; import addForm from "./components/addForm.vue";
import formEditor from "@/views/system/components/formEditor.vue"; import formEditor from "@/views/system/components/formEditor.vue";
import linkWith from "@/views/system/components/linkWith.vue";
import { deepCopy } from "@/utils";
export default { export default {
components:{ components:{
LxHeader,addForm,formEditor LxHeader,addForm,formEditor,linkWith
}, },
mixins: [authMixin], mixins: [authMixin],
@ -82,6 +89,7 @@ export default {
} }
}, },
methods: { methods: {
deepCopy,
index,destroy, index,destroy,
}, },

Loading…
Cancel
Save