dev
This commit is contained in:
@@ -16,6 +16,12 @@ request.interceptors.request.use((config) => {
|
|||||||
request.interceptors.response.use(
|
request.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
const { data } = response;
|
const { data } = response;
|
||||||
|
if (data.code === 401) {
|
||||||
|
localStorage.removeItem('seller_token');
|
||||||
|
localStorage.removeItem('seller_info');
|
||||||
|
window.location.href = '/login';
|
||||||
|
return Promise.reject(new Error(data.message || '登录已过期'));
|
||||||
|
}
|
||||||
if (data.code >= 200 && data.code < 300) {
|
if (data.code >= 200 && data.code < 300) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ export function request<T = any>(options: RequestOptions): Promise<ApiResponse<T
|
|||||||
|
|
||||||
const responseData = res.data as ApiResponse<T>;
|
const responseData = res.data as ApiResponse<T>;
|
||||||
|
|
||||||
if (res.statusCode === 401) {
|
// 检查响应体中的 code 是否为 401
|
||||||
|
if (responseData.code === 401 || res.statusCode === 401) {
|
||||||
// 如果是 skipAuthRedirect,只清除 token 不跳转页面
|
// 如果是 skipAuthRedirect,只清除 token 不跳转页面
|
||||||
if (skipAuthRedirect) {
|
if (skipAuthRedirect) {
|
||||||
if (useSellerToken) {
|
if (useSellerToken) {
|
||||||
@@ -67,9 +68,10 @@ export function request<T = any>(options: RequestOptions): Promise<ApiResponse<T
|
|||||||
|
|
||||||
// 正常 401 处理,只清除对应账户的 token,不互相干扰
|
// 正常 401 处理,只清除对应账户的 token,不互相干扰
|
||||||
if (useSellerToken) {
|
if (useSellerToken) {
|
||||||
// 商家 token 失效,只清除商家登录状态,不跳转页面
|
// 商家 token 失效,跳转到商家登录页
|
||||||
uni.removeStorageSync('sellerToken');
|
uni.removeStorageSync('sellerToken');
|
||||||
uni.removeStorageSync('sellerInfo');
|
uni.removeStorageSync('sellerInfo');
|
||||||
|
uni.navigateTo({ url: '/pages/seller/register?mode=login' });
|
||||||
} else {
|
} else {
|
||||||
// 用户 token 失效,清除用户登录状态并跳转登录页
|
// 用户 token 失效,清除用户登录状态并跳转登录页
|
||||||
uni.removeStorageSync('token');
|
uni.removeStorageSync('token');
|
||||||
|
|||||||
@@ -34,11 +34,13 @@ export const getInviteConfig = () =>
|
|||||||
|
|
||||||
// 更新邀请活动配置
|
// 更新邀请活动配置
|
||||||
export const updateInviteConfig = (data: {
|
export const updateInviteConfig = (data: {
|
||||||
firstOrderRate?: number;
|
config?: {
|
||||||
secondOrderRate?: number;
|
firstOrderRate?: number;
|
||||||
minCashback?: number;
|
secondOrderRate?: number;
|
||||||
maxCashback?: number;
|
minCashback?: number;
|
||||||
withdrawThreshold?: number;
|
maxCashback?: number;
|
||||||
|
withdrawThreshold?: number;
|
||||||
|
};
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
}) =>
|
}) =>
|
||||||
request.put('/admin/activity/invite/config', data);
|
request.put('/admin/activity/invite/config', data);
|
||||||
@@ -77,8 +77,8 @@ const InviteManage: React.FC = () => {
|
|||||||
try {
|
try {
|
||||||
const res = await getInviteConfig();
|
const res = await getInviteConfig();
|
||||||
setConfig(res.data);
|
setConfig(res.data);
|
||||||
if (res.data) {
|
if (res.data?.config) {
|
||||||
form.setFieldsValue(res.data);
|
form.setFieldsValue(res.data.config);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
setConfigLoading(false);
|
setConfigLoading(false);
|
||||||
@@ -121,9 +121,9 @@ const InviteManage: React.FC = () => {
|
|||||||
const handleSaveConfig = async () => {
|
const handleSaveConfig = async () => {
|
||||||
try {
|
try {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
await updateInviteConfig(values);
|
await updateInviteConfig({ config: values });
|
||||||
message.success('配置已保存');
|
message.success('配置已保存');
|
||||||
setConfig({ ...config, ...values });
|
setConfig({ ...config, config: { ...config?.config, ...values } });
|
||||||
} catch {}
|
} catch {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import { ScheduleModule as TaskScheduleModule } from './schedule/schedule.module
|
|||||||
password: process.env.DB_PASSWORD || '',
|
password: process.env.DB_PASSWORD || '',
|
||||||
database: process.env.DB_DATABASE || 'rent_platform',
|
database: process.env.DB_DATABASE || 'rent_platform',
|
||||||
entities: [__dirname + '/entities/**/*.entity{.ts,.js}'],
|
entities: [__dirname + '/entities/**/*.entity{.ts,.js}'],
|
||||||
synchronize: process.env.NODE_ENV === 'development',
|
synchronize: false,
|
||||||
logging: process.env.NODE_ENV === 'development',
|
logging: process.env.NODE_ENV === 'development',
|
||||||
charset: 'utf8mb4',
|
charset: 'utf8mb4',
|
||||||
timezone: '+08:00',
|
timezone: '+08:00',
|
||||||
|
|||||||
@@ -29,15 +29,15 @@ export class Admin {
|
|||||||
@Column({ type: 'enum', enum: ['active', 'frozen'], default: 'active', comment: '状态' })
|
@Column({ type: 'enum', enum: ['active', 'frozen'], default: 'active', comment: '状态' })
|
||||||
status: 'active' | 'frozen';
|
status: 'active' | 'frozen';
|
||||||
|
|
||||||
@Column({ type: 'datetime', nullable: true, comment: '最后登录时间' })
|
@Column({ name: 'last_login_at', type: 'datetime', nullable: true, comment: '最后登录时间' })
|
||||||
lastLoginAt: Date;
|
lastLoginAt: Date;
|
||||||
|
|
||||||
@Column({ length: 50, nullable: true, comment: '最后登录IP' })
|
@Column({ name: 'last_login_ip', length: 50, nullable: true, comment: '最后登录IP' })
|
||||||
lastLoginIp: string;
|
lastLoginIp: string;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,6 @@ export class Coupon {
|
|||||||
@Column({ name: 'created_by', type: 'bigint', unsigned: true, nullable: true, comment: '创建人ID' })
|
@Column({ name: 'created_by', type: 'bigint', unsigned: true, nullable: true, comment: '创建人ID' })
|
||||||
createdBy: number;
|
createdBy: number;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export class Merchant {
|
|||||||
@Column({ name: 'seller_id', type: 'bigint', unsigned: true, unique: true, comment: '关联商家账户ID' })
|
@Column({ name: 'seller_id', type: 'bigint', unsigned: true, unique: true, comment: '关联商家账户ID' })
|
||||||
sellerId: number;
|
sellerId: number;
|
||||||
|
|
||||||
@Column({ length: 100, comment: '店铺名称' })
|
@Column({ name: 'shop_name', length: 100, comment: '店铺名称' })
|
||||||
shopName: string;
|
shopName: string;
|
||||||
|
|
||||||
@Column({ length: 500, default: '', comment: '店铺Logo' })
|
@Column({ length: 500, default: '', comment: '店铺Logo' })
|
||||||
@@ -43,20 +43,20 @@ export class Merchant {
|
|||||||
@Column({ type: 'decimal', precision: 10, scale: 7, nullable: true, comment: '纬度' })
|
@Column({ type: 'decimal', precision: 10, scale: 7, nullable: true, comment: '纬度' })
|
||||||
latitude: number;
|
latitude: number;
|
||||||
|
|
||||||
@Column({ length: 500, default: '', comment: '营业执照图片' })
|
@Column({ name: 'business_license', length: 500, default: '', comment: '营业执照图片' })
|
||||||
businessLicense: string;
|
businessLicense: string;
|
||||||
|
|
||||||
@Column({ length: 50, default: '', comment: '营业执照编号' })
|
@Column({ name: 'license_no', length: 50, default: '', comment: '营业执照编号' })
|
||||||
licenseNo: string;
|
licenseNo: string;
|
||||||
|
|
||||||
@Column({ length: 50, default: '', comment: '法人姓名' })
|
@Column({ name: 'legal_person', length: 50, default: '', comment: '法人姓名' })
|
||||||
legalPerson: string;
|
legalPerson: string;
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@Column({ type: 'enum', enum: ['pending', 'approved', 'rejected', 'frozen'], default: 'pending', comment: '状态' })
|
@Column({ type: 'enum', enum: ['pending', 'approved', 'rejected', 'frozen'], default: 'pending', comment: '状态' })
|
||||||
status: 'pending' | 'approved' | 'rejected' | 'frozen';
|
status: 'pending' | 'approved' | 'rejected' | 'frozen';
|
||||||
|
|
||||||
@Column({ length: 500, nullable: true, comment: '拒绝原因' })
|
@Column({ name: 'reject_reason', length: 500, nullable: true, comment: '拒绝原因' })
|
||||||
rejectReason?: string;
|
rejectReason?: string;
|
||||||
|
|
||||||
@Column({ type: 'decimal', precision: 10, scale: 2, unsigned: true, default: 0, comment: '保证金' })
|
@Column({ type: 'decimal', precision: 10, scale: 2, unsigned: true, default: 0, comment: '保证金' })
|
||||||
@@ -78,18 +78,18 @@ export class Merchant {
|
|||||||
@Column({ type: 'decimal', precision: 2, scale: 1, unsigned: true, default: 5.0, comment: '评分' })
|
@Column({ type: 'decimal', precision: 2, scale: 1, unsigned: true, default: 5.0, comment: '评分' })
|
||||||
rating: number;
|
rating: number;
|
||||||
|
|
||||||
@Column({ type: 'int', unsigned: true, default: 0, comment: '评价数' })
|
@Column({ name: 'review_count', type: 'int', unsigned: true, default: 0, comment: '评价数' })
|
||||||
reviewCount: number;
|
reviewCount: number;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: false, comment: '是否自动接单' })
|
@Column({ name: 'auto_confirm', type: 'boolean', default: false, comment: '是否自动接单' })
|
||||||
autoConfirm: boolean;
|
autoConfirm: boolean;
|
||||||
|
|
||||||
@Column({ type: 'json', nullable: true, comment: '自动接单规则配置' })
|
@Column({ name: 'auto_confirm_rules', type: 'json', nullable: true, comment: '自动接单规则配置' })
|
||||||
autoConfirmRules: object;
|
autoConfirmRules: object;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ export class MktActivity {
|
|||||||
@Column({ name: 'end_time', type: 'datetime', nullable: true, comment: '活动结束时间' })
|
@Column({ name: 'end_time', type: 'datetime', nullable: true, comment: '活动结束时间' })
|
||||||
endTime: Date;
|
endTime: Date;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,6 @@ export class MktCashback {
|
|||||||
@JoinColumn({ name: 'order_id' })
|
@JoinColumn({ name: 'order_id' })
|
||||||
order: Order;
|
order: Order;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,6 @@ export class MktInvitation {
|
|||||||
@JoinColumn({ name: 'invitee_id' })
|
@JoinColumn({ name: 'invitee_id' })
|
||||||
invitee: User;
|
invitee: User;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '邀请时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '邀请时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ export class MktInviteWithdrawal {
|
|||||||
@JoinColumn({ name: 'user_id' })
|
@JoinColumn({ name: 'user_id' })
|
||||||
user: User;
|
user: User;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '申请时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '申请时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ export class MktUserInviteStats {
|
|||||||
@JoinColumn({ name: 'user_id' })
|
@JoinColumn({ name: 'user_id' })
|
||||||
user: User;
|
user: User;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,6 @@ export class Notification {
|
|||||||
@Column({ type: 'json', nullable: true, comment: '附加数据' })
|
@Column({ type: 'json', nullable: true, comment: '附加数据' })
|
||||||
extra: object;
|
extra: object;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export class Order {
|
|||||||
@PrimaryGeneratedColumn({ type: 'bigint', unsigned: true })
|
@PrimaryGeneratedColumn({ type: 'bigint', unsigned: true })
|
||||||
id: number;
|
id: number;
|
||||||
|
|
||||||
@Column({ length: 32, unique: true, comment: '订单号' })
|
@Column({ name: 'order_no', length: 32, unique: true, comment: '订单号' })
|
||||||
orderNo: string;
|
orderNo: string;
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@@ -124,9 +124,9 @@ export class Order {
|
|||||||
room: Room;
|
room: Room;
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,18 +5,18 @@ export class PlatformConfig {
|
|||||||
@PrimaryGeneratedColumn({ type: 'bigint', unsigned: true })
|
@PrimaryGeneratedColumn({ type: 'bigint', unsigned: true })
|
||||||
id: number;
|
id: number;
|
||||||
|
|
||||||
@Column({ name: 'config_key', length: 50, unique: true, comment: '配置键' })
|
@Column({ name: 'config_key', length: 100, unique: true, comment: '配置键' })
|
||||||
configKey: string;
|
configKey: string;
|
||||||
|
|
||||||
@Column({ name: 'config_value', length: 500, comment: '配置值' })
|
@Column({ name: 'config_value', type: 'text', comment: '配置值' })
|
||||||
configValue: string;
|
configValue: string;
|
||||||
|
|
||||||
@Column({ length: 200, nullable: true, comment: '配置说明' })
|
@Column({ length: 200, nullable: true, comment: '配置说明' })
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
@@ -46,15 +46,12 @@ export class Review {
|
|||||||
@Column({ name: 'is_anonymous', type: 'boolean', default: false, comment: '是否匿名' })
|
@Column({ name: 'is_anonymous', type: 'boolean', default: false, comment: '是否匿名' })
|
||||||
isAnonymous: boolean;
|
isAnonymous: boolean;
|
||||||
|
|
||||||
@Column({ name: 'audit_status', type: 'enum', enum: ['pending', 'approved', 'rejected'], default: 'pending', comment: '审核状态' })
|
@Column({ type: 'enum', enum: ['visible', 'hidden'], default: 'visible', comment: '状态' })
|
||||||
auditStatus: 'pending' | 'approved' | 'rejected';
|
status: 'visible' | 'hidden';
|
||||||
|
|
||||||
@Column({ name: 'audit_reject_reason', type: 'varchar', length: 500, nullable: true, comment: '审核拒绝原因' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
auditRejectReason: string;
|
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,18 +12,18 @@ export class RoomCalendarLog {
|
|||||||
@Column({ name: 'operator_id', type: 'bigint', unsigned: true, comment: '操作人ID' })
|
@Column({ name: 'operator_id', type: 'bigint', unsigned: true, comment: '操作人ID' })
|
||||||
operatorId: number;
|
operatorId: number;
|
||||||
|
|
||||||
@Column({ length: 100, comment: '变更日期范围' })
|
@Column({ name: 'date_range', length: 100, comment: '变更日期范围' })
|
||||||
dateRange: string;
|
dateRange: string;
|
||||||
|
|
||||||
@Column({ type: 'enum', enum: ['price', 'stock', 'status'], comment: '变更类型' })
|
@Column({ name: 'change_type', type: 'enum', enum: ['price', 'stock', 'status'], comment: '变更类型' })
|
||||||
changeType: 'price' | 'stock' | 'status';
|
changeType: 'price' | 'stock' | 'status';
|
||||||
|
|
||||||
@Column({ length: 100, nullable: true, comment: '变更前值' })
|
@Column({ name: 'old_value', length: 100, nullable: true, comment: '变更前值' })
|
||||||
oldValue: string;
|
oldValue: string;
|
||||||
|
|
||||||
@Column({ length: 100, nullable: true, comment: '变更后值' })
|
@Column({ name: 'new_value', length: 100, nullable: true, comment: '变更后值' })
|
||||||
newValue: string;
|
newValue: string;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ export class RoomCalendar {
|
|||||||
@Column({ type: 'enum', enum: ['available', 'unavailable'], default: 'available', comment: '房态' })
|
@Column({ type: 'enum', enum: ['available', 'unavailable'], default: 'available', comment: '房态' })
|
||||||
status: 'available' | 'unavailable';
|
status: 'available' | 'unavailable';
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ export class Room {
|
|||||||
@Column({ type: 'decimal', precision: 6, scale: 2, default: 0, comment: '面积(平方米)' })
|
@Column({ type: 'decimal', precision: 6, scale: 2, default: 0, comment: '面积(平方米)' })
|
||||||
area: number;
|
area: number;
|
||||||
|
|
||||||
@Column({ length: 50, default: '', comment: '床型' })
|
@Column({ name: 'bed_type', length: 50, default: '', comment: '床型' })
|
||||||
bedType: string;
|
bedType: string;
|
||||||
|
|
||||||
@Column({ type: 'tinyint', unsigned: true, default: 1, comment: '最多入住人数' })
|
@Column({ name: 'max_guests', type: 'tinyint', unsigned: true, default: 1, comment: '最多入住人数' })
|
||||||
maxGuests: number;
|
maxGuests: number;
|
||||||
|
|
||||||
@Column({ length: 20, default: '', comment: '楼层' })
|
@Column({ length: 20, default: '', comment: '楼层' })
|
||||||
@@ -39,7 +39,7 @@ export class Room {
|
|||||||
@Column({ type: 'json', nullable: true, comment: '图片URL列表' })
|
@Column({ type: 'json', nullable: true, comment: '图片URL列表' })
|
||||||
images: string[];
|
images: string[];
|
||||||
|
|
||||||
@Column({ length: 500, default: '', comment: '封面图' })
|
@Column({ name: 'cover_image', length: 500, default: '', comment: '封面图' })
|
||||||
coverImage: string;
|
coverImage: string;
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@@ -50,28 +50,28 @@ export class Room {
|
|||||||
status: 'on_sale' | 'off_sale';
|
status: 'on_sale' | 'off_sale';
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@Column({ type: 'enum', enum: ['pending', 'approved', 'rejected'], default: 'pending', comment: '审核状态' })
|
@Column({ name: 'audit_status', type: 'enum', enum: ['pending', 'approved', 'rejected'], default: 'pending', comment: '审核状态' })
|
||||||
auditStatus: 'pending' | 'approved' | 'rejected';
|
auditStatus: 'pending' | 'approved' | 'rejected';
|
||||||
|
|
||||||
@Column({ length: 500, nullable: true, comment: '审核拒绝原因' })
|
@Column({ name: 'audit_reject_reason', length: 500, nullable: true, comment: '审核拒绝原因' })
|
||||||
auditRejectReason?: string;
|
auditRejectReason?: string;
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@Column({ type: 'decimal', precision: 2, scale: 1, unsigned: true, default: 5.0, comment: '评分' })
|
@Column({ type: 'decimal', precision: 2, scale: 1, unsigned: true, default: 5.0, comment: '评分' })
|
||||||
rating: number;
|
rating: number;
|
||||||
|
|
||||||
@Column({ type: 'int', unsigned: true, default: 0, comment: '评价数' })
|
@Column({ name: 'review_count', type: 'int', unsigned: true, default: 0, comment: '评价数' })
|
||||||
reviewCount: number;
|
reviewCount: number;
|
||||||
|
|
||||||
@Column({ type: 'text', nullable: true, comment: '房源描述' })
|
@Column({ type: 'text', nullable: true, comment: '房源描述' })
|
||||||
description: string;
|
description: string;
|
||||||
|
|
||||||
@Column({ type: 'enum', enum: ['free', 'flexible', 'strict'], default: 'flexible', comment: '取消政策' })
|
@Column({ name: 'cancel_policy', type: 'enum', enum: ['free', 'flexible', 'strict'], default: 'flexible', comment: '取消政策' })
|
||||||
cancelPolicy: 'free' | 'flexible' | 'strict';
|
cancelPolicy: 'free' | 'flexible' | 'strict';
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ export class Seller {
|
|||||||
@OneToOne(() => Merchant, merchant => merchant.seller)
|
@OneToOne(() => Merchant, merchant => merchant.seller)
|
||||||
merchant: Merchant;
|
merchant: Merchant;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,6 @@ export class SettlementItem {
|
|||||||
@Column({ name: 'order_amount', type: 'decimal', precision: 10, scale: 2, unsigned: true, comment: '订单金额' })
|
@Column({ name: 'order_amount', type: 'decimal', precision: 10, scale: 2, unsigned: true, comment: '订单金额' })
|
||||||
orderAmount: number;
|
orderAmount: number;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,9 +56,9 @@ export class Settlement {
|
|||||||
@OneToMany(() => SettlementItem, item => item.settlement)
|
@OneToMany(() => SettlementItem, item => item.settlement)
|
||||||
items: SettlementItem[];
|
items: SettlementItem[];
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,22 +20,22 @@ export class User {
|
|||||||
@Column({ type: 'tinyint', unsigned: true, default: 0, comment: '性别 0-未知 1-男 2-女' })
|
@Column({ type: 'tinyint', unsigned: true, default: 0, comment: '性别 0-未知 1-男 2-女' })
|
||||||
gender: number;
|
gender: number;
|
||||||
|
|
||||||
@Column({ length: 50, nullable: true, comment: '真实姓名' })
|
@Column({ name: 'real_name', length: 50, nullable: true, comment: '真实姓名' })
|
||||||
realName: string;
|
realName: string;
|
||||||
|
|
||||||
@Column({ length: 255, nullable: true, select: false, comment: '身份证号' })
|
@Column({ name: 'id_card', length: 255, nullable: true, select: false, comment: '身份证号' })
|
||||||
idCard: string;
|
idCard: string;
|
||||||
|
|
||||||
@Index()
|
@Index()
|
||||||
@Column({ type: 'enum', enum: ['active', 'frozen', 'deleted'], default: 'active', comment: '状态' })
|
@Column({ type: 'enum', enum: ['active', 'frozen', 'deleted'], default: 'active', comment: '状态' })
|
||||||
status: 'active' | 'frozen' | 'deleted';
|
status: 'active' | 'frozen' | 'deleted';
|
||||||
|
|
||||||
@Column({ type: 'datetime', nullable: true, comment: '最后登录时间' })
|
@Column({ name: 'last_login_at', type: 'datetime', nullable: true, comment: '最后登录时间' })
|
||||||
lastLoginAt: Date;
|
lastLoginAt: Date;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ export class Withdrawal {
|
|||||||
@Column({ name: 'paid_at', type: 'datetime', nullable: true, comment: '打款时间' })
|
@Column({ name: 'paid_at', type: 'datetime', nullable: true, comment: '打款时间' })
|
||||||
paidAt: Date;
|
paidAt: Date;
|
||||||
|
|
||||||
@CreateDateColumn({ comment: '创建时间' })
|
@CreateDateColumn({ name: 'created_at', comment: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ comment: '更新时间' })
|
@UpdateDateColumn({ name: 'updated_at', comment: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,11 +236,11 @@ export class ActivityService {
|
|||||||
const inviteeIds = list.map((item) => item.inviteeId);
|
const inviteeIds = list.map((item) => item.inviteeId);
|
||||||
const orderCounts = await this.orderRepo
|
const orderCounts = await this.orderRepo
|
||||||
.createQueryBuilder('order')
|
.createQueryBuilder('order')
|
||||||
.select('order.userId', 'userId')
|
.select('order.user_id', 'userId')
|
||||||
.addSelect('COUNT(*)', 'count')
|
.addSelect('COUNT(*)', 'count')
|
||||||
.where('order.userId IN (:...ids)', { ids: inviteeIds })
|
.where('order.user_id IN (:...ids)', { ids: inviteeIds })
|
||||||
.andWhere('order.status = :status', { status: 'completed' })
|
.andWhere('order.status = :status', { status: 'completed' })
|
||||||
.groupBy('order.userId')
|
.groupBy('order.user_id')
|
||||||
.getRawMany();
|
.getRawMany();
|
||||||
|
|
||||||
const orderCountMap = new Map(orderCounts.map((item) => [item.userId, parseInt(item.count)]));
|
const orderCountMap = new Map(orderCounts.map((item) => [item.userId, parseInt(item.count)]));
|
||||||
@@ -436,11 +436,10 @@ export class ActivityService {
|
|||||||
// ===== 管理端功能 =====
|
// ===== 管理端功能 =====
|
||||||
|
|
||||||
async getInviteCashbackConfig() {
|
async getInviteCashbackConfig() {
|
||||||
const activity = await this.activityRepo.findOne({
|
let activity = await this.activityRepo.findOne({
|
||||||
where: { type: 'invite_cashback' },
|
where: { type: 'invite_cashback' },
|
||||||
});
|
});
|
||||||
if (!activity) {
|
if (!activity) {
|
||||||
// 创建默认配置
|
|
||||||
activity = this.activityRepo.create({
|
activity = this.activityRepo.create({
|
||||||
name: '邀请返现',
|
name: '邀请返现',
|
||||||
type: 'invite_cashback',
|
type: 'invite_cashback',
|
||||||
|
|||||||
@@ -24,6 +24,33 @@ export class InviteCashbackConfig {
|
|||||||
withdrawThreshold: number;
|
withdrawThreshold: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class UpdateInviteCashbackConfig {
|
||||||
|
@ApiPropertyOptional({ description: '首单返现比例' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
firstOrderRate?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: '二单返现比例' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
secondOrderRate?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: '最低返现' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
minCashback?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: '最高返现' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
maxCashback?: number;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: '提现门槛' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsNumber()
|
||||||
|
withdrawThreshold?: number;
|
||||||
|
}
|
||||||
|
|
||||||
// ===== 活动 DTO =====
|
// ===== 活动 DTO =====
|
||||||
|
|
||||||
export class CreateActivityDto {
|
export class CreateActivityDto {
|
||||||
@@ -63,12 +90,17 @@ export class UpdateActivityDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
name?: string;
|
name?: string;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ description: '是否启用' })
|
||||||
|
@IsOptional()
|
||||||
|
@IsBoolean()
|
||||||
|
enabled?: boolean;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: '活动配置' })
|
@ApiPropertyOptional({ description: '活动配置' })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsObject()
|
@IsObject()
|
||||||
@ValidateNested()
|
@ValidateNested()
|
||||||
@Type(() => InviteCashbackConfig)
|
@Type(() => UpdateInviteCashbackConfig)
|
||||||
config?: InviteCashbackConfig;
|
config?: UpdateInviteCashbackConfig;
|
||||||
|
|
||||||
@ApiPropertyOptional({ description: '活动开始时间' })
|
@ApiPropertyOptional({ description: '活动开始时间' })
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
|||||||
@@ -10,4 +10,7 @@ import { ConfigController } from './config.controller';
|
|||||||
providers: [ConfigService],
|
providers: [ConfigService],
|
||||||
exports: [ConfigService],
|
exports: [ConfigService],
|
||||||
})
|
})
|
||||||
export class ConfigModule {}
|
export class ConfigModule {}
|
||||||
|
|
||||||
|
// 别名导出,保持兼容性
|
||||||
|
export { ConfigModule as PlatformConfigModule };
|
||||||
@@ -63,7 +63,7 @@ export class MerchantService {
|
|||||||
.where('m.status = :status', { status: 'approved' });
|
.where('m.status = :status', { status: 'approved' });
|
||||||
|
|
||||||
if (keyword) {
|
if (keyword) {
|
||||||
qb.andWhere('m.shopName LIKE :kw', { kw: `%${keyword}%` });
|
qb.andWhere('m.shop_name LIKE :kw', { kw: `%${keyword}%` });
|
||||||
}
|
}
|
||||||
if (city) {
|
if (city) {
|
||||||
qb.andWhere('m.city = :city', { city });
|
qb.andWhere('m.city = :city', { city });
|
||||||
@@ -87,7 +87,7 @@ export class MerchantService {
|
|||||||
const qb = this.merchantRepo.createQueryBuilder('m');
|
const qb = this.merchantRepo.createQueryBuilder('m');
|
||||||
|
|
||||||
if (keyword) {
|
if (keyword) {
|
||||||
qb.andWhere('(m.shopName LIKE :kw OR m.phone LIKE :kw)', {
|
qb.andWhere('(m.shop_name LIKE :kw OR m.phone LIKE :kw)', {
|
||||||
kw: `%${keyword}%`,
|
kw: `%${keyword}%`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
|||||||
import { Order } from '@/entities/order.entity';
|
import { Order } from '@/entities/order.entity';
|
||||||
import { Room } from '@/entities/room.entity';
|
import { Room } from '@/entities/room.entity';
|
||||||
import { RoomCalendar } from '@/entities/room-calendar.entity';
|
import { RoomCalendar } from '@/entities/room-calendar.entity';
|
||||||
|
import { User } from '@/entities/user.entity';
|
||||||
|
import { Merchant } from '@/entities/merchant.entity';
|
||||||
import { OrderService } from './order.service';
|
import { OrderService } from './order.service';
|
||||||
import { UserOrderController, MerchantOrderController, AdminOrderController } from './order.controller';
|
import { UserOrderController, MerchantOrderController, AdminOrderController } from './order.controller';
|
||||||
import { MerchantModule } from '../merchant/merchant.module';
|
import { MerchantModule } from '../merchant/merchant.module';
|
||||||
@@ -11,7 +13,7 @@ import { PlatformConfigModule } from '../config/config.module';
|
|||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
TypeOrmModule.forFeature([Order, Room, RoomCalendar]),
|
TypeOrmModule.forFeature([Order, Room, RoomCalendar, User, Merchant]),
|
||||||
MerchantModule,
|
MerchantModule,
|
||||||
forwardRef(() => ActivityModule),
|
forwardRef(() => ActivityModule),
|
||||||
PlatformConfigModule,
|
PlatformConfigModule,
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export class OrderService {
|
|||||||
const qb = this.orderRepo.createQueryBuilder('o')
|
const qb = this.orderRepo.createQueryBuilder('o')
|
||||||
.leftJoinAndSelect('o.room', 'r')
|
.leftJoinAndSelect('o.room', 'r')
|
||||||
.leftJoinAndSelect('o.merchant', 'm')
|
.leftJoinAndSelect('o.merchant', 'm')
|
||||||
.where('o.userId = :userId', { userId });
|
.where('o.user_id = :userId', { userId });
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
qb.andWhere('o.status = :status', { status });
|
qb.andWhere('o.status = :status', { status });
|
||||||
@@ -104,12 +104,12 @@ export class OrderService {
|
|||||||
const qb = this.orderRepo.createQueryBuilder('o')
|
const qb = this.orderRepo.createQueryBuilder('o')
|
||||||
.leftJoinAndSelect('o.room', 'r')
|
.leftJoinAndSelect('o.room', 'r')
|
||||||
.leftJoinAndSelect('o.user', 'u')
|
.leftJoinAndSelect('o.user', 'u')
|
||||||
.where('o.merchantId = :merchantId', { merchantId });
|
.where('o.merchant_id = :merchantId', { merchantId });
|
||||||
|
|
||||||
if (status) qb.andWhere('o.status = :status', { status });
|
if (status) qb.andWhere('o.status = :status', { status });
|
||||||
if (orderNo) qb.andWhere('o.orderNo LIKE :orderNo', { orderNo: `%${orderNo}%` });
|
if (orderNo) qb.andWhere('o.order_no LIKE :orderNo', { orderNo: `%${orderNo}%` });
|
||||||
if (startDate) qb.andWhere('o.createdAt >= :startDate', { startDate });
|
if (startDate) qb.andWhere('o.created_at >= :startDate', { startDate });
|
||||||
if (endDate) qb.andWhere('o.createdAt <= :endDate', { endDate });
|
if (endDate) qb.andWhere('o.created_at <= :endDate', { endDate });
|
||||||
|
|
||||||
qb.orderBy('o.createdAt', 'DESC');
|
qb.orderBy('o.createdAt', 'DESC');
|
||||||
qb.skip((page - 1) * pageSize).take(pageSize);
|
qb.skip((page - 1) * pageSize).take(pageSize);
|
||||||
@@ -349,9 +349,9 @@ export class OrderService {
|
|||||||
.leftJoinAndSelect('o.user', 'u');
|
.leftJoinAndSelect('o.user', 'u');
|
||||||
|
|
||||||
if (status) qb.andWhere('o.status = :status', { status });
|
if (status) qb.andWhere('o.status = :status', { status });
|
||||||
if (orderNo) qb.andWhere('o.orderNo LIKE :orderNo', { orderNo: `%${orderNo}%` });
|
if (orderNo) qb.andWhere('o.order_no LIKE :orderNo', { orderNo: `%${orderNo}%` });
|
||||||
if (startDate) qb.andWhere('o.createdAt >= :startDate', { startDate });
|
if (startDate) qb.andWhere('o.created_at >= :startDate', { startDate });
|
||||||
if (endDate) qb.andWhere('o.createdAt <= :endDate', { endDate });
|
if (endDate) qb.andWhere('o.created_at <= :endDate', { endDate });
|
||||||
|
|
||||||
qb.orderBy('o.createdAt', 'DESC');
|
qb.orderBy('o.createdAt', 'DESC');
|
||||||
qb.skip((page - 1) * pageSize).take(pageSize);
|
qb.skip((page - 1) * pageSize).take(pageSize);
|
||||||
|
|||||||
@@ -47,26 +47,26 @@ export class ReviewService {
|
|||||||
content: dto.content,
|
content: dto.content,
|
||||||
images: dto.images,
|
images: dto.images,
|
||||||
isAnonymous: dto.isAnonymous || false,
|
isAnonymous: dto.isAnonymous || false,
|
||||||
auditStatus: 'pending',
|
status: 'visible',
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.reviewRepo.save(review);
|
await this.reviewRepo.save(review);
|
||||||
return { message: '评价已提交,等待审核' };
|
return { message: '评价已提交' };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询评价列表(公开,只显示审核通过的)
|
// 查询评价列表(公开,只显示可见的)
|
||||||
async findPublic(query: QueryReviewDto) {
|
async findPublic(query: QueryReviewDto) {
|
||||||
const { page = 1, pageSize = 10, merchantId, roomId } = query;
|
const { page = 1, pageSize = 10, merchantId, roomId } = query;
|
||||||
const qb = this.reviewRepo
|
const qb = this.reviewRepo
|
||||||
.createQueryBuilder('r')
|
.createQueryBuilder('r')
|
||||||
.leftJoinAndSelect('r.order', 'o')
|
.leftJoinAndSelect('r.order', 'o')
|
||||||
.where('r.auditStatus = :auditStatus', { auditStatus: 'approved' });
|
.where('r.status = :status', { status: 'visible' });
|
||||||
|
|
||||||
if (merchantId) {
|
if (merchantId) {
|
||||||
qb.andWhere('r.merchantId = :merchantId', { merchantId: Number(merchantId) });
|
qb.andWhere('r.merchant_id = :merchantId', { merchantId: Number(merchantId) });
|
||||||
}
|
}
|
||||||
if (roomId) {
|
if (roomId) {
|
||||||
qb.andWhere('r.roomId = :roomId', { roomId: Number(roomId) });
|
qb.andWhere('r.room_id = :roomId', { roomId: Number(roomId) });
|
||||||
}
|
}
|
||||||
|
|
||||||
qb.orderBy('r.createdAt', 'DESC');
|
qb.orderBy('r.createdAt', 'DESC');
|
||||||
@@ -83,7 +83,7 @@ export class ReviewService {
|
|||||||
return this.reviewRepo.findOne({ where: { orderId } });
|
return this.reviewRepo.findOne({ where: { orderId } });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 管理员审核评价列表
|
// 管理员评价列表
|
||||||
async findAllForAdmin(query: QueryReviewDto) {
|
async findAllForAdmin(query: QueryReviewDto) {
|
||||||
const { page = 1, pageSize = 10, auditStatus } = query;
|
const { page = 1, pageSize = 10, auditStatus } = query;
|
||||||
const qb = this.reviewRepo
|
const qb = this.reviewRepo
|
||||||
@@ -91,7 +91,7 @@ export class ReviewService {
|
|||||||
.leftJoinAndSelect('r.order', 'o');
|
.leftJoinAndSelect('r.order', 'o');
|
||||||
|
|
||||||
if (auditStatus) {
|
if (auditStatus) {
|
||||||
qb.andWhere('r.auditStatus = :auditStatus', { auditStatus });
|
qb.andWhere('r.status = :status', { status: auditStatus });
|
||||||
}
|
}
|
||||||
|
|
||||||
qb.orderBy('r.createdAt', 'DESC');
|
qb.orderBy('r.createdAt', 'DESC');
|
||||||
@@ -103,27 +103,27 @@ export class ReviewService {
|
|||||||
return { list, total, page: safePage, pageSize: safePageSize, totalPages: Math.ceil(total / safePageSize) };
|
return { list, total, page: safePage, pageSize: safePageSize, totalPages: Math.ceil(total / safePageSize) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 审核通过
|
// 显示评价
|
||||||
async approve(id: number) {
|
async approve(id: number) {
|
||||||
const review = await this.reviewRepo.findOne({ where: { id } });
|
const review = await this.reviewRepo.findOne({ where: { id } });
|
||||||
if (!review) throw new NotFoundException('评价不存在');
|
if (!review) throw new NotFoundException('评价不存在');
|
||||||
|
|
||||||
await this.reviewRepo.update(id, { auditStatus: 'approved', auditRejectReason: '' });
|
await this.reviewRepo.update(id, { status: 'visible' });
|
||||||
|
|
||||||
// 更新商家和房源的评分
|
// 更新商家和房源的评分
|
||||||
await this.updateMerchantRating(review.merchantId);
|
await this.updateMerchantRating(review.merchantId);
|
||||||
await this.updateRoomRating(review.roomId);
|
await this.updateRoomRating(review.roomId);
|
||||||
|
|
||||||
return { message: '评价已通过审核' };
|
return { message: '评价已显示' };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 审核拒绝
|
// 隐藏评价
|
||||||
async reject(id: number, reason: string) {
|
async reject(id: number, _reason: string) {
|
||||||
const review = await this.reviewRepo.findOne({ where: { id } });
|
const review = await this.reviewRepo.findOne({ where: { id } });
|
||||||
if (!review) throw new NotFoundException('评价不存在');
|
if (!review) throw new NotFoundException('评价不存在');
|
||||||
|
|
||||||
await this.reviewRepo.update(id, { auditStatus: 'rejected', auditRejectReason: reason });
|
await this.reviewRepo.update(id, { status: 'hidden' });
|
||||||
return { message: '评价已拒绝' };
|
return { message: '评价已隐藏' };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新商家平均评分
|
// 更新商家平均评分
|
||||||
@@ -132,8 +132,8 @@ export class ReviewService {
|
|||||||
.createQueryBuilder('r')
|
.createQueryBuilder('r')
|
||||||
.select('AVG(r.rating)', 'avgRating')
|
.select('AVG(r.rating)', 'avgRating')
|
||||||
.addSelect('COUNT(r.id)', 'count')
|
.addSelect('COUNT(r.id)', 'count')
|
||||||
.where('r.merchantId = :merchantId', { merchantId })
|
.where('r.merchant_id = :merchantId', { merchantId })
|
||||||
.andWhere('r.auditStatus = :auditStatus', { auditStatus: 'approved' })
|
.andWhere('r.status = :status', { status: 'visible' })
|
||||||
.getRawOne();
|
.getRawOne();
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
@@ -150,8 +150,8 @@ export class ReviewService {
|
|||||||
.createQueryBuilder('r')
|
.createQueryBuilder('r')
|
||||||
.select('AVG(r.rating)', 'avgRating')
|
.select('AVG(r.rating)', 'avgRating')
|
||||||
.addSelect('COUNT(r.id)', 'count')
|
.addSelect('COUNT(r.id)', 'count')
|
||||||
.where('r.roomId = :roomId', { roomId })
|
.where('r.room_id = :roomId', { roomId })
|
||||||
.andWhere('r.auditStatus = :auditStatus', { auditStatus: 'approved' })
|
.andWhere('r.status = :status', { status: 'visible' })
|
||||||
.getRawOne();
|
.getRawOne();
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export class RoomService {
|
|||||||
.createQueryBuilder('r')
|
.createQueryBuilder('r')
|
||||||
.leftJoinAndSelect('r.merchant', 'm')
|
.leftJoinAndSelect('r.merchant', 'm')
|
||||||
.where('r.status = :status', { status: 'on_sale' })
|
.where('r.status = :status', { status: 'on_sale' })
|
||||||
.andWhere('r.auditStatus = :auditStatus', { auditStatus: 'approved' });
|
.andWhere('r.audit_status = :auditStatus', { auditStatus: 'approved' });
|
||||||
|
|
||||||
if (keyword) {
|
if (keyword) {
|
||||||
qb.andWhere('r.name LIKE :kw', { kw: `%${keyword}%` });
|
qb.andWhere('r.name LIKE :kw', { kw: `%${keyword}%` });
|
||||||
@@ -108,15 +108,15 @@ export class RoomService {
|
|||||||
qb.andWhere('m.city = :city', { city });
|
qb.andWhere('m.city = :city', { city });
|
||||||
}
|
}
|
||||||
if (merchantId) {
|
if (merchantId) {
|
||||||
qb.andWhere('r.merchantId = :merchantId', { merchantId: Number(merchantId) });
|
qb.andWhere('r.merchant_id = :merchantId', { merchantId: Number(merchantId) });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 人数筛选:房间可住人数 >= 成人数
|
// 人数筛选:房间可住人数 >= 成人数
|
||||||
if (adultCount && !roomCount) {
|
if (adultCount && !roomCount) {
|
||||||
qb.andWhere('r.maxGuests >= :adultCount', { adultCount });
|
qb.andWhere('r.max_guests >= :adultCount', { adultCount });
|
||||||
} else if (adultCount && roomCount) {
|
} else if (adultCount && roomCount) {
|
||||||
// 多间房时,总可住人数 >= 成人数
|
// 多间房时,总可住人数 >= 成人数
|
||||||
qb.andWhere('r.maxGuests * :roomCount >= :adultCount', { roomCount, adultCount });
|
qb.andWhere('r.max_guests * :roomCount >= :adultCount', { roomCount, adultCount });
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortMap: Record<string, string> = {
|
const sortMap: Record<string, string> = {
|
||||||
@@ -203,7 +203,7 @@ export class RoomService {
|
|||||||
}
|
}
|
||||||
const qb = this.roomRepo
|
const qb = this.roomRepo
|
||||||
.createQueryBuilder('r')
|
.createQueryBuilder('r')
|
||||||
.where('r.merchantId = :merchantId', { merchantId: safeMerchantId });
|
.where('r.merchant_id = :merchantId', { merchantId: safeMerchantId });
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
qb.andWhere('r.status = :status', { status });
|
qb.andWhere('r.status = :status', { status });
|
||||||
@@ -232,7 +232,7 @@ export class RoomService {
|
|||||||
qb.andWhere('r.name LIKE :kw', { kw: `%${keyword}%` });
|
qb.andWhere('r.name LIKE :kw', { kw: `%${keyword}%` });
|
||||||
}
|
}
|
||||||
if (auditStatus) {
|
if (auditStatus) {
|
||||||
qb.andWhere('r.auditStatus = :auditStatus', { auditStatus });
|
qb.andWhere('r.audit_status = :auditStatus', { auditStatus });
|
||||||
}
|
}
|
||||||
if (type) {
|
if (type) {
|
||||||
qb.andWhere('r.type = :type', { type });
|
qb.andWhere('r.type = :type', { type });
|
||||||
|
|||||||
Generated
+9654
-7800
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user