feat(分类): 添加分类管理相关功能
refactor(商品类型): 将商品类型从 simple 改为 single fix(数据库配置): 更新数据库连接配置 style(分类): 修正分类中文标题 chore: 移除无用的脚本文件
This commit is contained in:
parent
0180360519
commit
b8aee530e8
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const mysql = require("mysql2/promise");
|
|
||||||
async function run() {
|
|
||||||
try {
|
|
||||||
const connection = await mysql.createConnection({
|
|
||||||
socketPath: '/Users/zksu/Library/Application Support/Local/run/oLbUT7qMU/mysql/mysqld.sock',
|
|
||||||
user: 'root',
|
|
||||||
password: 'root',
|
|
||||||
});
|
|
||||||
console.log('Connected to database server.');
|
|
||||||
await connection.query('CREATE DATABASE IF NOT EXISTS inventory');
|
|
||||||
console.log('Database "inventory" created or already exists.');
|
|
||||||
await connection.end();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error('Error:', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
run();
|
|
||||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3JlYXRlX2RiLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY3JlYXRlX2RiLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0Esd0NBQXdDO0FBRXhDLEtBQUssVUFBVSxHQUFHO0lBQ2hCLElBQUksQ0FBQztRQUNILE1BQU0sVUFBVSxHQUFHLE1BQU0sS0FBSyxDQUFDLGdCQUFnQixDQUFDO1lBQzlDLFVBQVUsRUFBRSwrRUFBK0U7WUFDM0YsSUFBSSxFQUFFLE1BQU07WUFDWixRQUFRLEVBQUUsTUFBTTtTQUNqQixDQUFDLENBQUM7UUFFSCxPQUFPLENBQUMsR0FBRyxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFFN0MsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUFDLHlDQUF5QyxDQUFDLENBQUM7UUFDbEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO1FBRS9ELE1BQU0sVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDN0IsQ0FBQztBQUNILENBQUM7QUFFRCxHQUFHLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIlxuaW1wb3J0ICogYXMgbXlzcWwgZnJvbSAnbXlzcWwyL3Byb21pc2UnO1xuXG5hc3luYyBmdW5jdGlvbiBydW4oKSB7XG4gIHRyeSB7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IG15c3FsLmNyZWF0ZUNvbm5lY3Rpb24oe1xuICAgICAgc29ja2V0UGF0aDogJy9Vc2Vycy96a3N1L0xpYnJhcnkvQXBwbGljYXRpb24gU3VwcG9ydC9Mb2NhbC9ydW4vb0xiVVQ3cU1VL215c3FsL215c3FsZC5zb2NrJyxcbiAgICAgIHVzZXI6ICdyb290JyxcbiAgICAgIHBhc3N3b3JkOiAncm9vdCcsXG4gICAgfSk7XG5cbiAgICBjb25zb2xlLmxvZygnQ29ubmVjdGVkIHRvIGRhdGFiYXNlIHNlcnZlci4nKTtcblxuICAgIGF3YWl0IGNvbm5lY3Rpb24ucXVlcnkoJ0NSRUFURSBEQVRBQkFTRSBJRiBOT1QgRVhJU1RTIGludmVudG9yeScpO1xuICAgIGNvbnNvbGUubG9nKCdEYXRhYmFzZSBcImludmVudG9yeVwiIGNyZWF0ZWQgb3IgYWxyZWFkeSBleGlzdHMuJyk7XG4gICAgXG4gICAgYXdhaXQgY29ubmVjdGlvbi5lbmQoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yOicsIGUpO1xuICB9XG59XG5cbnJ1bigpO1xuIl19
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const mysql = require("mysql2/promise");
|
|
||||||
async function run() {
|
|
||||||
try {
|
|
||||||
const connection = await mysql.createConnection({
|
|
||||||
host: '127.0.0.1',
|
|
||||||
port: 10014,
|
|
||||||
user: 'root',
|
|
||||||
password: 'root',
|
|
||||||
database: 'inventory'
|
|
||||||
});
|
|
||||||
console.log('Connected to database.');
|
|
||||||
const tables = ['product', 'category_attribute', 'category'];
|
|
||||||
for (const table of tables) {
|
|
||||||
console.log(`\nConstraints for table: ${table}`);
|
|
||||||
const [rows] = await connection.execute(`
|
|
||||||
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE
|
|
||||||
FROM information_schema.TABLE_CONSTRAINTS
|
|
||||||
WHERE TABLE_SCHEMA = 'inventory' AND TABLE_NAME = '${table}'
|
|
||||||
`);
|
|
||||||
console.table(rows);
|
|
||||||
}
|
|
||||||
await connection.end();
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error('Error:', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
run();
|
|
||||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhZ25vc2VfZGIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkaWFnbm9zZV9kYi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUNBLHdDQUF3QztBQUV4QyxLQUFLLFVBQVUsR0FBRztJQUNoQixJQUFJLENBQUM7UUFDSCxNQUFNLFVBQVUsR0FBRyxNQUFNLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQztZQUM5QyxJQUFJLEVBQUUsV0FBVztZQUNqQixJQUFJLEVBQUUsS0FBSztZQUNYLElBQUksRUFBRSxNQUFNO1lBQ1osUUFBUSxFQUFFLE1BQU07WUFDaEIsUUFBUSxFQUFFLFdBQVc7U0FDdEIsQ0FBQyxDQUFDO1FBRUgsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBRXRDLE1BQU0sTUFBTSxHQUFHLENBQUMsU0FBUyxFQUFFLG9CQUFvQixFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRTdELEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxFQUFFLENBQUM7WUFDM0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNqRCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxVQUFVLENBQUMsT0FBTyxDQUFDOzs7NkRBR2UsS0FBSztPQUMzRCxDQUFDLENBQUM7WUFDSCxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RCLENBQUM7UUFFRCxNQUFNLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzdCLENBQUM7QUFDSCxDQUFDO0FBRUQsR0FBRyxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJcbmltcG9ydCAqIGFzIG15c3FsIGZyb20gJ215c3FsMi9wcm9taXNlJztcblxuYXN5bmMgZnVuY3Rpb24gcnVuKCkge1xuICB0cnkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCBteXNxbC5jcmVhdGVDb25uZWN0aW9uKHtcbiAgICAgIGhvc3Q6ICcxMjcuMC4wLjEnLFxuICAgICAgcG9ydDogMTAwMTQsXG4gICAgICB1c2VyOiAncm9vdCcsXG4gICAgICBwYXNzd29yZDogJ3Jvb3QnLFxuICAgICAgZGF0YWJhc2U6ICdpbnZlbnRvcnknXG4gICAgfSk7XG5cbiAgICBjb25zb2xlLmxvZygnQ29ubmVjdGVkIHRvIGRhdGFiYXNlLicpO1xuXG4gICAgY29uc3QgdGFibGVzID0gWydwcm9kdWN0JywgJ2NhdGVnb3J5X2F0dHJpYnV0ZScsICdjYXRlZ29yeSddO1xuXG4gICAgZm9yIChjb25zdCB0YWJsZSBvZiB0YWJsZXMpIHtcbiAgICAgIGNvbnNvbGUubG9nKGBcXG5Db25zdHJhaW50cyBmb3IgdGFibGU6ICR7dGFibGV9YCk7XG4gICAgICBjb25zdCBbcm93c10gPSBhd2FpdCBjb25uZWN0aW9uLmV4ZWN1dGUoYFxuICAgICAgICBTRUxFQ1QgQ09OU1RSQUlOVF9OQU1FLCBDT05TVFJBSU5UX1RZUEUgXG4gICAgICAgIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLlRBQkxFX0NPTlNUUkFJTlRTIFxuICAgICAgICBXSEVSRSBUQUJMRV9TQ0hFTUEgPSAnaW52ZW50b3J5JyBBTkQgVEFCTEVfTkFNRSA9ICcke3RhYmxlfSdcbiAgICAgIGApO1xuICAgICAgY29uc29sZS50YWJsZShyb3dzKTtcbiAgICB9XG4gICAgXG4gICAgYXdhaXQgY29ubmVjdGlvbi5lbmQoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yOicsIGUpO1xuICB9XG59XG5cbnJ1bigpO1xuIl19
|
|
||||||
|
|
@ -536,4 +536,88 @@ export class ProductController {
|
||||||
return errorResponse(error?.message || error);
|
return errorResponse(error?.message || error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取所有分类
|
||||||
|
@ApiOkResponse({ description: '获取所有分类' })
|
||||||
|
@Get('/categories/all')
|
||||||
|
async getCategoriesAll() {
|
||||||
|
try {
|
||||||
|
const data = await this.productService.getCategoriesAll();
|
||||||
|
return successResponse(data);
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error?.message || error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取分类下的属性配置
|
||||||
|
@ApiOkResponse({ description: '获取分类下的属性配置' })
|
||||||
|
@Get('/category/:id/attributes')
|
||||||
|
async getCategoryAttributes(@Param('id') id: number) {
|
||||||
|
try {
|
||||||
|
const data = await this.productService.getCategoryAttributes(id);
|
||||||
|
return successResponse(data);
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error?.message || error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建分类
|
||||||
|
@ApiOkResponse({ description: '创建分类' })
|
||||||
|
@Post('/category')
|
||||||
|
async createCategory(@Body() body: any) {
|
||||||
|
try {
|
||||||
|
const data = await this.productService.createCategory(body);
|
||||||
|
return successResponse(data);
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error?.message || error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新分类
|
||||||
|
@ApiOkResponse({ description: '更新分类' })
|
||||||
|
@Put('/category/:id')
|
||||||
|
async updateCategory(@Param('id') id: number, @Body() body: any) {
|
||||||
|
try {
|
||||||
|
const data = await this.productService.updateCategory(id, body);
|
||||||
|
return successResponse(data);
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error?.message || error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除分类
|
||||||
|
@ApiOkResponse({ description: '删除分类' })
|
||||||
|
@Del('/category/:id')
|
||||||
|
async deleteCategory(@Param('id') id: number) {
|
||||||
|
try {
|
||||||
|
await this.productService.deleteCategory(id);
|
||||||
|
return successResponse(true);
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error?.message || error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建分类属性
|
||||||
|
@ApiOkResponse({ description: '创建分类属性' })
|
||||||
|
@Post('/category/attribute')
|
||||||
|
async createCategoryAttribute(@Body() body: { categoryId: number; dictId: number }) {
|
||||||
|
try {
|
||||||
|
const data = await this.productService.createCategoryAttribute(body);
|
||||||
|
return successResponse(data);
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error?.message || error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除分类属性
|
||||||
|
@ApiOkResponse({ description: '删除分类属性' })
|
||||||
|
@Del('/category/attribute/:id')
|
||||||
|
async deleteCategoryAttribute(@Param('id') id: number) {
|
||||||
|
try {
|
||||||
|
await this.productService.deleteCategoryAttribute(id);
|
||||||
|
return successResponse(true);
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error?.message || error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,10 @@ import { SeederOptions } from 'typeorm-extension';
|
||||||
|
|
||||||
const options: DataSourceOptions & SeederOptions = {
|
const options: DataSourceOptions & SeederOptions = {
|
||||||
type: 'mysql',
|
type: 'mysql',
|
||||||
// host: 'localhost',
|
host: 'localhost',
|
||||||
// port: 10014,
|
port: 23306,
|
||||||
socketPath: '/Users/zksu/Library/Application Support/Local/run/oLbUT7qMU/mysql/mysqld.sock',
|
|
||||||
username: 'root',
|
username: 'root',
|
||||||
password: 'root',
|
password: '12345678',
|
||||||
database: 'inventory',
|
database: 'inventory',
|
||||||
synchronize: true,
|
synchronize: true,
|
||||||
logging: true,
|
logging: true,
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ export default class CategorySeeder implements Seeder {
|
||||||
{
|
{
|
||||||
name: 'pouches-can',
|
name: 'pouches-can',
|
||||||
title: 'Pouches Can',
|
title: 'Pouches Can',
|
||||||
titleCN: ' nicotine 袋',
|
titleCN: '口含烟盒',
|
||||||
sort: 3
|
sort: 3
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -65,9 +65,9 @@ export class CreateProductDTO {
|
||||||
@Rule(RuleType.number())
|
@Rule(RuleType.number())
|
||||||
promotionPrice?: number;
|
promotionPrice?: number;
|
||||||
|
|
||||||
// 中文注释:商品类型(默认 simple;bundle 需手动设置组成)
|
// 中文注释:商品类型(默认 single;bundle 需手动设置组成)
|
||||||
@ApiProperty({ description: '商品类型', enum: ['simple', 'bundle'], default: 'simple', required: false })
|
@ApiProperty({ description: '商品类型', enum: ['single', 'bundle'], default: 'single', required: false })
|
||||||
@Rule(RuleType.string().valid('simple', 'bundle').default('simple'))
|
@Rule(RuleType.string().valid('single', 'bundle').default('single'))
|
||||||
type?: string;
|
type?: string;
|
||||||
|
|
||||||
// 中文注释:仅当 type 为 'bundle' 时,才需要提供 components
|
// 中文注释:仅当 type 为 'bundle' 时,才需要提供 components
|
||||||
|
|
@ -123,9 +123,9 @@ export class UpdateProductDTO {
|
||||||
@Rule(RuleType.array())
|
@Rule(RuleType.array())
|
||||||
attributes?: AttributeInputDTO[];
|
attributes?: AttributeInputDTO[];
|
||||||
|
|
||||||
// 中文注释:商品类型更新(simple 或 bundle)
|
// 中文注释:商品类型(single 或 bundle)
|
||||||
@ApiProperty({ description: '商品类型', enum: ['simple', 'bundle'], required: false })
|
@ApiProperty({ description: '商品类型', enum: ['single', 'bundle'], required: false })
|
||||||
@Rule(RuleType.string().valid('simple', 'bundle'))
|
@Rule(RuleType.string().valid('single', 'bundle'))
|
||||||
type?: string;
|
type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import { Stock } from '../entity/stock.entity';
|
||||||
import { StockPoint } from '../entity/stock_point.entity';
|
import { StockPoint } from '../entity/stock_point.entity';
|
||||||
import { ProductStockComponent } from '../entity/product_stock_component.entity';
|
import { ProductStockComponent } from '../entity/product_stock_component.entity';
|
||||||
import { Category } from '../entity/category.entity';
|
import { Category } from '../entity/category.entity';
|
||||||
|
import { CategoryAttribute } from '../entity/category_attribute.entity';
|
||||||
|
|
||||||
@Provide()
|
@Provide()
|
||||||
export class ProductService {
|
export class ProductService {
|
||||||
|
|
@ -70,7 +71,96 @@ export class ProductService {
|
||||||
async getWpProducts() {
|
async getWpProducts() {
|
||||||
return this.wpProductModel.find();
|
return this.wpProductModel.find();
|
||||||
}
|
}
|
||||||
|
// 获取所有分类
|
||||||
|
async getCategoriesAll(): Promise<Category[]> {
|
||||||
|
return this.categoryModel.find({
|
||||||
|
order: {
|
||||||
|
sort: 'ASC',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取分类下的属性配置
|
||||||
|
async getCategoryAttributes(categoryId: number): Promise<any[]> {
|
||||||
|
const category = await this.categoryModel.findOne({
|
||||||
|
where: { id: categoryId },
|
||||||
|
relations: ['attributes', 'attributes.attributeDict', 'attributes.attributeDict.items'],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!category) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化返回,方便前端使用
|
||||||
|
return category.attributes.map(attr => ({
|
||||||
|
id: attr.id,
|
||||||
|
dictId: attr.attributeDict.id,
|
||||||
|
name: attr.attributeDict.name,
|
||||||
|
title: attr.attributeDict.title,
|
||||||
|
items: attr.attributeDict.items, // 如果需要返回具体的选项
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建分类
|
||||||
|
async createCategory(payload: Partial<Category>): Promise<Category> {
|
||||||
|
const exists = await this.categoryModel.findOne({ where: { name: payload.name } });
|
||||||
|
if (exists) {
|
||||||
|
throw new Error('分类已存在');
|
||||||
|
}
|
||||||
|
return this.categoryModel.save(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新分类
|
||||||
|
async updateCategory(id: number, payload: Partial<Category>): Promise<Category> {
|
||||||
|
const category = await this.categoryModel.findOne({ where: { id } });
|
||||||
|
if (!category) {
|
||||||
|
throw new Error('分类不存在');
|
||||||
|
}
|
||||||
|
await this.categoryModel.update(id, payload);
|
||||||
|
return this.categoryModel.findOne({ where: { id } });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除分类
|
||||||
|
async deleteCategory(id: number): Promise<boolean> {
|
||||||
|
const result = await this.categoryModel.delete(id);
|
||||||
|
return result.affected > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建分类属性关联
|
||||||
|
async createCategoryAttribute(payload: { categoryId: number; dictId: number }): Promise<any> {
|
||||||
|
const category = await this.categoryModel.findOne({ where: { id: payload.categoryId } });
|
||||||
|
if (!category) {
|
||||||
|
throw new Error('分类不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
const dict = await this.dictModel.findOne({ where: { id: payload.dictId } });
|
||||||
|
if (!dict) {
|
||||||
|
throw new Error('字典不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
const existing = await this.categoryModel.manager.findOne(CategoryAttribute, {
|
||||||
|
where: {
|
||||||
|
category: { id: payload.categoryId },
|
||||||
|
attributeDict: { id: payload.dictId },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existing) {
|
||||||
|
throw new Error('该属性已关联到此分类');
|
||||||
|
}
|
||||||
|
|
||||||
|
const attr = this.categoryModel.manager.create(CategoryAttribute, {
|
||||||
|
category,
|
||||||
|
attributeDict: dict
|
||||||
|
});
|
||||||
|
return this.categoryModel.manager.save(attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除分类属性关联
|
||||||
|
async deleteCategoryAttribute(id: number): Promise<boolean> {
|
||||||
|
const result = await this.categoryModel.manager.delete(CategoryAttribute, id);
|
||||||
|
return result.affected > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// async findProductsByName(name: string): Promise<Product[]> {
|
// async findProductsByName(name: string): Promise<Product[]> {
|
||||||
|
|
@ -309,7 +399,7 @@ export class ProductService {
|
||||||
if (categoryItem) {
|
if (categoryItem) {
|
||||||
product.category = categoryItem;
|
product.category = categoryItem;
|
||||||
}
|
}
|
||||||
// 条件判断(中文注释:设置商品类型,默认 simple)
|
// 条件判断(中文注释:设置商品类型,默认 single)
|
||||||
product.type = (createProductDTO.type as any) || 'single';
|
product.type = (createProductDTO.type as any) || 'single';
|
||||||
|
|
||||||
// 生成或设置 SKU(中文注释:基于属性字典项的 name 生成)
|
// 生成或设置 SKU(中文注释:基于属性字典项的 name 生成)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue