You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1238 lines
43 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<!-- 查询配置 -->
<div>
<div ref="lxHeader">
<LxHeader
:icon="$route.meta.icon"
:text="$route.meta.title"
>
<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) &&
!isDateField(select.filter[0].key)
"
>
<Input
v-model="select.filter[0].value"
style="width: 150px; margin-left: 10px"
placeholder="请填写关键词"
@input="e => {
if (!select.filter[0].key) {
select.keyword = e
}
}"
/>
</template>
<template
v-else-if="
select.filter[0].op !== 'range' &&
isDateField(select.filter[0].key)
"
>
<el-date-picker
v-model="select.filter[0].value"
type="date"
value-format="yyyy-MM-dd"
style="width: 150px; margin-left: 10px; height: 32px"
size="small"
placeholder="请选择日期"
></el-date-picker>
</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-if="
select.filter[0].op === 'range' &&
isDateField(select.filter[0].key)
"
>
<el-date-picker
v-model="dateRangeStart0"
type="date"
placeholder="开始时间"
value-format="yyyy-MM-dd"
style="width: 150px; margin-left: 10px; height: 32px"
size="small"
@change="(val) => handleDateStartChange(val, select.filter[0])"
></el-date-picker>
<span
style="
margin-left: 10px;
display: flex;
align-items: center;
"
>至</span
>
<el-date-picker
v-model="dateRangeEnd0"
type="date"
placeholder="结束时间"
value-format="yyyy-MM-dd"
style="width: 150px; margin-left: 10px; height: 32px"
size="small"
@change="(val) => handleDateEndChange(val, select.filter[0])"
></el-date-picker>
</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) && !isDateField(item.key)
"
>
<Input
v-model="item.value"
style="width: 150px; margin-left: 10px"
placeholder="请填写关键词"
/>
</template>
<template
v-else-if="
item.op !== 'range' && isDateField(item.key)
"
>
<el-date-picker
v-model="item.value"
type="date"
value-format="yyyy-MM-dd"
style="width: 150px; margin-left: 10px; height: 32px"
size="small"
placeholder="请选择日期"
></el-date-picker>
</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-if="isDateField(item.key)"
>
<el-date-picker
:value="getDateRangeStart(item)"
type="date"
placeholder="开始时间"
value-format="yyyy-MM-dd"
style="width: 150px; margin-left: 10px; height: 32px"
size="small"
@change="(val) => handleDateStartChange(val, item)"
></el-date-picker>
<span style="margin-left: 10px">至</span>
<el-date-picker
:value="getDateRangeEnd(item)"
type="date"
placeholder="结束时间"
value-format="yyyy-MM-dd"
style="width: 150px; margin-left: 10px; height: 32px"
size="small"
@change="(val) => handleDateEndChange(val, item)"
></el-date-picker>
</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="360"
:auths="auths_auth_mixin"
:delay-req="true"
:destroy-action="destroy"
ref="xyTable"
:border="true"
:action="index"
:req-opt="formatSelect"
:destroy-req-opt="select"
:table-item="table"
:btn-to-more="true"
:more-auths="['edit','delete','picture','file']"
@loaded="adjustAlignment"
@detail="
(row) => {
$router.push({
path: '/houseDetail/' + row.id,
});
}
"
@editor="
(row) => {
$refs['dialog'].setId(row.id);
$refs['dialog'].setType('editor');
$refs['dialog'].show();
}
"
@picture="(row) => {
$refs['atlas'].setId(row.id);
$refs['atlas'].show();
}"
@file="(row) => {
$refs['files'].setId(row.id);
$refs['files'].show();
}"
>
<template #handle="{ row }">
<Button
size="small"
type="primary"
@click="toHandle(row)"
>资产处置</Button
>
</template>
<template #assetsHistory="{ row }">
<Button size="small" type="primary" @click="toHistory(row)"
>历史沿革</Button
>
</template>
<template #picture="{ row }">
<span
>图集</span
>
</template>
<template #file="{row}">
<span
>附件</span
>
</template>
</xy-table>
<add
:table-name="customForm.tableName"
:form-info="form"
ref="dialog"
@refresh="$refs['xyTable'].getTableData()"
>
</add>
<history ref="history"></history>
<lease ref="lease"></lease>
<atlas ref="atlas"></atlas>
<files ref="files"></files>
<addHandle ref="addHandle"></addHandle>
<imports
:table-name="customForm.tableName"
:form-info="form"
ref="imports"
@refresh="$refs['xyTable'].getTableData()"
></imports>
<!-- <atlas ref="atlas"></atlas>-->
<!-- <assetsHistoryList ref="assetsHistoryList"></assetsHistoryList>-->
</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 { deepCopy } from '@/utils'
import add from "./component/addHouse.vue";
import LxHeader from "@/components/LxHeader/index.vue";
import headerContent from "@/components/LxHeader/XyContent.vue";
import addHistory from "@/views/assets/component/addHistory.vue";
import lease from '@/views/assets/lease.vue'
import atlas from '@/views/assets/atlas.vue'
import history from '@/views/assets/history.vue'
import files from "@/views/assets/files.vue";
import addHandle from '@/views/assets/component/addHandle.vue'
// import drawer from "@/views/component/drawer.vue";
import imports from "@/views/component/imports.vue";
// import atlas from "@/views/assets/atlas.vue";
// import assetsHistoryList from '@/views/assets/assetsHistoryList.vue'
export default {
name: "tableList",
components: {
history,
atlas,
lease,
LxHeader,
add,
headerContent,
files,
addHandle,
// drawer,
imports,
// atlas,
// assetsHistoryList
},
mixins: [authMixin],
provide: {
formStore: () => this.form,
},
data() {
return {
firstAdjustTable: true,
op,
dateRangeStart0: null, // 第一个筛选条件的开始时间
dateRangeEnd0: null, // 第一个筛选条件的结束时间
select: {
is_auth: 1,
keyword: "",
table_name: "",
filter: [
{
key: "",
op: "",
value: "",
},
],
sort_name: 'fenlei',
sort_type: 'asc',
},
form: [],
table: [],
customForm: {
customFormId: "",
tableName: "",
},
};
},
methods: {
index,
destroy,
download,
reset() {
this.select.filter.splice(1);
this.select.filter[0] = {
key: "",
op: "",
value: "",
};
// 重置日期范围
this.dateRangeStart0 = null;
this.dateRangeEnd0 = null;
},
// 判断字段是否为数字类型
isNumericField(field, fieldName) {
if (!field) return false;
// 检查配置中的类型
if (field.edit_input === 'number' ||
field.type === 'number' ||
field.type === 'integer' ||
field.type === 'decimal' ||
field.type === 'float') {
return true;
}
// 检查字段名是否包含数字相关关键词
const numericKeywords = ['面积', '值', '金额', '价格', '费用', '成本', '数量', '数量', '金额', '元', '万元', '平方米', 'm²', '㎡'];
if (fieldName) {
for (let keyword of numericKeywords) {
if (fieldName.includes(keyword)) {
return true;
}
}
}
return false;
},
async exportExcel(sheetName) {
let filterTableColumns = this.$refs['xyTable']?.tableFormat || []
const res = await index(
Object.assign(this.select, { page: 1, page_size: 9999 })
);
if (res.data) {
let headers = this.form.filter(i => filterTableColumns.find(j => j.prop === i.field)).map((i) => {
return {
key: i.field,
title: i.name,
isNumber: this.isNumericField(i, i.name)
};
});
// 添加提交人、提交单位和创建时间到 headers
headers.push({
key: 'admin.name',
title: '提交人',
isNumber: false
});
headers.push({
key: 'department.name',
title: '提交单位',
isNumber: false
});
headers.push({
key: 'created_at',
title: '创建时间',
isNumber: false
});
const data = res.data.map((row) =>
headers.map((header) => {
let value;
// 处理提交人、提交单位和创建时间字段
if (header.key === 'admin.name') {
value = row['admin']?.name || '';
} else if (header.key === 'department.name') {
value = row['department']?.name || '';
} else if (header.key === 'created_at') {
value = row['created_at'] ? this.$moment(row['created_at']).format('YYYY-MM-DD HH:mm:ss') : '';
} else {
const i = this.form.find(i => i.field === header.key)
//if (i.edit_input === 'file' || i.edit_input === 'files') return ''
// if (
// i.select_item &&
// typeof i.select_item === "object" &&
// !(i.select_item instanceof Array)
// ) {
// let keys = Object.keys(i.select_item);
// let paramMap = new Map();
// keys.forEach((key) => {
// paramMap.set(i.select_item[key], key);
// });
// return paramMap.get(row[i.field]?.toString());
// }
if (i && i._relations) {
let { link_relation, foreign_key, link_with_name } = i._relations;
if (link_relation === "newHasOne" || link_relation === "hasOne") {
value = row[link_with_name]?.original_name || row[link_with_name]?.name ||
row[link_with_name]?.no ||
row[link_with_name]?.value
} else if (link_relation === "hasMany" || link_relation === "newHasMany") {
value = row[link_with_name]?.map((o) => (
o?.name ||
o?.no ||
o?.value ||
o?.biaoti ||
o?.mingcheng
)).toString()
} else {
value = row[header.key]
}
} else {
if (this.table.find(i => i.prop === header.key)?.formatter) {
value = this.table.find(i => i.prop === header.key).formatter(row, {}, row[header.key])
} else {
value = row[header.key]
}
}
}
// 如果是数字类型字段,确保值是数字类型
if (header.isNumber && value !== null && value !== undefined && value !== '') {
// 如果 value 是字符串,尝试转换为数字
let numValue;
if (typeof value === 'string') {
// 移除可能的单位(如"元"、"m²"等)和空格
const cleanedValue = value.toString().replace(/[元万元m²㎡\s,]/g, '').trim();
numValue = Number(cleanedValue);
} else {
numValue = Number(value);
}
if (!isNaN(numValue) && numValue !== '') {
return numValue;
}
}
return value;
})
);
data.unshift(headers.map((header) => header.title));
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet(data);
// 设置数字类型单元格的格式
const range = XLSX.utils.decode_range(ws['!ref']);
for (let R = 1; R <= range.e.r; R++) { // 跳过标题行R=0
for (let C = 0; C <= range.e.c; C++) {
const cellAddress = XLSX.utils.encode_cell({ r: R, c: C });
if (!ws[cellAddress]) continue;
const header = headers[C];
if (header && header.isNumber) {
const cell = ws[cellAddress];
let numValue;
// 处理单元格值,转换为数字
if (typeof cell.v === 'string') {
// 移除可能的单位(如"元"、"m²"等)和空格、逗号
const cleanedValue = cell.v.toString().replace(/[元万元m²㎡\s,]/g, '').trim();
numValue = Number(cleanedValue);
} else {
numValue = Number(cell.v);
}
if (!isNaN(numValue) && cell.v !== null && cell.v !== undefined && cell.v !== '') {
cell.t = 'n'; // 设置为数字类型
cell.v = numValue; // 确保值是数字
// 根据字段名设置合适的格式
if (header.title && (header.title.includes('面积') || header.title.includes('m²') || header.title.includes('㎡'))) {
cell.z = '#,##0.00'; // 面积保留2位小数
} else if (header.title && (header.title.includes('值') || header.title.includes('金额') || header.title.includes('元'))) {
cell.z = '#,##0.00'; // 金额保留2位小数
} else {
cell.z = '#,##0'; // 整数格式
}
}
}
}
}
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}`;
},
handleDateStartChange(val, target) {
// 开始时间变化时,更新筛选条件的值
const endValue = target.value && target.value.includes(',') ? target.value.split(',')[1] : '';
if (val) {
target.value = `${val},${endValue || ''}`;
} else {
target.value = endValue ? `,${endValue}` : '';
}
// 如果是第一个筛选条件,同步更新 dateRangeStart0
if (target === this.select.filter[0]) {
this.dateRangeStart0 = val;
}
},
handleDateEndChange(val, target) {
// 结束时间变化时,更新筛选条件的值
const startValue = target.value && target.value.includes(',') ? target.value.split(',')[0] : '';
if (val) {
target.value = `${startValue || ''},${val}`;
} else {
target.value = startValue ? `${startValue},` : '';
}
// 如果是第一个筛选条件,同步更新 dateRangeEnd0
if (target === this.select.filter[0]) {
this.dateRangeEnd0 = val;
}
},
getDateRangeStart(item) {
// 获取开始时间值
if (item.value && item.value.includes(',')) {
return item.value.split(',')[0] || null;
}
return null;
},
getDateRangeEnd(item) {
// 获取结束时间值
if (item.value && item.value.includes(',')) {
return item.value.split(',')[1] || null;
}
return null;
},
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);
fieldRes?.forEach((i, index) => {
i._relations = relation.find(
(j) => j.link_table_name.split("_")[1] === i.field
);
if (i.select_item && typeof i.select_item === "object" && !(i.select_item instanceof Array)) {
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],
};
});
//有select,radio
i.edit_input = 'radio'
}
}
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.formatter = (row) => {
let paramMap = new Map();
keys.forEach((key) => {
paramMap.set(i.select_item[key], key);
});
return paramMap.get(row[i.field]?.toString()) || row[i.field];
};
}
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 {
console.log("link_with_name",row[link_with_name])
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>
);
}
};
}
}
let alignLeft = [
"dikuaimingcheng",
"chengjiandanwei",
"jianshedanwei",
"wuyedanwei",
];
switch (i.field) {
// case "shiyongzhuangtai":
// this.table.push({
// label: i.name,
// width: i.width,
// customFn:row => {
// return (
// <span>{
// (() => {
// let res = '无';
// for (let i = 0;i < row.id_leases_house_id_relation.length;i++) {
// let nowDate = this.$moment(new Date())
// let startDate = this.$moment(new Date(row.id_leases_house_id_relation[i]?.zulinkaishiqixian))
// let endDate = this.$moment(new Date(row.id_leases_house_id_relation[i]?.zulinjieshuqixian))
//
// if (nowDate.isBetween(startDate,endDate)) {
// res = "租赁给"+row.id_leases_house_id_relation[i]?.chengzufang
// break;
// }
//
// }
// return res;
// })()
// }</span>
// )
// }
// })
// break;
case "bufuqingkuang":
this.table.push({
prop: i.field,
label: i.name,
width: i.width,
formatter: (row, column, cellValue, index) => {
let text = "";
text += row.tudiquanshuren !== row.quanliren ? "权利人名称不符" : ""
text += text ? "" : ""
text += row.dengjimianji !== row.shijimianji ? "登记面积不符": ""
return text || "无"
},
});
break;
case "bufuyuanyin":
this.table.push({
prop: i.field,
label: i.name,
width: i.width,
align: "center",
customFn: (row) => {
return (
<el-popover width="450" trigger="click">
<el-table size="small" data={row.id_his_evolutions_land_id_relation}>
<el-table-column width="40" type="index" align="center"></el-table-column>
<el-table-column width="150" property="mianjitiaozheng" label="面积调整" show-overflow-tooltip={true}></el-table-column>
<el-table-column width="150" property="qitashuoming" label="其他说明" show-overflow-tooltip={true}></el-table-column>
<el-table-column width="150" property="zichanlaiyuan" label="资产来源" show-overflow-tooltip={true}></el-table-column>
</el-table>
<a slot="reference">查看</a>
</el-popover>
// <a
// on={{
// ["click"]: (e) => {
// this.$refs["addHistory"].setRow(row);
// this.$refs["addHistory"].setType("show");
// this.$refs["addHistory"].show();
// },
// }}
// >
// 查看
// </a>
);
},
});
break;
default:
this.table.push(
Object.assign(
{
prop: i.field,
label: i.name,
width: i.width,
align: alignLeft.find((m) => m === i.field)
? "left"
: "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
})
this.table.push({
prop: 'admin.name',
width: 120,
label: '提交人'
})
this.table.push({
prop: 'department.name',
width: 120,
label: '提交单位'
})
this.table.push({
prop: 'created_at',
width: 160,
label: '提交日期',
formatter: (row, column, cellValue, index) => this.$moment(cellValue).format('YYYY-MM-DD')
})
},
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 && !i._params && numberLength !== 0) {
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';
}
})
console.log(this.table)
} catch (e) {
console.error(e)
}
this.$nextTick(() => {
this.$refs['xyTable'].doLayout();
this.firstAdjustTable = false;
})
}
},
toHistory(row) {
this.$refs['history'].setRow(row);
this.$refs['history'].show();
},
toLeave (row) {
this.$refs['lease'].setRow(row);
this.$refs['lease'].show();
},
toHandle (row) {
this.$refs['addHandle'].setRow(row);
this.$refs['addHandle'].show();
}
},
computed: {
formatSelect() {
let copySelect = deepCopy(this.select)
copySelect.filter = copySelect.filter.filter(i => i.key)
// 处理日期范围筛选:如果结束日期为空,默认使用当前日期
copySelect.filter = copySelect.filter.map(filter => {
if (filter.key && filter.op === 'range' && this.isDateField(filter.key) && filter.value) {
const parts = filter.value.split(',');
if (parts.length >= 1 && parts[0]) {
const startDate = parts[0];
const endDate = parts[1] || this.$moment().format('YYYY-MM-DD');
return {
...filter,
value: `${startDate},${endDate}`
};
}
}
return filter;
});
return copySelect
},
isDateField() {
return function (field) {
if (!field) return false;
// 通过检查字段名name中是否包含"日期"或"时间"来判断
const fieldConfig = this.form.find((i) => i.field === field);
if (fieldConfig && fieldConfig.name) {
return fieldConfig.name.includes('日期') || fieldConfig.name.includes('时间');
}
return false;
};
},
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
: [];
};
},
},
watch: {
'select.filter[0].key'(newVal) {
// 当字段变化时,如果是日期字段且操作符是 range初始化日期范围值
if (this.isDateField(newVal) && this.select.filter[0].op === 'range') {
this.dateRangeStart0 = null;
this.dateRangeEnd0 = null;
if (this.select.filter[0].value) {
// 如果已有值,尝试解析
const parts = this.select.filter[0].value.split(',');
if (parts.length >= 1 && parts[0]) {
this.dateRangeStart0 = parts[0];
}
if (parts.length >= 2 && parts[1]) {
this.dateRangeEnd0 = parts[1];
}
}
}
},
'select.filter[0].op'(newVal) {
// 当操作符变化时,如果是日期字段且操作符是 range初始化日期范围值
if (this.isDateField(this.select.filter[0].key) && newVal === 'range') {
this.dateRangeStart0 = null;
this.dateRangeEnd0 = null;
if (this.select.filter[0].value) {
// 如果是 range 且有值,尝试解析
const parts = this.select.filter[0].value.split(',');
if (parts.length >= 1 && parts[0]) {
this.dateRangeStart0 = parts[0];
}
if (parts.length >= 2 && parts[1]) {
this.dateRangeEnd0 = parts[1];
}
}
}
}
},
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: $primaryColor;
text-decoration: none;
transition: all 0.2s;
}
a:hover {
color: $primaryColor;
text-decoration: underline;
}
</style>