This commit is contained in:
zhaohy
2024-08-20 15:56:24 +08:00
31 changed files with 1312 additions and 812 deletions

View File

@@ -1,4 +1,4 @@
const prefix = '/carbon-smart'; const prefix = '/carbon-smart/api';
// 照明系统及相关接口 // 照明系统及相关接口
export enum lightingManage { export enum lightingManage {
// 主页 ======================================================== // 主页 ========================================================

View File

@@ -1,4 +1,4 @@
const prefix = '/carbon-smart'; const prefix = '/carbon-smart/api';
// 空调系统及相关接口 // 空调系统及相关接口
export enum airConditionControl { export enum airConditionControl {
// 主页 ====================================================== // 主页 ======================================================

View File

@@ -108,4 +108,5 @@ export enum carbonPlanning {
benchmarkSetting = '/carbon-smart/api/carbon/planning/benchmarkSetting', benchmarkSetting = '/carbon-smart/api/carbon/planning/benchmarkSetting',
monthBenchmarkSetting = '/carbon-smart/api/carbon/planning/monthBenchmarkSetting', monthBenchmarkSetting = '/carbon-smart/api/carbon/planning/monthBenchmarkSetting',
benchmarkSubmit = '/carbon-smart/api/carbon/planning/benchmarkSubmit', benchmarkSubmit = '/carbon-smart/api/carbon/planning/benchmarkSubmit',
autoObtained = '/carbon-smart/api/carbon/planning/autoObtained',
} }

View File

@@ -1,4 +1,4 @@
const prefix = '/carbon-smart'; const prefix = '/carbon-smart/api';
// 照明系统及相关接口 // 照明系统及相关接口
export enum planManage { export enum planManage {
/** /**
@@ -10,4 +10,6 @@ export enum planManage {
getTableData = prefix + '/deviceCtrlPlan/getActivatedPlanList', getTableData = prefix + '/deviceCtrlPlan/getActivatedPlanList',
// 提交计划状态修改 // 提交计划状态修改
submitTransData = prefix + '/deviceCtrlPlan/activePlanByIdList', submitTransData = prefix + '/deviceCtrlPlan/activePlanByIdList',
// 用于确认当前是否有计划正在运行
getRunningPlan = prefix + '/deviceCtrlPlan/getRunningPlan',
} }

View File

@@ -1,5 +1,5 @@
// 前缀 // 前缀
const prefix = '/carbon-smart'; const prefix = '/carbon-smart/api';
// 通风系统相关接口 // 通风系统相关接口
export enum ventilating { export enum ventilating {
// 排风扇相关 ============================================= // 排风扇相关 =============================================

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="11.05419921875" height="11.55615234375" viewBox="0 0 11.05419921875 11.55615234375" fill="none">
<path d="M10.9138 2.84916C10.8847 2.81354 10.8562 2.77791 10.8239 2.74831C10.7389 2.6699 10.6445 2.6025 10.5427 2.54769C9.03643 1.74524 7.53183 0.940587 6.02611 0.138129C5.89809 0.0686747 5.759 0.0219399 5.61502 8.98451e-08L5.4747 0C5.12499 0.0696122 4.82407 0.271323 4.51219 0.435761C3.14669 1.1531 1.7835 1.87517 0.422787 2.60189C0.210487 2.71542 0.0460472 2.89521 0.00767517 3.17037C0.00658035 3.18024 0.00274277 3.18901 0 3.19778L0 3.31453C0.0219307 3.44005 0.0586548 3.55899 0.137035 3.65875C0.16444 3.69274 0.190201 3.72836 0.221451 3.75632C0.30476 3.82922 0.389175 3.89938 0.486191 3.95145C2.00341 4.75994 3.51843 5.57171 5.0373 6.37746C5.16556 6.44653 5.29766 6.5134 5.44565 6.52765C5.59584 6.543 5.73671 6.51504 5.86935 6.44488L10.4747 3.99969C10.5262 3.97173 10.58 3.94816 10.6282 3.91583C10.7724 3.8221 10.9072 3.71412 10.9828 3.54529C11.0157 3.47349 11.03 3.39182 11.0541 3.31453L11.0541 3.19778C11.03 3.07061 10.9927 2.94893 10.9132 2.84917L10.9138 2.84916ZM10.3952 5.04387C10.2329 5.00984 10.0637 5.0339 9.91727 5.11184C9.62566 5.2686 9.33626 5.43249 9.04191 5.58542C7.88811 6.18507 6.73156 6.78143 5.57719 7.37999C5.54431 7.39643 5.5169 7.39917 5.48292 7.38163L1.23986 5.15789C1.01208 5.03459 0.748119 4.99558 0.494411 5.04771C0.231308 5.10197 0.0487823 5.33712 0.0120583 5.63585C0.00986099 5.6523 0.00383377 5.66874 0.000545502 5.68518L0.000545502 5.83647C0.0224686 5.95925 0.0591965 6.07545 0.133739 6.17521C0.204994 6.26894 0.287212 6.34677 0.386429 6.39939C1.94036 7.2331 3.49541 8.06789 5.05154 8.89722C5.17596 8.96299 5.30532 9.02877 5.45057 9.04137C5.59638 9.05453 5.7345 9.02822 5.86441 8.9608C7.46275 8.13313 9.06109 7.30655 10.6572 6.47504C10.871 6.36322 10.9932 6.16534 11.0415 5.91595C11.0464 5.89786 11.0497 5.87867 11.0541 5.86004L11.0541 5.71972C11.0393 5.66874 11.03 5.61448 11.0108 5.56624C10.8979 5.26532 10.6852 5.10033 10.3952 5.04442L10.3952 5.04387ZM10.3963 7.55319C10.2338 7.51913 10.0644 7.54318 9.91782 7.62116C9.62183 7.78012 9.32913 7.94456 9.03205 8.10023C7.88317 8.69659 6.73429 9.28967 5.58541 9.88602C5.5499 9.90681 5.50577 9.90618 5.47086 9.88438C4.06491 9.1455 2.65787 8.40882 1.25082 7.66994C1.04099 7.56197 0.804203 7.51759 0.569508 7.54223C0.295444 7.56415 0.0838623 7.78066 0.0241203 8.08104C0.0158997 8.11886 0.00767517 8.15558 0.000556946 8.19285L0.000556946 8.34414C0.0224762 8.46473 0.0581055 8.57983 0.12991 8.67849C0.202263 8.77661 0.287773 8.85554 0.390812 8.91035C1.94312 9.74351 3.49596 10.5767 5.0499 11.4043C5.18254 11.4756 5.32232 11.5414 5.47415 11.5562L5.58158 11.5562C5.70617 11.5342 5.82623 11.4916 5.93677 11.4301C6.08257 11.3506 6.23659 11.287 6.38404 11.2103C7.8026 10.4725 9.2206 9.73365 10.6375 8.99532C10.8622 8.87802 10.9922 8.68014 11.0426 8.41869L11.0541 8.36826L11.0541 8.22794C11.0393 8.17696 11.03 8.1227 11.0108 8.07446C10.8995 7.77299 10.6857 7.60856 10.3963 7.55374L10.3963 7.55319Z" fill="#4388FB" >
</path>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -48,64 +48,70 @@
</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">
<a-card> <div class="ns-form-title">
<div class="ns-form-title"> <div class="title">交易明细</div>
<div class="title">交易明细</div> <div class="operation" style="display: flex">
<div class="operation" style="display: flex"> <a-button type="primary" @click="addDetail">新增</a-button>
<a-button type="primary" @click="addDetail">新增</a-button> <a-upload
<a-upload v-model:file-list="importFileList"
v-model:file-list="importFileList" name="file"
name="file" accept=".xlsx"
accept=".xlsx" :showUploadList="false"
:showUploadList="false" :custom-request="importFile">
:custom-request="importFile"> <a-button type="primary" style="margin-left: 6px">导入</a-button>
<a-button type="primary" style="margin-left: 6px">导入</a-button> </a-upload>
</a-upload> <a-button type="primary" style="margin-left: 6px" @click="exportFile">导出</a-button>
<a-button type="primary" style="margin-left: 6px" @click="exportFile">导出</a-button> <a-button
<a-button type="primary"
type="primary" style="margin-left: 6px"
style="margin-left: 6px" :disabled="selectedRowKeys.length === 0"
:disabled="selectedRowKeys.length === 0" @click="deleteMore"
@click="deleteMore" >批量删除</a-button
>批量删除</a-button >
>
</div>
</div> </div>
<a-table </div>
:columns="columns" <a-table
:data-source="data" :columns="columns"
rowKey="id" :data-source="data"
@change="onChange" rowKey="id"
:rowSelection="{ @change="onChange"
selectedRowKeys: selectedRowKeys, :rowSelection="{
onChange: onSelectionChange, selectedRowKeys: selectedRowKeys,
}" onChange: onSelectionChange,
:scroll="{ x: 1500, y: 400 }" }"
:pagination="false"> :scroll="{ x: 1500, y: 400 }"
<template #bodyCell="{ column, text, record }"> :pagination="false">
<template v-if="column.dataIndex === 'accountType'"> <template #bodyCell="{ column, text, record }">
<span v-if="record.accountType">{{ record.accountType.label }}</span> <template v-if="column.dataIndex === 'accountType'">
</template> <span v-if="record.accountType">{{ record.accountType.label }}</span>
<template v-if="column.key === 'action'">
<span>
<a @click="editData(record)">编辑</a>
<a-divider type="vertical" />
<a @click="delData(record)">删除</a>
</span>
</template>
</template> </template>
</a-table> <template v-if="column.key === 'action'">
<a-pagination <span>
:current="queryParams.pageNum" <a @click="editData(record)">编辑</a>
:total="total" <a-divider type="vertical" />
:page-size="queryParams.pageSize" <a @click="delData(record)">删除</a>
style="display: flex; justify-content: center; margin-top: 16px" </span>
:show-size-changer="true" </template>
:show-quick-jumper="true" </template>
@change="onChange" /> </a-table>
</a-card> <a-pagination
:current="queryParams.pageNum"
:total="total"
:page-size="queryParams.pageSize"
style="display: flex; justify-content: center; margin-top: 16px"
:show-size-changer="true"
:show-quick-jumper="true"
@change="onChange" />
</div> </div>
<div class="total"> <div class="total">
<div class="ns-form-title">
<div class="title">配额统计</div>
<div class="operation" style="display: flex; justify-content: space-around; width: 63%">
<a-button type="primary" @click="getTotalTable(1)">全国配额</a-button>
<a-button type="primary" @click="getTotalTable(2)">地方配额</a-button>
<a-button type="primary" @click="getTotalTable(3)">CCER配额</a-button>
</div>
</div>
<a-table :columns="totalColumns" :data-source="totalData" bordered :pagination="false"> <a-table :columns="totalColumns" :data-source="totalData" bordered :pagination="false">
<template #bodyCell="{ column, text }"> <template #bodyCell="{ column, text }">
<template v-if="column.dataIndex === 'name'"> <template v-if="column.dataIndex === 'name'">
@@ -123,6 +129,9 @@
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
destroyOnClose destroyOnClose
@close="onClose"> @close="onClose">
<div class="ns-form-title" style="display: flex">
<div class="title">{{ text }}</div>
</div>
<a-form <a-form
ref="formRef" ref="formRef"
:model="formState" :model="formState"
@@ -295,6 +304,7 @@
}; };
const editData = (record) => { const editData = (record) => {
getDictList(); getDictList();
text.value = '编辑';
visible.value = true; visible.value = true;
formState.value.id = record.id; formState.value.id = record.id;
fetch(uploadPic.select, { bizId: record.id, bizType: 1 }).then((res) => { fetch(uploadPic.select, { bizId: record.id, bizType: 1 }).then((res) => {
@@ -376,6 +386,7 @@
}; };
// 新增相关数据 // 新增相关数据
const visible = ref(false); const visible = ref(false);
const text = ref('新增');
const formState = ref({ const formState = ref({
orgId: orgId.value, orgId: orgId.value,
}); });
@@ -404,6 +415,7 @@
getDictList(); getDictList();
// 点击新增 // 点击新增
const addDetail = () => { const addDetail = () => {
text.value = '新增';
visible.value = true; visible.value = true;
getDictList(); getDictList();
}; };
@@ -447,7 +459,7 @@
// 清理 URL 对象 // 清理 URL 对象
window.URL.revokeObjectURL(url); window.URL.revokeObjectURL(url);
selectedRowKeys.value = [] selectedRowKeys.value = [];
}) })
.catch((error) => { .catch((error) => {
console.error('下载失败:', error); console.error('下载失败:', error);
@@ -545,7 +557,10 @@
formRef.value.resetFields(); formRef.value.resetFields();
}; };
// 统计表格 // 统计表格
const getTotalTable = () => { const getTotalTable = (type) => {
if (type) {
queryParams.value.accountType = type;
}
fetch(carbonAssets.quotaStatistics, queryParams.value).then((res) => { fetch(carbonAssets.quotaStatistics, queryParams.value).then((res) => {
totalData.value = res.data; totalData.value = res.data;
}); });
@@ -614,11 +629,13 @@
height: 100%; height: 100%;
background: white; background: white;
border-radius: 12px; border-radius: 12px;
padding: 16px;
} }
.total { .total {
width: calc(35% - 20px); width: calc(35% - 20px);
height: 100%; height: 100%;
background: white; background: white;
border-radius: 12px; border-radius: 12px;
padding: 16px;
} }
</style> </style>

View File

@@ -5,7 +5,7 @@
<div class="left"> <div class="left">
<div class="top"> <div class="top">
<a-form style="width: 100%; margin: 0 auto"> <a-form style="width: 100%; margin: 0 auto">
<div class="ns-form-title"><div class="title">排放分类</div></div> <div class="ns-form-title"><div class="title">能源分组</div></div>
<div style="padding: 0 16px !important; width: 100%"> <div style="padding: 0 16px !important; width: 100%">
<a-row> <a-row>
<a-col :span="24" style="margin-bottom: 16px"> <a-col :span="24" style="margin-bottom: 16px">
@@ -23,7 +23,6 @@
class="draggable-tree" class="draggable-tree"
style="padding: 0 16px !important" style="padding: 0 16px !important"
draggable draggable
show-line
checkable checkable
block-node block-node
:tree-data="gData" :tree-data="gData"
@@ -80,9 +79,9 @@
</div> </div>
</template> </template>
</a-tree> </a-tree>
<div class="addTreeNode"> <!-- <div class="addTreeNode">
<a-button type="primary" style="width: 100%" @click="addTreeNodeData">新增</a-button> <a-button type="primary" style="width: 100%" @click="addTreeNodeData">新增</a-button>
</div> </div> -->
</div> </div>
</div> </div>
<div class="right"> <div class="right">
@@ -96,7 +95,7 @@
</div> </div>
<!-- 新增树节点 --> <!-- 新增树节点 -->
<ns-modal :visible="treeNodeAdd" :title="operationTree" @ok="handleOk" @cancel="handleCancel"> <ns-modal :visible="treeNodeAdd" :title="operationTree" @ok="handleOk" @cancel="handleCancel">
<ns-input v-model:value="addTreeNode" class="input" placeholder="请输入排放类型" /> <ns-input v-model:value="addTreeNode" :maxlength="10" class="input" placeholder="请输入排放类型" />
</ns-modal> </ns-modal>
<!-- 新增数据库数据 --> <!-- 新增数据库数据 -->
<a-drawer <a-drawer
@@ -106,6 +105,9 @@
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
destroyOnClose destroyOnClose
@close="onClose"> @close="onClose">
<div class="ns-form-title-add" style="display: flex">
<div class="title">{{ text }}</div>
</div>
<ns-form <ns-form
ref="formRef" ref="formRef"
:schemas="formSchema" :schemas="formSchema"
@@ -129,8 +131,8 @@
@close="closeUnitManag"> @close="closeUnitManag">
<div class="ns-form-title titleUnit"> <div class="ns-form-title titleUnit">
<div class="title">单位管理</div> <div class="title">单位管理</div>
<a-button type="primary" @click="addGroup">新增分组</a-button> <a-button type="primary" @click="addGroup" ghost>新增分组</a-button>
<a-button type="primary" @click="addUnit">新增单位</a-button> <a-button type="primary" @click="addUnit" ghost>新增单位</a-button>
</div> </div>
<!-- <div class="addButton"> <!-- <div class="addButton">
</div> --> </div> -->
@@ -147,7 +149,7 @@
ref="select" ref="select"
:value="unitTreeParams.id" :value="unitTreeParams.id"
allowClear allowClear
style="width: 96%" style="width: 90%"
placeholder="选择分组" placeholder="选择分组"
@change="handleChange"> @change="handleChange">
<a-select-option v-for="(item, index) in groupData" :key="index" :value="item.id"> <a-select-option v-for="(item, index) in groupData" :key="index" :value="item.id">
@@ -185,11 +187,12 @@
</template> </template>
</a-drawer> </a-drawer>
<!-- 新增分组管理 --> <!-- 新增分组管理 -->
<ns-modal <ns-modal :visible="addGroupManage" @ok="unitOrGroupOk" @cancel="groupCancel">
:visible="addGroupManage" <template #title>
:title="addGroupTitle" <div style="display: flex; align-items: center">
@ok="unitOrGroupOk" <span class="titleStyleGroup">{{ addGroupTitle }}</span>
@cancel="groupCancel"> </div>
</template>
<a-form ref="unitFormRef" :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol"> <a-form ref="unitFormRef" :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="分组名称" name="cnValue" :required="true"> <a-form-item label="分组名称" name="cnValue" :required="true">
<a-input v-model:value="formState.cnValue" placeholder="请输入分组名称" /> <a-input v-model:value="formState.cnValue" placeholder="请输入分组名称" />
@@ -197,11 +200,12 @@
</a-form> </a-form>
</ns-modal> </ns-modal>
<!-- 新增单位 --> <!-- 新增单位 -->
<ns-modal <ns-modal :visible="addUnitManage" @ok="unitOrGroupOk" @cancel="unitCancel">
:visible="addUnitManage" <template #title>
:title="addUnitTitle" <div style="display: flex; align-items: center">
@ok="unitOrGroupOk" <span class="titleStyle">{{ addUnitTitle }}</span>
@cancel="unitCancel"> </div>
</template>
<a-form ref="unitFormRef" :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol"> <a-form ref="unitFormRef" :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="单位名称" name="cnValue" :required="true"> <a-form-item label="单位名称" name="cnValue" :required="true">
<a-input v-model:value="formState.cnValue" placeholder="请输入单位名称" /> <a-input v-model:value="formState.cnValue" placeholder="请输入单位名称" />
@@ -265,6 +269,7 @@
const disabled = ref(false); const disabled = ref(false);
const treeNodeAdd = ref<boolean>(false); const treeNodeAdd = ref<boolean>(false);
const operationTree = ref<string>('新增'); const operationTree = ref<string>('新增');
const text = ref('新增数据');
// const showOperation = ref(false); // const showOperation = ref(false);
const opMap: any = ref({ const opMap: any = ref({
@@ -473,7 +478,11 @@
cancelText: '取消', cancelText: '取消',
onOk() { onOk() {
http http
.post(carbonEmissionFactorLibrary.delTreeNode, { orgId: orgId.value, id: data.id }) .post(carbonEmissionFactorLibrary.delTreeNode, {
orgId: orgId.value,
id: data.id,
emissionName: data.emissionName,
})
.then(() => { .then(() => {
getOrgTree(); getOrgTree();
NsMessage.success('操作成功'); NsMessage.success('操作成功');
@@ -637,6 +646,7 @@
}); });
}; };
show.value = false; show.value = false;
text.value = '新增数据';
visible.value = true; visible.value = true;
}, },
}, },
@@ -812,6 +822,7 @@
}); });
}; };
show.value = true; show.value = true;
text.value = '编辑数据';
visible.value = true; visible.value = true;
}, },
}, },
@@ -1122,6 +1133,10 @@
padding-bottom: 10px; padding-bottom: 10px;
border-bottom: 1px solid #e9e9e9; border-bottom: 1px solid #e9e9e9;
} }
.ns-form-title-add {
font-weight: bold;
user-select: text;
}
.titleUnit { .titleUnit {
font-weight: bold; font-weight: bold;
user-select: text; user-select: text;
@@ -1176,6 +1191,7 @@
margin-left: 10%; margin-left: 10%;
flex-direction: column; flex-direction: column;
border-radius: 12px; border-radius: 12px;
overflow: auto;
} }
.actionMore { .actionMore {
display: none; display: none;
@@ -1198,5 +1214,27 @@
text-align: right; text-align: right;
width: 27%; width: 27%;
} }
.titleStyleGroup::before {
content: '';
position: absolute;
left: 16px;
top: 13%;
transform: translateY(-50%);
height: 16px;
width: 3px;
border-radius: 1px;
background-color: #2778ff;
}
.titleStyle::before {
content: '';
position: absolute;
left: 16px;
top: 10.5%;
transform: translateY(-50%);
height: 16px;
width: 3px;
border-radius: 1px;
background-color: #2778ff;
}
</style> </style>
   

View File

@@ -3,15 +3,15 @@
<a-table <a-table
:columns="column" :columns="column"
:data-source="data" :data-source="data"
:bordered="false" :bordered="true"
:pagination="false" :pagination="false"
:scroll="{ x: 2000, y: 480 }"> :scroll="{ x: 2000, y: 480 }">
<template #title> <template #title>
<a-date-picker <a-date-picker v-model:value="selectYear" picker="year" valueFormat="YYYY" />
v-model:value="selectYear" <span style="margin-left: 30px">
picker="year" <a-button type="primary" @click="changeYearData">查询</a-button>
@change="changeYearData" <a-button type="primary" ghost style="margin-left: 6px" @click="reset">重置</a-button>
valueFormat="YYYY" /> </span>
</template> </template>
</a-table> </a-table>
<a-pagination <a-pagination
@@ -57,11 +57,17 @@
queryParams.value.year = selectYear.value; queryParams.value.year = selectYear.value;
getTableList(); getTableList();
}; };
const reset = () => {
selectYear.value = dayjs(new Date().getFullYear().toString());
queryParams.value.year = selectYear.value.format('YYYY');
getTableList();
};
// 表头 // 表头
const column: TableColumnsType[] = [ const column: TableColumnsType[] = [
{ {
title: '排放类型', title: '排放类型',
dataIndex: 'cnValue', dataIndex: 'cnValue',
width: 130,
customCell: (record, rowIndex) => { customCell: (record, rowIndex) => {
if (rowIndex == undefined) { if (rowIndex == undefined) {
return { return {
@@ -84,66 +90,82 @@
{ {
title: '能源种类', title: '能源种类',
dataIndex: 'energyType', dataIndex: 'energyType',
width: 80,
}, },
{ {
title: '计量单位', title: '计量单位',
dataIndex: 'unitName', dataIndex: 'unitName',
width: 80,
}, },
{ {
title: '加权平均', title: '加权平均',
dataIndex: 'averageFactorValue', dataIndex: 'averageFactorValue',
width: 80,
}, },
{ {
title: '全年', title: '全年',
dataIndex: 'carbonYearly', dataIndex: 'carbonYearly',
width: 80,
}, },
{ {
title: '1月', title: '1月',
dataIndex: 'jan', dataIndex: 'jan',
width: 80,
}, },
{ {
title: '2月', title: '2月',
dataIndex: 'feb', dataIndex: 'feb',
width: 80,
}, },
{ {
title: '3月', title: '3月',
dataIndex: 'mar', dataIndex: 'mar',
width: 80,
}, },
{ {
title: '4月', title: '4月',
dataIndex: 'apr', dataIndex: 'apr',
width: 80,
}, },
{ {
title: '5月', title: '5月',
dataIndex: 'may', dataIndex: 'may',
width: 80,
}, },
{ {
title: '6月', title: '6月',
dataIndex: 'jun', dataIndex: 'jun',
width: 80,
}, },
{ {
title: '7月', title: '7月',
dataIndex: 'jul', dataIndex: 'jul',
width: 80,
}, },
{ {
title: '8月', title: '8月',
dataIndex: 'aug', dataIndex: 'aug',
width: 80,
}, },
{ {
title: '9月', title: '9月',
dataIndex: 'sep', dataIndex: 'sep',
width: 80,
}, },
{ {
title: '10月', title: '10月',
dataIndex: 'oct', dataIndex: 'oct',
width: 80,
}, },
{ {
title: '11月', title: '11月',
dataIndex: 'nov', dataIndex: 'nov',
width: 80,
}, },
{ {
title: '12月', title: '12月',
dataIndex: 'dec', dataIndex: 'dec',
width: 80,
}, },
]; ];
// 合并单元格 // 合并单元格
@@ -189,9 +211,12 @@
:deep(.ant-table-container) { :deep(.ant-table-container) {
padding: 0px 16px; padding: 0px 16px;
} }
:deep(.ant-table-cell) { // :deep(.ant-table-cell) {
border: 1px solid #f0f0f0; // border: 1px solid #f0f0f0;
} // }
// :deep(.ant-table-cell::before) {
// display: none;
// }
</style> </style>
<style scoped> <style scoped>
th.column-money, th.column-money,

View File

@@ -54,150 +54,18 @@
</a-radio-group> </a-radio-group>
</a-form-item> </a-form-item>
<a-form-item label="排放类型" name="emissionType" :required="isRequired"> <a-form-item label="排放类型" name="emissionType" :required="isRequired">
<a-select v-model:value="formState.emissionType" placeholder="请选择排放类型"> <a-select
v-model:value="formState.emissionType"
placeholder="请选择排放类型"
:disabled="!isRequired">
<a-select-option v-for="(item, index) in emissionTypeDic" :key="index" :value="item.id"> <a-select-option v-for="(item, index) in emissionTypeDic" :key="index" :value="item.id">
{{ item.cnValue }} {{ item.cnValue }}
</a-select-option> </a-select-option>
</a-select> </a-select>
</a-form-item> </a-form-item>
</a-form> </a-form>
<!-- <a-row>
<a-col :span="24" style="display: flex; justify-content: space-around">
<a-form-item
label="1月"
name="janFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.janFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="2月"
name="febFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.febFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="3月"
name="marFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.marFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
</a-col>
<a-col :span="24" style="display: flex; justify-content: space-around">
<a-form-item
label="4月"
name="aprFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.aprFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="5月"
name="mayFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.mayFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="6月"
name="junFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.junFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
</a-col>
<a-col :span="24" style="display: flex; justify-content: space-around">
<a-form-item
label="7月"
name="julFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.julFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="8月"
name="augFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.augFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="9月"
name="sepFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.sepFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
</a-col>
<a-col :span="24" style="display: flex; justify-content: space-around">
<a-form-item
label="10月"
name="octFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.octFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="11月"
name="novFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.novFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
<a-form-item
label="12月"
name="decFlag"
:label-col="switchLabelCol"
:wrapper-col="switchWrapperCol">
<a-switch
v-model:checked="formState.decFlag"
:checked-value="1"
:unCheckedValue="0" />
</a-form-item>
</a-col>
</a-row> -->
<div class="ns-form-title"><div class="title">能耗统计</div></div> <div class="ns-form-title"><div class="title">能耗统计</div></div>
<a-table <a-table :columns="addColumns" :data-source="addData" size="small" :pagination="false">
:columns="addColumns"
:data-source="addData"
size="small"
:pagination="false"
:scroll="{ y: 200 }">
<template #bodyCell="{ column, text, record }"> <template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'action'"> <template v-if="column.key === 'action'">
<a-switch <a-switch
@@ -267,11 +135,20 @@
<!-- 凭证下载 --> <!-- 凭证下载 -->
<a-drawer <a-drawer
:visible="downLoadVisible" :visible="downLoadVisible"
title="凭证列表"
:width="500" :width="500"
@close="onCloseDownLoad" @close="onCloseDownLoad"
:footer-style="{ textAlign: 'right' }"> :footer-style="{ textAlign: 'right' }">
<div></div> <div class="ns-form-title" style="display: flex">
<div class="title">凭证列表</div>
<a-button
type="primary"
ghost
style="margin-left: 16px"
@click="onSubmitDownLoad"
:disabled="selectedRowKeysSet.length === 0">
批量下载
</a-button>
</div>
<a-table <a-table
:columns="downLoadColumns" :columns="downLoadColumns"
:data-source="downLoadData" :data-source="downLoadData"
@@ -281,6 +158,7 @@
selectedRowKeys: selectedRowKeysSet, selectedRowKeys: selectedRowKeysSet,
onChange: onSelectionChangeSet, onChange: onSelectionChangeSet,
}" }"
style="margin-top: 15px"
:pagination="false"> :pagination="false">
<template #bodyCell="{ column, text, record }"> <template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'action'"> <template v-if="column.key === 'action'">
@@ -485,23 +363,29 @@
customRender: (text: any) => { customRender: (text: any) => {
return text.index + 1; return text.index + 1;
}, },
width: 100,
}, },
{ {
title: '能源种类', title: '能源种类',
dataIndex: 'energyType', dataIndex: 'energyType',
width: 100,
ellipsis: true,
}, },
{ {
title: '计量单位', title: '计量单位',
className: 'unitName', className: 'unitName',
dataIndex: 'unitName', dataIndex: 'unitName',
width: 100,
}, },
{ {
title: '全年', title: '全年',
dataIndex: 'yearly', dataIndex: 'yearly',
width: 100,
}, },
{ {
title: '1月', title: '1月',
dataIndex: 'jan', dataIndex: 'jan',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -522,6 +406,7 @@
{ {
title: '2月', title: '2月',
dataIndex: 'feb', dataIndex: 'feb',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -542,6 +427,7 @@
{ {
title: '3月', title: '3月',
dataIndex: 'mar', dataIndex: 'mar',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -562,6 +448,7 @@
{ {
title: '4月', title: '4月',
dataIndex: 'apr', dataIndex: 'apr',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -582,6 +469,7 @@
{ {
title: '5月', title: '5月',
dataIndex: 'may', dataIndex: 'may',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -602,6 +490,7 @@
{ {
title: '6月', title: '6月',
dataIndex: 'jun', dataIndex: 'jun',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -622,6 +511,7 @@
{ {
title: '7月', title: '7月',
dataIndex: 'jul', dataIndex: 'jul',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -642,6 +532,7 @@
{ {
title: '8月', title: '8月',
dataIndex: 'aug', dataIndex: 'aug',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -662,6 +553,7 @@
{ {
title: '9月', title: '9月',
dataIndex: 'sep', dataIndex: 'sep',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -682,6 +574,7 @@
{ {
title: '10月', title: '10月',
dataIndex: 'oct', dataIndex: 'oct',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -702,6 +595,7 @@
{ {
title: '11月', title: '11月',
dataIndex: 'nov', dataIndex: 'nov',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -722,6 +616,7 @@
{ {
title: '12月', title: '12月',
dataIndex: 'dec', dataIndex: 'dec',
width: 100,
customRender: (value) => { customRender: (value) => {
let text; let text;
let color; let color;
@@ -878,6 +773,12 @@
? item.children.map((child) => ({ ? item.children.map((child) => ({
value: child.id, value: child.id,
label: child.pointName, label: child.pointName,
children: child.children
? child.children.map((childs) => ({
value: childs.id,
label: childs.pointName,
}))
: [],
})) }))
: [], : [],
})); }));

View File

@@ -82,7 +82,9 @@
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
destroyOnClose destroyOnClose
@close="onClose"> @close="onClose">
<div class="editTitle"><div class="title">编辑</div></div> <div class="editTitle">
<div class="title">{{ text }}</div>
</div>
<a-form <a-form
ref="formRef" ref="formRef"
:model="formState" :model="formState"
@@ -162,6 +164,7 @@
return http.post(api, params); return http.post(api, params);
}; };
const mainRef = ref(); const mainRef = ref();
const text = ref('新增');
// 数结构 // 数结构
const x = 3; const x = 3;
const y = 2; const y = 2;
@@ -290,6 +293,7 @@
name: 'userAdd', name: 'userAdd',
type: 'primary', type: 'primary',
handle: () => { handle: () => {
text.value = '新增';
visible.value = true; visible.value = true;
// getNewTable(); // getNewTable();
}, },
@@ -345,6 +349,7 @@
formState.value.emissionFactors = record.emissionFactors; formState.value.emissionFactors = record.emissionFactors;
formState.value.dateRange = [record.startTime, record.endTime]; formState.value.dateRange = [record.startTime, record.endTime];
formState.value.factorId = record.factorId; formState.value.factorId = record.factorId;
text.value = '编辑';
visible.value = true; visible.value = true;
emissionSources.value = record.emissionSources; emissionSources.value = record.emissionSources;
queryData.value.emissionSources = emissionSources.value; queryData.value.emissionSources = emissionSources.value;
@@ -493,6 +498,7 @@
const onClose = () => { const onClose = () => {
visible.value = false; visible.value = false;
selectedRowKeys.value = []; selectedRowKeys.value = [];
newTableData.value = [];
formState.value = {}; formState.value = {};
selectData.value = ''; selectData.value = '';
formRef.value.resetFields(); formRef.value.resetFields();

View File

@@ -45,7 +45,7 @@
</template> </template>
</a-tree> </a-tree>
</div> </div>
<div class="bottom"> <!-- <div class="bottom">
<a-form style="width: 100%; margin: 0 auto"> <a-form style="width: 100%; margin: 0 auto">
<div class="ns-form-title"><div class="title">报告相关</div></div> <div class="ns-form-title"><div class="title">报告相关</div></div>
<div class="button" style="padding: 0 16px !important"> <div class="button" style="padding: 0 16px !important">
@@ -53,80 +53,88 @@
<div :class="{ tplx: isClickedTplx }" @click="showTplx">碳排流向</div> <div :class="{ tplx: isClickedTplx }" @click="showTplx">碳排流向</div>
</div> </div>
</a-form> </a-form>
</div> </div> -->
</div> </div>
<div class="right"> <div class="right">
<div style="display: flex"> <a-button
<div class="ns-table-title ns-title-extra-box">排放源</div> type="primary"
<a-button type="primary" style="margin-left: 12px" @click="changeParentData">返回</a-button> @click="changeParentData"
</div> style="position: absolute; right: 25px; top: 10px; z-index: 99">
<div style="display: flex; height: 100%" v-if="fillInPage"> 返回
<div class="mainLeft"> </a-button>
<a-tree <a-tabs v-model:activeKey="activeKey" @change="handleTabChange" style="height: 100%">
:expandedKeys="expandedKeysR" <a-tab-pane key="1" tab="排放源">
:selectedKeys="selectedKeysR" <div style="display: flex; height: 100%">
:checkedKeys="checkedKeys" <div class="mainLeft">
:tree-data="treeData" <a-tree
@select="onSelectR" :expandedKeys="expandedKeysR"
block-node> :selectedKeys="selectedKeysR"
<template #title="data"> :checkedKeys="checkedKeys"
<div class="treeRow"> :tree-data="treeData"
<div> @select="onSelectR"
<span>{{ data.emissionSource }}</span> block-node>
</div> <template #title="data">
<div class="actionMore"> <div class="treeRow">
<EditOutlined @click="editUnit(data)" /> <div>
<MinusCircleOutlined style="margin-left: 6px" @click="delUnit(data)" /> <span>{{ data.emissionSource }}</span>
</div> </div>
<div class="actionMore">
<EditOutlined @click="editUnit(data)" />
<MinusCircleOutlined style="margin-left: 6px" @click="delUnit(data)" />
</div>
</div>
</template>
</a-tree>
<div class="addTreeNode">
<a-button type="primary" style="width: 100%" @click="addTreeNodeData"
>新增</a-button
>
</div> </div>
</template> </div>
</a-tree> <div class="mainRight">
<div class="addTreeNode"> <a-table
<a-button type="primary" style="width: 100%" @click="addTreeNodeData">新增</a-button> :columns="columns"
:data-source="data"
:pagination="false"
bordered
size="middle"
:scroll="{ y: 500 }">
<template #title>
<a-button type="primary" @click="downLoadVoucher">凭证</a-button>
</template>
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'dataSources'">
<span v-if="record.dataSources">{{ record.dataSources.label }}</span>
</template>
<template v-if="column.dataIndex === 'carbonSource'">
<span v-if="record.carbonSource">{{ record.carbonSource.label }}</span>
</template>
<template v-if="column.key === 'action'">
<span>
<a @click="edit(record)">编辑</a>
</span>
</template>
</template>
</a-table>
</div>
</div> </div>
</div> </a-tab-pane>
<div class="mainRight"> <a-tab-pane key="2" tab="排放统计">
<a-table <a-table
:columns="columns" :columns="pftjColumn"
:data-source="data" :data-source="pftjData"
:pagination="false"
bordered bordered
size="middle" :pagination="false"
:scroll="{ y: 480 }"> :scroll="{ x: 2000, y: 500 }">
<template #title>
<a-button type="primary" @click="downLoadVoucher">凭证</a-button>
</template>
<template #bodyCell="{ column, text, record }"> <template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'dataSources'"> {{ text || '-' }}
<span v-if="record.dataSources">{{ record.dataSources.label }}</span>
</template>
<template v-if="column.dataIndex === 'carbonSource'">
<span v-if="record.carbonSource">{{ record.carbonSource.label }}</span>
</template>
<template v-if="column.key === 'action'">
<span>
<a @click="edit(record)">编辑</a>
</span>
</template>
</template> </template>
</a-table> </a-table>
</div> </a-tab-pane>
</div> <a-tab-pane key="3" tab="碳排流向">
<div v-if="isClickedPftj"> <div ref="tplxChart" style="width: 100%; height: 68vh"></div>
<a-table </a-tab-pane>
:columns="pftjColumn" </a-tabs>
:data-source="pftjData"
bordered
:pagination="false"
:scroll="{ x: 2000 }">
<template #bodyCell="{ column, text, record }">
{{ text || '-' }}
</template>
</a-table>
</div>
<div v-if="isClickedTplx" style="width: 100%; height: 100%">
<div ref="tplxChart" style="width: 100%; height: 68vh"></div>
</div>
</div> </div>
<!-- 类别配置 --> <!-- 类别配置 -->
<a-drawer <a-drawer
@@ -240,7 +248,7 @@
</a-drawer> </a-drawer>
<!-- 点击编辑弹出框 --> <!-- 点击编辑弹出框 -->
<a-drawer <a-drawer
:width="700" :width="500"
:visible="editData" :visible="editData"
:body-style="{ paddingBottom: '80px' }" :body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
@@ -252,7 +260,7 @@
:label-col="labelCol" :label-col="labelCol"
:wrapper-col="wrapperCol"> :wrapper-col="wrapperCol">
<a-row> <a-row>
<a-col :span="12"> <a-col :span="24">
<a-form-item ref="name" label="数据来源" name="dataSources"> <a-form-item ref="name" label="数据来源" name="dataSources">
<a-select <a-select
ref="select" ref="select"
@@ -264,14 +272,29 @@
</a-select> </a-select>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="24">
<a-form-item ref="name" label="消耗量" name="consumption"> <a-form-item ref="name" label="消耗量" name="consumption">
<ns-input v-model:value="editFormState.consumption" :disabled="canEdit" /> <ns-input v-model:value="editFormState.consumption" :disabled="canEdit" />
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
<a-row v-if="automatic"> <a-row v-if="automatic">
<a-col :span="12"> <a-col :span="24">
<a-form-item label="能耗类型">
<a-select
v-model:value="editFormState.energyConsumptionType"
@change="changeEnergyType"
placeholder="请选择能耗类型">
<a-select-option
v-for="(item, index) in energyTypeOptions"
:key="index"
:value="item.dicKey">
{{ item.cnValue }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item ref="name" label="采集节点" name="collectionNode"> <a-form-item ref="name" label="采集节点" name="collectionNode">
<a-tree-select <a-tree-select
v-model:value="editFormState.collectionNode" v-model:value="editFormState.collectionNode"
@@ -283,12 +306,12 @@
</a-col> </a-col>
</a-row> </a-row>
<a-row> <a-row>
<a-col :span="12"> <a-col :span="24">
<a-form-item ref="name" label="因子值" name="factorId"> <a-form-item ref="name" label="因子值" name="factorId">
<ns-input v-model:value="editFormState.factorId" /> <ns-input v-model:value="editFormState.factorId" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <a-col :span="24">
<a-form-item ref="name" label="关键字" name="emissionFactors"> <a-form-item ref="name" label="关键字" name="emissionFactors">
<a-input-search <a-input-search
v-model:value="editFormState.emissionFactors" v-model:value="editFormState.emissionFactors"
@@ -303,7 +326,8 @@
:data-source="newTableData" :data-source="newTableData"
bordered bordered
rowKey="id" rowKey="id"
:scroll="{ y: 400 }" :scroll="{ y: 300 }"
size="small"
style="margin-bottom: 10px" style="margin-bottom: 10px"
:rowSelection="{ :rowSelection="{
selectedRowKeys: selectedRowKeysEdit, selectedRowKeys: selectedRowKeysEdit,
@@ -313,25 +337,28 @@
:pagination="false"> :pagination="false">
</a-table> </a-table>
<a-pagination <a-pagination
:current="queryParams.pageNum" :current="queryData.pageNum"
:total="total" :total="total"
:page-size="queryParams.pageSize" :page-size="queryData.pageSize"
:pageSizeOptions="['5']"
style="display: flex; justify-content: center; margin-top: 16px" style="display: flex; justify-content: center; margin-top: 16px"
:show-size-changer="true" :show-size-changer="true"
:show-quick-jumper="true" :show-quick-jumper="true"
@change="onChange" /> @change="onChange" />
<a-upload <a-upload-dragger
v-model:file-list="fileList" v-model:fileList="fileList"
accept=".pdf"
name="file" name="file"
accept=".jpg,.jpeg,.png,.gif,.bmp,.pdf"
@remove="handleFileRemove" @remove="handleFileRemove"
:before-upload="beforeUpload" :before-upload="beforeUpload"
@change="handleChange"> @change="handleChange">
<a-button> <p class="ant-upload-drag-icon">
<upload-outlined></upload-outlined> <inbox-outlined></inbox-outlined>
点击上传凭证 </p>
</a-button> <p class="ant-upload-hint">1.仅支持pdf格式文件或文件夹</p>
</a-upload> <p class="ant-upload-hint">2.文件名命名规则为能源种类_年份</p>
<p class="ant-upload-hint">3.每次上传自动覆盖</p>
</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>
@@ -341,15 +368,16 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, watch, toRaw, defineEmits } from 'vue'; import { ref, watch, toRaw, defineEmits, nextTick } from 'vue';
import { http } from '/nerv-lib/util/http'; import { http } from '/nerv-lib/util/http';
import { Pagination, Modal, message } from 'ant-design-vue'; import { Pagination, Modal, message, Upload } from 'ant-design-vue';
import type { TreeProps, UploadChangeParam } from 'ant-design-vue'; import type { TreeProps, UploadChangeParam } from 'ant-design-vue';
import { import {
EditOutlined, EditOutlined,
PlusCircleOutlined, PlusCircleOutlined,
MinusCircleOutlined, MinusCircleOutlined,
UploadOutlined, UploadOutlined,
InboxOutlined,
} from '@ant-design/icons-vue'; } from '@ant-design/icons-vue';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { voucherColumns, drawerColumns } from '../config'; import { voucherColumns, drawerColumns } from '../config';
@@ -361,6 +389,7 @@
} from '/@/api/carbonEmissionFactorLibrary'; } from '/@/api/carbonEmissionFactorLibrary';
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';
defineOptions({ defineOptions({
energyType: 'fillInPage', // 与页面路由name一致缓存才可生效 energyType: 'fillInPage', // 与页面路由name一致缓存才可生效
components: { components: {
@@ -382,12 +411,12 @@
type: String, type: String,
}, },
}); });
const activeKey = ref('1');
const orgId = ref(''); const orgId = ref('');
const result = JSON.parse(sessionStorage.getItem('ORGID')!); const result = JSON.parse(sessionStorage.getItem('ORGID')!);
orgId.value = result; orgId.value = result;
const fetch = (api, params = { orgId: orgId.value }) => { const fetch = (api, params = { orgId: orgId.value }, config) => {
return http.post(api, params); return http.post(api, params, config);
}; };
// 左侧树结构 // 左侧树结构
const x = 3; const x = 3;
@@ -865,15 +894,17 @@
selectedRowKeys.value.forEach((item) => { selectedRowKeys.value.forEach((item) => {
deleteIds.value.append('ids', item); deleteIds.value.append('ids', item);
}); });
fetch(uploadPic.downloadZip, deleteIds.value) const config = {
responseType: 'blob',
};
fetch(uploadPic.downloadZip, deleteIds.value, config)
.then((res) => { .then((res) => {
// 创建一个 URL 对象,指向图片数据的 blob // 创建一个 URL 对象,指向图片数据的 blob
const url = window.URL.createObjectURL(new Blob([res.data])); const url = window.URL.createObjectURL(new Blob([res]));
// 创建一个 <a> 标签,用于触发下载 // 创建一个 <a> 标签,用于触发下载
const link = document.createElement('a'); const link = document.createElement('a');
link.href = url; link.href = url;
debugger; link.setAttribute('download', '碳盘查凭证.zip'); // 设置下载的文件名
link.setAttribute('download', ''); // 设置下载的文件名
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
@@ -910,10 +941,15 @@
const queryData = ref({ const queryData = ref({
orgId: orgId.value, orgId: orgId.value,
pageNum: 1, pageNum: 1,
pageSize: 999, pageSize: 5,
}); });
const edit = (record) => { const energyTypeOptions = ref([]);
getDictList(); const acquisitionDate = ref();
const edit = async (record) => {
acquisitionDate.value = record.acquisitionDate;
// 获取能耗类型
const options = await dict({ params: { dicKey: 'ENERGY_TYPE' } });
energyTypeOptions.value = options.data.data;
getNewTable(); getNewTable();
editFormState.value.id = record.id; editFormState.value.id = record.id;
editFormState.value.dataSources = record.dataSources; editFormState.value.dataSources = record.dataSources;
@@ -949,46 +985,66 @@
if (value === '3') { if (value === '3') {
canEdit.value = true; canEdit.value = true;
automatic.value = true; automatic.value = true;
} else {
automatic.value = false;
} }
}; };
// 定义采集节点数的变量 // 定义采集节点数的变量
const collectingNodes = ref<TreeSelectProps['treeData']>([]); const collectingNodes = ref<TreeSelectProps['treeData']>([]);
const getDictList = () => { const getTypeConsume = ref();
const changeEnergyType = (value) => {
getTypeConsume.value = value;
// 获取自动采集节点的数据 // 获取自动采集节点的数据
fetch(group.queryDeviceGroupTree, { energyType: 'ELECTRICITY_USAGE', orgId: orgId.value }).then( fetch(group.queryDeviceGroupTree, { energyType: value, orgId: orgId.value }).then((res) => {
(res) => { collectingNodes.value = res.data;
collectingNodes.value = res.data; collectingNodes.value = collectingNodes.value.map((item) => ({
collectingNodes.value = collectingNodes.value.map((item) => ({ value: item.id,
value: item.id, label: item.pointName,
label: item.pointName, children: item.children
children: item.children ? item.children.map((child) => ({
? item.children.map((child) => ({ value: child.id,
value: child.id, label: child.pointName,
label: child.pointName, }))
})) : [],
: [], }));
})); });
},
);
}; };
const selectNode = (value) => { const selectNode = (value) => {
debugger; const getConsumeData = ref({
acquisitionDate: acquisitionDate.value,
collectionNode: value,
orgId: orgId.value,
energyConsumptionType: getTypeConsume.value,
});
fetch(carbonInventoryCheck.nodeCancellationConsumption, getConsumeData.value).then((res) => {
editFormState.value.consumption = res.data;
});
}; };
// 上传附件 // 上传附件
const fileList = ref<UploadProps['fileList']>([]); const fileList = ref<UploadProps['fileList']>([]);
const isValidFileName = (filename: string): boolean => {
const regex = /^[\s\S]+_\d{4}\.pdf$/;
return regex.test(filename);
};
const beforeUpload: UploadProps['beforeUpload'] = (file) => { const beforeUpload: UploadProps['beforeUpload'] = (file) => {
const filename = file.name;
if (!isValidFileName(filename)) {
message.error('文件名不符合规则');
return Upload.LIST_IGNORE; // 阻止文件上传
}
return false; return false;
}; };
const handleChange = (info: UploadChangeParam) => { const handleChange = (info: UploadChangeParam) => {
fileList.value = [...info.fileList]; // fileList.value = [...info.fileList];
if (info.file.status !== 'uploading') { const { fileList: newFileList } = info;
console.log(info.file, info.fileList); // 删除fileList中的第一条数据
} if (newFileList.length > 1) {
if (info.file.status === 'done') { delIds.value.push(info.fileList[0].uid);
message.success(`${info.file.name} 文件上传成功`); newFileList.shift(); // 删除第一条数据
} else if (info.file.status === 'error') {
message.error(`${info.file.name} 文件上传失败`);
} }
// 更新fileList
fileList.value = [...newFileList];
}; };
const delIds = ref([]); const delIds = ref([]);
const handleFileRemove = (file) => { const handleFileRemove = (file) => {
@@ -1062,8 +1118,8 @@
}; };
// 分页器 // 分页器
const onChange = (pageNumber: number, size: number) => { const onChange = (pageNumber: number, size: number) => {
queryParams.value.pageNum = pageNumber; queryData.value.pageNum = pageNumber;
queryParams.value.pageSize = size; queryData.value.pageSize = size;
getNewTable(); getNewTable();
}; };
// 点击切换排放统计/碳排流向 // 点击切换排放统计/碳排流向
@@ -1388,6 +1444,20 @@
chartInstance = echarts.init(tplxChart.value); chartInstance = echarts.init(tplxChart.value);
chartInstance.setOption(option); chartInstance.setOption(option);
}; };
const handleTabChange = (key) => {
console.log('Tab changed:', key);
// 在这里可以执行需要在页面切换时执行的逻辑
if (key === '2') {
nextTick(() => {
getEmissionStatistic();
});
} else if (key === '3') {
nextTick(() => {
getCarbonFlowDirection();
});
}
};
// 点击返回 // 点击返回
const emit = defineEmits(['change-data']); const emit = defineEmits(['change-data']);
const changeParentData = () => { const changeParentData = () => {
@@ -1413,7 +1483,7 @@
flex-direction: column; flex-direction: column;
.top { .top {
position: relative; position: relative;
height: 80%; height: 100%;
margin-bottom: 20px; margin-bottom: 20px;
.ns-form-title { .ns-form-title {
font-weight: bold; font-weight: bold;
@@ -1492,10 +1562,13 @@
flex: 1; flex: 1;
min-width: 0; min-width: 0;
height: 100%; height: 100%;
padding: @ns-gap;
background-color: @white; background-color: @white;
border-radius: @ns-border-radius; border-radius: @ns-border-radius;
box-shadow: @ns-content-box-shadow; box-shadow: @ns-content-box-shadow;
position: relative;
:deep(.ant-tabs-content-holder) {
padding: 20px;
}
.ns-table-title { .ns-table-title {
text-align: left; text-align: left;
font-size: 16px; font-size: 16px;
@@ -1552,4 +1625,8 @@
margin-left: 10%; margin-left: 10%;
flex-direction: column; flex-direction: column;
} }
:deep(.ant-upload.ant-upload-drag) {
height: 18vh;
margin-top: 10px;
}
</style> </style>

View File

@@ -1,51 +1,79 @@
<template> <template>
<div class="main"> <div class="main">
<div class="left"> <div class="totalTitle">
<div class="top"> <div class="ns-form-title">
<a-form style="width: 100%; margin: 0 auto"> <div class="title">{{ props.year }}年济阳站碳盘查报告</div>
<div class="ns-form-title"> <div class="standard" style="display: flex; align-items: center">
<div class="title">{{ props.year }}年济阳站碳盘查报告</div> <img
<div class="standard"> width="11px"
<span>适用标准ISO 14064-1</span> height="11px"
<a-button type="primary" style="margin-left: 12px" @click="openCategoryConfig" style="margin-right: 5px"
>类别配置</a-button src="../../../../../src/icon/carbonInventoryCheck.svg" />
> <span
</div> style="
</div> font-size: 12px;
<div style="padding: 0 16px !important; width: 100%"> font-weight: 400;
<a-row> letter-spacing: 0px;
<a-col :span="24" style="margin-bottom: 16px"> line-height: 16.8px;
<a-input-search color: rgba(67, 136, 251, 1);
v-model:value="searchValue" text-align: left;
style="margin-bottom: 8px" vertical-align: top;
placeholder="请输入关键词" /> ">
</a-col> 适用标准ISO 14064-1
</a-row> </span>
</div> <a-button type="primary" @click="changeParentData" ghost style="margin-left: 6px">
</a-form> 返回
<a-tree </a-button>
:expanded-keys="expandedKeysL" </div>
:selectedKeys="selectedKeysL"
:auto-expand-parent="autoExpandParent"
:tree-data="gData"
v-if="gData && gData.length > 0"
:height="233"
show-line
style="padding: 0 16px !important"
@expand="onExpandL"
@select="onSelectL"
block-node>
<template #title="{ cnValue }">
<span v-if="cnValue && searchValue && cnValue.indexOf(searchValue) > -1">
{{ cnValue.substring(0, cnValue.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ cnValue.substring(cnValue.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ cnValue }}</span>
</template>
</a-tree>
</div> </div>
<!-- <div class="bottom"> </div>
<div style="display: flex; height: 100%">
<div class="left">
<div class="top">
<a-form style="width: 100%; margin: 0 auto">
<div class="ns-form-title">
<div>能源类别</div>
<div class="standard">
<a-button type="primary" style="margin-left: 12px" @click="openCategoryConfig">
类别配置
</a-button>
</div>
</div>
<div style="padding: 0 16px !important; width: 100%">
<a-row>
<a-col :span="24" style="margin-bottom: 16px">
<a-input-search
v-model:value="searchValue"
style="margin-bottom: 8px"
placeholder="请输入关键词" />
</a-col>
</a-row>
</div>
</a-form>
<a-tree
:expanded-keys="expandedKeysL"
:selectedKeys="selectedKeysL"
:auto-expand-parent="autoExpandParent"
:tree-data="gData"
v-if="gData && gData.length > 0"
:height="233"
show-line
style="padding: 0 16px !important"
@expand="onExpandL"
@select="onSelectL"
block-node>
<template #title="{ cnValue }">
<span v-if="cnValue && searchValue && cnValue.indexOf(searchValue) > -1">
{{ cnValue.substring(0, cnValue.indexOf(searchValue)) }}
<span style="color: #f50">{{ searchValue }}</span>
{{ cnValue.substring(cnValue.indexOf(searchValue) + searchValue.length) }}
</span>
<span v-else>{{ cnValue }}</span>
</template>
</a-tree>
<a-empty v-else />
</div>
<!-- <div class="bottom">
<a-form style="width: 100%; margin: 0 auto"> <a-form style="width: 100%; margin: 0 auto">
<div class="ns-form-title"><div class="title">报告相关</div></div> <div class="ns-form-title"><div class="title">报告相关</div></div>
<div class="button" style="padding: 0 16px !important"> <div class="button" style="padding: 0 16px !important">
@@ -54,87 +82,89 @@
</div> </div>
</a-form> </a-form>
</div> --> </div> -->
</div> </div>
<div class="right"> <div class="right">
<a-button <a-tabs v-model:activeKey="activeKey" @change="handleTabChange" style="height: 100%">
type="primary" <a-tab-pane key="1" tab="排放源">
@click="changeParentData" <div style="display: flex; height: 100%">
style="position: absolute; right: 25px; top: 10px; z-index: 99"> <div class="mainLeft">
返回 <a-tree
</a-button> v-if="treeData && treeData.length > 0"
<a-tabs v-model:activeKey="activeKey" @change="handleTabChange" style="height: 100%"> :expandedKeys="expandedKeysR"
<a-tab-pane key="1" tab="排放源"> :selectedKeys="selectedKeysR"
<div style="display: flex; height: 100%"> :checkedKeys="checkedKeys"
<div class="mainLeft"> :tree-data="treeData"
<a-tree @select="onSelectR"
:expandedKeys="expandedKeysR" block-node>
:selectedKeys="selectedKeysR" <template #title="data">
:checkedKeys="checkedKeys" <div class="treeRow">
:tree-data="treeData" <div>
@select="onSelectR" <span>{{ data.emissionSource }}</span>
block-node> </div>
<template #title="data"> <div class="actionMore">
<div class="treeRow"> <EditOutlined @click="editUnit(data)" />
<div> <MinusCircleOutlined style="margin-left: 6px" @click="delUnit(data)" />
<span>{{ data.emissionSource }}</span> </div>
</div> </div>
<div class="actionMore"> </template>
<EditOutlined @click="editUnit(data)" /> </a-tree>
<MinusCircleOutlined style="margin-left: 6px" @click="delUnit(data)" /> <a-empty v-else />
</div> <div class="addTreeNode">
</div> <a-button type="primary" style="width: 100%" @click="addTreeNodeData">
</template> 新增
</a-tree> </a-button>
<div class="addTreeNode"> </div>
<a-button type="primary" style="width: 100%" @click="addTreeNodeData" </div>
>新增</a-button <div class="mainRight">
> <a-table
:columns="columns"
v-if="data && data.length > 0"
:data-source="data"
:pagination="false"
bordered
size="middle"
:scroll="{ y: 500 }">
<template #title>
<a-button type="primary" @click="downLoadVoucher">凭证</a-button>
</template>
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'dataSources'">
<span v-if="record.dataSources">{{ record.dataSources.label }}</span>
</template>
<template v-if="column.dataIndex === 'carbonSource'">
<span v-if="record.carbonSource">{{ record.carbonSource.label }}</span>
</template>
<template v-if="column.key === 'action'">
<span>
<a @click="edit(record)">编辑</a>
</span>
</template>
</template>
</a-table>
<a-empty v-else />
</div> </div>
</div> </div>
<div class="mainRight"> </a-tab-pane>
<a-table <a-tab-pane key="2" tab="排放统计">
:columns="columns" <a-table
:data-source="data" :columns="pftjColumn"
:pagination="false" v-if="pftjData && pftjData.length > 0"
bordered :data-source="pftjData"
size="middle" bordered
:scroll="{ y: 500 }"> :pagination="false"
<template #title> :scroll="{ x: 2000, y: 500 }">
<a-button type="primary" @click="downLoadVoucher">凭证</a-button> <template #bodyCell="{ column, text, record }">
</template> {{ text || '-' }}
<template #bodyCell="{ column, text, record }"> </template>
<template v-if="column.dataIndex === 'dataSources'"> </a-table>
<span v-if="record.dataSources">{{ record.dataSources.label }}</span> <a-empty v-else />
</template> </a-tab-pane>
<template v-if="column.dataIndex === 'carbonSource'"> <a-tab-pane key="3" tab="碳排流向">
<span v-if="record.carbonSource">{{ record.carbonSource.label }}</span> <div v-if="showChart" ref="tplxChart" style="width: 100%; height: 68vh"></div>
</template> <a-empty v-else />
<template v-if="column.key === 'action'"> </a-tab-pane>
<span> </a-tabs>
<a @click="edit(record)">编辑</a> </div>
</span>
</template>
</template>
</a-table>
</div>
</div>
</a-tab-pane>
<a-tab-pane key="2" tab="排放统计">
<a-table
:columns="pftjColumn"
:data-source="pftjData"
bordered
:pagination="false"
:scroll="{ x: 2000, y: 500 }">
<template #bodyCell="{ column, text, record }">
{{ text || '-' }}
</template>
</a-table>
</a-tab-pane>
<a-tab-pane key="3" tab="碳排流向">
<div ref="tplxChart" style="width: 100%; height: 68vh"></div>
</a-tab-pane>
</a-tabs>
</div> </div>
<!-- 类别配置 --> <!-- 类别配置 -->
<a-drawer <a-drawer
@@ -144,16 +174,18 @@
:body-style="{ paddingBottom: '80px' }" :body-style="{ paddingBottom: '80px' }"
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
destroyOnClose destroyOnClose
title="类别配置"
@close="closeCategoryConfig"> @close="closeCategoryConfig">
<div class="search"> <div class="ns-form-title" style="margin-left: 10%">
<a-input-search <div class="title">类别设置</div>
v-model:value="searchcategoryConfig"
placeholder="请输入类别名称"
style="width: 250px"
@search="onSearch" />
</div> </div>
<div class="treePart"> <div class="treePart">
<div class="search">
<a-input-search
v-model:value="searchcategoryConfig"
placeholder="请输入类别名称"
style="width: 250px"
@search="onSearch" />
</div>
<a-tree <a-tree
:expanded-keys="categoryExpandedKeys" :expanded-keys="categoryExpandedKeys"
:selectedKeys="categorySelectedKeys" :selectedKeys="categorySelectedKeys"
@@ -186,6 +218,9 @@
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
destroyOnClose destroyOnClose
@close="onClose"> @close="onClose">
<div class="ns-form-title" style="display: flex">
<div class="title">新增</div>
</div>
<a-form <a-form
ref="formRef" ref="formRef"
:model="formState" :model="formState"
@@ -229,6 +264,9 @@
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
destroyOnClose destroyOnClose
@close="onCloseVoucher"> @close="onCloseVoucher">
<div class="ns-form-title">
<div class="title">凭证列表</div>
</div>
<a-table <a-table
:columns="voucherColumns" :columns="voucherColumns"
:data-source="voucherData" :data-source="voucherData"
@@ -254,6 +292,9 @@
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
destroyOnClose destroyOnClose
@close="onCloseEditData"> @close="onCloseEditData">
<div class="ns-form-title-edit">
<div class="title">编辑</div>
</div>
<a-form <a-form
ref="editFormRef" ref="editFormRef"
:model="editFormState" :model="editFormState"
@@ -321,6 +362,9 @@
</a-col> </a-col>
</a-row> </a-row>
</a-form> </a-form>
<div class="ns-form-title-edit" style="display: flex">
<div class="titleEdit">因子列表</div>
</div>
<a-table <a-table
:columns="drawerColumns" :columns="drawerColumns"
:data-source="newTableData" :data-source="newTableData"
@@ -345,6 +389,9 @@
:show-size-changer="true" :show-size-changer="true"
:show-quick-jumper="true" :show-quick-jumper="true"
@change="onChange" /> @change="onChange" />
<div class="ns-form-title-edit" style="display: flex">
<div class="titleEdit">凭证上传</div>
</div>
<a-upload-dragger <a-upload-dragger
v-model:fileList="fileList" v-model:fileList="fileList"
accept=".pdf" accept=".pdf"
@@ -658,8 +705,8 @@
// 新增/编辑排放源树节点 // 新增/编辑排放源树节点
const addTreeNodeVisible = ref(false); const addTreeNodeVisible = ref(false);
const formRef = ref(); const formRef = ref();
const labelCol = { span: 5 }; const labelCol = { span: 4 };
const wrapperCol = { span: 19 }; const wrapperCol = { span: 20 };
const formState = ref({ const formState = ref({
orgId: orgId.value, orgId: orgId.value,
year: props.year, year: props.year,
@@ -1148,10 +1195,16 @@
}); });
const linksData = ref([]); const linksData = ref([]);
const datalist = ref([]); const datalist = ref([]);
const showChart = ref(true);
const getCarbonFlowDirection = () => { const getCarbonFlowDirection = () => {
fetch(carbonInventoryCheck.carbonFlowDirection, queryFlowDirection.value).then((res) => { fetch(carbonInventoryCheck.carbonFlowDirection, queryFlowDirection.value).then((res) => {
console.log(res); console.log(res);
linksData.value = res.data[0]; linksData.value = res.data[0];
if (linksData.value[0].value !== 0) {
showChart.value = true;
} else {
showChart.value = false;
}
datalist.value = res.data[1]; datalist.value = res.data[1];
drawEcharts(); drawEcharts();
}); });
@@ -1467,14 +1520,18 @@
<style lang="less" scoped> <style lang="less" scoped>
.main { .main {
background-color: @ns-content-bg; background-color: #ffffff;
display: flex;
height: 100%; height: 100%;
padding: 16px;
} }
.left { .left {
width: 300px; width: 300px;
margin-right: @ns-gap; margin-right: @ns-gap;
min-width: fit-content; min-width: fit-content;
height: 93%;
border-radius: 8px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px 2px 20px rgb(69 123 234 / 20%);
> div { > div {
background-color: @white; background-color: @white;
} }
@@ -1491,7 +1548,6 @@
padding: 16px; padding: 16px;
margin-bottom: 16px; margin-bottom: 16px;
padding-bottom: 10px; padding-bottom: 10px;
border-bottom: 1px solid #e9e9e9;
} }
.title { .title {
text-align: left; text-align: left;
@@ -1561,11 +1617,10 @@
.right { .right {
flex: 1; flex: 1;
min-width: 0; min-width: 0;
height: 100%; height: 93%;
background-color: @white; border-radius: 8px;
border-radius: @ns-border-radius; background: rgba(255, 255, 255, 1);
box-shadow: @ns-content-box-shadow; box-shadow: 0px 2px 20px rgb(69 123 234 / 20%);
position: relative;
:deep(.ant-tabs-content-holder) { :deep(.ant-tabs-content-holder) {
padding: 20px; padding: 20px;
} }
@@ -1611,17 +1666,17 @@
} }
.search { .search {
width: 70%;
height: 5vh; height: 5vh;
display: flex; display: flex;
align-items: center; align-items: center;
margin-left: 10%; justify-content: center;
} }
.treePart { .treePart {
width: 70%; width: 70%;
height: 100%; height: 100%;
display: flex; display: flex;
border: 1px solid #bfbfbf; border: 1px solid rgba(235, 238, 245, 1);
border-radius: 8px;
margin-left: 10%; margin-left: 10%;
flex-direction: column; flex-direction: column;
} }
@@ -1629,4 +1684,48 @@
height: 18vh; height: 18vh;
margin-top: 10px; margin-top: 10px;
} }
.ns-form-title {
font-weight: bold;
user-select: text;
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: space-between;
}
.ns-form-title-edit {
font-weight: bold;
user-select: text;
}
.title {
text-align: left;
height: 32px;
line-height: 32px;
font-weight: bold;
user-select: text;
position: relative;
padding-left: 9px;
}
.titleEdit {
text-align: left;
height: 32px;
line-height: 32px;
font-weight: bold;
user-select: text;
position: relative;
}
.title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 13px;
width: 3px;
border-radius: 1px;
background-color: #2778ff;
}
:deep(.ant-table-title) {
display: flex;
justify-content: right;
}
</style> </style>

View File

@@ -20,6 +20,7 @@
:footer-style="{ textAlign: 'right' }" :footer-style="{ textAlign: 'right' }"
destroyOnClose destroyOnClose
@close="onClose"> @close="onClose">
<div class="ns-form-title"><div class="title">{{text}}</div></div>
<a-form <a-form
ref="formRef" ref="formRef"
:model="formState" :model="formState"
@@ -78,8 +79,9 @@
const visible = ref(false); const visible = ref(false);
const formState = ref({}); const formState = ref({});
const formRef = ref(); const formRef = ref();
const labelCol = { span: 5 }; const labelCol = { span: 4 };
const wrapperCol = { span: 19 }; const wrapperCol = { span: 20 };
const text = ref('新增报告')
const disabledDate = (current: moment.Moment | null) => { const disabledDate = (current: moment.Moment | null) => {
if (formState.value.reportPeriod === '2') { if (formState.value.reportPeriod === '2') {
const year = current.year(); const year = current.year();
@@ -140,6 +142,7 @@
name: 'userAdd', name: 'userAdd',
type: 'primary', type: 'primary',
handle: () => { handle: () => {
text.value = '新增报告'
visible.value = true; visible.value = true;
}, },
}, },
@@ -183,6 +186,7 @@
label: '编辑', label: '编辑',
name: 'userEdit', name: 'userEdit',
handle: (record: any) => { handle: (record: any) => {
text.value = '编辑报告'
visible.value = true; visible.value = true;
fetch(carbonInventoryCheck.findById, { id: record.id }).then((res) => { fetch(carbonInventoryCheck.findById, { id: record.id }).then((res) => {
formState.value = res.data; formState.value = res.data;
@@ -274,4 +278,30 @@
}; };
</script> </script>
<style lang="less" scoped></style> <style lang="less" scoped>
.ns-form-title {
font-weight: bold;
user-select: text;
margin-bottom: 16px;
}
.title {
text-align: left;
height: 32px;
line-height: 32px;
font-weight: bold;
user-select: text;
position: relative;
padding-left: 9px;
}
.title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 13px;
width: 3px;
border-radius: 1px;
background-color: #2778ff;
}
</style>

View File

@@ -2,25 +2,37 @@
<div class="totalContant"> <div class="totalContant">
<div class="ns-form-title"> <div class="ns-form-title">
<div class="title"> <div class="title">
<span>查询</span> <span>统计数据</span>
<a-date-picker
v-if="selectedTime"
style="margin-left: 5%"
valueFormat="YYYY"
v-model:value="selectYear"
@change="changeYear"
picker="year" />
<a-date-picker
v-else
style="margin-left: 5%"
valueFormat="YYYY-MM"
v-model:value="selectMonth"
@change="changeMonth"
picker="month" />
</div> </div>
</div>
<div
style="
display: flex;
width: 100%;
height: 5%;
align-items: center;
justify-content: space-between;
margin-bottom: 1%;
">
<a-date-picker
v-if="selectedTime"
valueFormat="YYYY"
v-model:value="selectYear"
@change="changeYear"
picker="year" />
<a-date-picker
v-else
valueFormat="YYYY-MM"
v-model:value="selectMonth"
@change="changeMonth"
picker="month" />
<div class="operation"> <div class="operation">
<div class="month" :style="monthStyles" @click="changeToMonth"><span></span></div> <div class="month" :style="monthStyles" @click="changeToMonth">
<div class="year" :style="yearStyles" @click="changeToYear"><span></span></div> <span :style="monthText">本月</span>
</div>
<div class="year" :style="yearStyles" @click="changeToYear">
<span :style="yearText">本年</span>
</div>
</div> </div>
</div> </div>
<div class="contant"> <div class="contant">
@@ -62,8 +74,10 @@
const selectYear = ref<Dayjs>(dayjs(new Date().getFullYear().toString())); const selectYear = ref<Dayjs>(dayjs(new Date().getFullYear().toString()));
const selectMonth = ref<Dayjs>(dayjs().startOf('year').month(0)); const selectMonth = ref<Dayjs>(dayjs().startOf('year').month(0));
// 年/月切换 // 年/月切换
const monthStyles = ref('background: #f2f2f2'); const monthStyles = ref('background: transparent');
const yearStyles = ref('background: #2778ff'); const yearStyles = ref('background: #2778ff');
const monthText = ref('color: #2778ff');
const yearText = ref('color: #ffffff');
const selectedTime = ref(true); const selectedTime = ref(true);
const changeMonth = () => { const changeMonth = () => {
queryParams.value.yearMonth = selectMonth.value; queryParams.value.yearMonth = selectMonth.value;
@@ -71,7 +85,9 @@
}; };
const changeToMonth = () => { const changeToMonth = () => {
monthStyles.value = 'background: #2778ff'; monthStyles.value = 'background: #2778ff';
yearStyles.value = 'background: #f2f2f2'; yearStyles.value = 'background: transparent';
monthText.value = 'color: #ffffff';
yearText.value = 'color: #2778ff';
queryParams.value.yearAndMonth = 'month'; queryParams.value.yearAndMonth = 'month';
queryParams.value.yearMonth = selectMonth.value.format('YYYY-DD'); queryParams.value.yearMonth = selectMonth.value.format('YYYY-DD');
columns.value[2].title = '月份'; columns.value[2].title = '月份';
@@ -84,8 +100,10 @@
getTableData(); getTableData();
}; };
const changeToYear = () => { const changeToYear = () => {
monthStyles.value = 'background: #f2f2f2'; monthStyles.value = 'background:transparent';
yearStyles.value = 'background: #2778ff'; yearStyles.value = 'background: #2778ff';
monthText.value = 'color: #2778ff';
yearText.value = 'color: #ffffff';
queryParams.value.yearAndMonth = 'year'; queryParams.value.yearAndMonth = 'year';
delete queryParams.value.yearMonth; delete queryParams.value.yearMonth;
// queryParams.value.year = selectYear.value; // queryParams.value.year = selectYear.value;
@@ -218,6 +236,7 @@
const columns = ref([ const columns = ref([
{ {
title: '序号', title: '序号',
width: 100,
customRender: (text: any) => { customRender: (text: any) => {
return text.index + 1; return text.index + 1;
}, },
@@ -301,32 +320,32 @@
border-radius: 1px; border-radius: 1px;
background-color: #2778ff; background-color: #2778ff;
} }
.operation { }
display: flex; .operation {
margin-right: 10px; display: flex;
font-weight: 400; margin-right: 10px;
height: 70%; font-weight: 400;
cursor: pointer; height: 90%;
width: 10%; cursor: pointer;
} width: 10%;
.month { border-radius: 4px;
width: 70px; border: 1px solid rgba(39, 120, 255, 1);
display: flex; }
align-items: center; .month {
justify-content: center; width: 50%;
// background: #f2f2f2; display: flex;
} align-items: center;
.year { justify-content: center;
width: 70px; }
display: flex; .year {
align-items: center; width: 50%;
justify-content: center; display: flex;
// background: #2778ff; align-items: center;
} justify-content: center;
} }
.contant { .contant {
width: 100%; width: 100%;
height: calc(100% - 5vh); height: calc(94% - 5vh);
.chartsPart { .chartsPart {
width: 100%; width: 100%;
height: 35%; height: 35%;
@@ -336,6 +355,7 @@
width: 19%; width: 19%;
height: 100%; height: 100%;
background: rgba(39, 120, 255, 0.05); background: rgba(39, 120, 255, 0.05);
border-radius: 8px;
} }
} }
.tablePart { .tablePart {

View File

@@ -88,7 +88,6 @@
selectedRowKeys: selectedRowKeys, selectedRowKeys: selectedRowKeys,
onChange: onSelectionChange, onChange: onSelectionChange,
}" }"
:scroll="{ x: 1300, y: 400 }"
:pagination="false"> :pagination="false">
<template #bodyCell="{ column, text, record }"> <template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'action'"> <template v-if="column.key === 'action'">
@@ -209,6 +208,7 @@
import type { UnwrapRef } from 'vue'; import type { UnwrapRef } from 'vue';
import { ref, defineEmits, reactive, toRaw } from 'vue'; import { ref, defineEmits, reactive, toRaw } from 'vue';
import { http } from '/nerv-lib/util/http'; import { http } from '/nerv-lib/util/http';
import { message } from 'ant-design-vue';
import { import {
CaretUpOutlined, CaretUpOutlined,
CaretDownOutlined, CaretDownOutlined,
@@ -402,7 +402,7 @@
// 在这里可以执行需要在页面切换时执行的逻辑 // 在这里可以执行需要在页面切换时执行的逻辑
if (key === '1') { if (key === '1') {
} else if (key === '2') { } else if (key === '2') {
if (selectedRowKeysSet.value) { if (selectedRowKeysSet.value.length !== 0) {
fetch(carbonPlanning.monthBenchmarkSetting, { fetch(carbonPlanning.monthBenchmarkSetting, {
type: props.type, type: props.type,
referenceYear: selectedRowKeysSet.value[0], referenceYear: selectedRowKeysSet.value[0],
@@ -413,6 +413,7 @@
monthData.value = res.data; monthData.value = res.data;
}); });
} else { } else {
message.warning('请先选择年基准值!');
activeKey.value = '1'; activeKey.value = '1';
} }
} }
@@ -420,6 +421,16 @@
//开关 //开关
const changeSwitch = (data: any) => { const changeSwitch = (data: any) => {
data.isAutoObtained = data.isAutoObtained === 0 ? 1 : 0; data.isAutoObtained = data.isAutoObtained === 0 ? 1 : 0;
if (data.isAutoObtained === 0) {
fetch(carbonPlanning.autoObtained, {
type: props.type,
itemizeId: props.parentId,
orgId: orgId.value,
yearMonth: data.yearMonth,
}).then((res) => {
data.referenceValue = res.data.referenceValue;
});
}
monthData.value = [...monthData.value]; monthData.value = [...monthData.value];
console.log(monthData.value); console.log(monthData.value);
}; };
@@ -473,11 +484,18 @@
itemizeId: props.parentId, itemizeId: props.parentId,
}).then((res) => { }).then((res) => {
visible.value = false; visible.value = false;
activeKey.value = '1';
selectedRowKeysSet.value = []; selectedRowKeysSet.value = [];
getTableData(); getTableData();
}); });
}; };
const onClose = () => { const onClose = () => {
activeKey.value = '1';
selectedRowKeysSet.value = [];
if (selectYear.value) {
selectYear.value = '';
queryData.value.referenceYear = selectYear.value;
}
visible.value = false; visible.value = false;
}; };
// echarts图 // echarts图
@@ -766,9 +784,12 @@
} }
.model { .model {
width: 16%; width: 16%;
height: 90%; height: 100%;
background: #f7f9ff; background: #f7f9ff;
padding: 12px; padding: 12px;
border-radius: 12px;
background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(222, 255, 246, 1) 100%);
border: 1px solid rgba(18, 174, 132, 1);
.quantity { .quantity {
font-size: 12px; font-size: 12px;
font-weight: 400; font-weight: 400;

View File

@@ -4,25 +4,37 @@
<div class="title"> <div class="title">
<span>统计数据</span> <span>统计数据</span>
<a-button style="margin-left: 5%" type="primary" @click="addNode">新增节点</a-button> <a-button style="margin-left: 5%" type="primary" @click="addNode">新增节点</a-button>
<a-date-picker
v-if="selectedTime"
style="margin-left: 5%"
v-model:value="selectYearValue"
:disabled-date="disabledDate"
valueFormat="YYYY"
@change="changeYear"
picker="year" />
<a-date-picker
v-else
style="margin-left: 5%"
v-model:value="selectMonthValue"
valueFormat="YYYY-MM"
@change="changeMonth"
picker="month" />
</div> </div>
</div>
<div
style="
display: flex;
width: 100%;
height: 5%;
align-items: center;
justify-content: space-between;
margin-bottom: 1%;
">
<a-date-picker
v-if="selectedTime"
v-model:value="selectYearValue"
:disabled-date="disabledDate"
valueFormat="YYYY"
@change="changeYear"
picker="year" />
<a-date-picker
v-else
v-model:value="selectMonthValue"
valueFormat="YYYY-MM"
@change="changeMonth"
picker="month" />
<div class="operation"> <div class="operation">
<div class="month" :style="monthStyles" @click="changeToMonth"><span></span></div> <div class="month" :style="monthStyles" @click="changeToMonth">
<div class="year" :style="yearStyles" @click="changeToYear"><span></span></div> <span :style="monthText">本月</span>
</div>
<div class="year" :style="yearStyles" @click="changeToYear">
<span :style="yearText">本年</span>
</div>
</div> </div>
</div> </div>
<div class="contant"> <div class="contant">
@@ -38,8 +50,7 @@
:pagination="false" :pagination="false"
row-key="itemizeId" row-key="itemizeId"
:onRow="onRow" :onRow="onRow"
:customRow="customRow" :customRow="customRow">
:scroll="{ x: 1300, y: 250 }">
<template #bodyCell="{ column, text, record }"> <template #bodyCell="{ column, text, record }">
<template v-if="column.key === 'action'"> <template v-if="column.key === 'action'">
<span> <span>
@@ -61,6 +72,9 @@
</div> </div>
<!-- 新增节点 --> <!-- 新增节点 -->
<a-drawer :visible="visible" :width="500" @close="onClose" :footer-style="{ textAlign: 'right' }"> <a-drawer :visible="visible" :width="500" @close="onClose" :footer-style="{ textAlign: 'right' }">
<div class="ns-form-title">
<div class="title">新增节点</div>
</div>
<a-tree <a-tree
:expanded-keys="expandedKeys" :expanded-keys="expandedKeys"
:selectedKeys="selectedKeys" :selectedKeys="selectedKeys"
@@ -124,12 +138,16 @@
}; };
// 年/月切换 // 年/月切换
const monthStyles = ref('background: #f2f2f2'); const monthStyles = ref('background: #transparent');
const yearStyles = ref('background: #2778ff'); const yearStyles = ref('background: #2778ff');
const monthText = ref('color: #2778ff');
const yearText = ref('color: #ffffff');
const selectedTime = ref(true); const selectedTime = ref(true);
const changeToMonth = () => { const changeToMonth = () => {
monthStyles.value = 'background: #2778ff'; monthStyles.value = 'background: #2778ff';
yearStyles.value = 'background: #f2f2f2'; yearStyles.value = 'background: #transparent';
monthText.value = 'color: #ffffff';
yearText.value = 'color: #2778ff';
columns.value[2].title = '月份'; columns.value[2].title = '月份';
columns.value[2].dataIndex = 'yearMonth'; columns.value[2].dataIndex = 'yearMonth';
selectedTime.value = false; selectedTime.value = false;
@@ -138,8 +156,10 @@
getMonthPillarData(); getMonthPillarData();
}; };
const changeToYear = () => { const changeToYear = () => {
monthStyles.value = 'background: #f2f2f2'; monthStyles.value = 'background: #transparent';
yearStyles.value = 'background: #2778ff'; yearStyles.value = 'background: #2778ff';
monthText.value = 'color: #2778ff';
yearText.value = 'color: #ffffff';
columns.value[2].title = '年份'; columns.value[2].title = '年份';
columns.value[2].dataIndex = 'year'; columns.value[2].dataIndex = 'year';
selectedTime.value = true; selectedTime.value = true;
@@ -574,7 +594,9 @@
user-select: text; user-select: text;
position: relative; position: relative;
padding-left: 9px; padding-left: 9px;
width: 50%; width: 100%;
display: flex;
justify-content: space-between;
} }
.title::before { .title::before {
content: ''; content: '';
@@ -587,34 +609,35 @@
border-radius: 1px; border-radius: 1px;
background-color: #2778ff; background-color: #2778ff;
} }
.operation { }
display: flex; .operation {
margin-right: 10px; display: flex;
font-weight: 400; margin-right: 10px;
height: 70%; font-weight: 400;
cursor: pointer; height: 90%;
width: 10%; cursor: pointer;
} width: 10%;
.month { border-radius: 4px;
width: 70px; border: 1px solid rgba(39, 120, 255, 1);
display: flex; }
align-items: center; .month {
justify-content: center; width: 50%;
// background: #f2f2f2; display: flex;
} align-items: center;
.year { justify-content: center;
width: 70px; }
display: flex; .year {
align-items: center; width: 50%;
justify-content: center; display: flex;
// background: #2778ff; align-items: center;
} justify-content: center;
} }
.contant { .contant {
width: 100%; width: 100%;
height: calc(100% - 5vh); height: calc(94% - 5vh);
overflow-y: auto;
.chartsPart { .chartsPart {
width: 100%; width: 99%;
height: 40%; height: 40%;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@@ -9,13 +9,13 @@
<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" />
</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" />
</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" />
</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" />
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
@@ -51,47 +51,47 @@
} }
}); });
} else if (key === '2') { } else if (key === '2') {
tabId.value = 1; tabId.value = 4;
energyType.value = 'ELECTRICITY_USAGE' energyType.value = 'ELECTRICITY_USAGE';
nextTick(() => { nextTick(() => {
if (electricRef.value) { if (electricRef.value) {
electricRef.value.electricTotal = true electricRef.value.electricTotal = true;
electricRef.value.changeToYear(); // 调用子组件的方法 electricRef.value.changeToYear(); // 调用子组件的方法
} }
}); });
} else if (key === '3') { } else if (key === '3') {
tabId.value = 2; tabId.value = 5;
energyType.value = 'WATER_USAGE' energyType.value = 'WATER_USAGE';
nextTick(() => { nextTick(() => {
if (useWaterRef.value) { if (useWaterRef.value) {
useWaterRef.value.electricTotal = true useWaterRef.value.electricTotal = true;
useWaterRef.value.changeToYear(); // 调用子组件的方法 useWaterRef.value.changeToYear(); // 调用子组件的方法
} }
}); });
} else if (key === '4') { } else if (key === '4') {
tabId.value = 3; tabId.value = 6;
energyType.value = 'gongshuiliang' energyType.value = 'gongshuiliang';
nextTick(() => { nextTick(() => {
if (provideWaterRef.value) { if (provideWaterRef.value) {
provideWaterRef.value.electricTotal = true provideWaterRef.value.electricTotal = true;
provideWaterRef.value.changeToYear(); // 调用子组件的方法 provideWaterRef.value.changeToYear(); // 调用子组件的方法
} }
}); });
} else if (key === '5') { } else if (key === '5') {
tabId.value = 5; tabId.value = 7;
energyType.value = 'CARBON_EMISSIONS' energyType.value = 'CARBON_EMISSIONS';
nextTick(() => { nextTick(() => {
if (carbonEmissionsRef.value) { if (carbonEmissionsRef.value) {
carbonEmissionsRef.value.electricTotal = true carbonEmissionsRef.value.electricTotal = true;
carbonEmissionsRef.value.changeToYear(); // 调用子组件的方法 carbonEmissionsRef.value.changeToYear(); // 调用子组件的方法
} }
}); });
} else if (key === '6') { } else if (key === '6') {
tabId.value = 4; tabId.value = 8;
energyType.value = 'HEAT_SUPPLY' energyType.value = 'HEAT_SUPPLY';
nextTick(() => { nextTick(() => {
if (provideHotRef.value) { if (provideHotRef.value) {
provideHotRef.value.electricTotal = true provideHotRef.value.electricTotal = true;
provideHotRef.value.changeToYear(); // 调用子组件的方法 provideHotRef.value.changeToYear(); // 调用子组件的方法
} }
}); });

View File

@@ -1,7 +1,12 @@
<template> <template>
<div class="div-add"> <div class="div-add">
<button class="add" @click="addModal">添加</button> <button class="add" @click="addModal">添加</button>
<a-popconfirm title="是否提交以上修改?" ok-text="确定" cancel-text="取消" @confirm="sendTable"> <a-popconfirm
title="是否提交以上修改?"
placement="bottomLeft"
ok-text="确定"
cancel-text="取消"
@confirm="sendTable">
<button class="add" style="margin-left: 20px">执行</button> <button class="add" style="margin-left: 20px">执行</button>
</a-popconfirm> </a-popconfirm>
</div> </div>
@@ -47,6 +52,7 @@
title="此操作将移除该数据" title="此操作将移除该数据"
ok-text="确定" ok-text="确定"
cancel-text="取消" cancel-text="取消"
placement="topRight"
@confirm="deletePlan(row)"> @confirm="deletePlan(row)">
<div class="tabDelete">删除</div> <div class="tabDelete">删除</div>
</a-popconfirm> </a-popconfirm>
@@ -55,7 +61,7 @@
</tbody> </tbody>
</table> </table>
<div class="out-dialog" v-if="addVisible"> <div class="out-dialog" v-if="addVisible">
<div class="content" v-if="addVisible"> <div class="content">
<div class="div-operation"></div> <div class="div-operation"></div>
<span class="text-operation">计划库</span> <span class="text-operation">计划库</span>
</div> </div>
@@ -132,7 +138,15 @@
// 计划启用/禁用事件 // 计划启用/禁用事件
const togglePlan = (state: number) => { const togglePlan = (state: number) => {
dataSource.value.forEach((item: any) => { dataSource.value.forEach((item: any) => {
item.executeStatus.value = state; // 执行中 无法修改为待执行
if (state == 1) {
if (item.executeStatus.value != 2) {
item.executeStatus.value = state;
}
// 任何状态都可以修改为 暂停
} else {
item.executeStatus.value = state;
}
}); });
}; };
@@ -155,20 +169,33 @@
const deletePlan = (row: any) => { const deletePlan = (row: any) => {
row.executeStatus.value = 0; row.executeStatus.value = 0;
}; };
// 重启表格中的计划(将当前任意状态,修改为待执行 = 1 // 重启表格中的计划(将当前非 执行中 状态,修改为待执行 = 1
const startPlan = (row: any) => { const startPlan = (row: any) => {
if (row.executeStatus.value == 1) { if (row.executeStatus.value == 1) {
return message.info('该数据已是待执行状态,无需再次修改'); return message.info('该数据已是待执行状态,无需再次修改');
} }
if (row.executeStatus.value == 2) {
return message.info('执行中的状态已被启用,无需修改');
}
row.executeStatus.value = 1; row.executeStatus.value = 1;
}; };
// 将对表格的修改统一发送 // 将对表格的修改统一发送
const sendTable = () => { const sendTable = () => {
http.post(airConditionControl.submitTableData, dataSource.value).then(() => { http
message.success('操作成功'); .post(
getTable(); airConditionControl.submitTableData +
getLeftPlan(); `?projectId=${state.projectId}${state.siteId ? `&siteId=${state.siteId}` : ''}`,
}); dataSource.value,
)
.then((res) => {
if (res.retcode == 0) {
message.success('操作成功');
getTable();
getLeftPlan();
} else {
message.info(res.msg);
}
});
}; };
// tab页弹窗部分 ==================================================== // tab页弹窗部分 ====================================================
@@ -225,7 +252,7 @@
getLeftPlan(); getLeftPlan();
}); });
}; };
// 穿梭框交互
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
return option.description.indexOf(inputValue) > -1; return option.description.indexOf(inputValue) > -1;
}; };

View File

@@ -11,7 +11,7 @@
</thead> </thead>
<tbody> <tbody>
<tr <tr
:style="{ color: row.ctrlResult == 0 ? 'red' : 'white' }" :style="{ color: row.ctrlResult == 1 ? 'red' : 'white' }"
v-for="(row, index) in dataSource" v-for="(row, index) in dataSource"
:key="index" :key="index"
@click="handleRowClick(row.id, index)" @click="handleRowClick(row.id, index)"
@@ -20,7 +20,7 @@
<td>{{ row.startTime }}</td> <td>{{ row.startTime }}</td>
<td>{{ row.operationContent }}</td> <td>{{ row.operationContent }}</td>
<td>{{ row.createUser }}</td> <td>{{ row.createUser }}</td>
<td>{{ row.ctrlResult ? '成功' : '失败' }}</td> <td>{{ row.ctrlResult ? '失败' : '成功' }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -163,6 +163,8 @@
}; };
// 刷新功能(右下角) // 刷新功能(右下角)
const reset = () => { const reset = () => {
trIndex.value = -1;
logModalVisible.value = false;
pagination.value = { pagination.value = {
pageSize: 10, pageSize: 10,
pageNum: 1, pageNum: 1,
@@ -172,13 +174,8 @@
}; };
// 点击日志行事件 // 点击日志行事件
const handleRowClick = (id: any, index: any) => { const handleRowClick = (id: any, index: any) => {
// 忽略无效点击 trIndex.value = index;
if (index === trIndex.value) { getLogDetail(id);
return;
} else {
trIndex.value = index;
getLogDetail(id);
}
}; };
// 日志详情业务 ================================================== // 日志详情业务 ==================================================
@@ -200,7 +197,7 @@
const cxList = ref([]); const cxList = ref([]);
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@import './dialogStyle.less'; @import '../style/dialogStyle.less';
// 右下角添加按钮 // 右下角添加按钮
.div-add { .div-add {

View File

@@ -56,14 +56,15 @@
ref="tabs1Ref" ref="tabs1Ref"
@reset="reset" @reset="reset"
@reload="reload" @reload="reload"
@changeArea="changeArea" @reset-all="resetDrawer"
@change-area="changeArea"
:treeData="treeData" /> :treeData="treeData" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="计划列表" force-render> <a-tab-pane key="2" tab="计划列表" force-render>
<tabs2 /> <tabs2 ref="tabs2Ref" @reset-all="resetDrawer" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" tab="日志"> <a-tab-pane key="3" tab="日志">
<tabs3 /> <tabs3 ref="tabs3Ref" @reset-all="resetDrawer" />
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</a-drawer> </a-drawer>
@@ -269,8 +270,29 @@
const toggleDrawer = () => { const toggleDrawer = () => {
visible.value = !visible.value; visible.value = !visible.value;
}; };
// 当其中一个tab产生了数据修改可以调用该方法重置所有tab
const resetDrawer = () => {
// 设备点阵重置
getBulbs();
// tab1重置
reload();
tabs1Ref.value.refresh();
// tab2 tab3 可能未加载
try {
// tab2重置
tabs2Ref.value.reset();
} catch {}
try {
// tab3重置
tabs3Ref.value.reset();
} catch {}
};
// 抽屉tab1组件的引用 // 抽屉tab1组件的引用
const tabs1Ref = ref(); const tabs1Ref = ref();
// 抽屉tab2组件的引用
const tabs2Ref = ref();
// 抽屉tab3组件的引用
const tabs3Ref = ref();
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@import './index.less'; @import './index.less';

View File

@@ -7,7 +7,9 @@
<img src="/asset/image//bulbLogo/21962.png" alt="" /> <img src="/asset/image//bulbLogo/21962.png" alt="" />
<span class="tag-text">{{ blub.regionName + ' > ' + blub.deviceGroupName }}</span></div <span class="tag-text">{{ blub.regionName + ' > ' + blub.deviceGroupName }}</span></div
> >
<button class="right-button">{{ record.runStatus.label }}</button> <button class="right-button">{{
record?.runStatus?.label ? record.runStatus.label : '--'
}}</button>
</div> </div>
<div class="light-tag-box"> <div class="light-tag-box">
<div class="tag-box-item"> <div class="tag-box-item">
@@ -36,25 +38,25 @@
<div class="icon-box" :style="props.blub.styleText"> <div class="icon-box" :style="props.blub.styleText">
<!-- 正常=0 --> <!-- 正常=0 -->
<img <img
v-if="record.runStatus.value == 0" v-if="record?.runStatus?.value == 0"
class="icon-item" class="icon-item"
src="/asset/image/bulbLogo/on.png" src="/asset/image/bulbLogo/on.png"
alt="" /> alt="" />
<!-- 故障=1 --> <!-- 故障=1 -->
<img <img
v-if="record.runStatus.value == 1" v-if="record?.runStatus?.value == 1"
class="icon-item" class="icon-item"
src="/asset/image/bulbLogo/off.png" src="/asset/image/bulbLogo/off.png"
alt="" /> alt="" />
<!-- 维修=2 --> <!-- 维修=2 -->
<img <img
v-if="record.runStatus.value == 2" v-if="record?.runStatus?.value == 2"
class="icon-item" class="icon-item"
src="/asset/image/bulbLogo/repair.png" src="/asset/image/bulbLogo/repair.png"
alt="" /> alt="" />
<!-- 警告=3 --> <!-- 警告=3 -->
<img <img
v-if="record.runStatus.value == 3" v-if="record?.runStatus?.value == 3"
class="icon-item" class="icon-item"
src="/asset/image/bulbLogo/alarm.png" src="/asset/image/bulbLogo/alarm.png"
alt="" /> alt="" />

View File

@@ -265,12 +265,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, onMounted } from 'vue'; import { ref, computed, onMounted, watch } from 'vue';
import { DownOutlined, UpOutlined, StopOutlined } from '@ant-design/icons-vue'; import { DownOutlined, UpOutlined, StopOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue'; import { message, Modal } from 'ant-design-vue';
// 请求 // 请求
import { http } from '/nerv-lib/util/http'; import { http } from '/nerv-lib/util/http';
import { lightingManage } from '/@/api/IlluminationInfo'; import { lightingManage } from '/@/api/IlluminationInfo';
import { planManage } from '/@/api/planManage';
// 全局变量 // 全局变量
import { items } from '/@/store/item'; import { items } from '/@/store/item';
@@ -299,12 +300,24 @@
}, },
}, },
}); });
watch(
() => props.treeData,
(newValue) => {
// 重新为照明回路赋值
// buttons2.value = newValue[0].childList;
},
{
deep: true,
},
);
/** 向上传递方法 /** 向上传递方法
* @method changeArea 用于控制俯视图的选中状态 * @method changeArea 用于控制俯视图的选中状态
* @method reset 用于重置按钮区 * @method reset 用于重置按钮区
* @method reload 用于刷新一次页面 * @method reload 用于刷新一次页面
* @method resetAll 刷新所有tab对计划进行修改时需刷新tab2与tab3
*/ */
const emit = defineEmits(['changeArea', 'reset', 'reload']); const emit = defineEmits(['changeArea', 'reset', 'reload', 'resetAll']);
// 照明区域业务 ======================================================================= // 照明区域业务 =======================================================================
@@ -666,22 +679,21 @@
changeList.value.forEach((item: any) => { changeList.value.forEach((item: any) => {
resetChangeList(item); resetChangeList(item);
}); });
}
changeList.value = [];
if (!reload) {
lockList.value.forEach((item: any) => { lockList.value.forEach((item: any) => {
resetLockList(item); resetLockList(item);
}); });
// 默认选择第一个照明区域
let data = props.treeData[0];
// 默认选中
data.selected = true;
// 默认选中 1-1 分区 回路
buttons2.value = data.childList;
resetMode();
} }
changeList.value = [];
lockList.value = []; lockList.value = [];
// 默认选择第一个楼层
let data = props.treeData[0];
// 默认选中
data.selected = true;
// 默认选中 1-1 分区 回路
buttons2.value = data.childList;
resetMode();
}; };
// 将已修改的禁用/启用状态改回 // 将已修改的禁用/启用状态改回
const resetLockList = (item: any) => { const resetLockList = (item: any) => {
props.treeData.find((v: any) => { props.treeData.find((v: any) => {
@@ -729,6 +741,55 @@
if (!changeList.value.length && !lockList.value.length) { if (!changeList.value.length && !lockList.value.length) {
return message.info('未产生任何修改'); return message.info('未产生任何修改');
} }
http
.get(planManage.getRunningPlan, {
deviceType: 1,
projectId: state.projectId,
siteId: state.siteId,
})
.then((res) => {
// 如果有计划正在执行
if (res.data && res.data.length) {
// 此处框架本身存在问题弹出层在本地环境无法关闭暂时使用浏览器自带的confirm方法
// Modal.confirm({
// title: '提示信息',
// content: '有计划正在执行,点击"确定"将暂停当前计划',
// onOk() {
// return new Promise((resolve, reject) => {
// });
// },
// onCancel() { },
// });
let flag = window.confirm('有计划正在执行,点击"确定"将暂停当前计划');
if (flag) {
// 如果点击了确定,将先终止所有进行中的计划
http
.post(lightingManage.submitChangeList, {
projectId: state.projectId,
siteId: state.siteId,
lockList: [],
sceneList: [],
})
.then((res) => {
console.log(res, '成功');
// 如果重置成功,则获取修改前后对比数据
if (res.retcode == 0) {
sendChangeList();
// 未成功提示
} else {
message.error('关闭进行中的任务操作失败,请重新尝试');
}
});
}
// 没有计划正在执行,则直接请求
} else {
sendChangeList();
}
});
};
// 提交控制场景 与 禁用/启用 修改
const sendChangeList = () => {
http http
.post(lightingManage.getChangeList, { .post(lightingManage.getChangeList, {
sceneList: changeList.value, sceneList: changeList.value,
@@ -737,11 +798,11 @@
siteId: state.siteId, siteId: state.siteId,
}) })
.then((res) => { .then((res) => {
if (res.msg === 'success') { if (res.retcode == 0) {
diffList.value = res.data; diffList.value = res.data;
executeVisible.value = true; executeVisible.value = true;
} else { } else {
message.warning('获取修改内容失败'); message.error('获取修改内容失败');
} }
}) })
.catch(() => {}); .catch(() => {});
@@ -792,7 +853,7 @@
.then((res) => { .then((res) => {
let data = res.data; let data = res.data;
// 修改请求发送了,但操作时产生了失败结果 // 修改请求发送了,但操作时产生了失败结果
if (data.retcode != 0) { if (res.retcode != 0) {
// 直接提示并跳出 // 直接提示并跳出
return message.warning(data.msg); return message.warning(data.msg);
} }
@@ -803,8 +864,8 @@
} else { } else {
message.info(`${data.successList.length}条修改成功,${data.failList.length}条修改失败`); message.info(`${data.successList.length}条修改成功,${data.failList.length}条修改失败`);
} }
emit('reload');
refresh(true); refresh(true);
emit('resetAll');
}) })
.catch(() => {}); .catch(() => {});
}; };
@@ -829,8 +890,6 @@
changeLine, changeLine,
// 重置当前选择 // 重置当前选择
refresh, refresh,
resetLockList,
resetChangeList,
}); });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@@ -1,7 +1,12 @@
<template> <template>
<div class="div-add"> <div class="div-add">
<button class="add" @click="addModal">添加</button> <button class="add" @click="addModal">添加</button>
<a-popconfirm title="是否提交以上修改?" ok-text="确定" cancel-text="取消" @confirm="sendTable"> <a-popconfirm
title="是否提交以上修改?"
placement="bottomLeft"
ok-text="确定"
cancel-text="取消"
@confirm="sendTable">
<button class="add" style="margin-left: 20px">执行</button> <button class="add" style="margin-left: 20px">执行</button>
</a-popconfirm> </a-popconfirm>
</div> </div>
@@ -47,6 +52,7 @@
title="此操作将移除该数据" title="此操作将移除该数据"
ok-text="确定" ok-text="确定"
cancel-text="取消" cancel-text="取消"
placement="topRight"
@confirm="deletePlan(row)"> @confirm="deletePlan(row)">
<div class="tabDelete">删除</div> <div class="tabDelete">删除</div>
</a-popconfirm> </a-popconfirm>
@@ -55,7 +61,7 @@
</tbody> </tbody>
</table> </table>
<div class="out-dialog" v-if="addVisible"> <div class="out-dialog" v-if="addVisible">
<div class="content" v-if="addVisible"> <div class="content">
<div class="div-operation"></div> <div class="div-operation"></div>
<span class="text-operation">计划库</span> <span class="text-operation">计划库</span>
</div> </div>
@@ -93,18 +99,22 @@
// 初始化 =========================================================== // 初始化 ===========================================================
onMounted(() => { onMounted(() => {
// 获得枚举
getStateEnum(); getStateEnum();
// 计划表格 // 获得穿梭框 与 表格数据
getTable(); reset();
// 穿梭框原始数据
getLeftPlan();
}); });
// 全局变量 // 全局变量
const state = items(); const state = items();
// 获得任务状态枚举
const getStateEnum = async () => { const getStateEnum = async () => {
let enumData = await getEnum({ params: { enumType: 'PlanExecuteStatus' } }); let enumData = await getEnum({ params: { enumType: 'PlanExecuteStatus' } });
stateList.value = enumData.data; stateList.value = enumData.data;
}; };
/**
* @method resetAll 刷新3个tab中的全部数据修改计划会影响tab1数据信息生成tab3日志
*/
const emit = defineEmits(['resetAll']);
// tab页部分 ======================================================== // tab页部分 ========================================================
@@ -132,7 +142,15 @@
// 计划启用/禁用事件 // 计划启用/禁用事件
const togglePlan = (state: number) => { const togglePlan = (state: number) => {
dataSource.value.forEach((item: any) => { dataSource.value.forEach((item: any) => {
item.executeStatus.value = state; // 执行中 无法修改为待执行
if (state == 1) {
if (item.executeStatus.value != 2) {
item.executeStatus.value = state;
}
// 任何状态都可以修改为 暂停
} else {
item.executeStatus.value = state;
}
}); });
}; };
@@ -160,6 +178,9 @@
if (row.executeStatus.value == 1) { if (row.executeStatus.value == 1) {
return message.info('该数据已是待执行状态,无需再次修改'); return message.info('该数据已是待执行状态,无需再次修改');
} }
if (row.executeStatus.value == 2) {
return message.info('执行中的状态已被启用,无需修改');
}
row.executeStatus.value = 1; row.executeStatus.value = 1;
}; };
// 将对表格的修改统一发送 // 将对表格的修改统一发送
@@ -173,14 +194,21 @@
.then((res) => { .then((res) => {
if (res.retcode == 0) { if (res.retcode == 0) {
message.success('操作成功'); message.success('操作成功');
getTable(); // 刷新数据
getLeftPlan(); emit('resetAll');
} else { } else {
message.info(res.msg); message.info(res.msg);
} }
}); });
}; };
const reset = () => {
// 计划表格
getTable();
// 穿梭框原始数据
getLeftPlan();
};
// tab页弹窗部分 ==================================================== // tab页弹窗部分 ====================================================
// 添加弹窗控制变量 // 添加弹窗控制变量
@@ -204,7 +232,7 @@
deviceType: 1, deviceType: 1,
}) })
.then((res) => { .then((res) => {
let arr = []; let arr: Array<Object> = [];
res.data.forEach((item: any) => { res.data.forEach((item: any) => {
arr.push({ arr.push({
key: item.id, key: item.id,
@@ -231,14 +259,18 @@
http.post(planManage.submitTransData, targetKeys.value).then(() => { http.post(planManage.submitTransData, targetKeys.value).then(() => {
message.success('添加成功'); message.success('添加成功');
// 如果发送成功,则刷新表格 // 如果发送成功,则刷新表格
getTable(); reset();
getLeftPlan();
}); });
}; };
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
return option.description.indexOf(inputValue) > -1; return option.description.indexOf(inputValue) > -1;
}; };
// 向外暴露方法
defineExpose({
reset,
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@import '../style/dialogStyle.less'; @import '../style/dialogStyle.less';

View File

@@ -11,7 +11,7 @@
</thead> </thead>
<tbody> <tbody>
<tr <tr
:style="{ color: row.ctrlResult == 0 ? 'red' : 'white' }" :style="{ color: row.ctrlResult == 1 ? 'red' : 'white' }"
v-for="(row, index) in dataSource" v-for="(row, index) in dataSource"
:key="index" :key="index"
@click="handleRowClick(row.id, index)" @click="handleRowClick(row.id, index)"
@@ -20,7 +20,7 @@
<td>{{ row.startTime }}</td> <td>{{ row.startTime }}</td>
<td>{{ row.operationContent }}</td> <td>{{ row.operationContent }}</td>
<td>{{ row.createUser }}</td> <td>{{ row.createUser }}</td>
<td>{{ row.ctrlResult ? '成功' : '失败' }}</td> <td>{{ row.ctrlResult ? '失败' : '成功' }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -31,6 +31,7 @@
show-size-changer show-size-changer
:total="pagination.total" :total="pagination.total"
@change="getTable(true)" /> @change="getTable(true)" />
<div style="width: 100%; height: 40px"></div>
<div class="out-dialog" :class="{ showDialog: logModalVisible }" v-if="logModalVisible"> <div class="out-dialog" :class="{ showDialog: logModalVisible }" v-if="logModalVisible">
<div class="content"> <div class="content">
@@ -54,9 +55,17 @@
<div class="btn-item"> <div class="btn-item">
<div class="left">控制模式</div> <div class="left">控制模式</div>
<div class="right"> <div class="right">
<span>手动</span> <span>{{
item.autoStatusBefore.label.indexOf('模式') != -1
? item.autoStatusBefore.label.replace('模式', '')
: item.autoStatusBefore.label
}}</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" /> <img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span></div <span>{{
item.autoStatusAfter.label.indexOf('模式') != -1
? item.autoStatusAfter.label.replace('模式', '')
: item.autoStatusAfter.label
}}</span></div
> >
</div> </div>
<div class="btn-item"> <div class="btn-item">
@@ -163,6 +172,8 @@
}; };
// 刷新功能(右下角) // 刷新功能(右下角)
const reset = () => { const reset = () => {
trIndex.value = -1;
logModalVisible.value = false;
pagination.value = { pagination.value = {
pageSize: 10, pageSize: 10,
pageNum: 1, pageNum: 1,
@@ -172,13 +183,8 @@
}; };
// 点击日志行事件 // 点击日志行事件
const handleRowClick = (id: any, index: any) => { const handleRowClick = (id: any, index: any) => {
// 忽略无效点击 trIndex.value = index;
if (index === trIndex.value) { getLogDetail(id);
return;
} else {
trIndex.value = index;
getLogDetail(id);
}
}; };
// 日志详情业务 ================================================== // 日志详情业务 ==================================================
@@ -197,7 +203,13 @@
} }
}); });
}; };
// 日志详情
const cxList = ref([]); const cxList = ref([]);
// 向外暴露方法
defineExpose({
reset,
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@import '../style/dialogStyle.less'; @import '../style/dialogStyle.less';

View File

@@ -1,3 +1,4 @@
// 颜色变量
:root { :root {
// 电梯 // 电梯
// 正常 // 正常

View File

@@ -1,3 +1,4 @@
// 设备群控 > 抽屉 > 控制面板 & 日志 的附加弹窗
.out-dialog { .out-dialog {
position: fixed; position: fixed;
right: 496px; right: 496px;

View File

@@ -137,6 +137,7 @@
title="此操作将会撤销修改" title="此操作将会撤销修改"
ok-text="确定" ok-text="确定"
cancel-text="取消" cancel-text="取消"
placement="bottomRight"
@confirm="delBtn(item)" @confirm="delBtn(item)"
@cancel="changeCancel"> @cancel="changeCancel">
<button class="cxbtn">撤销</button> <button class="cxbtn">撤销</button>
@@ -146,9 +147,9 @@
<div class="btn-item"> <div class="btn-item">
<div class="left">控制模式</div> <div class="left">控制模式</div>
<div class="right"> <div class="right">
<span>手动</span> <span>{{ item.stateBefore.autoStatus.label.replace('模式', '') }}</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" /> <img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span></div <span>{{ item.stateAfter.autoStatus.label.replace('模式', '') }}</span></div
> >
</div> </div>
<div class="btn-item"> <div class="btn-item">
@@ -230,12 +231,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, onMounted } from 'vue'; import { ref, computed, onMounted, watch } from 'vue';
import { DownOutlined, UpOutlined, StopOutlined } from '@ant-design/icons-vue'; import { DownOutlined, UpOutlined, StopOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue'; import { message, Modal } from 'ant-design-vue';
// 请求 // 请求
import { http } from '/nerv-lib/util/http'; import { http } from '/nerv-lib/util/http';
import { ventilating } from '/@/api/ventilatingSystem'; import { ventilating } from '/@/api/ventilatingSystem';
import { planManage } from '/@/api/planManage';
// 全局变量 // 全局变量
import { items } from '/@/store/item'; import { items } from '/@/store/item';
@@ -247,12 +249,15 @@
if (props.type == '排风扇') { if (props.type == '排风扇') {
url.getList = ventilating.getChangeList1; url.getList = ventilating.getChangeList1;
url.sendList = ventilating.sendChangeList1; url.sendList = ventilating.sendChangeList1;
url.deviceType = 3;
} else if (props.type == '风幕机') { } else if (props.type == '风幕机') {
url.getList = ventilating.getChangeList2; url.getList = ventilating.getChangeList2;
url.sendList = ventilating.sendChangeList2; url.sendList = ventilating.sendChangeList2;
url.deviceType = 4;
} else { } else {
url.getList = ventilating.getChangeList3; url.getList = ventilating.getChangeList3;
url.sendList = ventilating.sendChangeList3; url.sendList = ventilating.sendChangeList3;
url.deviceType = 5;
} }
}); });
// 分区初始化,以 1-1 作为默认回路 // 分区初始化,以 1-1 作为默认回路
@@ -266,6 +271,7 @@
const url = { const url = {
getList: '', getList: '',
sendList: '', sendList: '',
deviceType: 0,
}; };
// 与父组件的交互 =================================================================== // 与父组件的交互 ===================================================================
@@ -282,12 +288,24 @@
type: String, type: String,
}, },
}); });
watch(
() => props.treeData,
(newValue) => {
// 重新为照明回路赋值
// buttons2.value = newValue[0].childList;
},
{
deep: true,
},
);
/** 向上传递方法 /** 向上传递方法
* @method changeArea 用于控制俯视图的选中状态 * @method changeArea 用于控制俯视图的选中状态
* @method reset 用于重置按钮区 * @method reset 用于重置按钮区
* @method reload 用于刷新一次页面 * @method reload 用于刷新一次页面
* @method resetAll 刷新所有tab对计划进行修改时需刷新tab2与tab3
*/ */
const emit = defineEmits(['reset', 'reload']); const emit = defineEmits(['reset', 'reload', 'resetAll']);
// 照明回路业务 ====================================================================== // 照明回路业务 ======================================================================
@@ -613,21 +631,19 @@
changeList.value.forEach((item: any) => { changeList.value.forEach((item: any) => {
resetChangeList(item); resetChangeList(item);
}); });
}
changeList.value = [];
if (!reload) {
lockList.value.forEach((item: any) => { lockList.value.forEach((item: any) => {
resetLockList(item); resetLockList(item);
}); });
// 默认选择第一个楼层
let data = props.treeData[0];
// 默认选中
data.selected = true;
// 默认选中 1-1 分区 回路
buttons2.value = data.childList;
resetMode();
} }
changeList.value = [];
lockList.value = []; lockList.value = [];
// 默认选择第一个楼层
let data = props.treeData[0];
// 默认选中
data.selected = true;
// 默认选中 1-1 分区 回路
buttons2.value = data.childList;
resetMode();
}; };
// 将已修改的禁用/启用状态改回 // 将已修改的禁用/启用状态改回
const resetLockList = (item: any) => { const resetLockList = (item: any) => {
@@ -676,6 +692,55 @@
if (!changeList.value.length && !lockList.value.length) { if (!changeList.value.length && !lockList.value.length) {
return message.info('未产生任何修改'); return message.info('未产生任何修改');
} }
http
.get(planManage.getRunningPlan, {
deviceType: url.deviceType,
projectId: state.projectId,
siteId: state.siteId,
})
.then((res) => {
// 如果有计划正在执行
if (res.data && res.data.length) {
// 此处框架本身存在问题弹出层在本地环境无法关闭暂时使用浏览器自带的confirm方法
// Modal.confirm({
// title: '提示信息',
// content: '有计划正在执行,点击"确定"将暂停当前计划',
// onOk() {
// return new Promise((resolve, reject) => {
// });
// },
// onCancel() { },
// });
let flag = window.confirm('有计划正在执行,点击"确定"将暂停当前计划');
if (flag) {
// 如果点击了确定,将先终止所有进行中的计划
http
.post(url.getList, {
projectId: state.projectId,
siteId: state.siteId,
lockList: [],
sceneList: [],
})
.then((res) => {
console.log(res, '成功');
// 如果重置成功,则获取修改前后对比数据
if (res.retcode == 0) {
sendChangeList();
// 未成功提示
} else {
message.error('关闭进行中的任务操作失败,请重新尝试');
}
});
}
// 没有计划正在执行,则直接请求
} else {
sendChangeList();
}
});
};
// 提交控制场景 与 禁用/启用 修改
const sendChangeList = () => {
http http
.post(url.getList, { .post(url.getList, {
sceneList: changeList.value, sceneList: changeList.value,
@@ -684,11 +749,11 @@
siteId: state.siteId, siteId: state.siteId,
}) })
.then((res) => { .then((res) => {
if (res.msg === 'success') { if (res.retcode == 0) {
diffList.value = res.data; diffList.value = res.data;
executeVisible.value = true; executeVisible.value = true;
} else { } else {
message.warning('获取修改内容失败'); message.error('获取修改内容失败');
} }
}) })
.catch(() => {}); .catch(() => {});
@@ -736,9 +801,22 @@
projectId: state.projectId, projectId: state.projectId,
siteId: state.siteId, siteId: state.siteId,
}) })
.then(() => { .then((res) => {
emit('reload'); let data = res.data;
// 修改请求发送了,但操作时产生了失败结果
if (res.retcode != 0) {
// 直接提示并跳出
return message.warning(data.msg);
}
// 所有修改均生效
if (data.allSucceed) {
message.success('修改完成');
// allSucceed不为true则至少有一条数据修改失败
} else {
message.info(`${data.successList.length}条修改成功,${data.failList.length}条修改失败`);
}
refresh(true); refresh(true);
emit('resetAll');
}) })
.catch(() => {}); .catch(() => {});
}; };
@@ -759,6 +837,8 @@
defineExpose({ defineExpose({
// 回路切换 // 回路切换
changeLine, changeLine,
// 重置当前选择
refresh,
}); });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@@ -11,7 +11,7 @@
</thead> </thead>
<tbody> <tbody>
<tr <tr
:style="{ color: row.ctrlResult == 0 ? 'red' : 'white' }" :style="{ color: row.ctrlResult == 1 ? 'red' : 'white' }"
v-for="(row, index) in dataSource" v-for="(row, index) in dataSource"
:key="index" :key="index"
@click="handleRowClick(row.id, index)" @click="handleRowClick(row.id, index)"
@@ -20,7 +20,7 @@
<td>{{ row.startTime }}</td> <td>{{ row.startTime }}</td>
<td>{{ row.operationContent }}</td> <td>{{ row.operationContent }}</td>
<td>{{ row.createUser }}</td> <td>{{ row.createUser }}</td>
<td>{{ row.ctrlResult ? '成功' : '失败' }}</td> <td>{{ row.ctrlResult ? '失败' : '成功' }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -31,6 +31,7 @@
show-size-changer show-size-changer
:total="pagination.total" :total="pagination.total"
@change="getTable(true)" /> @change="getTable(true)" />
<div style="width: 100%; height: 40px"></div>
<div class="out-dialog" :class="{ showDialog: logModalVisible }" v-if="logModalVisible"> <div class="out-dialog" :class="{ showDialog: logModalVisible }" v-if="logModalVisible">
<div class="content"> <div class="content">
@@ -54,9 +55,17 @@
<div class="btn-item"> <div class="btn-item">
<div class="left">控制模式</div> <div class="left">控制模式</div>
<div class="right"> <div class="right">
<span>手动</span> <span>{{
item.autoStatusBefore.label.indexOf('模式') != -1
? item.autoStatusBefore.label.replace('模式', '')
: item.autoStatusBefore.label
}}</span>
<img src="/asset/image/bulbLogo/22406.png" alt="" /> <img src="/asset/image/bulbLogo/22406.png" alt="" />
<span>自动</span></div <span>{{
item.autoStatusAfter.label.indexOf('模式') != -1
? item.autoStatusAfter.label.replace('模式', '')
: item.autoStatusAfter.label
}}</span></div
> >
</div> </div>
<div class="btn-item"> <div class="btn-item">
@@ -193,6 +202,8 @@
}; };
// 刷新功能(右下角) // 刷新功能(右下角)
const reset = () => { const reset = () => {
trIndex.value = -1;
logModalVisible.value = false;
// state.setLoading(true); // state.setLoading(true);
pagination.value = { pagination.value = {
pageSize: 10, pageSize: 10,
@@ -203,13 +214,8 @@
}; };
// 点击日志行事件 // 点击日志行事件
const handleRowClick = (id: any, index: any) => { const handleRowClick = (id: any, index: any) => {
// 忽略无效点击 trIndex.value = index;
if (index === trIndex.value) { getLogDetail(id);
return;
} else {
trIndex.value = index;
getLogDetail(id);
}
}; };
// 日志详情业务 ================================================== // 日志详情业务 ==================================================
@@ -229,6 +235,11 @@
}); });
}; };
const cxList = ref([]); const cxList = ref([]);
// 向外暴露方法
defineExpose({
reset,
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@import '../../style/dialogStyle.less'; @import '../../style/dialogStyle.less';

View File

@@ -52,6 +52,7 @@
title="此操作将移除该数据" title="此操作将移除该数据"
ok-text="确定" ok-text="确定"
cancel-text="取消" cancel-text="取消"
placement="topRight"
@confirm="deletePlan(row)"> @confirm="deletePlan(row)">
<div class="tabDelete">删除</div> <div class="tabDelete">删除</div>
</a-popconfirm> </a-popconfirm>
@@ -60,7 +61,7 @@
</tbody> </tbody>
</table> </table>
<div class="out-dialog" v-if="addVisible"> <div class="out-dialog" v-if="addVisible">
<div class="content" v-if="addVisible"> <div class="content">
<div class="div-operation"></div> <div class="div-operation"></div>
<span class="text-operation">计划库</span> <span class="text-operation">计划库</span>
</div> </div>
@@ -126,6 +127,11 @@
} }
}); });
/**
* @method resetAll 刷新3个tab中的全部数据修改计划会影响tab1数据信息生成tab3日志
*/
const emit = defineEmits(['resetAll']);
// tab页部分 ======================================================== // tab页部分 ========================================================
// 设置枚举的颜色 与 文本 // 设置枚举的颜色 与 文本
@@ -150,7 +156,15 @@
// 计划启用/禁用事件 // 计划启用/禁用事件
const togglePlan = (state: number) => { const togglePlan = (state: number) => {
dataSource.value.forEach((item: any) => { dataSource.value.forEach((item: any) => {
item.executeStatus.value = state; // 执行中 无法修改为待执行
if (state == 1) {
if (item.executeStatus.value != 2) {
item.executeStatus.value = state;
}
// 任何状态都可以修改为 暂停
} else {
item.executeStatus.value = state;
}
}); });
}; };
@@ -178,6 +192,9 @@
if (row.executeStatus.value == 1) { if (row.executeStatus.value == 1) {
return message.info('该数据已是待执行状态,无需再次修改'); return message.info('该数据已是待执行状态,无需再次修改');
} }
if (row.executeStatus.value == 2) {
return message.info('执行中的状态已被启用,无需修改');
}
row.executeStatus.value = 1; row.executeStatus.value = 1;
}; };
// 将对表格的修改统一发送 // 将对表格的修改统一发送
@@ -187,13 +204,24 @@
url + `?projectId=${state.projectId}${state.siteId ? `&siteId=${state.siteId}` : ''}`, url + `?projectId=${state.projectId}${state.siteId ? `&siteId=${state.siteId}` : ''}`,
dataSource.value, dataSource.value,
) )
.then(() => { .then((res) => {
message.success('操作成功'); if (res.retcode == 0) {
getTable(); message.success('操作成功');
getLeftPlan(); // 刷新数据
emit('resetAll');
} else {
message.info(res.msg);
}
}); });
}; };
const reset = () => {
// 计划表格
getTable();
// 穿梭框原始数据
getLeftPlan();
};
// tab页弹窗部分 ==================================================== // tab页弹窗部分 ====================================================
// 添加弹窗控制变量 // 添加弹窗控制变量
@@ -244,14 +272,18 @@
http.post(planManage.submitTransData, targetKeys.value).then(() => { http.post(planManage.submitTransData, targetKeys.value).then(() => {
message.success('添加成功'); message.success('添加成功');
// 如果发送成功,则刷新表格 // 如果发送成功,则刷新表格
getTable(); reset();
getLeftPlan();
}); });
}; };
const filterOption = (inputValue: string, option: any) => { const filterOption = (inputValue: string, option: any) => {
return option.description.indexOf(inputValue) > -1; return option.description.indexOf(inputValue) > -1;
}; };
// 向外暴露方法
defineExpose({
reset,
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
@import '../../style/dialogStyle.less'; @import '../../style/dialogStyle.less';

View File

@@ -137,13 +137,17 @@
</div> </div>
<a-tabs v-model:activeKey="activeKey"> <a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="控制面板"> <a-tab-pane key="1" tab="控制面板">
<fanControl :treeData="treeData" :type="`排风扇`" /> <fanControl
ref="tabs1Ref"
@reset-all="resetDrawer"
:treeData="treeData"
:type="`排风扇`" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="计划列表" force-render> <a-tab-pane key="2" tab="计划列表" force-render>
<fanPlant :status="stateList" :type="3" /> <fanPlant ref="tabs2Ref" @reset-all="resetDrawer" :status="stateList" :type="3" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" tab="日志"> <a-tab-pane key="3" tab="日志">
<fanLog :type="3" /> <fanLog ref="tabs3Ref" @reset-all="resetDrawer" :type="3" />
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</a-drawer> </a-drawer>
@@ -194,13 +198,17 @@
</div> </div>
<a-tabs v-model:activeKey="activeKey"> <a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="控制面板"> <a-tab-pane key="1" tab="控制面板">
<fanControl :treeData="treeData" :type="`风幕机`" /> <fanControl
ref="tabs1Ref"
@reset-all="resetDrawer"
:treeData="treeData"
:type="`风幕机`" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="计划列表" force-render> <a-tab-pane key="2" tab="计划列表" force-render>
<fanPlant :status="stateList" :type="4" /> <fanPlant ref="tabs2Ref" @reset-all="resetDrawer" :status="stateList" :type="4" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" tab="日志"> <a-tab-pane key="3" tab="日志">
<fanLog :type="4" /> <fanLog ref="tabs3Ref" @reset-all="resetDrawer" :type="4" />
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</a-drawer> </a-drawer>
@@ -250,13 +258,17 @@
</div> </div>
<a-tabs v-model:activeKey="activeKey"> <a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="控制面板"> <a-tab-pane key="1" tab="控制面板">
<fanControl :treeData="treeData" :type="`电动窗`" /> <fanControl
ref="tabs1Ref"
@reset-all="resetDrawer"
:treeData="treeData"
:type="`电动窗`" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="2" tab="计划列表" force-render> <a-tab-pane key="2" tab="计划列表" force-render>
<fanPlant :status="stateList" :type="5" /> <fanPlant ref="tabs2Ref" @reset-all="resetDrawer" :status="stateList" :type="5" />
</a-tab-pane> </a-tab-pane>
<a-tab-pane key="3" tab="日志"> <a-tab-pane key="3" tab="日志">
<fanLog :type="5" /> <fanLog ref="tabs3Ref" @reset-all="resetDrawer" :type="5" />
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
</a-drawer> </a-drawer>
@@ -351,6 +363,15 @@
const toggleDrawer = () => { const toggleDrawer = () => {
visible.value = !visible.value; visible.value = !visible.value;
}; };
// 当前设备的请求URL
let url = '';
// 刷新当前的树形结构数据
const reload = () => {
http.get(url, { projectId: state.projectId, siteId: state.siteId }).then((res) => {
const data = res.data;
treeData.value = data[0].childList;
});
};
// 抽屉中tab1 - 控制面板 ================================================================= // 抽屉中tab1 - 控制面板 =================================================================
@@ -359,7 +380,6 @@
const getTree = async (type: number, index: number) => { const getTree = async (type: number, index: number) => {
// 切换时默认选择tab1 // 切换时默认选择tab1
activeKey.value = '1'; activeKey.value = '1';
let url;
if (type == 1) { if (type == 1) {
url = ventilating.getTree1; url = ventilating.getTree1;
} else if (type == 2) { } else if (type == 2) {
@@ -489,93 +509,33 @@
}, },
]); ]);
// 排风扇 // 排风扇
const fanData = ref([ const fanData = ref([]);
// {
// title: '排风扇',
// styleText: { left: '43.2%', bottom: '77.8%' },
// type: 'fan',
// lineType: '1',
// },
// {
// title: '排风扇',
// styleText: { left: '50%', bottom: '77.8%' },
// type: 'fan',
// lineType: '2',
// },
// {
// title: '排风扇',
// styleText: { left: '41.2%', bottom: '27.8%' },
// type: 'fan',
// lineType: '1',
// },
// {
// title: '排风扇',
// styleText: { left: '51.2%', bottom: '27.8%' },
// type: 'fan',
// lineType: '2',
// },
]);
// 风幕机 // 风幕机
const airCurtainData = ref([ const airCurtainData = ref([]);
// {
// title: '风幕机',
// styleText: { left: '38%', bottom: '57.8%' },
// type: 'airCurtain',
// },
// {
// title: '风幕机',
// styleText: { left: '58.5%', bottom: '57.3%' },
// type: 'airCurtain',
// },
// {
// title: '风幕机',
// styleText: { left: '64.2%', bottom: '22.8%' },
// type: 'airCurtain',
// },
]);
// 电动窗 // 电动窗
const windowData = ref([ const windowData = ref([]);
// {
// title: '电动窗1', // 当其中一个tab产生了数据修改可以调用该方法重置所有tab
// styleText: { left: '32%', bottom: '28%' }, const resetDrawer = () => {
// type: 'window', // tab1重置
// }, reload();
// { tabs1Ref.value.refresh();
// title: '电动窗2', // tab2 tab3 可能未加载
// styleText: { left: '33.5%', bottom: '42.8%' }, try {
// type: 'window', // tab2重置
// }, tabs2Ref.value.reset();
// { } catch {}
// title: '电动窗3', try {
// styleText: { left: '35%', bottom: '57.8%' }, // tab3重置
// type: 'window', tabs3Ref.value.reset();
// }, } catch {}
// { };
// title: '电动窗4', // 抽屉tab1组件的引用
// styleText: { left: '36.5%', bottom: '72.8%' }, const tabs1Ref = ref();
// type: 'window', // 抽屉tab2组件的引用
// }, const tabs2Ref = ref();
// { // 抽屉tab3组件的引用
// title: '电动窗5', const tabs3Ref = ref();
// styleText: { left: '66%', bottom: '28%' },
// type: 'window',
// },
// {
// title: '电动窗6',
// styleText: { left: '64%', bottom: '42.8%' },
// type: 'window',
// },
// {
// title: '电动窗7',
// styleText: { left: '62%', bottom: '57.8%' },
// type: 'window',
// },
// {
// title: '电动窗8',
// styleText: { left: '60%', bottom: '72.8%' },
// type: 'window',
// },
]);
onMounted(() => { onMounted(() => {
// 获得枚举 // 获得枚举
getStateEnum(); getStateEnum();