index.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. <template>
  2. <el-row :gutter="20">
  3. <!-- 左侧部门树 -->
  4. <el-col :span="4" :xs="24">
  5. <!-- <div><Icon icon="ep:edit" @click="shou(treeShow)"/> </div>-->
  6. <ContentWrap class="h-1/1" v-if="treeShow">
  7. <DeptTree @node-click="handleDeptNodeClick" />
  8. </ContentWrap>
  9. </el-col>
  10. <el-col :span="contentSpan" :xs="24">
  11. <ContentWrap>
  12. <!-- 搜索工作栏 -->
  13. <el-form
  14. class="-mb-15px"
  15. :model="queryParams"
  16. ref="queryFormRef"
  17. :inline="true"
  18. label-width="68px"
  19. >
  20. <el-form-item
  21. :label="t('iotDevice.yfCode')"
  22. prop="yfDeviceCode"
  23. style="margin-left: 20px"
  24. >
  25. <el-input
  26. v-model="queryParams.yfDeviceCode"
  27. :placeholder="t('iotDevice.yfCodeHolder')"
  28. clearable
  29. @keyup.enter="handleQuery"
  30. class="!w-200px"
  31. />
  32. </el-form-item>
  33. <el-form-item :label="t('iotDevice.code')" prop="deviceCode" style="margin-left: 20px">
  34. <el-input
  35. v-model="queryParams.deviceCode"
  36. :placeholder="t('iotDevice.codeHolder')"
  37. clearable
  38. @keyup.enter="handleQuery"
  39. class="!w-200px"
  40. />
  41. </el-form-item>
  42. <el-form-item :label="t('iotDevice.name')" prop="deviceName">
  43. <el-input
  44. v-model="queryParams.deviceName"
  45. :placeholder="t('iotDevice.nameHolder')"
  46. clearable
  47. @keyup.enter="handleQuery"
  48. class="!w-200px"
  49. />
  50. </el-form-item>
  51. <el-form-item label="车牌号" prop="carNo">
  52. <el-input
  53. v-model="queryParams.carNo"
  54. placeholder="请输入车牌号"
  55. clearable
  56. @keyup.enter="handleQuery"
  57. class="!w-200px"
  58. />
  59. </el-form-item>
  60. <el-form-item label="设备号" prop="deviceNo">
  61. <el-input
  62. v-model="queryParams.deviceNo"
  63. placeholder="请输入设备号"
  64. clearable
  65. @keyup.enter="handleQuery"
  66. class="!w-200px"
  67. />
  68. </el-form-item>
  69. <el-form-item :label="t('iotDevice.brand')" prop="brandName">
  70. <el-input
  71. v-model="queryParams.brandName"
  72. :placeholder="t('iotDevice.brandHolder')"
  73. clearable
  74. @keyup.enter="handleQuery"
  75. class="!w-200px"
  76. />
  77. </el-form-item>
  78. <el-form-item
  79. v-show="ifShow"
  80. :label="t('iotDevice.status')"
  81. label-width="85px"
  82. prop="deviceStatus"
  83. >
  84. <el-select
  85. v-model="queryParams.deviceStatus"
  86. :placeholder="t('iotDevice.statusHolder')"
  87. clearable
  88. class="!w-200px"
  89. >
  90. <el-option
  91. v-for="dict in getStrDictOptions(DICT_TYPE.PMS_DEVICE_STATUS)"
  92. :key="dict.value"
  93. :label="dict.label"
  94. :value="dict.value"
  95. />
  96. </el-select>
  97. </el-form-item>
  98. <el-form-item v-show="ifShow" :label="t('iotDevice.assets')" prop="assetProperty">
  99. <el-select
  100. v-model="queryParams.assetProperty"
  101. :placeholder="t('iotDevice.assetsHolder')"
  102. clearable
  103. class="!w-200px"
  104. >
  105. <el-option
  106. v-for="dict in getStrDictOptions(DICT_TYPE.PMS_ASSET_PROPERTY)"
  107. :key="dict.value"
  108. :label="dict.label"
  109. :value="dict.value"
  110. />
  111. </el-select>
  112. </el-form-item>
  113. <el-form-item
  114. v-show="ifShow"
  115. :label="t('deviceForm.category')"
  116. prop="assetClass"
  117. style="width: 15vw"
  118. >
  119. <el-tree-select
  120. v-model="queryParams.assetClass"
  121. :data="productClassifyList"
  122. :props="defaultProps"
  123. check-strictly
  124. node-key="id"
  125. :placeholder="t('deviceForm.categoryHolder')"
  126. filterable
  127. />
  128. </el-form-item>
  129. <el-form-item>
  130. <el-button v-if="!ifShow" @click="moreQuery(true)" type="warning"
  131. ><Icon icon="ep:search" class="mr-5px" /> {{ t('iotDevice.moreSearch') }}</el-button
  132. >
  133. <el-button v-if="ifShow" @click="moreQuery(false)" type="danger"
  134. ><Icon icon="ep:search" class="mr-5px" /> {{ t('iotDevice.closeSearch') }}</el-button
  135. >
  136. <el-button @click="handleQuery"
  137. ><Icon icon="ep:search" class="mr-5px" />{{ t('operationFill.search') }}</el-button
  138. >
  139. <el-button @click="resetQuery"
  140. ><Icon icon="ep:refresh" class="mr-5px" /> {{ t('operationFill.reset') }}</el-button
  141. >
  142. <el-button
  143. type="primary"
  144. plain
  145. @click="openForm('create', undefined, queryParams.deptId)"
  146. v-hasPermi="['rq:iot-device:create']"
  147. >
  148. <Icon icon="ep:plus" class="mr-5px" /> {{ t('operationFill.add') }}
  149. </el-button>
  150. <el-button
  151. type="success"
  152. plain
  153. @click="handleExport"
  154. :loading="exportLoading"
  155. v-hasPermi="['rq:iot-device:export']"
  156. >
  157. <Icon icon="ep:download" class="mr-5px" /> 导出
  158. </el-button>
  159. </el-form-item>
  160. </el-form>
  161. </ContentWrap>
  162. <!-- 列表 -->
  163. <ContentWrap>
  164. <el-table
  165. v-loading="loading"
  166. :data="list"
  167. :stripe="true"
  168. :show-overflow-tooltip="true"
  169. height="65vh"
  170. @sort-change="handleSortChange"
  171. >
  172. <el-table-column :label="t('iotDevice.serial')" width="70" align="center" fixed="left">
  173. <template #default="scope">
  174. {{ scope.$index + 1 }}
  175. </template>
  176. </el-table-column>
  177. <el-table-column
  178. :label="t('iotDevice.yfCode')"
  179. sortable
  180. align="center"
  181. prop="yfDeviceCode"
  182. width="150"
  183. fixed="left"
  184. >
  185. <template #header>
  186. <span
  187. style="display: inline-block"
  188. class="text-[#ad9399] w-[70px] text-[12px] cursor-pointer z-[999] justify-center flex items-center"
  189. >
  190. <el-popover placement="bottom" :width="250" trigger="click">
  191. <template #reference>
  192. <div class="flex items-center" @click.stop>
  193. <span> 油服编码 </span>
  194. <Icon
  195. icon="ep:arrow-down"
  196. class="ml-1 cursor-pointer text-[#ad9399]"
  197. @click.stop
  198. />
  199. </div>
  200. </template>
  201. <div class="flex items-center gap-2">
  202. <el-input
  203. v-model="queryParams.yfDeviceCode"
  204. placeholder="请输入油服编码"
  205. style="width: 180px"
  206. clearable
  207. @keyup.enter="handleQuery"
  208. />
  209. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  210. </div>
  211. </el-popover>
  212. </span>
  213. </template>
  214. </el-table-column>
  215. <el-table-column
  216. :label="t('iotDevice.code')"
  217. sortable
  218. align="center"
  219. prop="deviceCode"
  220. width="150"
  221. fixed="left"
  222. >
  223. <template #header>
  224. <span
  225. style="display: inline-block"
  226. class="text-[#ad9399] w-[70px] text-[12px] cursor-pointer z-[999] justify-center flex items-center"
  227. >
  228. <el-popover placement="bottom" :width="250" trigger="click">
  229. <template #reference>
  230. <div class="flex items-center" @click.stop>
  231. <span> 历史编码 </span> <Icon icon="ep:arrow-down" />
  232. </div>
  233. </template>
  234. <div class="flex items-center gap-2">
  235. <el-input
  236. v-model="queryParams.deviceCode"
  237. placeholder="请输入历史编码"
  238. style="width: 180px"
  239. clearable
  240. @keyup.enter="handleQuery"
  241. />
  242. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  243. </div>
  244. </el-popover>
  245. </span>
  246. </template>
  247. </el-table-column>
  248. <el-table-column
  249. :label="t('iotDevice.name')"
  250. sortable
  251. align="center"
  252. prop="deviceName"
  253. min-width="280"
  254. >
  255. <template #header>
  256. <span
  257. style="display: inline-block"
  258. class="text-[#ad9399] w-[70px] text-[12px] cursor-pointer z-[999] justify-center flex items-center"
  259. >
  260. <el-popover placement="bottom" :width="250" trigger="click">
  261. <template #reference>
  262. <div class="flex items-center" @click.stop>
  263. <span> 设备名称 </span> <Icon icon="ep:arrow-down" />
  264. </div>
  265. </template>
  266. <div class="flex items-center gap-2">
  267. <el-input
  268. v-model="queryParams.deviceName"
  269. placeholder="请输入设备名称"
  270. style="width: 180px"
  271. clearable
  272. @keyup.enter="handleQuery"
  273. />
  274. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  275. </div>
  276. </el-popover>
  277. </span>
  278. </template>
  279. <template #default="scope">
  280. <el-link :underline="false" type="primary" @click="handleDetail(scope.row.id)">
  281. {{ scope.row.deviceName }}
  282. </el-link>
  283. </template>
  284. </el-table-column>
  285. <el-table-column label="设备号" sortable align="center" prop="deviceNo" width="120">
  286. <template #header>
  287. <span
  288. style="display: inline-block"
  289. class="text-[#ad9399] w-[70px] text-[12px] cursor-pointer z-[999] justify-center flex items-center"
  290. >
  291. <el-popover placement="bottom" :width="250" trigger="click">
  292. <template #reference>
  293. <div class="flex items-center" @click.stop>
  294. <span> 设备号 </span> <Icon icon="ep:arrow-down" />
  295. </div>
  296. </template>
  297. <div class="flex items-center gap-2">
  298. <el-input
  299. v-model="queryParams.deviceNo"
  300. placeholder="请输入设备号"
  301. style="width: 180px"
  302. clearable
  303. @keyup.enter="handleQuery"
  304. />
  305. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  306. </div>
  307. </el-popover>
  308. </span>
  309. </template>
  310. </el-table-column>
  311. <el-table-column
  312. :label="t('iotDevice.dept')"
  313. align="center"
  314. prop="deptName"
  315. min-width="150"
  316. >
  317. <template #header>
  318. <span
  319. style="display: inline-block"
  320. class="text-[#ad9399] w-[70px] text-[12px] cursor-pointer z-[999] justify-center flex items-center"
  321. >
  322. <el-popover placement="bottom" :width="250" trigger="click">
  323. <template #reference>
  324. <div class="flex items-center" @click.stop>
  325. <span> {{ t('iotDevice.dept') }} </span> <Icon icon="ep:arrow-down" />
  326. </div>
  327. </template>
  328. <div class="flex items-center gap-2">
  329. <el-tree-select
  330. :teleported="false"
  331. v-model="queryParams.deptId"
  332. :data="deptList"
  333. :props="defaultProps"
  334. check-strictly
  335. node-key="id"
  336. filterable
  337. placeholder="请选择所在部门"
  338. @change="handleQuery"
  339. style="width: 200px"
  340. />
  341. </div>
  342. </el-popover>
  343. </span>
  344. </template>
  345. </el-table-column>
  346. <el-table-column
  347. :label="t('iotDevice.status')"
  348. align="center"
  349. prop="deviceStatus"
  350. min-width="150"
  351. >
  352. <template #header>
  353. <div class="flex items-center justify-center pb-[1px]">
  354. <el-dropdown @command="handleCommand">
  355. <span class="text-[#ad9399] text-[12px] cursor-pointer flex items-center">
  356. <span> 设备状态 </span> <Icon icon="ep:arrow-down" />
  357. </span>
  358. <template #dropdown>
  359. <el-dropdown-menu>
  360. <el-dropdown-item
  361. v-for="item in getStrDictOptions(DICT_TYPE.PMS_DEVICE_STATUS)"
  362. :key="item.label"
  363. :command="item.value"
  364. >{{ item.label }}</el-dropdown-item
  365. >
  366. </el-dropdown-menu>
  367. </template>
  368. </el-dropdown>
  369. </div>
  370. </template>
  371. <template #default="scope">
  372. <dict-tag :type="DICT_TYPE.PMS_DEVICE_STATUS" :value="scope.row.deviceStatus" />
  373. </template>
  374. </el-table-column>
  375. <el-table-column
  376. :label="t('iotDevice.assets')"
  377. align="center"
  378. prop="assetProperty"
  379. min-width="110"
  380. >
  381. <template #header>
  382. <div class="flex items-center justify-center pb-[1px]">
  383. <el-dropdown @command="handleAssetProperty">
  384. <span class="text-[#ad9399] text-[12px] cursor-pointer flex items-center">
  385. <span> 资产性质 </span> <Icon icon="ep:arrow-down" />
  386. </span>
  387. <template #dropdown>
  388. <el-dropdown-menu>
  389. <el-dropdown-item
  390. v-for="item in getStrDictOptions(DICT_TYPE.PMS_ASSET_PROPERTY)"
  391. :key="item.label"
  392. :command="item.value"
  393. >{{ item.label }}</el-dropdown-item
  394. >
  395. </el-dropdown-menu>
  396. </template>
  397. </el-dropdown>
  398. </div>
  399. </template>
  400. <template #default="scope">
  401. <dict-tag :type="DICT_TYPE.PMS_ASSET_PROPERTY" :value="scope.row.assetProperty" />
  402. </template>
  403. </el-table-column>
  404. <el-table-column
  405. :label="t('iotDevice.assetClass')"
  406. align="center"
  407. prop="assetClassName"
  408. min-width="170"
  409. >
  410. <template #header>
  411. <span
  412. style="display: inline-block"
  413. class="text-[#ad9399] w-[70px] text-[12px] cursor-pointer z-[999] justify-center flex items-center"
  414. >
  415. <el-popover placement="bottom" :width="250" trigger="click">
  416. <template #reference>
  417. <div class="flex items-center" @click.stop>
  418. <span> {{ t('iotDevice.assetClass') }} </span> <Icon icon="ep:arrow-down" />
  419. </div>
  420. </template>
  421. <div class="flex items-center gap-2">
  422. <el-input
  423. v-model="queryParams.assetClassName"
  424. placeholder="请输入资产类别"
  425. style="width: 180px"
  426. clearable
  427. />
  428. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  429. </div>
  430. </el-popover>
  431. </span>
  432. </template>
  433. </el-table-column>
  434. <el-table-column label="车牌号" align="center" prop="carNo" min-width="170">
  435. <template #header>
  436. <el-popover placement="bottom" :width="250" trigger="click">
  437. <template #reference>
  438. <div class="flex items-center" @click.stop>
  439. <span> 车牌号 </span> <Icon icon="ep:arrow-down" />
  440. </div>
  441. </template>
  442. <div class="flex items-center gap-2">
  443. <el-input
  444. v-model="queryParams.carNo"
  445. placeholder="请输入车牌号"
  446. style="width: 180px"
  447. clearable
  448. />
  449. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  450. </div>
  451. </el-popover>
  452. </template>
  453. </el-table-column>
  454. <el-table-column align="center" prop="manufacturer" min-width="200">
  455. <template #header>
  456. <el-popover placement="bottom" :width="250" trigger="click">
  457. <template #reference>
  458. <div class="flex items-center" @click.stop>
  459. <span>
  460. {{ t('deviceForm.mfg') }}
  461. </span>
  462. <Icon icon="ep:arrow-down" />
  463. </div>
  464. </template>
  465. <div class="flex items-center gap-2">
  466. <el-input
  467. v-model="queryParams.manufacturer"
  468. placeholder="请输入制造商"
  469. style="width: 180px"
  470. clearable
  471. />
  472. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  473. </div>
  474. </el-popover>
  475. </template>
  476. </el-table-column>
  477. <el-table-column
  478. :label="t('deviceForm.brand')"
  479. align="center"
  480. prop="brandName"
  481. min-width="150"
  482. >
  483. <template #header>
  484. <el-popover placement="bottom" :width="250" trigger="click">
  485. <template #reference>
  486. <div class="flex items-center" @click.stop>
  487. <span> {{ t('deviceForm.brand') }} </span> <Icon icon="ep:arrow-down" />
  488. </div>
  489. </template>
  490. <div class="flex items-center gap-2">
  491. <el-input
  492. v-model="queryParams.brandName"
  493. placeholder="请输入品牌"
  494. style="width: 180px"
  495. clearable
  496. />
  497. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  498. </div>
  499. </el-popover>
  500. </template>
  501. </el-table-column>
  502. <el-table-column
  503. :label="t('deviceForm.model')"
  504. align="center"
  505. prop="model"
  506. min-width="170"
  507. >
  508. <template #header>
  509. <el-popover placement="bottom" :width="250" trigger="click">
  510. <template #reference>
  511. <div class="flex items-center" @click.stop>
  512. <span> {{ t('deviceForm.model') }} </span> <Icon icon="ep:arrow-down" />
  513. </div>
  514. </template>
  515. <div class="flex items-center gap-2">
  516. <el-input
  517. v-model="queryParams.model"
  518. placeholder="请输入规格型号"
  519. style="width: 180px"
  520. clearable
  521. />
  522. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  523. </div>
  524. </el-popover>
  525. </template>
  526. </el-table-column>
  527. <el-table-column
  528. :label="t('devicePerson.rp')"
  529. align="center"
  530. prop="chargeName"
  531. min-width="170"
  532. >
  533. <template #header>
  534. <el-popover placement="bottom" :width="250" trigger="click">
  535. <template #reference>
  536. <div class="flex items-center" @click.stop>
  537. <span> {{ t('devicePerson.rp') }} </span> <Icon icon="ep:arrow-down" />
  538. </div>
  539. </template>
  540. <div class="flex items-center gap-2">
  541. <el-input
  542. v-model="queryParams.chargeName"
  543. placeholder="请输入责任人"
  544. style="width: 180px"
  545. clearable
  546. />
  547. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  548. </div>
  549. </el-popover>
  550. </template>
  551. </el-table-column>
  552. <el-table-column
  553. :label="t('deviceForm.useProject')"
  554. align="center"
  555. prop="useProject"
  556. min-width="170"
  557. >
  558. <template #header>
  559. <el-popover placement="bottom" :width="250" trigger="click">
  560. <template #reference>
  561. <div class="flex items-center">
  562. <span> {{ t('deviceForm.useProject') }} </span> <Icon icon="ep:arrow-down" />
  563. </div>
  564. </template>
  565. <div class="flex items-center gap-2">
  566. <el-input
  567. v-model="queryParams.useProject"
  568. placeholder="请输入使用项目"
  569. style="width: 180px"
  570. clearable
  571. />
  572. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  573. </div>
  574. </el-popover>
  575. </template>
  576. </el-table-column>
  577. <el-table-column
  578. :label="t('deviceForm.assetOwner')"
  579. align="center"
  580. prop="assetOwnership"
  581. min-width="170"
  582. >
  583. <template #header>
  584. <el-popover placement="bottom" :width="250" trigger="click">
  585. <template #reference>
  586. <div class="flex items-center">
  587. <span> {{ t('deviceForm.assetOwner') }} </span> <Icon icon="ep:arrow-down" />
  588. </div>
  589. </template>
  590. <div class="flex items-center gap-2">
  591. <el-input
  592. v-model="queryParams.assetOwnership"
  593. placeholder="请输入资产归属"
  594. style="width: 180px"
  595. clearable
  596. />
  597. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  598. </div>
  599. </el-popover>
  600. </template>
  601. </el-table-column>
  602. <el-table-column label="所在地点" align="center" prop="address" min-width="170">
  603. <template #header>
  604. <el-popover placement="bottom" :width="250" trigger="click">
  605. <template #reference>
  606. <div class="table-header-flex">
  607. <span>所在地点</span>
  608. <Icon icon="ep:arrow-down" @click.stop />
  609. </div>
  610. </template>
  611. <div class="flex items-center gap-2">
  612. <el-input
  613. v-model="queryParams.address"
  614. placeholder="请输入所在地点"
  615. style="width: 180px"
  616. clearable
  617. />
  618. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  619. </div>
  620. </el-popover>
  621. </template>
  622. </el-table-column>
  623. <el-table-column
  624. :label="t('operationFill.operation')"
  625. align="center"
  626. min-width="180px"
  627. fixed="right"
  628. >
  629. <template #default="scope">
  630. <el-button
  631. link
  632. type="primary"
  633. @click="openForm('update', scope.row.id)"
  634. v-hasPermi="['rq:iot-device:update']"
  635. >
  636. {{ t('iotDevice.update') }}
  637. </el-button>
  638. <el-button
  639. link
  640. type="danger"
  641. @click="handleDelete(scope.row.id)"
  642. v-hasPermi="['rq:iot-device:delete']"
  643. >
  644. {{ t('iotDevice.delete') }}
  645. </el-button>
  646. <!-- <el-button link type="warning" @click="handleUpload(scope.row.id)">-->
  647. <!-- {{t('iotDevice.upload')}}-->
  648. <!-- </el-button>-->
  649. </template>
  650. </el-table-column>
  651. </el-table>
  652. <!-- 分页 -->
  653. <Pagination
  654. :total="total"
  655. v-model:page="queryParams.pageNo"
  656. v-model:limit="queryParams.pageSize"
  657. @pagination="getList"
  658. />
  659. </ContentWrap>
  660. </el-col>
  661. </el-row>
  662. <!-- 表单弹窗:添加/修改 -->
  663. <!-- <IotDeviceForm ref="formRef" @success="getList" />-->
  664. </template>
  665. <script setup lang="ts">
  666. import download from '@/utils/download'
  667. import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
  668. import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
  669. import DeptTree from '@/views/system/user/DeptTree.vue'
  670. import { useCache } from '@/hooks/web/useCache'
  671. import { buildSortingField } from '@/utils'
  672. import { defaultProps, handleTree } from '@/utils/tree'
  673. import * as ProductClassifyApi from '@/api/pms/productclassify'
  674. import { useRefreshStore } from '@/store/modules/pms/refreshStore'
  675. import { Search } from '@element-plus/icons-vue'
  676. import * as DeptApi from '@/api/system/dept'
  677. /** 设备台账 列表 */
  678. defineOptions({ name: 'IotDevicePms' })
  679. const message = useMessage() // 消息弹窗
  680. const { t } = useI18n() // 国际化
  681. const { push } = useRouter() // 路由跳转
  682. const deptList = ref<Tree[]>([]) // 树形结构
  683. const refreshStore = useRefreshStore()
  684. const loading = ref(true) // 列表的加载中
  685. const ifShow = ref(false)
  686. const isDetail = ref(false) // 是否查看详情
  687. const list = ref<IotDeviceVO[]>([]) // 列表的数据
  688. const productClassifyList = ref<Tree[]>([]) // 树形结构
  689. const total = ref(0) // 列表的总页数
  690. const queryParams = reactive({
  691. pageNo: 1,
  692. pageSize: 10,
  693. useProject: undefined,
  694. assetOwnership: undefined,
  695. address: undefined,
  696. deviceCode: undefined,
  697. deviceName: undefined,
  698. brand: undefined,
  699. brandName: undefined,
  700. model: undefined,
  701. deptId: undefined,
  702. deviceStatus: undefined,
  703. assetProperty: undefined,
  704. picUrl: undefined,
  705. remark: undefined,
  706. manufacturerId: undefined,
  707. supplierId: undefined,
  708. manDate: [],
  709. nameplate: undefined,
  710. expires: undefined,
  711. plPrice: undefined,
  712. plDate: [],
  713. plYear: undefined,
  714. plStartDate: [],
  715. plMonthed: undefined,
  716. plAmounted: undefined,
  717. remainAmount: undefined,
  718. infoId: undefined,
  719. infoType: undefined,
  720. infoName: undefined,
  721. infoRemark: undefined,
  722. infoUrl: undefined,
  723. templateJson: undefined,
  724. creator: undefined,
  725. sortingFields: [],
  726. assetClass: undefined,
  727. yfDeviceCode: undefined,
  728. carNo: undefined,
  729. deviceNo: undefined,
  730. assetClassName: undefined,
  731. manufacturer: undefined,
  732. chargeName: undefined
  733. })
  734. const queryFormRef = ref() // 搜索的表单
  735. const exportLoading = ref(false) // 导出的加载中
  736. const contentSpan = ref(20)
  737. const treeShow = ref(true)
  738. const shou = (tree) => {
  739. treeShow.value = !tree
  740. if (tree) {
  741. contentSpan.value = 20
  742. } else {
  743. contentSpan.value = 24
  744. }
  745. }
  746. const handleCommand = (command) => {
  747. queryParams.deviceStatus = command
  748. getList()
  749. }
  750. const handleAssetProperty = (command) => {
  751. queryParams.assetProperty = command
  752. getList()
  753. }
  754. const handleSortChange = (params: any) => {
  755. //console.log(`排序字段: ${prop}, 排序方式: ${order}`);
  756. queryParams.sortingFields = []
  757. queryParams.sortingFields = [buildSortingField(params)]
  758. getList()
  759. }
  760. /** 查询列表 */
  761. const getList = async () => {
  762. loading.value = true
  763. try {
  764. const data = await IotDeviceApi.getIotDevicePage(queryParams)
  765. list.value = data.list
  766. total.value = data.total
  767. } finally {
  768. loading.value = false
  769. }
  770. }
  771. /** 处理部门被点击 */
  772. const handleDeptNodeClick = async (row) => {
  773. queryParams.deptId = row.id
  774. await getList()
  775. }
  776. /** 搜索按钮操作 */
  777. const handleQuery = () => {
  778. queryParams.pageNo = 1
  779. getList()
  780. }
  781. const moreQuery = (show) => {
  782. ifShow.value = show
  783. }
  784. /** 重置按钮操作 */
  785. const resetQuery = () => {
  786. queryParams.chargeName = undefined
  787. queryParams.address = undefined
  788. queryParams.manufacturer = undefined
  789. queryParams.useProject = undefined
  790. queryParams.model = undefined
  791. queryParams.assetOwnership = undefined
  792. queryFormRef.value.resetFields()
  793. handleQuery()
  794. }
  795. /** 添加/修改操作 */
  796. const formRef = ref()
  797. const openForm = (type: string, id?: number, deptId?: number) => {
  798. //修改
  799. if (typeof id === 'number') {
  800. push({ name: 'DeviceDetailEdit', params: { type, id }, query: { source: 'devicerouter' } })
  801. return
  802. }
  803. // 新增
  804. if (deptId) {
  805. push({ name: 'DeviceDetailAdd', params: { type, deptId }, query: { source: 'devicerouter' } })
  806. } else {
  807. push({ name: 'DeviceDetailAddd', params: {}, query: { source: 'devicerouter' } })
  808. }
  809. }
  810. /** 删除按钮操作 */
  811. const handleDelete = async (id: number) => {
  812. try {
  813. // 删除的二次确认
  814. await message.delConfirm()
  815. // 发起删除
  816. await IotDeviceApi.deleteIotDevice(id)
  817. message.success(t('common.delSuccess'))
  818. // 刷新列表
  819. await getList()
  820. } catch {}
  821. }
  822. const handleDetail = (id: number) => {
  823. push({ name: 'DeviceDetailInfo', params: { id } })
  824. }
  825. const handleUpload = (id: number) => {
  826. push({ name: 'DeviceUpload', params: { id } })
  827. }
  828. /** 导出按钮操作 */
  829. const handleExport = async () => {
  830. try {
  831. // 导出的二次确认
  832. await message.exportConfirm()
  833. // 发起导出
  834. exportLoading.value = true
  835. const data = await IotDeviceApi.exportIotDevice(queryParams)
  836. download.excel(data, '设备台账.xls')
  837. } catch {
  838. } finally {
  839. exportLoading.value = false
  840. }
  841. }
  842. const { wsCache } = useCache()
  843. /** 初始化 **/
  844. onMounted(async () => {
  845. productClassifyList.value = handleTree(
  846. await ProductClassifyApi.IotProductClassifyApi.getSimpleProductClassifyList()
  847. )
  848. const sort = {
  849. field: 'sortColumn',
  850. order: 'asc'
  851. }
  852. queryParams.sortingFields.push(sort)
  853. await getList()
  854. refreshStore.registerCallback('devicerouter', getList)
  855. deptList.value = handleTree(await DeptApi.getSimpleDeptList())
  856. })
  857. </script>
  858. <style scoped scss>
  859. ::v-deep .el-table__header-wrapper {
  860. position: sticky !important;
  861. width: 100%;
  862. top: 0px;
  863. z-index: 2000;
  864. }
  865. ::v-deep .el-tooltip__trigger {
  866. border: none !important;
  867. outline: none !important;
  868. }
  869. ::v-deep .el-table__header-wrapper {
  870. position: sticky !important;
  871. width: 100%;
  872. top: 0px;
  873. z-index: 2000;
  874. }
  875. ::v-deep .el-tooltip__trigger {
  876. border: none !important;
  877. outline: none !important;
  878. }
  879. /* 表头对齐样式 */
  880. .table-header-flex {
  881. display: flex !important;
  882. align-items: center !important;
  883. justify-content: center !important;
  884. height: 100% !important;
  885. width: 100% !important;
  886. padding: 0 !important;
  887. }
  888. .table-header-text {
  889. flex: 1;
  890. text-align: center;
  891. font-size: 12px;
  892. color: #606266;
  893. }
  894. .header-arrow-icon {
  895. margin-left: 4px;
  896. cursor: pointer;
  897. color: #ad9399;
  898. font-size: 12px;
  899. }
  900. .popover-content-flex {
  901. display: flex;
  902. align-items: center;
  903. gap: 8px;
  904. }
  905. /* 修复单元格对齐 */
  906. ::v-deep .el-table th,
  907. ::v-deep .el-table td {
  908. padding: 6px 0 !important;
  909. }
  910. ::v-deep .el-table th .cell,
  911. ::v-deep .el-table td .cell {
  912. display: flex;
  913. align-items: center;
  914. justify-content: center;
  915. height: 100%;
  916. padding: 0 8px;
  917. }
  918. </style>