xuziqiang
5 months ago
12 changed files with 1127 additions and 599 deletions
@ -0,0 +1,251 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<a-table |
||||
|
:columns="tableColumns" |
||||
|
:data-source="data" |
||||
|
bordered |
||||
|
:pagination="false" |
||||
|
:scroll="{ x: 2000 }"> |
||||
|
<template #bodyCell="{ column, text }"> |
||||
|
<template v-if="column.key === 'action'"> |
||||
|
<span> |
||||
|
<a>编辑</a> |
||||
|
<a-divider type="vertical" /> |
||||
|
<a>删除</a> |
||||
|
</span> |
||||
|
</template> |
||||
|
</template> |
||||
|
<template #title> |
||||
|
<a-date-picker v-model:value="selectYear" picker="year" /> |
||||
|
<div class="buttonGroup"> |
||||
|
<a-button type="primary" @click="addNewData">新增</a-button> |
||||
|
<a-button type="primary">导入</a-button> |
||||
|
<a-button type="primary">导出</a-button> |
||||
|
<a-button type="primary">模板下载</a-button> |
||||
|
<a-button type="primary">上传凭证</a-button> |
||||
|
<a-button type="primary">凭证下载</a-button> |
||||
|
</div> |
||||
|
</template> |
||||
|
</a-table> |
||||
|
<a-pagination |
||||
|
:current="current" |
||||
|
:page-size="pageSize" |
||||
|
:total="0" |
||||
|
:show-total="(total, range) => `${range[0]}-${range[1]} of ${total} items`" /> |
||||
|
<!-- 新增数据库数据 --> |
||||
|
<a-drawer |
||||
|
:width="500" |
||||
|
:visible="visible" |
||||
|
:body-style="{ paddingBottom: '80px' }" |
||||
|
:footer-style="{ textAlign: 'right' }" |
||||
|
destroyOnClose |
||||
|
@close="onClose"> |
||||
|
<a-form |
||||
|
ref="formRef" |
||||
|
:model="formState" |
||||
|
:rules="rules" |
||||
|
:label-col="labelCol" |
||||
|
:wrapper-col="wrapperCol" |
||||
|
> |
||||
|
<a-form-item ref="name" label="能源种类" name="name"> |
||||
|
<a-input v-model:value="formState.name" /> |
||||
|
</a-form-item> |
||||
|
<a-form-item label="计量单位"> |
||||
|
<a-cascader v-model:value="value" :options="options" placeholder="Please select" /> |
||||
|
</a-form-item> |
||||
|
<a-form-item label="自动采集节点"> |
||||
|
<a-tree-select |
||||
|
v-model:value="treeValue" |
||||
|
style="width: 300px" |
||||
|
placeholder="Please select" |
||||
|
:tree-line="true" |
||||
|
:tree-data="treeData" |
||||
|
tree-node-filter-prop="title" |
||||
|
> |
||||
|
<template #title="{ value: val, title }"> |
||||
|
<b v-if="val === 'parent 1-1'" style="color: #08c">sss</b> |
||||
|
<template v-else>{{ title }}</template> |
||||
|
</template> |
||||
|
</a-tree-select> |
||||
|
</a-form-item> |
||||
|
<a-form-item label="计算碳排" name="resource"> |
||||
|
<a-radio-group v-model:value="formState.resource"> |
||||
|
<a-radio value="1">是</a-radio> |
||||
|
<a-radio value="2">否</a-radio> |
||||
|
</a-radio-group> |
||||
|
</a-form-item> |
||||
|
<a-form-item label="排放类型" name="region"> |
||||
|
<a-select v-model:value="formState.region" placeholder="请选择排放类型"> |
||||
|
<a-select-option value="shanghai">Zone one</a-select-option> |
||||
|
<a-select-option value="beijing">Zone two</a-select-option> |
||||
|
</a-select> |
||||
|
</a-form-item> |
||||
|
<a-form-item label="1月" name="delivery"> |
||||
|
<a-switch v-model:checked="formState.delivery" /> |
||||
|
</a-form-item> |
||||
|
</a-form> |
||||
|
<template #footer> |
||||
|
<a-button style="margin-right: 8px" @click="onClose">取消</a-button> |
||||
|
<a-button type="primary" @click="onSubmit">确定</a-button> |
||||
|
</template> |
||||
|
</a-drawer> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { ref,reactive, toRaw } from 'vue'; |
||||
|
import type { UnwrapRef } from 'vue'; |
||||
|
import type { Rule } from 'ant-design-vue/es/form'; |
||||
|
import type { CascaderProps,TreeSelectProps } from 'ant-design-vue'; |
||||
|
import type { Dayjs } from 'dayjs'; |
||||
|
import { http } from '/nerv-lib/util/http'; |
||||
|
import { tableColumns } from '../config'; |
||||
|
import { energyConsumption } from '/@/api/carbonEmissionFactorLibrary'; |
||||
|
defineOptions({ |
||||
|
name: 'EnergyConsumption', // 与页面路由name一致缓存才可生效 |
||||
|
}); |
||||
|
|
||||
|
const orgId = JSON.parse(sessionStorage.getItem('userInfo')).orgId; |
||||
|
const fetch = (api, params = { orgId }) => { |
||||
|
return http.post(api, params); |
||||
|
}; |
||||
|
const selectYear = ref<Dayjs>(); |
||||
|
const current = ref<number>(1); |
||||
|
const pageSize = ref<number>(10); |
||||
|
const visible = ref(false); |
||||
|
const value = ref<string[]>([]); |
||||
|
const data = ref([]); |
||||
|
interface FormState { |
||||
|
name: string; |
||||
|
region: string | undefined; |
||||
|
delivery: boolean; |
||||
|
resource: string; |
||||
|
} |
||||
|
const formRef = ref(); |
||||
|
const labelCol = { span: 5 }; |
||||
|
const wrapperCol = { span: 13 }; |
||||
|
const formState: UnwrapRef<FormState> = reactive({ |
||||
|
name: '', |
||||
|
region: undefined, |
||||
|
delivery: false, |
||||
|
resource: '', |
||||
|
}); |
||||
|
// 定义form表单的必填 |
||||
|
const rules: Record<string, Rule[]> = { |
||||
|
name: [ |
||||
|
{ required: true, message: '请输入能源种类', trigger: 'change' }, |
||||
|
], |
||||
|
resource: [{ required: true, message: 'Please select activity resource', trigger: 'change' }], |
||||
|
}; |
||||
|
// 定义计量单位级联选择的变量 |
||||
|
const options: CascaderProps['options'] = [ |
||||
|
{ |
||||
|
value: 'zhejiang', |
||||
|
label: 'Zhejiang', |
||||
|
children: [ |
||||
|
{ |
||||
|
value: 'hangzhou', |
||||
|
label: 'Hangzhou', |
||||
|
children: [ |
||||
|
{ |
||||
|
value: 'xihu', |
||||
|
label: 'West Lake', |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
{ |
||||
|
value: 'jiangsu', |
||||
|
label: 'Jiangsu', |
||||
|
children: [ |
||||
|
{ |
||||
|
value: 'nanjing', |
||||
|
label: 'Nanjing', |
||||
|
children: [ |
||||
|
{ |
||||
|
value: 'zhonghuamen', |
||||
|
label: 'Zhong Hua Men', |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
]; |
||||
|
// 定义自动采集节点数的变量 |
||||
|
const treeValue = ref<string>(); |
||||
|
const treeData = ref<TreeSelectProps['treeData']>([ |
||||
|
{ |
||||
|
title: 'parent 1', |
||||
|
value: 'parent 1', |
||||
|
children: [ |
||||
|
{ |
||||
|
title: 'parent 1-0', |
||||
|
value: 'parent 1-0', |
||||
|
children: [ |
||||
|
{ |
||||
|
title: 'my leaf', |
||||
|
value: 'leaf1', |
||||
|
}, |
||||
|
{ |
||||
|
title: 'your leaf', |
||||
|
value: 'leaf2', |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
{ |
||||
|
title: 'parent 1-1', |
||||
|
value: 'parent 1-1', |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
]); |
||||
|
// 获取表格数据 |
||||
|
const getTableList = () => { |
||||
|
fetch(energyConsumption.pageList).then((res) => { |
||||
|
console.log(res,'aaaaaa'); |
||||
|
}); |
||||
|
}; |
||||
|
getTableList() |
||||
|
// 点击确定提交 |
||||
|
const onSubmit = () => { |
||||
|
formRef.value |
||||
|
.validate() |
||||
|
.then(() => { |
||||
|
console.log('values', formState, toRaw(formState)); |
||||
|
}) |
||||
|
.catch(error => { |
||||
|
console.log('error', error); |
||||
|
}); |
||||
|
}; |
||||
|
const resetForm = () => { |
||||
|
formRef.value.resetFields(); |
||||
|
}; |
||||
|
// 点击新增按钮 |
||||
|
const addNewData = () => { |
||||
|
visible.value = true |
||||
|
} |
||||
|
// 关闭新增抽屉 |
||||
|
const onClose = () => { |
||||
|
visible.value = false; |
||||
|
}; |
||||
|
</script> |
||||
|
<style scoped lang="less"> |
||||
|
::v-deep .ant-table-title{ |
||||
|
display: flex; |
||||
|
} |
||||
|
::v-deep .ant-table-container{ |
||||
|
padding: 0px 16px; |
||||
|
} |
||||
|
.buttonGroup{ |
||||
|
margin-left: 1vw; |
||||
|
width: 30vw; |
||||
|
display: flex; |
||||
|
justify-content: space-around; |
||||
|
} |
||||
|
</style> |
||||
|
<style scoped> |
||||
|
th.column-money, |
||||
|
td.column-money { |
||||
|
text-align: right !important; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,122 @@ |
|||||
|
<template> |
||||
|
<a-table :columns="columns" :data-source="data" bordered /> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { defineComponent, watch, inject, ref, onMounted } from 'vue'; |
||||
|
import type { TableColumnType } from 'ant-design-vue'; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
name: 'EnvironmentTable', |
||||
|
setup() { |
||||
|
let data = ref<any[]>([]); |
||||
|
let columns = ref<TableColumnType[]>([]); |
||||
|
|
||||
|
interface PageData { |
||||
|
graphTableList: any[]; |
||||
|
graphTableColumns: any[]; |
||||
|
graphGraphList: any[]; |
||||
|
} |
||||
|
const pageData = inject<PageData>('pageData'); |
||||
|
|
||||
|
if (!pageData) { |
||||
|
throw new Error('pageData is not provided'); |
||||
|
} |
||||
|
// 监听 pageData 的变化 |
||||
|
watch( |
||||
|
() => pageData as PageData, |
||||
|
(_newValue, _oldValue) => { |
||||
|
data.value = pageData.graphTableList; |
||||
|
|
||||
|
let columnA: any[] = [...column]; |
||||
|
columnA.push(...pageData.graphTableColumns); |
||||
|
columns.value = columnA; |
||||
|
// pageData.graphList; |
||||
|
// 执行你的逻辑代码 |
||||
|
}, |
||||
|
{ deep: true }, |
||||
|
); |
||||
|
|
||||
|
const getRowSpan = (dataIndex: string, record: any, data: any, dependents: string[] = []) => { |
||||
|
let rowSpan = 1; |
||||
|
for (let i = data.indexOf(record) + 1; i < data.length; i++) { |
||||
|
let shouldMerge = true; |
||||
|
for (const dependent of dependents) { |
||||
|
if (data[i][dependent] !== record[dependent]) { |
||||
|
shouldMerge = false; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
if (shouldMerge && data[i][dataIndex] === record[dataIndex]) { |
||||
|
rowSpan++; |
||||
|
} else { |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
return rowSpan; |
||||
|
}; |
||||
|
|
||||
|
const column: TableColumnType[] = [ |
||||
|
{ |
||||
|
title: '设备/组名', |
||||
|
dataIndex: 'name', |
||||
|
customCell: (record, rowIndex) => { |
||||
|
if (rowIndex == undefined) { |
||||
|
return { |
||||
|
rowSpan: 0, |
||||
|
colSpan: 0, |
||||
|
}; |
||||
|
} |
||||
|
const rowSpan = getRowSpan('name', record, data.value); |
||||
|
if (rowIndex != 0 && data.value[rowIndex - 1].name == record.name) { |
||||
|
return { |
||||
|
rowSpan: 0, |
||||
|
colSpan: 0, |
||||
|
}; |
||||
|
} |
||||
|
return { |
||||
|
rowSpan: rowSpan, |
||||
|
}; |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
title: '参数名称', |
||||
|
dataIndex: 'paramName', |
||||
|
customCell: (record, rowIndex) => { |
||||
|
if (rowIndex == undefined) { |
||||
|
return { |
||||
|
rowSpan: 0, |
||||
|
colSpan: 0, |
||||
|
}; |
||||
|
} |
||||
|
const rowSpan = getRowSpan('paramName', record, data.value, ['name']); |
||||
|
if (rowIndex != 0 && data.value[rowIndex - 1].name == record.name) { |
||||
|
return { |
||||
|
rowSpan: 0, |
||||
|
colSpan: 0, |
||||
|
}; |
||||
|
} |
||||
|
return { |
||||
|
rowSpan: rowSpan, |
||||
|
}; |
||||
|
}, |
||||
|
}, |
||||
|
]; |
||||
|
|
||||
|
onMounted(() => { |
||||
|
data.value = pageData.graphTableList; |
||||
|
|
||||
|
let columnA: any[] = [...column]; |
||||
|
columnA.push(...pageData.graphTableColumns); |
||||
|
columns.value = columnA; |
||||
|
}); |
||||
|
return { |
||||
|
data, |
||||
|
column, |
||||
|
columns, |
||||
|
}; |
||||
|
}, |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped></style> |
@ -0,0 +1,88 @@ |
|||||
|
<!-- eslint-disable vue/multi-word-component-names --> |
||||
|
<template> |
||||
|
<a-tabs v-model:activeKey="activeKey" style="height: 8%"> |
||||
|
<a-tab-pane key="1" tab="图表" /> |
||||
|
<a-tab-pane key="2" tab="分析" /> |
||||
|
</a-tabs> |
||||
|
<a-row type="flex" style="height: 92%"> |
||||
|
<a-col :span="4"> |
||||
|
<div style="padding: 0 20px; width: 100%; height: 100%"> |
||||
|
<tree ref="treeRef" /> |
||||
|
</div> |
||||
|
</a-col> |
||||
|
<a-col :span="20"> |
||||
|
<div style="width: 100%; height: 100%"> |
||||
|
<div class="ns-right-title"> |
||||
|
<span>统计数据</span> |
||||
|
<div class="button"> |
||||
|
<ns-icon name="xiazai" size="18" style="margin-right: 10px" @click="downloadChart" /> |
||||
|
<ns-icon :name="iconName" size="18" style="margin-right: 10px" @click="change" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div v-if="activeKey == '1'" style="height: 90%"> |
||||
|
<graph-graph ref="graphRef" v-if="isGraph" /> |
||||
|
<environment-table ref="tableRef" v-else /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import { ref } from 'vue'; |
||||
|
import tree from './tree/index.vue'; |
||||
|
import graphGraph from './graphGraph/index.vue'; |
||||
|
import environmentTable from './graphTable/index.vue'; |
||||
|
|
||||
|
const iconName = ref('biaoge'); |
||||
|
|
||||
|
const treeRef = ref(); |
||||
|
const graphRef = ref(); |
||||
|
const tableRef = ref(); |
||||
|
|
||||
|
let isGraph = ref(true); |
||||
|
const activeKey = ref('1'); |
||||
|
|
||||
|
defineOptions({ |
||||
|
name: 'EnvironmentMonitorIndex', // 与页面路由name一致缓存才可生效 |
||||
|
}); |
||||
|
|
||||
|
const downloadChart = () => { |
||||
|
if (activeKey.value == '1' && isGraph) { |
||||
|
if (graphRef.value) { |
||||
|
graphRef.value.downloadChart(); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
function change() { |
||||
|
isGraph.value = !isGraph.value; |
||||
|
if (iconName.value == 'biaoge') { |
||||
|
iconName.value = 'bingtu'; |
||||
|
} else { |
||||
|
iconName.value = 'biaoge'; |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="less" scoped> |
||||
|
.ns-right-title { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
user-select: text; |
||||
|
margin-bottom: 5px; |
||||
|
padding-bottom: 10px; |
||||
|
padding-top: 10px; |
||||
|
border-bottom: 1px solid #e9e9e9; |
||||
|
|
||||
|
> span { |
||||
|
padding-left: 10px; |
||||
|
line-height: 20px; |
||||
|
} |
||||
|
} |
||||
|
.button { |
||||
|
display: inline-block; |
||||
|
padding-right: 10px; |
||||
|
} |
||||
|
</style> |
Loading…
Reference in new issue