736 lines
21 KiB
TypeScript
736 lines
21 KiB
TypeScript
import { LocaleType, BooleanNumber, SheetTypes } from '@univerjs/core'
|
||
|
||
export const protocolList = [
|
||
// * 代表需要配置的协议
|
||
{ label: 'IEC104从 *', value: 9 },
|
||
{ label: 'MODBUSTCP从 *', value: 17 },
|
||
{ label: 'MODBUS', value: 80 },
|
||
{ label: 'ADS', value: 81 },
|
||
{ label: '故障日志', value: 79 },
|
||
]
|
||
|
||
export const excelDefaultConfig: any = {
|
||
// IEC104从
|
||
9: {
|
||
//遥测138 ANALOG
|
||
138: {
|
||
name: '模拟量',
|
||
head: [
|
||
{
|
||
label: '序号',
|
||
code: 'order',
|
||
},
|
||
],
|
||
},
|
||
//遥控147 CONTROL
|
||
147: {
|
||
name: '遥控量',
|
||
head: [
|
||
{
|
||
label: '序号',
|
||
code: 'order',
|
||
},
|
||
],
|
||
},
|
||
//遥调146 SETPOINT
|
||
146: {
|
||
name: '遥调量',
|
||
head: [
|
||
{
|
||
label: '序号',
|
||
code: 'order',
|
||
},
|
||
],
|
||
},
|
||
//遥脉139 ACCUMULATOR
|
||
139: {
|
||
name: '累计量',
|
||
head: [
|
||
{
|
||
label: '序号',
|
||
code: 'order',
|
||
},
|
||
],
|
||
},
|
||
//遥信140 DISCRETE
|
||
140: {
|
||
name: '离散量',
|
||
head: [
|
||
{
|
||
label: '序号',
|
||
code: 'order',
|
||
},
|
||
],
|
||
},
|
||
},
|
||
// MODEBUS
|
||
80: {
|
||
//遥测138 ANALOG
|
||
138: {
|
||
name: '模拟量',
|
||
head: [
|
||
{
|
||
label: '功能码',
|
||
code: 'col1',
|
||
},
|
||
{
|
||
label: '数据类型',
|
||
code: 'col2',
|
||
},
|
||
{
|
||
label: '数据符号',
|
||
code: 'col3',
|
||
},
|
||
{
|
||
label: '寄存器地址',
|
||
code: 'col4',
|
||
},
|
||
{
|
||
label: '上界',
|
||
code: 'upBound',
|
||
},
|
||
{
|
||
label: '下界',
|
||
code: 'lowBound'
|
||
},
|
||
{
|
||
label: '基值',
|
||
code: 'base',
|
||
default: 0
|
||
},
|
||
{
|
||
label: '系数',
|
||
code: 'coef',
|
||
default: 1
|
||
},
|
||
{
|
||
label: '限值1',
|
||
code: 'limit1Enable',
|
||
default: 0
|
||
},
|
||
{
|
||
label: '限值1上限',
|
||
code: 'limit1High'
|
||
},
|
||
{
|
||
label: '限值1下限',
|
||
code: 'limit1Low'
|
||
},
|
||
{
|
||
label: '限值2',
|
||
code: 'limit2Enable',
|
||
default: 0
|
||
},
|
||
{
|
||
label: '限值2上限',
|
||
code: 'limit2High'
|
||
},
|
||
{
|
||
label: '限值2下限',
|
||
code: 'limit2Low'
|
||
},
|
||
{
|
||
label: '强制归档',
|
||
code: 'forceArchive',
|
||
}
|
||
],
|
||
R0C4: ['03', '04'],
|
||
R0C5: [
|
||
'0 - 32位浮点数(高位在第一个寄存器)',
|
||
'1 - 32位浮点数(高位在第二个寄存器)',
|
||
'2 - 16位归一化值',
|
||
'3 - 32位归一化值(高位在第一个寄存器)',
|
||
'4 - 32位归一化值(高位在第二个寄存器)',
|
||
'5 - 32位浮点数(小端系统模式)',
|
||
'6 - 32位BCD数据(*高位在第一个寄存器*)',
|
||
'7 - 32位BCD数据(*高位在第二个寄存器*)',
|
||
'8 - 16位BCD数据',
|
||
], // 数据类型的提示
|
||
R0C6: ['0 - 无符号', '1 - 有符号'], // 数据符号的提示
|
||
},
|
||
//遥控147 CONTROL
|
||
147: {
|
||
name: '遥控量',
|
||
head: [
|
||
{
|
||
label: '功能码',
|
||
code: 'col1',
|
||
},
|
||
{
|
||
label: '执行前需要预置',
|
||
code: 'col2',
|
||
},
|
||
{
|
||
label: '选择合寄存器',
|
||
code: 'col3',
|
||
},
|
||
{
|
||
label: '执行合寄存器',
|
||
code: 'col4',
|
||
},
|
||
{
|
||
label: '撤销合寄存器',
|
||
code: 'col5',
|
||
},
|
||
|
||
{
|
||
label: '合闸数值',
|
||
code: 'col6',
|
||
},
|
||
{
|
||
label: '选择分寄存器',
|
||
code: 'col7',
|
||
},
|
||
{
|
||
label: '执行分寄存器',
|
||
code: 'col8',
|
||
},
|
||
{
|
||
label: '撤销分寄存器',
|
||
code: 'col9',
|
||
},
|
||
{
|
||
label: '分闸数值',
|
||
code: 'col10',
|
||
},
|
||
],
|
||
R0C4: ['05', '15', '06', '16'],
|
||
R0C5: ['0 - 直接执行', '1 - 预置执行'],
|
||
},
|
||
//遥调146 SETPOINT
|
||
146: {
|
||
name: '遥调量',
|
||
head: [
|
||
{
|
||
label: '遥调类型',
|
||
code: 'col1',
|
||
},
|
||
{
|
||
label: '功能码',
|
||
code: 'col2',
|
||
},
|
||
{
|
||
label: '执行前需要预置',
|
||
code: 'col3',
|
||
},
|
||
{
|
||
label: '选择寄存器',
|
||
code: 'col4',
|
||
},
|
||
{
|
||
label: '执行寄存器',
|
||
code: 'col5',
|
||
},
|
||
{
|
||
label: '撤销寄存器',
|
||
code: 'col6',
|
||
},
|
||
],
|
||
R0C4: ['0 - 16位整型值', '1 - 32位值高位在第一个寄存器', '2 - 32位值高位在第二个寄存器'],
|
||
R0C5: ['06', '16'],
|
||
R0C6: ['0 - 直接执行', '1 - 预置执行'],
|
||
},
|
||
//遥脉139 ACCUMULATOR
|
||
139: {
|
||
name: '累计量',
|
||
head: [
|
||
{
|
||
label: '功能码',
|
||
code: 'col1',
|
||
},
|
||
{
|
||
label: '数据类型',
|
||
code: 'col2',
|
||
},
|
||
{
|
||
label: '寄存器地址',
|
||
code: 'col3',
|
||
},
|
||
{
|
||
label: '强制归档',
|
||
code: 'forceArchive',
|
||
}
|
||
],
|
||
R0C4: ['03', '04'],
|
||
R0C5: [
|
||
'0 - 16位无符号整型值',
|
||
'1 - 32位无符号整型值(高位在第一个寄存器)',
|
||
'2 - 32位有符号整型值(高位在第一个寄存器)',
|
||
'3 - 32位无符号整型值(高位在第二个寄存器)',
|
||
'4 - 32位有符号整型值(高位在第二个寄存器)',
|
||
'5 - 32位浮点数值(高位在第一个寄存器)',
|
||
'6 - 32位浮点数值(高位在第二个寄存器)',
|
||
'7 - 64位双精度值(AB CD EF GH)',
|
||
'8 - 64位双精度值(GH EF CD AB)',
|
||
'9 - 32位短浮点数值(小端模式)',
|
||
'10 - 32位BCD数据(*高位在第一个寄存器*)',
|
||
],
|
||
},
|
||
//遥信140 DISCRETE
|
||
140: {
|
||
name: '离散量',
|
||
head: [
|
||
{
|
||
label: '功能码',
|
||
code: 'col1',
|
||
},
|
||
{ label: '偏移量', code: 'col2' },
|
||
{
|
||
label: '寄存器',
|
||
code: 'col3',
|
||
},
|
||
{
|
||
label: '强制归档',
|
||
code: 'forceArchive',
|
||
}
|
||
],
|
||
R0C4: ['01', '02', '03', '04'],
|
||
},
|
||
},
|
||
// ADS
|
||
81: {
|
||
//遥测138 ANALOG
|
||
138: {
|
||
name: '模拟量',
|
||
head: [
|
||
{
|
||
label: '数据格式',
|
||
code: 'dataType',
|
||
},
|
||
{
|
||
label: '数据类型',
|
||
code: 'signMark',
|
||
},
|
||
{
|
||
label: '寄存器地址',
|
||
code: 'registerAddr',
|
||
},
|
||
{
|
||
label: '启用变量',
|
||
code: 'variableEnable',
|
||
},
|
||
{
|
||
label: '变量名称',
|
||
code: 'variableName',
|
||
},
|
||
{
|
||
label: '上界',
|
||
code: 'upBound',
|
||
},
|
||
{
|
||
label: '下界',
|
||
code: 'lowBound'
|
||
},
|
||
{
|
||
label: '基值',
|
||
code: 'base',
|
||
default: 0
|
||
},
|
||
{
|
||
label: '系数',
|
||
code: 'coef',
|
||
default: 1
|
||
},
|
||
{
|
||
label: '限值1',
|
||
code: 'limit1Enable',
|
||
default: 0
|
||
},
|
||
{
|
||
label: '限值1上限',
|
||
code: 'limit1High'
|
||
},
|
||
{
|
||
label: '限值1下限',
|
||
code: 'limit1Low'
|
||
},
|
||
{
|
||
label: '限值2',
|
||
code: 'limit2Enable',
|
||
default: 0
|
||
},
|
||
{
|
||
label: '限值2上限',
|
||
code: 'limit2High'
|
||
},
|
||
{
|
||
label: '限值2下限',
|
||
code: 'limit2Low'
|
||
},
|
||
{
|
||
label: '强制归档',
|
||
code: 'forceArchive',
|
||
}
|
||
],
|
||
R0C4: [
|
||
"0. 32位浮点数(高位在第一个寄存器)",
|
||
"1. 32位浮点数(高位在第二个寄存器)",
|
||
"2. 16位归一化值",
|
||
"3. 32位归一化值(高位在第一个寄存器)",
|
||
"4. 32位归一化值(高位在第二个寄存器)",
|
||
"5. 32位浮点数(小端系统模式)",
|
||
"6. 32位BCD数据(*高位在第一个寄存器*)",
|
||
"7. 32位BCD数据(*高位在第二个寄存器*)",
|
||
"8. 16位BCD数据",
|
||
"9. 8位归一化值"
|
||
], // 数据类型的提示
|
||
R0C7: [
|
||
"0. 不启用",
|
||
"1. 启用"
|
||
]
|
||
},
|
||
//遥控147 CONTROL
|
||
147: {
|
||
name: '遥控量',
|
||
head: [
|
||
{
|
||
label: '合闸寄存器地址',
|
||
code: 'closeRegisterAddr',
|
||
},
|
||
{
|
||
label: '合闸值',
|
||
code: 'closeValue',
|
||
},
|
||
{
|
||
label: '分闸寄存器地址',
|
||
code: 'openRegisterAddr',
|
||
},
|
||
{
|
||
label: '分闸值',
|
||
code: 'openValue',
|
||
},
|
||
]
|
||
},
|
||
//遥调146 SETPOINT
|
||
146: {
|
||
name: '遥调量',
|
||
head: [
|
||
{
|
||
label: '设值方式',
|
||
code: 'setType',
|
||
},
|
||
{
|
||
label: '寄存器地址',
|
||
code: 'registerAddr',
|
||
},
|
||
],
|
||
},
|
||
//遥脉139 ACCUMULATOR
|
||
139: {
|
||
name: '累计量',
|
||
head: [
|
||
{
|
||
label: '强制归档',
|
||
code: 'forceArchive',
|
||
}
|
||
],
|
||
},
|
||
//遥信140 DISCRETE
|
||
140: {
|
||
name: '离散量',
|
||
head: [
|
||
{
|
||
label: '数据格式',
|
||
code: 'dataType',
|
||
},
|
||
{
|
||
label: '数据偏移量',
|
||
code: 'offSet',
|
||
},
|
||
{
|
||
label: '寄存器地址',
|
||
code: 'registerAddr',
|
||
},
|
||
{
|
||
label: '强制归档',
|
||
code: 'forceArchive',
|
||
}
|
||
],
|
||
R0C4: [
|
||
"8位归一化值",
|
||
"16位归一化值",
|
||
"32位归一化值",
|
||
]
|
||
},
|
||
},
|
||
// MODBASETCP从
|
||
17: {
|
||
//遥测138 ANALOG
|
||
138: {
|
||
name: '模拟量',
|
||
head: [
|
||
{
|
||
label: '序号',
|
||
code: 'order',
|
||
},
|
||
],
|
||
},
|
||
//遥控147 CONTROL
|
||
147: {
|
||
name: '遥控量',
|
||
head: [
|
||
{
|
||
label: '序号',
|
||
code: 'order',
|
||
},
|
||
],
|
||
},
|
||
//遥调146 SETPOINT
|
||
146: {
|
||
name: '遥调量',
|
||
head: [
|
||
{
|
||
label: '序号',
|
||
code: 'order',
|
||
},
|
||
],
|
||
},
|
||
//遥脉139 ACCUMULATOR
|
||
139: {
|
||
name: '累计量',
|
||
head: [
|
||
{
|
||
label: '序号',
|
||
code: 'order',
|
||
},
|
||
],
|
||
},
|
||
//遥信140 DISCRETE
|
||
140: {
|
||
name: '离散量',
|
||
head: [
|
||
{
|
||
label: '序号',
|
||
code: 'order',
|
||
},
|
||
],
|
||
},
|
||
},
|
||
}
|
||
const DEFAULT_WORKBOOK_DATA = {
|
||
id: 'workbook-01',
|
||
locale: LocaleType.ZH_CN,
|
||
name: 'universheet',
|
||
sheetOrder: ['sheet-138', 'sheet-139', 'sheet-140', 'sheet-146', 'sheet-147'],
|
||
appVersion: '3.0.0-alpha',
|
||
styles: {
|
||
1: {
|
||
vt: 2,
|
||
ht: 2,
|
||
},
|
||
2: {
|
||
vt: 2,
|
||
ht: 2,
|
||
bg: {
|
||
rgb: '#eceff7',
|
||
},
|
||
},
|
||
|
||
},
|
||
sheets: {},
|
||
}
|
||
/**
|
||
* 创建excel标题行
|
||
* @param protocol
|
||
* @returns
|
||
*/
|
||
const createHeaderData = (protocol: string | number) => {
|
||
if (!protocol) return {}
|
||
const headerData: any = {}
|
||
|
||
Object.keys(excelDefaultConfig[protocol!]).forEach((item) => {
|
||
const dynamicData: any = {}
|
||
excelDefaultConfig[protocol!][item].head.forEach((head: any, index: number) => {
|
||
const key = index + 4
|
||
dynamicData[key] = {
|
||
v: head.label,
|
||
s: '1',
|
||
custom: head.code,
|
||
}
|
||
})
|
||
const headerItemData = {
|
||
0: {
|
||
0: {
|
||
v: '设备名称',
|
||
s: '1',
|
||
custom: 'equipmentName',
|
||
},
|
||
1: {
|
||
v: '设备编码',
|
||
s: '1',
|
||
custom: 'equipmentCode',
|
||
},
|
||
2: {
|
||
v: '属性名称',
|
||
s: '1',
|
||
custom: 'measPointName',
|
||
},
|
||
3: {
|
||
v: '属性编码',
|
||
s: '1',
|
||
custom: 'measPointCode',
|
||
},
|
||
...dynamicData,
|
||
},
|
||
}
|
||
headerData[item] = headerItemData
|
||
})
|
||
return headerData
|
||
}
|
||
|
||
/**
|
||
* 设置excel名称为linkId
|
||
* @param id linkId
|
||
*/
|
||
export const setExcelNameToLinkId = (id: string) => {
|
||
DEFAULT_WORKBOOK_DATA.name = id
|
||
}
|
||
|
||
/**
|
||
* 创建excel数据
|
||
* @param protocol 协议类型
|
||
* @param data excel数据
|
||
* @returns
|
||
*/
|
||
export const createWookbookData = (protocol: number, linkId: string, data: any = {}) => {
|
||
const headerData = createHeaderData(protocol)
|
||
|
||
const sheetData: any = {}
|
||
//#region
|
||
Object.keys(headerData).forEach((item) => {
|
||
const rowLen = Object.keys(data[item]).length + 1
|
||
|
||
sheetData['sheet-' + item] = {
|
||
type: SheetTypes.GRID,
|
||
id: 'sheet-' + item,
|
||
cellData: {
|
||
...headerData[item],
|
||
...data[item],
|
||
},
|
||
name: excelDefaultConfig[protocol][item].name,
|
||
tabColor: 'green',
|
||
hidden: BooleanNumber.FALSE,
|
||
rowCount: rowLen,
|
||
columnCount: Object.keys(headerData[item][0]).length,
|
||
zoomRatio: 1,
|
||
scrollTop: 200,
|
||
scrollLeft: 100,
|
||
defaultColumnWidth: 120,
|
||
defaultRowHeight: 30,
|
||
status: 1,
|
||
showGridlines: 1,
|
||
hideRow: [],
|
||
hideColumn: [],
|
||
columnData: {
|
||
0: {
|
||
w: 300,
|
||
h: 0,
|
||
},
|
||
1: {
|
||
w: 300,
|
||
h: 0,
|
||
},
|
||
2: {
|
||
w: 300,
|
||
h: 0,
|
||
},
|
||
3: {
|
||
w: 300,
|
||
h: 0,
|
||
},
|
||
|
||
},
|
||
rowHeader: {
|
||
width: 46,
|
||
hidden: BooleanNumber.FALSE,
|
||
},
|
||
columnHeader: {
|
||
height: 20,
|
||
hidden: BooleanNumber.FALSE,
|
||
},
|
||
rightToLeft: BooleanNumber.FALSE,
|
||
}
|
||
})
|
||
//#endregion
|
||
DEFAULT_WORKBOOK_DATA.sheets = sheetData
|
||
DEFAULT_WORKBOOK_DATA.name = linkId
|
||
|
||
return DEFAULT_WORKBOOK_DATA
|
||
}
|
||
|
||
export const createUpLoadExcelData = (workbookData: any) => {
|
||
const sheets = workbookData.sheets
|
||
const data: any = []
|
||
Object.keys(sheets).forEach((item) => {
|
||
const sheetkeyMap: any = {}
|
||
const sheetKeys = Object.keys(sheets[item].cellData)
|
||
sheetKeys.forEach((key) => {
|
||
let sheetData: any = {}
|
||
const fieldKeys = Object.keys(sheets[item].cellData[key])
|
||
if (key === '0') {
|
||
fieldKeys.forEach((fieldKey) => {
|
||
const sheetKey = sheets[item].cellData[key][fieldKey].custom
|
||
sheetkeyMap[fieldKey] = sheetKey
|
||
})
|
||
} else {
|
||
let params: any = {}
|
||
const sheetKeyMapKeys = Object.keys(sheetkeyMap)
|
||
for (let fieldKey of sheetKeyMapKeys) {
|
||
if (fieldKey === '0') {
|
||
sheetData = { ...sheets[item].cellData[key][fieldKey].custom.otherData }
|
||
sheetData.linkId = workbookData.name
|
||
sheetData[sheetkeyMap[fieldKey]] = sheets[item].cellData[key][fieldKey]?.v ?? ''
|
||
sheetData.type = sheets[item].cellData[key][fieldKey].custom.type
|
||
sheetData.protocol = sheets[item].cellData[key][fieldKey].custom.protocol
|
||
continue
|
||
}
|
||
if (['1','2','3'].includes(fieldKey)) {
|
||
sheetData[sheetkeyMap[fieldKey]] = sheets[item].cellData[key][fieldKey]?.v ?? ''
|
||
continue
|
||
}
|
||
params[sheetkeyMap[fieldKey]] = sheets[item].cellData[key][fieldKey]?.v ?? ''
|
||
}
|
||
sheetData.params = JSON.stringify(params)
|
||
data.push(sheetData)
|
||
}
|
||
})
|
||
})
|
||
return data
|
||
}
|
||
|
||
export const createSheetData = (data: any, protocol: string | number) => {
|
||
if (!protocol) return {}
|
||
const excelCellDataMap: any = {}
|
||
const headerData = createHeaderData(protocol)
|
||
const resultData: any = {}
|
||
Object.keys(headerData).forEach((item) => {
|
||
excelCellDataMap[item] = {}
|
||
Object.keys(headerData[item][0]).forEach((key) => {
|
||
excelCellDataMap[headerData[item][0][key].custom] = key
|
||
})
|
||
const result: any = {}
|
||
data[item].forEach((obj: any, index: number) => {
|
||
const params = obj.params && obj.params !== '' ? JSON.parse(obj.params) : {}
|
||
const newObj = { ...obj, ...params }
|
||
const row = index + 1
|
||
result[row] = {}
|
||
Object.keys(newObj).forEach((field) => {
|
||
const col = excelCellDataMap[field]
|
||
if (col) {
|
||
let custom: any
|
||
if (col === '0') {
|
||
custom = {}
|
||
custom.type = item
|
||
custom.protocol = Number(protocol)
|
||
custom.otherData = obj
|
||
}
|
||
result[row][col] = { v: newObj[field], s: '1', custom }
|
||
}
|
||
})
|
||
})
|
||
resultData[item] = result
|
||
})
|
||
return resultData
|
||
}
|
||
|