index.vue 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <template>
  2. <el-container class="is-vertical">
  3. <sc-page-header v-if="!selectable" @add="table_add()"></sc-page-header>
  4. <scTable ref="xGridTable" :apiObj="$API.production.bom" :formConfig="formConfig" :paramsColums="paramsColums" :columns="columns" :treeConfig="treeConfig" v-bind="options" v-on="tableEvents">
  5. <template #code_link="{ row }">
  6. <vxe-text v-if="row.parentId === '0'" status="primary" @click="table_detail(row)">{{ row.bomCode }}</vxe-text>
  7. </template>
  8. <template #action="{ row }">
  9. <el-button v-if="!row.isHaveChildren" type="primary" link @click="table_add(row)">
  10. <template #icon><sc-iconify icon="ant-design:cloud-upload-outlined"></sc-iconify></template>新增
  11. </el-button>
  12. <el-button v-else type="primary" link @click="table_edit(row)">
  13. <template #icon><sc-iconify icon="ant-design:edit-outlined"></sc-iconify></template>修改
  14. </el-button>
  15. <template v-if="row.parentId == 0">
  16. <el-button v-if="row.status == 'enable'" type="primary" link @click="table_change(row)">
  17. <template #icon><sc-iconify icon="material-symbols:lock-outline"></sc-iconify></template>停用
  18. </el-button>
  19. <el-button v-else type="primary" link @click="table_change(row)">
  20. <template #icon><sc-iconify icon="material-symbols:lock-open-outline"></sc-iconify></template>启用
  21. </el-button>
  22. </template>
  23. <el-button v-if="!row.isHaveChildren" type="primary" link @click="table_del(row)">
  24. <template #icon><sc-iconify icon="ant-design:delete-outlined"></sc-iconify></template>删除
  25. </el-button>
  26. </template>
  27. </scTable>
  28. </el-container>
  29. <bom-detail v-if="dialog.detail" ref="bomRef" @success="refreshTable" @closed="dialog.detail = false"></bom-detail>
  30. <bom-desc v-if="dialog.desc" ref="bomDescRef" @closed="dialog.desc = false"></bom-desc>
  31. </template>
  32. <script setup>
  33. import moment from "moment";
  34. import XEUtils from "xe-utils";
  35. import API from "@/api";
  36. import TOOL from "@/utils/tool";
  37. import { statusDic } from "@/utils/basicDic";
  38. import { mapFormItemInput, mapFormItemSelect, mapFormItemDatePicker, mapFormItemTenant } from "@/components/scTable/helper";
  39. import bomDetail from "./detail";
  40. import bomDesc from "./desc";
  41. import store from "@/store";
  42. watch(() => store.state.tenant.tenantId, () => refreshTable());
  43. const props = defineProps({
  44. selectable: { type: Boolean, default: false },
  45. multiple: { type: Boolean, default: false },
  46. paramsColums: { type: Array, default: () => [] },
  47. options: { type: Object, default: () => ({}) }
  48. });
  49. const formQueryData = reactive({});
  50. const treeConfig = reactive({
  51. lazy: true,
  52. hasChildField: "isHaveChildren",
  53. loadMethod: ({ row }) => API.production.bom.getChild({ parentId: row.id, ...XEUtils.pick(formQueryData, (_, key) => XEUtils.includes(["materialCodeLike", "materialNameLike", "routeId"], key)) })
  54. });
  55. const routeConfig = reactive({
  56. api: { key: "process.line", query: { orderBy: "createTime_desc", parentId: "0", status: "enable" } },
  57. optionProps: { label: "name", value: "id" },
  58. events: {
  59. change: data => XEUtils.merge(formConfig.data, data)
  60. }
  61. });
  62. const selectConfig = reactive({
  63. options: statusDic,
  64. events: {
  65. change: data => XEUtils.merge(formConfig.data, data)
  66. }
  67. });
  68. const daterangeConfig = reactive({
  69. resetValue: () => [],
  70. props: {
  71. type: "daterange",
  72. startPlaceholder: "开始日期",
  73. endPlaceholder: "结束日期",
  74. format: "YYYY-MM-DD"
  75. }
  76. });
  77. const formConfig = reactive({
  78. data: {},
  79. items: computed(() => props.selectable ? [
  80. mapFormItemInput("materialCodeLike", "产品编码"),
  81. mapFormItemInput("materialNameLike", "产品名称")
  82. ]: [
  83. mapFormItemTenant({ events: { change: data => XEUtils.merge(formConfig.data, { ...data, routeId: undefined }) } }),
  84. mapFormItemInput("materialCodeLike", "产品编码"),
  85. mapFormItemInput("materialNameLike", "产品名称"),
  86. mapFormItemInput("bomCodeLike", "BOM单编号"),
  87. mapFormItemSelect("status", "BOM单状态", selectConfig),
  88. mapFormItemSelect("routeId", "工艺路线", routeConfig),
  89. mapFormItemDatePicker("createTime", "创建日期", daterangeConfig)
  90. ])
  91. });
  92. const paramsColums = reactive([
  93. { column: "orderBy", defaultValue: "createTime_desc" },
  94. { column: "parentId", defaultValue: "0" },
  95. { column: "tenantId" },
  96. { column: "materialCodeLike" },
  97. { column: "materialNameLike" },
  98. { column: "bomCodeLike" },
  99. { column: "status" },
  100. { column: "routeId" },
  101. { column: "createTimeBegin", field: "createTime[0]" },
  102. { column: "createTimeEnd", field: "createTime[1]" },
  103. ...props.paramsColums
  104. ]);
  105. const columns = computed(() => props.selectable ? [
  106. { type: props.multiple && "checkbox" || "radio", fixed: "left", width: 40 },
  107. // { visible: computed(() => !XEUtils.isNull(XEUtils.get(props.options, "treeConfig"))), type: "html", field: "materialCode", title: "产品编码", fixed: "left", minWidth: 200, treeNode: true, headerAlign: "center", align: "left", sortable: true },
  108. // { visible: computed(() => XEUtils.isNull(XEUtils.get(props.options, "treeConfig"))), type: "html", field: "materialCode", title: "产品编码", fixed: "left", minWidth: 200, sortable: true },
  109. { type: "html", field: "materialCode", title: "产品编码", fixed: "left", minWidth: 200, sortable: true },
  110. { type: "html", field: "materialName", title: "产品名称", fixed: "left", minWidth: 150, sortable: true },
  111. { type: "html", field: "material.specification", title: "规格型号", minWidth: 120, sortable: true },
  112. { type: "html", field: "quantity", title: "标准用量", minWidth: 100, sortable: true },
  113. { type: "html", field: "material.unit", title: "单位", minWidth: 100, sortable: true }
  114. ] : [
  115. { type: "seq", fixed: "left", width: 80 },
  116. { visible: computed(() => store.state.tenant.tenantId === "0"), type: "html", field: "tenantName", title: "所属租户", fixed: "left", minWidth: 200, sortable: true, formatter: ({ cellValue, row }) => row.parentId === "0" ? cellValue || XEUtils.get(XEUtils.find(store.state.tenant.tenants, item => item.id == row.tenantId), "name") : "" },
  117. { type: "html", field: "materialCode", title: "产品编码", fixed: "left", minWidth: 200, treeNode: true, headerAlign: "center", align: "left", sortable: true },
  118. { type: "html", field: "materialName", title: "产品名称", fixed: "left", minWidth: 150, sortable: true },
  119. { field: "bomCode", title: "BOM单编号", minWidth: 150, sortable: true, className: "vxe-table-link-cell", slots: { default: "code_link" } },
  120. { field: "status", title: "BOM单状态", minWidth: 120, editRender: { name: "$cell-tag", options: statusDic } },
  121. { visible: true, type: "html", field: "routeName", title: "工艺路线", minWidth: 150, sortable: true },
  122. { type: "html", field: "createTime", title: "创建日期", minWidth: 120, sortable: true, formatter: ({ cellValue }) => TOOL.dateFormat(cellValue, "YYYY-MM-DD") || cellValue },
  123. { visible: false, type: "html", field: "remark", title: "概要", minWidth: 300, sortable: true },
  124. { title: "操作", fixed: "right", width: 220, slots: { default: "action" } }
  125. ]);
  126. // 显示隐藏 筛选表单
  127. const xGridTable = ref();
  128. const refreshTable = (mode = "add") => (xGridTable.value.searchData(mode), xGridTable.value.reloadColumn(columns.value));
  129. const bomRef = ref();
  130. const bomDescRef = ref();
  131. const dialog = reactive({
  132. detail: false,
  133. desc: false
  134. });
  135. const table_add = (row = {}) => {
  136. dialog.detail = true;
  137. nextTick(() => bomRef.value?.setData(row));
  138. }
  139. const table_edit = row => {
  140. dialog.detail = true;
  141. nextTick(() => bomRef.value?.setData(row, "edit"));
  142. }
  143. const table_detail = row => {
  144. dialog.desc = true;
  145. nextTick(() => bomDescRef.value?.setData(row));
  146. }
  147. const table_del = ({ id }) => {
  148. ElMessageBox.confirm("是否确认删除该BOM清单?", "删除警告", {
  149. type: "warning",
  150. confirmButtonText: "确定",
  151. cancelButtonText: "取消"
  152. }).then(() => {
  153. API.production.bom.del({ id }).then(() => {
  154. ElMessage.success("操作成功");
  155. refreshTable();
  156. });
  157. }).catch(() => {});
  158. }
  159. const table_change = row => {
  160. const status = row.status == "enable" && "disable" || "enable";
  161. const msg = row.status == "enable" && "停用" || "启用";
  162. ElMessageBox.confirm(`是否确认${msg}该BOM清单?`, `${msg}警告`, {
  163. type: "warning",
  164. confirmButtonText: "确定",
  165. cancelButtonText: "取消"
  166. }).then(() => {
  167. API.production.bom.edit({ id: row.id, status }).then(() => {
  168. ElMessage.success("操作成功");
  169. refreshTable();
  170. });
  171. }).catch(() => {});
  172. }
  173. const tableEvents = {
  174. tableSearch: data => (XEUtils.clear(formQueryData), XEUtils.merge(formQueryData, data)),
  175. tableReset: data => (XEUtils.clear(formQueryData), XEUtils.merge(formQueryData, data))
  176. }
  177. defineExpose({
  178. getSelectRows: () => xGridTable.value.getSelectRows()
  179. });
  180. </script>