duyufeng 3 months ago
parent
commit
c76dcaa7c5
  1. 8
      hx-ai-intelligent/src/api/planToAdd.ts
  2. 4
      hx-ai-intelligent/src/components/ns-modal-form.vue
  3. 22
      hx-ai-intelligent/src/icon/fenzujiedian.svg
  4. 11
      hx-ai-intelligent/src/icon/jisuanjiedian.svg
  5. 210
      hx-ai-intelligent/src/util/ExcelUtil.js
  6. 220
      hx-ai-intelligent/src/util/Export2Excel.js
  7. 30
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonAssets/carbonAssetsDetail/index.vue
  8. 5
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonAssets/index.vue
  9. 45
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/energyConsumption/index.vue
  10. 26
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/quickCalculation/index.vue
  11. 110
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/config.ts
  12. 104
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/fillInPage/index.vue
  13. 7
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/index.vue
  14. 81
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/category/categoryDeatil.vue
  15. 7
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/category/index.vue
  16. 36
      hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/index.vue
  17. 62
      hx-ai-intelligent/src/view/equipmentControl/planToAdd/index.vue
  18. 13
      hx-ai-intelligent/src/view/monitor/environmentMonitor/averageData/index.vue
  19. 62
      hx-ai-intelligent/src/view/monitor/environmentMonitor/historyData/index.vue
  20. 8
      lib/component/table/table.vue
  21. 5
      lib/component/tree/tree-api.vue

8
hx-ai-intelligent/src/api/planToAdd.ts

@ -1,7 +1,9 @@
import { BASE_URL } from './index'; import { BASE_URL } from './index';
export enum planToAddApi { export enum planToAddApi {
getActivatedPlanTree = `${BASE_URL}/api/deviceCtrlPlan/getActivatedPlanTree`, //计划树 getActivatedPlanTree = `${BASE_URL}/api/deviceCtrlPlan/getPlanLibTree`, //计划树
getActivatedPlanListByTree = `${BASE_URL}/api/deviceCtrlPlan/getActivatedPlanListByTree`, //计划列表 getActivatedPlanListByTree = `${BASE_URL}/api/deviceCtrlPlan/getPageAblePlanListByTree`, //计划列表
updPlan = `${BASE_URL}/api/deviceCtrlPlan/updateActivatedPlan`, //修改计划 updPlan = `${BASE_URL}/api/deviceCtrlPlan/updateCtrlPlan`, //修改计划
delPlan = `${BASE_URL}/api/deviceCtrlPlan/deleteCtrlPlanByIdList`, //修改计划
addPlan = `${BASE_URL}/api/deviceCtrlPlan/addCtrlPlan`, //添加计划
} }

4
hx-ai-intelligent/src/components/ns-modal-form.vue

@ -66,10 +66,14 @@
httpRequest({ api, params: data, pathParams: params, requestConfig }) httpRequest({ api, params: data, pathParams: params, requestConfig })
.then((res) => { .then((res) => {
if (res.msg === 'success') {
NsMessage.success('操作成功', 1, () => { NsMessage.success('操作成功', 1, () => {
toggle(); toggle();
success && success(res); success && success(res);
}); });
} else {
NsMessage.error(res.msg);
}
}) })
.finally(() => { .finally(() => {
setLoading(false); setLoading(false);

22
hx-ai-intelligent/src/icon/fenzujiedian.svg

@ -1,10 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="8.98974609375" height="8.14453125" viewBox="0 0 8.98974609375 8.14453125" fill="none"> <svg xmlns="http://www.w3.org/2000/svg" width="12.34" height="10.758" viewBox="0 0 12.34 10.758">
<path d="M7.93101 4.53462L6.23624 4.53462L5.52032 3.46466L6.49265 1.79796L5.44381 0L3.32621 0L2.27236 1.79796L3.29704 3.54617L2.62652 4.54987L1.05875 4.54987L0 6.34726L1.05875 8.1452L3.17144 8.1452L4.06128 6.62695L4.93729 6.62695L5.81886 8.13029L7.93102 8.13029L8.98978 6.33258L7.93101 4.53462ZM3.19734 4.59392L3.8643 3.59569L5.00553 3.59569L5.73168 4.68208L4.88461 6.1274L4.09644 6.1274L3.19734 4.59392Z" fill="url(#linear_fill_60_2513)" > <g id="组_6" data-name="组 6" transform="translate(-614 -150.796)">
</path> <g id="组_2" data-name="组 2" transform="translate(614 150.796)">
<defs> <path id="路径_4" data-name="路径 4" d="M67.653,196.269H56.4a.537.537,0,0,1-.541-.533v-8.743a.537.537,0,0,1,.541-.533H67.653a.537.537,0,0,1,.541.533v8.743A.537.537,0,0,1,67.653,196.269Z" transform="translate(-55.854 -185.512)" fill="#ffa000"/>
<linearGradient id="linear_fill_60_2513" x1="4.494873046875" y1="0" x2="4.494873046875" y2="8.14453125" gradientUnits="userSpaceOnUse"> <path id="路径_5" data-name="路径 5" d="M61.866,119.866H55.854v-2.911a.55.55,0,0,1,.527-.569H60.5a.535.535,0,0,1,.507.406l.863,3.074Z" transform="translate(-55.854 -116.387)" fill="#ffa000"/>
<stop offset="0" stop-color="#4DACE6" /> <path id="路径_6" data-name="路径 6" d="M158.881,264.762h-9.094a.521.521,0,0,1-.516-.526v-7.173a.521.521,0,0,1,.516-.526h9.094a.521.521,0,0,1,.516.526v7.173A.517.517,0,0,1,158.881,264.762Z" transform="translate(-148.006 -254.637)" fill="#fff"/>
<stop offset="1" stop-color="#2A93D5" /> <path id="路径_7" data-name="路径 7" d="M67.653,334.52H56.4a.535.535,0,0,1-.541-.528v-6.855a.535.535,0,0,1,.541-.528H67.653a.535.535,0,0,1,.541.528v6.855A.535.535,0,0,1,67.653,334.52Z" transform="translate(-55.854 -323.762)" fill="#ffca28"/>
</linearGradient> <path id="路径_8" data-name="路径 8" d="M129.146,444H126.2a.291.291,0,0,1,0-.58h2.941a.291.291,0,0,1,.007.581Zm0,1.951H126.2a.281.281,0,0,1-.27-.29.277.277,0,0,1,.27-.291h2.941a.281.281,0,0,1,.27.291.276.276,0,0,1-.263.29Z" transform="translate(-124.979 -438.985)" fill="#fff8e1"/>
</defs> </g>
<g id="组_3" data-name="组 3" transform="translate(622.818 153.637)">
<path id="路径_12" data-name="路径 12" d="M667.159,350.215V355.2l1.215-1.327,1.3,1.42v-5.076" transform="translate(-667.159 -350.215)" fill="#2778ff"/>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 888 B

After

Width:  |  Height:  |  Size: 1.7 KiB

11
hx-ai-intelligent/src/icon/jisuanjiedian.svg

@ -1,10 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="9.1005859375" height="9.099609375" viewBox="0 0 9.1005859375 9.099609375" fill="none"> <svg xmlns="http://www.w3.org/2000/svg" width="8" height="13" viewBox="0 0 8 13">
<path d="M7.01762 4.69157L2.30136 4.69157C2.04227 4.66303 1.84615 4.44409 1.84615 4.18343C1.84615 3.92276 2.04227 3.70384 2.30136 3.67525L7.01762 3.67525C7.27673 3.70384 7.47285 3.92276 7.47285 4.18343C7.47285 4.44409 7.27673 4.66303 7.01762 4.69157ZM7.01762 6.69587L2.30136 6.69587C2.04227 6.6673 1.84615 6.44837 1.84615 6.18771C1.84615 5.92704 2.04227 5.70809 2.30136 5.67952L7.01762 5.67952C7.27673 5.70809 7.47285 5.92704 7.47285 6.18771C7.47285 6.44837 7.27673 6.6673 7.01762 6.69587ZM9.09498 8.33346L9.09498 1.98149C9.09498 1.21918 8.46167 1.27564 8.46167 1.27564L4.88941 1.27564C4.77006 1.27634 4.65399 1.23653 4.56021 1.16271C4.56021 1.16271 4.40816 0.880585 4.12926 0.428757C3.87605 -0.0795288 3.54708 0.00531769 3.54708 0.00531769L0.785301 0.00531769C0 0.00531769 0 0.824379 0 0.824379L0 8.27722C0 9.2087 0.633301 9.09628 0.633301 9.09628L8.53744 9.09628C9.19643 9.09547 9.09498 8.33345 9.09498 8.33345L9.09498 8.33346Z" fill="url(#linear_fill_60_2485)" > <path id="路径_14" data-name="路径 14" d="M320.7,183.7h-6a1,1,0,0,0-1,1v11.875a.124.124,0,0,0,.2.1l3.65-2.875a.252.252,0,0,1,.3,0l3.65,2.875a.124.124,0,0,0,.2-.1V184.7A1,1,0,0,0,320.7,183.7Zm-.656,3.334a.486.486,0,0,1-.486.486h-4a.486.486,0,1,1,0-.973h4A.486.486,0,0,1,320.044,187.034Zm0-2.039a.486.486,0,0,1-.486.486h-4a.486.486,0,1,1,0-.973h4A.488.488,0,0,1,320.044,184.995Z" transform="translate(-313.7 -183.7)" fill="#2778ff"/>
</path>
<defs>
<linearGradient id="linear_fill_60_2485" x1="4.55029296875" y1="0" x2="4.55029296875" y2="9.099609375" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#4DACE6" />
<stop offset="1" stop-color="#2A93D5" />
</linearGradient>
</defs>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 527 B

210
hx-ai-intelligent/src/util/ExcelUtil.js

@ -0,0 +1,210 @@
/* eslint-disable */
/** Excel
* npm install xlsx file-saver -S
* npm install script-loader -S -D
*/
import ExcelJS from 'exceljs';
import FileSaver from 'file-saver';
// export default exportExcel;
// 导出excel文件
export function exportExcel (tableColumns,data,fillName,isMerge,start,end) {
if (!data || data.length == 0) {
return;
}
// 创建工作簿
const workbook = new ExcelJS.Workbook();
// 添加工作表,名为sheet1
const sheet1 = workbook.addWorksheet('sheet1');
// 导出的表头名
let tHeader = ['序号'];
// 字段名
let filterVal = ['index'];
// 表格columns
let columns = [{ header: '序号', key: 'index', width: 10 }];
for (let i = 0; i < tableColumns.length; i++) {
if (tableColumns[i].dataIndex) {
tHeader.push(tableColumns[i].title);
filterVal.push(tableColumns[i].dataIndex);
columns.push({
header: tableColumns[i].title,
key: tableColumns[i].dataIndex,
width: tableColumns[i].width / 5,
});
}
}
//传入的数据
const list = data;
const datas = formatJson(filterVal, list);
// // 导出数据列表
// const data = [
// { 姓名: '张三', 年龄: 18, 身高: 175, 体重: 74 },
// { 姓名: '李四', 年龄: 22, 身高: 177, 体重: 84 },
// { 姓名: '王五', 年龄: 53, 身高: 155, 体重: 64 },
// ];
// 获取表头所有键
// const headers = Object.keys(data[0]);
sheet1.columns = columns;
// // 将标题写入第一行
// sheet1.addRow(tHeader);
// 将数据写入工作表
datas.forEach((row) => {
// const values = Object.values(row);
sheet1.addRow(row);
});
// 判断是否合并单元格
if (isMerge) {
debugger
// 遍历列,从第一列到 end 列
for (let col = start; col <= end; col++) {
// let mergeStartRow = 2; // 每次新列开始时,重置起始行
for (let row = 3; row <= datas.length + 1; row++) {
const currentCellValue = sheet1.getCell(row, col).value;
const previousCellValue = sheet1.getCell(row - 1, col).value;
let currentCellValue_1 = ''
let previousCellValue_1 = ''
if (col > 1) {
currentCellValue_1 = sheet1.getCell(row, col-1).value;
previousCellValue_1 = sheet1.getCell(row - 1, col-1).value;
}
if (currentCellValue === previousCellValue && currentCellValue_1 === previousCellValue_1) {
// 当前列有变化,检查是否需要合并前面的单元格
// if (mergeStartRow < row - 1) {
// 只有在前面的行有超过1个时才合并
sheet1.mergeCells(row, col, row - 1, col);
// }
// 更新起始行
// mergeStartRow = row;
}
// // 如果是最后一行,检查是否需要合并
// if (row === datas.length + 1 && mergeStartRow < row) {
// sheet1.mergeCells(mergeStartRow, col, row, col);
// }
}
}
// 从第一列开始逐列检查,前提是前面的列已合并
// for (let col = start; col <= end; col++) {
// let startRow = 2; // 从数据开始的第二行开始检查
// let endRow = 2;
// while (endRow <= sheet1.rowCount) {
// let currentValue = sheet1.getCell(endRow, col).value;
// let prevValue = sheet1.getCell(endRow - 1, col).value;
// // 如果当前值等于前一个值,且前面的列是合并的,则继续合并
// if (currentValue === prevValue) {
// let mergeAllowed = true;
// for (let prevCol = 1; prevCol < col; prevCol++) {
// let range = sheet1.getCell(endRow - 1, prevCol).master;
// if (range && range.row !== startRow) {
// mergeAllowed = false;
// break;
// }
// }
// if (mergeAllowed) {
// endRow++;
// } else {
// // 不允许合并,直接移动起始行到当前行
// startRow = endRow;
// endRow++;
// }
// } else {
// // 当前值不等于前一个值或合并不允许,进行合并操作
// if (startRow < endRow - 1) {
// sheet1.mergeCells(startRow, col, endRow - 1, col);
// }
// startRow = endRow;
// endRow++;
// }
// }
// // 处理最后一段相同的单元格
// if (startRow < endRow - 1) {
// sheet1.mergeCells(startRow, col, endRow - 1, col);
// }
// }
}
// 修改所有单元格样式
// 遍历每一行
sheet1.eachRow((row, rowNumber) => {
// 遍历每个单元格
row.eachCell((cell) => {
// 设置边框样式
cell.border = {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' },
};
// 设置居中对齐
cell.alignment = {
vertical: 'middle',
horizontal: 'center',
};
});
});
// 获取标题行数据
const titleCell = sheet1.getRow(1);
// 设置行高为30
titleCell.height = 30;
// 设置标题行单元格样式
titleCell.eachCell((cell) => {
// 设置标题行背景颜色为黄色
cell.fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FFFFFF' },
};
// 设置标题行字体
cell.font = {
// color: { argb: 'FF0000' }, //颜色为红色
bold: true, // 字体粗体
size: 18, // 设置字体大小为18
};
});
// 获取第二行到最后一行的内容数据
const bodyRows = sheet1.getRows(2, sheet1.rowCount);
// 处理内容行的数据
bodyRows.forEach((bodyRow) => {
// 设置行高为20
bodyRow.height = 20;
bodyRow.eachCell((cell) => {
cell.font = {
size: 16, // 设置内容行字体大小为16
};
});
});
// 导出表格文件
workbook.xlsx
.writeBuffer()
.then((buffer) => {
let file = new Blob([buffer], { type: 'application/octet-stream' });
FileSaver.saveAs(file, fillName + '.xlsx');
})
.catch((error) => console.log('Error writing excel export', error));
};
/**
* 格式化表格数据
* @filterVal 格式头
* @jsonData 用来格式化的表格数据
*/
function formatJson (filterVal, jsonData) {
return jsonData.map((v) => filterVal.map((j) => v[j]));
};

220
hx-ai-intelligent/src/util/Export2Excel.js

@ -1,220 +0,0 @@
/* eslint-disable */
import { saveAs } from 'file-saver'
import XLSX from 'xlsx'
function generateArray(table) {
var out = [];
var rows = table.querySelectorAll('tr');
var ranges = [];
for (var R = 0; R < rows.length; ++R) {
var outRow = [];
var row = rows[R];
var columns = row.querySelectorAll('td');
for (var C = 0; C < columns.length; ++C) {
var cell = columns[C];
var colspan = cell.getAttribute('colspan');
var rowspan = cell.getAttribute('rowspan');
var cellValue = cell.innerText;
if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
//Skip ranges
ranges.forEach(function (range) {
if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {
for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
}
});
//Handle Row Span
if (rowspan || colspan) {
rowspan = rowspan || 1;
colspan = colspan || 1;
ranges.push({
s: {
r: R,
c: outRow.length
},
e: {
r: R + rowspan - 1,
c: outRow.length + colspan - 1
}
});
};
//Handle Value
outRow.push(cellValue !== "" ? cellValue : null);
//Handle Colspan
if (colspan)
for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
}
out.push(outRow);
}
return [out, ranges];
};
function datenum(v, date1904) {
if (date1904) v += 1462;
var epoch = Date.parse(v);
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = {
s: {
c: 10000000,
r: 10000000
},
e: {
c: 0,
r: 0
}
};
for (var R = 0; R != data.length; ++R) {
for (var C = 0; C != data[R].length; ++C) {
if (range.s.r > R) range.s.r = R;
if (range.s.c > C) range.s.c = C;
if (range.e.r < R) range.e.r = R;
if (range.e.c < C) range.e.c = C;
var cell = {
v: data[R][C]
};
if (cell.v == null) continue;
var cell_ref = XLSX.utils.encode_cell({
c: C,
r: R
});
if (typeof cell.v === 'number') cell.t = 'n';
else if (typeof cell.v === 'boolean') cell.t = 'b';
else if (cell.v instanceof Date) {
cell.t = 'n';
cell.z = XLSX.SSF._table[14];
cell.v = datenum(cell.v);
} else cell.t = 's';
ws[cell_ref] = cell;
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
return ws;
}
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook();
this.SheetNames = [];
this.Sheets = {};
}
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
export function export_table_to_excel(id) {
var theTable = document.getElementById(id);
var oo = generateArray(theTable);
var ranges = oo[1];
/* original data */
var data = oo[0];
var ws_name = "SheetJS";
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data);
/* add ranges to worksheet */
// ws['!cols'] = ['apple', 'banan'];
ws['!merges'] = ranges;
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {
bookType: 'xlsx',
bookSST: false,
type: 'binary'
});
saveAs(new Blob([s2ab(wbout)], {
type: "application/octet-stream"
}), "test.xlsx")
}
export function export_json_to_excel({
multiHeader = [],
header,
data,
filename,
merges = [],
autoWidth = true,
bookType = 'xlsx'
} = {}) {
/* original data */
filename = filename || 'excel-list'
data = [...data]
data.unshift(header);
for (let i = multiHeader.length - 1; i > -1; i--) {
data.unshift(multiHeader[i])
}
var ws_name = "SheetJS";
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data);
if (merges.length > 0) {
if (!ws['!merges']) ws['!merges'] = [];
merges.forEach(item => {
ws['!merges'].push(XLSX.utils.decode_range(item))
})
}
if (autoWidth) {
/*设置worksheet每列的最大宽度*/
const colWidth = data.map(row => row.map(val => {
/*先判断是否为null/undefined*/
if (val == null) {
return {
'wch': 10
};
}
/*再判断是否为中文*/
else if (val.toString().charCodeAt(0) > 255) {
return {
'wch': val.toString().length * 2
};
} else {
return {
'wch': val.toString().length
};
}
}))
/*以第一行为初始值*/
let result = colWidth[0];
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j]['wch'] < colWidth[i][j]['wch']) {
result[j]['wch'] = colWidth[i][j]['wch'];
}
}
}
ws['!cols'] = result;
}
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {
bookType: bookType,
bookSST: false,
type: 'binary'
});
saveAs(new Blob([s2ab(wbout)], {
type: "application/octet-stream"
}), `${filename}.${bookType}`);
}

30
hx-ai-intelligent/src/view/carbonEmissionManage/carbonAssets/carbonAssetsDetail/index.vue

@ -20,10 +20,11 @@
</a-form-item> </a-form-item>
<a-form-item> <a-form-item>
<a-cascader <a-cascader
v-model:value="queryParams.transactionType" v-model:value="transactionType"
multiple multiple
style="width: 200px" style="width: 200px"
:options="options" :options="options"
@change="changeSelect"
placeholder="请选择交易类型" placeholder="请选择交易类型"
suffix-icon="Shopping Around"> suffix-icon="Shopping Around">
<template #tagRender="data"> <template #tagRender="data">
@ -49,7 +50,7 @@
</div> </div>
<div style="display: flex; margin-top: 20px; height: calc(84% - 20px)"> <div style="display: flex; margin-top: 20px; height: calc(84% - 20px)">
<div class="detailTable"> <div class="detailTable">
<ns-view-list-table v-bind="tableConfig" :model="data" ref="mainRef" :scroll="{ x: 2000 }"> <ns-view-list-table v-bind="tableConfig" :model="data" ref="mainRef" :scroll="{ x: 1280 }">
<template #bodyCell="{ column, text, record }"> <template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'accountType'"> <template v-if="column.dataIndex === 'accountType'">
<span v-if="record.accountType">{{ record.accountType.label }}</span> <span v-if="record.accountType">{{ record.accountType.label }}</span>
@ -195,6 +196,7 @@
}; };
const total = ref<number>(); const total = ref<number>();
const year = ref(new Date().getFullYear().toString()); const year = ref(new Date().getFullYear().toString());
const transactionType = ref();
const queryParams = ref({ const queryParams = ref({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
@ -202,9 +204,16 @@
accountType: props.parentId, accountType: props.parentId,
year: year.value, year: year.value,
}); });
const transactionTypeValue = ref();
const changeSelect = (value, selectedOptions) => {
transactionTypeValue.value = selectedOptions.flatMap((group) =>
group.flatMap((node) => [node.value, ...(node.children?.map((child) => child.value) || [])]),
);
};
const searchTableList = () => { const searchTableList = () => {
year.value = queryParams.value.year; year.value = queryParams.value.year;
transactionType.value = queryParams.value.transactionType; transactionTypeList.value = transactionTypeValue.value;
queryParams.value.transactionTypeList = transactionTypeValue.value;
accountType.value = queryParams.value.accountType; accountType.value = queryParams.value.accountType;
getTotalTable(queryParams.value.accountType); getTotalTable(queryParams.value.accountType);
mainRef.value?.nsTableRef.reload(); mainRef.value?.nsTableRef.reload();
@ -283,6 +292,9 @@
accountType.value = props.parentId; accountType.value = props.parentId;
year.value = new Date().getFullYear(); year.value = new Date().getFullYear();
transactionType.value = ''; transactionType.value = '';
transactionTypeList.value = [];
queryParams.value.transactionTypeList = transactionTypeList.value;
getTotalTable();
mainRef.value?.nsTableRef.reload(); mainRef.value?.nsTableRef.reload();
// getDetailList(); // getDetailList();
}; };
@ -364,7 +376,7 @@
}; };
const mainRef = ref(); const mainRef = ref();
const transactionType = ref(); const transactionTypeList = ref([]);
const accountType = ref(); const accountType = ref();
accountType.value = props.parentId; accountType.value = props.parentId;
const tableConfig = ref({ const tableConfig = ref({
@ -373,6 +385,7 @@
params: { params: {
orgId, orgId,
accountType, accountType,
transactionTypeList,
year, year,
}, },
headerActions: [ headerActions: [
@ -467,40 +480,49 @@
{ {
title: '资产类别', title: '资产类别',
dataIndex: 'accountType', dataIndex: 'accountType',
width: 100,
}, },
{ {
title: '交易方式', title: '交易方式',
dataIndex: 'transactionTypeName', dataIndex: 'transactionTypeName',
width: 100,
}, },
{ {
title: '交易日期', title: '交易日期',
dataIndex: 'transactionDate', dataIndex: 'transactionDate',
width: 100,
sorter: (a, b) => a.transactionDate - b.transactionDate, sorter: (a, b) => a.transactionDate - b.transactionDate,
}, },
{ {
title: '本期收入(tCO2)', title: '本期收入(tCO2)',
dataIndex: 'income', dataIndex: 'income',
width: 150,
sorter: (a, b) => a.income - b.income, sorter: (a, b) => a.income - b.income,
}, },
{ {
title: '本期支出(tCO2)', title: '本期支出(tCO2)',
dataIndex: 'expenditure', dataIndex: 'expenditure',
width: 150,
sorter: (a, b) => a.expenditure - b.expenditure, sorter: (a, b) => a.expenditure - b.expenditure,
}, },
{ {
title: '发生金额(¥)', title: '发生金额(¥)',
width: 150,
dataIndex: 'amountIncurredValue', dataIndex: 'amountIncurredValue',
}, },
{ {
title: '交易对象', title: '交易对象',
width: 100,
dataIndex: 'tradingPartner', dataIndex: 'tradingPartner',
}, },
{ {
title: '更新人', title: '更新人',
width: 100,
dataIndex: 'updateUser', dataIndex: 'updateUser',
}, },
{ {
title: '更新时间', title: '更新时间',
width: 150,
dataIndex: 'updateTime', dataIndex: 'updateTime',
}, },
], ],

5
hx-ai-intelligent/src/view/carbonEmissionManage/carbonAssets/index.vue

@ -2,7 +2,9 @@
<div class="mainContant" v-if="homePage"> <div class="mainContant" v-if="homePage">
<a-card class="card" v-if="nationwide" style="margin-right: 1%; margin-bottom: 1%"> <a-card class="card" v-if="nationwide" style="margin-right: 1%; margin-bottom: 1%">
<div class="top" style="background: rgba(252, 139, 78, 0.05)"> <div class="top" style="background: rgba(252, 139, 78, 0.05)">
<div class="moneyImg"><img width="68" height="68" src="../../../../src/icon/carbonAssetsMoney-1.svg" /></div> <div class="moneyImg"
><img width="68" height="68" src="../../../../src/icon/carbonAssetsMoney-1.svg"
/></div>
<div class="moneyTitle">全国碳账户估值CNY</div> <div class="moneyTitle">全国碳账户估值CNY</div>
<div class="moneyTotal" style="color: rgba(229, 102, 22, 1)">{{ <div class="moneyTotal" style="color: rgba(229, 102, 22, 1)">{{
nationwide.valuation nationwide.valuation
@ -369,6 +371,7 @@
background: linear-gradient(180deg, rgba(244, 252, 250, 1) 0%, rgba(255, 255, 255, 1) 100%); background: linear-gradient(180deg, rgba(244, 252, 250, 1) 0%, rgba(255, 255, 255, 1) 100%);
border: 1px solid rgba(42, 197, 155, 0.3); border: 1px solid rgba(42, 197, 155, 0.3);
padding: 10px; padding: 10px;
border-radius: 8px;
.money { .money {
opacity: 1; opacity: 1;
font-size: 28px; font-size: 28px;

45
hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/energyConsumption/index.vue

@ -85,7 +85,7 @@
<div class="ns-form-title" style="display: flex"> <div class="ns-form-title" style="display: flex">
<div class="title">凭证上传</div> <div class="title">凭证上传</div>
</div> </div>
<a-upload <!-- <a-upload
:file-list="fileList" :file-list="fileList"
name="file" name="file"
accept=".pdf" accept=".pdf"
@ -109,33 +109,26 @@
<span>1.仅支持pdf格式文件或文件夹</span> <span>1.仅支持pdf格式文件或文件夹</span>
<span>2.文件名命名规则为能源种类_年份</span> <span>2.文件名命名规则为能源种类_年份</span>
<span>3.每次上传自动覆盖</span> <span>3.每次上传自动覆盖</span>
</div> </div> -->
<template #footer>
<a-button style="margin-right: 8px" @click="onClose">取消</a-button>
<a-button type="primary" @click="onSubmit">确定</a-button>
</template>
</a-drawer>
<!-- 上传凭证弹窗 -->
<!-- <a-modal :visible="openUpload" title="凭证上传" @ok="handleOk" @cancel="closeOpenUpload">
<a-upload-dragger <a-upload-dragger
v-model:fileList="fileList" v-model:fileList="fileList"
accept=".pdf"
name="file" name="file"
:multiple="true" @remove="handleFileRemove"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76" :before-upload="beforeUpload"
@change="handleChange" @change="handleChange">
@drop="handleDrop"
>
<p class="ant-upload-drag-icon"> <p class="ant-upload-drag-icon">
<inbox-outlined></inbox-outlined> <inbox-outlined></inbox-outlined>
</p> </p>
<p class="ant-upload-hint" style="display: flex;flex-direction: column;"> <p class="ant-upload-hint">1.仅支持pdf格式文件或文件夹</p>
<p>1.仅支持pdf格式文件或文件夹</p> <p class="ant-upload-hint">2.文件名命名规则为能源种类_年份</p>
<p>2.文件命名规则为能源种类_年份</p> <p class="ant-upload-hint">3.每次上传自动覆盖</p>
<p>3.每次上传自动覆盖</p>
</p>
</a-upload-dragger> </a-upload-dragger>
</a-modal> --> <template #footer>
<a-button style="margin-right: 8px" @click="onClose">取消</a-button>
<a-button type="primary" @click="onSubmit">确定</a-button>
</template>
</a-drawer>
<!-- 凭证下载 --> <!-- 凭证下载 -->
<a-drawer <a-drawer
:visible="downLoadVisible" :visible="downLoadVisible"
@ -172,10 +165,10 @@
</template> </template>
</template> </template>
</a-table> </a-table>
<template #footer> <!-- <template #footer>
<a-button style="margin-right: 8px" @click="onCloseDownLoad">取消</a-button> <a-button style="margin-right: 8px" @click="onCloseDownLoad">取消</a-button>
<a-button type="primary" @click="onSubmitDownLoad">确定</a-button> <a-button type="primary" @click="onSubmitDownLoad">确定</a-button>
</template> </template> -->
</a-drawer> </a-drawer>
</div> </div>
</template> </template>
@ -183,7 +176,7 @@
import { ref, toRaw, defineExpose, createVNode } from 'vue'; import { ref, toRaw, defineExpose, createVNode } from 'vue';
import type { Rule } from 'ant-design-vue/es/form'; import type { Rule } from 'ant-design-vue/es/form';
import { Pagination, message, Modal, Upload } from 'ant-design-vue'; import { Pagination, message, Modal, Upload } from 'ant-design-vue';
import { UploadOutlined } from '@ant-design/icons-vue'; import { UploadOutlined, InboxOutlined } from '@ant-design/icons-vue';
import type { TreeSelectProps, UploadChangeParam, UploadProps } from 'ant-design-vue'; import type { TreeSelectProps, UploadChangeParam, UploadProps } from 'ant-design-vue';
import { NsMessage } from '/nerv-lib/component'; import { NsMessage } from '/nerv-lib/component';
import dayjs, { Dayjs } from 'dayjs'; import dayjs, { Dayjs } from 'dayjs';
@ -1174,6 +1167,10 @@
:deep(.ant-table-container) { :deep(.ant-table-container) {
padding: unset; padding: unset;
} }
:deep(.ant-upload.ant-upload-drag) {
height: 18vh;
margin-top: 10px;
}
</style> </style>
<style scoped> <style scoped>
th.column-money, th.column-money,

26
hx-ai-intelligent/src/view/carbonEmissionManage/carbonEmissionStatistics/quickCalculation/index.vue

@ -119,10 +119,11 @@
<!-- 选择因子 --> <!-- 选择因子 -->
<a-modal <a-modal
v-model:visible="openVisible" v-model:visible="openVisible"
v-if="openVisible"
width="60%" width="60%"
title="选择因子" title="选择因子"
@ok="onSubmit" @ok="btnClick"
@cancel="onClose"> @cancel="onCloseClick">
<ns-view-list-table v-bind="config" ref="setFactorRef" style="height: 500px" /> <ns-view-list-table v-bind="config" ref="setFactorRef" style="height: 500px" />
</a-modal> </a-modal>
</div> </div>
@ -140,6 +141,7 @@
} from '/@/api/carbonEmissionFactorLibrary'; } from '/@/api/carbonEmissionFactorLibrary';
import { or } from '@vueuse/core'; import { or } from '@vueuse/core';
import { setFactorConfig } from '../config'; import { setFactorConfig } from '../config';
import { NsMessage } from '/nerv-lib/saas';
defineOptions({ defineOptions({
energyType: 'quickCalculation', // name energyType: 'quickCalculation', // name
components: { components: {
@ -340,8 +342,8 @@
formState.value.factorId = record.factorId; formState.value.factorId = record.factorId;
text.value = '编辑'; text.value = '编辑';
visible.value = true; visible.value = true;
emissionSources.value = record.emissionSources; emissionSources.value = record.factorId; //todo
queryData.value.emissionSources = emissionSources.value; queryData.value.factorId = emissionSources.value; //todo
getNewTable(); getNewTable();
}, },
}, },
@ -484,10 +486,26 @@
}); });
}; };
const openVisible = ref(false); const openVisible = ref(false);
const setFactorRef = ref();
const config = setFactorConfig(orgId.value); const config = setFactorConfig(orgId.value);
const selectFactor = () => { const selectFactor = () => {
openVisible.value = true; openVisible.value = true;
}; };
const btnClick = () => {
let selectRowKeys = setFactorRef.value?.nsTableRef.tableState.selectedRowKeys;
if (selectRowKeys.length === 0) {
NsMessage.warn('请选择因子');
return;
} else {
newTableData.value = setFactorRef.value?.nsTableRef.tableState.selectedRows;
selectedRowKeys.value = setFactorRef.value?.nsTableRef.tableState.selectedRowKeys;
formState.value.factorId = selectedRowKeys.value[0];
openVisible.value = false;
}
};
const onCloseClick = () => {
openVisible.value = false;
};
// //
const onClose = () => { const onClose = () => {
visible.value = false; visible.value = false;

110
hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/config.ts

@ -1,3 +1,5 @@
import { quickCalculation, carbonEmissionFactorLibrary } from '/@/api/carbonEmissionFactorLibrary';
import { ref } from 'vue';
// 凭证弹窗表头 // 凭证弹窗表头
export const voucherColumns = [ export const voucherColumns = [
{ {
@ -9,8 +11,8 @@ export const voucherColumns = [
}, },
{ {
title: '日期', title: '日期',
dataIndex: 'updateTime', dataIndex: 'bizName',
key: 'updateTime', key: 'bizName',
ellipsis: true, ellipsis: true,
}, },
{ {
@ -42,3 +44,107 @@ export const drawerColumns = [
dataIndex: 'dataSources', dataIndex: 'dataSources',
}, },
]; ];
export const setFactorConfig = (orgId) => {
return ref({
api: carbonEmissionFactorLibrary.getTableList,
params: { orgId, pageNum: 1, pageSize: 9999, emissionList: [0] },
treeConfig: {
header: {
icon: 'deviceType',
title: '排放分类',
},
params: { orgId},
dynamicParams: { emissionList: 'id[]' },
defaultExpandAll: true,
// checkable:true,
api: carbonEmissionFactorLibrary.getCarbonFactorTree,
fieldNames: { title: 'emissionName', key: 'id' },
formConfig: {
schemas: [
{
field: 'deviceType',
label: '设备名称',
component: 'NsInput',
autoSubmit: true,
componentProps: {
placeholder: '请输入关键字',
},
},
],
},
},
rowSelection: { type: 'radio' },
columns: [
{
title: '序号',
textNumber: 2,
dataIndex: 'address',
customRender: (text: any) => {
return text.index + 1;
},
},
{
title: '名称',
dataIndex: 'emissionSources',
textNumber: 3,
},
{
title: '排放因子',
dataIndex: 'emissionFactors',
textNumber: 4,
textEllipsis: true,
},
{
title: '排放因子单位',
dataIndex: 'emissionFactorUnits',
width: 100,
textEllipsis: true,
},
{
title: '排放环节',
dataIndex: 'emissionProcess',
textWidth: 88,
textEllipsis: true,
},
{
title: '数据来源',
dataIndex: 'dataSources',
textNumber: 5,
textEllipsis: true,
},
],
formConfig: {
schemas: [
{
field: 'emissionSources',
label: '排放源',
component: 'NsInput',
componentProps: {
placeholder: '请输入排放源',
maxLength: 20,
},
},
{
field: 'emissionProcess',
label: '排放环节',
component: 'NsSelectApi',
componentProps: {
placeholder: '请选择排放环节',
api: carbonEmissionFactorLibrary.gasAndDatabase,
resultField: 'data',
params: {
orgId: orgId.value,
type: 'emissionProcess',
},
immediate: true,
labelField: 'label',
valueField: 'value',
},
},
],
params: {},
},
// pagination: { pageSizeOptions: false },
rowKey: 'id',
});
};

104
hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/fillInPage/index.vue

@ -106,8 +106,13 @@
<span>{{ data.emissionSource }}</span> <span>{{ data.emissionSource }}</span>
</div> </div>
<div class="actionMore"> <div class="actionMore">
<EditOutlined @click="editUnit(data)" /> <EditOutlined
<MinusCircleOutlined style="margin-left: 6px" @click="delUnit(data)" /> @click="editUnit(data)"
v-if="data.emissionSource !== '全部'" />
<MinusCircleOutlined
v-if="data.emissionSource !== '全部'"
style="margin-left: 6px"
@click="delUnit(data)" />
<PlusCircleOutlined <PlusCircleOutlined
v-if="data.emissionSource === '全部'" v-if="data.emissionSource === '全部'"
style="margin-left: 6px" style="margin-left: 6px"
@ -131,7 +136,7 @@
:pagination="false" :pagination="false"
bordered bordered
size="middle" size="middle"
:scroll="{ y: 380 }"> :scroll="{ x: 660, y: 380 }">
<template #title> <template #title>
<a-button type="primary" @click="downLoadVoucher">凭证</a-button> <a-button type="primary" @click="downLoadVoucher">凭证</a-button>
</template> </template>
@ -373,20 +378,21 @@
@keydown="handleKeyDown" /> @keydown="handleKeyDown" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="24"> <!-- <a-col :span="24">
<a-form-item ref="name" label="关键字" name="key"> <a-form-item ref="name" label="关键字" name="key">
<a-input-search <a-input-search
v-model:value="editFormState.key" v-model:value="editFormState.key"
@search="searchKey" @search="searchKey"
placeholder="请输入关键字" /> placeholder="请输入关键字" />
</a-form-item> </a-form-item>
</a-col> </a-col> -->
</a-row> </a-row>
</a-form> </a-form>
</a-spin> </a-spin>
<div class="ns-form-title-edit" style="display: flex"> <!-- <div class="ns-form-title-edit" style="display: flex">
<div class="titleEdit">因子列表</div> <div class="titleEdit">因子列表</div>
</div> </div> -->
<a-button type="primary" style="margin-bottom: 10px" @click="selectFactor">选择因子</a-button>
<a-table <a-table
:columns="drawerColumns" :columns="drawerColumns"
:data-source="newTableData" :data-source="newTableData"
@ -430,14 +436,23 @@
<inbox-outlined></inbox-outlined> <inbox-outlined></inbox-outlined>
</p> </p>
<p class="ant-upload-hint">1.仅支持pdf格式文件或文件夹</p> <p class="ant-upload-hint">1.仅支持pdf格式文件或文件夹</p>
<p class="ant-upload-hint">2.文件名命名规则为能源种类_年份</p> <p class="ant-upload-hint">2.每次上传自动覆盖</p>
<p class="ant-upload-hint">3.每次上传自动覆盖</p>
</a-upload-dragger> </a-upload-dragger>
<template #footer> <template #footer>
<a-button style="margin-right: 8px" @click="onCloseEditData">取消</a-button> <a-button style="margin-right: 8px" @click="onCloseEditData">取消</a-button>
<a-button type="primary" @click="submitEditData">确定</a-button> <a-button type="primary" @click="submitEditData">确定</a-button>
</template> </template>
</a-drawer> </a-drawer>
<!-- 选择因子 -->
<a-modal
v-model:visible="openVisible"
v-if="openVisible"
width="60%"
title="选择因子"
@ok="btnClick"
@cancel="onCloseClick">
<ns-view-list-table v-bind="config" ref="setFactorRef" style="height: 500px" />
</a-modal>
</div> </div>
</template> </template>
@ -464,6 +479,8 @@
import { group } from '/@/api/deviceManage'; import { group } from '/@/api/deviceManage';
import { debug, log } from 'node:console'; import { debug, log } from 'node:console';
import { dict } from '/@/api'; import { dict } from '/@/api';
import { NsMessage } from '/nerv-lib/saas';
import { setFactorConfig } from '../config';
defineOptions({ defineOptions({
energyType: 'fillInPage', // name energyType: 'fillInPage', // name
components: { components: {
@ -673,12 +690,14 @@
} }
}; };
// //
const carbonEmission = ref();
const getTableHeardUnit = (id) => { const getTableHeardUnit = (id) => {
fetch(carbonInventoryCheck.findUnitById, { id: id }).then((res) => { fetch(carbonInventoryCheck.findUnitById, { id: id }).then((res) => {
if (res.data) { if (res.data) {
columns.value[1].title = '消耗量【' + res.data.unit + '】'; columns.value[1].title = '消耗量【' + res.data.unit + '】';
columns.value[2].title = '碳排因子【' + res.data.carbonEmission + '】'; columns.value[2].title = '碳排因子【' + res.data.carbonEmission + '】';
columns.value[3].title = '排放量【' + res.data.carbonUnits + '】'; columns.value[3].title = '排放量【' + res.data.carbonUnits + '】';
carbonEmission.value = res.data.carbonEmission;
} }
}); });
}; };
@ -879,6 +898,7 @@
{ {
title: '日期', title: '日期',
dataIndex: 'acquisitionDate', dataIndex: 'acquisitionDate',
width: 80,
key: 'acquisitionDate', key: 'acquisitionDate',
}, },
{ {
@ -887,11 +907,13 @@
{ {
title: '数据来源', title: '数据来源',
dataIndex: 'dataSources', dataIndex: 'dataSources',
width: 100,
key: 'dataSources', key: 'dataSources',
}, },
{ {
title: '数值', title: '数值',
dataIndex: 'consumption', dataIndex: 'consumption',
width: 100,
key: 'consumption', key: 'consumption',
}, },
], ],
@ -902,11 +924,13 @@
{ {
title: '数据来源', title: '数据来源',
dataIndex: 'carbonSource', dataIndex: 'carbonSource',
width: 100,
key: 'carbonSource', key: 'carbonSource',
}, },
{ {
title: '数值', title: '数值',
dataIndex: 'emissionFactors', dataIndex: 'emissionFactors',
width: 100,
key: 'emissionFactors', key: 'emissionFactors',
}, },
], ],
@ -914,6 +938,7 @@
{ {
title: '排放量', title: '排放量',
dataIndex: 'emissions', dataIndex: 'emissions',
width: 100,
key: 'emissions', key: 'emissions',
fixed: 'right', fixed: 'right',
}, },
@ -1069,12 +1094,23 @@
// //
const options = await dict({ params: { dicKey: 'ENERGY_TYPE' } }); const options = await dict({ params: { dicKey: 'ENERGY_TYPE' } });
energyTypeOptions.value = options.data.data; energyTypeOptions.value = options.data.data;
editFormState.value.key = record.factorName; editFormState.value.key = record.factorId;
searchKey(); searchKey();
editFormState.value.id = record.id; editFormState.value.id = record.id;
editFormState.value.dataSources = record.dataSources; editFormState.value.dataSources = record.dataSources;
if (record.dataSources !== undefined) {
if (record.dataSources.value === 3) {
canEdit.value = true;
automatic.value = true;
} else {
canEdit.value = false;
automatic.value = false;
}
}
editFormState.value.consumption = record.consumption; editFormState.value.consumption = record.consumption;
editFormState.value.collectionNode = record.carbonSource; editFormState.value.energyConsumptionType = record.energyConsumptionType;
changeEnergyType(record.energyConsumptionType);
editFormState.value.collectionNode = record.collectionNode;
editFormState.value.factorId = record.factorId; editFormState.value.factorId = record.factorId;
editFormState.value.emissionFactors = record.emissionFactors; editFormState.value.emissionFactors = record.emissionFactors;
selectedRowKeysEdit.value = [record.factorId]; selectedRowKeysEdit.value = [record.factorId];
@ -1097,9 +1133,9 @@
}; };
const searchKey = () => { const searchKey = () => {
if (editFormState.value.key) { if (editFormState.value.key) {
queryData.value.emissionSources = editFormState.value.key; queryData.value.factorId = editFormState.value.key;
} else { } else {
queryData.value.emissionSources = ''; queryData.value.factorId = 0;
} }
getNewTable(); getNewTable();
}; };
@ -1137,6 +1173,7 @@
}; };
const spinning = ref(false); const spinning = ref(false);
const selectNode = (value) => { const selectNode = (value) => {
editFormState.value.collectionNode = value;
spinning.value = true; spinning.value = true;
const getConsumeData = ref({ const getConsumeData = ref({
acquisitionDate: acquisitionDate.value, acquisitionDate: acquisitionDate.value,
@ -1198,9 +1235,9 @@
if (editFormState.value.dataSources.value) { if (editFormState.value.dataSources.value) {
editFormState.value.dataSources = editFormState.value.dataSources.value; editFormState.value.dataSources = editFormState.value.dataSources.value;
} }
if (editFormState.value.collectionNode) { // if (editFormState.value.collectionNode) {
editFormState.value.collectionNode = editFormState.value.collectionNode.value; // editFormState.value.collectionNode = editFormState.value.collectionNode.value;
} // }
fetch(carbonInventoryCheck.updateTable, editFormState.value).then((res) => { fetch(carbonInventoryCheck.updateTable, editFormState.value).then((res) => {
if (fileList.value.length !== 0) { if (fileList.value.length !== 0) {
const formData = ref(new FormData()); const formData = ref(new FormData());
@ -1235,6 +1272,32 @@
console.log('error', error); console.log('error', error);
}); });
}; };
const openVisible = ref(false);
const setFactorRef = ref();
const config = setFactorConfig(orgId.value);
const selectFactor = () => {
openVisible.value = true;
};
const btnClick = () => {
let selectRowKeys = setFactorRef.value?.nsTableRef.tableState.selectedRowKeys;
if (selectRowKeys.length === 0) {
NsMessage.warn('请选择因子');
return;
} else {
if (newTableData.value.emissionFactorUnits === carbonEmission.value) {
newTableData.value = setFactorRef.value?.nsTableRef.tableState.selectedRows;
selectedRowKeysEdit.value = setFactorRef.value?.nsTableRef.tableState.selectedRowKeys;
editFormState.value.emissionFactors = newTableData.value[0].emissionFactors;
editFormState.value.factorId = selectedRowKeysEdit.value[0];
openVisible.value = false;
} else {
NsMessage.warn('因子值单位不统一,请重新选择!');
}
}
};
const onCloseClick = () => {
openVisible.value = false;
};
const onCloseEditData = () => { const onCloseEditData = () => {
editData.value = false; editData.value = false;
delIds.value = []; delIds.value = [];
@ -1249,7 +1312,7 @@
const onChange = (pageNumber: number, size: number) => { const onChange = (pageNumber: number, size: number) => {
queryData.value.pageNum = pageNumber; queryData.value.pageNum = pageNumber;
queryData.value.pageSize = size; queryData.value.pageSize = size;
getNewTable(); // getNewTable();
}; };
// / // /
const fillInPage = ref(true); const fillInPage = ref(true);
@ -1730,9 +1793,11 @@
.mainLeft { .mainLeft {
width: 19%; width: 19%;
margin-right: 1%; margin-right: 1%;
border-right: 1px solid #f2f2f2;
position: relative; position: relative;
height: 96%; height: 100%;
border: 1px solid #f2f2f2;
border-radius: 8px;
padding: 4px;
.treeRow { .treeRow {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -1757,6 +1822,7 @@
} }
.mainRight { .mainRight {
width: 80%; width: 80%;
border-left: 1px solid #f2f2f2;
} }
} }

7
hx-ai-intelligent/src/view/carbonEmissionManage/carbonInventoryCheck/index.vue

@ -79,7 +79,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, toRaw } from 'vue'; import { ref, toRaw, watch, nextTick } from 'vue';
import { http } from '/nerv-lib/util/http'; import { http } from '/nerv-lib/util/http';
import { carbonInventoryCheck } from '/@/api/carbonEmissionFactorLibrary'; import { carbonInventoryCheck } from '/@/api/carbonEmissionFactorLibrary';
import fillIn from './fillInPage/index.vue'; import fillIn from './fillInPage/index.vue';
@ -118,7 +118,10 @@
const openChange = (status) => { const openChange = (status) => {
if (status === false) { if (status === false) {
if (formState.value.reportYear) { if (formState.value.reportYear) {
defaultPickerValue.value = [dayjs('2022'), dayjs('2022')]; defaultPickerValue.value = [
dayjs(formState.value.reportYear),
dayjs(formState.value.reportYear),
];
} }
} }
}; };

81
hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/category/categoryDeatil.vue

@ -100,7 +100,6 @@
<a-table-summary-row> <a-table-summary-row>
<a-table-summary-cell></a-table-summary-cell> <a-table-summary-cell></a-table-summary-cell>
<a-table-summary-cell :colSpan="2">合计</a-table-summary-cell> <a-table-summary-cell :colSpan="2">合计</a-table-summary-cell>
<a-table-summary-cell></a-table-summary-cell>
<a-table-summary-cell> <a-table-summary-cell>
<a-typography-text>{{ totalLastYearActualUsage + unit }}</a-typography-text> <a-typography-text>{{ totalLastYearActualUsage + unit }}</a-typography-text>
</a-table-summary-cell> </a-table-summary-cell>
@ -153,24 +152,35 @@
</a-form> </a-form>
</a-modal> </a-modal>
<!-- 基准值设置 --> <!-- 基准值设置 -->
<a-modal :visible="visible" @ok="onSubmit" @cancel="onClose"> <a-modal
:visible="visible"
@ok="onSubmit"
@cancel="onClose"
:style="{ top: '20px', left: '-100px' }"
:bodyStyle="{ maxHeight: '800px', overflowY: 'auto' }">
<a-spin :spinning="loading">
<a-tooltip placement="top"> <a-tooltip placement="top">
<template #title> <template #title>
<span>月基准值设置使用基准年相应月份的数据作为当前年相应月份的基准值</span> <span>月基准值设置使用基准年相应月份的数据作为当前年相应月份的基准值</span>
</template> </template>
<QuestionCircleOutlined style="position: absolute; right: 60px; top: 22px; z-index: 7" /> <QuestionCircleOutlined style="position: absolute; right: 60px; top: 22px; z-index: 7" />
</a-tooltip> </a-tooltip>
<div style="display: flex; margin-top: 20px; justify-content: space-between"> <a-tabs v-model:activeKey="activeKey" @change="handleTabChange">
<a-tab-pane key="1" tab="年基准值设置">
<div
style="
display: flex;
margin-bottom: 10px;
justify-content: space-between;
margin-top: 10px;
">
<span> 节点{{ props.nodeName }} </span> <span> 节点{{ props.nodeName }} </span>
<a-date-picker <a-date-picker
v-if="activeKey === '1'"
v-model:value="selectYear" v-model:value="selectYear"
picker="year" picker="year"
valueFormat="YYYY" valueFormat="YYYY"
@change="changeYearData" /> @change="changeYearData" />
</div> </div>
<a-tabs v-model:activeKey="activeKey" @change="handleTabChange">
<a-tab-pane key="1" tab="年基准值设置">
<a-table <a-table
:columns="yearColumns" :columns="yearColumns"
:data-source="yearTableData" :data-source="yearTableData"
@ -183,9 +193,29 @@
}" }"
:pagination="false"> :pagination="false">
</a-table> </a-table>
<a-pagination
v-model:current="queryData.pageNum"
simple
:total="total"
@change="onChange"
style="display: flex; justify-content: end; margin-top: 10px" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="月基准值设置" force-render> <a-tab-pane key="2" tab="月基准值设置" force-render>
<a-table :columns="monthColumns" :data-source="dataSource" bordered :pagination="false"> <div
style="
display: flex;
margin-bottom: 10px;
justify-content: space-between;
margin-top: 10px;
">
<span> 节点{{ props.nodeName }} </span>
</div>
<a-table
:columns="monthColumns"
:data-source="dataSource"
size="small"
bordered
:pagination="false">
<template #bodyCell="{ column, text, record }"> <template #bodyCell="{ column, text, record }">
<template v-if="['referenceValue'].includes(column.dataIndex)"> <template v-if="['referenceValue'].includes(column.dataIndex)">
<div> <div>
@ -235,6 +265,7 @@
</a-table> </a-table>
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</a-spin>
</a-modal> </a-modal>
</div> </div>
</template> </template>
@ -255,7 +286,13 @@
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { any, string } from 'vue-types'; import { any, string } from 'vue-types';
import type { Dayjs } from 'dayjs'; import type { Dayjs } from 'dayjs';
import { Pagination } from 'ant-design-vue';
defineOptions({
components: {
'a-pagination': Pagination,
},
});
// id // id
const props = defineProps({ const props = defineProps({
parentId: { parentId: {
@ -383,8 +420,10 @@
formState.value.ids = [record.id]; formState.value.ids = [record.id];
if (record.lastYear === '是') { if (record.lastYear === '是') {
formState.value.isLastYear = 1; formState.value.isLastYear = 1;
disabled.value = false;
} else { } else {
formState.value.isLastYear = 0; formState.value.isLastYear = 0;
disabled.value = true;
} }
formState.value.conversionRate = record.conversionRate; formState.value.conversionRate = record.conversionRate;
formState.value.lastYearList = [record.lastYearActualUsage]; formState.value.lastYearList = [record.lastYearActualUsage];
@ -454,7 +493,14 @@
orgId: orgId.value, orgId: orgId.value,
type: props.type, type: props.type,
itemizeId: props.parentId, itemizeId: props.parentId,
pageSize: 10,
pageNum: 1,
}); });
const total = ref();
const onChange = (page, pageSize) => {
queryData.value.pageNum = page;
setBasicData();
};
const changeYearData = () => { const changeYearData = () => {
queryData.value.referenceYear = selectYear.value; queryData.value.referenceYear = selectYear.value;
setBasicData(); setBasicData();
@ -462,7 +508,8 @@
const yearTableData = ref([]); const yearTableData = ref([]);
const setBasicData = () => { const setBasicData = () => {
fetch(carbonPlanning.benchmarkSetting, queryData.value).then((res) => { fetch(carbonPlanning.benchmarkSetting, queryData.value).then((res) => {
yearTableData.value = res.data; yearTableData.value = res.data.records;
total.value = res.data.total;
}); });
visible.value = true; visible.value = true;
}; };
@ -507,6 +554,7 @@
{ {
title: '日期', title: '日期',
dataIndex: 'yearMonth', dataIndex: 'yearMonth',
width: '20%',
}, },
{ {
title: '用电量', title: '用电量',
@ -543,7 +591,9 @@
const cancel = (yearMonth: string) => { const cancel = (yearMonth: string) => {
delete editableData[yearMonth]; delete editableData[yearMonth];
}; };
const loading = ref(false);
const onSubmit = () => { const onSubmit = () => {
loading.value = true;
const benchmark = monthData.value; const benchmark = monthData.value;
fetch(carbonPlanning.benchmarkSubmit, { fetch(carbonPlanning.benchmarkSubmit, {
benchmark: benchmark, benchmark: benchmark,
@ -555,6 +605,7 @@
visible.value = false; visible.value = false;
activeKey.value = '1'; activeKey.value = '1';
selectedRowKeysSet.value = []; selectedRowKeysSet.value = [];
loading.value = false;
getTableData(); getTableData();
}); });
}; };
@ -623,8 +674,8 @@
props.year + '年预算', props.year + '年预算',
'基准值', '基准值',
], ],
top: '0', top: '1%',
right: '0', right: '1%',
textStyle: { textStyle: {
color: '#666', color: '#666',
fontSize: 12, fontSize: 12,
@ -781,7 +832,6 @@
<style lang="less" scoped> <style lang="less" scoped>
.detailContant { .detailContant {
height: 100%; height: 100%;
margin: 12px;
} }
.ns-form-title { .ns-form-title {
font-weight: bold; font-weight: bold;
@ -791,7 +841,7 @@
align-items: center; align-items: center;
width: 100%; width: 100%;
height: 5vh; height: 5vh;
padding: 12px 12px 0 12px;
.title { .title {
text-align: left; text-align: left;
height: 32px; height: 32px;
@ -826,11 +876,15 @@
width: 100%; width: 100%;
height: calc(95% - 5vh); height: calc(95% - 5vh);
overflow: auto; overflow: auto;
padding: 12px;
.chartsPart { .chartsPart {
width: 100%; width: 100%;
height: 63%; height: 63%;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
border-radius: 12px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px 2px 20px rgb(69 123 234 / 20%);
.chart { .chart {
width: 100%; width: 100%;
height: 65%; height: 65%;
@ -938,6 +992,9 @@
right: 10px; right: 10px;
top: 5px; top: 5px;
} }
:deep(.ant-card-bordered) {
border: unset;
}
</style> </style>
<style scoped> <style scoped>
.editable-row-operations a { .editable-row-operations a {

7
hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/category/index.vue

@ -126,6 +126,9 @@
energyType: { energyType: {
type: String, type: String,
}, },
energyTypeName: {
type: String,
},
}); });
const orgId = ref(''); const orgId = ref('');
const result = JSON.parse(sessionStorage.getItem('ORGID')!); const result = JSON.parse(sessionStorage.getItem('ORGID')!);
@ -216,7 +219,9 @@
const option = { const option = {
backgroundColor: 'transparent', backgroundColor: 'transparent',
title: { title: {
text: '历年用电量分析', text: selectedTime.value
? '历年' + props.energyTypeName + '分析'
: '每月' + props.energyTypeName + '分析',
x: '0', x: '0',
textStyle: { textStyle: {
color: 'rgba(51, 51, 51, 1)', color: 'rgba(51, 51, 51, 1)',

36
hx-ai-intelligent/src/view/carbonEmissionManage/carbonPlanning/index.vue

@ -4,19 +4,39 @@
<all ref="allRef" /> <all ref="allRef" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="用电量"> <a-tab-pane key="2" tab="用电量">
<category ref="electricRef" :tabId="tabId" :energyType="energyType" /> <category
ref="electricRef"
:tabId="tabId"
:energyType="energyType"
:energyTypeName="energyTypeName" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" tab="用水量"> <a-tab-pane key="3" tab="用水量">
<category ref="useWaterRef" :tabId="tabId" :energyType="energyType" /> <category
ref="useWaterRef"
:tabId="tabId"
:energyType="energyType"
:energyTypeName="energyTypeName" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="4" tab="用气量"> <a-tab-pane key="4" tab="用气量">
<category ref="provideWaterRef" :tabId="tabId" :energyType="energyType" /> <category
ref="provideWaterRef"
:tabId="tabId"
:energyType="energyType"
:energyTypeName="energyTypeName" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="5" tab="供热量"> <a-tab-pane key="5" tab="供热量">
<category ref="carbonEmissionsRef" :tabId="tabId" :energyType="energyType" /> <category
ref="carbonEmissionsRef"
:tabId="tabId"
:energyType="energyType"
:energyTypeName="energyTypeName" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="6" tab="碳排量"> <a-tab-pane key="6" tab="碳排量">
<category ref="provideHotRef" :tabId="tabId" :energyType="energyType" /> <category
ref="provideHotRef"
:tabId="tabId"
:energyType="energyType"
:energyTypeName="energyTypeName" />
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</template> </template>
@ -41,6 +61,7 @@
// tab // tab
const tabId = ref(1); const tabId = ref(1);
const energyType = ref(); const energyType = ref();
const energyTypeName = ref();
const handleTabChange = (key) => { const handleTabChange = (key) => {
console.log('Tab changed:', key); console.log('Tab changed:', key);
// //
@ -53,6 +74,7 @@
} else if (key === '2') { } else if (key === '2') {
tabId.value = 4; tabId.value = 4;
energyType.value = 'ELECTRICITY_USAGE'; energyType.value = 'ELECTRICITY_USAGE';
energyTypeName.value = '用电量';
nextTick(() => { nextTick(() => {
if (electricRef.value) { if (electricRef.value) {
electricRef.value.electricTotal = true; electricRef.value.electricTotal = true;
@ -62,6 +84,7 @@
} else if (key === '3') { } else if (key === '3') {
tabId.value = 5; tabId.value = 5;
energyType.value = 'WATER_USAGE'; energyType.value = 'WATER_USAGE';
energyTypeName.value = '用水量';
nextTick(() => { nextTick(() => {
if (useWaterRef.value) { if (useWaterRef.value) {
useWaterRef.value.electricTotal = true; useWaterRef.value.electricTotal = true;
@ -71,6 +94,7 @@
} else if (key === '4') { } else if (key === '4') {
tabId.value = 6; tabId.value = 6;
energyType.value = 'GAS_USAGE'; energyType.value = 'GAS_USAGE';
energyTypeName.value = '用气量';
nextTick(() => { nextTick(() => {
if (provideWaterRef.value) { if (provideWaterRef.value) {
provideWaterRef.value.electricTotal = true; provideWaterRef.value.electricTotal = true;
@ -80,6 +104,7 @@
} else if (key === '5') { } else if (key === '5') {
tabId.value = 7; tabId.value = 7;
energyType.value = 'CARBON_EMISSIONS'; energyType.value = 'CARBON_EMISSIONS';
energyTypeName.value = '供热量';
nextTick(() => { nextTick(() => {
if (carbonEmissionsRef.value) { if (carbonEmissionsRef.value) {
carbonEmissionsRef.value.electricTotal = true; carbonEmissionsRef.value.electricTotal = true;
@ -89,6 +114,7 @@
} else if (key === '6') { } else if (key === '6') {
tabId.value = 8; tabId.value = 8;
energyType.value = 'HEAT_SUPPLY'; energyType.value = 'HEAT_SUPPLY';
energyTypeName.value = '碳排量';
nextTick(() => { nextTick(() => {
if (provideHotRef.value) { if (provideHotRef.value) {
provideHotRef.value.electricTotal = true; provideHotRef.value.electricTotal = true;

62
hx-ai-intelligent/src/view/equipmentControl/planToAdd/index.vue

@ -1,12 +1,33 @@
<template> <template>
<div style="width: 100%; height: 100%; position: relative">
<ns-view-list-table ref="mainRef" v-bind="config"> <ns-view-list-table ref="mainRef" v-bind="config">
<template #bodyCell="{ record, column }"> <template #bodyCell="{ record, column }">
<template v-if="column.dataIndex === 'executionTime'"> <template v-if="column.dataIndex === 'executionTime'">
{{ getData(record) }} {{ getData(record) }}
</template> </template>
<template v-if="column.dataIndex === 'executeStatus'">
<div
:style="{
color: {
'0': '#ccc',
'1': 'rgba(255, 165, 0, 1)',
'2': 'rgb(57, 215, 187)',
'3': 'rgb(255, 0, 0)',
}[record.executeStatus.value],
}">
{{ record.executeStatus.label }}</div
>
</template>
</template> </template>
</ns-view-list-table> </ns-view-list-table>
<a-button
type="primary"
style="position: absolute; bottom: 20px; height: 30px; left: 13%"
@click="addPlan"
>添加</a-button
>
<NsModalFrom ref="modalFormRef" v-bind="nsModalFormConfig" /> <NsModalFrom ref="modalFormRef" v-bind="nsModalFormConfig" />
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
@ -14,6 +35,7 @@
import { planToAddApi } from '/@/api/planToAdd'; import { planToAddApi } from '/@/api/planToAdd';
import { NsMessage } from '/nerv-lib/component'; import { NsMessage } from '/nerv-lib/component';
import { getEnum } from '/@/api'; import { getEnum } from '/@/api';
import { http } from '/nerv-lib/util';
// //
const orgId = ref(''); const orgId = ref('');
@ -24,6 +46,24 @@
projectId.value = results.projectId; projectId.value = results.projectId;
const mainRef = ref(null); const mainRef = ref(null);
const modalFormRef = ref(null); const modalFormRef = ref(null);
const addPlan = () => {
if (mainRef.value.nsTableRef.treeElRef.selectedRow.node.planLib) {
http
.get(planToAddApi.addPlan, {
libId: mainRef.value.nsTableRef.treeElRef.selectedRow.node.planLib.id,
})
.then((res) => {
if (res.msg === 'success') {
NsMessage.success('添加成功');
mainRef.value?.nsTableRef.reload();
} else {
NsMessage.error(res.msg);
}
});
} else {
NsMessage.warning('只有最后一级才能添加');
}
};
const getData = (record: any) => { const getData = (record: any) => {
return record.startTime return record.startTime
? record.startTime.substring(0, 10) + ' - ' + record.endTime.substring(0, 10) ? record.startTime.substring(0, 10) + ' - ' + record.endTime.substring(0, 10)
@ -67,8 +107,6 @@
success: (data: any) => { success: (data: any) => {
if (data.msg === 'success') { if (data.msg === 'success') {
mainRef.value?.nsTableRef.reload(); mainRef.value?.nsTableRef.reload();
} else {
NsMessage.error(data.msg);
} }
}, },
}); });
@ -81,7 +119,7 @@
config.value = { config.value = {
title: '计划库', title: '计划库',
api: planToAddApi.getActivatedPlanListByTree, api: planToAddApi.getActivatedPlanListByTree,
params: { orgId, projectId, ctrlType: enumData.data[0].value }, params: { orgId, projectId },
treeConfig: { treeConfig: {
defaultExpandAll: true, defaultExpandAll: true,
header: { header: {
@ -90,20 +128,13 @@
}, },
params: { projectId, ctrlType: enumData.data[0].value }, params: { projectId, ctrlType: enumData.data[0].value },
dynamicParams: { dynamicParams: {
id: 'id',
pid: 'pid',
level: 'level',
projectId: 'projectId', projectId: 'projectId',
ctrlType: 'ctrlType', treeId: 'id',
}, },
api: planToAddApi.getActivatedPlanTree, api: planToAddApi.getActivatedPlanTree,
fieldNames: { fieldNames: {
title: 'name', title: 'name',
key: 'id', key: 'id',
pid: 'pid',
level: 'level',
projectId: 'projectId',
ctrlType: 'ctrlType',
children: 'childList', children: 'childList',
}, },
formConfig: { formConfig: {
@ -151,6 +182,10 @@
dataIndex: 'planName', dataIndex: 'planName',
}, },
{ {
title: '执行状态',
dataIndex: 'executeStatus',
},
{
title: '执行时间', title: '执行时间',
dataIndex: 'executionTime', dataIndex: 'executionTime',
}, },
@ -166,9 +201,8 @@
name: 'energyAlarmEdit', name: 'energyAlarmEdit',
dynamicParams: ['uuid', 'appealType'], dynamicParams: ['uuid', 'appealType'],
handle: (data: any) => { handle: (data: any) => {
console.log(mainRef.value, '数据');
if (data?.executeStatus?.value === 2) { if (data?.executeStatus?.value === 2) {
NsMessage.warning('当前计划正在执行,无法进行编辑。如需编辑,请先停止计划.'); NsMessage.warning('当前计划正在执行,无法进行编辑。如需编辑,请先停止计划');
} else { } else {
const obj = { ...data }; const obj = { ...data };
nsModalFormConfig.value.title = '编辑'; nsModalFormConfig.value.title = '编辑';
@ -192,7 +226,7 @@
dynamicParams: ['uuid', 'appealType'], dynamicParams: ['uuid', 'appealType'],
confirm: true, confirm: true,
handle: (data: any) => { handle: (data: any) => {
http.post(planToAddApi.updPlan, [data.id]).then((res) => { http.post(planToAddApi.delPlan, [data.id]).then((res) => {
if (res.msg === 'success') { if (res.msg === 'success') {
NsMessage.success('操作成功'); NsMessage.success('操作成功');
mainRef.value?.nsTableRef.reload(); mainRef.value?.nsTableRef.reload();

13
hx-ai-intelligent/src/view/monitor/environmentMonitor/averageData/index.vue

@ -38,7 +38,10 @@
查询 查询
</a-button> </a-button>
</div> </div>
<a-button type="primary" style="position: absolute; right: 40px; top: -45px"> <a-button
type="primary"
style="position: absolute; right: 40px; top: -45px"
@click="export1()">
导出 导出
</a-button> </a-button>
</div> </div>
@ -66,6 +69,7 @@
<!-- </a-spin> --> <!-- </a-spin> -->
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { exportExcel } from '/@/util/ExcelUtil.js';
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
// import { http } from '/nerv-lib/util/http'; // import { http } from '/nerv-lib/util/http';
import { Pagination, SelectProps, TreeSelectProps, TableColumnType } from 'ant-design-vue'; import { Pagination, SelectProps, TreeSelectProps, TableColumnType } from 'ant-design-vue';
@ -200,6 +204,13 @@
loading.value = false; loading.value = false;
}); });
}; };
// excel
const export1 = () => {
for (let i = 0; i < data.value.length; i++) {
data.value[i].index = i + 1;
}
exportExcel(tableColumns.value, data.value, '平均数据导出', false);
};
onMounted(async () => { onMounted(async () => {
// //
let frequency = await getEnum({ params: { enumType: 'TimeFlagEnum' } }); let frequency = await getEnum({ params: { enumType: 'TimeFlagEnum' } });

62
hx-ai-intelligent/src/view/monitor/environmentMonitor/historyData/index.vue

@ -62,7 +62,7 @@
<a-button <a-button
type="primary" type="primary"
style="position: absolute; right: 40px; top: -45px" style="position: absolute; right: 40px; top: -45px"
@click="exportExcel()"> @click="export1()">
导出 导出
</a-button> </a-button>
</div> </div>
@ -87,8 +87,7 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import XLSX from 'xlsx'; import { exportExcel } from '/@/util/ExcelUtil.js';
// import Export2Excel from '/@/util/Export2Excel.js';
import { ref, onMounted, defineOptions } from 'vue'; import { ref, onMounted, defineOptions } from 'vue';
// import { http } from '/nerv-lib/util/http'; // import { http } from '/nerv-lib/util/http';
@ -352,60 +351,9 @@
} }
}); });
}; };
// excel // excel
/** const export1 = () => {
* @前期准备 npm install -S xlsx file-saver Export2Excel.js exportExcel(tableColumns.value, data.value, '历史数据导出', true, 1, 3);
*/
const exportExcel = () => {
import('/@/util/Export2Excel.js').then((excel) => {
//
let tHeader = [];
let filterVal = [];
for (let i = 0; i < tableColumns.value.length; i++) {
if (tableColumns.value[i].dataIndex) {
tHeader.push(tableColumns.value[i].title);
filterVal.push(tableColumns.value[i].dataIndex);
}
}
// const tHeader = [
// 'ID',
// '',
// 'ID',
// '',
// '',
// '',
// '',
// '',
// ];
// //
// const filterVal = [
// 'id',
// 'name',
// 'videoId',
// 'videoTitle',
// 'release',
// 'videoType',
// 'playVolume',
// 'updateTime',
// ];
//
const list = data.value;
const datas = formatJson(filterVal, list);
excel.export_json_to_excel({
header: tHeader, //
data: datas, //
filename: '表格导出测试', // excel
});
});
};
/**
* 格式化表格数据
* @filterVal 格式头
* @jsonData 用来格式化的表格数据
*/
const formatJson = (filterVal: any, jsonData: any) => {
return jsonData.map((v: any) => filterVal.map((j: any) => v[j]));
}; };
onMounted(async () => { onMounted(async () => {
// //

8
lib/component/table/table.vue

@ -17,7 +17,11 @@
<!-- todo drag --> <!-- todo drag -->
<div class="ns-part-tree" v-if="!isEmpty(treeConfig)"> <div class="ns-part-tree" v-if="!isEmpty(treeConfig)">
<ns-tree-api v-bind="getTreeBindValue" @reload="reload" @select="treeSelect" /> <ns-tree-api
ref="treeElRef"
v-bind="getTreeBindValue"
@reload="reload"
@select="treeSelect" />
</div> </div>
<div class="ns-part-table"> <div class="ns-part-table">
<a-spin :spinning="tableState.loading"> <a-spin :spinning="tableState.loading">
@ -220,6 +224,7 @@
setup(props, { attrs, emit }) { setup(props, { attrs, emit }) {
const tableElRef = ref(null); const tableElRef = ref(null);
const formElRef = ref(null); const formElRef = ref(null);
const treeElRef = ref(null);
const dataRef = ref([]); const dataRef = ref([]);
const treeParamsRef = ref({}); const treeParamsRef = ref({});
const formParamsRef = ref({}); const formParamsRef = ref({});
@ -632,6 +637,7 @@
reload, reload,
clearCheck, clearCheck,
formElRef, formElRef,
treeElRef,
tableElRef, tableElRef,
getColumnActions, getColumnActions,
getTableBindValues, getTableBindValues,

5
lib/component/tree/tree-api.vue

@ -43,6 +43,7 @@
const treeData = ref(props.treeData); const treeData = ref(props.treeData);
const selectedKeys = ref(props.selectedKeys || []); const selectedKeys = ref(props.selectedKeys || []);
const selectedRow = ref(props.selectedRow || {});
const { httpRequest } = useApi(); const { httpRequest } = useApi();
const requestConfig: AxiosRequestConfig = { method: 'get' }; const requestConfig: AxiosRequestConfig = { method: 'get' };
const route = useRoute(); const route = useRoute();
@ -87,6 +88,7 @@
const handleSelect = (keys: any, selectedRows: any) => { const handleSelect = (keys: any, selectedRows: any) => {
if (props.cancelable || !isEmpty(keys)) { if (props.cancelable || !isEmpty(keys)) {
selectedKeys.value = keys; selectedKeys.value = keys;
selectedRow.value = selectedRows;
// props.onSelect && props.onSelect(keys, selectedRows); // props.onSelect && props.onSelect(keys, selectedRows);
emit('select', keys, selectedRows); emit('select', keys, selectedRows);
} }
@ -147,9 +149,10 @@
const clearSelectedKeys = () => { const clearSelectedKeys = () => {
selectedKeys.value = []; selectedKeys.value = [];
selectedRow.value = {};
}; };
defineExpose({ treeReload, clearSelectedKeys }); defineExpose({ treeReload, clearSelectedKeys, selectedKeys, selectedRow });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@gap: 16px; @gap: 16px;

Loading…
Cancel
Save