New file |
| | |
| | | export default { |
| | | // 单体电压保留3位小数 |
| | | VOL: 3, |
| | | // 组端电压,保留1位小数 |
| | | GROUPVOL: 1, |
| | | // 充放电设备的电流保留1位小数 |
| | | CURR_YT: 1, |
| | | // 均衡仪的电流是3位小数 |
| | | CURR_JH: 3, |
| | | }; |
| | |
| | | * 数值保留指定位数小数 |
| | | */ |
| | | export default function toFixed(value, bit) { |
| | | if (!value) { |
| | | return 0; |
| | | } |
| | | const num = Math.pow(10, bit); |
| | | return Math.round(value * num) / num; |
| | | } |
| | |
| | | <div class="content">{{ formatSeconds(testObj.testTimelong) }}</div> |
| | | <div class="label">数据类型</div> |
| | | <div class="content"> |
| | | {{ { 2: "放电数据", 3: "充电数据" }[testInf.testType] }} |
| | | {{ { 2: "充电数据", 3: "放电数据" }[testInf.testType] }} |
| | | </div> |
| | | <!-- <div class="label">标称容量</div> |
| | | <div class="content">4444444</div> |
| | |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 删除设备 |
| | | */ |
| | | export const delDev = (devId) => { |
| | | return axios({ |
| | | method: "GET", |
| | | url: "devInf/delDinf", |
| | | params: { devId }, |
| | | }); |
| | | }; |
| | | |
| | | export const updateDev = (data) => { |
| | | return axios({ |
| | | method: "POST", |
| | |
| | | import { useRoute, useRouter } from "vue-router"; |
| | | import { ElMessage } from "element-plus"; |
| | | import useElement from "@/hooks/useElement.js"; |
| | | import { delDev } from "./api"; |
| | | |
| | | import useWebSocket from "@/hooks/useWebSocket"; |
| | | const { sendData, message: message1 } = useWebSocket("dinfSocket"); |
| | |
| | | ]; |
| | | const pageCurr = ref(1); |
| | | const pageSize = ref(10); |
| | | const total = ref(0); |
| | | const addEditVisible = ref(false); |
| | | const devType = ref(1); |
| | | const devOnline = ref(-1); |
| | |
| | | addEditVisible.value = true; |
| | | } |
| | | function confirmRemove(record) { |
| | | // $confirm("删除该用户", () => { |
| | | // remove(record.uid); |
| | | // }); |
| | | $confirm("删除该设备", () => { |
| | | remove(record.devId); |
| | | }); |
| | | } |
| | | function remove(uid) { |
| | | function remove(devId) { |
| | | let loading = $loading(); |
| | | // deleteUser(uid) |
| | | // .then((res) => { |
| | | // let { code, data } = res.data; |
| | | // loading.close(); |
| | | // if (code && data) { |
| | | // $message.success("操作成功"); |
| | | // handleCurrentChange(1); |
| | | // } else { |
| | | // $message.success("操作失败"); |
| | | // } |
| | | // }) |
| | | // .catch((err) => { |
| | | // loading.close(); |
| | | // console.log(err); |
| | | // }); |
| | | delDev(devId) |
| | | .then((res) => { |
| | | let { code, data } = res.data; |
| | | loading.close(); |
| | | if (code && data) { |
| | | $message.success("操作成功"); |
| | | handleCurrentChange(1); |
| | | } else { |
| | | $message.success("操作失败"); |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | loading.close(); |
| | | console.log(err); |
| | | }); |
| | | } |
| | | function onOk() { |
| | | addEditVisible.value = false; |
| | |
| | | </div> |
| | | <div class="p-content"> |
| | | <!-- 用户列表 --> |
| | | <div class="table-wrap"> |
| | | <el-table |
| | | class="yc-table" |
| | | stripe |
| | | height="100%" |
| | | size="small" |
| | | :data="rtdata.list" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column |
| | | type="index" |
| | | label="序号" |
| | | width="80" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | v-for="header in headers" |
| | | :key="header.prop" |
| | | :prop="header.prop" |
| | | :label="header.label" |
| | | :min-width="header.width" |
| | | align="center" |
| | | ></el-table-column> |
| | | <el-table-column label="操作" width="160" align="center"> |
| | | <template #default="scope"> |
| | | <el-button type="primary" size="small" @click="edit(scope.row)" |
| | | >编辑</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | size="small" |
| | | @click="confirmRemove(scope.row)" |
| | | >删除</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div class="table-wrap posR"> |
| | | <div class="pos-full"> |
| | | <el-table |
| | | class="yc-table" |
| | | stripe |
| | | height="100%" |
| | | size="small" |
| | | :data="rtdata.list" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column |
| | | type="index" |
| | | label="序号" |
| | | width="80" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | v-for="header in headers" |
| | | :key="header.prop" |
| | | :prop="header.prop" |
| | | :label="header.label" |
| | | :min-width="header.width" |
| | | align="center" |
| | | ></el-table-column> |
| | | <el-table-column label="操作" width="160" align="center"> |
| | | <template #default="scope"> |
| | | <el-button type="primary" size="small" @click="edit(scope.row)" |
| | | >编辑</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | size="small" |
| | | @click="confirmRemove(scope.row)" |
| | | >删除</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | <!-- 底部 --> |
| | | </div> |
| | |
| | | :page-sizes="[10, 20, 30, 50, 100]" |
| | | :page-size="pageSize" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :total="total" |
| | | :total="rtdata.total" |
| | | ></el-pagination> |
| | | </div> |
| | | <!-- 弹窗 --> |
| | |
| | | import { ref, computed } from "vue"; |
| | | import IconDot from "@/components/icons/IconDot.vue"; |
| | | import formatSeconds from "@/assets/js/tools/formatSeconds"; |
| | | import toFixed from "@/assets/js/tools/toFixed.js"; |
| | | import const_digits from "@/assets/js/const/const_digits"; |
| | | const { VOL, GROUPVOL, CURR_YT, CURR_JH } = const_digits; |
| | | const props = defineProps({ |
| | | datas: { |
| | | type: Object, |
| | |
| | | type: Array, |
| | | required: true, |
| | | }, |
| | | idx: { |
| | | type: Number, |
| | | required: true, |
| | | } |
| | | }); |
| | | const temp = computed(() => { |
| | | let tlist = props.rtdata.slice(0, 4).map((v) => v.monTmp); |
| | |
| | | <template> |
| | | <div class="info"> |
| | | <div :class="['title', { offline: 0 == datas.moduleStatusInt }]"> |
| | | <div class="index">#{{ datas.batteryStorageIndex + 1 }}</div> |
| | | <div class="index">#{{ (datas.batteryStorageIndex || idx) + 1 }}</div> |
| | | <div class="state"> |
| | | <el-icon class="ico"><icon-dot /></el-icon> |
| | | {{ datas.moduleStatus }} |
| | |
| | | <div class="label">电池串数</div> |
| | | <div class="content">{{ datas.batteryNumber }}</div> |
| | | </div> |
| | | <div class="box"> |
| | | <!-- <div class="box"> |
| | | <div class="label">模组目标电压</div> |
| | | <div class="content">{{ datas.storageVoltageThreshold }}</div> |
| | | </div> |
| | | <div class="content"> |
| | | {{ toFixed(datas.storageVoltageThreshold, GROUPVOL) }} |
| | | </div> |
| | | </div> --> |
| | | <div class="box"> |
| | | <div class="label">单体目标电压</div> |
| | | <div class="content">{{ datas.batteryVoltageThreshold }}</div> |
| | | <div class="content"> |
| | | {{ toFixed(datas.batteryVoltageThreshold, VOL) }} |
| | | </div> |
| | | </div> |
| | | <div class="box large"> |
| | | <div class="label">温度</div> |
| | |
| | | |
| | | <div class="item item1"> |
| | | <div class="label">Umax</div> |
| | | <div class="value">{{ datas.maxBatteryVoltage }}V</div> |
| | | <div class="value">{{ toFixed(datas.maxBatteryVoltage, VOL) }}V</div> |
| | | </div> |
| | | <div class="item"> |
| | | <div class="label">Umin</div> |
| | | <div class="value">{{ datas.minBatteryVoltage }} V</div> |
| | | <div class="value">{{toFixed(datas.minBatteryVoltage, VOL) }} V</div> |
| | | </div> |
| | | <div class="item"> |
| | | <div class="label">ΔU</div> |
| | | <div class="value">{{ datas.avgBatteryVoltage }} V</div> |
| | | <div class="value">{{ toFixed(datas.avgBatteryVoltage, VOL) }} V</div> |
| | | </div> |
| | | <div class="item"> |
| | | <div class="label">电芯压差</div> |
| | | <div class="value">{{ datas.diffBatteryVoltage }} V</div> |
| | | <div class="value">{{ toFixed(datas.diffBatteryVoltage, VOL) }} V</div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | import iconPower from "@/components/icons/iconPower.vue"; |
| | | import formatSeconds from "@/assets/js/tools/formatSeconds.js"; |
| | | import IconDot from "@/components/icons/IconDot.vue"; |
| | | |
| | | import toFixed from "@/assets/js/tools/toFixed.js"; |
| | | import const_digits from "@/assets/js/const/const_digits"; |
| | | const { VOL, GROUPVOL, CURR_YT, CURR_JH } = const_digits; |
| | | |
| | | const infoTab = ref(0); |
| | | const { sendData, message } = useWebSocket("rtstateSocket"); |
| | | |
| | |
| | | onlyOneGroup: { |
| | | type: Boolean, |
| | | default: false, |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | const headers = [ |
| | |
| | | |
| | | const battVolChart = ref(); |
| | | |
| | | const groupCount = computed(() => props.onlyOneGroup ? 1 : 2); |
| | | const groupCount = computed(() => (props.onlyOneGroup ? 1 : 2)); |
| | | |
| | | const rtDatas = computed(() => { |
| | | if (message.value) { |
| | |
| | | devStates = [{}, {}]; |
| | | } |
| | | |
| | | monStates0.forEach(v => { |
| | | v.monState = v.needTest==0 ? '--' : v.monState; |
| | | monStates0.forEach((v) => { |
| | | v.monState = v.needTest == 0 ? "--" : v.monState; |
| | | v.monVol = toFixed(v.monVol, VOL); |
| | | v.monCurr = toFixed(v.monCurr, CURR_JH); |
| | | }); |
| | | |
| | | monStates1.forEach(v => { |
| | | v.monState = v.needTest==0 ? '--' : v.monState; |
| | | monStates1.forEach((v) => { |
| | | v.monState = v.needTest == 0 ? "--" : v.monState; |
| | | v.monVol = toFixed(v.monVol, VOL); |
| | | v.monCurr = toFixed(v.monCurr, CURR_JH); |
| | | }); |
| | | |
| | | return { monStates0, monStates1, devStates, eventList }; |
| | |
| | | if (reg.test(v)) { |
| | | sendData(JSON.stringify({ devId: props.devId, devType: 2 })); |
| | | } |
| | | |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | |
| | | class="group" |
| | | :datas="rtDatas.devStates[0]" |
| | | :rtdata="rtDatas.monStates0" |
| | | :idx="0" |
| | | ></jhy-info> |
| | | <jhy-info |
| | | class="group" |
| | | v-if="!onlyOneGroup" |
| | | :datas="rtDatas.devStates[1]" |
| | | :rtdata="rtDatas.monStates1" |
| | | :idx="1" |
| | | ></jhy-info> |
| | | </div> |
| | | <!-- 单体列表 --> |
| | |
| | | ]" |
| | | > |
| | | <div class="index"> |
| | | #{{ rtDatas.devStates[idx].batteryStorageIndex + 1 }} |
| | | <!-- #{{ rtDatas.devStates[idx].batteryStorageIndex + 1 }} --> |
| | | #{{ i }} |
| | | </div> |
| | | <div class="state"> |
| | | <el-icon class="ico"><icon-dot /></el-icon> |
| | |
| | | <div class="chart-info"> |
| | | <div class="label">最大值</div> |
| | | <div class="value max"> |
| | | {{ rtDatas["devStates"][idx].maxBatteryVoltage }}V |
| | | {{ toFixed(rtDatas["devStates"][idx].maxBatteryVoltage, VOL) }}V |
| | | </div> |
| | | <div class="label">最小值</div> |
| | | <div class="value min"> |
| | | {{ rtDatas["devStates"][idx].minBatteryVoltage }}V |
| | | {{ toFixed(rtDatas["devStates"][idx].minBatteryVoltage, VOL) }}V |
| | | </div> |
| | | <div class="label">平均值</div> |
| | | <div class="value"> |
| | | {{ rtDatas["devStates"][idx].avgMonVol }}V |
| | | {{ toFixed(rtDatas["devStates"][idx].avgMonVol, VOL) }}V |
| | | </div> |
| | | </div> |
| | | <div class="chart-wrap1"> |
| | |
| | | import formatSeconds from "@/assets/js/tools/formatSeconds.js"; |
| | | import getPowerByUI from "@/assets/js/tools/getPowerByUI.js"; |
| | | import toFixed from "@/assets/js/tools/toFixed.js"; |
| | | import const_digits from "@/assets/js/const/const_digits"; |
| | | const { VOL, GROUPVOL, CURR_YT, CURR_JH } = const_digits; |
| | | |
| | | const infoTab = ref(0); |
| | | const { sendData, message } = useWebSocket("rtstateSocket"); |
| | |
| | | vols = []; |
| | | rtDatas.value.monStates.forEach((v) => { |
| | | mons.push(`#${v.monNum}`); |
| | | vols.push(v.monVol); |
| | | vols.push(toFixed(v.monVol, VOL)); |
| | | }); |
| | | battVolChart.value?.updateChart(mons, vols); |
| | | } |
| | |
| | | <div class="item item1"> |
| | | <div class="label">Umax</div> |
| | | <div class="value"> |
| | | {{ rtDatas.devStates.maxBatteryVoltage }}V |
| | | {{ toFixed(rtDatas.devStates.maxBatteryVoltage, VOL) }}V |
| | | </div> |
| | | </div> |
| | | <div class="item"> |
| | | <div class="label">Umin</div> |
| | | <div class="value"> |
| | | {{ rtDatas.devStates.minBatteryVoltage }}V |
| | | {{ toFixed(rtDatas.devStates.minBatteryVoltage, VOL) }}V |
| | | </div> |
| | | </div> |
| | | <div class="item"> |
| | | <div class="label">ΔU</div> |
| | | <div class="value">{{ rtDatas.devStates.avgMonVol }}V</div> |
| | | <div class="value">{{ toFixed(rtDatas.devStates.avgMonVol, VOL) }}V</div> |
| | | </div> |
| | | <div class="item-big"> |
| | | {{ toFixed(rtDatas.devStates.storageVoltage, 3) }} |
| | | {{ toFixed(rtDatas.devStates.storageVoltage, VOL) }} |
| | | <div class="unit">V</div> |
| | | </div> |
| | | |
| | |
| | | </div> |
| | | |
| | | <div class="item-big curr"> |
| | | {{ rtDatas.devStates.testCurrent }} |
| | | {{ toFixed(rtDatas.devStates.testCurrent, CURR_YT) }} |
| | | <div class="unit">A</div> |
| | | </div> |
| | | <div class="border border2"> |
| | |
| | | <div class="info"> |
| | | <div class="label">最大值</div> |
| | | <div class="value max"> |
| | | {{ rtDatas.devStates.maxBatteryVoltage }}V |
| | | {{ toFixed(rtDatas.devStates.maxBatteryVoltage, VOL) }}V |
| | | </div> |
| | | <div class="label">最小值</div> |
| | | <div class="value min"> |
| | | {{ rtDatas.devStates.minBatteryVoltage }}V |
| | | {{ toFixed(rtDatas.devStates.minBatteryVoltage, VOL) }}V |
| | | </div> |
| | | <div class="label">平均值</div> |
| | | <div class="value">{{ rtDatas.devStates.avgMonVol }}V</div> |
| | | <div class="value">{{ toFixed(rtDatas.devStates.avgMonVol, VOL) }}V</div> |
| | | </div> |
| | | <div class="list-wrap posR"> |
| | | <div class="pos-full scroll"> |
| | |
| | | }, |
| | | ]" |
| | | > |
| | | {{ item.monVol }} V |
| | | {{ toFixed(item.monVol, VOL) }} V |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="chart-info"> |
| | | <div class="label">最大值</div> |
| | | <div class="value max"> |
| | | {{ rtDatas.devStates.maxBatteryVoltage }}V |
| | | {{ toFixed(rtDatas.devStates.maxBatteryVoltage, VOL) }}V |
| | | </div> |
| | | <div class="label">最小值</div> |
| | | <div class="value min"> |
| | | {{ rtDatas.devStates.minBatteryVoltage }}V |
| | | {{ toFixed(rtDatas.devStates.minBatteryVoltage, VOL) }}V |
| | | </div> |
| | | <div class="label">平均值</div> |
| | | <div class="value">{{ rtDatas.devStates.avgMonVol }}V</div> |
| | | <div class="value">{{ toFixed(rtDatas.devStates.avgMonVol, VOL) }}V</div> |
| | | </div> |
| | | <div class="chart-wrap"> |
| | | <bar ref="battVolChart" unit="V"></bar> |
| | |
| | | import getPowerByUI from "@/assets/js/tools/getPowerByUI.js"; |
| | | import formatSeconds from "@/assets/js/tools/formatSeconds"; |
| | | import { useRouter, useRoute } from "vue-router"; |
| | | import const_digits from "@/assets/js/const/const_digits"; |
| | | const { VOL, GROUPVOL, CURR_YT, CURR_JH } = const_digits; |
| | | |
| | | const { $alert, $loading, $message, $confirm } = useElement(); |
| | | const { sendData, message } = useWebSocket("rtstateSocket"); |
| | | const router = useRouter(); |
| | | |
| | | |
| | | const props = defineProps({ |
| | | devId: { |
| | | type: [Number, String], |
| | |
| | | <el-form-item label="用户名" prop="name"> |
| | | <el-input :disabled="isEdit" v-model="form1.name"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="权限" prop="permission"> |
| | | <!-- <el-form-item label="权限" prop="permission"> |
| | | <el-checkbox v-model="form1.permission" label="控制权限"></el-checkbox> |
| | | </el-form-item> |
| | | </el-form-item> --> |
| | | <el-form-item> |
| | | <el-button v-if="isEdit" type="primary" @click="update">修改</el-button> |
| | | <el-button v-else type="primary" @click="onSubmit">新增</el-button> |
| | |
| | | width: "", |
| | | }, |
| | | { |
| | | prop: "canDownload", |
| | | label: "控制权限", |
| | | prop: "createTime", |
| | | label: "创建时间", |
| | | width: "", |
| | | }, |
| | | // { |
| | | // prop: "canDownload", |
| | | // label: "控制权限", |
| | | // width: "", |
| | | // }, |
| | | ]; |
| | | const pageCurr = ref(1); |
| | | const pageSize = ref(10); |
| | |
| | | > |
| | | </div> |
| | | </div> |
| | | <div class="p-content"> |
| | | <div class="p-content posR"> |
| | | <!-- 用户列表 --> |
| | | <div class="table-wrap"> |
| | | <el-table |
| | | class="yc-table" |
| | | stripe |
| | | height="100%" |
| | | size="small" |
| | | :data="datas.tableData" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column |
| | | type="index" |
| | | label="序号" |
| | | width="80" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | v-for="header in headers" |
| | | :key="header.prop" |
| | | :prop="header.prop" |
| | | :label="header.label" |
| | | :min-width="header.width" |
| | | align="center" |
| | | ></el-table-column> |
| | | <el-table-column label="操作" width="360" align="center"> |
| | | <template #default="scope"> |
| | | <el-button |
| | | type="primary" |
| | | size="small" |
| | | :disabled="scope.row.uid == uid" |
| | | @click="edit(scope.row)" |
| | | >编辑</el-button |
| | | > |
| | | <el-button |
| | | type="primary" |
| | | size="small" |
| | | :disabled="scope.row.uid == uid" |
| | | @click="resetSnIdfn(scope.row)" |
| | | >重置密码</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | size="small" |
| | | :disabled="scope.row.uid == uid" |
| | | @click="confirmRemove(scope.row)" |
| | | >删除</el-button |
| | | > |
| | | <el-button |
| | | type="success" |
| | | v-if="scope.row.uid > 1000" |
| | | size="small" |
| | | @click="improveRolefn(scope.row)" |
| | | >加入管理员组</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | v-else |
| | | :disabled="scope.row.uid == uid" |
| | | size="small" |
| | | @click="dropRolefn(scope.row)" |
| | | >移出管理员组</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div class="table-wrap posR"> |
| | | <div class="pos-full"> |
| | | <el-table |
| | | class="yc-table" |
| | | stripe |
| | | height="100%" |
| | | size="small" |
| | | :data="datas.tableData" |
| | | style="width: 100%" |
| | | > |
| | | <el-table-column |
| | | type="index" |
| | | label="序号" |
| | | width="80" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | v-for="header in headers" |
| | | :key="header.prop" |
| | | :prop="header.prop" |
| | | :label="header.label" |
| | | :min-width="header.width" |
| | | align="center" |
| | | ></el-table-column> |
| | | <el-table-column label="操作" width="360" align="center"> |
| | | <template #default="scope"> |
| | | <!-- <el-button |
| | | type="primary" |
| | | size="small" |
| | | :disabled="scope.row.uid == uid" |
| | | @click="edit(scope.row)" |
| | | >编辑</el-button |
| | | > --> |
| | | <el-button |
| | | type="primary" |
| | | size="small" |
| | | :disabled="scope.row.uid == uid" |
| | | @click="resetSnIdfn(scope.row)" |
| | | >重置密码</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | size="small" |
| | | :disabled="scope.row.uid == uid" |
| | | @click="confirmRemove(scope.row)" |
| | | >删除</el-button |
| | | > |
| | | <el-button |
| | | type="success" |
| | | v-if="scope.row.uid > 1000" |
| | | size="small" |
| | | @click="improveRolefn(scope.row)" |
| | | >加入管理员组</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | v-else |
| | | :disabled="scope.row.uid == uid" |
| | | size="small" |
| | | @click="dropRolefn(scope.row)" |
| | | >移出管理员组</el-button |
| | | > |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | <!-- 底部 --> |
| | | <!-- 底部分页 --> |