修复生成商品sku列表的bug

This commit is contained in:
2024-07-26 11:54:51 +08:00
parent 049a6f7476
commit 904bd82e39
6 changed files with 303 additions and 66 deletions

View File

@@ -80,6 +80,8 @@ export interface Goods {
goodsSpecs?: GoodsSpec[];
// 商品sku列表
goodsSkus?: GoodsSku[];
// 单位名称
unitName?: string;
}
export interface BathSet {

View File

@@ -2,6 +2,18 @@ import request from '@/utils/request';
import type { ApiResult, PageResult } from '@/api';
import type { GoodsSku, GoodsSkuParam } from './model';
import { MODULES_API_URL } from '@/config/setting';
import { GoodsSpec } from '@/api/shop/goodsSpec/model';
export async function generateGoodsSku(data: GoodsSpec) {
const res = await request.post<ApiResult<GoodsSku[]>>(
MODULES_API_URL + '/shop/goods-sku/generateGoodsSku',
data
);
if (res.data.code === 0) {
return res.data.data;
}
return Promise.reject(new Error(res.data.message));
}
/**
* 分页查询商品sku列表

View File

@@ -10,24 +10,24 @@ export interface GoodsSku {
goodsId?: number;
// 规格组ID
specId?: number;
// 规格值ID
specValueId?: number;
// 规格值0
specValue0?: string;
// 规格值1
specValue1?: string;
// 规格值2
specValue2?: string;
// 商品图片
image?: string;
// 商品价格
price?: string;
// 市场价格
salePrice?: string;
// 成本价
cost?: string;
// 库存
stock?: number;
// sku编码
skuNo?: string;
// 唯一值
unique?: string;
// 重量
weight?: string;
// 体积
volume?: string;
// 状态, 0正常, 1异常
status?: number;
// 备注
@@ -37,6 +37,7 @@ export interface GoodsSku {
// 创建时间
createTime?: string;
images?: any;
sku?: string;
}
/**
@@ -44,5 +45,6 @@ export interface GoodsSku {
*/
export interface GoodsSkuParam extends PageParam {
id?: number;
goodsId?: number;
keywords?: string;
}

View File

@@ -206,7 +206,7 @@
</a-space>
</a-space>
</a-form-item>
<a-form-item name="oneSpec">
<a-form-item name="oneSpec" v-if="form.specs == 1">
<div class="w-full">
<div class="sku-table">
<a-table
@@ -319,7 +319,7 @@
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject, uuid } from 'ele-admin-pro';
import { addGoods, getGoods, updateGoods } from "@/api/shop/goods";
import { addGoods, updateGoods } from "@/api/shop/goods";
import { Goods } from '@/api/shop/goods/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
@@ -331,11 +331,9 @@
import { uploadFile, uploadOss } from "@/api/system/file";
import { SpecValue } from "@/api/shop/specValue/model";
import { Spec } from "@/api/shop/spec/model";
import {ColumnItem} from "ele-admin-pro/es/ele-pro-table/types";
import { GoodsSku } from "@/api/shop/goodsSku/model";
import { GoodsSpec } from "@/api/shop/goodsSpec/model";
import { getGoodsSpec, pageGoodsSpec } from "@/api/shop/goodsSpec";
import { openUrl } from "@/utils/common";
import { generateGoodsSku, listGoodsSku } from "@/api/shop/goodsSku";
// 是否是修改
const isUpdate = ref(false);
@@ -366,13 +364,13 @@
const content = ref('');
const disabled = ref(false);
// 当前选项卡
const active = ref('spec');
const active = ref('base');
const spec = ref<SpecValue[]>([]);
const showSpecForm = ref(false);
const name = ref();
const value = ref();
const skuList = ref<GoodsSku[]>([{images: []}]);
const skuList = ref<GoodsSku[]>([]);
const fileList = ref<any[]>([]);
const files = ref<ItemType[]>([]);
const goodsSpec = ref<GoodsSpec>();
@@ -419,6 +417,7 @@
goodsName: undefined,
image: undefined,
content: undefined,
unitName: '',
categoryId: undefined,
categoryParent: undefined,
categoryChildren: undefined,
@@ -468,9 +467,15 @@
files: [
{
required: true,
message: '请上传图',
message: '请上传轮播图',
type: 'string',
trigger: 'blur'
trigger: 'blur',
validator: async (_rule: RuleObject, value: string) => {
if (form.files?.length == 0) {
return Promise.reject('选择上传轮播图');
}
return Promise.resolve();
}
}
],
specs: [
@@ -576,11 +581,15 @@
images.value.splice(index, 1);
};
const onChange = () => {
// reload();
const onChange = (text: string) => {
// 加载商品多规格
if(text == 'spec'){
listGoodsSku({goodsId: props.data?.goodsId}).then(data => {
skuList.value = data;
})
}
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
@@ -634,6 +643,16 @@
files.value.splice(index, 1);
};
/**
* 生成商品SKU列表
*/
const generateSku = () => {
generateGoodsSku(spec.value).then(data => {
if(data){
skuList.value = data;
}
})
}
const editorRef = ref<InstanceType<typeof TinymceEditor> | null>(null);
const config = ref({
@@ -698,7 +717,7 @@
...form,
content: content.value,
files: JSON.stringify(fileList.value),
goodsSpecs: goodsSpec.value,
goodsSpec: goodsSpec.value,
goodsSkus: skuList.value
};
const saveOrUpdate = isUpdate.value ? updateGoods : addGoods;
@@ -722,6 +741,8 @@
(visible) => {
if (visible) {
images.value = [];
files.value = [];
category.value = [];
if (props.data) {
assignObject(form, props.data);
if (props.data.image) {
@@ -731,6 +752,16 @@
status: 'done'
});
}
if(props.data.files){
const arr = JSON.parse(props.data.files);
arr.map((img) => {
files.value.push({
uid: uuid(),
url: img,
status: 'done'
});
});
}
if(props.data.goodsSpecs){
goodsSpec.value = props.data.goodsSpecs[0];
if(props.data.specs == 1){
@@ -748,6 +779,16 @@
return d;
});
}
// 商品分类
if(props.data.categoryParent){
category.value.push(props.data.categoryParent);
}
if(props.data.categoryChildren){
category.value.push(props.data.categoryChildren);
}
if (props.data.content){
content.value = props.data.content;
}
isUpdate.value = true;
} else {

View File

@@ -19,15 +19,94 @@
styleResponsive ? { md: 19, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="商品sku列表名称" name="goodsSkuName">
<a-form-item label="商品ID" name="goodsId">
<a-input
allow-clear
:maxlength="100"
placeholder="请输入商品sku列表"
v-model:value="form.goodsSkuName"
placeholder="请输入商品ID"
v-model:value="form.goodsId"
/>
</a-form-item>
<a-form-item label="描述" name="comments">
<a-form-item label="商品属性索引值 (attr_value|attr_value[|....])" name="sku">
<a-input
allow-clear
placeholder="请输入商品属性索引值 (attr_value|attr_value[|....])"
v-model:value="form.sku"
/>
</a-form-item>
<a-form-item
label="商品图片"
name="image">
<SelectFile
:placeholder="`请选择图片`"
:limit="1"
:data="images"
@done="chooseImage"
@del="onDeleteItem"
/>
</a-form-item>
<a-form-item label="商品价格" name="price">
<a-input
allow-clear
placeholder="请输入商品价格"
v-model:value="form.price"
/>
</a-form-item>
<a-form-item label="市场价格" name="salePrice">
<a-input
allow-clear
placeholder="请输入市场价格"
v-model:value="form.salePrice"
/>
</a-form-item>
<a-form-item label="成本价" name="cost">
<a-input
allow-clear
placeholder="请输入成本价"
v-model:value="form.cost"
/>
</a-form-item>
<a-form-item label="库存" name="stock">
<a-input
allow-clear
placeholder="请输入库存"
v-model:value="form.stock"
/>
</a-form-item>
<a-form-item label="sku编码" name="skuNo">
<a-input
allow-clear
placeholder="请输入sku编码"
v-model:value="form.skuNo"
/>
</a-form-item>
<a-form-item label="唯一值" name="unique">
<a-input
allow-clear
placeholder="请输入唯一值"
v-model:value="form.unique"
/>
</a-form-item>
<a-form-item label="重量" name="weight">
<a-input
allow-clear
placeholder="请输入重量"
v-model:value="form.weight"
/>
</a-form-item>
<a-form-item label="体积" name="volume">
<a-input
allow-clear
placeholder="请输入体积"
v-model:value="form.volume"
/>
</a-form-item>
<a-form-item label="状态, 0正常, 1异常" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
<a-form-item label="备注" name="comments">
<a-textarea
:rows="4"
:maxlength="200"
@@ -35,21 +114,6 @@
v-model:value="form.comments"
/>
</a-form-item>
<a-form-item label="排序号" name="sortNumber">
<a-input-number
:min="0"
:max="9999"
class="ele-fluid"
placeholder="请输入排序号"
v-model:value="form.sortNumber"
/>
</a-form-item>
<a-form-item label="状态" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">显示</a-radio>
<a-radio :value="1">隐藏</a-radio>
</a-radio-group>
</a-form-item>
</a-form>
</ele-modal>
</template>
@@ -57,12 +121,14 @@
<script lang="ts" setup>
import { ref, reactive, watch } from 'vue';
import { Form, message } from 'ant-design-vue';
import { assignObject } from 'ele-admin-pro';
import { assignObject, uuid } from 'ele-admin-pro';
import { addGoodsSku, updateGoodsSku } from '@/api/shop/goodsSku';
import { GoodsSku } from '@/api/shop/goodsSku/model';
import { useThemeStore } from '@/store/modules/theme';
import { storeToRefs } from 'pinia';
import { ItemType } from 'ele-admin-pro/es/ele-image-upload/types';
import { FormInstance } from 'ant-design-vue/es/form';
import { FileRecord } from '@/api/system/file/model';
// 是否是修改
const isUpdate = ref(false);
@@ -89,9 +155,26 @@
const maxable = ref(true);
// 表格选中数据
const formRef = ref<FormInstance | null>(null);
const images = ref<ItemType[]>([]);
// 用户信息
const form = reactive<GoodsSku>({
id: undefined,
goodsId: undefined,
sku: undefined,
image: undefined,
price: undefined,
salePrice: undefined,
cost: undefined,
stock: undefined,
skuNo: undefined,
unique: undefined,
weight: undefined,
volume: undefined,
status: undefined,
comments: undefined,
tenantId: undefined,
createTime: undefined,
goodsSkuId: undefined,
goodsSkuName: '',
status: 0,
@@ -116,6 +199,20 @@
]
});
const chooseImage = (data: FileRecord) => {
images.value.push({
uid: data.id,
url: data.path,
status: 'done'
});
form.image = data.path;
};
const onDeleteItem = (index: number) => {
images.value.splice(index, 1);
form.image = '';
};
const { resetFields } = useForm(form, rules);
/* 保存编辑 */
@@ -150,8 +247,16 @@
() => props.visible,
(visible) => {
if (visible) {
images.value = [];
if (props.data) {
assignObject(form, props.data);
if(props.data.image){
images.value.push({
uid: uuid(),
url: props.data.image,
status: 'done'
})
}
isUpdate.value = true;
} else {
isUpdate.value = false;

View File

@@ -21,9 +21,12 @@
/>
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'image'">
<a-image :src="record.image" :width="50" />
</template>
<template v-if="column.key === 'status'">
<a-tag v-if="record.status === 0" color="green">开启</a-tag>
<a-tag v-if="record.status === 1" color="red">关闭</a-tag>
<a-tag v-if="record.status === 0" color="green">显示</a-tag>
<a-tag v-if="record.status === 1" color="red">隐藏</a-tag>
</template>
<template v-if="column.key === 'action'">
<a-space>
@@ -52,6 +55,7 @@
import { message, Modal } from 'ant-design-vue';
import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import type { EleProTable } from 'ele-admin-pro';
import { toDateString } from 'ele-admin-pro';
import type {
DatasourceFunction,
ColumnItem
@@ -97,26 +101,98 @@
// 表格列配置
const columns = ref<ColumnItem[]>([
{
title: 'ID',
width: 90,
dataIndex: 'goodsSkuId'
},
{
title: '名称',
dataIndex: 'goodsSkuname',
key: 'goodsSkuname'
},
{
title: '描述',
dataIndex: 'comments',
ellipsis: true
},
{
title: '状态',
dataIndex: 'status',
width: 120,
title: '主键ID',
dataIndex: 'id',
key: 'id',
align: 'center',
key: 'status'
width: 90,
},
{
title: '商品ID',
dataIndex: 'goodsId',
key: 'goodsId',
align: 'center',
},
{
title: '商品属性索引值 (attr_value|attr_value[|....])',
dataIndex: 'sku',
key: 'sku',
align: 'center',
},
{
title: '商品图片',
dataIndex: 'image',
key: 'image',
align: 'center',
},
{
title: '商品价格',
dataIndex: 'price',
key: 'price',
align: 'center',
},
{
title: '市场价格',
dataIndex: 'salePrice',
key: 'salePrice',
align: 'center',
},
{
title: '成本价',
dataIndex: 'cost',
key: 'cost',
align: 'center',
},
{
title: '库存',
dataIndex: 'stock',
key: 'stock',
align: 'center',
},
{
title: 'sku编码',
dataIndex: 'skuNo',
key: 'skuNo',
align: 'center',
},
{
title: '唯一值',
dataIndex: 'unique',
key: 'unique',
align: 'center',
},
{
title: '重量',
dataIndex: 'weight',
key: 'weight',
align: 'center',
},
{
title: '体积',
dataIndex: 'volume',
key: 'volume',
align: 'center',
},
{
title: '状态, 0正常, 1异常',
dataIndex: 'status',
key: 'status',
align: 'center',
},
{
title: '备注',
dataIndex: 'comments',
key: 'comments',
align: 'center',
},
{
title: '创建时间',
dataIndex: 'createTime',
key: 'createTime',
align: 'center',
sorter: true,
ellipsis: true,
customRender: ({ text }) => toDateString(text, 'yyyy-MM-dd')
},
{
title: '操作',
@@ -148,7 +224,7 @@
/* 删除单个 */
const remove = (row: GoodsSku) => {
const hide = message.loading('请求中..', 0);
removeGoodsSku(row.id)
removeGoodsSku(row.goodsSkuId)
.then((msg) => {
hide();
message.success(msg);
@@ -173,7 +249,7 @@
maskClosable: true,
onOk: () => {
const hide = message.loading('请求中..', 0);
removeBatchGoodsSku(selection.value.map((d) => d.id))
removeBatchGoodsSku(selection.value.map((d) => d.goodsSkuId))
.then((msg) => {
hide();
message.success(msg);
@@ -205,7 +281,6 @@
}
};
};
query();
</script>