diff --git a/src/api/sales/product.js b/src/api/sales/product.js index 733af3a..9580089 100644 --- a/src/api/sales/product.js +++ b/src/api/sales/product.js @@ -34,6 +34,27 @@ export const remove = (params) => { }); }; +export const searchSkus = (id) => { + return request({ + url: '/mall/product/admin/productSku/list/' + id, + method: 'get', + }); +}; +export const createSkus = (id, data) => { + return request({ + url: '/mall/product/admin/productSku/' + id, + method: 'post', + data, + }); +}; +export const createAndClearSkus = (id, data) => { + return request({ + url: '/mall/product/admin/productSku/deleteAllAndAdd/' + id, + method: 'post', + data, + }); +}; + export const searchAttrs = (id) => { return request({ url: '/mall/product/admin/productAttributeGroup/' + id, @@ -54,6 +75,13 @@ export const updateAttrs = (data) => { data, }); }; +export const updateAttrsSort = (data) => { + return request({ + url: '/mall/product/admin/productAttributeGroup/updateSort', + method: 'put', + data, + }); +}; export const removeAttrs = (params) => { return request({ url: '/mall/product/admin/productAttributeGroup', @@ -64,7 +92,7 @@ export const removeAttrs = (params) => { export const searchAttrsValue = (id) => { return request({ - url: '/mall/product/admin/productAttribute/' + id, + url: '/mall/product/admin/productAttribute/list/' + id, method: 'get', }); }; diff --git a/src/store/modules/sales/productAttrsGroup.js b/src/store/modules/sales/productAttrsGroup.js index cc5910b..b337e29 100644 --- a/src/store/modules/sales/productAttrsGroup.js +++ b/src/store/modules/sales/productAttrsGroup.js @@ -21,13 +21,23 @@ const actions = { } return res; }, + sort: async (context, data) => { + let res = await api.updateAttrsSort(data); + if (res) { + ElMessage.success('保存成功'); + } else { + ElMessage.error('保存失败'); + } + return res; + }, remove: async (context, ids) => { + let res = null; if (!ids.length) { ElMessage.warning('请选择要删除的数据'); } else { try { await ElMessageBox.confirm('数据删除后无法恢复,确定要删除吗?', '危险操作'); - let res = await api.removeAttrs({ id: ids.join(',') }); + res = await api.removeAttrs({ id: ids.join(',') }); if (res) { ElMessage.success('删除成功'); } else { @@ -37,6 +47,7 @@ const actions = { console.info('取消删除', e); } } + return res; }, }; export default { diff --git a/src/store/modules/sales/productAttrsValue.js b/src/store/modules/sales/productAttrsValue.js index 085333d..c55eb83 100644 --- a/src/store/modules/sales/productAttrsValue.js +++ b/src/store/modules/sales/productAttrsValue.js @@ -22,12 +22,13 @@ const actions = { return res; }, remove: async (context, ids) => { + let res = null; if (!ids.length) { ElMessage.warning('请选择要删除的数据'); } else { try { await ElMessageBox.confirm('数据删除后无法恢复,确定要删除吗?', '危险操作'); - let res = await api.removeAttrsValue({ id: ids.join(',') }); + res = await api.removeAttrsValue({ id: ids.join(',') }); if (res) { ElMessage.success('删除成功'); } else { @@ -37,6 +38,7 @@ const actions = { console.info('取消删除', e); } } + return res; }, }; export default { diff --git a/src/store/modules/sales/productSkus.js b/src/store/modules/sales/productSkus.js new file mode 100644 index 0000000..d8629a3 --- /dev/null +++ b/src/store/modules/sales/productSkus.js @@ -0,0 +1,30 @@ +import * as api from '@/api/sales/product.js'; +import { ElMessage } from '@/plugins/element-plus'; +const state = () => ({}); +const getters = {}; +const mutations = {}; +const actions = { + search: async (context, id) => { + let res = await api.searchSkus(id); + if (!res) { + ElMessage.error('查询商品SKU列表失败'); + } + return res || []; + }, + save: async (context, { id, data }) => { + let save = data.every((item) => !item.id) ? api.createAndClearSkus : api.createSkus; + let res = await save(id, data); + if (res) { + ElMessage.success('保存成功'); + } else { + ElMessage.error('保存失败'); + } + return res; + }, +}; +export default { + state, + getters, + mutations, + actions, +}; diff --git a/src/views/sales/product/form/step2.vue b/src/views/sales/product/form/step2.vue index 7562c48..ac0df44 100644 --- a/src/views/sales/product/form/step2.vue +++ b/src/views/sales/product/form/step2.vue @@ -49,19 +49,38 @@ :label="sku.name" :prop="sku.id + ''" /> - + - + - + + + + + @@ -70,15 +89,17 @@ - + @@ -109,7 +130,17 @@ const id = route.params.id; if (id && id !== state.form.id) { state.form.id = id; - let res = await store.dispatch('productAttrsGroup/search', id); + let res = await store.dispatch('productSkus/search', id); + state.form.skuInfos = res.map((item) => { + return { + ...item, + name: item.name?.split(',') || [], + attributeSymbolList: item.attributeSymbolList?.split(',') || [], + stockChange: 0, + stockAfter: item.stock, + }; + }); + res = await store.dispatch('productAttrsGroup/search', id); let arr = []; res.forEach((item) => { arr.push( @@ -134,7 +165,8 @@ attrsGroup.values?.forEach((value) => { let temp = _.cloneDeep(row); temp[attrsGroup.id + ''] = value.name; - temp.groups.push(value.id); + temp.attributeSymbolList.push(value.symbol); + temp.name.push(value.name); res.push(temp); }); }); @@ -143,29 +175,42 @@ } return res; }, - [{ sales: 0, inventory: 0, price: 0, warn: 100, groups: [] }] + [ + { + sellPrice: 0, + stock: 0, + stockChange: 0, + costPrice: 0, + warn: 100, + isEnable: false, + name: [], + attributeSymbolList: [], + }, + ] ) .map((info) => { - let row = old.find((item) => item.groups.sort().join() === info.groups.sort().join()); + let row = old.find( + (item) => + item.attributeSymbolList.sort().join() === info.attributeSymbolList.sort().join() + ); if (row) { Object.assign(info, row); } return info; }); - console.info(state.form.skuInfos, old); }, { deep: true } ); const handleAddSku = async () => { if (state.skuName) { - let res = await store.dispatch('productAttrsGroup', { + let res = await store.dispatch('productAttrsGroup/save', { name: state.skuName, productId: route.params.id, sort: state.form.attrsGroupList.length, }); if (res) { state.form.skuInfos = []; - state.form.attrsGroupList.push({ name: state.skuName, values: [] }); + state.form.attrsGroupList.push({ id: res, name: state.skuName, values: [] }); state.skuName = null; } else { proxy.$message.error('添加属性规格失败'); @@ -178,15 +223,17 @@ let res = await store.dispatch('productAttrsGroup/remove', [state.form.attrsGroupList[index].id]); if (res) { state.form.attrsGroupList.splice(index, 1); - proxy.$message.success('删除成功'); - } else { - proxy.$message.error('删除失败'); } }; - const handleMove = (oldIndex, newIndex) => { - let temp = state.form.attrsGroupList[oldIndex]; - state.form.attrsGroupList[oldIndex] = state.form.attrsGroupList[newIndex]; - state.form.attrsGroupList[newIndex] = temp; + const handleMove = async (oldSort, currentSort) => { + let temp = state.form.attrsGroupList[oldSort]; + let res = await store.dispatch('productAttrsGroup/sort', { id: temp.id, oldSort, currentSort }); + if (res) { + state.form.attrsGroupList[oldSort] = state.form.attrsGroupList[currentSort]; + state.form.attrsGroupList[currentSort] = temp; + } else { + proxy.$message.error('移动失败'); + } }; const handleAddValue = async (sku, index) => { let value = state.skuValue[index]; @@ -211,36 +258,49 @@ let res = await store.dispatch('productAttrsValue/remove', [sku.values[index].id]); if (res) { sku.values.splice(index, 1); - proxy.$message.success('删除成功'); - } else { - proxy.$message.error('删除失败'); } }; - const handleSave = async () => { + const handleStockChange = (row) => { + row.stockAfter = row.stock + row.stockChange; + }; + const handleBack = () => { + router.push({ + name: 'UpdateProduct', + params: { + id: route.params.id, + step: 1, + }, + }); + }; + const handleSave = async (enable) => { state.loading = true; - try { - await state.refsForm.validate(); - router.push({ - name: 'UpdateProduct', - params: { - id: route.params.id || state.form.id, - step: 2, - }, + if (state.form.skuInfos.length) { + let data = _.cloneDeep(state.form.skuInfos).map((item) => { + return { + ...item, + name: item.name.join(','), + attributeSymbolList: item.attributeSymbolList.join(','), + }; }); - } catch (e) { - console.info('取消保存', e); + await store.dispatch('productSkus/save', { id: route.params.id, data }); + if (enable) { + // + } + await handleLoad(); } state.loading = false; }; return { ...toRefs(state), + handleBack, handleSave, handleAddSku, handleDelSku, handleMove, handleAddValue, handleDelValue, + handleStockChange, }; }, }); @@ -251,6 +311,7 @@ display: flex; flex-direction: column; overflow: hidden; + width: 100%; .step-content { flex: 1; overflow: auto; diff --git a/vite.config.js b/vite.config.js index 5c22475..bf754d1 100644 --- a/vite.config.js +++ b/vite.config.js @@ -22,6 +22,7 @@ export default (configEnv) => { '/api': { // target: 'http://192.168.10.109:8090/', // 显雨 // target: 'http://192.168.10.251:8090', // 高玉 + // target: 'http://192.168.10.67:8090', // 罗战 target: 'https://k8s-horse-gateway.mashibing.cn/', // 测试地址 // target: 'https://gateway.mashibing.cn', // 预发地址 // target: 'https://gateway.mashibing.com', // 生产环境