master
xy 2 years ago
parent 152ec95a3d
commit 701ba78fdf

@ -0,0 +1,13 @@
NODE_ENV = production
# just a flag
ENV = 'prostaging'
# base api
#VUE_APP_BASE_API=http://wuxiwuye.ali251.langye.net/
#VUE_APP_UPLOAD_API=http://wuxiwuye.ali251.langye.net/api/admin/upload-file
#VUE_APP_PREVIEW=//view.langye.net:8012/onlinePreview
# base api
VUE_APP_BASE_API=http://192.168.221.31:9001/
VUE_APP_UPLOAD_API=http://192.168.221.31:9001/api/admin/upload-file
VUE_APP_PREVIEW=http://192.168.221.31:8012/onlinePreview

@ -4,10 +4,10 @@ NODE_ENV = production
ENV = 'staging'
# base api
#VUE_APP_BASE_API=http://wuxiwuye.ali251.langye.net/
#VUE_APP_UPLOAD_API=http://wuxiwuye.ali251.langye.net/api/admin/upload-file
#VUE_APP_PREVIEW=//view.langye.net:8012/onlinePreview
VUE_APP_BASE_API=http://wuxiwuye.ali251.langye.net/
VUE_APP_UPLOAD_API=http://wuxiwuye.ali251.langye.net/api/admin/upload-file
VUE_APP_PREVIEW=//view.langye.net:8012/onlinePreview
# base api
VUE_APP_BASE_API=http://192.168.221.31:9001/
VUE_APP_UPLOAD_API=http://192.168.221.31:9001/api/admin/upload-file
VUE_APP_PREVIEW=http://192.168.221.31:8012/onlinePreview
#VUE_APP_BASE_API=http://192.168.221.31:9001/
#VUE_APP_UPLOAD_API=http://192.168.221.31:9001/api/admin/upload-file
#VUE_APP_PREVIEW=http://192.168.221.31:8012/onlinePreview

@ -7,6 +7,7 @@
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"build:prostaging": "vue-cli-service build --mode prostaging",
"postinstall": "patch-package",
"preview": "node build/index.js --preview",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",

@ -45,7 +45,7 @@
<div class="el-descriptions__header el-descriptions__title">
处置资产
</div>
<xy-table size="mini" :height="300" :is-page="false" :list="detail.lets_to_assets || []" :table-item="assetTable"></xy-table>
<xy-table size="mini" :height="300" :is-page="false" :list="detail.asset_handles_to_assets || []" :table-item="assetTable"></xy-table>
</el-card>
</el-col>
</el-row>

@ -128,15 +128,15 @@ export default {
align: "center",
},
{
prop: "_chuzumianji",
label: "出租面积",
prop: "_zichanshengyumianji",
label: "资产剩余面积",
width: 160,
customFn: (row) => {
return (
<el-input-number
controls={false}
precision={2}
vModel={row._chuzumianji}
vModel={row._zichanshengyumianji}
size="small"
></el-input-number>
);
@ -710,12 +710,10 @@ export default {
this.form = Object.assign({}, this.form);
this.originalForm = deepCopy(res);
if (this.type !== 'add') {
this.originalForm?.id_handle_signs_to_assets_handle_sign_id_relation?.forEach(
this.originalForm?.handle_signs_to_assets?.forEach(
(item) => {
if (item.land_id) {
let land = this.originalForm.land?.find(
(land) => land.id === item.land_id
);
let land = item.lands;
if (land) {
this.nowAssets.push({
id: land.id,
@ -728,9 +726,7 @@ export default {
});
}
} else {
let house = this.originalForm.houses?.find(
(house) => house.id === item.house_id
);
let house = item.house;
if (house) {
this.nowAssets.push({
id: house.id,
@ -780,7 +776,7 @@ export default {
land_id: !item.hasOwnProperty("land_id") ? item.id : "",
house_id: item.hasOwnProperty("land_id") ? item.id : "",
zichanshengyumianji: item._zichanshengyumianji,
handle_id: res.id
handle_sign_id: res.id
}));
if (handleToAssetsData && handleToAssetsData.length > 0) {
imports(
@ -812,7 +808,7 @@ export default {
content: `${this.type === "add" ? "新增" : "编辑"}成功`,
});
this.$emit("refresh");
this.$router.push("/lease");
this.$router.push("/handleSignList");
});
},
},
@ -884,7 +880,7 @@ export default {
this.$nextTick(() => this.getDetail());
} else {
show({ id: this.$route.params.handleId, table_name: "asset_handles" }).then(handleDetail => {
handleDetail?.lets_to_assets?.forEach(item => {
handleDetail?.asset_handles_to_assets?.forEach(item => {
if (item.land_id) {
let land = item.lands;
if (land) {
@ -894,7 +890,7 @@ export default {
zuoluo: land.zuoluo,
zichanweizhi: land.zichanweizhi,
shijimianji: land.shijimianji,
_chuzumianji: item.chuzumianji||0,
_zichanshengyumianji: item.zichanshengyumianji||0,
_relation_id: item.id,
});
}
@ -907,7 +903,7 @@ export default {
zuoluo: house.zuoluo,
zichanweizhi: house.zichanweizhi,
shijimianji: house.shijimianji,
_chuzumianji: item.chuzumianji||0,
_zichanshengyumianji: item.zichanshengyumianji||0,
_relation_id: item.id,
land_id: house.land_id,
});

@ -0,0 +1,600 @@
<template>
<div>
<el-page-header
:content="$route.meta.title"
style="
padding: 1em;
font-size: 1em;
background: #fff;
margin: 1.67em 0;
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
border-radius: 5px;
"
@back="$router.back()"
>
</el-page-header>
<el-row :gutter="20">
<el-col :span="24">
<el-card>
<div class="el-descriptions__header el-descriptions__title">
基本信息
</div>
<el-descriptions
border
:column="2"
:label-style="{ 'font-weight': '600' }"
>
<el-descriptions-item
v-for="item in showFields"
:label="item.name"
v-if="!['file', 'picture'].find((j) => j === item.field)"
>
<template v-if="item.edit_input === 'richtext'">
<div v-html="detail[item.field]"></div>
</template>
<template v-else-if="item.edit_input === 'file'">
<div>img</div>
</template>
<template v-else-if="item.edit_input === 'files'">
<div
v-for="(item, index) in detail[
`${item.field}_upload_details`
]"
style="
display: flex;
justify-content: space-between;
margin-bottom: 4px;
"
>
<a :download="item.url"
>{{ ++index }}.{{ item.original_name }}</a
>
<div>
<el-button
type="primary"
icon="el-icon-download"
circle
size="mini"
@click="down(item)"
></el-button>
<el-button
type="primary"
icon="el-icon-search"
circle
size="mini"
@click="open(item.url)"
></el-button>
</div>
</div>
</template>
<template v-else>
{{ contentFormat(item) }}
</template>
</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card>
<div class="el-descriptions__header el-descriptions__title">
资产详情
</div>
<xy-table
size="mini"
:height="300"
:is-page="false"
:list="detail.handle_signs_to_assets || []"
:table-item="assetTable"
:show-summary="true"
:summary-method="summaryAssets"
></xy-table>
</el-card>
</el-col>
</el-row>
<el-backtop></el-backtop>
<Modal
:width="76"
transfer
:z-index="6000"
v-model="showModal"
:footer-hide="true"
title="预览"
>
<template>
<iframe
style="width: 100%; height: 57vh"
:src="codeUri"
border="0"
></iframe>
</template>
</Modal>
</div>
</template>
<script>
import { show, index } from "@/api/system/baseForm";
import {
show as formShow,
index as customFormIndex,
} from "@/api/system/customForm";
import { getparameter } from "@/api/system/dictionary";
import { listdept } from "@/api/system/department";
import { download } from "@/utils/downloadRequest";
export default {
name: "detail",
data() {
return {
showModal: false,
codeUri: "",
detail: {},
fields: [],
relation: [],
customForm: {
customFormId: "",
tableName: "",
},
allTables: [],
linkTableList: [],
assetTable: [
{
prop: "name",
label: "地块名称",
width: 0,
fixed: "left",
align: "left",
customFn: (row) => {
return (
<span>
{row.land_id
? row.lands?.name
: row.house?.name}
</span>
);
},
},
{
prop: "zuoluo",
label: "坐落",
width: 0,
align: "left",
customFn: (row) => {
return (
<span>
{row.land_id
? row.lands?.zuoluo
: row.house?.zuoluo}
</span>
);
},
},
{
prop: "shijimianji",
label: "实际面积",
width: 160,
align: "right",
customFn: (row) => {
return (
<span>
{parseFloat((row.land_id
? row.lands?.shijimianji
: row.house?.shijimianji)??0).toFixed(2)}
</span>
);
},
},
{
prop: "zichanshengyumianji",
label: "资产剩余面积",
width: 160,
align: "right",
formatter: (row, data ,val) => parseFloat(val??0).toFixed(2)
},
],
leasePlanTable: [
{
prop: "zujindiyicidaoweishijian",
label: "租金到位时间",
width: 200,
},
{
prop: "yingshou",
label: "应收租金",
width: 160,
align: "right",
formatter: (row, data ,val) => parseFloat(val??0).toFixed(2)
},
{
prop: "shijidaozhang",
label: "实际到账",
width: 160,
align: "right",
formatter: (row, data ,val) => parseFloat(val??0).toFixed(2)
},
{
prop: "weidaoweiyuanyin",
label: "未到位原因",
minWidth: 180,
align: "left",
},
{
prop: "shijidaozhangriqi",
label: "实际到账日期",
width: 200,
},
],
};
},
methods: {
open(url) {
this.codeUri = `${process.env.VUE_APP_PREVIEW}?url=${encodeURIComponent(
new Buffer(url).toString("base64")
)}`;
this.showModal = true;
},
down(e) {
download(e.url, "get", {}, e.original_name);
},
formatColumn(info) {
let table = [];
//
//
let baseTable = new Map([
[
"departments",
async () => {
const res = await listdept();
return res;
},
],
["admins", []],
]);
let { fields, relation } = info;
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.custom_form_field === 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],
};
});
}
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));
} 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;
});
}
}
});
fields
?.filter((i) => i.list_show)
.forEach((i) => {
if (i._relations) return;
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>
);
}
};
}
}
table.push(
Object.assign(
{
prop: i.field,
label: i.name,
width: i.width,
fixed: i.is_fixed,
},
linkOb
)
);
});
table.unshift({
type: "index",
width: 60,
label: "序号",
});
return table;
},
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.custom_form_field === 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.params.id,
table_name: this.customForm.tableName,
});
this.detail = detail;
},
summaryAssets ({ columns, data }) {
return columns.map((column,index) => {
if (index === 0) return '合计'
if (column.property === 'zichanshengyumianji') {
return data.reduce((pre,cur) => pre + parseFloat(cur[column.property]??0),0).toFixed(2)
} else if (column.property === 'shijimianji') {
return data.reduce((pre,cur) => pre + parseFloat((
cur.land_id
? cur?.lands?.shijimianji
: cur.house?.shijimianji
)??0),0).toFixed(2)
} else {
return ""
}
})
},
},
computed: {
showFields() {
return this.fields.filter(
(field) =>
(!field._relations ||
field._relations.link_relation === "hasOne" ||
field._relations.link_relation === "newHasOne") &&
!/_id/g.test(field.field)
);
},
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]?.original_name ||
this.detail[_relations.link_with_name]?.name ||
this.detail[_relations.link_with_name]?.no ||
this.detail[_relations.link_with_name]?.value ||
this.detail[_relations.link_with_name]?.mingcheng
);
}
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];
};
},
},
created() {
this.getFields().then((_) => {});
},
};
</script>
<style scoped lang="scss">
::v-deep .el-card {
margin-bottom: 20px;
}
::v-deep .el-empty__image {
width: 120px;
}
a {
color: red;
text-decoration: none;
transition: all 0.2s;
}
a:hover {
color: red;
text-decoration: underline;
}
.el-descriptions__title {
position: relative;
padding-left: 14px;
&::before {
content: "";
width: 4px;
background: linear-gradient(
to bottom,
rgb(57, 129, 199),
rgba(118, 148, 183, 0.7)
);
position: absolute;
left: 0;
top: 2px;
bottom: 2px;
}
}
::v-deep .el-table__fixed-footer-wrapper .el-table__cell:first-child .cell {
text-align: center;
}
</style>

@ -0,0 +1,683 @@
<template>
<div>
<!-- 查询配置 -->
<div>
<div ref="lxHeader">
<LxHeader
:icon="$route.meta.icon"
:text="$route.meta.title"
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>
<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>
<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="getColumnField(select.filter[0].key)._relations ? item[getColumnField(select.filter[0].key)._relations.foreign_key] : item.value"
>{{
item.key || item.value || item.name || item.no || item.mingcheng || 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])"
/>
</template>
<Button
style="margin-left: 10px"
type="primary"
@click="$refs['xyTable'].getTableData(true)"
>查询</Button
>
<xy-selectors
style="margin-left: 10px"
@reset="reset"
@search="$refs['xyTable'].getTableData(true)"
>
<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
>
</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>
<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="getColumnField(item.key)._relations ? item[getColumnField(item.key)._relations.foreign_key] : item.value"
>{{
item.key || item.value || item.name || item.no || item.mingcheng || 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)"
/>
</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>
</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>
<span>新增一条</span>
</div>
</template>
</xy-selectors>
</div>
</template>
<template #create>
<Button
type="primary"
@click="
$refs['dialog'].setType('add'), $refs['dialog'].show()
"
>新增</Button
>
</template>
<template #import>
<Button type="primary" @click="$refs['imports'].show()"
>导入</Button
>
</template>
<template #export>
<Button
type="primary"
@click="exportExcel(new Date().getTime().toString())"
>导出</Button
>
</template>
</header-content>
</slot>
</LxHeader>
</div>
</div>
<xy-table
:btn-width="300"
:auths="auths_auth_mixin"
:delay-req="true"
:destroy-action="destroy"
ref="xyTable"
:border="true"
:action="index"
:req-opt="select"
:destroy-req-opt="select"
:table-item="table"
:btn-to-more="true"
@detail="
(row) => {
$router.push({
path: $route.path + '/detail/' + row.id
})
}
"
@editor="
(row) => {
$router.push('/handleSign/'+row.let_id+'?type=editor&handleId='+row.id)
}
"
@loaded="adjustAlignment"
>
<template #rentCollection="{ row }">
<template v-if="$moment().isBetween($moment(row.zulinkaishiqixian),$moment(row.zulinjieshuqixian))">
<Button size="small" type="primary" @click="$refs['payList'].setLeaseId(row.id),$refs['payList'].show()"></Button>
</template>
</template>
<template #expiredLet="{ row }">
<template v-if="$moment().valueOf() > $moment(row.zulinjieshuqixian).valueOf()">
<Button size="small" type="primary" @click="$router.push('/let'+'?renewId='+row.let_id)"></Button>
</template>
</template>
<template #contractChange="{ row }">
<Button size="small" type="primary" @click="$router.push('/sign/'+row.let_id+'?type=change&leaseId='+row.id)"></Button>
</template>
</xy-table>
<add
:table-name="customForm.tableName"
ref="dialog"
@refresh="$refs['xyTable'].getTableData()"
>
</add>
<addPay ref="addPay"></addPay>
<payList ref="payList"></payList>
</div>
</template>
<script>
import { index as fieldIndex } from "@/api/system/customFormField";
import { authMixin } from "@/mixin/authMixin";
import { index, destroy } from "@/api/system/baseForm";
import { op } from "@/const/op";
import { download } from "@/utils/downloadRequest";
import { getparameter } from "@/api/system/dictionary";
import { show } from "@/api/system/customForm";
import * as XLSX from "xlsx";
import { saveAs } from "file-saver";
import { listdept } from "@/api/system/department"
import add from "./component/addLease.vue";
import LxHeader from "@/components/LxHeader/index.vue";
import headerContent from "@/components/LxHeader/XyContent.vue";
import addPay from "@/views/lease/component/addPay.vue";
import payList from "@/views/lease/component/payList.vue"
export default {
name: 'tableList',
components: {
LxHeader,
add,
headerContent,
addPay,
payList
},
mixins: [authMixin],
provide: {
formStore: () => this.form,
},
data() {
return {
firstAdjustTable: true,
op,
select: {
table_name: "",
filter: [
{
key: "",
op: "",
value: "",
},
],
},
form: [],
table: [],
customForm: {
customFormId: "",
tableName: "",
},
};
},
methods: {
index,
destroy,
download,
reset() {
this.select.filter.splice(1);
this.select.filter[0] = {
key: "",
op: "",
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) => {
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));
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`
);
}
},
//target
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}`;
},
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格式错误");
}
console.log(fieldRes)
fieldRes?.forEach((i, index) => {
i._relations = relation.find(
(j) => j.link_table_name.split("_")[1] === i.field
) || relation.find(
(j) => j.local_key === i.field
);
if (i.select_item && typeof i.select_item === "object") {
let keys = Object.keys(i.select_item);
if (keys.length > 0) {
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(/^\d*$/.test(i.select_item[key]) ? Number(i.select_item[key]) : i.select_item[key], key);
});
return <span>{ paramMap.get(row[i.field]) ? paramMap.get(row[i.field]) : row[i.field] }</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,
align: 'center',
fixed: i.is_fixed,
},
linkOb
)
);
});
this.table.unshift({
prop: "id",
width: 60,
label: "序号",
formatter: (row, column, cellValue, index) => (this.$refs['xyTable'].selectOpt.page - 1) * this.$refs['xyTable'].selectOpt.page_size + index + 1
})
},
adjustAlignment () {
if (this.firstAdjustTable) {
const data = this.$refs['xyTable'].getListData();
if (data.length < 2) return;
try {
this.form.filter(i => i.list_show).forEach((i) => {
let maxLength = -Infinity;
let minLength = Infinity;
let numberLength = 0;
let temp = 0;
while (temp < data.length) {
maxLength = Math.max(maxLength, data[temp][i.field]?.length??0);
minLength = Math.min(minLength, data[temp][i.field]?.length??0);
numberLength += /^-?[0-9]+(\.[0-9]+)?$/.test(data[temp][i.field]) ? 1 : 0;
temp++;
}
if (numberLength === temp && numberLength !== 0 && i.edit_input !== 'radio') {
this.table.find(a => a.prop === i.field).align = 'right';
}
else if (Math.abs(maxLength - minLength) > 4) {
this.table.find(a => a.prop === i.field).align = 'left';
}
})
} catch (e) {
console.error(e)
}
this.$nextTick(() => {
this.$refs['xyTable'].doLayout();
this.firstAdjustTable = false;
})
}
}
},
computed: {
columnArrTest() {
return function (field) {
return this.form.find((i) => i.field === field)
? this.form.find((i) => i.field === field).search_input === "checkbox" || this.form.find((i) => i.field === field).search_input === "radio"
: false;
};
},
getColumnField() {
return function (field) {
return this.form.find((i) => i.field === field)
? this.form.find((i) => i.field === field)
: {};
};
},
getColumnParams() {
return function (field) {
return this.form.find((i) => i.field === field)
? this.form.find((i) => i.field === field)._params
: [];
};
}
},
created() {
this.getFormDetail();
},
};
</script>
<style scoped lang="scss">
.select {
&__item {
& > p {
display: inline-block;
width: 80px;
text-align: center;
}
& + div {
margin-top: 6px;
}
}
}
.add-btn {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
& > span {
padding: 0 10px;
}
}
a {
color: red;
text-decoration: none;
transition: all 0.2s;
}
a:hover {
color: red;
text-decoration: underline;
}
</style>

@ -93,7 +93,17 @@
<el-form-item label="父菜单">
<el-input
v-model="form.pname"
disabled
readonly
autocomplete="off"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="父级id">
<el-input
v-model="form.pid"
autocomplete="off"
></el-input>
</el-form-item>
@ -304,7 +314,7 @@ export default {
],
icon: [
{
required: true,
required: false,
message: "请输入图标",
trigger: "blur",
},

@ -24,7 +24,7 @@ module.exports = {
* In most cases please use '/' !!!
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: process.env.ENV === 'staging' ? '/app_test' : '/app',
publicPath: (process.env.ENV === 'staging' || process.env.ENV === 'prostaging') ? '/app_test' : '/app',
outputDir: './dist',
assetsDir: 'static',
css: {

Loading…
Cancel
Save