index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. <template>
  2. <el-row :gutter="20">
  3. <el-col :span="4" :xs="24">
  4. <ContentWrap class="h-1/1">
  5. <DeptTree @node-click="handleDeptNodeClick" />
  6. </ContentWrap>
  7. </el-col>
  8. <el-col :span="20" :xs="24">
  9. <ContentWrap>
  10. <!-- 搜索工作栏 -->
  11. <el-form
  12. class="-mb-15px"
  13. :model="queryParams"
  14. ref="queryFormRef"
  15. :inline="true"
  16. label-width="68px"
  17. >
  18. <el-form-item
  19. :label="t('maintain.faultCode')"
  20. prop="failureCode"
  21. style="margin-left: 25px"
  22. >
  23. <el-input
  24. v-model="queryParams.failureCode"
  25. :placeholder="t('maintain.codeHolder')"
  26. clearable
  27. @keyup.enter="handleQuery"
  28. class="!w-200px"
  29. />
  30. </el-form-item>
  31. <el-form-item :label="t('maintain.faultName')" label-width="70px" prop="failureName">
  32. <el-input
  33. v-model="queryParams.failureName"
  34. :placeholder="t('maintain.nameHolder')"
  35. clearable
  36. @keyup.enter="handleQuery"
  37. class="!w-200px"
  38. />
  39. </el-form-item>
  40. <el-form-item :label="t('maintain.status')" label-width="40px" prop="status">
  41. <el-select
  42. v-model="queryParams.status"
  43. :placeholder="t('maintain.status')"
  44. clearable
  45. class="!w-200px"
  46. >
  47. <el-option
  48. v-for="dict in getStrDictOptions(DICT_TYPE.PMS_MAIN_STATUS)"
  49. :key="dict.value"
  50. :label="dict.label"
  51. :value="dict.value"
  52. />
  53. </el-select>
  54. </el-form-item>
  55. <el-form-item :label="t('maintain.shutDown')" v-show="ifShow" prop="ifStop">
  56. <el-select
  57. v-model="queryParams.ifStop"
  58. :placeholder="t('maintain.shutDown')"
  59. clearable
  60. class="!w-200px"
  61. >
  62. <el-option
  63. v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
  64. :key="dict.value"
  65. :label="dict.label"
  66. :value="dict.value"
  67. />
  68. </el-select>
  69. </el-form-item>
  70. <el-form-item
  71. :label="t('maintain.failureTime')"
  72. v-show="ifShow"
  73. prop="failureTime"
  74. style="margin-left: 25px"
  75. >
  76. <el-date-picker
  77. v-model="queryParams.failureTime"
  78. value-format="YYYY-MM-DD HH:mm:ss"
  79. type="daterange"
  80. start-placeholder="开始日期"
  81. end-placeholder="结束日期"
  82. :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
  83. class="!w-220px"
  84. />
  85. </el-form-item>
  86. <el-form-item :label="t('maintain.solve')" v-show="ifShow" prop="ifDeal">
  87. <el-select
  88. v-model="queryParams.ifDeal"
  89. :placeholder="t('maintain.solve')"
  90. clearable
  91. class="!w-200px"
  92. >
  93. <el-option
  94. v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
  95. :key="dict.value"
  96. :label="dict.label"
  97. :value="dict.value"
  98. />
  99. </el-select>
  100. </el-form-item>
  101. <el-form-item :label="t('maintain.assist')" v-show="ifShow" prop="needHelp">
  102. <el-select
  103. v-model="queryParams.needHelp"
  104. :placeholder="t('maintain.assist')"
  105. clearable
  106. class="!w-200px"
  107. >
  108. <el-option
  109. v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
  110. :key="dict.value"
  111. :label="dict.label"
  112. :value="dict.value"
  113. />
  114. </el-select>
  115. </el-form-item>
  116. <el-form-item>
  117. <el-button v-if="!ifShow" @click="moreQuery(true)" type="warning"
  118. ><Icon icon="ep:search" class="mr-5px" /> {{ t('maintain.moreSearch') }}</el-button
  119. >
  120. <el-button v-if="ifShow" @click="moreQuery(false)" type="danger"
  121. ><Icon icon="ep:search" class="mr-5px" /> {{ t('maintain.closeSearch') }}</el-button
  122. >
  123. <el-button @click="handleQuery"
  124. ><Icon icon="ep:search" class="mr-5px" /> {{ t('maintain.search') }}</el-button
  125. >
  126. <el-button @click="resetQuery"
  127. ><Icon icon="ep:refresh" class="mr-5px" /> {{ t('maintain.reset') }}</el-button
  128. >
  129. <el-button
  130. type="primary"
  131. plain
  132. @click="openForm('create')"
  133. v-hasPermi="['rq:iot-maintain:create']"
  134. >
  135. <Icon icon="ep:plus" class="mr-5px" /> {{ t('maintain.added') }}
  136. </el-button>
  137. <el-button type="success" plain @click="handleExport" :loading="exportLoading">
  138. <Icon icon="ep:download" class="mr-5px" /> 导出
  139. </el-button>
  140. </el-form-item>
  141. </el-form>
  142. </ContentWrap>
  143. <!-- 列表 -->
  144. <ContentWrap>
  145. <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
  146. <el-table-column :label="t('maintain.serial')" min-width="70" align="center">
  147. <template #default="scope">
  148. {{ scope.$index + 1 }}
  149. </template>
  150. </el-table-column>
  151. <el-table-column
  152. :label="t('iotDevice.code')"
  153. align="center"
  154. prop="deviceCode"
  155. min-width="180"
  156. />
  157. <el-table-column
  158. :label="t('maintain.deviceName')"
  159. align="center"
  160. prop="deviceName"
  161. min-width="280"
  162. />
  163. <el-table-column
  164. :label="t('maintain.status')"
  165. align="center"
  166. prop="status"
  167. min-width="95"
  168. >
  169. <template #default="scope">
  170. <dict-tag :type="DICT_TYPE.PMS_MAIN_STATUS" :value="scope.row.status" />
  171. </template>
  172. </el-table-column>
  173. <el-table-column
  174. :label="t('maintain.source')"
  175. align="center"
  176. prop="maintainType"
  177. min-width="135"
  178. />
  179. <el-table-column
  180. :label="t('iotMaintain.repairType')"
  181. align="center"
  182. prop="type"
  183. min-width="135"
  184. >
  185. <template #default="scope">
  186. <dict-tag :type="DICT_TYPE.PMS_MAIN_TYPE" :value="scope.row.type" />
  187. </template>
  188. </el-table-column>
  189. <el-table-column
  190. :label="t('maintain.shutDown')"
  191. align="center"
  192. prop="ifStop"
  193. min-width="135"
  194. >
  195. <template #default="scope">
  196. <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.ifStop" />
  197. </template>
  198. </el-table-column>
  199. <el-table-column
  200. label="执行时间"
  201. align="center"
  202. prop="executeDate"
  203. :formatter="dateFormatter"
  204. min-width="180px"
  205. />
  206. <el-table-column
  207. :label="t('iotMaintain.oaFlowNo')"
  208. align="center"
  209. prop="oaFlowNo"
  210. min-width="250"
  211. />
  212. <el-table-column
  213. :label="t('maintain.dept')"
  214. align="center"
  215. prop="deptName"
  216. min-width="135"
  217. />
  218. <el-table-column
  219. :label="t('inspect.createName')"
  220. align="center"
  221. prop="createName"
  222. min-width="130"
  223. />
  224. <el-table-column
  225. label="创建时间"
  226. align="center"
  227. prop="createTime"
  228. :formatter="dateFormatter"
  229. width="180px"
  230. />
  231. <el-table-column
  232. :label="t('maintain.operation')"
  233. align="center"
  234. min-width="170"
  235. fixed="right"
  236. >
  237. <template #default="scope">
  238. <el-button link type="primary" @click="detail(scope.row.id)">
  239. {{ t('maintain.view') }}
  240. </el-button>
  241. <el-button
  242. link
  243. v-if="
  244. scope.row.status === 'tx' &&
  245. (scope.row.auditStatus === 20 || scope.row.auditStatus === null)
  246. "
  247. type="danger"
  248. @click="
  249. openForm('update', scope.row.id, scope.row.maintainPerson, scope.row.company)
  250. "
  251. >
  252. {{ t('maintain.fill') }}
  253. </el-button>
  254. <el-button
  255. link
  256. v-if="scope.row.status === 'personnel' && userid === scope.row.maintainPerson"
  257. type="danger"
  258. @click="openDialog(scope.row.id)"
  259. >
  260. {{ t('maintain.maintainWay') }}
  261. </el-button>
  262. <el-button
  263. v-if="scope.row.status!=='personnel'"
  264. link
  265. type="warning"
  266. @click="openRecord(scope.row.id)"
  267. >
  268. {{ t('maintain.record') }}
  269. </el-button>
  270. </template>
  271. </el-table-column>
  272. </el-table>
  273. <el-dialog
  274. v-model="dialogVisible"
  275. title="维修方式"
  276. :width="600"
  277. :before-close="handleClose"
  278. append-to-body
  279. :close-on-click-modal="false"
  280. >
  281. <el-form ref="methodFormRef" :model="form" :rules="rules" label-width="70px">
  282. <el-form-item label="维修方式" prop="maintainMethod">
  283. <el-select v-model="form.maintainMethod" placeholder="请选择维修方式">
  284. <el-option
  285. v-for="dict in getStrDictOptions(DICT_TYPE.PMS_MAINTAIN_METHOD)"
  286. :key="dict.label"
  287. :label="dict.label"
  288. :value="dict.value"
  289. />
  290. </el-select>
  291. </el-form-item>
  292. <el-form-item label="备注说明" prop="methodDescription">
  293. <el-input
  294. type="textarea"
  295. v-model="form.methodDescription"
  296. placeholder="请输入备注说明"
  297. :rows="4"
  298. resize="none"
  299. />
  300. </el-form-item>
  301. </el-form>
  302. <template #footer>
  303. <el-button @click="handleCancel">取消</el-button>
  304. <el-button type="primary" @click="handleConfirm">确定</el-button>
  305. </template>
  306. </el-dialog>
  307. <!-- 分页 -->
  308. <Pagination
  309. :total="total"
  310. v-model:page="queryParams.pageNo"
  311. v-model:limit="queryParams.pageSize"
  312. @pagination="getList"
  313. />
  314. </ContentWrap>
  315. </el-col>
  316. </el-row>
  317. <!-- 表单弹窗:添加/修改 -->
  318. </template>
  319. <script setup lang="ts">
  320. import { dateFormatter } from '@/utils/formatTime'
  321. import download from '@/utils/download'
  322. import { IotMaintainApi, IotMaintainVO } from '@/api/pms/maintain'
  323. import DeptTree from '@/views/system/user/DeptTree.vue'
  324. import { DICT_TYPE, getBoolDictOptions, getStrDictOptions } from '@/utils/dict'
  325. import { useUserStore } from '@/store/modules/user'
  326. /** 维修工单 列表 */
  327. defineOptions({ name: 'IotMaintain' })
  328. const message = useMessage() // 消息弹窗
  329. const { t } = useI18n() // 国际化
  330. const { push } = useRouter() // 路由跳转
  331. const ifShow = ref(false)
  332. const loading = ref(true) // 列表的加载中
  333. const list = ref<IotMaintainVO[]>([]) // 列表的数据
  334. const total = ref(0) // 列表的总页数
  335. const dialogVisible = ref(false)
  336. const queryParams = reactive({
  337. pageNo: 1,
  338. pageSize: 10,
  339. failureCode: undefined,
  340. failureName: undefined,
  341. deviceId: undefined,
  342. status: undefined,
  343. ifStop: undefined,
  344. failureTime: [],
  345. failureInfluence: undefined,
  346. failureSystem: undefined,
  347. description: undefined,
  348. pic: undefined,
  349. solution: undefined,
  350. maintainStartTime: [],
  351. maintainEndTime: [],
  352. remark: undefined,
  353. createTime: [],
  354. deviceName: undefined,
  355. processInstanceId: undefined,
  356. auditStatus: undefined,
  357. deptId: undefined
  358. })
  359. const queryFormRef = ref() // 搜索的表单
  360. const exportLoading = ref(false) // 导出的加载中
  361. const moreQuery = (show) => {
  362. ifShow.value = show
  363. }
  364. // 表单验证规则
  365. const rules = {
  366. methodDescription: [{ required: true, message: '请输入备注说明', trigger: 'blur' }],
  367. maintainMethod: [{ required: true, message: '请选择维修方式', trigger: 'blur' }]
  368. }
  369. // 确定按钮处理
  370. const handleConfirm = async () => {
  371. // 表单验证
  372. try {
  373. debugger
  374. await methodFormRef.value.validate()
  375. // 验证通过,调用接口
  376. await IotMaintainApi.maintainMethod(form)
  377. ElMessage.success('操作成功')
  378. dialogVisible.value = false
  379. resetForm()
  380. } catch (error) {
  381. return
  382. }
  383. }
  384. // 取消按钮处理
  385. const handleCancel = () => {
  386. dialogVisible.value = false
  387. resetForm()
  388. }
  389. const methodFormRef = ref(null)
  390. const form = reactive({
  391. id: undefined,
  392. maintainMethod: '',
  393. methodDescription: ''
  394. })
  395. // 关闭对话框前的回调
  396. const handleClose = () => {
  397. resetForm()
  398. }
  399. // 重置表单
  400. const resetForm = () => {
  401. methodFormRef.value?.resetFields()
  402. }
  403. // 打开对话框
  404. const openDialog = (id: number) => {
  405. dialogVisible.value = true
  406. form.id = id
  407. form.maintainMethod = ''
  408. form.methodDescription = ''
  409. }
  410. const openRecord = async (id?: number) => {
  411. await push({ name: 'MaintainRecord', params: {id} })
  412. }
  413. const openForm = async (type: string, id?: number, person: any, company) => {
  414. if (company === 'rh' && person === userid.value) {
  415. message.error('维修人员无法填写工单')
  416. return
  417. }
  418. //修改
  419. if (typeof id === 'number') {
  420. await push({ name: 'MaintainAdd', params: { id } })
  421. return
  422. }
  423. // 新增
  424. await push({ name: 'MaintainAdd', params: {} })
  425. }
  426. const detail = (id?: number) => {
  427. push({ name: 'MaintainDetail', params: { id } })
  428. }
  429. /** 查询列表 */
  430. const getList = async () => {
  431. loading.value = true
  432. try {
  433. const data = await IotMaintainApi.getIotMaintainPage(queryParams)
  434. list.value = data.list
  435. total.value = data.total
  436. } finally {
  437. loading.value = false
  438. }
  439. }
  440. /** 处理部门被点击 */
  441. const handleDeptNodeClick = async (row) => {
  442. queryParams.deptId = row.id
  443. await getList()
  444. }
  445. /** 搜索按钮操作 */
  446. const handleQuery = () => {
  447. queryParams.pageNo = 1
  448. getList()
  449. }
  450. /** 重置按钮操作 */
  451. const resetQuery = () => {
  452. queryFormRef.value.resetFields()
  453. handleQuery()
  454. }
  455. /** 删除按钮操作 */
  456. const handleDelete = async (id: number) => {
  457. try {
  458. // 删除的二次确认
  459. await message.delConfirm()
  460. // 发起删除
  461. await IotMaintainApi.deleteIotMaintain(id)
  462. message.success(t('common.delSuccess'))
  463. // 刷新列表
  464. await getList()
  465. } catch {}
  466. }
  467. /** 导出按钮操作 */
  468. const handleExport = async () => {
  469. try {
  470. // 导出的二次确认
  471. await message.exportConfirm()
  472. // 发起导出
  473. exportLoading.value = true
  474. const data = await IotMaintainApi.exportIotMaintain(queryParams)
  475. download.excel(data, '维修工单.xls')
  476. } catch {
  477. } finally {
  478. exportLoading.value = false
  479. }
  480. }
  481. const userid = ref()
  482. /** 初始化 **/
  483. onMounted(() => {
  484. getList()
  485. userid.value = useUserStore().getUser.id
  486. })
  487. </script>