xuziqiang
5 months ago
12 changed files with 1127 additions and 599 deletions
@ -1,111 +1,74 @@ |
|||
import { dateUtil } from '/nerv-lib/util/date-util'; |
|||
import data from './mock.json'; |
|||
export const tableConfig = { |
|||
title: '设备台账', |
|||
// api: '/carbon_emission/device/getDeviceList',
|
|||
value: data.dataSource, |
|||
params: { |
|||
page: 0, |
|||
pageSize: 10, |
|||
}, |
|||
rowSelection: null, |
|||
columns: [ |
|||
{ |
|||
title: '序号', |
|||
customRender: (text: any) => { |
|||
return text.index + 1; |
|||
}, |
|||
export const tableColumns = [ |
|||
{ |
|||
title: '序号', |
|||
customRender: (text: any) => { |
|||
return text.index + 1; |
|||
}, |
|||
{ |
|||
title: '能源种类', |
|||
dataIndex: 'id', |
|||
}, |
|||
{ |
|||
title: '计量单位', |
|||
dataIndex: 'deviceCode', |
|||
}, |
|||
{ |
|||
title: '全年', |
|||
dataIndex: 'deviceName', |
|||
textNumber: 8, |
|||
textEllipsis: true, |
|||
}, |
|||
{ |
|||
title: '设备一级区域', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '设备二级区域', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '设备详细位置', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '设备规格', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '设备厂商纳税人识别号', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '厂商联系人', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '设备描述', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: 'IP地址', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '生产日期', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '采购日期', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '启用日期', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '设备成本(元)', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '使用期限', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '额定功率', |
|||
dataIndex: 'position', |
|||
}, |
|||
{ |
|||
title: '特殊参数', |
|||
dataIndex: 'position', |
|||
}, |
|||
], |
|||
|
|||
formConfig: { |
|||
schemas: [ |
|||
{ |
|||
field: 'createTime', |
|||
label: '生产日期', |
|||
component: 'NsRangePicker', |
|||
fieldMap: ['queryStartDate', 'queryEndDate'], |
|||
componentProps: { |
|||
valueFormat: 'YYYY-MM-DD', |
|||
}, |
|||
}, |
|||
], |
|||
params: {}, |
|||
}, |
|||
// pagination: { pageSizeOptions: false },
|
|||
rowKey: 'uuid', |
|||
}; |
|||
}, |
|||
{ |
|||
title: '能源种类', |
|||
dataIndex: 'money', |
|||
}, |
|||
{ |
|||
title: '计量单位', |
|||
className: 'column-money', |
|||
dataIndex: 'money', |
|||
}, |
|||
{ |
|||
title: '全年', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '1月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '2月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '3月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '4月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '5月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '6月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '7月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '8月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '9月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '10月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '11月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '12月', |
|||
dataIndex: 'address', |
|||
}, |
|||
{ |
|||
title: '操作', |
|||
key: 'action', |
|||
width: 130 |
|||
}, |
|||
]; |
@ -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