From a25704662c0192a9581a1bb709411b3ac4c9e6ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=A2=A8=E5=A4=A7=E5=8F=94?= <494979559@qq.com>
Date: Sun, 6 Oct 2024 18:02:50 +0800
Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=8F=8CMAC=E5=9C=A8?=
 =?UTF-8?q?=E7=BA=BF=E7=8A=B6=E6=80=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/api/system/device.js                      | 21 +++++-
 src/utils/constants.js                        |  9 +++
 .../ss/suit/component/SuitEditDialog.vue      | 20 +++++
 src/views/ss/suit/index.vue                   |  8 ++
 src/views/system/device/detail.vue            | 73 ++++++++++++++++---
 src/views/system/device/index.vue             | 26 ++++---
 src/views/system/recharge/detail.vue          | 15 +++-
 7 files changed, 147 insertions(+), 25 deletions(-)

diff --git a/src/api/system/device.js b/src/api/system/device.js
index 3ec8e02..ffd69cc 100644
--- a/src/api/system/device.js
+++ b/src/api/system/device.js
@@ -78,10 +78,25 @@ export function refreshIot(deviceId) {
 }
 
 // 添加时长
-export function addTime(deviceId, amount) {
+export function addTime(deviceId, amount, timeUnit) {
   return request({
-    url: `/system/device/addTime/${deviceId}?amount=${amount}`,
-    method: 'put'
+    url: `/system/device/addTime/${deviceId}`,
+    method: 'put',
+    params: {
+      amount,
+      timeUnit
+    }
+  })
+}
+
+// 添加电量
+export function addEle(deviceId, amount) {
+  return request({
+    url: `/system/device/addEle/${deviceId}`,
+    method: 'put',
+    params: {
+      amount
+    }
   })
 }
 
diff --git a/src/utils/constants.js b/src/utils/constants.js
index 430928d..7538a89 100644
--- a/src/utils/constants.js
+++ b/src/utils/constants.js
@@ -193,3 +193,12 @@ export const BonusArrivalType = {
     return [this.PLATFORM]
   }
 }
+
+// 型号功能
+export const ModelTag = {
+  BLUETOOTH: "1", // 蓝牙
+  WIFI: "2", // WIFI
+  FOUR_G: "3", // 4G
+  GPS: "4", // GPS
+  ELE: "5", // 电量
+}
diff --git a/src/views/ss/suit/component/SuitEditDialog.vue b/src/views/ss/suit/component/SuitEditDialog.vue
index a3fc0db..bbd83b3 100644
--- a/src/views/ss/suit/component/SuitEditDialog.vue
+++ b/src/views/ss/suit/component/SuitEditDialog.vue
@@ -81,6 +81,26 @@
           <device-input v-model="form.deviceIds" multiple :before-open="beforeOpenDevice" :query="deviceQuery"/>
         </form-col>
       </el-row>
+      <el-row v-if="SuitFeeType.eleList().includes(form.feeType)">
+        <form-col :span="10" label="低功率关闭订单" prop="enabledLowPowerClose" label-width="9em">
+          <el-switch v-model="form.enabledLowPowerClose" active-text="开启" inactive-text="关闭"/>
+        </form-col>
+        <form-col :span="14" label="功率阈值" prop="lowPower" v-if="form.enabledLowPowerClose">
+          <el-input v-model="form.lowPower" placeholder="请输入功率阈值,低于该功率会自动关闭订单" type="number">
+            <template #append>瓦</template>
+          </el-input>
+        </form-col>
+      </el-row>
+      <el-row v-if="SuitFeeType.timeList().includes(form.feeType)">
+        <form-col :span="10" label="时长语音播报" prop="enabledVoice" label-width="8em">
+          <el-switch v-model="form.enabledVoice" active-text="开启" inactive-text="关闭"/>
+        </form-col>
+        <form-col :span="14" label="播报时机" prop="voiceMinutes" v-if="form.enabledVoice">
+          <el-input v-model="form.voiceMinutes" placeholder="请输入播报时机" type="number">
+            <template #append>分钟</template>
+          </el-input>
+        </form-col>
+      </el-row>
     </el-form>
     <div slot="footer" class="dialog-footer">
       <el-button type="primary" @click="submitForm">确 定</el-button>
diff --git a/src/views/ss/suit/index.vue b/src/views/ss/suit/index.vue
index e411fbb..7fb90e1 100644
--- a/src/views/ss/suit/index.vue
+++ b/src/views/ss/suit/index.vue
@@ -9,6 +9,14 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
+      <el-form-item label="用户名称" prop="userName">
+        <el-input
+          v-model="queryParams.userName"
+          placeholder="请输入用户名称"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
       <el-form-item label="套餐名称" prop="name">
         <el-input
           v-model="queryParams.name"
diff --git a/src/views/system/device/detail.vue b/src/views/system/device/detail.vue
index afa851a..dcb048d 100644
--- a/src/views/system/device/detail.vue
+++ b/src/views/system/device/detail.vue
@@ -6,9 +6,10 @@
           <el-card class="box-card" >
               <el-descriptions title="设备信息" :column="4">
                 <template slot="extra">
-                  <el-button size="small" plain icon="el-icon-plus" @click="handleAddElectricity">增加时长</el-button>
+                  <el-button size="small" plain icon="el-icon-plus" @click="handleAddTime">增加时长</el-button>
+                  <el-button size="small" plain icon="el-icon-plus" @click="handleAddEle" v-if="deviceData.modelTags.includes(ModelTag.ELE)">增加电量</el-button>
                   <el-button size="small" plain icon="el-icon-refresh" @click="handleReset">时长归零</el-button>
-                  <el-button size="small" plain icon="el-icon-refresh" @click="handleResetEle">电量归零</el-button>
+                  <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>
@@ -25,9 +26,13 @@
                 </template>
                 <el-descriptions-item label="MAC-1">
                   {{deviceData.mac | defaultValue}}
+                  <dict-tag :options="dict.type.sm_device_online_status" :value="deviceData.onlineStatus1" size="mini"/>
                 </el-descriptions-item>
                 <el-descriptions-item label="MAC-2">
                   {{deviceData.mac2 | defaultValue}}
+                  <template v-if="!isEmpty(deviceData.mac2)">
+                    <dict-tag :options="dict.type.sm_device_online_status" :value="deviceData.onlineStatus2" size="mini"/>
+                  </template>
                 </el-descriptions-item>
                 <el-descriptions-item label="SN">
                   {{deviceData.deviceNo | defaultValue}}
@@ -143,7 +148,13 @@
     <el-dialog title="增加时长" :visible.sync="showAddElectricity" center width="400px">
       <el-form :model="addElectricityForm" :rules="addRules">
         <el-form-item label="时长" prop="amount">
-          <el-input-number v-model="addElectricityForm.amount" style="width: 250px" controls-position="right" :step="1" step-strictly :min="0"/> 分钟
+          <el-input v-model="addElectricityForm.amount" :min="0" type="number">
+            <template #append>
+              <el-select v-model="addElectricityForm.timeUnit" style="width: 6em">
+                <el-option v-for="item in dict.type.time_unit" :key="item.value" :label="item.label" :value="item.value"/>
+              </el-select>
+            </template>
+          </el-input>
         </el-form-item>
       </el-form>
       <template #footer>
@@ -156,7 +167,16 @@
 
 <script>
 
-import { addTime, getDevice, refreshIot, resetDevice, resetEleDevice, switchDevice, unbind } from '@/api/system/device'
+import {
+  addEle,
+  addTime,
+  getDevice,
+  refreshIot,
+  resetDevice,
+  resetEleDevice,
+  switchDevice,
+  unbind
+} from '@/api/system/device'
 import LineChart from "@/views/dashboard/LineChart.vue";
 import RechargeRecord from "@/views/system/device/components/rechargeRecord.vue";
 import QrCode from "@/components/QrCode/index.vue";
@@ -175,12 +195,13 @@ 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 { DeviceServiceMode } from '@/utils/constants'
+import { DeviceServiceMode, ModelTag } from '@/utils/constants'
 import { isEmpty } from '@/utils'
 
 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'],
   components: {
     BooleanTag,
     Recharge,
@@ -190,15 +211,17 @@ export default {
     Suit,
     SuitList,
     TenantList, ResetRecord, BindRecord, ReadingRecord, MeterRecordReport, QrCode, RechargeRecord, LineChart},
-  dicts: ['sm_device_status', 'sm_device_outage_way', 'sm_device_notice_way', 'sm_model_tag', 'sm_device_online_status', 'service_type', 'device_service_mode'],
   data() {
     return {
       loading: false,
-      deviceData: {},
+      deviceData: {
+        modelTags: [],
+      },
       timer: null,
       surplusTime: 0, // 剩余时长
       addElectricityForm: {
-        amount: 0
+        amount: 0,
+        timeUnit: '3'
       },
       showAddElectricity: false,
       addRules: {
@@ -211,6 +234,9 @@ export default {
     }
   },
   computed: {
+    ModelTag() {
+      return ModelTag
+    },
     DeviceServiceMode() {
       return DeviceServiceMode
     },
@@ -317,12 +343,36 @@ export default {
         })
       })
     },
-    handleAddElectricity() {
+    handleAddTime() {
       this.resetAddElectricityForm();
       this.showAddElectricity = true;
     },
+    handleAddEle() {
+      this.$prompt('请输入增加的电量(度)', '增加电量', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        inputValidator: (val) => {
+          if (val < 0) {
+            return "输入的电量不允许小于0";
+          }
+          return true;
+        }
+      }).then(({ value }) => {
+        addEle(this.deviceData.deviceId, value).then(res => {
+          if (res.code === 200) {
+            this.$message.success('操作成功');
+            this.getDevice();
+          }
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '取消输入'
+        });
+      });
+    },
     submitAddElectricity() {
-      addTime(this.deviceData.deviceId, this.addElectricityForm.amount).then(res => {
+      addTime(this.deviceData.deviceId, this.addElectricityForm.amount, this.addElectricityForm.timeUnit).then(res => {
         if (res.code === 200) {
           this.$message.success('操作成功');
           this.showAddElectricity = false;
@@ -332,7 +382,8 @@ export default {
     },
     resetAddElectricityForm() {
       this.addElectricityForm = {
-        amount: 0
+        amount: 0,
+        timeUnit: '3'
       }
     },
     // 刷新设备信息
diff --git a/src/views/system/device/index.vue b/src/views/system/device/index.vue
index ee7fa0b..a3eddf9 100644
--- a/src/views/system/device/index.vue
+++ b/src/views/system/device/index.vue
@@ -194,14 +194,18 @@
           <dict-tag :options="dict.type.device_service_mode" :value="d.row.serviceMode"/>
         </template>
       </el-table-column>
-      <el-table-column label="所属用户" align="center" prop="userName" v-if="notHasView(views.user)">
-        <user-link slot-scope="d" :id="d.row.userId" :name="d.row.userName"/>
-      </el-table-column>
-      <el-table-column label="所属店铺" align="center" prop="storeName" >
-        <store-link slot-scope="d" :id="d.row.storeId" :name="d.row.storeName"/>
-      </el-table-column>
-      <el-table-column label="所属代理" align="center" prop="agentName" >
-        <user-link slot-scope="d" :id="d.row.agentId" :name="d.row.agentName"/>
+      <el-table-column label="归属信息" align="center" width="180">
+        <template slot-scope="d">
+          <template v-if="d.row.userId != null">
+            商户:<user-link :id="d.row.userId" :name="d.row.userName"/><br/>
+          </template>
+          <template v-if="d.row.storeId != null">
+            店铺:<store-link :id="d.row.storeId" :name="d.row.storeName"/><br/>
+          </template>
+          <template v-if="d.row.agentId != null">
+            代理:<user-link :id="d.row.agentId" :name="d.row.agentName"/>
+          </template>
+        </template>
       </el-table-column>
       <el-table-column label="服务费" align="center" prop="serviceRate" width="180">
         <template slot-scope="d">
@@ -209,10 +213,10 @@
             月费:{{d.row.monthFee | money | defaultValue}} 元 / 月 <br/>
           </template>
           <template v-if="d.row.serviceMode === DeviceServiceMode.DIRECT">
-            平台服务费:{{d.row.realServiceRate | money | defaultValue}} % <br/>
+            平台:{{d.row.realServiceRate | money | defaultValue}} % <br/>
           </template>
           <template v-if="d.row.serviceMode === DeviceServiceMode.AGENT">
-            代理服务费:{{d.row.agentServiceRate | money | defaultValue}} % <br/>
+            代理:{{d.row.agentServiceRate | money | defaultValue}} % <br/>
           </template>
         </template>
       </el-table-column>
@@ -410,6 +414,8 @@ export default {
       queryParams: {
         pageNum: 1,
         pageSize: 20,
+        orderByColumn: "createTime",
+        isAsc: "desc",
         storeName: null,
         deviceName: null,
         model: null,
diff --git a/src/views/system/recharge/detail.vue b/src/views/system/recharge/detail.vue
index ccf717d..cc81e8b 100644
--- a/src/views/system/recharge/detail.vue
+++ b/src/views/system/recharge/detail.vue
@@ -91,6 +91,8 @@
             <el-descriptions-item label="失效时间">{{detail.suitExpireTime | defaultValue}}</el-descriptions-item>
             <el-descriptions-item label="开始总用电量">{{detail.suitStartEle | money | defaultValue}} 度</el-descriptions-item>
             <el-descriptions-item label="结束总用电量">{{detail.suitEndEle | money | defaultValue}} 度</el-descriptions-item>
+          </el-descriptions>
+          <el-descriptions :column="4">
             <el-descriptions-item label="低功率自动关闭" :span="2">
               <template v-if="detail.suitEnableLowPowerClose">
                 <span style="color: green;margin-right: 0.5em;">已开启<i class="el-icon-check"/></span>
@@ -100,6 +102,16 @@
                 <span style="color: red">未启用<i class="el-icon-close"/></span>
               </template>
             </el-descriptions-item>
+
+            <el-descriptions-item label="语音播报" :span="2">
+              <template v-if="detail.suitEnabledVoid">
+                <span style="color: green;margin-right: 0.5em;">已开启<i class="el-icon-check"/></span>
+                设备时长低于 {{detail.suitVoidMinute | money | defaultValue}} 分钟将播放语音通知
+              </template>
+              <template v-else>
+                <span style="color: red">未启用<i class="el-icon-close"/></span>
+              </template>
+            </el-descriptions-item>
           </el-descriptions>
         </el-card>
       </el-col>
@@ -161,11 +173,12 @@ import Bonus from '@/views/ss/bonus/index.vue'
 import { $recharge } from '@/utils/mixins'
 import RefundDialog from '@/views/system/recharge/components/RefundDialog.vue'
 import { toDescriptionFromSecond } from '@/utils/date'
+import BooleanTag from '@/components/BooleanTag/index.vue'
 
 export default {
   name: 'Recharge/:billId',
   mixins: [$recharge],
-  components: { RefundDialog, Bonus, PayBill, UserLink, DeviceLink, Refund },
+  components: { BooleanTag, RefundDialog, Bonus, PayBill, UserLink, DeviceLink, Refund },
   dicts: ['channel_type','sm_transaction_bill_status', 'sm_transaction_bill_device_recharge_status', 'time_unit', 'suit_fee_mode', 'suit_fee_type', 'recharge_close_status', 'device_service_mode'],
   computed: {
     DeviceServiceMode() {