diff --git a/src/views/assets/house.vue b/src/views/assets/house.vue
index 40a2031..50f562f 100644
--- a/src/views/assets/house.vue
+++ b/src/views/assets/house.vue
@@ -528,6 +528,32 @@ export default {
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(
@@ -538,78 +564,138 @@ export default {
return {
key: i.field,
title: i.name,
+ isNumber: this.isNumericField(i, i.name)
};
});
// 添加提交人、提交单位和创建时间到 headers
headers.push({
key: 'admin.name',
- title: '提交人'
+ title: '提交人',
+ isNumber: false
});
headers.push({
key: 'department.name',
- title: '提交单位'
+ title: '提交单位',
+ isNumber: false
});
headers.push({
key: 'created_at',
- title: '创建时间'
+ title: '创建时间',
+ isNumber: false
});
const data = res.data.map((row) =>
headers.map((header) => {
+ let value;
// 处理提交人、提交单位和创建时间字段
if (header.key === 'admin.name') {
- return row['admin']?.name || '';
- }
- if (header.key === 'department.name') {
- return row['department']?.name || '';
- }
- if (header.key === 'created_at') {
- return row['created_at'] ? this.$moment(row['created_at']).format('YYYY-MM-DD HH:mm:ss') : '';
+ 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]
+ }
+ }
}
- 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") {
- return row[link_with_name]?.original_name || row[link_with_name]?.name ||
- row[link_with_name]?.no ||
- row[link_with_name]?.value
+ // 如果是数字类型字段,确保值是数字类型
+ 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 (link_relation === "hasMany" || link_relation === "newHasMany") {
- return row[link_with_name]?.map((o) => (
- o?.name ||
- o?.no ||
- o?.value ||
- o?.biaoti ||
- o?.mingcheng
- )).toString()
+
+ if (!isNaN(numValue) && numValue !== '') {
+ return numValue;
}
}
-
- if (this.table.find(i => i.prop === header.key)?.formatter) {
- return this.table.find(i => i.prop === header.key).formatter(row, {}, row[header.key])
- }
- return row[header.key]
+
+ 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",
diff --git a/src/views/assets/land.vue b/src/views/assets/land.vue
index 8c29972..db7c3ef 100644
--- a/src/views/assets/land.vue
+++ b/src/views/assets/land.vue
@@ -507,6 +507,32 @@ export default {
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(
@@ -517,78 +543,138 @@ export default {
return {
key: i.field,
title: i.name,
+ isNumber: this.isNumericField(i, i.name)
};
});
// 添加提交人、提交单位和创建时间到 headers
headers.push({
key: 'admin.name',
- title: '提交人'
+ title: '提交人',
+ isNumber: false
});
headers.push({
key: 'department.name',
- title: '提交单位'
+ title: '提交单位',
+ isNumber: false
});
headers.push({
key: 'created_at',
- title: '创建时间'
+ title: '创建时间',
+ isNumber: false
});
const data = res.data.map((row) =>
headers.map((header) => {
+ let value;
// 处理提交人、提交单位和创建时间字段
if (header.key === 'admin.name') {
- return row['admin']?.name || '';
- }
- if (header.key === 'department.name') {
- return row['department']?.name || '';
- }
- if (header.key === 'created_at') {
- return row['created_at'] ? this.$moment(row['created_at']).format('YYYY-MM-DD HH:mm:ss') : '';
+ 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]
+ }
+ }
}
- 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") {
- return row[link_with_name]?.original_name || row[link_with_name]?.name ||
- row[link_with_name]?.no ||
- row[link_with_name]?.value
+ // 如果是数字类型字段,确保值是数字类型
+ 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 (link_relation === "hasMany" || link_relation === "newHasMany") {
- return row[link_with_name]?.map((o) => (
- o?.name ||
- o?.no ||
- o?.value ||
- o?.biaoti ||
- o?.mingcheng
- )).toString()
+
+ if (!isNaN(numValue) && numValue !== '') {
+ return numValue;
}
}
-
- if (this.table.find(i => i.prop === header.key)?.formatter) {
- return this.table.find(i => i.prop === header.key).formatter(row, {}, row[header.key])
- }
- return row[header.key]
+
+ 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('元') || 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",
diff --git a/src/views/lease/let.vue b/src/views/lease/let.vue
index 9b2e7d0..71278e1 100644
--- a/src/views/lease/let.vue
+++ b/src/views/lease/let.vue
@@ -311,7 +311,7 @@
@@ -373,7 +373,7 @@ 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 * as XLSX from "xlsx-js-style";
import { saveAs } from "file-saver";
import { listdept } from "@/api/system/department"
import { deepCopy } from '@/utils'
@@ -435,51 +435,271 @@ export default {
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;
+ },
+
+ handleExport() {
+ const fileName = '招租管理' + this.$moment().format('YYYY-MM-DD');
+ this.exportExcel(fileName);
+ },
+
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 = filterTableColumns.filter(i => !!i.prop).map((i) => {
+ // 基础列(排除标的物列)
+ let baseHeaders = filterTableColumns.filter(i => !!i.prop && i.prop !== 'assets').map((i) => {
+ // 从 form 中查找字段配置
+ const fieldConfig = this.form.find(f => f.field === i.prop);
return {
key: i.prop,
title: i.label,
+ isNumber: this.isNumericField(fieldConfig, i.label)
};
});
// 添加提交人、提交单位和创建时间到 headers
- headers.push({
+ baseHeaders.push({
key: 'admin.name',
- title: '提交人'
+ title: '提交人',
+ isNumber: false
});
- headers.push({
+ baseHeaders.push({
key: 'department.name',
- title: '提交单位'
+ title: '提交单位',
+ isNumber: false
});
- headers.push({
+ baseHeaders.push({
key: 'created_at',
- title: '创建时间'
+ title: '创建时间',
+ isNumber: false
});
- const data = res.data.map((row) =>
- headers.map((header) => {
+ // 标的物相关列
+ const assetHeaders = [
+ { key: 'asset_name', title: '资产名称', isNumber: false },
+ { key: 'asset_type', title: '分类', isNumber: false },
+ { key: 'asset_zuoluo', title: '坐落', isNumber: false },
+ { key: 'asset_xiangxiweizhi', title: '详细位置', isNumber: false },
+ { key: 'asset_shijimianji', title: '实际面积(m²)', isNumber: true },
+ { key: 'asset_chuzumianji', title: '出租面积(m²)', isNumber: true }
+ ];
+
+ // 完整的 headers(基础列 + 标的物列)
+ const headers = [...baseHeaders, ...assetHeaders];
+
+ // 构建数据行
+ const data = [];
+ const merges = []; // 用于存储合并单元格信息
+
+ res.data.forEach((row, rowIndex) => {
+ const assets = row.id_lets_to_assets_let_id_relation || [];
+ const assetCount = Math.max(1, assets.length); // 至少1行(主数据行或标的物行)
+
+ // 记录当前记录在主数据中的起始行(不包括标题行,从0开始)
+ const startRowIndex = data.length;
+
+ // 构建主数据行
+ const mainRow = baseHeaders.map((header) => {
+ let value;
// 处理提交人、提交单位和创建时间字段
if (header.key === 'admin.name') {
- return row['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 {
+ value = row[header.key];
}
- if (header.key === 'department.name') {
- return row['department']?.name || '';
+
+ // 如果是数字类型字段,确保值是数字类型
+ if (header.isNumber && value !== null && value !== undefined && value !== '') {
+ let numValue;
+ if (typeof value === 'string') {
+ const cleanedValue = value.toString().replace(/[元万元m²㎡\s,,/天]/g, '').trim();
+ numValue = Number(cleanedValue);
+ } else {
+ numValue = Number(value);
+ }
+
+ if (!isNaN(numValue) && numValue !== '') {
+ return numValue;
+ }
}
- if (header.key === 'created_at') {
- return row['created_at'] ? this.$moment(row['created_at']).format('YYYY-MM-DD HH:mm:ss') : '';
+
+ return value;
+ });
+
+ // 辅助函数:获取标的物数据
+ const getAssetData = (asset) => {
+ // 判断资产类型
+ let assetType = '资产';
+ if (asset.house_id) {
+ assetType = '房产';
+ } else if (asset.land_id) {
+ assetType = '土地';
+ } else if (asset.biaodileixing) {
+ assetType = asset.biaodileixing;
}
- return row[header.key];
- })
- );
+
+ // 标的物数据
+ return [
+ asset.name || '',
+ assetType,
+ asset.zuoluo || '',
+ asset.xiangxiweizhi || '',
+ asset.shijimianji || '0',
+ asset.chuzumianji || '0'
+ ];
+ };
+
+ // 主数据行的标的物列:如果有标的物,显示第一个标的物;否则为空
+ let firstAssetData = assets.length > 0 ? getAssetData(assets[0]) : assetHeaders.map(() => '');
+ const mainRowWithAssets = [...mainRow, ...firstAssetData];
+ data.push(mainRowWithAssets);
+
+ // 添加剩余的标的物行(从第二个开始)
+ if (assets.length > 1) {
+ for (let i = 1; i < assets.length; i++) {
+ const assetRow = baseHeaders.map(() => ''); // 基础列为空
+ const assetData = getAssetData(assets[i]);
+ data.push([...assetRow, ...assetData]);
+ }
+ } else if (assets.length === 0) {
+ // 如果没有标的物,添加一行空的标的物行
+ const emptyAssetRow = baseHeaders.map(() => '');
+ const emptyAssetData = assetHeaders.map(() => '');
+ data.push([...emptyAssetRow, ...emptyAssetData]);
+ }
+
+ // 如果有多行(主数据行 + 标的物行),需要合并主数据列
+ if (assetCount > 1) {
+ const endRowIndex = data.length - 1; // 结束行索引(不包括标题行)
+ baseHeaders.forEach((header, colIndex) => {
+ merges.push({
+ s: { r: startRowIndex + 1, c: colIndex }, // +1 因为标题行
+ e: { r: endRowIndex + 1, c: colIndex } // +1 因为标题行
+ });
+ });
+ }
+ });
+
+ // 添加标题行
data.unshift(headers.map((header) => header.title));
+
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet(data);
+
+ // 应用合并单元格
+ if (merges.length > 0) {
+ ws['!merges'] = merges;
+ }
+
+ // 定义样式
+ const headerStyle = {
+ font: { bold: true, color: { rgb: "FFFFFF" } },
+ fill: { fgColor: { rgb: "4472C4" } }, // 蓝色背景
+ alignment: { horizontal: "center", vertical: "center" },
+ border: {
+ top: { style: "thin", color: { rgb: "000000" } },
+ bottom: { style: "thin", color: { rgb: "000000" } },
+ left: { style: "thin", color: { rgb: "000000" } },
+ right: { style: "thin", color: { rgb: "000000" } }
+ }
+ };
+
+ const cellStyle = {
+ alignment: { horizontal: "center", vertical: "center" },
+ border: {
+ top: { style: "thin", color: { rgb: "000000" } },
+ bottom: { style: "thin", color: { rgb: "000000" } },
+ left: { style: "thin", color: { rgb: "000000" } },
+ right: { style: "thin", color: { rgb: "000000" } }
+ }
+ };
+
+ // 设置所有单元格的样式和数字格式
+ const range = XLSX.utils.decode_range(ws['!ref']);
+ for (let R = 0; R <= range.e.r; R++) {
+ for (let C = 0; C <= range.e.c; C++) {
+ const cellAddress = XLSX.utils.encode_cell({ r: R, c: C });
+ if (!ws[cellAddress]) {
+ // 如果单元格不存在,创建一个空单元格
+ ws[cellAddress] = { v: '', t: 's' };
+ }
+
+ const cell = ws[cellAddress];
+ const header = headers[C];
+
+ // 设置样式:标题行使用 headerStyle,其他行使用 cellStyle
+ if (R === 0) {
+ // 标题行
+ cell.s = JSON.parse(JSON.stringify(headerStyle));
+ } else {
+ // 数据行
+ cell.s = JSON.parse(JSON.stringify(cellStyle));
+ }
+
+ // 处理数字类型字段
+ if (header && header.isNumber && R > 0) {
+ let numValue;
+
+ // 处理单元格值,转换为数字
+ if (typeof cell.v === 'string') {
+ 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('元') || header.title.includes('单价') || header.title.includes('租金') || header.title.includes('底价') || header.title.includes('评估'))) {
+ cell.z = '#,##0.00'; // 金额保留2位小数
+ } else if (header.title && (header.title.includes('天') || header.title.includes('期'))) {
+ cell.z = '#,##0'; // 天数整数格式
+ } else {
+ cell.z = '#,##0'; // 整数格式
+ }
+ }
+ }
+ }
+ }
+
+ // 设置列宽(可选,让表格更美观)
+ const colWidths = headers.map(() => ({ wch: 15 })); // 默认列宽15
+ ws['!cols'] = colWidths;
+
XLSX.utils.book_append_sheet(wb, ws, sheetName);
const wbout = XLSX.write(wb, {
bookType: "xlsx",
@@ -732,6 +952,119 @@ export default {
label: "序号",
formatter: (row, column, cellValue, index) => (this.$refs['xyTable'].selectOpt.page - 1) * this.$refs['xyTable'].selectOpt.page_size + index + 1
})
+ this.table.unshift({
+ label: "标的物",
+ prop: 'assets',
+ width: 320,
+ align: 'left',
+ customFn: row => {
+ if (!row.id_lets_to_assets_let_id_relation || row.id_lets_to_assets_let_id_relation.length === 0) {
+ return -
+ }
+
+ // 判断资产类型:有 house_id 是房产,有 land_id 是土地,都没有则根据 biaodileixing 判断
+ const getAssetType = (item) => {
+ if (item.house_id) return '房产'
+ if (item.land_id) return '土地'
+ if (item.biaodileixing) return item.biaodileixing
+ return '资产'
+ }
+
+ let tags = row.id_lets_to_assets_let_id_relation.slice(0, 1).map(i => {
+ const assetType = getAssetType(i)
+ const assetName = i.name || " "
+ const detailLocation = i.xiangxiweizhi || ""
+ return (
+