master
xy 3 years ago
parent c7c0f49393
commit 5eafcdcbba

@ -49,3 +49,19 @@ export function realTableIndex() {
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))
if(temp.indexOf('search') !== -1){
console.log(temp.indexOf('search'))
temp.splice(temp.indexOf('search'),1)
temp.unshift('search')
}

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

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

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

@ -60,85 +60,89 @@ export default {
: false,
},
},
[
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) => {
console.log(1111, 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;
console.log(111, file);
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",
}
},
file.name
)
]),
h("i", {
class: "el-icon-close",
on: {
["click"]: () =>
this.fileRemoveHandler(
file,
i.field
this.$scopedSlots[i.field]
? this.$scopedSlots[i.field]({ fieldInfo: i, form: this.form })
: [
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);
}
},
['visible-change']:_ => i._params.set()
},
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",
},
},
file.name
),
},
}),
];
},
}
: "",
},
this.optionsRender(h, i)
),
]
]),
h("i", {
class: "el-icon-close",
on: {
["click"]: () =>
this.fileRemoveHandler(
file,
i.field
),
},
}),
];
},
}
: "",
},
this.optionsRender(h, i)
),
]
)
);
}
@ -202,7 +206,7 @@ export default {
},
//on
getEventType(info) {
if (info.type === "checkbox") {
if (info === "checkbox") {
return "change";
}
return "input";
@ -211,12 +215,12 @@ export default {
//
optionsRender(h, info) {
if (info.edit_input === "checkbox" || info.edit_input === "radio") {
return info._paramters && info._paramters instanceof Array
? info._paramters.map((i) =>
return info._params.get() && info._params.get() instanceof Array
? info._params.get().map((i) =>
h("el-option", {
props: {
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;
};
props.onError = (err,file,fileList) => {
props.onError = (err, file, fileList) => {
this.file[info.field] = fileList;
this.$message({
type: "warning",
message: err
})
}
message: err,
});
};
}
return props;
},

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

@ -17,84 +17,6 @@
<el-form-item required prop="field" label="字段标识">
<el-input v-model="selectedForm.field"></el-input>
</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-input
v-model="selectedForm.help"
@ -119,13 +41,20 @@
></el-option>
</el-select>
</el-form-item>
<el-form-item label="是否显示" prop="list_show">
<el-form-item label="列表是否显示" prop="list_show">
<el-switch
v-model="selectedForm.list_show"
:active-value="1"
:inactive-value="0"
></el-switch>
</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-select
v-model="selectedForm.is_fix"
@ -257,10 +186,7 @@ export default {
const res = await formIndex({ page: 1, page_size: 999 });
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() {
this.$store.commit("form/SPLICE_FORM_LIST", {
@ -275,20 +201,8 @@ export default {
computed: {
...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() {
this.getForms();
this.getParameters();
this.debouncedInputHandler = debounce((e) => {
if (e) {

@ -203,8 +203,7 @@ export default {
validation: "",
select_item: "",
list_show: 1,
link_table_name: "",
link_relation: "",
form_show: 1,
is_fix: "",
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) {
return h(
"div",
{
class: this.config.list_show ? "" : "no-list-show",
class: this.hiddenClass,
style: {
opacity: this.config.list_show ? 1 : 0.5,
opacity: (this.config.list_show && this.config.form_show) ? 1 : 0.5,
filter:
this.index === this.$store.state.form.selectedIndex
? "drop-shadow(0 0 2px #0077CCFF) drop-shadow(0 0 8px #449FD9FF)"
@ -72,7 +86,29 @@ export default {
<style scoped lang="scss">
.no-list-show {
&::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;
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">
<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>
</template>
</xy-table>
<addForm ref="addForm" @refresh="$refs['xyTable'].getTableData()"></addForm>
<formEditor ref="formEditor"></formEditor>
<linkWith ref="linkWith"></linkWith>
</div>
</template>
@ -47,9 +52,11 @@ import { authMixin } from "@/mixin/authMixin";
import LxHeader from "@/components/LxHeader/index.vue";
import addForm from "./components/addForm.vue";
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
LxHeader,addForm,formEditor,linkWith
},
mixins: [authMixin],
@ -82,6 +89,7 @@ export default {
}
},
methods: {
deepCopy,
index,destroy,
},

Loading…
Cancel
Save