提交
This commit is contained in:
parent
79cd20467c
commit
a14e1841cc
36
.cursorrules
Normal file
36
.cursorrules
Normal file
|
@ -0,0 +1,36 @@
|
|||
# 项目背景
|
||||
这是一个基于RuoYi-Vue的智能开关项目后台管理系统,主要用于管理智能开关设备、用户、订单、支付、设备状态、设备参数等。
|
||||
|
||||
# 主要框架
|
||||
- Vue2
|
||||
- Element-UI
|
||||
- Axios
|
||||
- Vuex
|
||||
- Vue-Router
|
||||
|
||||
# 编码标准
|
||||
- 变量和函数名使用 camelCase 规范,组件名使用 PascalCase
|
||||
- 组件的样式使用 scoped 属性,避免样式污染
|
||||
- 样式使用scss
|
||||
- props、data、methods、computed、watch 生命周期函数等都使用驼峰命名
|
||||
- 对于全局能够重复使用的组件,尽量封装成组件,并放在 src/components 目录下
|
||||
- 对于业务能够重复使用的组件,尽量封装成组件,并放在 src/views/{模块名}/components 目录下
|
||||
- 所有请求都需要在 src/api/{模块名}.js 文件中定义,并保持统一的命名规范,使用时统一调用
|
||||
- 业务操作尽量封装成方法或组件
|
||||
- table中的数据使用columns定义,具体可以参考其他组件
|
||||
- 保持与现有代码风格一致
|
||||
- 代码需要具有可读性,注释清晰,后续可拓展
|
||||
- 生成的代码需要自动导入相关依赖,这点很重要
|
||||
|
||||
# 项目结构
|
||||
- src/api 目录下存放接口文件
|
||||
- src/assets 目录下存放静态资源
|
||||
- src/components 目录下存放全局组件
|
||||
- src/views 目录下存放页面
|
||||
- src/utils 目录下存放工具类
|
||||
- src/utils/constants.js 目录下存放常量
|
||||
- src/views/ss 目录下存放业务相关页面
|
||||
- src/views/system 目录下存放系统相关页面
|
||||
|
||||
# 文档规范
|
||||
- 使用 JSDoc 格式编写函数和组件的注释
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -21,3 +21,4 @@ selenium-debug.log
|
|||
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
dist.zip
|
||||
|
|
10
jsconfig.json
Normal file
10
jsconfig.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
|
@ -70,10 +70,14 @@ export function logicDelDevice(deviceId) {
|
|||
|
||||
|
||||
// 刷新物联网设备信息
|
||||
export function refreshIot(deviceId) {
|
||||
export function refreshIot(deviceId, onlineType) {
|
||||
return request({
|
||||
url: `/system/device/${deviceId}/refreshIot`,
|
||||
method: 'get'
|
||||
method: 'get',
|
||||
timeout: 20000,
|
||||
params: {
|
||||
onlineType
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -289,3 +289,9 @@ export const VipExpireType = {
|
|||
FOREVER: "1", // 永久有效
|
||||
TIME: "2", // 有效期
|
||||
}
|
||||
|
||||
// 设备获取在线状态类型
|
||||
export const DeviceOnlineType = {
|
||||
GET: "1", //OneNet获取
|
||||
COMMAND: "2", // 命令获取
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ export default {
|
|||
default: getVipLevel
|
||||
},
|
||||
addApi: {
|
||||
typ: Function,
|
||||
type: Function,
|
||||
default: addVipLevel
|
||||
},
|
||||
updateApi: {
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { listVipLevel, getVipLevel, delVipLevel, addVipLevel, updateVipLevel } from "@/api/ss/vipLevel";
|
||||
import { delVipLevel } from "@/api/ss/vipLevel";
|
||||
import { $showColumns } from '@/utils/mixins';
|
||||
import UserLink from '@/components/Business/SmUser/UserLink.vue'
|
||||
import VipLevelEditDialog from '@/views/ss/vipLevel/components/VipLevelEditDialog.vue'
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<el-button size="small" plain icon="el-icon-refresh" @click="handleResetEle" v-if="deviceData.modelTags.includes(ModelTag.ELE)">电量归零</el-button>
|
||||
<el-button size="small" plain type="warning" icon="el-icon-switch-button" v-if="!isOpen" @click="handleSwitch(true)">强制开启</el-button>
|
||||
<el-button size="small" plain type="warning" icon="el-icon-switch-button" v-if="isOpen" @click="handleSwitch(false)">强制关闭</el-button>
|
||||
<el-button size="small" plain icon="el-icon-refresh" @click="refreshIot(deviceId, true)" style="margin-right: 1em">刷新设备信息</el-button>
|
||||
<el-button size="small" plain icon="el-icon-refresh" @click="refreshIot(deviceId, true, DeviceOnlineType.COMMAND)" style="margin-right: 1em">刷新设备信息</el-button>
|
||||
<el-popover
|
||||
placement="left"
|
||||
width="180"
|
||||
|
@ -52,6 +52,15 @@
|
|||
<el-descriptions-item label="限制充值原因">
|
||||
{{deviceData.limitRechargeReason | defaultValue}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户手动操作时间">
|
||||
{{deviceData.userOperaTime | defaultValue}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户手动操作电量">
|
||||
{{deviceData.userOpereEle | defaultValue}} 度
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户手动操作类型">
|
||||
<dict-tag :options="dict.type.device_user_opera_type" :value="deviceData.userOperaType" size="mini"/>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
|
||||
|
@ -110,15 +119,9 @@
|
|||
<el-descriptions-item label="开关状态">
|
||||
<el-tag :type="isOpen ? 'success' : 'danger'" size="mini">{{isOpen ? '已开启' : '已关闭'}}</el-tag>
|
||||
</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="电压">{{deviceData.voltage | money | defaultValue }} V</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="电流">{{deviceData.electricity | money | defaultValue }} A</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="功率">{{deviceData.realTimePower | money | defaultValue }} W</el-descriptions-item>-->
|
||||
<el-descriptions-item label="总用电量">
|
||||
{{deviceData.totalElectriQuantity | money | defaultValue}} 度
|
||||
</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="电压系数">-->
|
||||
<!-- {{deviceData.vxs | fix3 | defaultValue}}-->
|
||||
<!-- </el-descriptions-item>-->
|
||||
<el-descriptions-item label="电量读数">
|
||||
{{deviceData.totalElectriQuantity - deviceData.initReading | money | defaultValue}} 度
|
||||
<el-link @click="handleInitReading" type="primary" icon="el-icon-refresh" style="margin-left: 0.5em">重置</el-link>
|
||||
|
@ -126,15 +129,6 @@
|
|||
<el-descriptions-item label="最近重置读数时间">
|
||||
{{deviceData.lastInitReading | defaultValue}}
|
||||
</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="剩余时长">-->
|
||||
<!-- 数据库:{{surplusTimeDesc(surplusTime).text}} / 设备:{{surplusTimeDesc(deviceData.remainTime).text}}-->
|
||||
<!-- </el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="剩余电量">-->
|
||||
<!-- {{deviceData.surplusEle | defaultValue}} 度-->
|
||||
<!-- </el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="最近更新时间">-->
|
||||
<!-- {{deviceData.lastPullTime | defaultValue }}-->
|
||||
<!-- </el-descriptions-item>-->
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
@ -159,29 +153,32 @@
|
|||
</el-row>
|
||||
</template>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<el-col :span="12">
|
||||
<el-statistic style="margin-bottom: 8px" title="时长(数据库)">
|
||||
<template #formatter>{{surplusTimeDesc(surplusTime).text}}</template>
|
||||
</el-statistic>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="12">
|
||||
<el-statistic style="margin-bottom: 8px" title="时长(设备)">
|
||||
<template #formatter>{{surplusTimeDesc(deviceData.remainTime).text}}</template>
|
||||
</el-statistic>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-statistic style="margin-bottom: 8px" title="电量" :value="deviceData.surplusEle" :precision="2" suffix="度"/>
|
||||
<el-col :span="12">
|
||||
<el-statistic style="margin-bottom: 8px" title="电量(数据库)" :value="deviceData.surplusEleDb" :precision="2" suffix="度"/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="12">
|
||||
<el-statistic style="margin-bottom: 8px" title="电量(设备)" :value="deviceData.surplusEle" :precision="2" suffix="度"/>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-statistic style="margin-bottom: 8px" title="电压" :value="deviceData.voltage" :precision="2" suffix="V"/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="12">
|
||||
<el-statistic style="margin-bottom: 8px" title="电流" :value="deviceData.electricity" :precision="2" suffix="A"/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="12">
|
||||
<el-statistic style="margin-bottom: 8px" title="功率" :value="deviceData.realTimePower" :precision="2" suffix="W"/>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="12">
|
||||
<el-statistic style="margin-bottom: 8px" title="电压系数">
|
||||
<template #formatter>{{deviceData.vxs | fix3 | defaultValue}}</template>
|
||||
</el-statistic>
|
||||
|
@ -276,7 +273,7 @@ import UserLink from '@/components/Business/SmUser/UserLink.vue'
|
|||
import { $serviceType, $view } from '@/utils/mixins'
|
||||
import Recharge from '@/views/system/recharge/index.vue'
|
||||
import BooleanTag from '@/components/BooleanTag/index.vue'
|
||||
import { DeviceOnlineStatus, DeviceServiceMode, ModelTag } from '@/utils/constants'
|
||||
import { DeviceOnlineStatus, DeviceServiceMode, ModelTag, DeviceOnlineType } from '@/utils/constants'
|
||||
import { isEmpty } from '@/utils'
|
||||
import BindMchButton from '@/views/system/device/components/BindMchButton.vue'
|
||||
import BindAgentButton from '@/views/system/device/components/BindAgentButton.vue'
|
||||
|
@ -287,7 +284,7 @@ import CommandLog from "@/views/ss/commandLog/index.vue";
|
|||
export default {
|
||||
name: 'Device/:deviceId',
|
||||
mixins: [$serviceType, $view],
|
||||
dicts: ['sm_device_status', 'sm_device_outage_way', 'sm_device_notice_way', 'sm_model_tag', 'sm_device_online_status', 'service_type', 'device_service_mode', 'time_unit', 'bonus_arrival_type'],
|
||||
dicts: ['sm_device_status', 'sm_device_outage_way', 'sm_device_notice_way', 'sm_model_tag', 'sm_device_online_status', 'service_type', 'device_service_mode', 'time_unit', 'bonus_arrival_type', 'device_user_opera_type'],
|
||||
components: {
|
||||
CommandLog,
|
||||
DeviceSetWifiDialog,
|
||||
|
@ -324,9 +321,20 @@ export default {
|
|||
},
|
||||
// 设备ID
|
||||
deviceId: null,
|
||||
DeviceOnlineStatus,
|
||||
ModelTag,
|
||||
DeviceServiceMode,
|
||||
DeviceOnlineType
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 计算数据库电量
|
||||
calcDbEle() {
|
||||
return (device) => {
|
||||
return device.expireEle - device.totalElectriQuantity;
|
||||
}
|
||||
},
|
||||
// MAC 列表
|
||||
macList() {
|
||||
let list = [];
|
||||
if (!isEmpty(this.deviceData.mac)) {
|
||||
|
@ -337,25 +345,19 @@ export default {
|
|||
}
|
||||
return list;
|
||||
},
|
||||
DeviceOnlineStatus() {
|
||||
return DeviceOnlineStatus
|
||||
},
|
||||
ModelTag() {
|
||||
return ModelTag
|
||||
},
|
||||
DeviceServiceMode() {
|
||||
return DeviceServiceMode
|
||||
},
|
||||
// 二维码文本
|
||||
qrCodeText() {
|
||||
return (device) => {
|
||||
return getWxIndexUrl({ s: device.deviceNo});
|
||||
}
|
||||
},
|
||||
// 剩余时长描述
|
||||
surplusTimeDesc() {
|
||||
return (second) => {
|
||||
return toDescriptionFromSecond(second);
|
||||
}
|
||||
},
|
||||
// 是否开启
|
||||
isOpen() {
|
||||
return this.deviceData != null && this.deviceData.powerStatus === '1';
|
||||
},
|
||||
|
@ -369,7 +371,7 @@ export default {
|
|||
},
|
||||
created() {
|
||||
this.deviceId = this.$route.params.deviceId;
|
||||
this.refreshIot(this.deviceId);
|
||||
this.refreshIot(this.deviceId, false, DeviceOnlineType.GET);
|
||||
},
|
||||
beforeDestroy() {
|
||||
clearInterval(this.timer);
|
||||
|
@ -529,9 +531,9 @@ export default {
|
|||
}
|
||||
},
|
||||
// 刷新设备信息
|
||||
refreshIot(deviceId, notice = false) {
|
||||
refreshIot(deviceId, notice = false, onlineType = DeviceOnlineType.GET) {
|
||||
this.loading = true;
|
||||
refreshIot(deviceId).then(res => {
|
||||
refreshIot(deviceId, onlineType).then(res => {
|
||||
if (res.code !== 200) {
|
||||
return this.$message.error(res.msg);
|
||||
}
|
||||
|
@ -560,7 +562,7 @@ export default {
|
|||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.remark-text {
|
||||
color: #ccc;
|
||||
margin-left: 1em;
|
||||
|
|
Loading…
Reference in New Issue
Block a user