index.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. <template>
  2. <div>
  3. <el-card :class="props.selectStatus ? 'select-card' : 'box-card'">
  4. <byTable
  5. :source="sourceList.data"
  6. :pagination="sourceList.pagination"
  7. :config="config"
  8. :loading="loading"
  9. :searchConfig="searchConfig"
  10. :defaultExpandAll="props.selectStatus"
  11. highlight-current-row
  12. :action-list="[
  13. props.selectStatus
  14. ? {}
  15. : {
  16. text: '添加产品',
  17. action: () => clickModal(),
  18. },
  19. // {
  20. // text: '操作日志',
  21. // action: () => viewLogs(),
  22. // },
  23. ]"
  24. @get-list="getList"
  25. @clickReset="clickReset">
  26. <template #typeExpand="{ item }">
  27. <div style="padding: 0px 20px; box-sizing: border-box" v-if="item.skuSpecList && item.skuSpecList.length > 0">
  28. <div
  29. v-for="spec in item.skuSpecList"
  30. :key="spec.id"
  31. style="display: flex; padding: 8px 16px; align-items: center; box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1); margin-bottom: 8px">
  32. <div style="width: 80px">
  33. <div v-if="spec.specImgUrl">
  34. <img
  35. style="width: 40px; height: 40px; object-fit: contain; vertical-align: middle; border: none; cursor: pointer"
  36. :src="spec.specImgUrl"
  37. @click="openFile(spec.specImgUrl)" />
  38. </div>
  39. <div
  40. v-else
  41. class="el-icon-picture-outline"
  42. style="width: 40px; height: 40px; font-size: 36px; line-height: 40px; text-align: center; color: rgb(229 228 228)"></div>
  43. </div>
  44. <div style="width: 180px">
  45. {{ spec.code }}
  46. </div>
  47. <div style="flex: 1">
  48. {{ spec.name }}
  49. </div>
  50. <div style="width: 180px">
  51. {{ `${spec.length} * ${spec.width} * ${spec.height}(cm³)` }}
  52. </div>
  53. <div style="width: 60px; text-align: center" v-if="props.selectStatus">
  54. <el-button type="text" @click="selectProduct(spec)" :disabled="selectBtnStatus">选择</el-button>
  55. </div>
  56. </div>
  57. </div>
  58. </template>
  59. <template #name="{ item }">
  60. <div>
  61. <a style="color: #409eff; cursor: pointer; word-break: break-all" @click="clickName(item)">{{ item.name }}</a>
  62. </div>
  63. </template>
  64. </byTable>
  65. </el-card>
  66. <el-dialog :title="modalTitle" v-if="openDialog" v-model="openDialog" width="90%">
  67. <MakeSKU :rowData="rowData" :detailStatus="detailStatus" @clickCancel="clickCancel"></MakeSKU>
  68. </el-dialog>
  69. <el-dialog title="操作日志" v-if="openLogs" v-model="openLogs" width="50%">
  70. <byTable
  71. :source="logsList.data"
  72. :pagination="logsList.pagination"
  73. :config="configLogs"
  74. :loading="loadingLogs"
  75. highlight-current-row
  76. @get-list="getLogsList">
  77. </byTable>
  78. <template #footer>
  79. <el-button @click="openLogs = false" size="large">关 闭</el-button>
  80. </template>
  81. </el-dialog>
  82. </div>
  83. </template>
  84. <script setup>
  85. import byTable from "@/components/byTable/index";
  86. import MakeSKU from "@/components/makeProduct/index";
  87. const { proxy } = getCurrentInstance();
  88. const props = defineProps({
  89. selectStatus: Boolean,
  90. });
  91. const sourceList = ref({
  92. data: [],
  93. pagination: {
  94. total: 0,
  95. pageNum: 1,
  96. pageSize: 10,
  97. name: "",
  98. code: "",
  99. type: 0,
  100. brand: "",
  101. },
  102. });
  103. const loading = ref(false);
  104. const searchConfig = computed(() => {
  105. return [
  106. {
  107. type: "input",
  108. prop: "name",
  109. label: "品名",
  110. },
  111. {
  112. type: "input",
  113. prop: "code",
  114. label: "品号",
  115. },
  116. {
  117. type: "select",
  118. prop: "brand",
  119. dictKey: "wlnBrand",
  120. label: "品牌",
  121. },
  122. ];
  123. });
  124. const config = computed(() => {
  125. return [
  126. {
  127. type: "expand",
  128. attrs: {
  129. label: " ",
  130. slot: "typeExpand",
  131. width: 50,
  132. },
  133. },
  134. {
  135. attrs: {
  136. label: "群组品号",
  137. prop: "code",
  138. width: 180,
  139. },
  140. },
  141. {
  142. attrs: {
  143. label: "群组品名",
  144. slot: "name",
  145. "min-width": 240,
  146. },
  147. },
  148. {
  149. attrs: {
  150. label: "产品来源",
  151. prop: "source",
  152. width: 120,
  153. },
  154. render(val) {
  155. return val == 1 ? "MES" : "万里牛";
  156. },
  157. },
  158. {
  159. attrs: {
  160. label: "品牌",
  161. prop: "brand",
  162. width: 120,
  163. },
  164. render(val) {
  165. return proxy.dictKeyValue(val, proxy.useUserStore().allDict["wlnBrand"]);
  166. },
  167. },
  168. {
  169. attrs: {
  170. label: "型号",
  171. prop: "modelNumber",
  172. width: 200,
  173. },
  174. },
  175. {
  176. attrs: {
  177. label: "材质",
  178. prop: "material",
  179. width: 200,
  180. },
  181. },
  182. props.selectStatus
  183. ? {
  184. attrs: { width: 1 },
  185. }
  186. : {
  187. attrs: {
  188. label: "操作",
  189. width: 80,
  190. align: "center",
  191. fixed: "right",
  192. },
  193. renderHTML(row) {
  194. return [
  195. {
  196. attrs: {
  197. label: "编辑",
  198. type: "primary",
  199. text: true,
  200. },
  201. el: "button",
  202. click() {
  203. clickUpdate(row);
  204. },
  205. },
  206. ];
  207. },
  208. },
  209. ];
  210. });
  211. const getList = async (req, status) => {
  212. if (status) {
  213. sourceList.value.pagination = {
  214. pageNum: sourceList.value.pagination.pageNum,
  215. pageSize: sourceList.value.pagination.pageSize,
  216. };
  217. } else {
  218. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  219. }
  220. loading.value = true;
  221. proxy.post("/sku/page", sourceList.value.pagination).then((res) => {
  222. sourceList.value.data = res.rows;
  223. sourceList.value.pagination.total = res.total;
  224. setTimeout(() => {
  225. loading.value = false;
  226. }, 200);
  227. });
  228. };
  229. getList();
  230. const clickReset = () => {
  231. getList("", true);
  232. };
  233. const modalTitle = ref("添加SKU");
  234. const openDialog = ref(false);
  235. const rowData = ref({});
  236. const detailStatus = ref(false);
  237. const clickModal = () => {
  238. modalTitle.value = "添加SKU";
  239. rowData.value = {};
  240. detailStatus.value = false;
  241. openDialog.value = true;
  242. };
  243. const clickUpdate = (row) => {
  244. modalTitle.value = "编辑SKU";
  245. rowData.value = row;
  246. detailStatus.value = false;
  247. openDialog.value = true;
  248. };
  249. const clickCancel = (status) => {
  250. openDialog.value = false;
  251. if (status) {
  252. getList();
  253. }
  254. };
  255. const openFile = (path) => {
  256. window.open(path);
  257. };
  258. const clickName = (row) => {
  259. modalTitle.value = "SKU详情";
  260. rowData.value = row;
  261. detailStatus.value = true;
  262. openDialog.value = true;
  263. };
  264. const openLogs = ref(false);
  265. const loadingLogs = ref(false);
  266. const logsList = ref({
  267. data: [],
  268. pagination: {
  269. total: 0,
  270. pageNum: 1,
  271. pageSize: 10,
  272. },
  273. });
  274. const type = ref([
  275. { dictKey: "1", dictValue: "新增" },
  276. { dictKey: "2", dictValue: "修改" },
  277. { dictKey: "3", dictValue: "删除" },
  278. ]);
  279. const configLogs = computed(() => {
  280. return [
  281. {
  282. attrs: {
  283. label: "操作时间",
  284. prop: "createTime",
  285. width: 160,
  286. align: "center",
  287. },
  288. },
  289. {
  290. attrs: {
  291. label: "操作人",
  292. prop: "operator",
  293. align: "center",
  294. },
  295. },
  296. {
  297. attrs: {
  298. label: "SKU品号",
  299. prop: "code",
  300. align: "center",
  301. },
  302. },
  303. {
  304. attrs: {
  305. label: "行为",
  306. prop: "type",
  307. width: 100,
  308. align: "center",
  309. },
  310. render(val) {
  311. return proxy.dictKeyValue(val, type.value);
  312. },
  313. },
  314. ];
  315. });
  316. const viewLogs = () => {
  317. logsList.value.data = [];
  318. logsList.value.pagination.total = 0;
  319. openLogs.value = true;
  320. getLogsList({ pageNum: 1, pageSize: 10 });
  321. };
  322. const getLogsList = async (req) => {
  323. logsList.value.pagination = { ...logsList.value.pagination, ...req };
  324. loadingLogs.value = true;
  325. proxy.post("/bomOperatingLog/page", logsList.value.pagination).then((res) => {
  326. logsList.value.data = res.rows;
  327. logsList.value.pagination.total = res.total;
  328. setTimeout(() => {
  329. loadingLogs.value = false;
  330. }, 200);
  331. });
  332. };
  333. const emit = defineEmits(["selectProduct"]);
  334. const selectBtnStatus = ref(false);
  335. const selectProduct = (item) => {
  336. selectBtnStatus.value = true;
  337. emit("selectProduct", item);
  338. setTimeout(() => {
  339. selectBtnStatus.value = false;
  340. }, 200);
  341. };
  342. </script>
  343. <style lang="scss" scoped>
  344. :deep(.el-dialog) {
  345. margin-top: 10px !important;
  346. margin-bottom: 10px !important;
  347. }
  348. .select-card {
  349. height: calc(100vh - 184px);
  350. overflow-y: auto;
  351. overflow-x: hidden;
  352. }
  353. </style>