Compare commits
2 Commits
3545633f9e
...
cd72783291
| Author | SHA1 | Date |
|---|---|---|
|
|
cd72783291 | |
|
|
46cfaa24e7 |
|
|
@ -34,6 +34,7 @@ import { Site } from '../entity/site.entity';
|
||||||
import { Dict } from '../entity/dict.entity';
|
import { Dict } from '../entity/dict.entity';
|
||||||
import { DictItem } from '../entity/dict_item.entity';
|
import { DictItem } from '../entity/dict_item.entity';
|
||||||
import { Template } from '../entity/template.entity';
|
import { Template } from '../entity/template.entity';
|
||||||
|
import { Area } from '../entity/area.entity';
|
||||||
import DictSeeder from '../db/seeds/dict.seeder';
|
import DictSeeder from '../db/seeds/dict.seeder';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -76,7 +77,8 @@ export default {
|
||||||
Site,
|
Site,
|
||||||
Dict,
|
Dict,
|
||||||
DictItem,
|
DictItem,
|
||||||
Template
|
Template,
|
||||||
|
Area,
|
||||||
],
|
],
|
||||||
synchronize: true,
|
synchronize: true,
|
||||||
logging: false,
|
logging: false,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
|
||||||
|
import { Inject } from '@midwayjs/core';
|
||||||
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Del,
|
||||||
|
Get,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
Put,
|
||||||
|
Query,
|
||||||
|
} from '@midwayjs/decorator';
|
||||||
|
import {
|
||||||
|
ApiBearerAuth,
|
||||||
|
ApiBody,
|
||||||
|
ApiExtension,
|
||||||
|
ApiOkResponse,
|
||||||
|
ApiOperation,
|
||||||
|
ApiTags,
|
||||||
|
} from '@midwayjs/swagger';
|
||||||
|
import { AreaService } from '../service/area.service';
|
||||||
|
import { CreateAreaDTO, QueryAreaDTO, UpdateAreaDTO } from '../dto/area.dto';
|
||||||
|
import { errorResponse, successResponse } from '../utils/response.util';
|
||||||
|
import { Area } from '../entity/area.entity';
|
||||||
|
|
||||||
|
@ApiBearerAuth()
|
||||||
|
@ApiTags('Area')
|
||||||
|
@Controller('/api/area')
|
||||||
|
export class AreaController {
|
||||||
|
@Inject()
|
||||||
|
areaService: AreaService;
|
||||||
|
|
||||||
|
@ApiOperation({ summary: '创建区域' })
|
||||||
|
@ApiBody({ type: CreateAreaDTO })
|
||||||
|
@ApiOkResponse({ type: Area, description: '成功创建的区域' })
|
||||||
|
@Post('/')
|
||||||
|
async createArea(@Body() area: CreateAreaDTO) {
|
||||||
|
try {
|
||||||
|
const newArea = await this.areaService.createArea(area);
|
||||||
|
return successResponse(newArea, '创建成功');
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation({ summary: '更新区域' })
|
||||||
|
@ApiBody({ type: UpdateAreaDTO })
|
||||||
|
@ApiOkResponse({ type: Area, description: '成功更新的区域' })
|
||||||
|
@Put('/:id')
|
||||||
|
async updateArea(@Param('id') id: number, @Body() area: UpdateAreaDTO) {
|
||||||
|
try {
|
||||||
|
const updatedArea = await this.areaService.updateArea(id, area);
|
||||||
|
return successResponse(updatedArea, '更新成功');
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation({ summary: '删除区域' })
|
||||||
|
@ApiOkResponse({ description: '删除成功' })
|
||||||
|
@Del('/:id')
|
||||||
|
async deleteArea(@Param('id') id: number) {
|
||||||
|
try {
|
||||||
|
await this.areaService.deleteArea(id);
|
||||||
|
return successResponse(null, '删除成功');
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation({ summary: '获取区域列表(分页)' })
|
||||||
|
@ApiOkResponse({ type: [Area], description: '区域列表' })
|
||||||
|
@ApiExtension('x-pagination', { currentPage: 1, pageSize: 10, total: 100 })
|
||||||
|
@Get('/')
|
||||||
|
async getAreaList(@Query() query: QueryAreaDTO) {
|
||||||
|
try {
|
||||||
|
const { list, total } = await this.areaService.getAreaList(query);
|
||||||
|
return successResponse({ list, total }, '查询成功');
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation({ summary: '获取所有区域' })
|
||||||
|
@ApiOkResponse({ type: [Area], description: '所有区域列表' })
|
||||||
|
@Get('/all')
|
||||||
|
async getAllAreas() {
|
||||||
|
try {
|
||||||
|
const areas = await this.areaService.getAllAreas();
|
||||||
|
return successResponse(areas, '查询成功');
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation({ summary: '根据ID获取区域详情' })
|
||||||
|
@ApiOkResponse({ type: Area, description: '区域详情' })
|
||||||
|
@Get('/:id')
|
||||||
|
async getAreaById(@Param('id') id: number) {
|
||||||
|
try {
|
||||||
|
const area = await this.areaService.getAreaById(id);
|
||||||
|
if (!area) {
|
||||||
|
return errorResponse('区域不存在');
|
||||||
|
}
|
||||||
|
return successResponse(area, '查询成功');
|
||||||
|
} catch (error) {
|
||||||
|
return errorResponse(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Inject, Controller, Get, Post, Put, Del, Body, Param } from '@midwayjs/core';
|
import { Inject, Controller, Get, Post, Put, Del, Body, Param, Query } from '@midwayjs/core';
|
||||||
import { TemplateService } from '../service/template.service';
|
import { TemplateService } from '../service/template.service';
|
||||||
import { successResponse, errorResponse } from '../utils/response.util';
|
import { successResponse, errorResponse } from '../utils/response.util';
|
||||||
import { CreateTemplateDTO, UpdateTemplateDTO } from '../dto/template.dto';
|
import { CreateTemplateDTO, UpdateTemplateDTO } from '../dto/template.dto';
|
||||||
|
|
@ -20,17 +20,10 @@ export class TemplateController {
|
||||||
* @description 获取所有可用模板的列表
|
* @description 获取所有可用模板的列表
|
||||||
*/
|
*/
|
||||||
@ApiOkResponse({ type: [Template], description: '成功获取模板列表' })
|
@ApiOkResponse({ type: [Template], description: '成功获取模板列表' })
|
||||||
@Get('/')
|
@Get('/list')
|
||||||
async getTemplateList() {
|
async getTemplateList(@Query() params: any) {
|
||||||
try {
|
|
||||||
// 调用服务层获取列表
|
// 调用服务层获取列表
|
||||||
const data = await this.templateService.getTemplateList();
|
return this.templateService.getTemplateList(params);
|
||||||
// 返回成功响应
|
|
||||||
return successResponse(data);
|
|
||||||
} catch (error) {
|
|
||||||
// 返回错误响应
|
|
||||||
return errorResponse(error.message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -112,4 +105,27 @@ export class TemplateController {
|
||||||
return errorResponse(error.message);
|
return errorResponse(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary 渲染模板
|
||||||
|
* @description 根据模板名称和输入的数据渲染最终字符串
|
||||||
|
* @param name 模板名称
|
||||||
|
* @param data 渲染数据
|
||||||
|
*/
|
||||||
|
@ApiOkResponse({ type: String, description: '成功渲染模板' })
|
||||||
|
@Post('/render/:name')
|
||||||
|
async renderTemplate(
|
||||||
|
@Param('name') name: string,
|
||||||
|
@Body() data: Record<string, any>
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
// 调用服务层渲染模板
|
||||||
|
const renderedString = await this.templateService.render(name, data);
|
||||||
|
// 返回成功响应
|
||||||
|
return successResponse(renderedString);
|
||||||
|
} catch (error) {
|
||||||
|
// 返回错误响应
|
||||||
|
return errorResponse(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ import { Subscription } from '../entity/subscription.entity';
|
||||||
import { Site } from '../entity/site.entity';
|
import { Site } from '../entity/site.entity';
|
||||||
import { Dict } from '../entity/dict.entity';
|
import { Dict } from '../entity/dict.entity';
|
||||||
import { DictItem } from '../entity/dict_item.entity';
|
import { DictItem } from '../entity/dict_item.entity';
|
||||||
|
import { Template } from '../entity/template.entity';
|
||||||
|
import { Area } from '../entity/area.entity';
|
||||||
|
|
||||||
const options: DataSourceOptions & SeederOptions = {
|
const options: DataSourceOptions & SeederOptions = {
|
||||||
type: 'mysql',
|
type: 'mysql',
|
||||||
|
|
@ -79,8 +81,10 @@ const options: DataSourceOptions & SeederOptions = {
|
||||||
Site,
|
Site,
|
||||||
Dict,
|
Dict,
|
||||||
DictItem,
|
DictItem,
|
||||||
|
Template,
|
||||||
|
Area,
|
||||||
],
|
],
|
||||||
migrations: ['src/migration/*.ts'],
|
migrations: ['src/db/migrations/**/*.ts'],
|
||||||
seeds: ['src/db/seeds/**/*.ts'],
|
seeds: ['src/db/seeds/**/*.ts'],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class Area1764294088896 implements MigrationInterface {
|
||||||
|
name = 'Area1764294088896'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
// await queryRunner.query(`DROP INDEX \`IDX_4ca3fbc46d2dbf393ff4ebddbb\` ON \`site\``);
|
||||||
|
// await queryRunner.query(`CREATE TABLE \`area\` (\`id\` int NOT NULL AUTO_INCREMENT, \`name\` varchar(255) NOT NULL, \`createdAt\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), \`updatedAt\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), UNIQUE INDEX \`IDX_644ffaf8fbde4db798cb47712f\` (\`name\`), PRIMARY KEY (\`id\`)) ENGINE=InnoDB`);
|
||||||
|
// await queryRunner.query(`CREATE TABLE \`stock_point_areas_area\` (\`stockPointId\` int NOT NULL, \`areaId\` int NOT NULL, INDEX \`IDX_07d2db2150151e2ef341d2f1de\` (\`stockPointId\`), INDEX \`IDX_92707ea81fc19dc707dba24819\` (\`areaId\`), PRIMARY KEY (\`stockPointId\`, \`areaId\`)) ENGINE=InnoDB`);
|
||||||
|
// await queryRunner.query(`CREATE TABLE \`site_areas_area\` (\`siteId\` int NOT NULL, \`areaId\` int NOT NULL, INDEX \`IDX_926a14ac4c91f38792831acd2a\` (\`siteId\`), INDEX \`IDX_7c26c582048e3ecd3cd5938cb9\` (\`areaId\`), PRIMARY KEY (\`siteId\`, \`areaId\`)) ENGINE=InnoDB`);
|
||||||
|
// await queryRunner.query(`ALTER TABLE \`site\` DROP COLUMN \`siteName\``);
|
||||||
|
// await queryRunner.query(`ALTER TABLE `product` ADD `promotionPrice` decimal(10,2) NOT NULL DEFAULT '0.00'`);
|
||||||
|
// await queryRunner.query(`ALTER TABLE `product` ADD `source` int NOT NULL DEFAULT '0'`);
|
||||||
|
// await queryRunner.query(`ALTER TABLE \`site\` ADD \`token\` varchar(255) NULL`);
|
||||||
|
// await queryRunner.query(`ALTER TABLE `site` ADD `name` varchar(255) NOT NULL`);
|
||||||
|
// await queryRunner.query(`ALTER TABLE \`site\` ADD UNIQUE INDEX \`IDX_9669a09fcc0eb6d2794a658f64\` (\`name\`)`);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`stock_point_areas_area\` ADD CONSTRAINT \`FK_07d2db2150151e2ef341d2f1de1\` FOREIGN KEY (\`stockPointId\`) REFERENCES \`stock_point\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`stock_point_areas_area\` ADD CONSTRAINT \`FK_92707ea81fc19dc707dba24819c\` FOREIGN KEY (\`areaId\`) REFERENCES \`area\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`site_areas_area\` ADD CONSTRAINT \`FK_926a14ac4c91f38792831acd2a6\` FOREIGN KEY (\`siteId\`) REFERENCES \`site\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`site_areas_area\` ADD CONSTRAINT \`FK_7c26c582048e3ecd3cd5938cb9f\` FOREIGN KEY (\`areaId\`) REFERENCES \`area\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE \`site_areas_area\` DROP FOREIGN KEY \`FK_7c26c582048e3ecd3cd5938cb9f\``);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`site_areas_area\` DROP FOREIGN KEY \`FK_926a14ac4c91f38792831acd2a6\``);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`stock_point_areas_area\` DROP FOREIGN KEY \`FK_92707ea81fc19dc707dba24819c\``);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`stock_point_areas_area\` DROP FOREIGN KEY \`FK_07d2db2150151e2ef341d2f1de1\``);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`site\` DROP INDEX \`IDX_9669a09fcc0eb6d2794a658f64\``);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`site\` DROP COLUMN \`name\``);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`site\` DROP COLUMN \`token\``);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`product\` DROP COLUMN \`source\``);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`product\` DROP COLUMN \`promotionPrice\``);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`site\` ADD \`siteName\` varchar(255) NOT NULL`);
|
||||||
|
await queryRunner.query(`DROP INDEX \`IDX_7c26c582048e3ecd3cd5938cb9\` ON \`site_areas_area\``);
|
||||||
|
await queryRunner.query(`DROP INDEX \`IDX_926a14ac4c91f38792831acd2a\` ON \`site_areas_area\``);
|
||||||
|
await queryRunner.query(`DROP TABLE \`site_areas_area\``);
|
||||||
|
await queryRunner.query(`DROP INDEX \`IDX_92707ea81fc19dc707dba24819\` ON \`stock_point_areas_area\``);
|
||||||
|
await queryRunner.query(`DROP INDEX \`IDX_07d2db2150151e2ef341d2f1de\` ON \`stock_point_areas_area\``);
|
||||||
|
await queryRunner.query(`DROP TABLE \`stock_point_areas_area\``);
|
||||||
|
await queryRunner.query(`DROP INDEX \`IDX_644ffaf8fbde4db798cb47712f\` ON \`area\``);
|
||||||
|
await queryRunner.query(`DROP TABLE \`area\``);
|
||||||
|
await queryRunner.query(`CREATE UNIQUE INDEX \`IDX_4ca3fbc46d2dbf393ff4ebddbb\` ON \`site\` (\`siteName\`)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
import { Seeder, SeederFactoryManager } from 'typeorm-extension';
|
||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
import { Area } from '../../entity/area.entity';
|
||||||
|
|
||||||
|
export default class AreaSeeder implements Seeder {
|
||||||
|
public async run(
|
||||||
|
dataSource: DataSource,
|
||||||
|
factoryManager: SeederFactoryManager
|
||||||
|
): Promise<any> {
|
||||||
|
const repository = dataSource.getRepository(Area);
|
||||||
|
|
||||||
|
const areas = [
|
||||||
|
{ name: '加拿大' },
|
||||||
|
{ name: '澳大利亚' },
|
||||||
|
{ name: '欧洲' },
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const area of areas) {
|
||||||
|
const existing = await repository.findOne({ where: { name: area.name } });
|
||||||
|
if (!existing) {
|
||||||
|
await repository.insert(area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
|
||||||
|
import { ApiProperty } from '@midwayjs/swagger';
|
||||||
|
import { Rule, RuleType } from '@midwayjs/validate';
|
||||||
|
|
||||||
|
// 创建区域的数据传输对象
|
||||||
|
export class CreateAreaDTO {
|
||||||
|
@ApiProperty({ type: 'string', description: '区域名称', example: '欧洲' })
|
||||||
|
@Rule(RuleType.string().required())
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新区域的数据传输对象
|
||||||
|
export class UpdateAreaDTO {
|
||||||
|
@ApiProperty({ type: 'string', description: '区域名称', example: '欧洲' })
|
||||||
|
@Rule(RuleType.string())
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询区域的数据传输对象
|
||||||
|
export class QueryAreaDTO {
|
||||||
|
@ApiProperty({ type: 'number', description: '当前页码', example: 1 })
|
||||||
|
@Rule(RuleType.number().min(1).default(1))
|
||||||
|
currentPage: number;
|
||||||
|
|
||||||
|
@ApiProperty({ type: 'number', description: '每页数量', example: 10 })
|
||||||
|
@Rule(RuleType.number().min(1).max(100).default(10))
|
||||||
|
pageSize: number;
|
||||||
|
|
||||||
|
@ApiProperty({ type: 'string', description: '区域名称', example: '欧洲' })
|
||||||
|
@Rule(RuleType.string())
|
||||||
|
name?: string;
|
||||||
|
}
|
||||||
|
|
@ -61,6 +61,11 @@ export class CreateProductDTO {
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@Rule(RuleType.string())
|
@Rule(RuleType.string())
|
||||||
humidity: string;
|
humidity: string;
|
||||||
|
|
||||||
|
// 商品价格
|
||||||
|
@ApiProperty({ description: '价格', example: 99.99, required: false })
|
||||||
|
@Rule(RuleType.number())
|
||||||
|
price?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -132,7 +137,7 @@ export class QueryBrandDTO {
|
||||||
pageSize: number; // 每页大小
|
pageSize: number; // 每页大小
|
||||||
|
|
||||||
@ApiProperty({ example: 'ZYN', description: '关键字' })
|
@ApiProperty({ example: 'ZYN', description: '关键字' })
|
||||||
@Rule(RuleType.string().required())
|
@Rule(RuleType.string())
|
||||||
name: string; // 搜索关键字(支持模糊查询)
|
name: string; // 搜索关键字(支持模糊查询)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { ApiProperty } from '@midwayjs/swagger';
|
||||||
|
import {
|
||||||
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
|
Entity,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
UpdateDateColumn,
|
||||||
|
} from 'typeorm';
|
||||||
|
|
||||||
|
@Entity('area')
|
||||||
|
export class Area {
|
||||||
|
@ApiProperty({ type: 'number' })
|
||||||
|
@PrimaryGeneratedColumn()
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@ApiProperty({ type: 'string', description: '区域名称' })
|
||||||
|
@Column({ unique: true })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
example: '2022-12-12 11:11:11',
|
||||||
|
description: '创建时间',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
@CreateDateColumn()
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
example: '2022-12-12 11:11:11',
|
||||||
|
description: '更新时间',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
@UpdateDateColumn()
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
@ -42,12 +42,27 @@ export class Product {
|
||||||
@Column({ unique: true })
|
@Column({ unique: true })
|
||||||
sku: string;
|
sku: string;
|
||||||
|
|
||||||
|
// 商品价格
|
||||||
|
@ApiProperty({ description: '价格', example: 99.99 })
|
||||||
|
@Column({ type: 'decimal', precision: 10, scale: 2, default: 0 })
|
||||||
|
price: number;
|
||||||
|
|
||||||
|
// 促销价格
|
||||||
|
@ApiProperty({ description: '促销价格', example: 99.99 })
|
||||||
|
@Column({ type: 'decimal', precision: 10, scale: 2, default: 0 })
|
||||||
|
promotionPrice: number;
|
||||||
|
|
||||||
@ManyToMany(() => DictItem, {
|
@ManyToMany(() => DictItem, {
|
||||||
cascade: true,
|
cascade: true,
|
||||||
})
|
})
|
||||||
@JoinTable()
|
@JoinTable()
|
||||||
attributes: DictItem[];
|
attributes: DictItem[];
|
||||||
|
|
||||||
|
// 来源
|
||||||
|
@ApiProperty({ description: '来源', example: '1' })
|
||||||
|
@Column({ default: 0 })
|
||||||
|
source: number;
|
||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
example: '2022-12-12 11:11:11',
|
example: '2022-12-12 11:11:11',
|
||||||
description: '创建时间',
|
description: '创建时间',
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
import { Column, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
|
import { Area } from './area.entity';
|
||||||
|
|
||||||
@Entity('site')
|
@Entity('site')
|
||||||
export class Site {
|
export class Site {
|
||||||
|
|
@ -14,8 +15,11 @@ export class Site {
|
||||||
@Column({ length: 255, nullable: true })
|
@Column({ length: 255, nullable: true })
|
||||||
consumerSecret: string;
|
consumerSecret: string;
|
||||||
|
|
||||||
|
@Column({ nullable: true })
|
||||||
|
token: string;
|
||||||
|
|
||||||
@Column({ length: 255, unique: true })
|
@Column({ length: 255, unique: true })
|
||||||
siteName: string;
|
name: string;
|
||||||
|
|
||||||
@Column({ length: 32, default: 'woocommerce' })
|
@Column({ length: 32, default: 'woocommerce' })
|
||||||
type: string; // 平台类型:woocommerce | shopyy
|
type: string; // 平台类型:woocommerce | shopyy
|
||||||
|
|
@ -25,4 +29,8 @@ export class Site {
|
||||||
|
|
||||||
@Column({ default: false })
|
@Column({ default: false })
|
||||||
isDisabled: boolean;
|
isDisabled: boolean;
|
||||||
|
|
||||||
|
@ManyToMany(() => Area)
|
||||||
|
@JoinTable()
|
||||||
|
areas: Area[];
|
||||||
}
|
}
|
||||||
|
|
@ -8,8 +8,11 @@ import {
|
||||||
PrimaryGeneratedColumn,
|
PrimaryGeneratedColumn,
|
||||||
UpdateDateColumn,
|
UpdateDateColumn,
|
||||||
OneToMany,
|
OneToMany,
|
||||||
|
ManyToMany,
|
||||||
|
JoinTable,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
import { Shipment } from './shipment.entity';
|
import { Shipment } from './shipment.entity';
|
||||||
|
import { Area } from './area.entity';
|
||||||
|
|
||||||
@Entity('stock_point')
|
@Entity('stock_point')
|
||||||
export class StockPoint extends BaseEntity {
|
export class StockPoint extends BaseEntity {
|
||||||
|
|
@ -72,4 +75,8 @@ export class StockPoint extends BaseEntity {
|
||||||
|
|
||||||
@DeleteDateColumn()
|
@DeleteDateColumn()
|
||||||
deletedAt: Date; // 软删除时间
|
deletedAt: Date; // 软删除时间
|
||||||
|
|
||||||
|
@ManyToMany(() => Area)
|
||||||
|
@JoinTable()
|
||||||
|
areas: Area[];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,13 @@ export class Template {
|
||||||
@Column('text',{nullable: true,comment: "描述"})
|
@Column('text',{nullable: true,comment: "描述"})
|
||||||
description?: string;
|
description?: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
example: true,
|
||||||
|
description: '是否可删除',
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
@Column({ default: true })
|
||||||
|
deletable: boolean;
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
example: '2022-12-12 11:11:11',
|
example: '2022-12-12 11:11:11',
|
||||||
description: '创建时间',
|
description: '创建时间',
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export class WpProduct {
|
||||||
@Column()
|
@Column()
|
||||||
externalProductId: string;
|
externalProductId: string;
|
||||||
|
|
||||||
@ApiProperty({ description: 'sku', type: 'string' })
|
@ApiProperty({ description: '商店sku', type: 'string' })
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
sku?: string;
|
sku?: string;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
|
||||||
|
import { Provide } from '@midwayjs/core';
|
||||||
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||||
|
import { Repository } from 'typeorm';
|
||||||
|
import { Area } from '../entity/area.entity';
|
||||||
|
import { CreateAreaDTO, QueryAreaDTO, UpdateAreaDTO } from '../dto/area.dto';
|
||||||
|
|
||||||
|
@Provide()
|
||||||
|
export class AreaService {
|
||||||
|
@InjectEntityModel(Area)
|
||||||
|
areaModel: Repository<Area>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建区域
|
||||||
|
* @param params 创建参数
|
||||||
|
*/
|
||||||
|
async createArea(params: CreateAreaDTO) {
|
||||||
|
// 检查区域名称是否已存在
|
||||||
|
const existing = await this.areaModel.findOne({ where: { name: params.name } });
|
||||||
|
if (existing) {
|
||||||
|
throw new Error('区域名称已存在');
|
||||||
|
}
|
||||||
|
const area = new Area();
|
||||||
|
area.name = params.name;
|
||||||
|
return await this.areaModel.save(area);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新区域
|
||||||
|
* @param id 区域ID
|
||||||
|
* @param params 更新参数
|
||||||
|
*/
|
||||||
|
async updateArea(id: number, params: UpdateAreaDTO) {
|
||||||
|
const area = await this.areaModel.findOneBy({ id });
|
||||||
|
if (!area) {
|
||||||
|
throw new Error('区域不存在');
|
||||||
|
}
|
||||||
|
if (params.name) {
|
||||||
|
// 检查新的区域名称是否已存在
|
||||||
|
const existing = await this.areaModel.findOne({ where: { name: params.name } });
|
||||||
|
if (existing && existing.id !== id) {
|
||||||
|
throw new Error('区域名称已存在');
|
||||||
|
}
|
||||||
|
area.name = params.name;
|
||||||
|
}
|
||||||
|
return await this.areaModel.save(area);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除区域
|
||||||
|
* @param id 区域ID
|
||||||
|
*/
|
||||||
|
async deleteArea(id: number) {
|
||||||
|
const result = await this.areaModel.delete(id);
|
||||||
|
return result.affected > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取区域列表(分页)
|
||||||
|
* @param query 查询参数
|
||||||
|
*/
|
||||||
|
async getAreaList(query: QueryAreaDTO) {
|
||||||
|
const { currentPage, pageSize, name } = query;
|
||||||
|
const [list, total] = await this.areaModel.findAndCount({
|
||||||
|
where: name ? { name } : {},
|
||||||
|
skip: (currentPage - 1) * pageSize,
|
||||||
|
take: pageSize,
|
||||||
|
order: {
|
||||||
|
id: 'DESC',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { list, total };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有区域
|
||||||
|
*/
|
||||||
|
async getAllAreas() {
|
||||||
|
return await this.areaModel.find();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID获取区域详情
|
||||||
|
* @param id 区域ID
|
||||||
|
*/
|
||||||
|
async getAreaById(id: number) {
|
||||||
|
return await this.areaModel.findOneBy({ id });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1350,7 +1350,7 @@ export class OrderService {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...order,
|
...order,
|
||||||
siteName: site?.siteName,
|
siteName: site?.name,
|
||||||
// Site 实体无邮箱字段,这里返回空字符串保持兼容
|
// Site 实体无邮箱字段,这里返回空字符串保持兼容
|
||||||
email: '',
|
email: '',
|
||||||
items,
|
items,
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,10 @@ export class SiteService {
|
||||||
// 将配置中的 WpSite 同步到数据库 Site 表(用于一次性导入或初始化)
|
// 将配置中的 WpSite 同步到数据库 Site 表(用于一次性导入或初始化)
|
||||||
for (const siteConfig of sites) {
|
for (const siteConfig of sites) {
|
||||||
// 按站点名称查询是否已存在记录
|
// 按站点名称查询是否已存在记录
|
||||||
const exist = await this.siteModel.findOne({ where: { siteName: siteConfig.siteName } });
|
const exist = await this.siteModel.findOne({ where: { name: siteConfig.siteName } });
|
||||||
// 将 WpSite 字段映射为 Site 实体字段
|
// 将 WpSite 字段映射为 Site 实体字段
|
||||||
const payload: Partial<Site> = {
|
const payload: Partial<Site> = {
|
||||||
siteName: siteConfig.siteName,
|
name: siteConfig.siteName,
|
||||||
apiUrl: (siteConfig as any).wpApiUrl,
|
apiUrl: (siteConfig as any).wpApiUrl,
|
||||||
consumerKey: (siteConfig as any).consumerKey,
|
consumerKey: (siteConfig as any).consumerKey,
|
||||||
consumerSecret: (siteConfig as any).consumerSecret,
|
consumerSecret: (siteConfig as any).consumerSecret,
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,14 @@ export class TemplateService {
|
||||||
* 获取所有模板的列表
|
* 获取所有模板的列表
|
||||||
* @returns {Promise<Template[]>} 模板实体数组
|
* @returns {Promise<Template[]>} 模板实体数组
|
||||||
*/
|
*/
|
||||||
async getTemplateList(): Promise<Template[]> {
|
async getTemplateList(params: { currentPage?: number, pageSize?: number } = {}): Promise<{ items: Template[], total: number }> {
|
||||||
// 使用 find 方法查询所有模板
|
const { currentPage = 1, pageSize = 10 } = params;
|
||||||
return this.templateModel.find();
|
// 使用 findAndCount 方法查询所有模板
|
||||||
|
const [items, total] = await this.templateModel.findAndCount({
|
||||||
|
skip: (currentPage - 1) * pageSize,
|
||||||
|
take: pageSize,
|
||||||
|
});
|
||||||
|
return { items, total };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -76,6 +81,16 @@ export class TemplateService {
|
||||||
* @returns {Promise<boolean>} 如果删除成功则返回 true,否则返回 false
|
* @returns {Promise<boolean>} 如果删除成功则返回 true,否则返回 false
|
||||||
*/
|
*/
|
||||||
async deleteTemplate(id: number): Promise<boolean> {
|
async deleteTemplate(id: number): Promise<boolean> {
|
||||||
|
// 首先根据 ID 查找模板
|
||||||
|
const template = await this.templateModel.findOneBy({ id });
|
||||||
|
// 如果模板不存在,则抛出错误
|
||||||
|
if (!template) {
|
||||||
|
throw new Error(`模板 ID ${id} 不存在`);
|
||||||
|
}
|
||||||
|
// 如果模板不可删除,则抛出错误
|
||||||
|
if (!template.deletable) {
|
||||||
|
throw new Error(`模板 ${template.name} 不可删除`);
|
||||||
|
}
|
||||||
// 执行删除操作
|
// 执行删除操作
|
||||||
const result = await this.templateModel.delete(id);
|
const result = await this.templateModel.delete(id);
|
||||||
// 如果影响的行数大于 0,则表示删除成功
|
// 如果影响的行数大于 0,则表示删除成功
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue