index.vue 8.1 KB

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