feat: Domain develop
This commit is contained in:
parent
8ad1a48c60
commit
cd32cc1ac0
|
@ -31,6 +31,7 @@ import { ProductModule } from './modules/product/product.module';
|
|||
import { ProjectModule } from './modules/project/project.module';
|
||||
import { VehicleUsageModule } from './modules/vehicle_usage/vehicle_usage.module';
|
||||
import { SaleQuotationModule } from './modules/sale_quotation/sale_quotation.module';
|
||||
import { DomainModule } from './modules/domian/domain.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
|
@ -77,7 +78,9 @@ import { SaleQuotationModule } from './modules/sale_quotation/sale_quotation.mod
|
|||
VehicleUsageModule,
|
||||
|
||||
//报价管理
|
||||
SaleQuotationModule
|
||||
SaleQuotationModule,
|
||||
//域
|
||||
DomainModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: APP_FILTER, useClass: AllExceptionsFilter },
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { ExecutionContext, createParamDecorator } from '@nestjs/common';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsOptional } from 'class-validator';
|
||||
import type { FastifyRequest } from 'fastify';
|
||||
/**
|
||||
* 当前域
|
||||
*/
|
||||
export const Domain = createParamDecorator((_, context: ExecutionContext) => {
|
||||
const request = context.switchToHttp().getRequest<FastifyRequest>();
|
||||
return request.headers['sk-domain'];
|
||||
});
|
||||
|
||||
export type SkDomain = number;
|
||||
export class DomainType {
|
||||
@ApiProperty({ description: '所属域' })
|
||||
@IsOptional()
|
||||
domain: SkDomain;
|
||||
}
|
|
@ -5,6 +5,7 @@ import type { FastifyRequest } from 'fastify';
|
|||
|
||||
import { getIp, getIsMobile } from '~/utils/ip.util';
|
||||
|
||||
|
||||
/**
|
||||
* 快速获取IP
|
||||
*/
|
||||
|
|
|
@ -65,6 +65,8 @@ export enum ErrorEnum {
|
|||
|
||||
// SaleQuotation
|
||||
SALE_QUOTATION_COMPONENT_DUPLICATED = '1412:存在名称,价格,规格都相同的配件,请检查是否重复录入',
|
||||
SALE_QUOTATION_TEMPLATE_NAME_DUPLICATE = '1413:模板名已存在'
|
||||
SALE_QUOTATION_TEMPLATE_NAME_DUPLICATE = '1413:模板名已存在',
|
||||
|
||||
//domain
|
||||
DOMAIN_TITLE_DUPLICATE = '1414:域标题已存在'
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import { LoginToken } from './models/auth.model';
|
|||
import { CaptchaService } from './services/captcha.service';
|
||||
import { AuthUser } from './decorators/auth-user.decorator';
|
||||
import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator';
|
||||
import { Domain, SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
@ApiTags('Auth - 认证模块')
|
||||
@UseGuards(LocalGuard)
|
||||
|
@ -35,7 +36,7 @@ export class AuthController {
|
|||
@IsMobile() isMobile: boolean,
|
||||
@Headers('user-agent') ua: string
|
||||
): Promise<LoginToken> {
|
||||
if(!isMobile){
|
||||
if (!isMobile) {
|
||||
await this.captchaService.checkImgCaptcha(dto.captchaId, dto.verifyCode);
|
||||
}
|
||||
const token = await this.authService.login(dto.username, dto.password, ip, ua);
|
||||
|
@ -53,7 +54,7 @@ export class AuthController {
|
|||
|
||||
@Post('register')
|
||||
@ApiOperation({ summary: '注册' })
|
||||
async register(@Body() dto: RegisterDto): Promise<void> {
|
||||
await this.userService.register(dto);
|
||||
async register(@Domain() domain: SkDomain, @Body() dto: RegisterDto): Promise<void> {
|
||||
await this.userService.register(dto, domain);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import { AccountMenus, AccountUpdateDto } from '../dto/account.dto';
|
|||
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
|
||||
import { IsMobile } from '~/common/decorators/http.decorator';
|
||||
import { ResourceDeviceEnum } from '~/constants/enum';
|
||||
import { Domain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
@ApiTags('Account - 账户模块')
|
||||
@ApiSecurityAuth()
|
||||
|
|
|
@ -16,6 +16,7 @@ import { ApiResult } from '~/common/decorators/api-result.decorator';
|
|||
import { CompanyEntity } from './company.entity';
|
||||
import { CompanyDto, CompanyQueryDto, CompanyUpdateDto } from './company.dto';
|
||||
import { IdParam } from '~/common/decorators/id-param.decorator';
|
||||
import { Domain, SkDomain } from '~/common/decorators/domain.decorator';
|
||||
export const permissions = definePermission('app:company', {
|
||||
LIST: 'list',
|
||||
CREATE: 'create',
|
||||
|
@ -24,7 +25,7 @@ export const permissions = definePermission('app:company', {
|
|||
DELETE: 'delete'
|
||||
} as const);
|
||||
|
||||
@ApiTags('Company - 公司')
|
||||
@ApiTags('Company - 公司')
|
||||
@ApiSecurityAuth()
|
||||
@Controller('company')
|
||||
export class CompanyController {
|
||||
|
@ -34,8 +35,8 @@ export class CompanyController {
|
|||
@ApiOperation({ summary: '获取公司列表' })
|
||||
@ApiResult({ type: [CompanyEntity], isPage: true })
|
||||
@Perm(permissions.LIST)
|
||||
async list(@Query() dto: CompanyQueryDto) {
|
||||
return this.companyService.findAll(dto);
|
||||
async list(@Domain() domain: SkDomain, @Query() dto: CompanyQueryDto) {
|
||||
return this.companyService.findAll({ ...dto, domain });
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
|
@ -49,8 +50,8 @@ export class CompanyController {
|
|||
@Post()
|
||||
@ApiOperation({ summary: '新增公司' })
|
||||
@Perm(permissions.CREATE)
|
||||
async create(@Body() dto: CompanyDto): Promise<void> {
|
||||
await this.companyService.create(dto);
|
||||
async create(@Domain() domain: SkDomain, @Body() dto: CompanyDto): Promise<void> {
|
||||
await this.companyService.create({ ...dto, domain });
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
|
|
|
@ -15,8 +15,9 @@ import { PagerDto } from '~/common/dto/pager.dto';
|
|||
import { Storage } from '../tools/storage/storage.entity';
|
||||
import { IsUnique } from '~/shared/database/constraints/unique.constraint';
|
||||
import { CompanyEntity } from './company.entity';
|
||||
import { DomainType, SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
export class CompanyDto {
|
||||
export class CompanyDto extends DomainType {
|
||||
@ApiProperty({ description: '公司名称' })
|
||||
@IsUnique(CompanyEntity, { message: '已存在同名公司' })
|
||||
@IsString()
|
||||
|
@ -42,7 +43,8 @@ export class ComapnyCreateDto extends PartialType(CompanyDto) {
|
|||
|
||||
export class CompanyQueryDto extends IntersectionType(
|
||||
PagerDto<CompanyDto>,
|
||||
PartialType(CompanyDto)
|
||||
PartialType(CompanyDto),
|
||||
DomainType
|
||||
) {
|
||||
@ApiProperty({ description: '公司名称' })
|
||||
@IsOptional()
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Column, Entity, JoinTable, ManyToMany, OneToMany, Relation } from 'type
|
|||
import { CommonEntity } from '~/common/entity/common.entity';
|
||||
import { Storage } from '../tools/storage/storage.entity';
|
||||
import { ProductEntity } from '../product/product.entity';
|
||||
import { SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
@Entity({ name: 'company' })
|
||||
export class CompanyEntity extends CommonEntity {
|
||||
|
@ -20,6 +21,10 @@ export class CompanyEntity extends CommonEntity {
|
|||
@ApiProperty({ description: '删除状态:0未删除,1已删除' })
|
||||
isDelete: number;
|
||||
|
||||
@Column({ type: 'int', default: 1, comment: '所属域' })
|
||||
@ApiProperty({ description: '所属域' })
|
||||
domain: SkDomain;
|
||||
|
||||
@ApiHideProperty()
|
||||
@OneToMany(() => ProductEntity, product => product.company)
|
||||
products: Relation<ProductEntity[]>;
|
||||
|
|
|
@ -9,6 +9,7 @@ import { Storage } from '../tools/storage/storage.entity';
|
|||
import { BusinessException } from '~/common/exceptions/biz.exception';
|
||||
import { ErrorEnum } from '~/constants/error-code.constant';
|
||||
import { fieldSearch } from '~/shared/database/field-search';
|
||||
import { SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
@Injectable()
|
||||
export class CompanyService {
|
||||
|
@ -70,11 +71,7 @@ export class CompanyService {
|
|||
throw new BusinessException(ErrorEnum.STORAGE_NOT_FOUND);
|
||||
}
|
||||
// 附件要批量插入
|
||||
await manager
|
||||
.createQueryBuilder()
|
||||
.relation(CompanyEntity, 'files')
|
||||
.of(id)
|
||||
.add(fileIds);
|
||||
await manager.createQueryBuilder().relation(CompanyEntity, 'files').of(id).add(fileIds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import { ApiResult } from '~/common/decorators/api-result.decorator';
|
|||
import { ContractEntity } from './contract.entity';
|
||||
import { ContractDto, ContractQueryDto, ContractUpdateDto } from './contract.dto';
|
||||
import { IdParam } from '~/common/decorators/id-param.decorator';
|
||||
import { Domain, SkDomain } from '~/common/decorators/domain.decorator';
|
||||
export const permissions = definePermission('app:contract', {
|
||||
LIST: 'list',
|
||||
CREATE: 'create',
|
||||
|
@ -34,8 +35,8 @@ export class ContractController {
|
|||
@ApiOperation({ summary: '获取合同列表' })
|
||||
@ApiResult({ type: [ContractEntity], isPage: true })
|
||||
@Perm(permissions.LIST)
|
||||
async list(@Query() dto: ContractQueryDto) {
|
||||
return this.contractService.findAll(dto);
|
||||
async list(@Domain() domain: SkDomain, @Query() dto: ContractQueryDto) {
|
||||
return this.contractService.findAll({ ...dto, domain });
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
|
@ -49,8 +50,8 @@ export class ContractController {
|
|||
@Post()
|
||||
@ApiOperation({ summary: '新增合同' })
|
||||
@Perm(permissions.CREATE)
|
||||
async create(@Body() dto: ContractDto): Promise<void> {
|
||||
await this.contractService.create(dto);
|
||||
async create(@Domain() domain: SkDomain, @Body() dto: ContractDto): Promise<void> {
|
||||
await this.contractService.create({ ...dto, domain });
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
|
@ -70,8 +71,10 @@ export class ContractController {
|
|||
@Put('unlink-attachments/:id')
|
||||
@ApiOperation({ summary: '附件解除关联' })
|
||||
@Perm(permissions.UPDATE)
|
||||
async unlinkAttachments(@IdParam() id: number, @Body() {fileIds}: ContractUpdateDto): Promise<void> {
|
||||
async unlinkAttachments(
|
||||
@IdParam() id: number,
|
||||
@Body() { fileIds }: ContractUpdateDto
|
||||
): Promise<void> {
|
||||
await this.contractService.unlinkAttachments(id, fileIds);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,8 +15,9 @@ import {
|
|||
import { PagerDto } from '~/common/dto/pager.dto';
|
||||
import { Storage } from '../tools/storage/storage.entity';
|
||||
import { ContractStatusEnum } from '~/constants/enum';
|
||||
import { DomainType, SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
export class ContractDto {
|
||||
export class ContractDto extends DomainType {
|
||||
@ApiProperty({ description: '合同编号' })
|
||||
@Matches(/^[a-z0-9A-Z]+$/, { message: '合同编号只能包含字母和数字' })
|
||||
@IsString()
|
||||
|
@ -65,5 +66,7 @@ export class ContractUpdateDto extends PartialType(ContractDto) {
|
|||
}
|
||||
export class ContractQueryDto extends IntersectionType(
|
||||
PagerDto<ContractDto>,
|
||||
PartialType(ContractDto)
|
||||
) {}
|
||||
PartialType(ContractDto),
|
||||
DomainType
|
||||
) {}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import { ApiHideProperty, ApiProperty } from '@nestjs/swagger';
|
|||
import { Column, Entity, JoinTable, ManyToMany, Relation } from 'typeorm';
|
||||
import { CommonEntity } from '~/common/entity/common.entity';
|
||||
import { Storage } from '../tools/storage/storage.entity';
|
||||
import { SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
@Entity({ name: 'contract' })
|
||||
export class ContractEntity extends CommonEntity {
|
||||
|
@ -47,6 +48,10 @@ export class ContractEntity extends CommonEntity {
|
|||
@ApiProperty({ description: '删除状态:0未删除,1已删除' })
|
||||
isDelete: number;
|
||||
|
||||
@Column({ type: 'int', default: 1, comment: '所属域' })
|
||||
@ApiProperty({ description: '所属域' })
|
||||
domain: SkDomain;
|
||||
|
||||
@ManyToMany(() => Storage, storage => storage.contracts)
|
||||
@JoinTable({
|
||||
name: 'contract_storage',
|
||||
|
|
|
@ -10,6 +10,7 @@ import { Storage } from '../tools/storage/storage.entity';
|
|||
import { BusinessException } from '~/common/exceptions/biz.exception';
|
||||
import { ErrorEnum } from '~/constants/error-code.constant';
|
||||
import { fieldSearch } from '~/shared/database/field-search';
|
||||
import { SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
@Injectable()
|
||||
export class ContractService {
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
Query,
|
||||
Put,
|
||||
Delete,
|
||||
Post,
|
||||
BadRequestException
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { Perm, definePermission } from '../auth/decorators/permission.decorator';
|
||||
import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator';
|
||||
import { DomainService } from './domain.service';
|
||||
import { ApiResult } from '~/common/decorators/api-result.decorator';
|
||||
import { DomainEntity } from './domain.entity';
|
||||
import { DomainDto, DomainQueryDto, DomainUpdateDto } from './domain.dto';
|
||||
import { IdParam } from '~/common/decorators/id-param.decorator';
|
||||
export const permissions = definePermission('app:domain', {
|
||||
LIST: 'list',
|
||||
CREATE: 'create',
|
||||
READ: 'read',
|
||||
UPDATE: 'update',
|
||||
DELETE: 'delete'
|
||||
} as const);
|
||||
|
||||
@ApiTags('Domain - 域')
|
||||
@ApiSecurityAuth()
|
||||
@Controller('domain')
|
||||
export class DomainController {
|
||||
constructor(private domainService: DomainService) {}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ summary: '获取域列表' })
|
||||
@ApiResult({ type: [DomainEntity], isPage: true })
|
||||
@Perm(permissions.LIST)
|
||||
async list(@Query() dto: DomainQueryDto) {
|
||||
return this.domainService.findAll(dto);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@ApiOperation({ summary: '获取域信息' })
|
||||
@ApiResult({ type: DomainDto })
|
||||
@Perm(permissions.READ)
|
||||
async info(@IdParam() id: number) {
|
||||
return this.domainService.info(id);
|
||||
}
|
||||
|
||||
@Post()
|
||||
@ApiOperation({ summary: '新增域' })
|
||||
@Perm(permissions.CREATE)
|
||||
async create(@Body() dto: DomainDto): Promise<void> {
|
||||
await this.domainService.create(dto);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@ApiOperation({ summary: '更新域' })
|
||||
@Perm(permissions.UPDATE)
|
||||
async update(@IdParam() id: number, @Body() dto: DomainUpdateDto): Promise<void> {
|
||||
await this.domainService.update(id, dto);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@ApiOperation({ summary: '删除域' })
|
||||
@Perm(permissions.DELETE)
|
||||
async delete(@IdParam() id: number): Promise<void> {
|
||||
await this.domainService.delete(id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { ApiProperty, IntersectionType, PartialType } from '@nestjs/swagger';
|
||||
import { IsString } from 'class-validator';
|
||||
import { PagerDto } from '~/common/dto/pager.dto';
|
||||
|
||||
export class DomainDto {
|
||||
@ApiProperty({ description: '域标题' })
|
||||
@IsString()
|
||||
title: string;
|
||||
}
|
||||
|
||||
export class DomainUpdateDto extends PartialType(DomainDto) {}
|
||||
export class DomainQueryDto extends IntersectionType(PagerDto<DomainDto>, PartialType(DomainDto)) {}
|
|
@ -0,0 +1,15 @@
|
|||
import { ApiHideProperty, ApiProperty } from '@nestjs/swagger';
|
||||
import { Column, Entity, JoinTable, ManyToMany, Relation } from 'typeorm';
|
||||
import { CommonEntity } from '~/common/entity/common.entity';
|
||||
import { Storage } from '../tools/storage/storage.entity';
|
||||
|
||||
@Entity({ name: 'domain' })
|
||||
export class DomainEntity extends CommonEntity {
|
||||
@Column({ name: 'title', type: 'varchar', length: 255, comment: '域标题' })
|
||||
@ApiProperty({ description: '域标题' })
|
||||
title: string;
|
||||
|
||||
@Column({ name: 'is_delete', type: 'tinyint', default: 0, comment: '是否删除' })
|
||||
@ApiProperty({ description: '删除状态:0未删除,1已删除' })
|
||||
isDelete: number;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { DomainController } from './domain.controller';
|
||||
import { DomainService } from './domain.service';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { DomainEntity } from './domain.entity';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([DomainEntity])],
|
||||
controllers: [DomainController],
|
||||
providers: [DomainService]
|
||||
})
|
||||
export class DomainModule {}
|
|
@ -0,0 +1,95 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
|
||||
import { DomainEntity } from './domain.entity';
|
||||
import { EntityManager, Like, Not, Repository } from 'typeorm';
|
||||
import { DomainDto, DomainQueryDto, DomainUpdateDto } from './domain.dto';
|
||||
import { Pagination } from '~/helper/paginate/pagination';
|
||||
import { isNumber } from 'lodash';
|
||||
import { paginate } from '~/helper/paginate';
|
||||
import { Storage } from '../tools/storage/storage.entity';
|
||||
import { BusinessException } from '~/common/exceptions/biz.exception';
|
||||
import { ErrorEnum } from '~/constants/error-code.constant';
|
||||
import { fieldSearch } from '~/shared/database/field-search';
|
||||
|
||||
@Injectable()
|
||||
export class DomainService {
|
||||
constructor(
|
||||
@InjectEntityManager() private entityManager: EntityManager,
|
||||
@InjectRepository(DomainEntity)
|
||||
private domainRepository: Repository<DomainEntity>
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 查找所有域
|
||||
*/
|
||||
async findAll({ page, pageSize, ...fields }: DomainQueryDto): Promise<Pagination<DomainEntity>> {
|
||||
const queryBuilder = this.domainRepository
|
||||
.createQueryBuilder('domain')
|
||||
.where(fieldSearch(fields))
|
||||
.andWhere('domain.isDelete = 0');
|
||||
|
||||
return paginate<DomainEntity>(queryBuilder, {
|
||||
page,
|
||||
pageSize
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
async create({ title, ...ext }: DomainDto): Promise<void> {
|
||||
if (await this.checkIsDomainExsit(title)) {
|
||||
throw new BusinessException(ErrorEnum.DOMAIN_TITLE_DUPLICATE);
|
||||
}
|
||||
await this.domainRepository.insert(this.domainRepository.create({ title, ...ext }));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*/
|
||||
async update(id: number, { title, ...ext }: Partial<DomainUpdateDto>): Promise<void> {
|
||||
await this.entityManager.transaction(async manager => {
|
||||
if (title && (await this.checkIsDomainExsit(title, id))) {
|
||||
throw new BusinessException(ErrorEnum.CONTRACT_NUMBER_EXIST);
|
||||
}
|
||||
await manager.update(DomainEntity, id, {
|
||||
...ext,
|
||||
title
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在相同的域
|
||||
* @param title 域编号
|
||||
*/
|
||||
async checkIsDomainExsit(title: string, id?: number): Promise<Boolean> {
|
||||
return !!(await this.domainRepository.findOne({
|
||||
where: {
|
||||
title: title,
|
||||
id: Not(id)
|
||||
}
|
||||
}));
|
||||
}
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
async delete(id: number): Promise<void> {
|
||||
// 域比较重要,做逻辑删除
|
||||
await this.domainRepository.update(id, { isDelete: 1 });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个域信息
|
||||
*/
|
||||
async info(id: number) {
|
||||
const info = await this.domainRepository
|
||||
.createQueryBuilder('domain')
|
||||
.where({
|
||||
id
|
||||
})
|
||||
.andWhere('domain.isDelete = 0')
|
||||
.getOne();
|
||||
return info;
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ import {
|
|||
MaterialsInOutDto,
|
||||
MaterialsInOutUpdateDto
|
||||
} from './materials_in_out.dto';
|
||||
import { Domain, DomainType, SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
export const permissions = definePermission('materials_inventory:history_in_out', {
|
||||
LIST: 'list',
|
||||
|
@ -29,8 +30,8 @@ export class MaterialsInOutController {
|
|||
@ApiOperation({ summary: '获取原材料出入库记录列表' })
|
||||
@ApiResult({ type: [MaterialsInOutEntity], isPage: true })
|
||||
@Perm(permissions.LIST)
|
||||
async list(@Query() dto: MaterialsInOutQueryDto) {
|
||||
return this.materialsInOutService.findAll(dto);
|
||||
async list(@Domain() domain: SkDomain, @Query() dto: MaterialsInOutQueryDto) {
|
||||
return this.materialsInOutService.findAll({ ...dto, domain });
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
|
@ -44,8 +45,8 @@ export class MaterialsInOutController {
|
|||
@Post()
|
||||
@ApiOperation({ summary: '新增原材料出入库记录' })
|
||||
@Perm(permissions.CREATE)
|
||||
async create(@Body() dto: MaterialsInOutDto): Promise<number> {
|
||||
return this.materialsInOutService.create(dto);
|
||||
async create(@Domain() domain: SkDomain, @Body() dto: MaterialsInOutDto): Promise<number> {
|
||||
return this.materialsInOutService.create({ ...dto, domain });
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
|
|
|
@ -17,12 +17,13 @@ import {
|
|||
isNumber
|
||||
} from 'class-validator';
|
||||
import dayjs from 'dayjs';
|
||||
import { DomainType } from '~/common/decorators/domain.decorator';
|
||||
import { PagerDto } from '~/common/dto/pager.dto';
|
||||
import { MaterialsInOrOutEnum } from '~/constants/enum';
|
||||
import { Storage } from '~/modules/tools/storage/storage.entity';
|
||||
import { formatToDate } from '~/utils';
|
||||
|
||||
export class MaterialsInOutDto {
|
||||
export class MaterialsInOutDto extends DomainType {
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@ApiProperty({ description: '项目Id' })
|
||||
|
@ -100,7 +101,10 @@ export class MaterialsInOutUpdateDto extends PartialType(MaterialsInOutDto) {
|
|||
@IsArray()
|
||||
fileIds: number[];
|
||||
}
|
||||
export class MaterialsInOutQueryDto extends PagerDto<MaterialsInOutQueryDto> {
|
||||
export class MaterialsInOutQueryDto extends IntersectionType(
|
||||
PagerDto<MaterialsInOutQueryDto>,
|
||||
DomainType
|
||||
) {
|
||||
@ApiProperty({ description: '出入库时间YYYY-MM-DD' })
|
||||
@IsOptional()
|
||||
// @IsString()
|
||||
|
|
|
@ -20,6 +20,7 @@ import { ProjectEntity } from '~/modules/project/project.entity';
|
|||
import { ParamConfigEntity } from '~/modules/system/param-config/param-config.entity';
|
||||
import { Storage } from '~/modules/tools/storage/storage.entity';
|
||||
import { MaterialsInventoryEntity } from '../materials_inventory.entity';
|
||||
import { SkDomain } from '~/common/decorators/domain.decorator';
|
||||
@Entity({ name: 'materials_in_out' })
|
||||
export class MaterialsInOutEntity extends CommonEntity {
|
||||
@Column({
|
||||
|
@ -129,6 +130,10 @@ export class MaterialsInOutEntity extends CommonEntity {
|
|||
@JoinColumn({ name: 'product_id' })
|
||||
product: ProductEntity;
|
||||
|
||||
@Column({ type: 'int', default: 1, comment: '所属域' })
|
||||
@ApiProperty({ description: '所属域' })
|
||||
domain: SkDomain;
|
||||
|
||||
@ManyToMany(() => Storage, storage => storage.materialsInOuts)
|
||||
@JoinTable({
|
||||
name: 'materials_in_out_storage',
|
||||
|
|
|
@ -13,6 +13,7 @@ import { MaterialsInventoryService } from './materials_inventory.service';
|
|||
import { MaterialsInventoryEntity } from './materials_inventory.entity';
|
||||
import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator';
|
||||
import { FastifyReply } from 'fastify';
|
||||
import { Domain, DomainType, SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
export const permissions = definePermission('app:materials_inventory', {
|
||||
LIST: 'list',
|
||||
|
@ -33,10 +34,11 @@ export class MaterialsInventoryController {
|
|||
@ApiOperation({ summary: '导出原材料盘点表' })
|
||||
@Perm(permissions.EXPORT)
|
||||
async exportMaterialsInventoryCheck(
|
||||
@Domain() domain: SkDomain,
|
||||
@Query() dto: MaterialsInventoryExportDto,
|
||||
@Res() res: FastifyReply
|
||||
): Promise<void> {
|
||||
await this.miService.exportMaterialsInventoryCheck(dto, res);
|
||||
await this.miService.exportMaterialsInventoryCheck({ ...dto, domain }, res);
|
||||
}
|
||||
|
||||
@Get()
|
||||
|
|
|
@ -18,13 +18,15 @@ import { Transform } from 'class-transformer';
|
|||
import dayjs from 'dayjs';
|
||||
import { formatToDate } from '~/utils';
|
||||
import { HasInventoryStatusEnum } from '~/constants/enum';
|
||||
import { DomainType } from '~/common/decorators/domain.decorator';
|
||||
|
||||
export class MaterialsInventoryDto {}
|
||||
export class MaterialsInventoryDto extends DomainType {}
|
||||
|
||||
export class MaterialsInventoryUpdateDto extends PartialType(MaterialsInventoryDto) {}
|
||||
export class MaterialsInventoryQueryDto extends IntersectionType(
|
||||
PagerDto<MaterialsInventoryDto>,
|
||||
PartialType(MaterialsInventoryDto)
|
||||
PartialType(MaterialsInventoryDto),
|
||||
DomainType
|
||||
) {
|
||||
@ApiProperty({ description: '产品名' })
|
||||
@IsOptional()
|
||||
|
@ -46,7 +48,7 @@ export class MaterialsInventoryQueryDto extends IntersectionType(
|
|||
@IsNumber()
|
||||
projectId: number;
|
||||
}
|
||||
export class MaterialsInventoryExportDto {
|
||||
export class MaterialsInventoryExportDto extends DomainType {
|
||||
@ApiProperty({ description: '项目' })
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
|
|
|
@ -13,6 +13,7 @@ import { CommonEntity } from '~/common/entity/common.entity';
|
|||
import { ProductEntity } from '../product/product.entity';
|
||||
import { ProjectEntity } from '../project/project.entity';
|
||||
import { MaterialsInOutEntity } from './in_out/materials_in_out.entity';
|
||||
import { SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
@Entity({ name: 'materials_inventory' })
|
||||
export class MaterialsInventoryEntity extends CommonEntity {
|
||||
|
@ -70,6 +71,10 @@ export class MaterialsInventoryEntity extends CommonEntity {
|
|||
@ApiProperty({ description: '删除状态:0未删除,1已删除' })
|
||||
isDelete: number;
|
||||
|
||||
@Column({ type: 'int', default: 1, comment: '所属域' })
|
||||
@ApiProperty({ description: '所属域' })
|
||||
domain: SkDomain;
|
||||
|
||||
@ManyToOne(() => ProjectEntity)
|
||||
@JoinColumn({ name: 'project_id' })
|
||||
project: ProjectEntity;
|
||||
|
@ -89,5 +94,5 @@ export class MaterialsInventoryEntity extends CommonEntity {
|
|||
|
||||
@ApiHideProperty()
|
||||
@OneToMany(() => MaterialsInOutEntity, inout => inout.inventory)
|
||||
materialsInOuts: Relation<MaterialsInOutEntity[]>;
|
||||
materialsInOuts: Relation<MaterialsInOutEntity[]>;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ export class MaterialsInventoryService {
|
|||
* 导出原材料盘点表
|
||||
*/
|
||||
async exportMaterialsInventoryCheck(
|
||||
{ time, projectId }: MaterialsInventoryExportDto,
|
||||
{ time, projectId, domain }: MaterialsInventoryExportDto,
|
||||
res: FastifyReply
|
||||
): Promise<void> {
|
||||
const ROW_HEIGHT = 20;
|
||||
|
|
|
@ -16,6 +16,7 @@ import { ApiResult } from '~/common/decorators/api-result.decorator';
|
|||
import { ProductEntity } from './product.entity';
|
||||
import { ProductDto, ProductQueryDto, ProductUpdateDto } from './product.dto';
|
||||
import { IdParam } from '~/common/decorators/id-param.decorator';
|
||||
import { Domain, SkDomain } from '~/common/decorators/domain.decorator';
|
||||
export const permissions = definePermission('app:product', {
|
||||
LIST: 'list',
|
||||
CREATE: 'create',
|
||||
|
@ -34,8 +35,8 @@ export class ProductController {
|
|||
@ApiOperation({ summary: '获取产品列表' })
|
||||
@ApiResult({ type: [ProductEntity], isPage: true })
|
||||
@Perm(permissions.LIST)
|
||||
async list(@Query() dto: ProductQueryDto) {
|
||||
return this.productService.findAll(dto);
|
||||
async list(@Domain() domain: SkDomain, @Query() dto: ProductQueryDto) {
|
||||
return this.productService.findAll({ ...dto, domain });
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
|
@ -49,8 +50,8 @@ export class ProductController {
|
|||
@Post()
|
||||
@ApiOperation({ summary: '新增产品' })
|
||||
@Perm(permissions.CREATE)
|
||||
async create(@Body() dto: ProductDto): Promise<void> {
|
||||
await this.productService.create(dto);
|
||||
async create(@Domain() domain: SkDomain, @Body() dto: ProductDto): Promise<void> {
|
||||
await this.productService.create({ ...dto, domain });
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
|
|
|
@ -2,13 +2,13 @@ import { ApiProperty, IntersectionType, PartialType } from '@nestjs/swagger';
|
|||
import { IsArray, IsNumber, IsOptional, IsString } from 'class-validator';
|
||||
import { PagerDto } from '~/common/dto/pager.dto';
|
||||
import { Storage } from '../tools/storage/storage.entity';
|
||||
import { DomainType } from '~/common/decorators/domain.decorator';
|
||||
|
||||
export class ProductDto {
|
||||
export class ProductDto extends DomainType {
|
||||
@ApiProperty({ description: '产品名称' })
|
||||
@IsString()
|
||||
name: string;
|
||||
|
||||
|
||||
@ApiProperty({ description: '产品规格' })
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
|
@ -42,7 +42,8 @@ export class ProductUpdateDto extends PartialType(ProductDto) {
|
|||
|
||||
export class ProductQueryDto extends IntersectionType(
|
||||
PagerDto<ProductDto>,
|
||||
PartialType(ProductDto)
|
||||
PartialType(ProductDto),
|
||||
DomainType
|
||||
) {
|
||||
@ApiProperty({ description: '所属公司名称' })
|
||||
@IsOptional()
|
||||
|
@ -58,5 +59,4 @@ export class ProductQueryDto extends IntersectionType(
|
|||
@IsOptional()
|
||||
@IsString()
|
||||
keyword?: string;
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import { Storage } from '../tools/storage/storage.entity';
|
|||
import { CompanyEntity } from '../company/company.entity';
|
||||
import pinyin from 'pinyin';
|
||||
import { DictItemEntity } from '../system/dict-item/dict-item.entity';
|
||||
import { SkDomain } from '~/common/decorators/domain.decorator';
|
||||
@Entity({ name: 'product' })
|
||||
export class ProductEntity extends CommonEntity {
|
||||
@Column({
|
||||
|
@ -70,6 +71,10 @@ export class ProductEntity extends CommonEntity {
|
|||
@ManyToOne(() => DictItemEntity)
|
||||
@JoinColumn({ name: 'unit_id' })
|
||||
unit: DictItemEntity;
|
||||
|
||||
@Column({ type: 'int', default: 1, comment: '所属域' })
|
||||
@ApiProperty({ description: '所属域' })
|
||||
domain: SkDomain;
|
||||
|
||||
@ApiHideProperty()
|
||||
@Column({
|
||||
|
|
|
@ -22,6 +22,7 @@ import { UserPasswordDto } from './dto/password.dto';
|
|||
import { UserDto, UserQueryDto, UserUpdateDto } from './dto/user.dto';
|
||||
import { UserEntity } from './user.entity';
|
||||
import { UserService } from './user.service';
|
||||
import { Domain, SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
export const permissions = definePermission('system:user', {
|
||||
LIST: 'list',
|
||||
|
@ -47,8 +48,8 @@ export class UserController {
|
|||
@ApiOperation({ summary: '获取用户列表' })
|
||||
@ApiResult({ type: [UserEntity], isPage: true })
|
||||
@Perm(permissions.LIST)
|
||||
async list(@Query() dto: UserQueryDto) {
|
||||
return this.userService.list(dto);
|
||||
async list(@Domain() domain: SkDomain, @Query() dto: UserQueryDto) {
|
||||
return this.userService.list(dto, domain);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
OneToMany,
|
||||
Relation
|
||||
} from 'typeorm';
|
||||
import { SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
import { CommonEntity } from '~/common/entity/common.entity';
|
||||
|
||||
|
@ -73,6 +74,9 @@ export class UserEntity extends CommonEntity {
|
|||
@Column({ type: 'tinyint', nullable: true, default: 1 })
|
||||
status: number;
|
||||
|
||||
@Column({ type: 'int', default: 1, comment: '所属域' })
|
||||
domain: SkDomain;
|
||||
|
||||
@ManyToMany(() => RoleEntity, role => role.users)
|
||||
@JoinTable({
|
||||
name: 'sys_user_roles',
|
||||
|
|
|
@ -28,6 +28,7 @@ import { PasswordUpdateDto } from './dto/password.dto';
|
|||
import { UserDto, UserQueryDto, UserUpdateDto } from './dto/user.dto';
|
||||
import { UserEntity } from './user.entity';
|
||||
import { AccountInfo } from './user.model';
|
||||
import { SkDomain } from '~/common/decorators/domain.decorator';
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
|
@ -243,16 +244,10 @@ export class UserService {
|
|||
/**
|
||||
* 查询用户列表
|
||||
*/
|
||||
async list({
|
||||
page,
|
||||
pageSize,
|
||||
username,
|
||||
nickname,
|
||||
deptId,
|
||||
email,
|
||||
status,
|
||||
keyword
|
||||
}: UserQueryDto): Promise<Pagination<UserEntity>> {
|
||||
async list(
|
||||
{ page, pageSize, username, nickname, deptId, email, status, keyword }: UserQueryDto,
|
||||
domain: SkDomain
|
||||
): Promise<Pagination<UserEntity>> {
|
||||
const queryBuilder = this.userRepository
|
||||
.createQueryBuilder('user')
|
||||
.leftJoinAndSelect('user.dept', 'dept')
|
||||
|
@ -337,7 +332,7 @@ export class UserService {
|
|||
/**
|
||||
* 注册
|
||||
*/
|
||||
async register({ username, ...data }: RegisterDto): Promise<void> {
|
||||
async register({ username, ...data }: RegisterDto, domain: SkDomain): Promise<void> {
|
||||
const exists = await this.userRepository.findOneBy({
|
||||
username
|
||||
});
|
||||
|
@ -352,7 +347,8 @@ export class UserService {
|
|||
username,
|
||||
password,
|
||||
status: 1,
|
||||
psalt: salt
|
||||
psalt: salt,
|
||||
domain
|
||||
});
|
||||
|
||||
const user = await manager.save(u);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { isNumber } from 'lodash';
|
||||
import { Between, Like, ObjectLiteral, ObjectType } from 'typeorm';
|
||||
import { Between, Like, ObjectLiteral } from 'typeorm';
|
||||
import { SkDomain } from '~/common/decorators/domain.decorator';
|
||||
export const fieldSearch = <T>(entity: Partial<T>): ObjectLiteral => {
|
||||
let result = {};
|
||||
for (let key in entity) {
|
||||
|
|
Loading…
Reference in New Issue