index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. <template>
  2. <div class="mainContentBox">
  3. <avue-crud
  4. ref="crudRef"
  5. v-model:search="search"
  6. v-model="form"
  7. :data="data"
  8. :option="option"
  9. v-model:page="page"
  10. @row-save="createRow"
  11. @row-update="updateRow"
  12. @search-change="searchChange"
  13. @search-reset="resetChange"
  14. @size-change="dataList"
  15. @current-change="dataList"
  16. @selection-change="selectionChange"
  17. >
  18. <template #usable="{ row }">
  19. <el-tag v-if="row.usable == '1'" type="success">已绑定</el-tag>
  20. <el-tag v-else type="info">未绑定</el-tag>
  21. </template>
  22. <template #productManager-form="{ row }">
  23. <el-select
  24. v-model="form.productManager"
  25. placeholder="产品负责人"
  26. filterable
  27. >
  28. <el-option
  29. v-for="item in userList"
  30. :key="item.userName"
  31. :label="item.userName"
  32. :value="item.userName"
  33. />
  34. </el-select>
  35. </template>
  36. <!-- :disabled="row.usable == '1' ? false : true" -->
  37. <!--<template #menu-right="{}">
  38. <el-dropdown split-button
  39. >导入
  40. <template #dropdown>
  41. <el-dropdown-menu>
  42. <el-dropdown-item
  43. @click="downloadTemplate('/api/v1/op/route/template')"
  44. >
  45. <i-ep-download />下载模板
  46. </el-dropdown-item>
  47. <el-dropdown-item @click="importExcelData">
  48. <i-ep-top />导入数据
  49. </el-dropdown-item>
  50. </el-dropdown-menu>
  51. </template>
  52. </el-dropdown>
  53. </template>-->
  54. <template #menu="{ row }">
  55. <el-button
  56. link
  57. type="primary"
  58. icon="el-icon-edit"
  59. v-if="row.usable === 0"
  60. @click="doEdit(row, index)"
  61. >编辑</el-button
  62. >
  63. <el-button
  64. link
  65. type="primary"
  66. icon="el-icon-edit"
  67. v-else
  68. @click="showProductManager(row, index)"
  69. >编辑</el-button
  70. >
  71. <el-button
  72. link
  73. type="danger"
  74. icon="el-icon-edit"
  75. v-if="row.usable === 0"
  76. @click="deleteRow(row, index)"
  77. >删除</el-button
  78. >
  79. <el-button
  80. link
  81. type="primary"
  82. v-if="row.upgradeVersion === '1'"
  83. icon="el-icon-notification"
  84. @click="changeLog(row)"
  85. >修改记录</el-button
  86. >
  87. <el-button
  88. link
  89. type="primary"
  90. v-if="row.isMain === '0'"
  91. icon="el-icon-setting"
  92. @click="setMain(row)"
  93. >主路线</el-button
  94. >
  95. <el-button
  96. link
  97. icon="el-icon-copy-document"
  98. :disabled="false"
  99. @click="copyRow(row)"
  100. >升版</el-button
  101. >
  102. <el-button
  103. link
  104. icon="el-icon-copy-document"
  105. @click="bindProcessPop(row)"
  106. >绑定</el-button
  107. >
  108. </template>
  109. </avue-crud>
  110. <CommonTable
  111. ref="ctableRef"
  112. tableTitle="添加产品"
  113. tableType="MARTERIAL"
  114. @selected-sure="onSelectedFinish"
  115. />
  116. <CommonTable
  117. ref="commonRef"
  118. tableTitle="选择通用工艺"
  119. tableType="ROUTE_COMMON"
  120. @selected-sure="onCommonFinish"
  121. />
  122. <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
  123. <el-dialog
  124. v-model="centerDialogVisible"
  125. title="重命名"
  126. width="500"
  127. align-center
  128. >
  129. <el-form :model="tmpForm" label-width="auto" style="max-width: 800px">
  130. <el-row>
  131. <el-col :span="12">
  132. <el-form-item label="工艺路线编号">
  133. <el-input v-model="tmpForm.processRouteCode" />
  134. </el-form-item>
  135. </el-col>
  136. <el-col :span="12">
  137. <el-form-item label="工艺路线名称">
  138. <el-input v-model="tmpForm.processRouteName" />
  139. </el-form-item>
  140. </el-col>
  141. </el-row>
  142. </el-form>
  143. <template #footer>
  144. <div class="dialog-footer">
  145. <el-button @click="centerDialogVisible = false">取消</el-button>
  146. <el-button type="primary" @click="renameRoute()"> 确定 </el-button>
  147. </div>
  148. </template>
  149. </el-dialog>
  150. <el-dialog
  151. v-model="productManagerVisible"
  152. title="编辑产品负责人"
  153. width="500"
  154. align-center
  155. >
  156. <el-form
  157. :model="form"
  158. label-width="auto"
  159. style="max-width: 800px"
  160. :rules="rules"
  161. >
  162. <el-form-item label="产品负责人" prop="productManager">
  163. <el-select
  164. v-model="form.productManager"
  165. placeholder="产品负责人"
  166. filterable
  167. >
  168. <el-option
  169. v-for="item in userList"
  170. :key="item.userName"
  171. :label="item.userName"
  172. :value="item.userName"
  173. />
  174. </el-select>
  175. </el-form-item>
  176. </el-form>
  177. <template #footer>
  178. <div class="dialog-footer">
  179. <el-button @click="sureCancelProductManager">取消</el-button>
  180. <el-button type="primary" @click="sureToEditProductManager">
  181. 确定
  182. </el-button>
  183. </div>
  184. </template>
  185. </el-dialog>
  186. <el-dialog
  187. v-model="dialog1.visible"
  188. :title="dialog1.title"
  189. width="900px"
  190. @close="dialog1.visible = false"
  191. :destroy-on-close="true"
  192. >
  193. <RouteChangeLog :targetRouteId="routeDeatil.id" />
  194. </el-dialog>
  195. <el-dialog
  196. v-model="dialog2.visible"
  197. :title="dialog2.title"
  198. width="900px"
  199. @close="dialog2.visible = false"
  200. :destroy-on-close="true"
  201. >
  202. <el-table
  203. :data="tableData"
  204. style="width: 100%"
  205. ref="singleTableRef"
  206. highlight-current-row
  207. @current-change="handleCurrentChange"
  208. >
  209. <el-table-column type="index" width="50" />
  210. <el-table-column prop="id" label="id" width="180" v-if="false" />
  211. <el-table-column
  212. prop="processRouteName"
  213. label="工艺路线名称"
  214. width="180"
  215. />
  216. <el-table-column
  217. prop="processRouteCode"
  218. label="工艺路线编码"
  219. width="180"
  220. />
  221. <el-table-column prop="processRouteVersion" label="版本" />
  222. <el-table-column prop="prodtName" label="产品名称" />
  223. <el-table-column prop="prodtModel" label="产品规格" width="180" />
  224. </el-table>
  225. <template #footer>
  226. <div class="footer">
  227. <el-button type="primary" @click="copyProcess()" :loading="isLoading"
  228. >复制</el-button
  229. >
  230. <el-button
  231. type="primary"
  232. @click="bindProcess(rowDetail)"
  233. :loading="loading"
  234. >自定义</el-button
  235. >
  236. <el-button @click="dialog2.visible = false">取消</el-button>
  237. </div>
  238. </template>
  239. </el-dialog>
  240. </div>
  241. </template>
  242. <script setup>
  243. import { ref, getCurrentInstance } from "vue";
  244. import { useCrud } from "@/hooks/userCrud";
  245. import dictDataUtil from "@/common/configs/dictDataUtil";
  246. import { useDictionaryStore } from "@/store";
  247. import {
  248. copyList,
  249. copyProductRoute,
  250. copyRoute,
  251. editRouteWith,
  252. getMaxRouteVersion,
  253. updateMain,
  254. } from "@/api/craft/route/index";
  255. import { getUserList } from "@/api/system/user/index";
  256. import RouteChangeLog from "@/views/base/craftManagement/route/components/routeChangeLog.vue";
  257. import { ElMessageBox } from "element-plus";
  258. const isLoading = ref(false);
  259. const loading = ref(false);
  260. // 数据字典相关
  261. const { dicts } = useDictionaryStore();
  262. const sureCancelProductManager = () => {
  263. productManagerVisible.value = false;
  264. dataList();
  265. form.value = {};
  266. };
  267. const tableData = ref([]);
  268. const currentRow = ref();
  269. const singleTableRef = ref(null);
  270. const handleCurrentChange = (val) => {
  271. currentRow.value = val;
  272. };
  273. const setMain = (row) => {
  274. ElMessageBox.confirm("是否将该工艺路线设置为主路线?", "提示", {
  275. confirmButtonText: "确定",
  276. cancelButtonText: "取消",
  277. type: "warning",
  278. }).then(async () => {
  279. updateMain(row).then((data) => {
  280. ElMessage.success(data.msg);
  281. dataList();
  282. });
  283. });
  284. };
  285. const dialog1 = ref({
  286. title: "修改记录",
  287. visible: false,
  288. });
  289. const dialog2 = ref({
  290. title: "绑定",
  291. visible: false,
  292. });
  293. const routeData = ref({});
  294. // 传入一个url,后面不带/
  295. const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
  296. useCrud({
  297. src: "/api/v1/op/route",
  298. afterAdd: (routeData) => {
  299. if (routeData.sourceRouteId) {
  300. router.push({
  301. path: `/base/craftManagement/bindProcess/${routeData.id}/${routeData.prodtCode}`,
  302. });
  303. }
  304. },
  305. });
  306. const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
  307. Methords; //增删改查
  308. const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
  309. const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
  310. // checkBtnPerm(ButtonPermKeys.PLAN.BTNS.order_add) :permission="permission"
  311. // const permission = reactive({
  312. // delBtn: checkPerm(buttonPermission.PLAN.BTNS.order_del),
  313. // addBtn: checkPerm(buttonPermission.PLAN.BTNS.order_add),
  314. // editBtn: checkPerm(buttonPermission.PLAN.BTNS.order_edit),
  315. // menu: true,
  316. // });
  317. const rowDetail = ref({});
  318. let centerDialogVisible = ref(false);
  319. const crudRef = ref(null); //crudRef.value 获取avue-crud对象
  320. const tmpForm = ref({});
  321. // 产品负责人相关
  322. const userList = ref([]);
  323. const currentPMRow = ref({});
  324. const productManagerVisible = ref(false);
  325. const showProductManager = (row, index) => {
  326. productManagerVisible.value = true;
  327. currentPMRow.value = row;
  328. form.value = row;
  329. };
  330. const rules = reactive({
  331. productManager: [
  332. { required: true, message: "产品管理员不能为空", trigger: "blur" },
  333. ],
  334. });
  335. const sureToEditProductManager = () => {
  336. editRouteWith(currentPMRow.value).then(() => {
  337. dataList();
  338. productManagerVisible.value = false;
  339. form.value = {};
  340. });
  341. };
  342. const copyProductProject = ref({});
  343. const copyProcess = () => {
  344. if (!currentRow.value) {
  345. ElMessage.error("未选择要复制工艺路线!");
  346. return;
  347. }
  348. isLoading.value = true;
  349. loading.value = true;
  350. copyProductProject.value.sourceId = currentRow.value.id;
  351. copyProductProject.value.targetId = rowDetail.value.id;
  352. copyProductRoute(copyProductProject.value)
  353. .then((data) => {
  354. if (data.code === "200") {
  355. isLoading.value = false;
  356. loading.value = false;
  357. dialog2.value.visible = false;
  358. dataList();
  359. ElMessage.success(data.msg);
  360. }
  361. })
  362. .finally(() => {
  363. isLoading.value = false;
  364. loading.value = false;
  365. });
  366. };
  367. onMounted(() => {
  368. // console.log("crudRef", crudRef)
  369. dataList();
  370. getUserList({}).then((data) => {
  371. userList.value = data.data;
  372. });
  373. });
  374. /**
  375. * 上传excel相关
  376. */
  377. const uploadRef = ref(null);
  378. const uploadFinished = () => {
  379. // 上传完成后的刷新操作
  380. page.currentPage = 1;
  381. dataList();
  382. };
  383. const routeDeatil = ref({});
  384. const changeLog = (row) => {
  385. routeDeatil.value = row;
  386. dialog1.value.visible = true;
  387. };
  388. const doEdit = (row, index) => {
  389. row.prodtName1 = row.prodtName;
  390. crudRef.value && crudRef.value.rowEdit(row, index);
  391. };
  392. const importExcelData = () => {
  393. if (uploadRef.value) {
  394. uploadRef.value.show("/api/v1/op/route/import");
  395. }
  396. };
  397. // 选择产品相关
  398. const ctableRef = ref(null);
  399. const commonRef = ref(null);
  400. const onSelectedFinish = (selectedValue) => {
  401. // search.value.prodtName = selectedValue.materialName;
  402. form.value.prodtName = selectedValue.materialName;
  403. form.value.prodtName1 = selectedValue.materialName;
  404. form.value.prodtCode = selectedValue.materialCode;
  405. form.value.prodtModel = selectedValue.spec;
  406. };
  407. const onCommonFinish = (selectedValue) => {
  408. form.value.commonRouteId = selectedValue.id;
  409. form.value.commonRouteName = selectedValue.processRouteName;
  410. form.value.commonRouteCode = selectedValue.processRouteCode;
  411. };
  412. const startChooseProduct = () => {
  413. if (ctableRef.value) {
  414. ctableRef.value.startSelect();
  415. }
  416. };
  417. const startChooseRoute = () => {
  418. if (ctableRef.value) {
  419. commonRef.value.startSelect();
  420. }
  421. };
  422. // 已经绑定了工序的可以复制,跟后端HT商量只传id即可。
  423. const copyRow = (row) => {
  424. option.value.column.forEach((item) => {
  425. if (item.prop === "commonRouteCode" || item.prop === "commonRouteName") {
  426. item.display = false;
  427. }
  428. });
  429. if (row.usable == 0) {
  430. ElMessage.error("该路线未被绑定!");
  431. return;
  432. }
  433. getMaxRouteVersion(row.prodtCode).then((data) => {
  434. if (data.code === "200") {
  435. form.value = Object.assign(form.value, row);
  436. form.value.processRouteVersion = "";
  437. if (data.data) {
  438. form.value.processRouteVersion = (parseFloat(data.data) + 1).toFixed(1);
  439. }
  440. form.value.prodtName1 = row.prodtName;
  441. crudRef.value.rowAdd();
  442. }
  443. });
  444. };
  445. const renameRoute = () => {
  446. tmpForm.value.id;
  447. tmpForm.value.processRouteCode;
  448. tmpForm.value.processRouteName;
  449. copyRoute(tmpForm.value).then(() => {
  450. tmpForm.value.id = undefined;
  451. tmpForm.value.processRouteCode = undefined;
  452. tmpForm.value.processRouteName = undefined;
  453. page.currentPage = 1;
  454. dataList();
  455. });
  456. centerDialogVisible.value = false;
  457. };
  458. const router = useRouter();
  459. // 绑定工序
  460. const bindProcess = (row) => {
  461. router.push({
  462. path: `/base/craftManagement/bindProcess/${row.id}/${row.prodtCode}`,
  463. });
  464. };
  465. const bindProcessPop = (row) => {
  466. if (row.routeData) {
  467. router.push({
  468. path: `/base/craftManagement/bindProcess/${row.id}/${row.prodtCode}`,
  469. });
  470. return;
  471. }
  472. copyList(row).then((data) => {
  473. tableData.value = data.data;
  474. console.log(tableData.value);
  475. if (!tableData.value || tableData.value.length == 0) {
  476. router.push({
  477. path: `/base/craftManagement/bindProcess/${row.id}/${row.prodtCode}`,
  478. });
  479. return;
  480. }
  481. rowDetail.value = row;
  482. dialog2.value.visible = true;
  483. });
  484. };
  485. // 设置表格列或者其他自定义的option
  486. option.value = Object.assign(option.value, {
  487. searchEnter: true,
  488. selection: true,
  489. labelWidth: 150,
  490. menuWidth: 250,
  491. delBtn: false,
  492. searchLabelWidth: 110,
  493. editBtn: false,
  494. rowParentKey: "mainCode",
  495. column: [
  496. {
  497. label: "工艺路线名称",
  498. prop: "processRouteName",
  499. width: 150,
  500. search: true,
  501. overHidden: true,
  502. rules: [
  503. {
  504. required: true,
  505. message: "工艺路线名称不能为空",
  506. trigger: "blur",
  507. },
  508. ],
  509. },
  510. {
  511. label: "工艺路线编号",
  512. prop: "processRouteCode",
  513. search: true,
  514. width: 150,
  515. addDisplay: true,
  516. editDisabled: true,
  517. overHidden: true,
  518. display: false,
  519. },
  520. {
  521. label: "工艺路线类型",
  522. prop: "processRouteType",
  523. minWidth: 120,
  524. search: true,
  525. overHidden: true,
  526. rules: [
  527. {
  528. required: true,
  529. message: "工艺路线类型不能为空",
  530. trigger: "change",
  531. },
  532. ],
  533. type: "select",
  534. dicUrl: dictDataUtil.request_url + dictDataUtil.TYPE_CODE.routing_type,
  535. props: {
  536. label: "dictLabel",
  537. value: "dictValue",
  538. },
  539. },
  540. {
  541. label: "通用工艺id",
  542. prop: "commonRouteId",
  543. addDisplay: false,
  544. editDisplay: false,
  545. hide: true,
  546. width: 150,
  547. overHidden: true,
  548. },
  549. {
  550. label: "通用工艺名称",
  551. prop: "commonRouteName",
  552. editDisplay: false,
  553. width: 150,
  554. overHidden: true,
  555. click: () => {
  556. startChooseRoute();
  557. },
  558. },
  559. {
  560. label: "通用工艺编码",
  561. prop: "commonRouteCode",
  562. disabled: true,
  563. editDisplay: false,
  564. width: 150,
  565. overHidden: true,
  566. },
  567. {
  568. label: "执行文件和标准",
  569. prop: "executeFileStd",
  570. width: 180,
  571. addDisplay: true,
  572. editDisabled: true,
  573. overHidden: true,
  574. rules: [
  575. {
  576. required: true,
  577. message: "执行文件和标准不能为空",
  578. trigger: "blur",
  579. },
  580. ],
  581. },
  582. {
  583. label: "是否查看产品文档",
  584. prop: "documentShow",
  585. hide: true,
  586. type: "select",
  587. display: true,
  588. rules: [
  589. {
  590. required: true,
  591. trigger: "blur",
  592. },
  593. ],
  594. dicData: [
  595. {
  596. label: "是",
  597. value: 1,
  598. },
  599. {
  600. label: "否",
  601. value: 0,
  602. },
  603. ],
  604. value: 0,
  605. },
  606. {
  607. label: "产品名称",
  608. prop: "prodtName",
  609. overHidden: true,
  610. width: 150,
  611. search: true,
  612. editDisplay: false,
  613. addDisplay: false,
  614. rules: [
  615. {
  616. required: true,
  617. message: "请选择产品",
  618. trigger: "blur",
  619. },
  620. ],
  621. },
  622. {
  623. label: "产品名称",
  624. prop: "prodtName1",
  625. overHidden: true,
  626. hide: true,
  627. viewDisplay: false,
  628. width: 150,
  629. rules: [
  630. {
  631. required: true,
  632. message: "请选择产品",
  633. trigger: "blur",
  634. },
  635. ],
  636. readOnly: true,
  637. click: () => {
  638. startChooseProduct();
  639. },
  640. change: ({ value, column }) => {
  641. if (value != form.value.prodtName1) {
  642. startChooseProduct();
  643. }
  644. },
  645. },
  646. {
  647. label: "产品编号",
  648. prop: "prodtCode",
  649. overHidden: true,
  650. search: true,
  651. width: 150,
  652. disabled: true,
  653. },
  654. {
  655. label: "产品负责人",
  656. prop: "productManager",
  657. width: 120,
  658. slot: true,
  659. rules: [
  660. {
  661. required: true,
  662. message: "工艺路线类型不能为空",
  663. trigger: "change",
  664. },
  665. ],
  666. },
  667. {
  668. label: "产品型号",
  669. prop: "prodtModel",
  670. overHidden: true,
  671. search: true,
  672. minWidth: 200,
  673. disabled: true,
  674. },
  675. // 在产品那边绑定了工艺路线才是已绑定
  676. {
  677. label: "路线状态",
  678. prop: "usable",
  679. addDisplay: false,
  680. editDisplay: false,
  681. slot: true,
  682. width: 100,
  683. type: "radio",
  684. dicData: [
  685. {
  686. label: "已绑定",
  687. value: 1,
  688. },
  689. {
  690. label: "未绑定",
  691. value: 0,
  692. },
  693. ],
  694. },
  695. {
  696. label: "启用状态",
  697. prop: "enabled",
  698. addDisplay: false,
  699. // editDisplay: false,
  700. slot: true,
  701. width: 100,
  702. type: "radio",
  703. dicData: [
  704. {
  705. label: "未启用",
  706. value: 1,
  707. },
  708. {
  709. label: "启用",
  710. value: 0,
  711. },
  712. ],
  713. value: 0,
  714. },
  715. // 只有绑定了工序才可以复制。
  716. {
  717. label: "是否可复制",
  718. prop: "usable2",
  719. slot: true,
  720. width: 100,
  721. search: false,
  722. filterable: true,
  723. hide: true,
  724. addDisplay: false,
  725. editDisplay: false,
  726. type: "radio",
  727. dicData: [
  728. {
  729. label: "否",
  730. value: 0,
  731. },
  732. {
  733. label: "是",
  734. value: 1,
  735. },
  736. ],
  737. value: 0,
  738. },
  739. {
  740. label: "版本",
  741. prop: "processRouteVersion",
  742. addDisplay: true,
  743. editDisplay: true,
  744. value: "1.0",
  745. rules: [
  746. {
  747. required: true,
  748. message: "版本不能为空",
  749. trigger: "blur",
  750. },
  751. ],
  752. precision: 1,
  753. },
  754. {
  755. label: "来源版本",
  756. prop: "sourceVersion",
  757. display: false,
  758. },
  759. {
  760. label: "创建人",
  761. prop: "creator",
  762. addDisplay: false,
  763. editDisplay: false,
  764. overHidden: true,
  765. },
  766. {
  767. label: "创建时间",
  768. prop: "created",
  769. addDisplay: false,
  770. editDisplay: false,
  771. width: 150,
  772. overHidden: true,
  773. },
  774. {
  775. label: "主分支编码",
  776. prop: "mainCode",
  777. width: 150,
  778. hide: true,
  779. display: false,
  780. },
  781. ],
  782. });
  783. </script>