processRoute.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. <template>
  2. <div class="module-container">
  3. <el-row type="flex" :gutter="10" class="module-flex">
  4. <el-col :span="10">
  5. <el-card shadow="hover">
  6. <template #header>
  7. <div class="card-header">
  8. <span class="card-title">工艺路线</span>
  9. <span>
  10. <el-button size="mini" type="primary" @click="routeAdd" v-if="checkMenuLimit('room/craft/Add')">新增</el-button>
  11. </span>
  12. </div>
  13. </template>
  14. <div class="card-container">
  15. <el-form :inline="true" :model="formData.filterForm" size="small">
  16. <el-form-item prop="craftName">
  17. <el-input v-model="formData.filterForm.craftName" placeholder="路线名称" clearable style="width: 160px"></el-input>
  18. </el-form-item>
  19. <el-form-item prop="projectCatagoryCode">
  20. <el-select v-model="formData.filterForm.projectCatagoryCode" placeholder="选择业态" clearable style="width: 160px">
  21. <el-option v-for="item in dictionaryData.formatList" :key="item.value" :label="item.label" :value="item.value"></el-option>
  22. </el-select>
  23. </el-form-item>
  24. <el-form-item>
  25. <el-button type="primary" @click="getTreeTableList()">查询</el-button>
  26. </el-form-item>
  27. </el-form>
  28. <el-table :data="tableData.treeTableList" v-loading="tableData.treeTableLoading" :height="props.resizeHeight - 252" stripe border fit @row-click="nodeClick">
  29. <el-table-column prop="craftName" label="路线名称" minWidth="140" align="center"></el-table-column>
  30. <el-table-column prop="lpCategoryName" label="类别" width="80" align="center"></el-table-column>
  31. <el-table-column prop="projectCatagory" label="业态" minWidth="80" align="center"></el-table-column>
  32. <el-table-column label="操作" width="80" align="center" fixed="right" class-name="table-flex-column-right">
  33. <template #default="scope">
  34. <i class="tree-icon el-icon-edit-outline" @click="routeEdit(scope.row)" v-if="checkMenuLimit('room/craft/Edit')"></i>
  35. <i class="tree-icon el-icon-delete" @click="routeDel(scope.row)" v-if="checkMenuLimit('room/craft/Delete')"></i>
  36. </template>
  37. </el-table-column>
  38. </el-table>
  39. </div>
  40. </el-card>
  41. </el-col>
  42. <el-col :span="14">
  43. <el-card shadow="hover">
  44. <template #header>
  45. <div class="card-header">
  46. <span class="card-title">设备类型/标准内容</span>
  47. <span style="display: flex;">
  48. <el-button size="mini" type="primary" @click="relationType" :disabled="!tableData.selectNode" v-if="checkMenuLimit('room/craft/level/Join')">关联类型</el-button>
  49. <el-upload
  50. action="device/deviceCraft/downloadTemplate"
  51. :headers="{Authorization: 'Bearer '+ token}"
  52. accept=".xlsx"
  53. :show-file-list="false"
  54. :on-success="uploadSuccess"
  55. v-if="checkMenuLimit('room/craft/Import')">
  56. <el-button size="mini" type="primary" style="margin-left: 8px">批量导入</el-button>
  57. </el-upload>
  58. </span>
  59. </div>
  60. </template>
  61. <div class="card-container">
  62. <el-table :data="tableData.tableList" v-loading="tableData.tableLoading" :height="props.resizeHeight - 242" row-key="id"
  63. stripe border fit lazy :load="loadTableList" :tree-props="{children: 'children', hasChildren: 'hasChildren'}">
  64. <el-table-column label="内容" minWidth="180" header-align="center" align="left">
  65. <template #default="scope">{{scope.row.name || scope.row.colName}}</template>
  66. </el-table-column>
  67. <el-table-column prop="colType" label="任务类型" width="140" align="center"></el-table-column>
  68. <el-table-column prop="isReq" label="是否必填" width="100" align="center"></el-table-column>
  69. <el-table-column label="操作" width="110" align="center" fixed="right" class-name="table-flex-column-right">
  70. <template #default="scope">
  71. <el-button size="mini" type="primary" @click="handleAdd(scope.row)" v-if="scope.row.level == 1 && checkMenuLimit('room/craft/standard/Add')">添加步骤</el-button>
  72. <el-button size="mini" type="danger" @click="handleDel(scope.row)" v-if="scope.row.level == 2 && checkMenuLimit('room/craft/standard/Delete')">删除</el-button>
  73. </template>
  74. </el-table-column>
  75. </el-table>
  76. <el-pagination background layout="prev, pager, next" :total="tableData.tableTotal" @current-change="handlePageChange"></el-pagination>
  77. </div>
  78. </el-card>
  79. </el-col>
  80. </el-row>
  81. <el-dialog
  82. :title="formData.routeFormType == 'add' ? '新增工艺路线' : '编辑工艺路线'"
  83. v-model="formData.routeFormShow"
  84. custom-class="table-dialog"
  85. width="500px">
  86. <el-form ref="routeFormRef" :model="formData.routeForm" :rules="formData.routeFormRules" label-width="100px" class="table-form">
  87. <el-row>
  88. <el-col :span="24">
  89. <el-form-item label="路线名称" prop="craftName">
  90. <el-input v-model="formData.routeForm.craftName"></el-input>
  91. </el-form-item>
  92. </el-col>
  93. </el-row>
  94. <el-row>
  95. <el-col :span="24">
  96. <el-form-item label="关联业态" prop="projectCatagoryCode">
  97. <el-select v-model="formData.routeForm.projectCatagoryCode" placeholder="请选择">
  98. <el-option v-for="item in dictionaryData.formatList" :key="item.value" :label="item.label" :value="item.value"></el-option>
  99. </el-select>
  100. </el-form-item>
  101. </el-col>
  102. </el-row>
  103. </el-form>
  104. <template #footer>
  105. <span class="dialog-footer">
  106. <el-button size="medium" @click="formData.routeFormShow = false">取 消</el-button>
  107. <el-button type="primary" size="medium" @click="submitRouteForm">确 定</el-button>
  108. </span>
  109. </template>
  110. </el-dialog>
  111. <el-dialog title="关联类型" v-model="formData.typeFormShow" custom-class="table-dialog" width="500px">
  112. <el-form ref="destroyFormRef" :model="formData.destroyForm" :rules="formData.destroyFormRules" label-width="120px" class="table-form">
  113. <el-row>
  114. <el-col :span="24">
  115. <el-form-item label="级别" prop="deviceLevelIds">
  116. <el-cascader v-model="formData.typeForm.deviceLevelIds" :options="dictionaryData.relationList"
  117. :props="{ multiple: true }" clearable filterable></el-cascader>
  118. </el-form-item>
  119. </el-col>
  120. </el-row>
  121. </el-form>
  122. <template #footer>
  123. <span class="dialog-footer">
  124. <el-button size="medium" @click="formData.typeFormShow = false">取消</el-button>
  125. <el-button type="primary" size="medium" @click="submitTypeForm">提交</el-button>
  126. </span>
  127. </template>
  128. </el-dialog>
  129. <el-dialog
  130. title="选择步骤"
  131. v-model="formData.stepFormShow"
  132. width="850px">
  133. <el-table ref="stepTableRef" row-key="fieldId" :data="tableData.stepTableList" v-loading="tableData.stepTableLoading" :height="300" stripe border fit
  134. @selection-change="stepSelectionChange">
  135. <el-table-column type="selection" width="55" align="center"></el-table-column>
  136. <el-table-column prop="gtfieldName" label="参数描述" minWidth="180" align="center"></el-table-column>
  137. <el-table-column prop="gtfieldTypeName" label="字段类型" minWidth="120" align="center"></el-table-column>
  138. <el-table-column label="必填" width="100" align="center">
  139. <template #default="scope">{{scope.row.requiredState == 1 ? '是' : '否'}}</template>
  140. </el-table-column>
  141. <el-table-column label="强制拍照" width="100" align="center">
  142. <template #default="scope">{{scope.row.photograph == 1 ? '是' : '否'}}</template>
  143. </el-table-column>
  144. <el-table-column label="强制扫码" width="100" align="center">
  145. <template #default="scope">{{scope.row.scan == 1 ? '是' : '否'}}</template>
  146. </el-table-column>
  147. </el-table>
  148. <template #footer>
  149. <span class="dialog-footer">
  150. <el-button size="medium" @click="formData.stepFormShow = false">取 消</el-button>
  151. <el-button type="primary" size="medium" @click="submitStepForm">确 定</el-button>
  152. </span>
  153. </template>
  154. </el-dialog>
  155. </div>
  156. </template>
  157. <script>
  158. import {reactive, ref, nextTick} from "vue";
  159. import {checkMenuLimit} from 'utils/util'
  160. import {setStore, getStore, getToken} from 'utils/store'
  161. import {
  162. getCurrencyDictionary,
  163. getRouteTypeDictionary,
  164. } from 'api/dictionary'
  165. import {
  166. getProcessTableListOfRoute,
  167. submitProcessFormOfRoute,
  168. submitDeleteProcessFormOfRoute,
  169. getStandardTableListOfRoute,
  170. getStandardStepTableListOfRoute,
  171. getStandardExistTypeListOfRoute,
  172. submitTypeFormOfRoute,
  173. getAvailableStepTableListOfRoute,
  174. submitStepFormOfRoute,
  175. submitDeleteStepFormOfRoute,
  176. } from 'api/device'
  177. import {
  178. ElNotification,
  179. ElMessage, ElMessageBox,
  180. } from "element-plus";
  181. export default {
  182. name: 'processRoute',
  183. props: {
  184. resizeHeight: {
  185. default: 500,
  186. },
  187. },
  188. setup(props, context){
  189. // 凭证
  190. let token = ref('')
  191. token = getToken()
  192. // 字典参数
  193. let dictionaryData = reactive({
  194. formatList: [],
  195. relationList: [],
  196. })
  197. getCurrencyDictionary({
  198. dictCode: 'projectCatagory',
  199. }).then(res => {
  200. if (res.status == 200) {
  201. dictionaryData.formatList = res.data
  202. } else {
  203. ElNotification({
  204. title: '获取业态失败',
  205. message: res.message,
  206. type: 'error'
  207. });
  208. }
  209. })
  210. // 表单参数
  211. let routeFormRef = ref(null)
  212. let formData = reactive({
  213. // 工艺路线
  214. filterForm: {
  215. craftName: '',
  216. projectCatagoryCode: '',
  217. },
  218. routeFormShow: false,
  219. routeFormType: '',
  220. routeForm: {
  221. craftId: '',
  222. craftName: '',
  223. projectCatagoryCode: '',
  224. },
  225. routeFormRules: {
  226. craftName: [
  227. {required: true, message: '请输入路线名称', trigger: 'blur'}
  228. ],
  229. projectCatagoryCode: [
  230. {required: true, message: '请选择关联业态', trigger: 'change'}
  231. ],
  232. },
  233. // 关联类型
  234. typeFormShow: false,
  235. typeForm:{
  236. deviceLevelIds: []
  237. },
  238. // 关联步骤
  239. stepForm: {
  240. gtFormId: '',
  241. fieldIds: [],
  242. },
  243. stepFormShow: false,
  244. })
  245. // 表格参数
  246. let stepTableRef = ref(null)
  247. let tableData = reactive({
  248. // 工艺路线
  249. selectNode: null,
  250. treeTableList: [],
  251. treeTableLoading: false,
  252. // 标准内容
  253. tableList: [],
  254. pageIndex: 1,
  255. pageSize: 10,
  256. tableTotal: 0,
  257. tableLoading: false,
  258. // 关联步骤
  259. stepTableList: [],
  260. stepTableLoading: false,
  261. })
  262. // 获取工艺路线表格数据
  263. function getTreeTableList () {
  264. tableData.treeTableLoading = true
  265. getProcessTableListOfRoute({
  266. craftName: formData.filterForm.craftName,
  267. projectCatagoryCode: formData.filterForm.projectCatagoryCode,
  268. userId: getStore({name: 'userIdJH'}),
  269. companyId: getStore({name: 'companyIdJH'}),
  270. }).then(res => {
  271. tableData.treeTableLoading = false
  272. if (res.status == 200) {
  273. tableData.treeTableList = res.data
  274. } else {
  275. ElNotification({
  276. title: '获取工艺路线列表失败',
  277. message: res.message,
  278. type: 'error'
  279. });
  280. }
  281. })
  282. }
  283. // 树形结构点击节点
  284. function nodeClick (row, column,) {
  285. tableData.selectNode = row
  286. getTableList()
  287. }
  288. // 工艺路线新增
  289. function routeAdd () {
  290. formData.routeFormShow = true
  291. formData.routeFormType = 'add'
  292. if (routeFormRef.value){
  293. routeFormRef.value.resetFields()
  294. }
  295. }
  296. // 工艺路线编辑
  297. function routeEdit (data) {
  298. formData.routeFormShow = true
  299. formData.routeFormType = 'edit'
  300. if (routeFormRef.value){
  301. routeFormRef.value.clearValidate()
  302. }
  303. formData.routeForm = {
  304. craftId: data.id,
  305. craftName: data.craftName,
  306. projectCatagoryCode: data.projectCatagoryCode,
  307. }
  308. }
  309. // 工艺路线删除
  310. function routeDel (data) {
  311. ElMessageBox.confirm('是否删除,删除后无法找回!', '提示', {
  312. confirmButtonText: '确定',
  313. cancelButtonText: '取消',
  314. type: 'warning'
  315. }).then(() => {
  316. submitDeleteProcessFormOfRoute({
  317. craftId: data.id,
  318. companyId: getStore({name: 'companyIdJH'}),
  319. }).then(res => {
  320. if (res.status == 200) {
  321. ElNotification({
  322. title: '删除成功',
  323. type: 'success'
  324. });
  325. getTreeTableList()
  326. } else {
  327. ElNotification({
  328. title: '删除失败',
  329. message: res.message,
  330. type: 'error'
  331. });
  332. }
  333. })
  334. })
  335. }
  336. // 切换表格页数
  337. function handlePageChange (val) {
  338. tableData.pageIndex = val
  339. getTableList()
  340. }
  341. // 获取表格数据
  342. function getTableList () {
  343. tableData.tableLoading = true
  344. tableData.tableList = []
  345. getStandardTableListOfRoute({
  346. craftId: tableData.selectNode.id,
  347. pageIndex: tableData.pageIndex,
  348. pageSize: tableData.pageSize,
  349. }).then(res => {
  350. tableData.tableLoading = false
  351. if (res.status == 200) {
  352. tableData.tableList = res.data.records.map(site => {
  353. return {
  354. ...site,
  355. level: 1,
  356. hasChildren: true,
  357. }
  358. })
  359. tableData.tableTotal = res.data.total
  360. } else {
  361. ElNotification({
  362. title: '获取设备类型/标准内容列表失败',
  363. message: res.message,
  364. type: 'error'
  365. });
  366. }
  367. })
  368. }
  369. // 懒加载标准表格数据
  370. function loadTableList (tree, treeNode, resolve) {
  371. getStandardStepTableListOfRoute({
  372. gtformId: tree.id
  373. }).then(res => {
  374. if (res.status == 200) {
  375. resolve(res.data.map(site => {
  376. return {
  377. ...site,
  378. level: 2,
  379. hasChildren: false,
  380. }
  381. }))
  382. } else {
  383. ElNotification({
  384. title: '获取设备类型/标准内容列表失败',
  385. message: res.message,
  386. type: 'error'
  387. });
  388. }
  389. })
  390. }
  391. // 关联类型
  392. function relationType () {
  393. getRouteTypeDictionary({
  394. format: tableData.selectNode.projectCatagoryCode,
  395. }).then(res => {
  396. if (res.status == 200) {
  397. dictionaryData.relationList = res.data.map(item => {
  398. return {
  399. value: item.id,
  400. label: item.sysName,
  401. children: item.levelList && item.levelList.length ? item.levelList.map(site =>{
  402. return{
  403. value: site.id,
  404. label: site.title,
  405. }
  406. }) : [],
  407. }
  408. })
  409. } else {
  410. ElNotification({
  411. title: '请求出错',
  412. message: res.message,
  413. type: 'error'
  414. });
  415. }
  416. })
  417. getStandardExistTypeListOfRoute({
  418. craftId: tableData.selectNode.id,
  419. projectCatagoryCode: tableData.selectNode.projectCatagoryCode,
  420. }).then(res => {
  421. if (res.status == 200) {
  422. formData.typeFormShow = true
  423. formData.typeForm.deviceLevelIds = res.data.records.map(site => {
  424. return [site.sysId, site.levelId]
  425. })
  426. } else {
  427. ElNotification({
  428. title: '请求出错',
  429. message: res.message,
  430. type: 'error'
  431. });
  432. }
  433. })
  434. }
  435. // 表格添加步骤操作
  436. function handleAdd (data) {
  437. tableData.stepTableLoading = true
  438. getAvailableStepTableListOfRoute({
  439. gtformId: data.id,
  440. }).then(res => {
  441. if (res.status == 200) {
  442. tableData.stepTableList = res.data.all
  443. tableData.stepTableLoading = false
  444. formData.stepFormShow = true
  445. formData.stepForm.gtFormId = data.id
  446. nextTick(function() {
  447. let selectList = res.data.checked.map(site => {
  448. return site.fieldId
  449. })
  450. let selectNodeList = tableData.stepTableList.filter(site => selectList.indexOf(site.fieldId) != -1)
  451. selectNodeList.forEach(site => {
  452. stepTableRef.value.toggleRowSelection(site);
  453. })
  454. })
  455. } else {
  456. ElNotification({
  457. title: '请求出错',
  458. message: res.message,
  459. type: 'error'
  460. });
  461. }
  462. })
  463. }
  464. // 表格删除操作
  465. function handleDel (data) {
  466. ElMessageBox.confirm('是否删除,删除后无法找回!', '提示', {
  467. confirmButtonText: '确定',
  468. cancelButtonText: '取消',
  469. type: 'warning'
  470. }).then(() => {
  471. submitDeleteStepFormOfRoute({
  472. gtFormId: data.gtformId,
  473. gtFormFieldId: data.id,
  474. }).then(res => {
  475. if (res.status == 200) {
  476. ElNotification({
  477. title: '删除成功',
  478. type: 'success'
  479. });
  480. getTableList()
  481. } else {
  482. ElNotification({
  483. title: '删除失败',
  484. message: res.message,
  485. type: 'error'
  486. });
  487. }
  488. })
  489. })
  490. }
  491. // 提交工艺路线表单
  492. function submitRouteForm () {
  493. routeFormRef.value.validate((valid) => {
  494. if (valid) {
  495. submitProcessFormOfRoute(formData.routeForm).then(res => {
  496. if (res.status == 200) {
  497. formData.routeFormShow = false
  498. getTreeTableList()
  499. ElNotification({
  500. title: formData.routeFormType == 'add' ? '新增成功' : '编辑成功',
  501. message: res.message,
  502. type: 'success'
  503. });
  504. } else {
  505. ElNotification({
  506. title: '请求出错',
  507. message: res.message,
  508. type: 'error'
  509. });
  510. }
  511. })
  512. }
  513. });
  514. }
  515. // 提交关联类型表单
  516. function submitTypeForm () {
  517. submitTypeFormOfRoute({
  518. deviceCraftId: tableData.selectNode.id,
  519. deviceLevelIds: formData.typeForm.deviceLevelIds.map(site => {
  520. return site[1]
  521. }),
  522. }).then(res => {
  523. if (res.status == 200) {
  524. formData.typeFormShow = false
  525. tableData.pageIndex = 1
  526. getTableList()
  527. ElNotification({
  528. title: '关联成功',
  529. message: res.message,
  530. type: 'success'
  531. });
  532. } else {
  533. ElNotification({
  534. title: '请求出错',
  535. message: res.message,
  536. type: 'error'
  537. });
  538. }
  539. })
  540. }
  541. // 勾选步骤
  542. function stepSelectionChange(data) {
  543. formData.stepForm.fieldIds = data.map(site => {
  544. return site.fieldId
  545. })
  546. }
  547. // 提交步骤表单
  548. function submitStepForm () {
  549. submitStepFormOfRoute({
  550. gtFormId: formData.stepForm.gtFormId,
  551. fieldIds: formData.stepForm.fieldIds.join(','),
  552. }).then(res => {
  553. if (res.status == 200) {
  554. formData.stepFormShow = false
  555. tableData.pageIndex = 1
  556. getTableList()
  557. ElNotification({
  558. title: '新增成功',
  559. message: res.message,
  560. type: 'success'
  561. });
  562. } else {
  563. ElNotification({
  564. title: '请求出错',
  565. message: res.message,
  566. type: 'error'
  567. });
  568. }
  569. })
  570. }
  571. // 上传附件成功
  572. function uploadSuccess (res, file, fileList) {
  573. if (res.status == 200) {
  574. ElNotification({
  575. title: '上传成功',
  576. message: res.message,
  577. type: 'success'
  578. });
  579. } else {
  580. ElNotification({
  581. title: '上传失败',
  582. message: res.message,
  583. type: 'error'
  584. });
  585. }
  586. }
  587. getTreeTableList()
  588. // 暴露
  589. return {
  590. checkMenuLimit,
  591. token,
  592. props,
  593. // 字典
  594. dictionaryData,
  595. getTreeTableList,
  596. nodeClick,
  597. routeAdd,
  598. routeEdit,
  599. routeDel,
  600. handlePageChange,
  601. tableData,
  602. loadTableList,
  603. relationType,
  604. handleAdd,
  605. handleDel,
  606. formData,
  607. routeFormRef,
  608. stepTableRef,
  609. submitRouteForm,
  610. submitTypeForm,
  611. stepSelectionChange,
  612. submitStepForm,
  613. // 上传
  614. uploadSuccess,
  615. }
  616. }
  617. }
  618. </script>
  619. <style scoped lang="scss">
  620. .tree-icon{
  621. font-size: 16px;
  622. color: #2d8cf0;
  623. font-weight: bold;
  624. margin: 0 4px;
  625. cursor: pointer;
  626. }
  627. .tree-icon:hover{
  628. color: #2db7f5;
  629. }
  630. </style>