feat: 秒杀、推荐

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

@ -20,3 +20,19 @@ export const remove = (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>
</TableList>
<ProductPicker ref="refsPicker" @pick="handlePick" />
<ProductSku ref="refsSku" @save="handleSkuSave" />
</div>
</template>
<script setup lang="jsx">
import ElButton from '@/components/extra/ElButton.vue';
import ProductPicker from '@/views/sales/product/picker.vue';
import ProductSku from './sku.vue';
const store = useStore();
const route = useRoute();
const loading = ref(false);
@ -96,22 +98,28 @@
const handleCreate = async () => {
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) => {
await store.dispatch(
'limitProduct/remove',
rows.map((item) => item.id)
);
};
const refsSku = ref(null);
const handleSku = (row) => {
console.info(row);
unref(refsSku).show(row);
};
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 handleSkuSave = () => {
unref(refsSku).close();
};
/* 列表配置 */
@ -145,7 +153,7 @@
slots: {
default: ({ row }) => (
<ElButton type="text" onClick={() => handleSku(row)}>
<ElIcon name="Edit" />
<ElIcon name="Edit" size="20" />
</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: '商品图片',
minWidth: 100,
slots: {
default: ({ row }) => <ElImage src={row.picture} alt={row.name} height="100px" />,
default: ({ row }) => <ElImage src={row.productMainPicture} alt={row.productName} height="100px" />,
},
},
{
label: '商品名称',
prop: 'name',
prop: 'productName',
minWidth: 160,
},
{
@ -126,7 +126,7 @@
{
label: '操作',
fixed: 'right',
width: 300,
width: 100,
slots: {
default: ({ row }) => (
<div>

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

Loading…
Cancel
Save