overhaul.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. <template>
  2. <div class="hc-page-layout-box">
  3. <div class="hc-layout-left-box menu" :style="'width:' + leftWidth + 'px;'">
  4. <div class="hc-menu-header-box">
  5. <div class="text-xl name">设备分类 - 检修记录</div>
  6. </div>
  7. <div class="hc-menu-contents-box">
  8. <el-scrollbar>
  9. <HcMenuSimple :props="menusProps" :datas="menus" :keys="menuKey" @change="menuChange"/>
  10. </el-scrollbar>
  11. </div>
  12. <!--左右拖动-->
  13. <div class="horizontal-drag-line" @mousedown="onmousedown"/>
  14. </div>
  15. <div class="hc-page-content-box">
  16. <HcCard>
  17. <template #header>
  18. <HcTooltip keys="tentative_device_overhaul_add">
  19. <el-button type="primary" hc-btn @click="addFormModalClick">
  20. <HcIcon name="add-circle"/>
  21. <span>新增</span>
  22. </el-button>
  23. </HcTooltip>
  24. <HcTooltip keys="tentative_device_overhaul_edit">
  25. <el-button hc-btn :disabled="tableCheckedKeys.length <= 0" @click="editFormModalClick">
  26. <HcIcon name="edit"/>
  27. <span>编辑</span>
  28. </el-button>
  29. </HcTooltip>
  30. <HcTooltip keys="tentative_device_overhaul_del">
  31. <el-button hc-btn :disabled="tableCheckedKeys.length <= 0" @click="delNodeModalClick">
  32. <HcIcon name="delete-bin-2"/>
  33. <span>删除</span>
  34. </el-button>
  35. </HcTooltip>
  36. <HcTooltip keys="tentative_device_overhaul_printer">
  37. <el-button hc-btn :disabled="tableCheckedKeys.length <= 0" :loading="printerLoading" @click="printerClick">
  38. <HcIcon name="printer"/>
  39. <span>打印</span>
  40. </el-button>
  41. </HcTooltip>
  42. <HcTooltip keys="tentative_device_overhaul_import">
  43. <el-button hc-btn @click="importModalClick">
  44. <HcIcon name="folder-upload"/>
  45. <span>导入</span>
  46. </el-button>
  47. </HcTooltip>
  48. </template>
  49. <template #search>
  50. <div class="w-64">
  51. <HcDatePicker :dates="betweenTime" clearable @change="betweenTimeUpdate"/>
  52. </div>
  53. <div class="w-72 ml-2">
  54. <el-input v-model="searchForm.queryValue" placeholder="请输入设备名称\设备型号查询" clearable @keyup="keyUpEvent"/>
  55. </div>
  56. <div class="ml-2">
  57. <el-button type="primary" @click="searchClick">
  58. <HcIcon name="search-2"/>
  59. <span>搜索</span>
  60. </el-button>
  61. </div>
  62. </template>
  63. <HcTable ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading" isCheck @selection-change="tableSelection"/>
  64. <template #action>
  65. <HcPages :pages="searchForm" @change="pageChange"/>
  66. </template>
  67. </HcCard>
  68. </div>
  69. <!--新增/编辑-->
  70. <HcDialog :show="addEditFormModal" title="新增/编辑 设备检修信息" widths="50rem" :loading="addEditFormLoading" @close="addEditFormModalClose" @save="addEditFormClick">
  71. <el-form ref="addEditFormRef" :model="addEditFormModel" :rules="addEditFormRules" label-width="auto" size="large">
  72. <div class="hc-form-item">
  73. <el-form-item label="设备分类">
  74. <el-select :disabled="deviceFormLoading" v-model="addEditFormModel.deviceClassId" block @change="deviceClassIdChange">
  75. <el-option v-for="item in typeData" :label="item.className" :value="item.id"/>
  76. </el-select>
  77. </el-form-item>
  78. <el-form-item label="维修/检定日期">
  79. <el-date-picker type="date" v-model="addEditFormModel.overhaulDate" class="block" value-format="YYYY-MM-DD" :clearable="false"/>
  80. </el-form-item>
  81. </div>
  82. <div class="hc-form-item">
  83. <el-form-item label="设备编号">
  84. <el-select :disabled="deviceFormLoading" v-model="addEditFormModel.deviceNumber" block @change="deviceNumberChange">
  85. <el-option v-for="item in deviceFormSelectData" :label="item.deviceNumber" :value="item.deviceNumber"/>
  86. </el-select>
  87. </el-form-item>
  88. <el-form-item label="维修/检定人">
  89. <hcAutoComplete v-model="addEditFormModel.managerName" :datas="userListData" keys="userName" placeholder="请选择或输入维修/检定人"/>
  90. </el-form-item>
  91. </div>
  92. <div class="hc-form-item">
  93. <el-form-item label="设备名称">
  94. <el-select :disabled="deviceFormLoading" v-model="addEditFormModel.deviceName" block @change="deviceNameChange">
  95. <el-option v-for="item in deviceFormSelectData" :label="item.deviceName" :value="item.deviceName"/>
  96. </el-select>
  97. </el-form-item>
  98. <el-form-item/>
  99. </div>
  100. <el-form-item label="维修/检定内容">
  101. <el-input v-model="addEditFormModel.overhaulText" type="textarea" :autosize="{ minRows: 3}"/>
  102. </el-form-item>
  103. <el-form-item label="备注">
  104. <el-input v-model="addEditFormModel.remarks" type="textarea" :autosize="{ minRows: 3}"/>
  105. </el-form-item>
  106. </el-form>
  107. </HcDialog>
  108. <!--导入-->
  109. <HcDialog :show="importModal" title="导入设备检修数据" widths="70rem" isTable isFooterCenter :loading="importModalLoading" @save="importModalYesClick" @close="importModalClose">
  110. <div class="text-orange mb-6">
  111. <span>请先下载模板模板表格 (</span>
  112. <span class="text-link" @click="downloadImportClick">范例试验设备文件</span>
  113. <span>) ,按模板样式编辑试验容器后,在点击“选择文件”按钮选择编辑好的文件,点击确认即可导入成功!</span>
  114. </div>
  115. <HcDragUpload/>
  116. <div class="hc-import-modal-table-box">
  117. <HcTable ref="tableImportRef" :column="tableColumn" :datas="tableImportData" :loading="tableImportLoading" isCheck @selection-change="tableImportSelection"/>
  118. </div>
  119. </HcDialog>
  120. </div>
  121. </template>
  122. <script setup>
  123. import {ref, onMounted, watch} from "vue";
  124. import {useAppStore} from "~src/store";
  125. import HcDragUpload from "./components/HcDragUpload.vue"
  126. import {getClassList, queryDeviceList, querySampleList} from "~api/tentative";
  127. import {getContractUserList} from "~api/other";
  128. import {formValidate, getArrValue} from "vue-utils-plus"
  129. import dataApi from "~api/tentative/device/overhaul";
  130. import {getRowsValue, rowsToId} from "~uti/tools";
  131. //初始变量
  132. const useAppState = useAppStore()
  133. const projectId = ref(useAppState.getProjectId);
  134. const contractId = ref(useAppState.getContractId);
  135. const isCollapse = ref(useAppState.getCollapse)
  136. //监听
  137. watch(() => [
  138. useAppState.getCollapse
  139. ], ([Collapse]) => {
  140. isCollapse.value = Collapse
  141. })
  142. //渲染完成
  143. onMounted(() => {
  144. getClassListData()
  145. getTableData()
  146. getUserListData()
  147. })
  148. //获取用户列表
  149. const userListData = ref([])
  150. const getUserListData = async () => {
  151. const { data } = await getContractUserList({
  152. contractId: contractId.value
  153. })
  154. userListData.value = getArrValue(data)
  155. }
  156. //左侧菜单
  157. const menuKey = ref('0')
  158. const menuItem = ref({})
  159. const menusProps = ref({
  160. key: 'id',
  161. label: 'className'
  162. })
  163. //获取菜单数据
  164. const menus = ref([]);
  165. const typeData = ref([]);
  166. const getClassListData = async () => {
  167. const { data } = await getClassList({
  168. contractId: contractId.value
  169. })
  170. const arr = getArrValue(data)
  171. typeData.value = arr
  172. menus.value = [{id: '0', className: '全部', isNoContextMenu: true}, ...arr]
  173. }
  174. //菜单被点击
  175. const menuChange = (item) => {
  176. menuItem.value = item
  177. menuKey.value = item?.id
  178. searchForm.value.deviceClassId = item?.id
  179. searchForm.value.current = 1;
  180. getTableData()
  181. }
  182. //搜索表单
  183. const searchForm = ref({
  184. deviceClassId: '', startTime: null, endTime: null, queryValue: null,
  185. current: 1, size: 20, total: 0
  186. })
  187. //日期时间被选择
  188. const betweenTime = ref(null)
  189. const betweenTimeUpdate = ({arr}) => {
  190. betweenTime.value = arr
  191. if (arr.length > 0) {
  192. searchForm.value.startTime = arr[0]
  193. searchForm.value.endTime = arr[1]
  194. }
  195. }
  196. //回车搜索
  197. const keyUpEvent = (e) => {
  198. if (e.key === "Enter") {
  199. searchForm.value.current = 1;
  200. getTableData()
  201. }
  202. }
  203. //搜索
  204. const searchClick = () => {
  205. searchForm.value.current = 1;
  206. getTableData()
  207. }
  208. //分页被点击
  209. const pageChange = ({current, size}) => {
  210. searchForm.value.current = current
  211. searchForm.value.size = size
  212. getTableData()
  213. }
  214. //表格数据
  215. const tableRef = ref(null)
  216. const tableColumn = ref([
  217. {key:'deviceName', name: '设备名称'},
  218. {key:'deviceClassName', name: '设备分类'},
  219. {key:'deviceNumber', name: '设备编号'},
  220. {key:'deviceModel', name: '设备型号'},
  221. {key:'factoryNumber', name: '出厂编号'},
  222. {key:'overhaulDate', name: '维修/检定日期'},
  223. {key:'overhaulText', name: '维修/检定内容'},
  224. {key:'managerName', name: '维修/检定人'},
  225. {key:'remarks', name: '备注'},
  226. ])
  227. const tableLoading = ref(false)
  228. //获取数据
  229. const tableData = ref([])
  230. const getTableData = async () => {
  231. tableLoading.value = true
  232. const { error, code, data } = await dataApi.queryPage({
  233. projectId: projectId.value,
  234. contractId: contractId.value,
  235. ...searchForm.value,
  236. })
  237. //处理数据
  238. tableLoading.value = false
  239. if (!error && code === 200) {
  240. tableData.value = getArrValue(data['records'])
  241. searchForm.value.total = data.total || 0
  242. } else {
  243. tableData.value = []
  244. searchForm.value.total = 0
  245. }
  246. }
  247. //多选
  248. const tableCheckedKeys = ref([]);
  249. const tableSelection = (rows) => {
  250. tableCheckedKeys.value = rows
  251. }
  252. //删除
  253. const delNodeModalClick = () => {
  254. window?.$messageBox?.alert('请谨慎考虑后,确认是否需要删除?', '删除提醒', {
  255. showCancelButton: true,
  256. confirmButtonText: '确认删除',
  257. cancelButtonText: '取消',
  258. type: 'warning',
  259. callback: (action) => {
  260. if (action === 'confirm') {
  261. tableRemoveData()
  262. }
  263. }
  264. })
  265. }
  266. //批量删除
  267. const tableRemoveData = async () => {
  268. const rows = tableCheckedKeys.value
  269. if (rows.length > 0 ) {
  270. const ids = rowsToId(rows)
  271. //删除请求
  272. const { error, code } = await dataApi.removeData({
  273. contractId: contractId.value,
  274. ids: ids,
  275. })
  276. //处理数据
  277. if (!error && code === 200) {
  278. window?.$message?.success('操作成功')
  279. searchClick()
  280. }
  281. }
  282. }
  283. //打印
  284. const printerLoading = ref(false)
  285. const printerClick = async () => {
  286. const rows = tableCheckedKeys.value
  287. if (rows.length > 0 ) {
  288. printerLoading.value = true
  289. const ids = rowsToId(rows)
  290. //删除请求
  291. const { error, code, data } = await dataApi.exportPdf({
  292. projectId: projectId.value,
  293. contractId: contractId.value,
  294. ids: ids,
  295. })
  296. //处理数据
  297. printerLoading.value = false
  298. if (!error && code === 200) {
  299. window.open(data,'_blank')
  300. }
  301. }
  302. }
  303. //导入
  304. const importModal = ref(false)
  305. const importModalClick = () => {
  306. importModal.value = true
  307. }
  308. //确认导入
  309. const importModalLoading = ref(false)
  310. const importModalYesClick = () => {
  311. importModal.value = false
  312. }
  313. //关闭导入
  314. const importModalClose = () => {
  315. importModal.value = false
  316. }
  317. //表格数据
  318. const tableImportRef = ref(null)
  319. const tableImportLoading = ref(false)
  320. const tableImportData = ref([])
  321. //多选
  322. const tableImportKeys = ref([]);
  323. const tableImportSelection = (rows) => {
  324. tableImportKeys.value = rows
  325. }
  326. //新增
  327. const addEditFormModal = ref(false)
  328. const addFormModalClick = () => {
  329. addEditFormModel.value = {}
  330. addEditFormModal.value = true
  331. }
  332. //编辑
  333. const editFormModalClick = () => {
  334. const keys = tableCheckedKeys.value
  335. if (keys.length === 1) {
  336. addEditFormModel.value = keys[0]
  337. addEditFormModal.value = true
  338. } else if (keys.length > 1) {
  339. window?.$message?.warning('只能选择一条数据编辑')
  340. }
  341. }
  342. //关闭
  343. const addEditFormModalClose = () => {
  344. addEditFormModal.value = false
  345. addEditFormModel.value = {}
  346. }
  347. //新增/编辑 表单
  348. const addEditFormRef = ref(null)
  349. const addEditFormModel = ref({})
  350. const addEditFormRules = {
  351. key1: {
  352. required: true,
  353. trigger: 'blur',
  354. message: "请输入"
  355. },
  356. key2: {
  357. required: true,
  358. trigger: 'blur',
  359. message: "请选择"
  360. },
  361. }
  362. //分类被选择
  363. const deviceFormLoading = ref(false)
  364. const deviceFormSelectData = ref([])
  365. const deviceClassIdChange = async (val) => {
  366. deviceFormLoading.value = true
  367. const {data} = await queryDeviceList({
  368. projectId: projectId.value,
  369. contractId: contractId.value,
  370. deviceClassId: val
  371. })
  372. //处理数据
  373. const records = getArrValue(data)
  374. deviceFormSelectData.value = records
  375. if (records.length > 0) {
  376. addEditFormModel.value.deviceNumber = records[0].deviceNumber
  377. addEditFormModel.value.deviceName = records[0].deviceName
  378. addEditFormModel.value.deviceInfoId = records[0].id
  379. } else {
  380. addEditFormModel.value.deviceNumber = ''
  381. addEditFormModel.value.deviceName = ''
  382. addEditFormModel.value.deviceInfoId = ''
  383. }
  384. deviceFormLoading.value = false;
  385. }
  386. //设备编号
  387. const deviceNumberChange = (val) => {
  388. addEditFormModel.value.deviceName = getRowsValue(deviceFormSelectData.value, 'deviceNumber', 'deviceName', val)
  389. addEditFormModel.value.deviceInfoId = getRowsValue(deviceFormSelectData.value, 'deviceNumber', 'id', val)
  390. }
  391. //设备名称
  392. const deviceNameChange = (val) => {
  393. addEditFormModel.value.deviceNumber = getRowsValue(deviceFormSelectData.value, 'deviceName', 'deviceNumber', val)
  394. addEditFormModel.value.deviceInfoId = getRowsValue(deviceFormSelectData.value, 'deviceName', 'id', val)
  395. }
  396. //新增/编辑 保存
  397. const addEditFormLoading = ref(false)
  398. const addEditFormClick = async () => {
  399. const validate = await formValidate(addEditFormRef.value)
  400. if (validate) {
  401. addEditFormLoading.value = true
  402. const { error, code } = await dataApi.submitForm({
  403. ...addEditFormModel.value,
  404. projectId: projectId.value,
  405. contractId: contractId.value
  406. })
  407. //处理数据
  408. addEditFormLoading.value = false
  409. if (!error && code === 200) {
  410. window?.$message?.success('操作成功')
  411. addEditFormModal.value = false
  412. await getTableData()
  413. }
  414. }
  415. }
  416. //下载导入模板
  417. const downloadImportClick = () => {
  418. window.open('https://bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20221109/d8011cf7b101ff694ed4f21ac4348542.xlsx','_blank')
  419. }
  420. //左右拖动,改变树形结构宽度
  421. const leftWidth = ref(240);
  422. const onmousedown = () => {
  423. const leftNum = isCollapse.value ? 142 : 272
  424. document.onmousemove = (ve) => {
  425. let diffVal = ve.clientX - leftNum;
  426. if(diffVal >= 220 && diffVal <= 400) {
  427. leftWidth.value = diffVal;
  428. }
  429. }
  430. document.onmouseup = () => {
  431. document.onmousemove = null;
  432. document.onmouseup = null;
  433. }
  434. }
  435. </script>
  436. <style lang="scss" scoped>
  437. .hc-import-modal-table-box {
  438. position: relative;
  439. height: calc(100% - 228px);
  440. margin-top: 25px;
  441. }
  442. </style>