deviceDetails.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. <template>
  2. <oa-scroll
  3. customClass="deviceDetails-container scroll-height"
  4. :isSticky="false"
  5. :refresherLoad="false"
  6. :refresherEnabled="false"
  7. :refresherEnabledTitle="false"
  8. :refresherDefaultStyle="'none'"
  9. :refresherThreshold="44"
  10. :refresherBackground="'#f5f6f7'"
  11. :data-theme="'theme-' + proxy.$settingStore.themeColor.name"
  12. >
  13. <template #default>
  14. <view style=" background: linear-gradient(to bottom, #FAFBFF, #E7F3FF);">
  15. <view class="flex" style="padding: 15px 15px 0">
  16. <view style="margin: auto auto auto 0">
  17. <view style="font-size: 16px;color:#000"> {{ detailData.deviceName }} </view>
  18. </view>
  19. <view style="margin: auto 0 auto 0">
  20. <view style="margin-left: 20px; font-size: 12px;color: #ffffff;padding: 2px 10px; border-radius: 20px; line-height: 20px;"
  21. :style="{ fontSize: '15px', backgroundColor: detailData.deviceStatus == 1 ? '#16bf00' : 'red' } ">
  22. {{ detailData.deviceStatus == 1 ? "在线" : "离线" }}
  23. </view>
  24. </view>
  25. </view>
  26. <view class=" p15" style="color:rgba(0,0,0,.7)" >
  27. <!-- <uni-section class="block mb10" title="基本信息" type="line"></uni-section> -->
  28. <view class=" basicBox p0">
  29. <u-empty v-if="dataList.length <= 0" text="暂无数据" mode="data" icon="http://cdn.uviewui.com/uview/empty/data.png"> </u-empty>
  30. <u-row>
  31. <u-col span="9" class="basicLeft">
  32. <view v-for="po in dataList" :key="po">
  33. <view style="text-align: left; padding: 0px 5px 0px 5px">{{ po.title }}:</view>
  34. <view style="text-align: left; padding: 0px 5px 0px 5px">{{ po.value }}</view>
  35. </view>
  36. </u-col>
  37. <u-col span="3">
  38. <image style="width: 80px; height: 80px; margin: auto 15px auto 0" :src="'/static/images/jg.png'" mode="aspectFill"></image>
  39. </u-col>
  40. </u-row>
  41. </view>
  42. </view>
  43. </view>
  44. <view class="bg-white p15 mb15">
  45. <!-- 分段器组件 -->
  46. <view class="app-subsection">
  47. <u-subsection :list="list" mode="subsection" :current="tabPosition" @change="tabPositionChange" style="width: 100%;font-size:16px"></u-subsection>
  48. </view>
  49. <view v-if="tabPosition == 1">
  50. <view class="flex" :style="{ color: proxy.$settingStore.themeColor.color }">
  51. <view class="ml10" style="margin-left: auto" @click="open">选择时间</view>
  52. <view class="ml10" @click="modalShow = true">筛选</view>
  53. </view>
  54. <chart :currentDateList="currentDateList"></chart>
  55. <!-- <view class="tableType1">
  56. <u-row>
  57. <u-col span="12">
  58. <view>指数</view>
  59. </u-col>
  60. </u-row>
  61. <u-row v-for="(co, index) in content4" :key="index">
  62. <u-col span="12">
  63. <view>{{ co.name1 }}</view>
  64. </u-col>
  65. </u-row>
  66. </view> -->
  67. </view>
  68. <view v-if="tabPosition == 0">
  69. <u-empty v-if="realTimeDataList.length <= 0" text="暂无数据" mode="data" icon="http://cdn.uviewui.com/uview/empty/data.png"> </u-empty>
  70. <view v-else class="flex" style="flex-wrap: wrap; line-height: 36px;font-size:16px">
  71. <view style="width: 100%;border-bottom:1px solid #F3F3F3" v-for="realTime in realTimeDataList" :key="realTime">
  72. {{ realTime.attributeName + ":" }}
  73. <view style="color:#000;display:inline-block;">{{ realTime.value }}</view>
  74. {{ realTime.attributeUnit ? realTime.attributeUnit : "" }}
  75. </view>
  76. </view>
  77. </view>
  78. <view v-if="tabPosition == 2">
  79. <br/>
  80. <u-row
  81. gutter="10"
  82. style="justify-content:center"
  83. >
  84. <u-empty v-if="deviceCotrolList.length <= 0" text="暂无数据" mode="data" icon="http://cdn.uviewui.com/uview/empty/data.png"> </u-empty>
  85. <u-col v-else span="3" v-for="(item, index) in deviceCotrolList" :key="index">
  86. <view class="demo-layout" @click="goAction(item)">{{ item.commandName }}</view>
  87. </u-col>
  88. </u-row>
  89. <br/>
  90. <br/>
  91. <br/>
  92. </view>
  93. </view>
  94. <u-modal :show="modalShow" @confirm="modalShow = false" @close="modalShow = false" :closeOnClickOverlay="true">
  95. <view class="slot-content">
  96. <u-checkbox-group
  97. v-model="checkboxValueList"
  98. @change="
  99. (val) => {
  100. checkboxChange(val);
  101. }
  102. "
  103. :size="14"
  104. :activeColor="proxy.$settingStore.themeColor.color"
  105. >
  106. <u-checkbox class="mb10" v-for="option in checkboxDataList" :key="option" :label="option.attributeName" :name="option.attributeCode"> </u-checkbox>
  107. </u-checkbox-group>
  108. </view>
  109. </u-modal>
  110. <uni-calendar ref="calendar" class="uni-calendar--hook" :clearDate="false" :insert="false" :lunar="false" :range="true" @confirm="calendarConfirm" />
  111. </template>
  112. </oa-scroll>
  113. </template>
  114. <script setup>
  115. /*----------------------------------依赖引入-----------------------------------*/
  116. import { onLoad, onShow, onReady, onHide, onLaunch, onNavigationBarButtonTap, onPageScroll } from "@dcloudio/uni-app";
  117. import { ref, reactive, computed, getCurrentInstance, toRefs, inject,watch } from "vue";
  118. /*----------------------------------接口引入-----------------------------------*/
  119. import { dmpDeviceInfo,dmpProductAttribute, historyMetrics, last,getList } from "@/api/business/fireIot/deviceManage.js";
  120. /*----------------------------------组件引入-----------------------------------*/
  121. import chart from "./chart.vue";
  122. /*----------------------------------store引入-----------------------------------*/
  123. import { useStores, commonStores } from "@/store/modules/index";
  124. /*----------------------------------公共方法引入-----------------------------------*/
  125. /*----------------------------------公共变量-----------------------------------*/
  126. const { proxy } = getCurrentInstance();
  127. const commonStore = commonStores();
  128. /*----------------------------------变量声明-----------------------------------*/
  129. const dataList = ref([
  130. {
  131. title: "设备类型",
  132. value: commonStore.deviceDetailsArray.productName,
  133. },
  134. {
  135. title: "设备编号",
  136. value: commonStore.deviceDetailsArray.deviceId,
  137. },
  138. {
  139. title: "物联网卡号",
  140. value: commonStore.deviceDetailsArray.simCode,
  141. },
  142. {
  143. title: "安装位置",
  144. value: commonStore.deviceDetailsArray.installAddress,
  145. },
  146. {
  147. title: "添加时间",
  148. value: commonStore.deviceDetailsArray.createdTime ? commonStore.deviceDetailsArray.createdTime.replace("T", " ") : "",
  149. },
  150. ]);
  151. const checkboxDataList = ref([]); //复选框渲染数据存储
  152. const checkboxValueList = ref([]); //复选框值数据存储
  153. const realTimeDataList = ref([]); //实时数据存储
  154. const tableDataList = ref([]); //表格数据存储
  155. const currentDateList = ref([]); //图表数据存储
  156. const modalShow = ref(false); //模态框显示隐藏
  157. const calendar = ref(null);
  158. const calendarStartTime = ref(""); //日历开始时间
  159. const calendarEndTime = ref(""); //日历结束时间
  160. const productId = ref(0); //产品id
  161. const deviceId = ref(0); //设备id
  162. const detailData = ref({}) //设备详情数据存储
  163. const deviceCotrolList = ref([]) //设备调试数据存储
  164. function open() {
  165. calendar.value.open();
  166. }
  167. /**
  168. * @初始化
  169. */
  170. /**
  171. * @详情查询
  172. * @api接口查询
  173. */
  174. function dmpDeviceInfoApi() {
  175. dmpDeviceInfo({ productId: productId.value, deviceId:deviceId.value,current: 1, size: 10 }).then((requset) => {
  176. if (requset.status === "SUCCESS") {
  177. dataList.value[0].value = requset.data.records[0].deviceName;
  178. dataList.value[1].value = requset.data.records[0].deviceId;
  179. dataList.value[2].value = requset.data.records[0].simCode ;
  180. dataList.value[3].value = requset.data.records[0].installAddress
  181. dataList.value[4].value = requset.data.records[0].createdTime ? requset.data.records[0].createdTime.replace("T", " ") : requset.data.records[0].createdTime;
  182. detailData.value=requset.data.records[0]
  183. }
  184. });
  185. }
  186. function init() {
  187. dmpDeviceInfoApi();
  188. dmpProductAttribute({
  189. current: 1,
  190. size: 100,
  191. attributeName: "",
  192. productId: productId.value,
  193. deviceId:deviceId.value,
  194. }).then((requset) => {
  195. if (requset.status === "SUCCESS") {
  196. checkboxDataList.value = requset.data.records;
  197. realTimeDataList.value = requset.data.records;
  198. var array = [];
  199. requset.data.records.forEach((el) => {
  200. array.push(el.attributeCode);
  201. });
  202. last({
  203. deviceUUId: detailData.value.deviceUuid,
  204. metrics: array,
  205. }).then((requsets) => {
  206. if (requsets.status === "SUCCESS") {
  207. realTimeDataList.value.forEach((el) => {
  208. el.value = 0;
  209. requsets.data.forEach((e) => {
  210. if (el.attributeCode === e.metric) {
  211. el.value = e.value;
  212. }
  213. });
  214. });
  215. }
  216. });
  217. }
  218. });
  219. }
  220. function deviceControlData(){
  221. getList({
  222. current: 1,
  223. size: 10,
  224. productCode:detailData.value.productCode,
  225. }).then((response) => {
  226. deviceCotrolList.value=response.data.records
  227. // console.log(response.data.records)
  228. // dataList.value = response.data.records;
  229. // state.total = response.data.total;
  230. // state.loading = false;
  231. });
  232. }
  233. /**
  234. * @tabs切换change事件
  235. */
  236. const list = ref(["实时数据", "历史数据","设备调试"]);
  237. const tabPosition = ref(0);
  238. function tabPositionChange(index) {
  239. tabPosition.value = index;
  240. }
  241. /**
  242. * @checkbox选中change事件
  243. */
  244. function checkboxChange(value) {
  245. checkboxValueList.value = value;
  246. historyMetricsApi();
  247. }
  248. /**
  249. * @日历确认事件
  250. */
  251. function calendarConfirm(e) {
  252. calendarStartTime.value = e.range.before;
  253. calendarEndTime.value = e.range.after ? e.range.after : e.range.before;
  254. historyMetricsApi();
  255. }
  256. /**
  257. * @设备多属性历史数据请求
  258. * @api接口请求
  259. */
  260. function historyMetricsApi() {
  261. historyMetrics({
  262. startTime: calendarStartTime.value?calendarStartTime.value+' 00:00:00':calendarStartTime.value,
  263. endTime: calendarEndTime.value?calendarEndTime.value+' 23:59:59':calendarEndTime.value,
  264. deviceUUId: detailData.value.deviceUuid,
  265. // deviceId: commonStore.deviceDetailsArray.deviceId,
  266. // deviceType: commonStore.deviceDetailsArray.deviceType,
  267. metrics: checkboxValueList.value,
  268. }).then((requset) => {
  269. if (requset.status === "SUCCESS") {
  270. currentDateList.value = requset.data;
  271. checkboxDataList.value.forEach((el) => {
  272. currentDateList.value.forEach((e) => {
  273. if (el.attributeCode == e.metric) {
  274. e.attributeName = el.attributeName;
  275. }
  276. });
  277. });
  278. currentDateList.value.forEach((el) => {
  279. if (el.metricItems.length > 0) {
  280. el.data = [];
  281. el.metricItems.forEach((e) => {
  282. el.data.push([e.timestamp, e.value]);
  283. });
  284. } else {
  285. el.data = [];
  286. }
  287. });
  288. }
  289. });
  290. }
  291. function goAction(row) {
  292. proxy.$tab.navigateTo(`/pages/business/fireIot/deviceManage/components/goAction?productCode=${row.productCode}&commandCode=${row.commandCode}&deviceId=${deviceId.value}`);
  293. }
  294. onReady(() => {});
  295. onShow(() => {
  296. //设置导航栏颜色
  297. uni.setNavigationBarColor({
  298. frontColor: '#000000', //字体颜色
  299. backgroundColor: '#ffffff' //背景颜色
  300. })
  301. //调用系统主题颜色
  302. // proxy.$settingStore.systemThemeColor([1]);
  303. });
  304. onLoad((options) => {
  305. if ("deviceId" in options) {
  306. deviceId.value = options.deviceId;
  307. }
  308. if ("productId" in options) {
  309. productId.value = parseInt(options.productId);
  310. init();
  311. }
  312. });
  313. watch(
  314. () => tabPosition.value,
  315. (val) => {
  316. if(val==2){
  317. deviceControlData()
  318. }
  319. }
  320. );
  321. </script>
  322. <style lang="scss" scoped>
  323. uni-page-body{
  324. background-color: #fff;
  325. }
  326. .basicBox{
  327. font-size:16px;
  328. .basicLeft view{
  329. display:inline-block;
  330. line-height:30px;
  331. .subsection__item__text{
  332. font-size:16px!important
  333. }
  334. }
  335. }
  336. .app-subsection {
  337. display: flex;
  338. margin-bottom: 10px;
  339. // padding: 0px 5rem;
  340. }
  341. .demo-layout{
  342. border:1px solid #e0e0e0;
  343. padding:15px 10px;
  344. box-shadow:0px 0px 12px rgba(0, 0, 0, 0.12);
  345. }
  346. </style>