|
@ -48,68 +48,27 @@ |
|
|
</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"> |
|
|
<div class="ns-form-title"> |
|
|
<ns-view-list-table v-bind="tableConfig" :model="data" ref="mainRef" :scroll="{ x: 2000 }"> |
|
|
<div class="title">交易明细</div> |
|
|
|
|
|
<div class="operation" style="display: flex"> |
|
|
|
|
|
<a-button type="primary" @click="addDetail">新增</a-button> |
|
|
|
|
|
<a-upload |
|
|
|
|
|
v-model:file-list="importFileList" |
|
|
|
|
|
name="file" |
|
|
|
|
|
accept=".xlsx" |
|
|
|
|
|
:showUploadList="false" |
|
|
|
|
|
:custom-request="importFile"> |
|
|
|
|
|
<a-button type="primary" style="margin-left: 6px">导入</a-button> |
|
|
|
|
|
</a-upload> |
|
|
|
|
|
<a-button type="primary" style="margin-left: 6px" @click="exportFile">导出</a-button> |
|
|
|
|
|
<a-button |
|
|
|
|
|
type="primary" |
|
|
|
|
|
style="margin-left: 6px" |
|
|
|
|
|
:disabled="selectedRowKeys.length === 0" |
|
|
|
|
|
@click="deleteMore" |
|
|
|
|
|
>批量删除</a-button |
|
|
|
|
|
> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<a-table |
|
|
|
|
|
:columns="columns" |
|
|
|
|
|
:data-source="data" |
|
|
|
|
|
rowKey="id" |
|
|
|
|
|
@change="onChange" |
|
|
|
|
|
:rowSelection="{ |
|
|
|
|
|
selectedRowKeys: selectedRowKeys, |
|
|
|
|
|
onChange: onSelectionChange, |
|
|
|
|
|
}" |
|
|
|
|
|
:scroll="{ x: 1500, y: 400 }" |
|
|
|
|
|
:pagination="false"> |
|
|
|
|
|
<template #bodyCell="{ column, text, record }"> |
|
|
<template #bodyCell="{ column, text, record }"> |
|
|
<template v-if="column.dataIndex === 'accountType'"> |
|
|
<template v-if="column.dataIndex === 'accountType'"> |
|
|
<span v-if="record.accountType">{{ record.accountType.label }}</span> |
|
|
<span v-if="record.accountType">{{ record.accountType.label }}</span> |
|
|
</template> |
|
|
</template> |
|
|
<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> |
|
|
</ns-view-list-table> |
|
|
<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="ns-form-title"> |
|
|
<div class="title">配额统计</div> |
|
|
<div class="title">配额统计</div> |
|
|
<div class="operation" style="display: flex; justify-content: space-around; width: 63%"> |
|
|
<div class="operation" style="display: flex; justify-content: flex-end; width: 63%"> |
|
|
<a-button type="primary" @click="getTotalTable(1)">全国配额</a-button> |
|
|
<a-button type="primary" v-if="parentId === 1" @click="getTotalTable(1)" |
|
|
<a-button type="primary" @click="getTotalTable(2)">地方配额</a-button> |
|
|
>全国配额</a-button |
|
|
<a-button type="primary" @click="getTotalTable(3)">CCER配额</a-button> |
|
|
> |
|
|
|
|
|
<a-button type="primary" v-if="parentId === 2" @click="getTotalTable(2)" |
|
|
|
|
|
>地方配额</a-button |
|
|
|
|
|
> |
|
|
|
|
|
<a-button type="primary" v-if="parentId === 3" @click="getTotalTable(3)" |
|
|
|
|
|
>CCER配额</a-button |
|
|
|
|
|
> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<a-table :columns="totalColumns" :data-source="totalData" bordered :pagination="false"> |
|
|
<a-table :columns="totalColumns" :data-source="totalData" bordered :pagination="false"> |
|
@ -155,13 +114,25 @@ |
|
|
<a-date-picker v-model:value="formState.transactionDate" valueFormat="YYYY-MM-DD" /> |
|
|
<a-date-picker v-model:value="formState.transactionDate" valueFormat="YYYY-MM-DD" /> |
|
|
</a-form-item> |
|
|
</a-form-item> |
|
|
<a-form-item ref="name" label="交易数量" name="transactionQuantity"> |
|
|
<a-form-item ref="name" label="交易数量" name="transactionQuantity"> |
|
|
<a-input v-model:value="formState.transactionQuantity" placeholder="请输入交易数量" /> |
|
|
<a-input-number |
|
|
|
|
|
v-model:value="formState.transactionQuantity" |
|
|
|
|
|
:maxlength="11" |
|
|
|
|
|
@keydown="handleKeyDown" |
|
|
|
|
|
placeholder="请输入交易数量" /> |
|
|
</a-form-item> |
|
|
</a-form-item> |
|
|
<a-form-item ref="name" label="发生金额" name="amountIncurred"> |
|
|
<a-form-item ref="name" label="发生金额" name="amountIncurred"> |
|
|
<a-input v-model:value="formState.amountIncurred" placeholder="请输入发生金额" /> |
|
|
<a-input-number |
|
|
|
|
|
v-model:value="formState.amountIncurred" |
|
|
|
|
|
:maxlength="16" |
|
|
|
|
|
@keydown="handleKeyDown" |
|
|
|
|
|
placeholder="请输入发生金额" /> |
|
|
</a-form-item> |
|
|
</a-form-item> |
|
|
<a-form-item ref="name" label="交易对象" name="tradingPartner"> |
|
|
<a-form-item ref="name" label="交易对象" name="tradingPartner"> |
|
|
<a-input v-model:value="formState.tradingPartner" placeholder="请输入交易对象" /> |
|
|
<a-input |
|
|
|
|
|
v-model:value="formState.tradingPartner" |
|
|
|
|
|
:maxlength="20" |
|
|
|
|
|
@keydown="handleKeyDown" |
|
|
|
|
|
placeholder="请输入交易对象" /> |
|
|
</a-form-item> |
|
|
</a-form-item> |
|
|
<a-form-item ref="name" label="交易凭证"> |
|
|
<a-form-item ref="name" label="交易凭证"> |
|
|
<a-upload |
|
|
<a-upload |
|
@ -221,16 +192,20 @@ |
|
|
selectedRowKeys.value = selectedKeys; |
|
|
selectedRowKeys.value = selectedKeys; |
|
|
}; |
|
|
}; |
|
|
const total = ref<number>(); |
|
|
const total = ref<number>(); |
|
|
const thisYear = ref(new Date().getFullYear().toString()); |
|
|
const year = ref(new Date().getFullYear().toString()); |
|
|
const queryParams = ref({ |
|
|
const queryParams = ref({ |
|
|
pageNum: 1, |
|
|
pageNum: 1, |
|
|
pageSize: 10, |
|
|
pageSize: 10, |
|
|
orgId: orgId.value, |
|
|
orgId: orgId.value, |
|
|
accountType: props.parentId, |
|
|
accountType: props.parentId, |
|
|
year: thisYear.value, |
|
|
year: year.value, |
|
|
}); |
|
|
}); |
|
|
const searchTableList = () => { |
|
|
const searchTableList = () => { |
|
|
getDetailList(); |
|
|
year.value = queryParams.value.year; |
|
|
|
|
|
transactionType.value = queryParams.value.transactionType; |
|
|
|
|
|
accountType.value = queryParams.value.accountType; |
|
|
|
|
|
mainRef.value?.nsTableRef.reload(); |
|
|
|
|
|
// getDetailList(); |
|
|
}; |
|
|
}; |
|
|
// 获取左侧列表数据 |
|
|
// 获取左侧列表数据 |
|
|
const getDetailList = () => { |
|
|
const getDetailList = () => { |
|
@ -239,10 +214,11 @@ |
|
|
total.value = res.data.total; |
|
|
total.value = res.data.total; |
|
|
}); |
|
|
}); |
|
|
}; |
|
|
}; |
|
|
getDetailList(); |
|
|
// getDetailList(); |
|
|
const columns = [ |
|
|
const columns = [ |
|
|
{ |
|
|
{ |
|
|
title: '序号', |
|
|
title: '序号', |
|
|
|
|
|
width: 80, |
|
|
customRender: (text: any) => { |
|
|
customRender: (text: any) => { |
|
|
return text.index + 1; |
|
|
return text.index + 1; |
|
|
}, |
|
|
}, |
|
@ -298,9 +274,14 @@ |
|
|
pageNum: 1, |
|
|
pageNum: 1, |
|
|
pageSize: 10, |
|
|
pageSize: 10, |
|
|
orgId: orgId.value, |
|
|
orgId: orgId.value, |
|
|
year: new Date().getFullYear(), |
|
|
accountType: props.parentId, |
|
|
|
|
|
year: new Date().getFullYear().toString(), |
|
|
}; |
|
|
}; |
|
|
getDetailList(); |
|
|
accountType.value = props.parentId; |
|
|
|
|
|
year.value = new Date().getFullYear(); |
|
|
|
|
|
transactionType.value = ''; |
|
|
|
|
|
mainRef.value?.nsTableRef.reload(); |
|
|
|
|
|
// getDetailList(); |
|
|
}; |
|
|
}; |
|
|
const editData = (record) => { |
|
|
const editData = (record) => { |
|
|
getDictList(); |
|
|
getDictList(); |
|
@ -378,6 +359,196 @@ |
|
|
}, |
|
|
}, |
|
|
}); |
|
|
}); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const mainRef = ref(); |
|
|
|
|
|
const transactionType = ref(); |
|
|
|
|
|
const accountType = ref(); |
|
|
|
|
|
accountType.value = props.parentId; |
|
|
|
|
|
const tableConfig = ref({ |
|
|
|
|
|
title: '数据库', |
|
|
|
|
|
api: carbonAssets.carbonDetailsList, |
|
|
|
|
|
params: { |
|
|
|
|
|
orgId, |
|
|
|
|
|
accountType, |
|
|
|
|
|
year, |
|
|
|
|
|
}, |
|
|
|
|
|
headerActions: [ |
|
|
|
|
|
{ |
|
|
|
|
|
label: '新增', |
|
|
|
|
|
name: 'userAdd', |
|
|
|
|
|
type: 'primary', |
|
|
|
|
|
handle: () => { |
|
|
|
|
|
text.value = '新增'; |
|
|
|
|
|
visible.value = true; |
|
|
|
|
|
getDictList(); |
|
|
|
|
|
}, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
label: '导入', |
|
|
|
|
|
type: 'primary', |
|
|
|
|
|
name: 'carbonAssetsImport', |
|
|
|
|
|
extra: { |
|
|
|
|
|
api: carbonAssets.import, // 导入接口名 |
|
|
|
|
|
params: { |
|
|
|
|
|
orgId, |
|
|
|
|
|
}, |
|
|
|
|
|
title: '碳资产', // 弹窗title |
|
|
|
|
|
templateName: 'carbonAssets', // 所使用的文件名称 |
|
|
|
|
|
indexName: '碳资产', // 匹配类型字段 |
|
|
|
|
|
message: [ |
|
|
|
|
|
{ label: '1、若必填项未填写,则不能进行导入操作' }, |
|
|
|
|
|
{ label: `2、当重复时,则更新数据。` }, |
|
|
|
|
|
{ label: '3、数据将从模版的第五行进行导入。' }, |
|
|
|
|
|
{ label: '4、文件导入勿超过5MB。' }, |
|
|
|
|
|
], |
|
|
|
|
|
}, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
label: '导出', |
|
|
|
|
|
type: 'primary', |
|
|
|
|
|
handle: () => { |
|
|
|
|
|
const exportQuery = ref({ |
|
|
|
|
|
orgId: orgId.value, |
|
|
|
|
|
pageNum: 1, |
|
|
|
|
|
pageSize: 999, |
|
|
|
|
|
year: queryParams.value.year, |
|
|
|
|
|
ids: selectedRowKeys.value, |
|
|
|
|
|
}); |
|
|
|
|
|
const config = { |
|
|
|
|
|
responseType: 'blob', |
|
|
|
|
|
}; |
|
|
|
|
|
fetch(carbonAssets.export, exportQuery.value, config) |
|
|
|
|
|
.then((res) => { |
|
|
|
|
|
// 创建一个 URL 对象,指向图片数据的 blob |
|
|
|
|
|
const url = window.URL.createObjectURL(new Blob([res])); |
|
|
|
|
|
// 创建一个 <a> 标签,用于触发下载 |
|
|
|
|
|
const link = document.createElement('a'); |
|
|
|
|
|
link.href = url; |
|
|
|
|
|
link.setAttribute('download', 'carbonTradeDetails.xlsx'); // 设置下载的文件名 |
|
|
|
|
|
document.body.appendChild(link); |
|
|
|
|
|
link.click(); |
|
|
|
|
|
|
|
|
|
|
|
// 清理 URL 对象 |
|
|
|
|
|
window.URL.revokeObjectURL(url); |
|
|
|
|
|
selectedRowKeys.value = []; |
|
|
|
|
|
}) |
|
|
|
|
|
.catch((error) => { |
|
|
|
|
|
console.error('下载失败:', error); |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
label: '批量删除', |
|
|
|
|
|
type: 'primary', |
|
|
|
|
|
name: 'userBatchDel', |
|
|
|
|
|
dynamicDisabled: (data: any) => { |
|
|
|
|
|
return data.list.length === 0; |
|
|
|
|
|
}, |
|
|
|
|
|
confirm: true, |
|
|
|
|
|
isReload: true, |
|
|
|
|
|
isClearCheck: true, |
|
|
|
|
|
api: carbonAssets.delete, |
|
|
|
|
|
dynamicParams: { ids: 'id[]' }, |
|
|
|
|
|
}, |
|
|
|
|
|
], |
|
|
|
|
|
columns: [ |
|
|
|
|
|
{ |
|
|
|
|
|
title: '序号', |
|
|
|
|
|
width: 80, |
|
|
|
|
|
customRender: (text: any) => { |
|
|
|
|
|
return text.index + 1; |
|
|
|
|
|
}, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '资产类别', |
|
|
|
|
|
dataIndex: 'accountType', |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '交易方式', |
|
|
|
|
|
dataIndex: 'transactionTypeName', |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '交易日期', |
|
|
|
|
|
dataIndex: 'transactionDate', |
|
|
|
|
|
sorter: (a, b) => a.transactionDate - b.transactionDate, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '本期收入(tCO2)', |
|
|
|
|
|
dataIndex: 'income', |
|
|
|
|
|
sorter: (a, b) => a.income - b.income, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '本期支出(tCO2)', |
|
|
|
|
|
dataIndex: 'expenditure', |
|
|
|
|
|
sorter: (a, b) => a.expenditure - b.expenditure, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '发生金额(¥)', |
|
|
|
|
|
dataIndex: 'amountIncurredValue', |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '交易对象', |
|
|
|
|
|
dataIndex: 'tradingPartner', |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '更新人', |
|
|
|
|
|
dataIndex: 'updateUser', |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
title: '更新时间', |
|
|
|
|
|
dataIndex: 'updateTime', |
|
|
|
|
|
}, |
|
|
|
|
|
], |
|
|
|
|
|
columnActions: { |
|
|
|
|
|
title: '操作', |
|
|
|
|
|
actions: [ |
|
|
|
|
|
{ |
|
|
|
|
|
label: '编辑', |
|
|
|
|
|
name: 'userEdit', |
|
|
|
|
|
handle: (record: any) => { |
|
|
|
|
|
getDictList(); |
|
|
|
|
|
text.value = '编辑'; |
|
|
|
|
|
visible.value = true; |
|
|
|
|
|
formState.value.id = record.id; |
|
|
|
|
|
fetch(uploadPic.select, { bizId: record.id, bizType: 1 }).then((res) => { |
|
|
|
|
|
fileList.value = res.data.map((item) => ({ |
|
|
|
|
|
uid: item.id.toString(), // 使用文件的id作为唯一标识 |
|
|
|
|
|
name: item.fileName, // 文件名 |
|
|
|
|
|
status: 'done', // 设置默认状态为已完成 |
|
|
|
|
|
type: 'done', |
|
|
|
|
|
url: item.filePath, // 文件的URL,这里假设用示例的URL格式 |
|
|
|
|
|
})); |
|
|
|
|
|
}); |
|
|
|
|
|
formState.value = JSON.parse(JSON.stringify(record)); |
|
|
|
|
|
if (formState.value.expenditure === 0) { |
|
|
|
|
|
formState.value.transactionQuantity = formState.value.income; |
|
|
|
|
|
} else { |
|
|
|
|
|
formState.value.transactionQuantity = formState.value.expenditure; |
|
|
|
|
|
} |
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
let selectDevice = ref([Number(formState.value.transactionType)]); |
|
|
|
|
|
findParentIds(options.value, formState.value.transactionType, selectDevice.value); |
|
|
|
|
|
formState.value.transactionType = selectDevice; |
|
|
|
|
|
formState.value.transactionType = formState.value.transactionType; |
|
|
|
|
|
}, 500); |
|
|
|
|
|
}, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
label: '删除', |
|
|
|
|
|
name: 'userDelete', |
|
|
|
|
|
dynamicParams: { ids: 'id[]' }, |
|
|
|
|
|
confirm: true, |
|
|
|
|
|
isReload: true, |
|
|
|
|
|
api: carbonAssets.delete, |
|
|
|
|
|
}, |
|
|
|
|
|
], |
|
|
|
|
|
}, |
|
|
|
|
|
formConfig: { |
|
|
|
|
|
schemas: [], |
|
|
|
|
|
params: {}, |
|
|
|
|
|
}, |
|
|
|
|
|
rowKey: 'id', |
|
|
|
|
|
}); |
|
|
// 分页器 |
|
|
// 分页器 |
|
|
const onChange = (pageNumber: number, size: number) => { |
|
|
const onChange = (pageNumber: number, size: number) => { |
|
|
queryParams.value.pageNum = pageNumber; |
|
|
queryParams.value.pageNum = pageNumber; |
|
@ -492,6 +663,12 @@ |
|
|
}); |
|
|
}); |
|
|
fileList.value = newFileList; |
|
|
fileList.value = newFileList; |
|
|
}; |
|
|
}; |
|
|
|
|
|
const handleKeyDown = (event: KeyboardEvent) => { |
|
|
|
|
|
// Check if the pressed key is a space |
|
|
|
|
|
if (event.code === 'Space') { |
|
|
|
|
|
event.preventDefault(); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
const onSubmit = () => { |
|
|
const onSubmit = () => { |
|
|
formRef.value |
|
|
formRef.value |
|
|
.validate() |
|
|
.validate() |
|
@ -625,7 +802,7 @@ |
|
|
height: 16%; |
|
|
height: 16%; |
|
|
} |
|
|
} |
|
|
.detailTable { |
|
|
.detailTable { |
|
|
width: 65%; |
|
|
width: 70%; |
|
|
margin-right: 20px; |
|
|
margin-right: 20px; |
|
|
height: 100%; |
|
|
height: 100%; |
|
|
background: white; |
|
|
background: white; |
|
@ -633,10 +810,27 @@ |
|
|
padding: 16px; |
|
|
padding: 16px; |
|
|
} |
|
|
} |
|
|
.total { |
|
|
.total { |
|
|
width: calc(35% - 20px); |
|
|
width: calc(30% - 20px); |
|
|
height: 100%; |
|
|
height: 100%; |
|
|
background: white; |
|
|
background: white; |
|
|
border-radius: 12px; |
|
|
border-radius: 12px; |
|
|
padding: 16px; |
|
|
padding: 16px; |
|
|
} |
|
|
} |
|
|
|
|
|
:deep(.ns-table-search) { |
|
|
|
|
|
display: none; |
|
|
|
|
|
} |
|
|
|
|
|
:deep(.ns-table-header) { |
|
|
|
|
|
padding-top: unset !important; |
|
|
|
|
|
align-items: unset !important; |
|
|
|
|
|
padding-bottom: 10px; |
|
|
|
|
|
height: unset !important; |
|
|
|
|
|
} |
|
|
|
|
|
:deep(.ns-basic-table) { |
|
|
|
|
|
padding-top: unset !important; |
|
|
|
|
|
} |
|
|
|
|
|
:deep(.ns-table-main) { |
|
|
|
|
|
padding: unset !important; |
|
|
|
|
|
margin: unset !important; |
|
|
|
|
|
border-radius: unset !important; |
|
|
|
|
|
} |
|
|
</style> |
|
|
</style> |
|
|