DeviceAllot.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <template>
  2. <el-row :gutter="20">
  3. <!-- 左侧部门树 -->
  4. <el-col :span="4" :xs="24">
  5. <ContentWrap class="h-1/1" v-if="treeShow">
  6. <DeptTree @node-click="handleDeptNodeClick" />
  7. </ContentWrap>
  8. </el-col>
  9. <el-col :span="contentSpan" :xs="24">
  10. <ContentWrap>
  11. <!-- 搜索工作栏 -->
  12. <el-form
  13. class="-mb-15px"
  14. :model="queryParams"
  15. ref="queryFormRef"
  16. :inline="true"
  17. label-width="68px"
  18. >
  19. <el-form-item :label="t('devicePerson.deviceCode')" prop="deviceCode" style="margin-left: 25px">
  20. <el-input
  21. v-model="queryParams.deviceCode"
  22. :placeholder="t('devicePerson.codeHolder')"
  23. clearable
  24. @keyup.enter="handleQuery"
  25. class="!w-200px"
  26. />
  27. </el-form-item>
  28. <el-form-item :label="t('devicePerson.deviceName')" prop="deviceName">
  29. <el-input
  30. v-model="queryParams.deviceName"
  31. :placeholder="t('devicePerson.nameHolder')"
  32. clearable
  33. @keyup.enter="handleQuery"
  34. class="!w-200px"
  35. />
  36. </el-form-item>
  37. <el-form-item :label="t('deviceStatus.transfer')" prop="setFlag" label-width="140px">
  38. <el-select
  39. v-model="queryParams.setFlag"
  40. :placeholder="t('deviceStatus.choose')"
  41. clearable
  42. class="!w-240px"
  43. >
  44. <el-option
  45. v-for="dict in resultOptions"
  46. :key="dict.value"
  47. :label="dict.label"
  48. :value="dict.value"
  49. />
  50. </el-select>
  51. </el-form-item>
  52. <el-form-item v-show="ifShow" :label="t('devicePerson.status')" label-width="85px" prop="deviceStatus">
  53. <el-select
  54. v-model="queryParams.deviceStatus"
  55. :placeholder="t('devicePerson.status')"
  56. clearable
  57. class="!w-240px"
  58. >
  59. <el-option
  60. v-for="dict in getStrDictOptions(DICT_TYPE.PMS_DEVICE_STATUS)"
  61. :key="dict.value"
  62. :label="dict.label"
  63. :value="dict.value"
  64. />
  65. </el-select>
  66. </el-form-item>
  67. <el-form-item v-show="ifShow" :label="t('devicePerson.assets')" prop="assetProperty">
  68. <el-select
  69. v-model="queryParams.assetProperty"
  70. :placeholder="t('devicePerson.assets')"
  71. clearable
  72. class="!w-240px"
  73. >
  74. <el-option
  75. v-for="dict in getStrDictOptions(DICT_TYPE.PMS_ASSET_PROPERTY)"
  76. :key="dict.value"
  77. :label="dict.label"
  78. :value="dict.value"
  79. />
  80. </el-select>
  81. </el-form-item>
  82. <el-form-item v-show="ifShow" :label="t('devicePerson.brand')" prop="brand">
  83. <el-input
  84. v-model="queryParams.brand"
  85. :placeholder="t('devicePerson.brandHolder')"
  86. clearable
  87. @keyup.enter="handleQuery"
  88. class="!w-200px"
  89. />
  90. </el-form-item>
  91. <el-form-item>
  92. <el-button v-if="!ifShow" @click="moreQuery(true)" type="warning"
  93. ><Icon icon="ep:search" class="mr-5px" /> {{ t('devicePerson.moreSearch') }}</el-button
  94. >
  95. <el-button v-if="ifShow" @click="moreQuery(false)" type="danger"
  96. ><Icon icon="ep:search" class="mr-5px" /> {{ t('devicePerson.closeSearch') }}</el-button
  97. >
  98. <el-button @click="handleQuery"
  99. ><Icon icon="ep:search" class="mr-5px" /> {{ t('devicePerson.search') }}</el-button
  100. >
  101. <el-button @click="resetQuery"
  102. ><Icon icon="ep:refresh" class="mr-5px" /> {{ t('devicePerson.reset') }}</el-button
  103. >
  104. <el-button
  105. type="primary"
  106. plain
  107. @click="openForm('create', undefined, queryParams.deptId)"
  108. v-hasPermi="['pms:iot-device-allot-log:create']"
  109. >
  110. <Icon icon="ep:plus" class="mr-5px" /> {{ t('deviceAllot.setUp') }}
  111. </el-button>
  112. <el-button
  113. type="success"
  114. plain
  115. @click="handleExport"
  116. :loading="exportLoading"
  117. v-hasPermi="['rq:iot-device:export']"
  118. >
  119. <Icon icon="ep:download" class="mr-5px" /> 导出
  120. </el-button>
  121. </el-form-item>
  122. </el-form>
  123. </ContentWrap>
  124. <!-- 列表 -->
  125. <ContentWrap>
  126. <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
  127. <el-table-column :label="t('monitor.serial')" width="70" align="center">
  128. <template #default="scope">
  129. {{ scope.$index + 1 }}
  130. </template>
  131. </el-table-column>
  132. <el-table-column :label="t('monitor.deviceCode')" align="center" prop="deviceCode" />
  133. <el-table-column :label="t('monitor.deviceName')" align="center" prop="deviceName">
  134. <template #default="scope">
  135. <el-link :underline="false" type="primary" @click="handleDetail(scope.row.id)">
  136. {{ scope.row.deviceName }}
  137. </el-link>
  138. </template>
  139. </el-table-column>
  140. <el-table-column :label="t('devicePerson.dept')" align="center" prop="deptName" />
  141. <el-table-column :label="t('deviceStatus.status')" align="center" prop="deviceStatus">
  142. <template #default="scope">
  143. <dict-tag :type="DICT_TYPE.PMS_DEVICE_STATUS" :value="scope.row.deviceStatus" />
  144. </template>
  145. </el-table-column>
  146. <!--
  147. <el-table-column
  148. label="创建时间"
  149. align="center"
  150. prop="createTime"
  151. :formatter="dateFormatter"
  152. width="180px"
  153. /> -->
  154. <el-table-column :label="t('deviceStatus.operation')" align="center" min-width="120px">
  155. <template #default="scope">
  156. <el-button
  157. link
  158. type="primary"
  159. @click="handleView(scope.row.id)"
  160. v-hasPermi="['rq:iot-device:query']"
  161. >
  162. {{ t('deviceAllot.adjustmentRecords') }}
  163. </el-button>
  164. </template>
  165. </el-table-column>
  166. </el-table>
  167. <!-- 分页 -->
  168. <Pagination
  169. :total="total"
  170. v-model:page="queryParams.pageNo"
  171. v-model:limit="queryParams.pageSize"
  172. @pagination="getList"
  173. />
  174. </ContentWrap>
  175. </el-col>
  176. </el-row>
  177. <DeviceAllotLogDrawer
  178. :model-value="drawerVisible"
  179. @update:model-value="val => drawerVisible = val"
  180. :device-id="currentDeviceId"
  181. ref="showDrawer"
  182. />
  183. </template>
  184. <script setup lang="ts">
  185. import download from '@/utils/download'
  186. import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
  187. import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
  188. import { dateFormatter } from '@/utils/formatTime'
  189. import DeptTree from '@/views/system/user/DeptTree.vue'
  190. import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
  191. import DeviceAllotLogDrawer from "@/views/pms/device/allotlog/DeviceAllotLogDrawer.vue";
  192. /** 设备调拨 列表 */
  193. defineOptions({ name: 'IotDeviceAllot' })
  194. const message = useMessage() // 消息弹窗
  195. const { t } = useI18n() // 国际化
  196. const { push } = useRouter() // 路由跳转
  197. const loading = ref(true) // 列表的加载中
  198. const ifShow = ref(false)
  199. const isDetail = ref(false) // 是否查看详情
  200. const list = ref<IotDeviceVO[]>([]) // 列表的数据
  201. const total = ref(0) // 列表的总页数
  202. const queryParams = reactive({
  203. pageNo: 1,
  204. pageSize: 10,
  205. deviceCode: undefined,
  206. deviceName: undefined,
  207. brand: undefined,
  208. model: undefined,
  209. deptId: undefined,
  210. deviceStatus: undefined,
  211. assetProperty: undefined,
  212. picUrl: undefined,
  213. remark: undefined,
  214. manufacturerId: undefined,
  215. supplierId: undefined,
  216. nameplate: undefined,
  217. expires: undefined,
  218. creator: undefined,
  219. setFlag: ''
  220. })
  221. const queryFormRef = ref() // 搜索的表单
  222. const exportLoading = ref(false) // 导出的加载中
  223. const contentSpan = ref(20)
  224. const treeShow = ref(true)
  225. const currentDeviceId = ref() // 设备id
  226. const drawerVisible = ref<boolean>(false)
  227. const showDrawer = ref()
  228. /** 查询列表 */
  229. const getList = async () => {
  230. loading.value = true
  231. try {
  232. const data = await IotDeviceApi.allotRelationDevices(queryParams)
  233. list.value = data.list
  234. total.value = data.total
  235. } finally {
  236. loading.value = false
  237. }
  238. }
  239. /** 处理部门被点击 */
  240. const handleDeptNodeClick = async (row) => {
  241. queryParams.deptId = row.id
  242. await getList()
  243. }
  244. /** 搜索按钮操作 */
  245. const handleQuery = () => {
  246. queryParams.pageNo = 1
  247. getList()
  248. }
  249. const moreQuery = (show) => {
  250. ifShow.value = show
  251. }
  252. /** 重置按钮操作 */
  253. const resetQuery = () => {
  254. queryFormRef.value.resetFields()
  255. handleQuery()
  256. }
  257. /** 查看设备调拨详情 */
  258. const handleView = async (deviceId: number) => {
  259. currentDeviceId.value = deviceId
  260. drawerVisible.value = true
  261. // 强制重新加载数据
  262. nextTick(() => {
  263. showDrawer.value?.loadDeviceAllots(deviceId)
  264. })
  265. showDrawer.value.openDrawer()
  266. }
  267. /** 添加/修改操作 */
  268. const formRef = ref()
  269. const openForm = (type: string, id?: number) => {
  270. //修改
  271. if (typeof id === 'number') {
  272. push({ name: 'DeviceDetailEdit', params: { id } })
  273. return
  274. }
  275. // 新增
  276. push({ name: 'ConfigDeviceAllot', params: {} })
  277. }
  278. /** 删除按钮操作 */
  279. const handleDelete = async (id: number) => {
  280. try {
  281. // 删除的二次确认
  282. await message.delConfirm()
  283. // 发起删除
  284. await IotDeviceApi.deleteIotDevice(id)
  285. message.success(t('common.delSuccess'))
  286. // 刷新列表
  287. await getList()
  288. } catch {}
  289. }
  290. // 是否设置过责任人 下拉列表 模拟字典项
  291. const resultOptions = computed(() => [
  292. {
  293. label: '全部',
  294. value: 'A' // 空值会触发 clearable 效果
  295. },
  296. {
  297. label: '是',
  298. value: 'Y' // 空值会触发 clearable 效果
  299. },
  300. {
  301. label: '否',
  302. value: 'N' // 空值会触发 clearable 效果
  303. },
  304. ])
  305. const handleDetail = (id: number) => {
  306. push({ name: 'DeviceDetailInfo', params: { id } })
  307. }
  308. const handleUpload = (id: number) => {
  309. push({ name: 'DeviceUpload', params: { id } })
  310. }
  311. /** 导出按钮操作 */
  312. const handleExport = async () => {
  313. try {
  314. // 导出的二次确认
  315. await message.exportConfirm()
  316. // 发起导出
  317. exportLoading.value = true
  318. const data = await IotDeviceApi.exportIotDevice(queryParams)
  319. download.excel(data, '设备台账.xls')
  320. } catch {
  321. } finally {
  322. exportLoading.value = false
  323. }
  324. }
  325. const { wsCache } = useCache()
  326. /** 初始化 **/
  327. onMounted(() => {
  328. const user = wsCache.get(CACHE_KEY.USER)
  329. getList()
  330. })
  331. </script>
  332. <style scoped></style>