feat: 秒杀、推荐

feature/task1.0.0__0514__ch
向文可 2 years ago
parent 118a4affc9
commit b15139f55b

@ -20,3 +20,19 @@ export const remove = (idList) => {
params: { idList }, params: { idList },
}); });
}; };
export const searchSkus = (activityProductId) => {
return request({
url: '/mall/marketing/activityProductSku',
method: 'get',
params: { activityProductId },
});
};
export const saveSkus = (data) => {
return request({
url: '/mall/marketing/activityProductSku',
method: 'post',
data,
});
};

@ -0,0 +1,44 @@
import * as api from '@/api/operation/limit/limitProduct.js';
import { ElMessage } from '@/plugins/element-plus';
const state = () => ({
code: 'LimitProduct',
condition: {},
list: [],
total: 0,
opts: {
init: false,
},
});
const getters = {};
const mutations = {
setCode: (state, data) => (state.code = data),
setCondition: (state, data) => (state.condition = data),
setList: (state, data) => (state.list = data),
setTotal: (state, data) => (state.total = data),
setOpts: (state, data) => (state.opts = data),
};
const actions = {
search: async ({ commit }, id) => {
let res = await api.searchSkus(id);
commit('setList', res || []);
if (!res) {
ElMessage.error('查询秒杀商品SKU列表失败');
}
return res;
},
save: async (context, data) => {
let res = await api.saveSkus(data);
if (res) {
ElMessage.success('保存成功');
} else {
ElMessage.error('保存失败');
}
return res;
},
};
export default {
state,
getters,
mutations,
actions,
};

@ -34,12 +34,14 @@
</template> </template>
</TableList> </TableList>
<ProductPicker ref="refsPicker" @pick="handlePick" /> <ProductPicker ref="refsPicker" @pick="handlePick" />
<ProductSku ref="refsSku" @save="handleSkuSave" />
</div> </div>
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import ElButton from '@/components/extra/ElButton.vue'; import ElButton from '@/components/extra/ElButton.vue';
import ProductPicker from '@/views/sales/product/picker.vue'; import ProductPicker from '@/views/sales/product/picker.vue';
import ProductSku from './sku.vue';
const store = useStore(); const store = useStore();
const route = useRoute(); const route = useRoute();
const loading = ref(false); const loading = ref(false);
@ -96,22 +98,28 @@
const handleCreate = async () => { const handleCreate = async () => {
unref(refsPicker).show(); unref(refsPicker).show();
}; };
const handlePick = async (rows) => {
loading.value = true;
await store.dispatch('limitProduct/save', {
activityTimeId: state.condition.activityTimeId,
productId: rows.map((item) => item.id),
});
loading.value = false;
};
const handleRemove = async (rows) => { const handleRemove = async (rows) => {
await store.dispatch( await store.dispatch(
'limitProduct/remove', 'limitProduct/remove',
rows.map((item) => item.id) rows.map((item) => item.id)
); );
}; };
const refsSku = ref(null);
const handleSku = (row) => { const handleSku = (row) => {
console.info(row); unref(refsSku).show(row);
}; };
const handlePick = async (rows) => { const handleSkuSave = () => {
loading.value = true; unref(refsSku).close();
await store.dispatch('limitProduct/save', {
activityTimeId: state.condition.activityTimeId,
productId: rows.map((item) => item.id),
});
loading.value = false;
}; };
/* 列表配置 */ /* 列表配置 */
@ -145,7 +153,7 @@
slots: { slots: {
default: ({ row }) => ( default: ({ row }) => (
<ElButton type="text" onClick={() => handleSku(row)}> <ElButton type="text" onClick={() => handleSku(row)}>
<ElIcon name="Edit" /> <ElIcon name="Edit" size="20" />
</ElButton> </ElButton>
), ),
}, },

@ -0,0 +1,110 @@
<template>
<el-dialog v-model="visible" title="编辑SKU" width="max-content">
<TableList
v-loading="loading"
:code="code"
:config="config"
:data="list"
:operation="[]"
style="height: 500px"
:total="total"
>
<template #operation>
<el-button type="primary" @click="handleSave"></el-button>
<h3 style="margin-left: 10px">{{ activityProduct?.productName }}</h3>
</template>
</TableList>
</el-dialog>
</template>
<script setup lang="jsx">
import { ElInputNumber } from 'element-plus/es/components/input-number/index';
import 'element-plus/es/components/input-number/style/css';
const store = useStore();
const loading = ref(false);
const visible = ref(false);
const code = computed(() => store.state.limitSku.code);
const list = computed(() => _.cloneDeep(store.state.limitSku.list));
const total = computed(() => store.state.limitSku.total);
/* 查询订单 */
const activityProduct = ref(null);
const handleSearch = async () => {
loading.value = true;
await store.dispatch('limitSku/search', unref(activityProduct).id);
loading.value = false;
};
const emits = defineEmits(['save']);
const handleSave = async () => {
loading.value = true;
await store.dispatch('limitSku/save', {
activityProductId: unref(activityProduct).id,
activityProductSkuInfoList: unref(list),
});
emits('save');
loading.value = false;
};
const handleShow = (product) => {
activityProduct.value = product;
handleSearch();
visible.value = true;
};
const handleClose = () => {
visible.value = false;
};
defineExpose({
show: handleShow,
close: handleClose,
});
/* 列表配置 */
const config = reactive({
columns: [
{
label: 'SKU属性',
prop: 'skuName',
minWidth: 200,
},
{
label: '售价(元)',
prop: 'originalPrice',
width: 120,
},
{
label: '秒杀价(元)',
width: 160,
slots: {
default: ({ row }) => <ElInputNumber v-model={row.price} min={0} />,
},
},
{
label: '秒杀数量',
width: 160,
slots: {
default: ({ row }) => <ElInputNumber v-model={row.number} min={0} max={row.stock} />,
},
},
{
label: '剩余数量',
prop: 'stock',
width: 120,
slots: {
default: ({ row }) => row.stock || 0,
},
},
{
label: '活动已售数量',
width: 160,
slots: {
default: ({ row }) => (row.number || 0) - (row.stock || 0),
},
},
],
});
</script>
<style lang="less" scoped>
:deep(.el-input-number) {
width: 100%;
}
</style>

@ -108,12 +108,12 @@
label: '商品图片', label: '商品图片',
minWidth: 100, minWidth: 100,
slots: { slots: {
default: ({ row }) => <ElImage src={row.picture} alt={row.name} height="100px" />, default: ({ row }) => <ElImage src={row.productMainPicture} alt={row.productName} height="100px" />,
}, },
}, },
{ {
label: '商品名称', label: '商品名称',
prop: 'name', prop: 'productName',
minWidth: 160, minWidth: 160,
}, },
{ {
@ -126,7 +126,7 @@
{ {
label: '操作', label: '操作',
fixed: 'right', fixed: 'right',
width: 300, width: 100,
slots: { slots: {
default: ({ row }) => ( default: ({ row }) => (
<div> <div>

@ -284,7 +284,9 @@
}); });
await store.dispatch('productSkus/save', { id: route.params.id, data }); await store.dispatch('productSkus/save', { id: route.params.id, data });
if (enable) { if (enable) {
// let product = await store.dispatch('product/detail', route.params.id);
product.isEnable = true;
await store.dispatch('product/save', product);
} }
await handleLoad(); await handleLoad();
} }

Loading…
Cancel
Save