feat: 迭代

This commit is contained in:
2026-05-15 11:28:02 +08:00
parent 6a7ec5fca7
commit 8c908ea557
120 changed files with 1139 additions and 238 deletions
+3 -3
View File
@@ -2,15 +2,15 @@ import { get, post } from '@/utils/request';
// 获取可领取的优惠券列表
export function getAvailableCoupons(params?: { merchantId?: number; roomId?: number }) {
return get('/api/user/coupons/available', params);
return get('/api/app/coupons/available', params);
}
// 领取优惠券
export function claimCoupon(couponId: number) {
return post('/api/user/coupons/claim', { couponId });
return post('/api/app/coupons/claim', { couponId });
}
// 获取我的优惠券列表
export function getMyCoupons(params?: { status?: string }) {
return get('/api/user/coupons', params);
return get('/api/app/coupons/my', params);
}
+2 -2
View File
@@ -2,7 +2,7 @@ import { get, post, put, del } from '@/utils/request';
// 获取常住人列表
export function getGuestList() {
return get('/api/user/guests');
return get('/api/app/guests');
}
// 获取常住人详情
@@ -12,7 +12,7 @@ export function getGuestDetail(id: number) {
// 添加常住人
export function createGuest(data: any) {
return post('/api/user/guests', data);
return post('/api/app/guests', data);
}
// 更新常住人
+5 -5
View File
@@ -30,25 +30,25 @@ export interface SellerLoginResult {
// 发送商家验证码
export function sellerSendCode(phone: string) {
return post('/seller/auth/send-code', { phone });
return post('/api/merchant/auth/send-code', { phone });
}
// 商家注册(验证码)
export function sellerRegister(data: SellerRegisterParams) {
return request<SellerLoginResult>({ url: '/seller/auth/register', method: 'POST', data, useSellerToken: true, skipAuthRedirect: true });
return request<SellerLoginResult>({ url: '/api/merchant/auth/register', method: 'POST', data, useSellerToken: true, skipAuthRedirect: true });
}
// 商家登录(验证码或密码)
export function sellerLogin(data: SellerLoginParams) {
return request<SellerLoginResult>({ url: '/seller/auth/login', method: 'POST', data, useSellerToken: true, skipAuthRedirect: true });
return request<SellerLoginResult>({ url: '/api/merchant/auth/login', method: 'POST', data, useSellerToken: true, skipAuthRedirect: true });
}
// 刷新商家令牌
export function sellerRefreshToken(refreshToken: string) {
return post<SellerLoginResult>('/seller/auth/refresh', { refreshToken });
return post<SellerLoginResult>('/api/merchant/auth/refresh', { refreshToken });
}
// 获取商家信息(需要商家token)
export function getSellerProfile() {
return request({ url: '/seller/auth/profile', method: 'GET', useSellerToken: true });
return request({ url: '/api/merchant/auth/profile', method: 'GET', useSellerToken: true });
}
+7 -7
View File
@@ -7,17 +7,17 @@ export const financeApi = {
/**
* 获取钱包信息
*/
getWallet: () => get('/seller/finance/wallet'),
getWallet: () => get('/api/merchant/finance/wallet'),
/**
* 获取交易流水
*/
getTransactions: (params?: any) => get('/seller/finance/transactions', params),
getTransactions: (params?: any) => get('/api/merchant/finance/transactions', params),
/**
* 获取结算记录
*/
getSettlements: (params?: any) => get('/seller/finance/settlements', params),
getSettlements: (params?: any) => get('/api/merchant/finance/settlements', params),
/**
* 获取结算详情
@@ -39,12 +39,12 @@ export const financeApi = {
accountName: string;
accountNumber: string;
bankName?: string;
}) => post('/seller/finance/withdrawals', data),
}) => post('/api/merchant/finance/withdrawals', data),
/**
* 获取提现记录
*/
getWithdrawals: (params?: any) => get('/seller/finance/withdrawals', params),
getWithdrawals: (params?: any) => get('/api/merchant/finance/withdrawals', params),
/**
* 获取提现详情
@@ -59,11 +59,11 @@ export const statisticsApi = {
/**
* 获取数据概览
*/
getOverview: () => get('/seller/statistics/overview'),
getOverview: () => get('/api/merchant/statistics/overview'),
/**
* 获取收入趋势
*/
getIncomeTrend: (type: 'day' | 'week' | 'month' = 'day') =>
get('/seller/statistics/income-trend', { type }),
get('/api/merchant/statistics/income-trend', { type }),
};
+3 -3
View File
@@ -62,7 +62,7 @@ export interface UpdateMerchantParams {
// 申请创建店铺(需要商家token)
export function applyMerchant(data: ApplyMerchantParams) {
return request({
url: '/seller/merchant/apply',
url: '/api/merchant/merchant/apply',
method: 'POST',
data,
useSellerToken: true,
@@ -72,7 +72,7 @@ export function applyMerchant(data: ApplyMerchantParams) {
// 获取我的店铺信息(需要商家token)
export function getMyMerchant() {
return request({
url: '/seller/merchant/mine',
url: '/api/merchant/merchant/mine',
method: 'GET',
useSellerToken: true,
});
@@ -81,7 +81,7 @@ export function getMyMerchant() {
// 更新店铺信息(需要商家token)
export function updateMerchant(data: UpdateMerchantParams) {
return request({
url: '/seller/merchant/update',
url: '/api/merchant/merchant/update',
method: 'PUT',
data,
useSellerToken: true,
+1 -1
View File
@@ -8,7 +8,7 @@ export function getSellerOrders(params: {
orderNo?: string;
}) {
return request({
url: '/seller/orders',
url: '/api/merchant/orders',
method: 'GET',
data: params,
useSellerToken: true,
+2 -2
View File
@@ -18,7 +18,7 @@ export function batchUpdateCalendar(data: {
status?: string;
}) {
return request({
url: '/seller/room-calendar/batch',
url: '/api/merchant/room-calendar/batch',
method: 'PUT',
data,
useSellerToken: true,
@@ -33,7 +33,7 @@ export function singleDayUpdate(data: {
status?: string;
}) {
return request({
url: '/seller/room-calendar/single',
url: '/api/merchant/room-calendar/single',
method: 'PUT',
data,
useSellerToken: true,
+2 -2
View File
@@ -2,7 +2,7 @@ import { request } from '@/utils/request';
// 商家管理接口(需要 sellerToken
export function getMerchantRooms(params: any) {
return request({ url: '/seller/rooms', method: 'GET', data: params, useSellerToken: true });
return request({ url: '/api/merchant/rooms', method: 'GET', data: params, useSellerToken: true });
}
export function getMerchantRoom(id: number) {
@@ -10,7 +10,7 @@ export function getMerchantRoom(id: number) {
}
export function createMerchantRoom(data: any) {
return request({ url: '/seller/rooms', method: 'POST', data, useSellerToken: true });
return request({ url: '/api/merchant/rooms', method: 'POST', data, useSellerToken: true });
}
export function updateMerchantRoom(id: number, data: any) {
+11 -11
View File
@@ -1,41 +1,41 @@
import { post, get } from '@/utils/request';
export function sendCode(phone: string) {
return post('/api/user/auth/send-code', { phone });
return post('/api/app/auth/send-code', { phone });
}
export function loginByPhone(phone: string, code: string) {
return post('/api/user/auth/login/phone', { phone, code });
return post('/api/app/auth/login/phone', { phone, code });
}
export function loginByPassword(phone: string, password: string) {
return post('/api/user/auth/login/password', { phone, password });
return post('/api/app/auth/login/password', { phone, password });
}
export function loginByWechat(code: string, nickname?: string, avatar?: string) {
return post('/api/user/auth/login/wechat', { code, nickname, avatar });
return post('/api/app/auth/login/wechat', { code, nickname, avatar });
}
export function register(data: { phone: string; code: string; password?: string; nickname?: string }) {
return post('/api/user/auth/register', data);
return post('/api/app/auth/register', data);
}
export function refreshToken(refreshToken: string) {
return post('/api/user/auth/refresh', { refreshToken });
return post('/api/app/auth/refresh', { refreshToken });
}
export function getUserProfile() {
return get('/api/user/profile/profile');
return get('/api/app/profile/profile');
}
export function updateUserProfile(data: { nickname?: string; avatar?: string }) {
return post('/api/user/profile/profile', data);
return post('/api/app/profile/profile', data);
}
export function uploadAvatar(filePath: string) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: import.meta.env.VITE_API_BASE_URL + '/api/user/profile/avatar',
url: import.meta.env.VITE_API_BASE_URL + '/api/app/profile/avatar',
filePath,
name: 'file',
header: {
@@ -54,9 +54,9 @@ export function uploadAvatar(filePath: string) {
}
export function verifyIdentity(data: { realName: string; idCard: string }) {
return post('/api/user/profile/verify', data);
return post('/api/app/profile/verify', data);
}
export function getVerifyStatus() {
return get('/api/user/profile/verify/status');
return get('/api/app/profile/verify/status');
}
+8 -8
View File
@@ -2,32 +2,32 @@ import { get, post } from '@/utils/request';
// 获取活动列表
export const getActivityList = () =>
get('/api/public/activity/list');
get('/api/app/activity/list');
// 获取邀请活动配置
export const getInviteConfig = () =>
get('/api/public/activity/invite/config');
get('/api/app/activity/invite/config');
// 获取我的邀请统计
export const getInviteStats = () =>
get('/api/user/activity/invite/stats');
get('/api/app/activity/invite/stats');
// 绑定邀请关系
export const bindInvitation = (inviteCode: string) =>
post('/api/user/activity/invite/bind', { inviteCode });
post('/api/app/activity/invite/bind', { inviteCode });
// 邀请记录列表
export const getInviteRecords = (params?: { page?: number; pageSize?: number }) =>
get('/api/user/activity/invite/records', params);
get('/api/app/activity/invite/records', params);
// 返现记录列表
export const getCashbackRecords = (params?: { page?: number; pageSize?: number }) =>
get('/api/user/activity/invite/cashbacks', params);
get('/api/app/activity/invite/cashbacks', params);
// 申请提现
export const createInviteWithdrawal = (amount: number) =>
post('/api/user/activity/invite/withdraw', { amount });
post('/api/app/activity/invite/withdraw', { amount });
// 提现记录列表
export const getInviteWithdrawals = (params?: { page?: number; pageSize?: number }) =>
get('/api/user/activity/invite/withdrawals', params);
get('/api/app/activity/invite/withdrawals', params);
+2 -2
View File
@@ -28,7 +28,7 @@ export interface MerchantInfo {
// 获取商家详情(公开)
export function getMerchantById(id: number) {
return get<MerchantInfo>(`/api/public/merchants/${id}`);
return get<MerchantInfo>(`/api/app/merchants/${id}`);
}
// 获取商家列表(公开,已审核通过)
@@ -38,5 +38,5 @@ export function getMerchantList(params: {
keyword?: string;
city?: string;
}) {
return get('/api/public/merchants', params);
return get('/api/app/merchants', params);
}
+3 -3
View File
@@ -13,11 +13,11 @@ export function createOrder(data: {
remark?: string;
paymentMethod?: string;
}) {
return post('/api/user/orders', data);
return post('/api/app/orders', data);
}
export function getOrderList(params: { page?: number; pageSize?: number; status?: string }) {
return get('/api/user/orders', params);
return get('/api/app/orders', params);
}
export function getOrderDetail(id: number) {
@@ -33,5 +33,5 @@ export function refundOrder(id: number, reason: string) {
}
export function payOrder(orderId: number, paymentMethod: 'wechat' | 'alipay' | 'balance' = 'wechat') {
return post('/api/user/orders/pay', { orderId, paymentMethod });
return post('/api/app/orders/pay', { orderId, paymentMethod });
}
+2 -2
View File
@@ -1,11 +1,11 @@
import { post, get } from '@/utils/request';
export function createReview(orderId: number, data: { rating: number; content?: string; images?: string[]; isAnonymous?: boolean }) {
return post('/api/user/reviews/order', { orderId, ...data });
return post('/api/app/reviews/order', { orderId, ...data });
}
export function getReviewList(params: { merchantId?: number; roomId?: number; page?: number; pageSize?: number }) {
return get('/api/user/reviews', params);
return get('/api/app/reviews', params);
}
export function checkOrderReviewed(orderId: number) {
+1 -1
View File
@@ -16,7 +16,7 @@ export function getRoomList(params: {
roomCount?: number;
adultCount?: number;
}) {
return get('/api/public/rooms', params);
return get('/api/app/rooms', params);
}
export function getRoomDetail(id: number) {
+4 -4
View File
@@ -41,7 +41,7 @@ export const walletApi = {
// 获取钱包信息
getWallet() {
return request<WalletInfo>({
url: '/api/user/finance/wallet',
url: '/api/app/finance/wallet',
method: 'GET',
});
},
@@ -56,7 +56,7 @@ export const walletApi = {
pageSize?: number;
}) {
return request<{ items: Transaction[]; total: number }>({
url: '/api/user/finance/transactions',
url: '/api/app/finance/transactions',
method: 'GET',
data: params,
});
@@ -70,7 +70,7 @@ export const walletApi = {
accountNumber: string;
}) {
return request({
url: '/api/user/finance/withdraw',
url: '/api/app/finance/withdraw',
method: 'POST',
data,
});
@@ -83,7 +83,7 @@ export const walletApi = {
pageSize?: number;
}) {
return request<{ items: Withdrawal[]; total: number }>({
url: '/api/user/finance/withdrawals',
url: '/api/app/finance/withdrawals',
method: 'GET',
data: params,
});
+38 -4
View File
@@ -49,9 +49,9 @@
<u-icon name="rmb-circle-fill" :size="14" color="#FFB800" />
<text class="tag-text">最高¥{{ activity.config.maxCashback }}</text>
</view>
<view v-if="activity.config.minWithdraw" class="tag-item">
<view v-if="activity.config.withdrawThreshold" class="tag-item">
<u-icon name="checkmark-circle-fill" :size="14" color="#52C41A" />
<text class="tag-text">{{ activity.config.minWithdraw }}元可提现</text>
<text class="tag-text">{{ activity.config.withdrawThreshold }}元可提现</text>
</view>
</view>
@@ -105,7 +105,10 @@ interface Activity {
config?: {
maxCashback?: number;
firstOrderRate?: number;
minWithdraw?: number;
secondOrderRate?: number;
withdrawThreshold?: number;
minCashback?: number;
maxOrderIndex?: number;
};
}
@@ -120,7 +123,20 @@ async function fetchActivities() {
loading.value = true;
try {
const res = await getActivityList();
activities.value = (res.data?.list || []).filter((item: Activity) => item.enabled);
const list = Array.isArray(res.data) ? res.data : (res.data?.list || []);
// 转换后端数据格式为前端需要的格式
activities.value = list
.filter((item: any) => item.enabled)
.map((item: any) => ({
id: item.id,
type: item.type === 'invite_cashback' ? 'invite' : item.type,
title: item.name || '活动',
description: getActivityDescription(item.type),
icon: getActivityIcon(item.type),
enabled: item.enabled,
config: item.config,
}));
} catch (e) {
console.error('获取活动列表失败:', e);
uni.showToast({ title: '加载失败,请重试', icon: 'none' });
@@ -129,6 +145,24 @@ async function fetchActivities() {
}
}
function getActivityDescription(type: string) {
const descMap: Record<string, string> = {
invite_cashback: '邀请好友下单,双方都有奖励',
coupon: '领取优惠券,享受更多优惠',
discount: '限时折扣,不容错过',
};
return descMap[type] || '参与活动,赢取奖励';
}
function getActivityIcon(type: string) {
const iconMap: Record<string, string> = {
invite_cashback: '🎁',
coupon: '🎫',
discount: '💰',
};
return iconMap[type] || '🎉';
}
function getCardClass(type: string) {
const classMap: Record<string, string> = {
invite: 'card-invite',
@@ -169,6 +169,7 @@ const activeUsers = computed(() => {
// 筛选记录
const filteredRecords = computed(() => {
console.log('计算筛选记录, 当前筛选:', currentFilter.value);
if (currentFilter.value === 'ordered') {
return records.value.filter(item => item.orderCount > 0);
} else if (currentFilter.value === 'not-ordered') {
@@ -223,7 +224,10 @@ function onRefresh() {
}
function changeFilter(value: string) {
console.log('切换筛选:', value);
currentFilter.value = value;
console.log('当前筛选值:', currentFilter.value);
console.log('筛选后记录数:', filteredRecords.value.length);
}
function formatTime(dateStr: string) {
@@ -11,6 +11,8 @@ const { RangePicker } = DatePicker;
interface EarningRecord {
id: number;
date: string;
startDate?: string;
endDate?: string;
orderCount: number;
totalAmount: number;
platformCommission: number;
@@ -81,6 +83,8 @@ const Earnings: React.FC = () => {
setDataSource([{
id: 1,
date: data.startDate,
startDate: data.startDate,
endDate: data.endDate,
orderCount: data.orderCount || 0,
totalAmount: data.orderAmount || 0,
platformCommission: data.serviceFee || 0,
@@ -109,10 +113,15 @@ const Earnings: React.FC = () => {
const columns: ColumnsType<EarningRecord> = [
{
title: '日期',
title: '日期范围',
dataIndex: 'date',
key: 'date',
render: (date: string) => formatDateTime(date).split(' ')[0],
render: (date: string, record: EarningRecord) => {
if (record.startDate && record.endDate) {
return `${formatDateTime(record.startDate).split(' ')[0]} ~ ${formatDateTime(record.endDate).split(' ')[0]}`;
}
return formatDateTime(date).split(' ')[0];
},
},
{
title: '订单数',
+7 -7
View File
@@ -7,11 +7,11 @@ import jwtConfig from './config/jwt.config';
import redisConfig from './config/redis.config';
import { ScheduleModule as TaskScheduleModule } from './schedule/schedule.module';
// 新的模块结构
import { UserModule } from './modules/user/user.module';
// 新的模块结构 - 按端分类
import { AppModule as AppClientModule } from './modules/app/app.module';
import { MerchantModule } from './modules/merchant/merchant.module';
import { AdminModule } from './modules/admin/admin.module';
import { CommonModule } from './modules/common/common.module';
import { SharedModule } from './modules/shared/shared.module';
import { WebsiteModule } from './modules/website/website.module';
@Module({
@@ -39,11 +39,11 @@ import { WebsiteModule } from './modules/website/website.module';
}),
}),
// 新的模块结构:按端分组
UserModule, // 用户端(C端)
MerchantModule, // 商家端(B端
AppClientModule, // 应用端(小程序C端)
MerchantModule, // 商家端(小程序商家端+商家管理后台
AdminModule, // 平台管理端
CommonModule, // 公共模块
WebsiteModule, // 官网模块
SharedModule, // 共享模块(上传、配置等)
WebsiteModule, // 官网
],
})
export class AppModule {}
@@ -1,4 +1,5 @@
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, Index } from 'typeorm';
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, Index, ManyToOne, JoinColumn } from 'typeorm';
import { User } from './user.entity';
@Entity('mkt_invite_withdrawals')
export class MktInviteWithdrawal {
@@ -13,6 +14,10 @@ export class MktInviteWithdrawal {
@Index()
user_id: number;
@ManyToOne(() => User)
@JoinColumn({ name: 'user_id' })
user: User;
@Column({ type: 'decimal', precision: 10, scale: 2, comment: '提现金额' })
amount: number;
+12
View File
@@ -16,14 +16,26 @@ export class Review {
@Column({ name: 'order_id', type: 'bigint', unsigned: true, unique: true, comment: '订单ID' })
orderId: number;
@ManyToOne(() => User)
@JoinColumn({ name: 'user_id' })
user: User;
@Index()
@Column({ name: 'user_id', type: 'bigint', unsigned: true, comment: '用户ID' })
userId: number;
@ManyToOne(() => Merchant)
@JoinColumn({ name: 'merchant_id' })
merchant: Merchant;
@Index()
@Column({ name: 'merchant_id', type: 'bigint', unsigned: true, comment: '商家ID' })
merchantId: number;
@ManyToOne(() => Room)
@JoinColumn({ name: 'room_id' })
room: Room;
@Column({ name: 'room_id', type: 'bigint', unsigned: true, comment: '房型ID' })
roomId: number;
+4
View File
@@ -42,6 +42,10 @@ async function bootstrap() {
.setDescription('平台后端接口文档')
.setVersion('1.0')
.addBearerAuth()
.addTag('应用端', '小程序C端用户使用的接口')
.addTag('商家端', '小程序商家端和商家管理后台使用的接口')
.addTag('平台管理端', '平台管理后台使用的接口')
.addTag('官网', '官方网站使用的接口')
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api/docs', app, document);
@@ -1,8 +1,8 @@
import { Controller, Get, Put, Body, UseGuards } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { ConfigService } from '@/modules/common/config/config.service';
import { ConfigService } from '@/modules/shared/config/config.service';
import { JwtAuthGuard, RolesGuard, Roles } from '@/common';
import { UploadService } from '@/modules/common/upload/upload.service';
import { UploadService } from '@/modules/shared/upload/upload.service';
@ApiTags('管理端-系统配置')
@ApiBearerAuth()
@@ -1,6 +1,6 @@
import { Module } from '@nestjs/common';
import { ConfigModule as CommonConfigModule } from '@/modules/common/config/config.module';
import { UploadModule } from '@/modules/common/upload/upload.module';
import { ConfigModule as CommonConfigModule } from '@/modules/shared/config/config.module';
import { UploadModule } from '@/modules/shared/upload/upload.module';
import { AdminConfigController } from './config.controller';
@Module({
@@ -10,7 +10,7 @@ import {
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { CouponService } from '@/modules/common/coupon/coupon.service';
import { CouponService } from '@/modules/shared/coupon/coupon.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { CurrentUser } from '@/common/decorators/current-user.decorator';
@@ -1,5 +1,5 @@
import { Module } from '@nestjs/common';
import { CouponModule } from '@/modules/common/coupon/coupon.module';
import { CouponModule } from '@/modules/shared/coupon/coupon.module';
import { CouponController } from './coupon.controller';
@Module({
@@ -1,2 +1,2 @@
// 复用共享的 CouponService
export { CouponService } from '@/modules/common/coupon/coupon.service';
export { CouponService } from '@/modules/shared/coupon/coupon.service';
@@ -1 +1 @@
export * from '@/modules/common/coupon/dto/coupon.dto';
export * from '@/modules/shared/coupon/dto/coupon.dto';
@@ -6,10 +6,10 @@ import {
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { AccountService } from './account.service';
import { AccountService } from '@/modules/shared/finance/account.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { QueryUserAccountsDto, QueryMerchantAccountsDto } from './dto/account.dto';
import { QueryUserAccountsDto, QueryMerchantAccountsDto } from '@/modules/shared/finance/dto/account.dto';
@ApiTags('账户管理(管理员)')
@Controller('admin/finance/accounts')
@@ -1,9 +1,22 @@
import { Module } from '@nestjs/common';
import { FinanceModule as CommonFinanceModule } from '@/modules/common/finance/finance.module';
import { FinanceModule as CommonFinanceModule } from '@/modules/shared/finance/finance.module';
import { AccountAdminController } from './account-admin.controller';
import { ReconciliationAdminController } from './reconciliation-admin.controller';
import { ReportAdminController } from './report-admin.controller';
import { SettlementAdminController } from './settlement-admin.controller';
import { TransactionAdminController } from './transaction-admin.controller';
import { WithdrawalAdminController } from './withdrawal-admin.controller';
@Module({
imports: [CommonFinanceModule],
controllers: [],
controllers: [
AccountAdminController,
ReconciliationAdminController,
ReportAdminController,
SettlementAdminController,
TransactionAdminController,
WithdrawalAdminController,
],
})
export class AdminFinanceModule {}
@@ -10,11 +10,11 @@ import {
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { ReconciliationService } from './reconciliation.service';
import { ReconciliationService } from '@/modules/shared/finance/reconciliation.service';
import {
ManualReconciliationDto,
QueryReconciliationDto,
} from './dto/reconciliation.dto';
} from '@/modules/shared/finance/dto/reconciliation.dto';
@ApiTags('对账管理(管理员)')
@Controller('admin/finance/reconciliations')
@@ -5,7 +5,7 @@ import {
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { ReportService } from './report.service';
import { ReportService } from '@/modules/shared/finance/report.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import {
@@ -13,7 +13,7 @@ import {
QueryDailyReportDto,
QueryWeeklyReportDto,
QueryMonthlyReportDto,
} from './dto/report.dto';
} from '@/modules/shared/finance/dto/report.dto';
@ApiTags('财务报表(管理员)')
@Controller('admin/finance/reports')
@@ -32,25 +32,24 @@ export class ReportAdminController {
@Get('trend')
@ApiOperation({ summary: '财务趋势' })
async getTrend(@Query() dto: QueryTrendDto) {
return this.reportService.getTrend({
startDate: dto.startDate,
endDate: dto.endDate,
});
const startDate = dto.startDate || new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
const endDate = dto.endDate || new Date().toISOString().split('T')[0];
return this.reportService.getTrend({ startDate, endDate });
}
@Get('daily')
@ApiOperation({ summary: '日报表' })
async getDailyReport(@Query() dto: QueryDailyReportDto) {
return this.reportService.getDailyReport(dto.date);
const date = dto.date || new Date().toISOString().split('T')[0];
return this.reportService.getDailyReport(date);
}
@Get('weekly')
@ApiOperation({ summary: '周报表' })
async getWeeklyReport(@Query() dto: QueryWeeklyReportDto) {
return this.reportService.getWeeklyReport({
startDate: dto.startDate,
endDate: dto.endDate,
});
const endDate = dto.endDate || new Date().toISOString().split('T')[0];
const startDate = dto.startDate || new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
return this.reportService.getWeeklyReport({ startDate, endDate });
}
@Get('monthly')
@@ -9,7 +9,7 @@ import {
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { SettlementService } from './settlement.service';
import { SettlementService } from '@/modules/shared/finance/settlement.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import {
@@ -17,7 +17,7 @@ import {
ManualSettlementDto,
ApproveSettlementDto,
RejectSettlementDto,
} from './dto/settlement.dto';
} from '@/modules/shared/finance/dto/settlement.dto';
@ApiTags('结算管理(管理员)')
@Controller('admin/finance/settlements')
@@ -8,12 +8,12 @@ import {
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { TransactionService } from './transaction.service';
import { TransactionService } from '@/modules/shared/finance/transaction.service';
import {
QueryUserTransactionDto,
QueryMerchantTransactionDto,
QueryPlatformTransactionDto,
} from './dto/transaction.dto';
} from '@/modules/shared/finance/dto/transaction.dto';
@ApiTags('交易流水管理(管理员)')
@Controller('admin/finance/transactions')
@@ -9,7 +9,7 @@ import {
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { WithdrawalService } from './withdrawal.service';
import { WithdrawalService } from '@/modules/shared/finance/withdrawal.service';
import { JwtAuthGuard, RolesGuard } from '@/common';
import { Roles } from '@/common/decorators/roles.decorator';
import { CurrentUser } from '@/common/decorators/current-user.decorator';
@@ -20,7 +20,7 @@ import {
QueryMerchantWithdrawalDto,
RejectWithdrawalDto,
ConfirmPaymentDto,
} from './dto/withdrawal.dto';
} from '@/modules/shared/finance/dto/withdrawal.dto';
@ApiTags('提现管理(管理员)')
@Controller('admin/finance/withdrawals')
@@ -0,0 +1,84 @@
import {
Controller,
Get,
Post,
Body,
Query,
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { ActivityService } from './activity.service';
import { JwtAuthGuard, CurrentUser } from '@/common';
import {
BindInvitationDto,
CreateInviteWithdrawalDto,
QueryInviteRecordsDto,
} from './dto/activity.dto';
// ===== 用户端活动接口 =====
@ApiTags('用户端-活动')
@Controller('app/activity')
export class ActivityController {
constructor(private readonly activityService: ActivityService) {}
@Get('list')
@ApiOperation({ summary: '获取活动列表' })
async getActivityList() {
const activity = await this.activityService.getEnabledInviteCashbackActivity();
return activity ? [activity] : [];
}
@Get('invite/config')
@ApiOperation({ summary: '获取邀请活动配置' })
async getInviteConfig() {
return this.activityService.getEnabledInviteCashbackActivity();
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Get('invite/stats')
@ApiOperation({ summary: '获取我的邀请统计' })
async getStats(@CurrentUser('sub') userId: number) {
return this.activityService.getUserStats(userId);
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Post('invite/bind')
@ApiOperation({ summary: '绑定邀请关系' })
async bind(@CurrentUser('sub') userId: number, @Body() dto: BindInvitationDto) {
return this.activityService.bindInvitation(userId, dto);
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Get('invite/records')
@ApiOperation({ summary: '邀请记录列表' })
async getRecords(@CurrentUser('sub') userId: number, @Query() dto: QueryInviteRecordsDto) {
return this.activityService.getInviteRecords(userId, dto);
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Get('invite/cashbacks')
@ApiOperation({ summary: '返现记录列表' })
async getCashbacks(@CurrentUser('sub') userId: number, @Query() dto: QueryInviteRecordsDto) {
return this.activityService.getCashbackRecords(userId, dto);
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Post('invite/withdraw')
@ApiOperation({ summary: '申请提现' })
async createWithdrawal(@CurrentUser('sub') userId: number, @Body() dto: CreateInviteWithdrawalDto) {
return this.activityService.createWithdrawal(userId, dto);
}
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@Get('invite/withdrawals')
@ApiOperation({ summary: '提现记录列表' })
async getWithdrawals(@CurrentUser('sub') userId: number, @Query() dto: QueryInviteRecordsDto) {
return this.activityService.getWithdrawalRecords(userId, dto);
}
}
@@ -205,6 +205,11 @@ export class ActivityService {
take: pageSize,
});
// 如果没有邀请记录,直接返回
if (list.length === 0) {
return { list: [], total: 0 };
}
// 获取每个被邀请人的订单数
const inviteeIds = list.map((item) => item.inviteeId);
const orderCounts = await this.orderRepo
@@ -1,4 +1,9 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Merchant } from '@/entities/merchant.entity';
import { MerchantAccount } from '@/entities/merchant-account.entity';
import { Room } from '@/entities/room.entity';
import { RoomCalendar } from '@/entities/room-calendar.entity';
import { UserAuthModule } from './auth/auth.module';
import { UserProfileModule } from './profile/profile.module';
import { UserGuestModule } from './guest/guest.module';
@@ -7,9 +12,13 @@ import { UserReviewModule } from './review/review.module';
import { UserCouponModule } from './coupon/coupon.module';
import { UserFinanceModule } from './finance/finance.module';
import { UserActivityModule } from './activity/activity.module';
import { RoomModule } from './room/room.module';
import { MerchantController } from './merchant/merchant.controller';
import { MerchantService } from '@/modules/merchant/merchant.service';
@Module({
imports: [
TypeOrmModule.forFeature([Merchant, MerchantAccount, Room, RoomCalendar]),
UserAuthModule,
UserProfileModule,
UserGuestModule,
@@ -18,6 +27,9 @@ import { UserActivityModule } from './activity/activity.module';
UserCouponModule,
UserFinanceModule,
UserActivityModule,
RoomModule,
],
controllers: [MerchantController],
providers: [MerchantService],
})
export class UserModule {}
export class AppModule {}
@@ -11,7 +11,7 @@ import {
import { JwtAuthGuard } from '@/common/guards/jwt-auth.guard';
@ApiTags('用户认证')
@Controller('user/auth')
@Controller('app/auth')
export class AuthController {
constructor(private readonly authService: AuthService) {}
@@ -14,7 +14,7 @@ import { CurrentUser } from '@/common/decorators/current-user.decorator';
import { ReceiveCouponDto, QueryUserCouponDto, QueryCouponDto } from './dto/coupon.dto';
@ApiTags('优惠券(用户)')
@Controller('user/coupons')
@Controller('app/coupons')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class CouponUserController {
@@ -14,7 +14,7 @@ import { CurrentUser } from '@/common/decorators/current-user.decorator';
import { ReceiveCouponDto, QueryUserCouponDto, QueryCouponDto } from './dto/coupon.dto';
@ApiTags('优惠券(用户)')
@Controller('user/coupons')
@Controller('app/coupons')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class CouponController {
@@ -0,0 +1,2 @@
// 复用现有的 CouponDto
export * from '@/modules/shared/coupon/dto/coupon.dto';
@@ -9,17 +9,17 @@ import {
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { JwtAuthGuard } from '@/common';
import { CurrentUser } from '@/common/decorators/current-user.decorator';
import { WithdrawalService } from './withdrawal.service';
import { TransactionService } from './transaction.service';
import { AccountService } from './account.service';
import { WithdrawalService } from '@/modules/shared/finance/withdrawal.service';
import { TransactionService } from '@/modules/shared/finance/transaction.service';
import { AccountService } from '@/modules/shared/finance/account.service';
import {
CreateUserWithdrawalDto,
QueryUserWithdrawalDto,
QueryTransactionDto,
} from './dto/finance.dto';
} from '@/modules/shared/finance/dto/finance.dto';
@ApiTags('财务管理(用户)')
@Controller('user/finance')
@Controller('app/finance')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class FinanceUserController {
@@ -1,9 +1,10 @@
import { Module } from '@nestjs/common';
import { FinanceModule as CommonFinanceModule } from '@/modules/common/finance/finance.module';
import { FinanceModule as CommonFinanceModule } from '@/modules/shared/finance/finance.module';
import { FinanceUserController } from './finance-user.controller';
@Module({
imports: [CommonFinanceModule],
controllers: [],
controllers: [FinanceUserController],
})
export class UserFinanceModule {}
@@ -8,16 +8,16 @@ import {
UseGuards,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { WithdrawalService } from './withdrawal.service';
import { WithdrawalService } from '@/modules/shared/finance/withdrawal.service';
import { JwtAuthGuard } from '@/common';
import { CurrentUser } from '@/common/decorators/current-user.decorator';
import {
CreateUserWithdrawalDto,
QueryUserWithdrawalDto,
} from './dto/withdrawal.dto';
} from '@/modules/shared/finance/dto/withdrawal.dto';
@ApiTags('提现管理(用户)')
@Controller('user/finance/withdrawals')
@Controller('app/finance/withdrawals')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class WithdrawalUserController {
@@ -13,7 +13,7 @@ import { GuestService } from './guest.service';
import { CreateGuestDto, UpdateGuestDto } from './dto/guest.dto';
import { JwtAuthGuard } from '@/common/guards/jwt-auth.guard';
@Controller('user/guests')
@Controller('app/guests')
@UseGuards(JwtAuthGuard)
export class GuestController {
constructor(private readonly guestService: GuestService) {}
@@ -1,11 +1,11 @@
import { Controller, Get, Param, Query } from '@nestjs/common';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { MerchantService } from './merchant.service';
import { QueryMerchantDto } from './dto/merchant.dto';
import { MerchantService } from '@/modules/merchant/merchant.service';
import { QueryMerchantDto } from '@/modules/merchant/dto/merchant.dto';
@ApiTags('商家')
@Controller('public/merchants')
export class MerchantPublicController {
@Controller('app/merchants')
export class MerchantController {
constructor(private readonly merchantService: MerchantService) {}
@Get()
@@ -19,7 +19,7 @@ import {
} from './dto/order.dto';
@ApiTags('订单(用户)')
@Controller('user/orders')
@Controller('app/orders')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class OrderController {
@@ -6,10 +6,10 @@ import { Order } from '@/entities/order.entity';
import { Room } from '@/entities/room.entity';
import { RoomCalendar } from '@/entities/room-calendar.entity';
import { Review } from '@/entities/review.entity';
import { UserActivityModule } from '@/modules/user/activity/activity.module';
import { ConfigModule } from '@/modules/common/config/config.module';
import { FinanceModule } from '@/modules/common/finance/finance.module';
import { UserCouponModule } from '@/modules/user/coupon/coupon.module';
import { UserActivityModule } from '@/modules/app/activity/activity.module';
import { ConfigModule } from '@/modules/shared/config/config.module';
import { FinanceModule } from '@/modules/shared/finance/finance.module';
import { UserCouponModule } from '@/modules/app/coupon/coupon.module';
@Module({
imports: [
@@ -6,10 +6,10 @@ import { Room } from '@/entities/room.entity';
import { RoomCalendar } from '@/entities/room-calendar.entity';
import { Review } from '@/entities/review.entity';
import { CreateOrderDto, QueryOrderDto } from './dto/order.dto';
import { ActivityService } from '@/modules/user/activity/activity.service';
import { ConfigService } from '@/modules/common/config/config.service';
import { RefundService } from '@/modules/common/finance/refund.service';
import { CouponService } from '@/modules/user/coupon/coupon.service';
import { ActivityService } from '@/modules/app/activity/activity.service';
import { ConfigService } from '@/modules/shared/config/config.service';
import { RefundService } from '@/modules/shared/finance/refund.service';
import { CouponService } from '@/modules/app/coupon/coupon.service';
@Injectable()
export class OrderService {
@@ -20,7 +20,7 @@ import {
} from './dto/user.dto';
@ApiTags('用户信息')
@Controller('user/profile')
@Controller('app/profile')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class ProfileController {
@@ -14,7 +14,7 @@ import { CreateReviewDto, QueryReviewDto } from './dto/review.dto';
import { JwtAuthGuard } from '@/common/guards/jwt-auth.guard';
// 用户端评价接口
@Controller('user/reviews')
@Controller('app/reviews')
export class ReviewController {
constructor(private readonly reviewService: ReviewService) {}
@@ -0,0 +1,56 @@
import { IsOptional, IsInt, IsDateString, Min } from 'class-validator';
import { Type } from 'class-transformer';
import { ApiPropertyOptional } from '@nestjs/swagger';
export class QueryAvailableRoomsDto {
@ApiPropertyOptional({ description: '商家ID' })
@IsOptional()
@Type(() => Number)
@IsInt()
merchantId?: number;
@ApiPropertyOptional({ description: '入住日期', example: '2026-05-15' })
@IsOptional()
@IsDateString()
checkIn?: string;
@ApiPropertyOptional({ description: '退房日期', example: '2026-05-16' })
@IsOptional()
@IsDateString()
checkOut?: string;
@ApiPropertyOptional({ description: '房间数量', default: 1 })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
roomCount?: number;
@ApiPropertyOptional({ description: '成人数量', default: 1 })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
adultCount?: number;
@ApiPropertyOptional({ description: '儿童数量', default: 0 })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(0)
childCount?: number;
@ApiPropertyOptional({ description: '页码', default: 1 })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
page?: number;
@ApiPropertyOptional({ description: '每页数量', default: 10 })
@IsOptional()
@Type(() => Number)
@IsInt()
@Min(1)
pageSize?: number;
}
@@ -0,0 +1,22 @@
import { Controller, Get, Query, Param } from '@nestjs/common';
import { ApiTags, ApiOperation } from '@nestjs/swagger';
import { RoomService } from './room.service';
import { QueryAvailableRoomsDto } from './dto/room.dto';
@ApiTags('房源')
@Controller('app/rooms')
export class RoomController {
constructor(private readonly roomService: RoomService) {}
@Get()
@ApiOperation({ summary: '查询可用房源' })
async findAvailable(@Query() query: QueryAvailableRoomsDto) {
return this.roomService.findAvailable(query);
}
@Get(':id')
@ApiOperation({ summary: '获取房源详情' })
async findOne(@Param('id') id: number) {
return this.roomService.findById(id);
}
}
@@ -0,0 +1,15 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Room } from '@/entities/room.entity';
import { RoomCalendar } from '@/entities/room-calendar.entity';
import { Merchant } from '@/entities/merchant.entity';
import { RoomController } from './room.controller';
import { RoomService } from './room.service';
@Module({
imports: [TypeOrmModule.forFeature([Room, RoomCalendar, Merchant])],
controllers: [RoomController],
providers: [RoomService],
exports: [RoomService],
})
export class RoomModule {}
@@ -0,0 +1,83 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Between, LessThanOrEqual, MoreThanOrEqual } from 'typeorm';
import { Room } from '@/entities/room.entity';
import { RoomCalendar } from '@/entities/room-calendar.entity';
import { QueryAvailableRoomsDto } from './dto/room.dto';
@Injectable()
export class RoomService {
constructor(
@InjectRepository(Room)
private roomRepo: Repository<Room>,
@InjectRepository(RoomCalendar)
private calendarRepo: Repository<RoomCalendar>,
) {}
async findById(id: number) {
const room = await this.roomRepo.findOne({
where: { id: Number(id) },
relations: ['merchant'],
});
if (!room) throw new NotFoundException('房源不存在');
return room;
}
async findAvailable(query: QueryAvailableRoomsDto) {
const {
merchantId,
checkIn,
checkOut,
roomCount = 1,
adultCount = 1,
childCount = 0,
page = 1,
pageSize = 10,
} = query;
const qb = this.roomRepo
.createQueryBuilder('room')
.leftJoinAndSelect('room.merchant', 'merchant')
.where('room.status = :status', { status: 'on_sale' })
.andWhere('room.audit_status = :auditStatus', { auditStatus: 'approved' });
// 按商家筛选
if (merchantId) {
qb.andWhere('room.merchant_id = :merchantId', { merchantId });
}
// 按容纳人数筛选
const totalGuests = adultCount + childCount;
qb.andWhere('room.max_guests >= :totalGuests', { totalGuests });
// 如果提供了日期,检查可用性
if (checkIn && checkOut) {
// 查询在该日期范围内有库存的房间
const availableRoomIds = await this.calendarRepo
.createQueryBuilder('cal')
.select('DISTINCT cal.room_id', 'roomId')
.where('cal.date >= :checkIn', { checkIn })
.andWhere('cal.date < :checkOut', { checkOut })
.andWhere('cal.status = :status', { status: 'available' })
.andWhere('(cal.stock - cal.sold) >= :roomCount', { roomCount })
.groupBy('cal.room_id')
.having('COUNT(*) = DATEDIFF(:checkOut, :checkIn)', { checkIn, checkOut })
.getRawMany();
if (availableRoomIds.length > 0) {
const roomIds = availableRoomIds.map(item => item.roomId);
qb.andWhere('room.id IN (:...roomIds)', { roomIds });
} else {
// 没有可用房间,返回空结果
return { list: [], total: 0, page, pageSize };
}
}
qb.orderBy('room.created_at', 'DESC');
qb.skip((page - 1) * pageSize).take(pageSize);
const [list, total] = await qb.getManyAndCount();
return { list, total, page, pageSize };
}
}
@@ -20,7 +20,7 @@ import {
} from './dto/user.dto';
@ApiTags('用户')
@Controller('user')
@Controller('app')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
export class UserUserController {
@@ -37,6 +37,12 @@ export class MerchantFinanceController {
return account;
}
@Get('wallet')
@ApiOperation({ summary: '获取商家钱包信息' })
async getWallet(@CurrentSeller('sub') sellerId: number) {
return this.getAccount(sellerId);
}
@Get('transactions')
@ApiOperation({ summary: '交易流水列表' })
async getTransactions(
@@ -7,11 +7,11 @@ import {
NotFoundException,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { SettlementService } from './settlement.service';
import { SettlementService } from '@/modules/shared/finance/settlement.service';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { CurrentSeller } from '@/common/decorators/current-seller.decorator';
import { MerchantService } from '@/modules/merchant/merchant.service';
import { QuerySettlementDto } from './dto/settlement.dto';
import { QuerySettlementDto } from '@/modules/shared/finance/dto/settlement.dto';
@ApiTags('结算管理(商家)')
@Controller('merchant/finance/settlements')
@@ -8,10 +8,10 @@ import {
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { CurrentSeller } from '@/common/decorators/current-seller.decorator';
import { TransactionService } from './transaction.service';
import { AccountService } from './account.service';
import { TransactionService } from '@/modules/shared/finance/transaction.service';
import { AccountService } from '@/modules/shared/finance/account.service';
import { MerchantService } from '@/modules/merchant/merchant.service';
import { QueryTransactionDto } from './dto/finance.dto';
import { QueryTransactionDto } from '@/modules/shared/finance/dto/finance.dto';
@ApiTags('交易流水(商家)')
@Controller('merchant/finance/transactions')
@@ -9,14 +9,14 @@ import {
NotFoundException,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { WithdrawalService } from './withdrawal.service';
import { WithdrawalService } from '@/modules/shared/finance/withdrawal.service';
import { SellerJwtAuthGuard } from '@/common/guards/seller-jwt-auth.guard';
import { CurrentSeller } from '@/common/decorators/current-seller.decorator';
import { MerchantService } from '@/modules/merchant/merchant.service';
import {
CreateMerchantWithdrawalDto,
QueryMerchantWithdrawalDto,
} from './dto/withdrawal.dto';
} from '@/modules/shared/finance/dto/withdrawal.dto';
@ApiTags('提现管理(商家)')
@Controller('merchant/finance/withdrawals')
@@ -27,6 +27,12 @@ export class MerchantAdminController {
return this.merchantService.findAll(query);
}
@Get(':id')
@ApiOperation({ summary: '获取商家详情' })
async findById(@Param('id') id: number) {
return this.merchantService.findById(id);
}
@Put(':id/approve')
@ApiOperation({ summary: '审核通过' })
async approve(@Param('id') id: number) {
@@ -17,7 +17,7 @@ import {
} from './dto/merchant.dto';
@ApiTags('商家管理(商家)')
@Controller('seller/merchant')
@Controller('merchant/merchant')
@UseGuards(SellerJwtAuthGuard)
@ApiBearerAuth()
export class MerchantSellerController {
@@ -7,7 +7,6 @@ import { RoomCalendar } from '@/entities/room-calendar.entity';
import { Order } from '@/entities/order.entity';
import { MerchantService } from './merchant.service';
import { StatisticsService } from './statistics.service';
import { MerchantPublicController } from './merchant-public.controller';
import { MerchantSellerController } from './merchant-seller.controller';
import { MerchantAdminController } from './merchant-admin.controller';
import { StatisticsSellerController } from './statistics-seller.controller';
@@ -33,7 +32,6 @@ import { MerchantStatisticsModule } from './statistics/statistics.module';
MerchantStatisticsModule,
],
controllers: [
MerchantPublicController,
MerchantSellerController,
MerchantAdminController,
StatisticsSellerController,
@@ -10,7 +10,7 @@ import { StatisticsService } from './statistics.service';
@ApiBearerAuth()
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('merchant')
@Controller('seller/statistics')
@Controller('merchant/statistics')
export class StatisticsSellerController {
constructor(private readonly statisticsService: StatisticsService) {}
@@ -3,13 +3,11 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { Coupon } from '@/entities/coupon.entity';
import { UserCoupon } from '@/entities/user-coupon.entity';
import { CouponService } from './coupon.service';
import { CouponAdminController } from './coupon-admin.controller';
import { CouponUserController } from './coupon-user.controller';
// 注意:coupon-admin 和 coupon-user controller 已移动到各自模块
@Module({
imports: [TypeOrmModule.forFeature([Coupon, UserCoupon])],
controllers: [CouponAdminController, CouponUserController],
providers: [CouponService],
exports: [CouponService],
exports: [CouponService, TypeOrmModule],
})
export class CouponModule {}
@@ -3,29 +3,34 @@ import { Type } from 'class-transformer';
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
export class QueryTrendDto {
@ApiProperty({ description: '开始日期', example: '2026-05-01' })
@ApiPropertyOptional({ description: '开始日期', example: '2026-05-01' })
@IsOptional()
@IsDateString()
startDate: string;
startDate?: string;
@ApiProperty({ description: '结束日期', example: '2026-05-31' })
@ApiPropertyOptional({ description: '结束日期', example: '2026-05-31' })
@IsOptional()
@IsDateString()
endDate: string;
endDate?: string;
}
export class QueryDailyReportDto {
@ApiProperty({ description: '日期', example: '2026-05-12' })
@ApiPropertyOptional({ description: '日期', example: '2026-05-12' })
@IsOptional()
@IsDateString()
date: string;
date?: string;
}
export class QueryWeeklyReportDto {
@ApiProperty({ description: '开始日期', example: '2026-05-06' })
@ApiPropertyOptional({ description: '开始日期', example: '2026-05-06' })
@IsOptional()
@IsDateString()
startDate: string;
startDate?: string;
@ApiProperty({ description: '结束日期', example: '2026-05-12' })
@ApiPropertyOptional({ description: '结束日期', example: '2026-05-12' })
@IsOptional()
@IsDateString()
endDate: string;
endDate?: string;
}
export class QueryMonthlyReportDto {

Some files were not shown because too many files have changed in this diff Show More