index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. <template>
  2. <div class="tenant">
  3. <!-- <Banner /> -->
  4. <div class="content">
  5. <byTable
  6. :source="sourceList.data"
  7. :pagination="sourceList.pagination"
  8. :config="config"
  9. :loading="loading"
  10. highlight-current-row
  11. :selectConfig="selectConfig"
  12. :table-events="{
  13. //element talbe事件都能传
  14. select: select,
  15. }"
  16. :action-list="[
  17. {
  18. text: '添加工艺',
  19. action: () => openModal('add'),
  20. },
  21. ]"
  22. @get-list="getList"
  23. >
  24. <template #line="{ item }">
  25. <span v-for="(x, i) in item.processRouteNameList" :key="i">
  26. {{ x }}
  27. <span
  28. style="margin: 0 3px"
  29. v-if="i + 1 < item.processRouteNameList.length"
  30. >>
  31. </span>
  32. </span>
  33. </template>
  34. <template #product="{ item }">
  35. <span v-for="(x, i) in item.applicableProductsNameList" :key="i">
  36. {{ x }}
  37. <span v-if="i + 1 < item.applicableProductsNameList.length"
  38. >,
  39. </span>
  40. </span>
  41. </template>
  42. </byTable>
  43. </div>
  44. <el-dialog
  45. :title="modalType == 'add' ? '添加工艺' : '编辑工艺'"
  46. v-model="dialogVisible"
  47. width="650"
  48. v-loading="loading"
  49. >
  50. <byForm
  51. :formConfig="formConfig"
  52. :formOption="formOption"
  53. v-model="formData.data"
  54. :rules="rules"
  55. ref="byform"
  56. >
  57. <template #lineSlot>
  58. <el-transfer
  59. v-model="selectLine"
  60. filterable
  61. filter-placeholder="搜索"
  62. :data="lineData"
  63. :titles="['可选', '已选']"
  64. target-order="push"
  65. >
  66. <template #default="{ option }">
  67. <div class="parent">
  68. <!-- 只有选择的数据才能拖拽 -->
  69. <div
  70. :draggable="selectLine.includes(option.key)"
  71. @dragstart="dragStar($event, option)"
  72. @dragover="dragOver($event, option)"
  73. @drop="handleDrop($event)"
  74. style="cursor: default"
  75. :id="option.key"
  76. >
  77. {{ option.label }}
  78. </div>
  79. </div>
  80. </template>
  81. </el-transfer>
  82. </template>
  83. <template #productSlot>
  84. <div>
  85. <el-button type="primary" @click="openProduct = true">
  86. 添加产品
  87. </el-button>
  88. <div style="margin-top: 15px">
  89. <el-tag
  90. style="margin-right: 10px"
  91. type="info"
  92. closable
  93. v-for="(product, index) in productList"
  94. :key="product.id"
  95. @close="handleRemove(index)"
  96. >{{ product.name }}</el-tag
  97. >
  98. </div>
  99. </div>
  100. </template>
  101. </byForm>
  102. <template #footer>
  103. <el-button @click="dialogVisible = false" size="large">取 消</el-button>
  104. <el-button
  105. type="primary"
  106. @click="submitForm('byform')"
  107. size="large"
  108. :loading="submitLoading"
  109. >
  110. 确 定
  111. </el-button>
  112. </template>
  113. </el-dialog>
  114. <el-dialog
  115. v-model="openProduct"
  116. title="选择产品"
  117. width="70%"
  118. append-to-body
  119. >
  120. <SelectProduct @handleSelect="handleSelect"></SelectProduct>
  121. <template #footer>
  122. <span class="dialog-footer">
  123. <el-button @click="openProduct = false">取消</el-button>
  124. </span>
  125. </template>
  126. </el-dialog>
  127. </div>
  128. </template>
  129. <script setup>
  130. /* eslint-disable vue/no-unused-components */
  131. import { ElMessage, ElMessageBox } from "element-plus";
  132. import byTable from "@/components/byTable/index";
  133. import byForm from "@/components/byForm/index";
  134. import SelectProduct from "@/components/product/SelectProduct";
  135. import { computed, defineComponent, ref, toRaw } from "vue";
  136. const loading = ref(false);
  137. const submitLoading = ref(false);
  138. const sourceList = ref({
  139. data: [],
  140. pagination: {
  141. total: 3,
  142. pageNum: 1,
  143. pageSize: 10,
  144. },
  145. });
  146. let lineData = ref([
  147. {
  148. key: "1",
  149. label: "测试1",
  150. disabled: false,
  151. },
  152. {
  153. key: "2",
  154. label: "测试2",
  155. disabled: false,
  156. },
  157. {
  158. key: "3",
  159. label: "测试3",
  160. disabled: false,
  161. },
  162. {
  163. key: "4",
  164. label: "测试4",
  165. disabled: false,
  166. },
  167. ]);
  168. let selectLine = ref([]);
  169. let dialogVisible = ref(false);
  170. let openProduct = ref(false);
  171. let modalType = ref("add");
  172. let rules = ref({
  173. name: [{ required: true, message: "请输入工艺名称", trigger: "blur" }],
  174. });
  175. const { proxy } = getCurrentInstance();
  176. const selectConfig = reactive([
  177. // {
  178. // label: "车间类型",
  179. // prop: "type",
  180. // data: [
  181. // {
  182. // label: "普通车间",
  183. // value: "1",
  184. // },
  185. // {
  186. // label: "半自动化车间",
  187. // value: "2",
  188. // },
  189. // {
  190. // label: "自动化车间",
  191. // value: "3",
  192. // },
  193. // ],
  194. // },
  195. ]);
  196. const config = computed(() => {
  197. return [
  198. {
  199. attrs: {
  200. label: "工艺名称",
  201. prop: "name",
  202. width: 150,
  203. },
  204. },
  205. {
  206. attrs: {
  207. label: "工艺路线",
  208. slot: "line",
  209. },
  210. },
  211. {
  212. attrs: {
  213. label: "适用产品",
  214. slot: "product",
  215. },
  216. },
  217. {
  218. attrs: {
  219. label: "工艺说明",
  220. prop: "remarks",
  221. },
  222. },
  223. {
  224. attrs: {
  225. label: "操作",
  226. width: "200",
  227. align: "right",
  228. },
  229. // 渲染 el-button,一般用在最后一列。
  230. renderHTML(row) {
  231. return [
  232. {
  233. attrs: {
  234. label: "修改",
  235. type: "primary",
  236. text: true,
  237. },
  238. el: "button",
  239. click() {
  240. getDtl(row);
  241. },
  242. },
  243. {
  244. attrs: {
  245. label: "删除",
  246. type: "danger",
  247. text: true,
  248. },
  249. el: "button",
  250. click() {
  251. // 弹窗提示是否删除
  252. ElMessageBox.confirm(
  253. "此操作将永久删除该数据, 是否继续?",
  254. "提示",
  255. {
  256. confirmButtonText: "确定",
  257. cancelButtonText: "取消",
  258. type: "warning",
  259. }
  260. ).then(() => {
  261. // 删除
  262. proxy
  263. .post("/technology/delete", {
  264. id: row.id,
  265. })
  266. .then((res) => {
  267. ElMessage({
  268. message: "删除成功",
  269. type: "success",
  270. });
  271. getList();
  272. });
  273. });
  274. },
  275. },
  276. ];
  277. },
  278. },
  279. ];
  280. });
  281. let formData = reactive({
  282. data: {
  283. name: "",
  284. processRouteList: [],
  285. remarks: "",
  286. productList: [],
  287. },
  288. });
  289. const formOption = reactive({
  290. inline: true,
  291. labelWidth: 100,
  292. itemWidth: 100,
  293. rules: [],
  294. });
  295. const byform = ref(null);
  296. const formConfig = computed(() => {
  297. return [
  298. {
  299. type: "input",
  300. prop: "name",
  301. label: "工艺名称",
  302. required: true,
  303. },
  304. {
  305. type: "slot",
  306. slotName: "lineSlot",
  307. label: "工艺路线",
  308. },
  309. {
  310. type: "slot",
  311. slotName: "productSlot",
  312. label: "适用产品",
  313. },
  314. {
  315. type: "input",
  316. prop: "remarks",
  317. label: "工艺说明",
  318. itemType: "textarea",
  319. },
  320. ];
  321. });
  322. const getList = async (req) => {
  323. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  324. loading.value = true;
  325. proxy
  326. .post("/technology/page", sourceList.value.pagination)
  327. .then((message) => {
  328. console.log(message);
  329. sourceList.value.data = message.rows;
  330. sourceList.value.pagination.total = message.total;
  331. setTimeout(() => {
  332. loading.value = false;
  333. }, 200);
  334. });
  335. };
  336. const getProcesses = async () => {
  337. proxy
  338. .post("/productionProcesses/page", { pageNum: 1, pageSize: 9999 })
  339. .then((message) => {
  340. lineData.value = message.rows.map((x) => ({
  341. key: x.id,
  342. label: x.name,
  343. disabled: false,
  344. }));
  345. });
  346. };
  347. const openModal = () => {
  348. dialogVisible.value = true;
  349. modalType.value = "add";
  350. formData.data = {};
  351. selectLine.value = [];
  352. productList.value = [];
  353. };
  354. const submitForm = () => {
  355. byform.value.handleSubmit((valid) => {
  356. if (!selectLine.value.length > 0)
  357. return ElMessage({
  358. message: "请添加工艺路线",
  359. type: "info",
  360. });
  361. if (!productList.value.length > 0)
  362. return ElMessage({
  363. message: "请添加适用产品",
  364. type: "info",
  365. });
  366. submitLoading.value = true;
  367. formData.data.processRouteList = selectLine.value; //选择的工序数据
  368. formData.data.productList = productList.value.map((x) => ({
  369. productId: x.id,
  370. })); //选择的产品数据
  371. proxy.post("/technology/" + modalType.value, formData.data).then(
  372. (res) => {
  373. ElMessage({
  374. message: modalType.value == "add" ? "添加成功" : "编辑成功",
  375. type: "success",
  376. });
  377. dialogVisible.value = false;
  378. submitLoading.value = false;
  379. getList();
  380. },
  381. (err) => {
  382. console.log(err, "aswwwww");
  383. submitLoading.value = false;
  384. }
  385. );
  386. });
  387. };
  388. const getDtl = (row) => {
  389. modalType.value = "edit";
  390. proxy.post("/technology/detail", { id: row.id }).then((res) => {
  391. productList.value = res.applicableProductsList;
  392. selectLine.value = res.processRouteList.map((x) => x.id);
  393. formData.data = res;
  394. dialogVisible.value = true;
  395. });
  396. };
  397. const productList = ref([]);
  398. const handleSelect = (row) => {
  399. const flag = productList.value.some((x) => x.id === row.id);
  400. if (flag)
  401. return ElMessage({
  402. message: "该产品已选择",
  403. type: "info",
  404. });
  405. productList.value.push(row);
  406. return ElMessage({
  407. message: "选择成功",
  408. type: "success",
  409. });
  410. };
  411. const handleRemove = (index) => {
  412. productList.value.splice(index, 1);
  413. return ElMessage({
  414. message: "删除成功",
  415. type: "success",
  416. });
  417. };
  418. getList();
  419. getProcesses();
  420. // 以下是实现拖拽排序的处理方法
  421. const dragStar = (e, option) => {
  422. // if (!selectLine.value.includes(e.target.id)) return; //拖拽的数据如不是选择的数据直接return
  423. e.dataTransfer.setData("text/plain", option.key);
  424. e.dataTransfer.effectAllowed = "move";
  425. e.dataTransfer.dropEffect = "move";
  426. };
  427. const dragOver = (e, option) => {
  428. e.preventDefault();
  429. };
  430. const handleDrop = (e) => {
  431. // if (!selectLine.value.includes(e.target.id)) return; //拖拽的数据如不是选择的数据直接return
  432. e.preventDefault();
  433. const sourceKey = e.dataTransfer.getData("text/plain"); //获取拖动元素的key值
  434. const targetKey = e.target.id; //获取被互换元素的id值
  435. swapItems(sourceKey, targetKey);
  436. };
  437. // const findIndex = (target) => {
  438. // while (target && target.parentNode) {
  439. // let targetParent = target.parentNode;
  440. // const index = Array.from(targetParent.children).indexOf(target);
  441. // if (index !== -1) {
  442. // return index;
  443. // }
  444. // }
  445. // return -1;
  446. // };
  447. // 调换数据源位置
  448. const swapItems = (sourceKey, targetKey) => {
  449. const sourceIndex = selectLine.value.findIndex((x) => x === sourceKey);
  450. const targetIndex = selectLine.value.findIndex((x) => x === targetKey);
  451. const temp = selectLine.value[sourceIndex];
  452. selectLine.value[sourceIndex] = selectLine.value[targetIndex];
  453. selectLine.value[targetIndex] = temp;
  454. };
  455. </script>
  456. <style lang="scss" scoped>
  457. .tenant {
  458. padding: 20px;
  459. }
  460. </style>