代码初始化

This commit is contained in:
tianyongbao
2025-04-24 17:33:21 +08:00
commit 58da6b59c7
669 changed files with 209122 additions and 0 deletions

View File

@@ -0,0 +1,646 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<!--层级数据-->
<el-col :span="4" :xs="24">
<div class="head-container">
<el-input v-model="buildingName" placeholder="请输入层级名称" clearable prefix-icon="Search" style="margin-bottom: 20px" />
</div>
<div class="head-container">
<el-scrollbar>
<el-tree
:data="buildingOptions"
:props="{ label: 'label', children: 'children' }"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="buildingTreeRef"
node-key="id"
:highlight-current="false"
default-expand-all
show-checkbox
:check-on-click-node="true"
:check-strictly="false"
@check="handleCheckClick"
/>
</el-scrollbar>
</div>
</el-col>
<el-col :span="20" :xs="24">
<div class="search-con">
<div class="title">查询条件</div>
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="100px">
<el-form-item label="所属产品" prop="type">
<el-select v-model="queryParams.type" placeholder="请选择所属产品" clearable>
<el-option v-for="dict in lamp_product" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="灯具名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入灯具名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="网络状态" prop="networkStatus">
<el-select v-model="queryParams.networkStatus" placeholder="请选择网络状态" clearable>
<el-option v-for="dict in is_online" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-form>
<div class="search-btn-con">
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button type="info" icon="Refresh" @click="resetQuery">重置</el-button>
</div>
</div>
<div class="main-con">
<div class="title-con">
<div class="title">基本信息</div>
<div class="operate-btn-con">
<el-button :disabled="multiple" @click="handleAdjust(1)" icon="Open" v-hasPermi="['light:lamp:add']">开灯</el-button>
<el-button :disabled="multiple" @click="handleAdjust(0)" icon="TurnOff" v-hasPermi="['light:lamp:export']">关灯</el-button>
<el-button :disabled="multiple" @click="handleAdjust(2)" icon="Sunny" v-hasPermi="['light:lamp:export']">调光</el-button>
<el-button :disabled="multiple" @click="handleCreateGroups" icon="Connection" v-hasPermi="['light:lamp:export']">创建分组</el-button>
<el-button :disabled="multiple" @click="handleConfig" icon="FolderChecked" v-hasPermi="['light:lamp:export']">策略配置</el-button>
<el-button :disabled="multiple" @click="handleClear" icon="FolderDelete" v-hasPermi="['light:lamp:export']">清除策略</el-button>
</div>
</div>
<div class="content-con" v-loading="loading">
<el-table v-loading="loading" :data="lampList" height="calc(100% - 60px)" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="所属产品" align="center" prop="type">
<template #default="scope">
<dict-tag :options="lamp_product" :value="scope.row.type" />
</template>
</el-table-column>
<el-table-column label="IMEI号" align="center" prop="code" />
<el-table-column label="灯具名称" align="center" prop="name" />
<el-table-column label="所属灯杆" align="center" prop="poleName" />
<el-table-column label="层级名称" align="center" prop="buildingName" />
<el-table-column label="灯具状态" align="center" prop="lampStatus">
<template #default="scope">
<dict-tag :options="switch_status" :value="scope.row.lampStatus" />
</template>
</el-table-column>
<el-table-column label="亮度(%)" align="center" prop="brightness" width="100" />
<el-table-column label="网络状态" align="center" prop="networkStatus">
<template #default="scope">
<dict-tag :options="is_online" :value="scope.row.networkStatus" />
</template>
</el-table-column>
<el-table-column label="数据最后更新时间" align="center" prop="lastUpdatedTime" width="180"></el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<div class="ctrl-btn d-flex">
<el-tooltip v-for="item in operateList" :key="item.id" class="item" effect="dark" :content="item.title" placement="top">
<el-button :icon="item.icon" :v-hasPermi="item.hasPermi" circle @click="handleOperate(item.id, scope.row)"></el-button>
</el-tooltip>
</div>
</template>
</el-table-column>
</el-table>
<el-pagination small background layout="total, prev, pager, next" :total="total" @current-change="handleCurrentChange" />
</div>
</div>
</el-col>
</el-row>
<el-dialog title="历史数据" v-model="openHis" width="1100px" append-to-body destroy-on-close>
<el-form :model="queryHisParams" ref="queryHisRef" inline>
<el-form-item label="选择时间" prop="startTime">
<el-date-picker v-model="queryHisParams.time" type="daterange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
</el-form-item>
<el-form-item label="">
<el-button type="primary" icon="Search" @click="handleHisQuery">搜索</el-button>
<el-button type="info" icon="Refresh" @click="resetHisQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loadingHis" :data="tableHisData">
<el-table-column label="" align="center" width="55">
<template #default="scope">
<el-checkbox v-model="scope.row.isSelect" @change="selectHandler(scope)"></el-checkbox>
</template>
</el-table-column>
<el-table-column label="上报时间" property="dataReportingTime" width="200px" />
<el-table-column label="能耗(kwh)" property="energyConsumption" />
<el-table-column label="电压(V)" property="voltage" />
<el-table-column label="电流(mA)" property="currentValue" />
<el-table-column label="有功功率(W)" property="power" />
<el-table-column label="温度(°C)" align="center" prop="temperature"> </el-table-column>
<el-table-column label="信号强度(dbm)" property="signalStrength" />
</el-table>
<el-pagination small background layout="total, prev, pager, next" :total="historyTotal" @current-change="handleCurrentHisChange" />
<template #footer>
<span class="dialog-footer">
<div class="search-btn-con">
<el-button type="primary" @click="cancelHis">确定</el-button>
</div>
</span>
</template>
</el-dialog>
<el-dialog :title="detailTitle" v-model="detailOpen" width="1150px" append-to-body>
<el-radio-group v-model="activeName" style="margin-bottom: 20px">
<el-radio-button label="first">基本信息</el-radio-button>
<el-radio-button label="second">上传信息</el-radio-button>
<el-radio-button label="third">当前策略</el-radio-button>
</el-radio-group>
<div v-if="activeName === 'first'" class="basic-information">
<el-row :gutter="20">
<el-col :span="8">
<span class="title">所属产品</span
><span class="content"> <dict-tag style="display: inline" :options="lamp_product" :value="basicInformation.type" /></span>
</el-col>
<el-col :span="8">
<span class="title">IMEI号</span><span class="content">{{ basicInformation.imeiCode }}</span>
</el-col>
<el-col :span="8">
<span class="title">灯具名称</span><span class="content">{{ basicInformation.name }}</span>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<span class="title">所属灯杆</span><span class="content">{{ basicInformation.poleName }}</span>
</el-col>
<el-col :span="8">
<span class="title">所属层级</span><span class="content">{{ basicInformation.buildingName }}</span>
</el-col>
<el-col :span="8">
<span class="title">所属集控</span><span class="content">{{ basicInformation.centralizedControlName }}</span>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<span class="title">调光类型</span
><span class="content"><dict-tag style="display: inline" :options="dimmer_type" :value="basicInformation.dimmerType" /></span>
</el-col>
<el-col :span="8">
<span class="title">项目经纬度</span><span class="content">{{ basicInformation.lampLonLat }}</span>
</el-col>
<el-col :span="8">
<span class="title">灯控经纬度</span><span class="content">{{ basicInformation.lampLonLat }}</span>
</el-col>
</el-row>
</div>
<div v-if="activeName === 'second'" class="basic-information">
<el-row :gutter="20">
<el-col :span="8">
<span class="title">数据上报时间</span><span class="content">{{ uploadInformation.dataReportingTime }}</span>
</el-col>
<el-col :span="8">
<span class="title">网络状态</span>
<span class="content"><dict-tag style="display: inline" :options="is_online" :value="uploadInformation.networkStatus" /></span>
</el-col>
<el-col :span="8">
<span class="title">最后在线时间</span><span class="content">{{ uploadInformation.lastUpdatedTime }}</span>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<span class="title">电压(v)</span><span class="content">{{ uploadInformation.voltage }}</span>
</el-col>
<el-col :span="8">
<span class="title">电流(mA)</span><span class="content">{{ uploadInformation.currentValue }}</span>
</el-col>
<el-col :span="8">
<span class="title">功率(W)</span><span class="content">{{ uploadInformation.power }}</span>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<span class="title">能耗(kwh)</span><span class="content">{{ uploadInformation.energyConsumption }}</span>
</el-col>
<el-col :span="8">
<span class="title">温度()</span><span class="content">{{ uploadInformation.temperature }}</span>
</el-col>
<el-col :span="8">
<span class="title">当前亮灯时长(h)</span><span class="content">{{ uploadInformation.lightingUpTimeph }}</span>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
<span class="title">累计亮灯时长(h)</span><span class="content">{{ uploadInformation.lightingUpTotalTimeph }}</span>
</el-col>
</el-row>
</div>
<div v-if="activeName === 'third'" class="basic-information">
<div class="main-con">
<div class="content-con">
<el-table v-loading="lampStrategyLoading" :data="lampStrategyList">
<el-table-column label="策略名称" align="center" prop="name" />
<el-table-column label="开始时间" align="center" prop="beginDate" />
<el-table-column label="结束时间" align="center" prop="endDate" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template v-slot="scope">
<div class="ctrl-btn d-flex">
<el-tooltip v-for="item in operateListStrategy" :key="item.id" class="item" effect="dark" :content="item.title" placement="top">
<el-button :icon="item.icon" :v-hasPermi="item.hasPermi" circle @click="handleOperateLampStrategy(item.id, scope.row)"></el-button>
</el-tooltip>
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<template #footer> </template>
</el-dialog>
<el-dialog title="调光" v-model="dimmingOpen" width="500px" append-to-body>
<el-slider v-model="dimmingValue" show-input />
<template #footer>
<span class="dialog-footer">
<div class="search-btn-con">
<el-button @click="cancelDimming">取消</el-button>
<el-button type="primary" @click="submitDimming">确定</el-button>
</div>
</span>
</template>
</el-dialog>
<el-dialog title="新增分组" v-model="groupOpen" width="800px" append-to-body @close="handleGroupCancel">
<div class="search-con">
<el-form ref="groupRef" :model="groupForm" :inline="true" :rules="groupRules" label-width="80px">
<el-form-item label="分组用途" prop="purpose">
<el-select v-model="groupForm.purpose" placeholder="请选择分组用途" clearable>
<el-option v-for="dict in light_group_purpose" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="分组名称" prop="name">
<el-input v-model="groupForm.name" placeholder="请输入分组名称" />
</el-form-item>
<el-form-item label="分组描述" prop="remark">
<el-input type="textarea" v-model="groupForm.remark" placeholder="请输入备注信息" />
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="handleGroupSubmit"> </el-button>
<el-button @click="handleGroupCancel"> </el-button>
</div>
</template>
</el-dialog>
<LampStrategyConfig :currentIds="ids" :lampStrategyOpen="lampStrategyOpen" @update-open="handleUpdateOpen" type="1" />
<lampStrategyDialog :open="openStrategy" :strategyId="strategyId" />
</div>
</template>
<script setup name="Lamp">
import dayjs from 'dayjs'
import { ElMessage } from 'element-plus'
import lampStrategyDialog from '@/views/components/light/lampStrategyDialog'
import LampStrategyConfig from '@/views/components/light/lampStrategyConfig.vue'
import { addGroup } from '@/api/light/group'
import { listLamp, getLamp, getLampUploadInfo, getLampHistory, getLampStrategy } from '@/api/light/lamp'
import { updateLampControl } from '@/api/light/lightMonitor'
import { clearLampStrategy } from '@/api/light/lampStrategy'
import { buildingTree } from '@/api/building/buildingInfo'
// eslint-disable-next-line no-unused-vars
import { require } from '@/utils/require'
import { nextTick, reactive, toRefs } from 'vue'
import { treeFilterNode } from '@/utils/utils'
const { proxy } = getCurrentInstance()
const { is_online, switch_status, lamp_product, dimmer_type, light_group_purpose } = proxy.useDict(
'is_online',
'switch_status',
'lamp_product',
'dimmer_type',
'light_group_purpose'
)
const lampList = ref([])
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const buildingOptions = ref(undefined)
const basicInformation = ref(null)
const detailTitle = ref('')
const detailOpen = ref(false)
const uploadInformation = ref(null)
const activeName = ref('first')
const openHis = ref(false)
const currentHisId = ref(false)
const loadingHis = ref(false)
const tableHisData = ref([])
const historyTotal = ref(0)
const dimmingOpen = ref(false)
const dimmingValue = ref(0)
const lampStrategyOpen = ref(false)
const openStrategy = ref(false)
const strategyId = ref('')
const currentId = ref('')
const lampStrategyObj = reactive({
lampStrategyLoading: false,
lampStrategyList: []
})
const { lampStrategyLoading, lampStrategyList } = toRefs(lampStrategyObj)
const operateListStrategy = ref([
{ id: 'view', icon: 'View', title: '详情', hasPermi: ['light:group:query'] },
{ id: 'clear', icon: 'FolderDelete', title: '清除', hasPermi: ['light:group:remove'] }
])
const queryHisParams = ref({
time: '',
pageNum: 1
})
const operateList = ref([
{ id: 'view', icon: 'Document', title: '详情', hasPermi: ['light:lamp:query'] },
{ id: 'history', icon: 'Histogram', title: '历史数据', hasPermi: ['light:lamp:query'] }
])
const data = reactive({
form: {},
formHis: {},
queryParams: {
pageNum: 1,
pageSize: 10,
name: null,
buildingId: null,
buildingIdList: null,
code: null,
type: null,
networkStatus: null
},
rules: {
name: [{ required: true, message: '灯具名称不能为空', trigger: 'blur' }],
position: [{ required: true, message: '灯具位置不能为空', trigger: 'change' }],
code: [{ required: true, message: '灯具编号不能为空', trigger: 'change' }]
}
})
const { queryParams, formHis } = toRefs(data)
const groupData = reactive({
groupOpen: false,
groupForm: {
purpose: '',
name: '',
remark: ''
},
groupRules: {
purpose: [{ required: true, message: '分组用途不能为空', trigger: 'change' }],
name: [{ required: true, message: '分组名称不能为空', trigger: 'blur' }]
}
})
const { groupOpen, groupForm, groupRules } = toRefs(groupData)
const handleOperate = (operate, row) => {
switch (operate) {
case 'view':
handleView(row)
break
case 'history':
handleHis(row)
break
default:
break
}
}
const buildingName = ref('')
/** 通过条件过滤节点 */
const filterNode = (value, data, node) => {
return treeFilterNode(value, data, node)
}
/** 根据名称筛选层级树 */
watch(buildingName, (val) => {
// eslint-disable-next-line dot-notation
proxy.$refs['buildingTreeRef'].filter(val)
})
/** 查询灯具信息列表 */
function getList() {
loading.value = true
listLamp(queryParams.value).then((response) => {
lampList.value = response.rows
total.value = response.total
loading.value = false
})
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm('queryRef')
queryParams.value.buildingIdList = null
proxy.$refs.buildingTreeRef.setCheckedKeys([])
handleQuery()
}
// 分页
const handleCurrentChange = (val) => {
queryParams.value.pageNum = val
getList()
}
// 多选框选中数据
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.id)
single.value = selection.length !== 1
multiple.value = !selection.length
}
const handleAdjust = (type) => {
if (type === 2) {
dimmingOpen.value = true
} else {
updateLampControl(ids.value, type, type).then((res) => {
ElMessage.success(type === 1 ? '开灯成功' : '关灯成功')
getList()
})
}
}
const submitDimming = () => {
updateLampControl(ids.value, '2', dimmingValue.value).then((res) => {
ElMessage.success('调光成功')
cancelDimming()
getList()
})
}
const cancelDimming = () => {
dimmingOpen.value = false
dimmingValue.value = 0
}
// 查看
const handleView = (row) => {
const _id = row.id || ids.value
currentId.value = _id
activeName.value = 'first'
getLamp(_id).then((response) => {
basicInformation.value = response.data
detailOpen.value = true
detailTitle.value = '查看灯具信息'
})
getLampUploadInfo(_id).then((response) => {
uploadInformation.value = response.data
})
getLampStrategy(_id).then((res) => {
lampStrategyList.value = res.data
})
}
/** 历史数据操作 */
function handleHis(row) {
const _id = row.id || ids.value
currentHisId.value = _id
getHisList(1)
openHis.value = true
}
// 取消按钮
function cancelHis() {
queryHisParams.value.time = ''
openHis.value = false
}
const handleCurrentHisChange = (num) => {
getHisList(num)
}
const handleHisQuery = () => {
getHisList(1)
}
const resetHisQuery = () => {
queryHisParams.value.time = ''
historyTotal.value = 0
getHisList(1)
}
const getHisList = (num) => {
loadingHis.value = true
const timeRange = queryHisParams.value.time
let st = ''
let et = ''
if (timeRange && timeRange.length === 2) {
st = dayjs(timeRange[0]).format('YYYY-MM-DD')
et = dayjs(timeRange[1]).format('YYYY-MM-DD')
}
getLampHistory({ lampId: currentHisId.value, startTime: st, endTime: et, pageNum: num, pageSize: 10 }).then((res) => {
loadingHis.value = false
tableHisData.value = res.rows
historyTotal.value = res.total
formHis.value = res.data
})
}
/** 查询层级下拉树结构 */
function getBuildingTree() {
buildingTree().then((response) => {
buildingOptions.value = response.data
})
}
/** 节点复选框事件 */
function handleCheckClick(data) {
const checkNodes = proxy.$refs.buildingTreeRef.getCheckedNodes()
const buildingIdArray = []
// 遍历
for (let i = 0; i < checkNodes.length; i++) {
const node = checkNodes[i]
buildingIdArray.push(node.id)
}
const halfCheckNodes = proxy.$refs.buildingTreeRef.getHalfCheckedNodes()
// 遍历
for (let i = 0; i < halfCheckNodes.length; i++) {
const node = halfCheckNodes[i]
buildingIdArray.push(node.id)
}
queryParams.value.buildingIdList = buildingIdArray
handleQuery()
}
const resetGroup = () => {
groupForm.value = {
name: '',
purpose: '',
remark: ''
}
}
const handleCreateGroups = () => {
groupOpen.value = true
console.log(ids.value)
}
const handleGroupSubmit = () => {
proxy.$refs.groupRef.validate((valid) => {
if (valid) {
const { name, purpose, remark } = groupForm.value
addGroup({ ids: ids.value, name, purpose, remark, type: '1' }).then((response) => {
proxy.$modal.msgSuccess('添加分组成功')
groupOpen.value = false
resetGroup()
getList()
})
}
})
}
const handleGroupCancel = () => {
groupOpen.value = false
resetGroup()
}
const handleConfig = () => {
lampStrategyOpen.value = false
nextTick(() => {
lampStrategyOpen.value = true
})
}
const handleUpdateOpen = () => {
lampStrategyOpen.value = false
getList()
}
const handleClear = () => {
proxy.$modal
.confirm('确认清除所有灯具策略?')
.then(function () {
clearLampStrategy({ ids: ids.value.join(','), lampStrategyId: '', type: '1' }).then((res) => {
proxy.$modal.msgSuccess('清除成功')
getList()
})
})
.catch(() => {})
}
const handleOperateLampStrategy = (operate, row) => {
switch (operate) {
case 'view':
console.log(row.id)
strategyId.value = ''
nextTick(() => {
strategyId.value = row.id
openStrategy.value = true
})
break
case 'clear':
proxy.$modal
.confirm('确认清除该灯具的当前策略?')
.then(function () {
clearLampStrategy({ ids: currentId.value, lampStrategyId: row.id, type: '1' }).then((res) => {
proxy.$modal.msgSuccess('清除成功')
getLampStrategy(currentId.value).then((res) => {
lampStrategyList.value = res.data
})
})
})
.catch(() => {})
break
default:
break
}
}
getBuildingTree()
getList()
</script>