index.vue 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  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 cursor-pointer" @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 cursor-pointer gap-1" @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 cursor-pointer gap-1" @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 cursor-pointer gap-1" @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 cursor-pointer gap-1" @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 gap-1">
  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 gap-1">
  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 cursor-pointer gap-1" @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-tree-select
  423. :teleported="false"
  424. v-model="queryParams.assetClass"
  425. :data="productClassifyList"
  426. :props="defaultProps"
  427. check-strictly
  428. node-key="id"
  429. :placeholder="t('deviceForm.categoryHolder')"
  430. filterable
  431. @change="handleQuery"
  432. />
  433. </div>
  434. </el-popover>
  435. </span>
  436. </template>
  437. </el-table-column>
  438. <el-table-column label="车牌号" align="center" prop="carNo" min-width="170">
  439. <template #header>
  440. <el-popover placement="bottom" :width="250" trigger="click">
  441. <template #reference>
  442. <div class="flex items-center cursor-pointer gap-1" @click.stop>
  443. <span> 车牌号 </span> <Icon icon="ep:arrow-down" />
  444. </div>
  445. </template>
  446. <div class="flex items-center gap-2">
  447. <el-input
  448. v-model="queryParams.carNo"
  449. placeholder="请输入车牌号"
  450. style="width: 180px"
  451. clearable
  452. />
  453. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  454. </div>
  455. </el-popover>
  456. </template>
  457. </el-table-column>
  458. <el-table-column align="center" prop="manufacturer" min-width="200">
  459. <template #header>
  460. <el-popover placement="bottom" :width="250" trigger="click">
  461. <template #reference>
  462. <div class="flex items-center cursor-pointer gap-1" @click.stop>
  463. <span>
  464. {{ t('deviceForm.mfg') }}
  465. </span>
  466. <Icon icon="ep:arrow-down" />
  467. </div>
  468. </template>
  469. <div class="flex items-center gap-2">
  470. <el-select
  471. v-model="queryParams.manufacturerId"
  472. style="width: 220px"
  473. filterable
  474. :teleported="false"
  475. :loading="brandList.length === 0"
  476. loading-text="数据加载中..."
  477. @change="handleQuery"
  478. @visible-change="handleBrandChange"
  479. >
  480. <el-option
  481. v-for="item in brandList"
  482. :key="item.id"
  483. :label="item.name"
  484. :value="item.id"
  485. style="width: 300px"
  486. />
  487. </el-select>
  488. </div>
  489. </el-popover>
  490. </template>
  491. </el-table-column>
  492. <el-table-column
  493. :label="t('deviceForm.brand')"
  494. align="center"
  495. prop="brandName"
  496. min-width="150"
  497. >
  498. <template #header>
  499. <el-popover placement="bottom" :width="250" trigger="click">
  500. <template #reference>
  501. <div class="flex items-center cursor-pointer gap-1" @click.stop>
  502. <span> {{ t('deviceForm.brand') }} </span> <Icon icon="ep:arrow-down" />
  503. </div>
  504. </template>
  505. <div class="flex items-center gap-2">
  506. <el-input
  507. v-model="queryParams.brandName"
  508. placeholder="请输入品牌"
  509. style="width: 180px"
  510. clearable
  511. />
  512. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  513. </div>
  514. </el-popover>
  515. </template>
  516. </el-table-column>
  517. <el-table-column
  518. :label="t('deviceForm.model')"
  519. align="center"
  520. prop="model"
  521. min-width="170"
  522. >
  523. <template #header>
  524. <el-popover placement="bottom" :width="250" trigger="click">
  525. <template #reference>
  526. <div class="flex items-center cursor-pointer gap-1" @click.stop>
  527. <span> {{ t('deviceForm.model') }} </span> <Icon icon="ep:arrow-down" />
  528. </div>
  529. </template>
  530. <div class="flex items-center gap-2">
  531. <el-input
  532. v-model="queryParams.model"
  533. placeholder="请输入规格型号"
  534. style="width: 180px"
  535. clearable
  536. />
  537. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  538. </div>
  539. </el-popover>
  540. </template>
  541. </el-table-column>
  542. <el-table-column
  543. :label="t('devicePerson.rp')"
  544. align="center"
  545. prop="chargeName"
  546. min-width="170"
  547. >
  548. <template #header>
  549. <el-popover placement="bottom" :width="250" trigger="click">
  550. <template #reference>
  551. <div class="flex items-center cursor-pointer gap-1" @click.stop>
  552. <span> {{ t('devicePerson.rp') }} </span> <Icon icon="ep:arrow-down" />
  553. </div>
  554. </template>
  555. <div class="flex items-center gap-2">
  556. <el-input
  557. v-model="queryParams.chargeName"
  558. placeholder="请输入责任人"
  559. style="width: 180px"
  560. clearable
  561. />
  562. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  563. </div>
  564. </el-popover>
  565. </template>
  566. </el-table-column>
  567. <el-table-column
  568. :label="t('deviceForm.useProject')"
  569. align="center"
  570. prop="useProject"
  571. min-width="170"
  572. >
  573. <template #header>
  574. <el-popover placement="bottom" :width="250" trigger="click">
  575. <template #reference>
  576. <div class="flex items-center cursor-pointer gap-1">
  577. <span> {{ t('deviceForm.useProject') }} </span> <Icon icon="ep:arrow-down" />
  578. </div>
  579. </template>
  580. <div class="flex items-center gap-2">
  581. <el-input
  582. v-model="queryParams.useProject"
  583. placeholder="请输入使用项目"
  584. style="width: 180px"
  585. clearable
  586. />
  587. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  588. </div>
  589. </el-popover>
  590. </template>
  591. </el-table-column>
  592. <el-table-column
  593. :label="t('deviceForm.assetOwner')"
  594. align="center"
  595. prop="assetOwnership"
  596. min-width="170"
  597. >
  598. <template #header>
  599. <el-popover placement="bottom" :width="250" trigger="click">
  600. <template #reference>
  601. <div class="flex items-center cursor-pointer gap-1">
  602. <span> {{ t('deviceForm.assetOwner') }} </span>
  603. <Icon icon="ep:arrow-down" />
  604. </div>
  605. </template>
  606. <div class="flex items-center gap-2">
  607. <el-input
  608. v-model="queryParams.assetOwnership"
  609. placeholder="请输入资产归属"
  610. style="width: 180px"
  611. clearable
  612. />
  613. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  614. </div>
  615. </el-popover>
  616. </template>
  617. </el-table-column>
  618. <el-table-column label="所在地点" align="center" prop="address" min-width="170">
  619. <template #header>
  620. <el-popover placement="bottom" :width="250" trigger="click">
  621. <template #reference>
  622. <div class="table-header-flex cursor-pointer">
  623. <span class="pr-1">所在地点</span>
  624. <Icon icon="ep:arrow-down" @click.stop />
  625. </div>
  626. </template>
  627. <div class="flex items-center gap-2">
  628. <el-input
  629. v-model="queryParams.address"
  630. placeholder="请输入所在地点"
  631. style="width: 180px"
  632. clearable
  633. />
  634. <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
  635. </div>
  636. </el-popover>
  637. </template>
  638. </el-table-column>
  639. <el-table-column
  640. :label="t('operationFill.operation')"
  641. align="center"
  642. min-width="180px"
  643. fixed="right"
  644. >
  645. <template #default="scope">
  646. <el-button
  647. link
  648. type="primary"
  649. @click="openForm('update', scope.row.id)"
  650. v-hasPermi="['rq:iot-device:update']"
  651. >
  652. {{ t('iotDevice.update') }}
  653. </el-button>
  654. <el-button
  655. link
  656. type="danger"
  657. @click="handleDelete(scope.row.id)"
  658. v-hasPermi="['rq:iot-device:delete']"
  659. >
  660. {{ t('iotDevice.delete') }}
  661. </el-button>
  662. <!-- <el-button link type="warning" @click="handleUpload(scope.row.id)">-->
  663. <!-- {{t('iotDevice.upload')}}-->
  664. <!-- </el-button>-->
  665. </template>
  666. </el-table-column>
  667. </el-table>
  668. <!-- 分页 -->
  669. <Pagination
  670. :total="total"
  671. v-model:page="queryParams.pageNo"
  672. v-model:limit="queryParams.pageSize"
  673. @pagination="getList"
  674. />
  675. </ContentWrap>
  676. </el-col>
  677. </el-row>
  678. <!-- 表单弹窗:添加/修改 -->
  679. <!-- <IotDeviceForm ref="formRef" @success="getList" />-->
  680. </template>
  681. <script setup lang="ts">
  682. import download from '@/utils/download'
  683. import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
  684. import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
  685. import DeptTree from '@/views/system/user/DeptTree.vue'
  686. import { buildSortingField } from '@/utils'
  687. import { defaultProps, handleTree } from '@/utils/tree'
  688. import * as ProductClassifyApi from '@/api/pms/productclassify'
  689. import { useRefreshStore } from '@/store/modules/pms/refreshStore'
  690. import { Search } from '@element-plus/icons-vue'
  691. import * as DeptApi from '@/api/system/dept'
  692. /** 设备台账 列表 */
  693. defineOptions({ name: 'IotDevicePms' })
  694. const message = useMessage() // 消息弹窗
  695. const { t } = useI18n() // 国际化
  696. const { push } = useRouter() // 路由跳转
  697. const deptList = ref<Tree[]>([]) // 树形结构
  698. const refreshStore = useRefreshStore()
  699. const loading = ref(true) // 列表的加载中
  700. const ifShow = ref(false)
  701. const isDetail = ref(false) // 是否查看详情
  702. const list = ref<IotDeviceVO[]>([]) // 列表的数据
  703. const productClassifyList = ref<Tree[]>([]) // 树形结构
  704. const total = ref(0) // 列表的总页数
  705. const queryParams = reactive({
  706. pageNo: 1,
  707. pageSize: 10,
  708. useProject: undefined,
  709. assetOwnership: undefined,
  710. address: undefined,
  711. deviceCode: undefined,
  712. deviceName: undefined,
  713. brand: undefined,
  714. brandName: undefined,
  715. model: undefined,
  716. deptId: undefined,
  717. deviceStatus: undefined,
  718. assetProperty: undefined,
  719. picUrl: undefined,
  720. remark: undefined,
  721. manufacturerId: undefined,
  722. supplierId: undefined,
  723. manDate: [],
  724. nameplate: undefined,
  725. expires: undefined,
  726. plPrice: undefined,
  727. plDate: [],
  728. plYear: undefined,
  729. plStartDate: [],
  730. plMonthed: undefined,
  731. plAmounted: undefined,
  732. remainAmount: undefined,
  733. infoId: undefined,
  734. infoType: undefined,
  735. infoName: undefined,
  736. infoRemark: undefined,
  737. infoUrl: undefined,
  738. templateJson: undefined,
  739. creator: undefined,
  740. sortingFields: [],
  741. assetClass: undefined,
  742. yfDeviceCode: undefined,
  743. carNo: undefined,
  744. deviceNo: undefined,
  745. manufacturer: undefined,
  746. chargeName: undefined
  747. })
  748. const queryFormRef = ref() // 搜索的表单
  749. const exportLoading = ref(false) // 导出的加载中
  750. const contentSpan = ref(20)
  751. const treeShow = ref(true)
  752. const brandList = ref([])
  753. const shou = (tree) => {
  754. treeShow.value = !tree
  755. if (tree) {
  756. contentSpan.value = 20
  757. } else {
  758. contentSpan.value = 24
  759. }
  760. }
  761. const handleCommand = (command) => {
  762. queryParams.deviceStatus = command
  763. getList()
  764. }
  765. const handleAssetProperty = (command) => {
  766. queryParams.assetProperty = command
  767. getList()
  768. }
  769. const handleSortChange = (params: any) => {
  770. //console.log(`排序字段: ${prop}, 排序方式: ${order}`);
  771. queryParams.sortingFields = []
  772. queryParams.sortingFields = [buildSortingField(params)]
  773. getList()
  774. }
  775. /** 查询列表 */
  776. const getList = async () => {
  777. loading.value = true
  778. try {
  779. const data = await IotDeviceApi.getIotDevicePage(queryParams)
  780. list.value = data.list
  781. total.value = data.total
  782. } finally {
  783. loading.value = false
  784. }
  785. }
  786. /** 处理部门被点击 */
  787. const handleDeptNodeClick = async (row) => {
  788. queryParams.deptId = row.id
  789. await getList()
  790. }
  791. /** 搜索按钮操作 */
  792. const handleQuery = () => {
  793. queryParams.pageNo = 1
  794. getList()
  795. }
  796. const moreQuery = (show) => {
  797. ifShow.value = show
  798. }
  799. /** 重置按钮操作 */
  800. const resetQuery = () => {
  801. queryParams.chargeName = undefined
  802. queryParams.address = undefined
  803. queryParams.manufacturer = undefined
  804. queryParams.useProject = undefined
  805. queryParams.model = undefined
  806. queryParams.assetOwnership = undefined
  807. queryParams.manufacturerId = undefined
  808. queryFormRef.value.resetFields()
  809. handleQuery()
  810. }
  811. /** 添加/修改操作 */
  812. const formRef = ref()
  813. const openForm = (type: string, id?: number, deptId?: number) => {
  814. //修改
  815. if (typeof id === 'number') {
  816. push({ name: 'DeviceDetailEdit', params: { type, id }, query: { source: 'devicerouter' } })
  817. return
  818. }
  819. // 新增
  820. if (deptId) {
  821. push({ name: 'DeviceDetailAdd', params: { type, deptId }, query: { source: 'devicerouter' } })
  822. } else {
  823. push({ name: 'DeviceDetailAddd', params: {}, query: { source: 'devicerouter' } })
  824. }
  825. }
  826. /** 删除按钮操作 */
  827. const handleDelete = async (id: number) => {
  828. try {
  829. // 删除的二次确认
  830. await message.delConfirm()
  831. // 发起删除
  832. await IotDeviceApi.deleteIotDevice(id)
  833. message.success(t('common.delSuccess'))
  834. // 刷新列表
  835. await getList()
  836. } catch {}
  837. }
  838. const handleDetail = (id: number) => {
  839. push({ name: 'DeviceDetailInfo', params: { id } })
  840. }
  841. const handleBrandChange = async (visible) => {
  842. if (visible && brandList.value.length === 0) {
  843. brandList.value = await IotDeviceApi.getDeviceBrand()
  844. }
  845. }
  846. /** 导出按钮操作 */
  847. const handleExport = async () => {
  848. try {
  849. // 导出的二次确认
  850. await message.exportConfirm()
  851. // 发起导出
  852. exportLoading.value = true
  853. const data = await IotDeviceApi.exportIotDevice(queryParams)
  854. download.excel(data, '设备台账.xls')
  855. } catch {
  856. } finally {
  857. exportLoading.value = false
  858. }
  859. }
  860. /** 初始化 **/
  861. onMounted(async () => {
  862. productClassifyList.value = handleTree(
  863. await ProductClassifyApi.IotProductClassifyApi.getSimpleProductClassifyList()
  864. )
  865. // brandList.value = await IotDeviceApi.getDeviceBrand()
  866. const sort = {
  867. field: 'sortColumn',
  868. order: 'asc'
  869. }
  870. queryParams.sortingFields.push(sort)
  871. await getList()
  872. refreshStore.registerCallback('devicerouter', getList)
  873. deptList.value = handleTree(await DeptApi.getSimpleDeptList())
  874. })
  875. </script>
  876. <style scoped scss>
  877. ::v-deep .el-table__header-wrapper {
  878. position: sticky !important;
  879. width: 100%;
  880. top: 0px;
  881. z-index: 2000;
  882. }
  883. ::v-deep .el-tooltip__trigger {
  884. border: none !important;
  885. outline: none !important;
  886. }
  887. ::v-deep .el-table__header-wrapper {
  888. position: sticky !important;
  889. width: 100%;
  890. top: 0px;
  891. z-index: 2000;
  892. }
  893. ::v-deep .el-tooltip__trigger {
  894. border: none !important;
  895. outline: none !important;
  896. }
  897. /* 表头对齐样式 */
  898. .table-header-flex {
  899. display: flex !important;
  900. align-items: center !important;
  901. justify-content: center !important;
  902. height: 100% !important;
  903. width: 100% !important;
  904. padding: 0 !important;
  905. }
  906. .table-header-text {
  907. flex: 1;
  908. text-align: center;
  909. font-size: 12px;
  910. color: #606266;
  911. }
  912. .header-arrow-icon {
  913. margin-left: 4px;
  914. cursor: pointer;
  915. color: #ad9399;
  916. font-size: 12px;
  917. }
  918. .popover-content-flex {
  919. display: flex;
  920. align-items: center;
  921. gap: 8px;
  922. }
  923. /* 修复单元格对齐 */
  924. ::v-deep .el-table th,
  925. ::v-deep .el-table td {
  926. padding: 6px 0 !important;
  927. }
  928. ::v-deep .el-table th .cell,
  929. ::v-deep .el-table td .cell {
  930. display: flex;
  931. align-items: center;
  932. justify-content: center;
  933. height: 100%;
  934. padding: 0 8px;
  935. }
  936. </style>