Prechádzať zdrojové kódy

♻️ refactor(docs): 删除旧数据表文档和小程序登录文档

- 删除不再需要的旧数据表文档文件
- 删除已完成的小程序登录实现文档
- 清理项目文档结构,保持整洁
yourname 4 mesiacov pred
rodič
commit
ecb307f2cb

+ 0 - 361
docs/mini-code-login.md

@@ -1,361 +0,0 @@
-基于对现有认证系统的分析,我来为您设计小程序 code-openid 自动注册登录的实现方案。
-
-## 当前系统分析
-
-### 现有认证流程
-1. **用户实体**:包含 `username`, `password`, `phone`, `email`, `nickname` 等字段
-2. **认证方式**:基于用户名+密码的传统登录
-3. **注册流程**:需要手动填写用户名、密码、邮箱
-4. **令牌机制**:JWT Token 认证
-
-### 小程序自动注册登录方案
-
-#### 1. 数据库模型扩展
-
-需要扩展用户实体以支持小程序登录:
-
-```typescript
-// 在 UserEntity 中添加小程序相关字段
-@Entity({ name: 'users' })
-export class UserEntity {
-  // ... 现有字段
-  
-  @Column({ name: 'openid', type: 'varchar', length: 255, nullable: true, unique: true, comment: '微信小程序openid' })
-  openid!: string | null;
-  
-  @Column({ name: 'unionid', type: 'varchar', length: 255, nullable: true, comment: '微信unionid' })
-  unionid!: string | null;
-
-  @Column({ name: 'miniapp_avatar', type: 'varchar', length: 500, nullable: true, comment: '小程序头像URL' })
-  miniappAvatar!: string | null;
-
-  @Column({ name: 'registration_source', type: 'varchar', length: 20, default: 'web', comment: '注册来源: web, miniapp' })
-  registrationSource!: string;
-}
-```
-
-#### 2. 小程序登录服务
-
-创建小程序认证服务:
-
-```typescript
-// src/server/modules/auth/mini-auth.service.ts
-import { DataSource, Repository } from 'typeorm';
-import { UserEntity } from '../users/user.entity';
-import jwt from 'jsonwebtoken';
-import axios from 'axios';
-
-export class MiniAuthService {
-  private userRepository: Repository<UserEntity>;
-  
-  constructor(private dataSource: DataSource) {
-    this.userRepository = dataSource.getRepository(UserEntity);
-  }
-
-  async miniLogin(code: string): Promise<{ token: string; user: UserEntity; isNewUser: boolean }> {
-    // 1. 通过code获取openid
-    const openidInfo = await this.getOpenIdByCode(code);
-    
-    // 2. 查找或创建用户
-    let user = await this.userRepository.findOne({ 
-      where: { openid: openidInfo.openid } 
-    });
-    
-    let isNewUser = false;
-    
-    if (!user) {
-      // 自动注册新用户
-      user = await this.createMiniUser(openidInfo);
-      isNewUser = true;
-    }
-    
-    // 3. 生成token
-    const token = this.generateToken(user);
-    
-    return { token, user, isNewUser };
-  }
-
-  private async getOpenIdByCode(code: string): Promise<{ openid: string; unionid?: string; session_key: string }> {
-    const appId = process.env.WX_MINI_APP_ID!;
-    const appSecret = process.env.WX_MINI_APP_SECRET!;
-    
-    const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${appId}&secret=${appSecret}&js_code=${code}&grant_type=authorization_code`;
-    
-    const response = await axios.get(url);
-    
-    if (response.data.errcode) {
-      throw new Error(`微信API错误: ${response.data.errmsg}`);
-    }
-    
-    return {
-      openid: response.data.openid,
-      unionid: response.data.unionid,
-      session_key: response.data.session_key
-    };
-  }
-
-  private async createMiniUser(openidInfo: { openid: string; unionid?: string }): Promise<UserEntity> {
-    const user = this.userRepository.create({
-      username: `wx_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`,
-      password: '', // 小程序用户不需要密码
-      openid: openidInfo.openid,
-      unionid: openidInfo.unionid,
-      nickname: '微信用户',
-      registrationSource: 'miniapp',
-      isDisabled: 0
-    });
-    
-    return await this.userRepository.save(user);
-  }
-
-  private generateToken(user: UserEntity): string {
-    const payload = {
-      id: user.id,
-      username: user.username,
-      openid: user.openid
-    };
-    return jwt.sign(payload, process.env.JWT_SECRET!, { expiresIn: '7d' });
-  }
-
-  async updateUserProfile(userId: number, profile: { nickname?: string; avatar?: string }): Promise<UserEntity> {
-    const user = await this.userRepository.findOne({ where: { id: userId } });
-    if (!user) throw new Error('用户不存在');
-    
-    if (profile.nickname) user.nickname = profile.nickname;
-    if (profile.avatar) user.miniappAvatar = profile.avatar;
-    
-    return await this.userRepository.save(user);
-  }
-}
-```
-
-#### 3. API路由实现
-
-```typescript
-// src/server/api/auth/mini-login/post.ts
-import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
-import { z } from '@hono/zod-openapi';
-import { MiniAuthService } from '@/server/modules/auth/mini-auth.service';
-import { AppDataSource } from '@/server/data-source';
-import { ErrorSchema } from '@/server/utils/errorHandler';
-
-const MiniLoginSchema = z.object({
-  code: z.string().openapi({
-    example: '08123456789012345678901234567890',
-    description: '小程序登录code'
-  }),
-  userInfo: z.object({
-    nickName: z.string().optional(),
-    avatarUrl: z.string().optional()
-  }).optional()
-});
-
-const MiniLoginResponseSchema = z.object({
-  token: z.string().openapi({
-    example: 'jwt.token.here',
-    description: 'JWT Token'
-  }),
-  user: z.object({
-    id: z.number(),
-    username: z.string(),
-    nickname: z.string().nullable(),
-    avatar: z.string().nullable()
-  }),
-  isNewUser: z.boolean().openapi({
-    example: true,
-    description: '是否为新注册用户'
-  })
-});
-
-const miniLoginRoute = createRoute({
-  method: 'post',
-  path: '/mini-login',
-  request: {
-    body: {
-      content: {
-        'application/json': {
-          schema: MiniLoginSchema
-        }
-      }
-    }
-  },
-  responses: {
-    200: {
-      description: '小程序登录成功',
-      content: {
-        'application/json': {
-          schema: MiniLoginResponseSchema
-        }
-      }
-    },
-    400: {
-      description: '参数错误',
-      content: {
-        'application/json': {
-          schema: ErrorSchema
-        }
-      }
-    }
-  }
-});
-
-const miniAuthService = new MiniAuthService(AppDataSource);
-
-const app = new OpenAPIHono().openapi(miniLoginRoute, async (c) => {
-  try {
-    const { code, userInfo } = c.req.valid('json');
-    
-    const result = await miniAuthService.miniLogin(code);
-    
-    // 如果有用户信息,更新用户资料
-    if (userInfo && result.isNewUser) {
-      await miniAuthService.updateUserProfile(result.user.id, {
-        nickname: userInfo.nickName,
-        avatar: userInfo.avatarUrl
-      });
-    }
-    
-    return c.json({
-      token: result.token,
-      user: {
-        id: result.user.id,
-        username: result.user.username,
-        nickname: result.user.nickname,
-        avatar: result.user.miniappAvatar
-      },
-      isNewUser: result.isNewUser
-    });
-  } catch (error) {
-    return c.json({
-      code: 400,
-      message: error instanceof Error ? error.message : '登录失败'
-    }, 400);
-  }
-});
-
-export default app;
-```
-
-#### 4. 小程序端实现
-
-```typescript
-// mini/src/pages/login/index.tsx
-import { useState } from 'react'
-import Taro from '@tarojs/taro'
-import { View, Text, Button } from '@tarojs/components'
-import { useForm } from 'react-hook-form'
-import { zodResolver } from '@hookform/resolvers/zod'
-import { z } from 'zod'
-
-const miniLoginSchema = z.object({
-  code: z.string(),
-  userInfo: z.object({
-    nickName: z.string(),
-    avatarUrl: z.string()
-  }).optional()
-})
-
-export default function MiniLoginPage() {
-  const [loading, setLoading] = useState(false)
-
-  const handleLogin = async () => {
-    setLoading(true)
-    
-    try {
-      // 1. 获取用户信息
-      const userProfile = await Taro.getUserProfile({
-        desc: '用于完善用户资料'
-      })
-      
-      // 2. 获取登录code
-      const loginRes = await Taro.login()
-      
-      // 3. 调用后端API
-      const response = await Taro.request({
-        url: `${API_BASE_URL}/api/v1/auth/mini-login`,
-        method: 'POST',
-        data: {
-          code: loginRes.code,
-          userInfo: userProfile.userInfo
-        }
-      })
-      
-      if (response.statusCode === 200) {
-        const { token, user, isNewUser } = response.data
-        
-        // 4. 保存token
-        Taro.setStorageSync('token', token)
-        Taro.setStorageSync('userInfo', user)
-        
-        // 5. 跳转到首页
-        Taro.switchTab({ url: '/pages/index/index' })
-        
-        Taro.showToast({
-          title: isNewUser ? '注册成功' : '登录成功',
-          icon: 'success'
-        })
-      }
-    } catch (error) {
-      Taro.showToast({
-        title: '登录失败',
-        icon: 'none'
-      })
-    } finally {
-      setLoading(false)
-    }
-  }
-
-  return (
-    <View className="min-h-screen flex items-center justify-center bg-gray-50">
-      <View className="w-80">
-        <Text className="text-2xl font-bold text-center mb-8">欢迎使用</Text>
-        <Button
-          type="primary"
-          loading={loading}
-          onClick={handleLogin}
-          className="w-full"
-        >
-          微信一键登录
-        </Button>
-      </View>
-    </View>
-  )
-}
-```
-
-#### 5. 环境配置
-
-```bash
-# .env
-WX_MINI_APP_ID=your_mini_app_id
-WX_MINI_APP_SECRET=your_mini_app_secret
-```
-
-#### 6. 路由注册
-
-```typescript
-// src/server/api/auth/index.ts
-import miniLoginRoute from './mini-login/post'
-
-const authRoutes = new OpenAPIHono()
-  .route('/', loginRoute)
-  .route('/', registerRoute)
-  .route('/', miniLoginRoute) // 新增小程序登录路由
-
-export default authRoutes
-```
-
-### 实现步骤总结
-
-1. **数据库迁移**:添加小程序相关字段
-2. **创建服务**:`MiniAuthService` 处理小程序登录逻辑
-3. **创建路由**:添加 `/api/v1/auth/mini-login` 端点
-4. **小程序端**:实现微信登录按钮和API调用
-5. **配置环境**:设置微信小程序的 AppID 和 AppSecret
-
-这个方案实现了:
-- ✅ 自动注册:首次登录自动创建用户
-- ✅ 自动登录:无需输入用户名密码
-- ✅ 用户信息获取:支持获取微信昵称和头像
-- ✅ 向后兼容:不影响现有的用户名密码登录
-- ✅ 安全可靠:使用微信官方API验证用户身份

+ 0 - 2095
docs/roo_task_aug-13-2025_3-14-36-am.md

@@ -1,2095 +0,0 @@
-**User:**
-
-<task>Command 'shadcn-manage-page' (see below for command content) Command 'file-relation' (see below for command content)    Command 'generic-crud' (see below for command content) docs/旧数据表.sql 
-其中 广告,广告类别 已完成
-</task>
-
-<command name="shadcn-manage-page">
-Description: Shadcn-ui 管理页开发指令
-
-## 概述
-基于 `src/client/admin-shadcn/pages/Users.tsx` 中用户管理页的实现,提取可复用的开发模式和最佳实践,适用于基于 Shadcn-ui 的管理后台页面开发。
-
-## 页面结构规范
-
-### 1. 文件位置
-- **管理后台页面**: `src/client/admin-shadcn/pages/[EntityName].tsx`
-
-### 2. 页面组件结构
-```typescript
-// 1. 类型导入和定义
-type CreateRequest = InferRequestType<typeof client.$post>['json'];
-type UpdateRequest = InferRequestType<typeof client[':id']['$put']>['json'];
-type EntityResponse = InferResponseType<typeof client.$get, 200>['data'][0];
-
-// 2. 表单Schema直接使用后端定义
-const createFormSchema = CreateEntityDto;
-const updateFormSchema = UpdateEntityDto;
-
-// 3. 主页面组件
-export const EntityPage = () => {
-  // 状态管理
-  const [searchParams, setSearchParams] = useState({ page: 1, limit: 10, search: '' });
-  const [isModalOpen, setIsModalOpen] = useState(false);
-  const [editingEntity, setEditingEntity] = useState<any>(null);
-  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
-  const [entityToDelete, setEntityToDelete] = useState<number | null>(null);
-  
-  // 表单实例
-  const createForm = useForm<CreateRequest>({...});
-  const updateForm = useForm<UpdateRequest>({...});
-  
-  // 数据查询
-  const { data, isLoading, refetch } = useQuery({...});
-  
-  // 业务逻辑函数
-  const handleSearch = () => {...};
-  const handleCreateEntity = () => {...};
-  const handleEditEntity = () => {...};
-  const handleDeleteEntity = () => {...};
-  
-  // 渲染
-  return (...);
-};
-```
-
-## 核心开发模式
-
-### 1. 类型驱动的开发
-- **RPC类型提取**: 使用 `InferRequestType` 和 `InferResponseType` 从后端API自动提取类型
-- **Schema复用**: 直接使用后端定义的Zod Schema作为表单验证
-- **类型安全**: 所有API调用都有完整的TypeScript类型支持
-
-### 2. 状态管理模式
-```typescript
-// 分页和搜索参数
-const [searchParams, setSearchParams] = useState({
-  page: 1,
-  limit: 10,
-  search: '',
-  // 其他筛选条件...
-});
-
-// 模态框状态
-const [isModalOpen, setIsModalOpen] = useState(false);
-const [editingEntity, setEditingEntity] = useState<any>(null);
-const [isCreateForm, setIsCreateForm] = useState(true);
-```
-
-### 3. 数据获取模式
-```typescript
-const { data, isLoading, refetch } = useQuery({
-  queryKey: ['entities', searchParams],
-  queryFn: async () => {
-    const res = await entityClient.$get({
-      query: {
-        page: searchParams.page,
-        pageSize: searchParams.limit,
-        keyword: searchParams.search,
-        // 其他查询参数...
-      }
-    });
-    if (res.status !== 200) throw new Error('获取列表失败');
-    return await res.json();
-  }
-});
-```
-
-## 页面布局规范
-
-### 1. 页面标题区域
-```tsx
-<div className="flex justify-between items-center">
-  <h1 className="text-2xl font-bold">页面标题</h1>
-  <Button onClick={handleCreateEntity}>
-    <Plus className="mr-2 h-4 w-4" />
-    创建实体
-  </Button>
-</div>
-```
-
-### 2. 搜索区域
-```tsx
-<Card>
-  <CardHeader>
-    <CardTitle>列表标题</CardTitle>
-    <CardDescription>列表描述信息</CardDescription>
-  </CardHeader>
-  <CardContent>
-    <div className="mb-4">
-      <form onSubmit={handleSearch} className="flex gap-2">
-        <div className="relative flex-1 max-w-sm">
-          <Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
-          <Input
-            placeholder="搜索提示..."
-            value={searchParams.search}
-            onChange={(e) => setSearchParams(prev => ({ ...prev, search: e.target.value }))}
-            className="pl-8"
-          />
-        </div>
-        <Button type="submit" variant="outline">
-          搜索
-        </Button>
-      </form>
-    </div>
-  </CardContent>
-</Card>
-```
-
-### 3. 数据表格
-```tsx
-<div className="rounded-md border">
-  <Table>
-    <TableHeader>
-      <TableRow>
-        <TableHead>列标题1</TableHead>
-        <TableHead>列标题2</TableHead>
-        <TableHead className="text-right">操作</TableHead>
-      </TableRow>
-    </TableHeader>
-    <TableBody>
-      {data.map((item) => (
-        <TableRow key={item.id}>
-          <TableCell>{item.field1}</TableCell>
-          <TableCell>{item.field2}</TableCell>
-          <TableCell className="text-right">
-            <div className="flex justify-end gap-2">
-              <Button variant="ghost" size="icon" onClick={() => handleEdit(item)}>
-                <Edit className="h-4 w-4" />
-              </Button>
-              <Button variant="ghost" size="icon" onClick={() => handleDelete(item.id)}>
-                <Trash2 className="h-4 w-4" />
-              </Button>
-            </div>
-          </TableCell>
-        </TableRow>
-      ))}
-    </TableBody>
-  </Table>
-</div>
-```
-
-## 表单开发模式
-
-### 1. 表单组件结构
-```typescript
-// 创建表单
-const createForm = useForm<CreateRequest>({
-  resolver: zodResolver(createFormSchema),
-  defaultValues: {
-    // 默认值设置
-  },
-});
-
-// 更新表单
-const updateForm = useForm<UpdateRequest>({
-  resolver: zodResolver(updateFormSchema),
-  defaultValues: {
-    // 更新时默认值
-  },
-});
-```
-
-### 2. 模态框表单(创建/编辑分离模式)
-```tsx
-<Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
-  <DialogContent className="sm:max-w-[500px] max-h-[90vh] overflow-y-auto">
-    <DialogHeader>
-      <DialogTitle>{isCreateForm ? '创建实体' : '编辑实体'}</DialogTitle>
-      <DialogDescription>
-        {isCreateForm ? '创建一个新的实体' : '编辑现有实体信息'}
-      </DialogDescription>
-    </DialogHeader>
-    
-    {isCreateForm ? (
-      // 创建表单
-      <Form {...createForm}>
-        <form onSubmit={createForm.handleSubmit(handleCreateSubmit)} className="space-y-4">
-          {/* 创建专用字段 */}
-          <DialogFooter>
-            <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
-              取消
-            </Button>
-            <Button type="submit">创建</Button>
-          </DialogFooter>
-        </form>
-      </Form>
-    ) : (
-      // 编辑表单
-      <Form {...updateForm}>
-        <form onSubmit={updateForm.handleSubmit(handleUpdateSubmit)} className="space-y-4">
-          {/* 编辑专用字段 */}
-          <DialogFooter>
-            <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
-              取消
-            </Button>
-            <Button type="submit">更新</Button>
-          </DialogFooter>
-        </form>
-      </Form>
-    )}
-  </DialogContent>
-</Dialog>
-```
-
-### 3. 表单字段模式
-```tsx
-<FormField
-  control={form.control}
-  name="fieldName"
-  render={({ field }) => (
-    <FormItem>
-      <FormLabel className="flex items-center">
-        字段标签
-        {isRequired && <span className="text-red-500 ml-1">*</span>}
-      </FormLabel>
-      <FormControl>
-        <Input placeholder="请输入..." {...field} />
-      </FormControl>
-      <FormDescription>字段描述信息</FormDescription>
-      <FormMessage />
-    </FormItem>
-  )}
-/>
-```
-
-## 图片上传集成
-
-### 1. AvatarSelector组件使用
-```tsx
-<FormField
-  control={form.control}
-  name="avatarFileId"
-  render={({ field }) => (
-    <FormItem>
-      <FormLabel>头像</FormLabel>
-      <FormControl>
-        <AvatarSelector
-          value={field.value || undefined}
-          onChange={(value) => field.onChange(value)}
-          maxSize={2} // MB
-          uploadPath="/avatars"
-          uploadButtonText="上传头像"
-          previewSize="medium"
-          placeholder="选择头像"
-        />
-      </FormControl>
-      <FormMessage />
-    </FormItem>
-  )}
-/>
-```
-
-## 状态管理最佳实践
-
-### 1. 状态提升策略
-- **表单状态**: 使用React Hook Form管理
-- **UI状态**: 使用useState管理模态框、加载状态等
-- **服务器状态**: 使用React Query管理数据获取和缓存
-
-### 2. 数据刷新策略
-```typescript
-// 操作成功后刷新数据
-const handleCreateSubmit = async (data: CreateRequest) => {
-  try {
-    const res = await entityClient.$post({ json: data });
-    if (res.status !== 201) throw new Error('创建失败');
-    toast.success('创建成功');
-    setIsModalOpen(false);
-    refetch(); // 刷新数据
-  } catch (error) {
-    toast.error('操作失败,请重试');
-  }
-};
-```
-
-## 加载状态处理
-
-### 1. 骨架屏模式
-```tsx
-if (isLoading) {
-  return (
-    <div className="space-y-4">
-      <div className="flex justify-between items-center">
-        <h1 className="text-2xl font-bold">页面标题</h1>
-        <Button disabled>
-          <Plus className="mr-2 h-4 w-4" />
-          创建实体
-        </Button>
-      </div>
-      
-      <Card>
-        <CardHeader>
-          <Skeleton className="h-6 w-1/4" />
-        </CardHeader>
-        <CardContent>
-          <div className="space-y-2">
-            <Skeleton className="h-4 w-full" />
-            <Skeleton className="h-4 w-full" />
-            <Skeleton className="h-4 w-full" />
-          </div>
-        </CardContent>
-      </Card>
-    </div>
-  );
-}
-```
-
-### 2. 空数据状态
-```tsx
-{users.length === 0 && !isLoading && (
-  <div className="text-center py-8">
-    <p className="text-muted-foreground">暂无数据</p>
-  </div>
-)}
-```
-
-## 错误处理模式
-
-### 1. API错误处理
-```typescript
-try {
-  const res = await entityClient.$post({ json: data });
-  if (res.status !== 201) throw new Error('操作失败');
-  toast.success('操作成功');
-} catch (error) {
-  console.error('操作失败:', error);
-  toast.error('操作失败,请重试');
-}
-```
-
-### 2. 删除确认模式
-```tsx
-const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
-const [entityToDelete, setEntityToDelete] = useState<number | null>(null);
-
-// 删除确认对话框
-<Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
-  <DialogContent>
-    <DialogHeader>
-      <DialogTitle>确认删除</DialogTitle>
-      <DialogDescription>
-        确定要删除这个实体吗?此操作无法撤销。
-      </DialogDescription>
-    </DialogHeader>
-    <DialogFooter>
-      <Button variant="outline" onClick={() => setDeleteDialogOpen(false)}>
-        取消
-      </Button>
-      <Button variant="destructive" onClick={confirmDelete}>
-        删除
-      </Button>
-    </DialogFooter>
-  </DialogContent>
-</Dialog>
-```
-
-## 样式规范
-
-### 1. 间距系统
-- 页面标题区域: `space-y-4`
-- 卡片内容: `space-y-4`
-- 表单字段: `space-y-4`
-- 按钮组: `gap-2`
-
-### 2. 响应式设计
-- 模态框最大宽度: `sm:max-w-[500px]`
-- 模态框最大高度: `max-h-[90vh]`
-- 搜索输入框: `max-w-sm`
-
-### 3. 视觉层次
-- 标题: `text-2xl font-bold`
-- 卡片标题: `text-lg font-semibold`
-- 描述文字: `text-sm text-muted-foreground`
-
-## 开发流程
-
-### 1. 创建新管理页面
-1. 复制 `Users.tsx` 作为模板
-2. 替换以下部分:
-   - API客户端导入
-   - 类型定义
-   - 表单Schema引用
-   - 页面标题和描述
-   - 表格列定义
-   - 表单字段定义
-3. 根据业务需求调整字段和逻辑
-
-### 2. 字段映射规范
-- **文本字段**: 使用 `Input`
-- **长文本**: 使用 `Textarea`
-- **选择字段**: 使用 `Select`
-- **开关字段**: 使用 `Switch`
-- **日期字段**: 使用 `DatePicker`
-- **图片字段**: 使用 `AvatarSelector`
-
-### 3. 业务逻辑复用
-- 保持相同的CRUD操作模式
-- 复用分页、搜索、排序逻辑
-- 统一的状态管理模式
-- 一致的表单验证和错误处理
-</command>
-
-<command name="file-relation">
-Description: 实体与文件关联开发指令 - 指导如何在实体中添加文件关联字段
-
-# 实体与文件关联开发指令
-
-## 概述
-本指令指导如何在实体中添加与文件管理系统的关联关系,基于用户实体(UserEntity)的最佳实践。
-
-## 文件关联标准实现
-
-### 1. 实体定义规范
-
-在实体类中添加文件关联字段:
-
-```typescript
-// 1. 导入文件实体
-import { File } from '@/server/modules/files/file.entity';
-
-// 2. 在实体类中添加字段
-@Column({ 
-  name: '{field_prefix}_file_id', 
-  type: 'int', 
-  unsigned: true, 
-  nullable: true, 
-  comment: '{描述}文件ID' 
-})
-{fieldPrefix}FileId!: number | null;
-
-@ManyToOne(() => File, { nullable: true })
-@JoinColumn({ 
-  name: '{field_prefix}_file_id', 
-  referencedColumnName: 'id' 
-})
-{fieldPrefix}File!: File | null;
-```
-
-### 2. Schema定义规范
-
-在实体的schema文件中添加文件关联字段:
-
-```typescript
-// 基础字段定义
-{fieldPrefix}FileId: z.number()
-  .int()
-  .positive()
-  .nullable()
-  .openapi({
-    example: 1,
-    description: '{描述}文件ID'
-  }),
-
-// 关联文件对象(用于响应)
-{fieldPrefix}File: z.object({
-  id: z.number().int().positive().openapi({ description: '文件ID' }),
-  name: z.string().max(255).openapi({ description: '文件名', example: 'example.jpg' }),
-  fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/file.jpg' }),
-  type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }),
-  size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
-}).nullable().optional().openapi({
-  description: '{描述}文件信息'
-}),
-```
-
-### 3. 命名规范
-
-| 类型 | 命名格式 | 示例 |
-|------|----------|------|
-| 数据库字段 | `{前缀}_file_id` | `avatar_file_id` |
-| 实体字段 | `{前缀}FileId` | `avatarFileId` |
-| 关联实体 | `{前缀}File` | `avatarFile` |
-| 描述注释 | `{描述}文件ID` | `头像文件ID` |
-
-### 4. 完整示例 - 基于用户实体
-
-**实体类** ([`src/server/modules/users/user.entity.ts`](src/server/modules/users/user.entity.ts:29-34)):
-```typescript
-@Column({ name: 'avatar_file_id', type: 'int', unsigned: true, nullable: true, comment: '头像文件ID' })
-avatarFileId!: number | null;
-
-@ManyToOne(() => File, { nullable: true })
-@JoinColumn({ name: 'avatar_file_id', referencedColumnName: 'id' })
-avatarFile!: File | null;
-```
-
-**Schema定义** ([`src/server/modules/users/user.schema.ts`](src/server/modules/users/user.schema.ts:33-45)):
-```typescript
-avatarFileId: z.number().int().positive().nullable().openapi({
-  example: 1,
-  description: '头像文件ID'
-}),
-avatarFile: z.object({
-  id: z.number().int().positive().openapi({ description: '文件ID' }),
-  name: z.string().max(255).openapi({ description: '文件名', example: 'avatar.jpg' }),
-  fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/avatar.jpg' }),
-  type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }),
-  size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
-}).nullable().optional().openapi({
-  description: '头像文件信息'
-}),
-```
-
-## 使用步骤
-
-### 步骤1: 添加实体字段
-1. 在实体类中添加 `{prefix}FileId` 和 `{prefix}File` 字段
-2. 使用 `@ManyToOne` 关联 `File` 实体
-3. 配置 `@JoinColumn` 指定外键字段名
-
-### 步骤2: 添加Schema定义
-1. 在 `Create{Entity}Dto` 中添加 `{prefix}FileId` 字段
-2. 在 `Update{Entity}Dto` 中添加可选的 `{prefix}FileId` 字段
-3. 在实体Schema中添加 `{prefix}File` 对象用于响应
-
-### 步骤3: 数据库迁移
-确保数据库表包含 `{prefix}_file_id` 字段,类型为 INT UNSIGNED NULL
-
-## 使用场景
-
-### 场景1: 单文件关联
-适用于实体只需要关联单个文件的情况,如:
-- 用户头像
-- 商品封面图
-- 文档附件
-
-### 场景2: 多文件关联
-如需关联多个文件,请使用 ManyToMany 关联,参考广告实体的实现。
-
-## 注意事项
-
-1. **空值处理**: 字段必须支持 `null`,允许无文件关联
-2. **级联操作**: 默认不级联,删除文件不会影响关联实体
-3. **文件验证**: 前端需先上传文件获取文件ID,再进行实体关联
-4. **类型安全**: 确保所有字段类型定义一致(number | null)
-
-## 扩展说明
-
-此标准基于用户实体的头像文件关联实现,适用于项目中所有需要文件关联的实体。后续实体按此标准实现即可保持统一性。
-</command>
-
-<command name="generic-crud">
-Description: 通用curd开发指令
-
-按通用curd开发规范开发
-
-创建实体类 your-entity.entity.ts
-创建实体Zod Schema定义 your-entity.schema.ts
-注册实体到数据源
-创建服务类继承GenericCrudService
-创建通用CRUD路由
-注册路由到API
-创建客户端API调用方法
-创建管理后台页面,按照 .roo/commands/shadcn-manage-form.md 指令规范
-注册路由和菜单
-</command>
-<environment_details>
-# VSCode Visible Files
-docs/旧数据表.sql
-
-# VSCode Open Tabs
-docs/旧数据表.sql
-
-# Current Time
-Current time in ISO 8601 UTC format: 2025-08-13T03:09:12.332Z
-User time zone: UTC, UTC+0:00
-
-# Current Cost
-$0.00
-
-# Current Mode
-<slug>code</slug>
-<name>💻 代码</name>
-<model>d8d-ai-model</model>
-
-
-# Current Workspace Directory (/mnt/code/161-145-template-10) Files
-.gitignore
-.npmrc
-🔒 .rooignore
-components.json
-docker-compose.yml
-Dockerfile.release
-Dockerfile.test
-index.html
-🔒 .gitea/
-.roo/
-docs/
-docs/mini-code-login.md
-docs/tailwind-merge.md
-docs/旧数据表.sql
-mini/
-mini/.husky/
-mini/config/
-mini/src/
-mini/src/components/
-mini/src/components/ui/
-mini/src/layouts/
-mini/src/pages/
-mini/src/pages/explore/
-mini/src/pages/index/
-mini/src/pages/login/
-mini/src/pages/profile/
-mini/src/pages/register/
-mini/src/schemas/
-mini/src/utils/
-mini/types/
-mini-starter/
-mini-starter/package.json
-mini-starter/pnpm-lock.yaml
-mini-starter/server.js
-🔒 mini-starter/.gitea/
-mini-starter/.roo/
-mini-starter/docs/
-mini-starter/docs/前台页面/
-mini-starter/docs/后台服务/
-mini-starter/docs/小程序/
-mini-starter/docs/旧代码/
-mini-starter/mini/
-mini-starter/mini/stylelint.config.mjs
-mini-starter/mini/tailwind.config.js
-mini-starter/mini/tsconfig.json
-mini-starter/mini/.husky/
-mini-starter/mini/config/
-mini-starter/mini/src/
-mini-starter/mini/src/components/
-mini-starter/mini/src/components/ui/
-mini-starter/mini/src/layouts/
-mini-starter/mini/src/pages/
-mini-starter/mini/src/pages/duihuan/
-mini-starter/mini/src/pages/explore/
-mini-starter/mini/src/pages/index/
-mini-starter/mini/src/pages/login/
-mini-starter/mini/src/pages/profile/
-mini-starter/mini/src/pages/register/
-mini-starter/mini/src/schemas/
-mini-starter/mini/src/utils/
-mini-starter/mini/types/
-mini-starter/public/
-mini-starter/public/vite.svg
-🔒 mini-starter/scripts/
-🔒 mini-starter/scripts/release_tag.sh
-mini-starter/src/
-mini-starter/src/assets/
-mini-starter/src/assets/react.svg
-mini-starter/src/client/
-mini-starter/src/client/api.ts
-mini-starter/src/client/index.tsx
-mini-starter/src/client/admin-shadcn/
-mini-starter/src/client/admin-shadcn/routes.tsx
-mini-starter/src/client/admin-shadcn/components/
-mini-starter/src/client/admin-shadcn/hooks/
-mini-starter/src/client/admin-shadcn/layouts/
-mini-starter/src/client/admin-shadcn/pages/
-mini-starter/src/client/admin-shadcn/pages/Advertisements.tsx
-mini-starter/src/client/admin-shadcn/pages/CouponLogs.tsx
-mini-starter/src/client/admin-shadcn/pages/Dashboard.tsx
-mini-starter/src/client/admin-shadcn/pages/Files.tsx
-mini-starter/src/client/admin-shadcn/pages/Login.tsx
-mini-starter/src/client/admin-shadcn/pages/RedemptionCodes.tsx
-mini-starter/src/client/admin-shadcn/pages/Users.tsx
-mini-starter/src/client/admin-shadcn/pages/WechatCoupons.tsx
-mini-starter/src/client/admin-shadcn/pages/WechatCouponStocks.tsx
-mini-starter/src/client/admin-shadcn/pages/WechatPayConfig.tsx
-mini-starter/src/client/components/
-mini-starter/src/client/components/ui/
-mini-starter/src/client/components/ui/slider.tsx
-mini-starter/src/client/components/ui/sonner.tsx
-mini-starter/src/client/components/ui/switch.tsx
-mini-starter/src/client/components/ui/table.tsx
-mini-starter/src/client/components/ui/tabs.tsx
-mini-starter/src/client/components/ui/textarea.tsx
-mini-starter/src/client/components/ui/toggle-group.tsx
-mini-starter/src/client/components/ui/toggle.tsx
-mini-starter/src/client/components/ui/tooltip.tsx
-mini-starter/src/client/home-shadcn/
-mini-starter/src/client/home-shadcn/routes.tsx
-mini-starter/src/client/home-shadcn/components/
-mini-starter/src/client/home-shadcn/hooks/
-mini-starter/src/client/home-shadcn/layouts/
-mini-starter/src/client/home-shadcn/pages/
-mini-starter/src/client/home-shadcn/pages/HomePage.tsx
-mini-starter/src/client/home-shadcn/pages/LoginPage.tsx
-mini-starter/src/client/home-shadcn/pages/MemberPage.tsx
-mini-starter/src/client/home-shadcn/pages/RegisterPage.tsx
-mini-starter/src/client/hooks/
-mini-starter/src/client/hooks/use-mobile.ts
-mini-starter/src/client/lib/
-mini-starter/src/client/lib/utils.ts
-mini-starter/src/client/utils/
-mini-starter/src/client/utils/axios-fetch.ts
-mini-starter/src/client/utils/ClientOnly.tsx
-mini-starter/src/client/utils/logger.ts
-mini-starter/src/server/
-mini-starter/src/server/api/
-mini-starter/src/server/api/advertisements/
-mini-starter/src/server/api/auth/
-mini-starter/src/server/api/auth/login/
-mini-starter/src/server/api/auth/me/
-mini-starter/src/server/api/auth/mini-login/
-mini-starter/src/server/api/auth/register/
-mini-starter/src/server/api/coupon-logs/
-mini-starter/src/server/api/files/
-mini-starter/src/server/api/files/[id]/
-mini-starter/src/server/api/files/multipart-complete/
-mini-starter/src/server/api/files/multipart-policy/
-mini-starter/src/server/api/files/upload-policy/
-mini-starter/src/server/api/public/
-mini-starter/src/server/api/public/advertisements/
-mini-starter/src/server/api/public/wechat-coupon-stocks/
-mini-starter/src/server/api/redemption-codes/
-mini-starter/src/server/api/roles/
-mini-starter/src/server/api/users/
-mini-starter/src/server/api/users/[id]/
-mini-starter/src/server/api/wechat-coupon-stocks/
-mini-starter/src/server/api/wechat-coupons/
-mini-starter/src/server/api/wechat-pay/
-mini-starter/src/server/api/wechat-pay/actions/
-mini-starter/src/server/api/wechat-pay-config/
-mini-starter/src/server/middleware/
-mini-starter/src/server/modules/
-mini-starter/src/server/modules/advertisements/
-mini-starter/src/server/modules/auth/
-mini-starter/src/server/modules/coupon-logs/
-mini-starter/src/server/modules/files/
-mini-starter/src/server/modules/redemption-codes/
-mini-starter/src/server/modules/users/
-mini-starter/src/server/modules/wechat-pay/
-mini-starter/src/server/types/
-mini-starter/src/server/utils/
-mini-starter/src/share/
-public/
-🔒 scripts/
-src/
-src/assets/
-src/client/
-src/client/admin-shadcn/
-src/client/admin-shadcn/components/
-src/client/admin-shadcn/hooks/
-src/client/admin-shadcn/layouts/
-src/client/admin-shadcn/pages/
-src/client/components/
-src/client/components/ui/
-src/client/home-shadcn/
-src/client/home-shadcn/components/
-src/client/home-shadcn/hooks/
-src/client/home-shadcn/layouts/
-src/client/home-shadcn/pages/
-src/client/hooks/
-src/client/lib/
-src/client/utils/
-src/server/
-src/server/api/
-src/server/api/advertisement-types/
-src/server/api/advertisements/
-src/server/api/auth/
-src/server/api/auth/login/
-src/server/api/auth/me/
-src/server/api/auth/mini-login/
-src/server/api/auth/register/
-src/server/api/files/
-src/server/api/files/[id]/
-src/server/api/files/multipart-complete/
-src/server/api/files/multipart-policy/
-src/server/api/files/upload-policy/
-src/server/api/roles/
-src/server/api/users/
-src/server/api/users/[id]/
-src/server/middleware/
-src/server/modules/
-src/server/modules/advertisements/
-src/server/modules/auth/
-src/server/modules/files/
-src/server/modules/users/
-src/server/types/
-src/server/utils/
-src/share/
-
-(File list truncated. Use list_files on specific subdirectories if you need to explore further.)
-You have not created a todo list yet. Create one with `update_todo_list` if your task is complicated or involves multiple steps.
-</environment_details>
-
----
-
-**Assistant:**
-
-我需要分析现有的旧数据表结构,然后基于通用CRUD规范创建相应的实体和API。让我先查看旧数据表的内容。
-
-<read_file>
-<path>docs/旧数据表.sql</path>
-</read_file>
-
----
-
-**User:**
-
-[read_file for 'docs/旧数据表.sql'. Reading multiple files at once is more efficient for the LLM. If other files are relevant to your current task, please read them simultaneously.] Result:
-<files>
-<file><path>docs/旧数据表.sql</path>
-<content lines="1-528">
-  1 | 
-  2 | DROP TABLE IF EXISTS `ad`;
-  3 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-  4 | /*!50503 SET character_set_client = utf8mb4 */;
-  5 | CREATE TABLE `ad` (
-  6 |   `id` int unsigned NOT NULL AUTO_INCREMENT,
-  7 |   `title` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '标题',
-  8 |   `type_id` int DEFAULT NULL COMMENT '广告类型',
-  9 |   `code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '调用别名',
- 10 |   `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'url',
- 11 |   `img` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '图片',
- 12 |   `sort` int DEFAULT '0' COMMENT '排序',
- 13 |   `create_time` int DEFAULT NULL COMMENT '创建时间',
- 14 |   `update_time` int DEFAULT '0' COMMENT '更新时间',
- 15 |   `status` int unsigned DEFAULT '0' COMMENT '状态',
- 16 |   `action_type` int DEFAULT '1' COMMENT '跳转类型 0 不跳转 1webview 2小程序页面',
- 17 |   PRIMARY KEY (`id`) USING BTREE
- 18 | ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='广告';
- 19 | /*!40101 SET character_set_client = @saved_cs_client */;
- 20 | 
- 21 | --
- 22 | -- Dumping data for table `ad`
- 23 | --
- 24 | 
- 25 | --
- 26 | -- Table structure for table `ad_type`
- 27 | --
- 28 | 
- 29 | DROP TABLE IF EXISTS `ad_type`;
- 30 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
- 31 | /*!50503 SET character_set_client = utf8mb4 */;
- 32 | CREATE TABLE `ad_type` (
- 33 |   `id` int unsigned NOT NULL AUTO_INCREMENT,
- 34 |   `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '类型名称',
- 35 |   `code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '调用别名',
- 36 |   `remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
- 37 |   `create_time` int unsigned DEFAULT NULL COMMENT '创建时间',
- 38 |   `update_time` int unsigned DEFAULT NULL COMMENT '更新时间',
- 39 |   `status` int DEFAULT '0' COMMENT '状态',
- 40 |   PRIMARY KEY (`id`) USING BTREE
- 41 | ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='广告类型';
- 42 | /*!40101 SET character_set_client = @saved_cs_client */;
- 43 | 
- 44 | --
- 45 | -- Dumping data for table `ad_type`
- 46 | --
- 47 | 
- 48 | 
- 49 | --
- 50 | -- Dumping data for table `agent`
- 51 | --
- 52 | 
- 53 | 
- 54 | --
- 55 | -- Table structure for table `card`
- 56 | --
- 57 | 
- 58 | DROP TABLE IF EXISTS `card`;
- 59 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
- 60 | /*!50503 SET character_set_client = utf8mb4 */;
- 61 | CREATE TABLE `card` (
- 62 |   `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
- 63 |   `agent_id` int DEFAULT NULL,
- 64 |   `card_type` int DEFAULT NULL COMMENT '1盛京通卡 2通用联名电子卡',
- 65 |   `card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '卡号',
- 66 |   `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
- 67 |   `create_time` int unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
- 68 |   `update_time` int unsigned NOT NULL DEFAULT '0' COMMENT '修改时间',
- 69 |   `state` int unsigned NOT NULL DEFAULT '1' COMMENT '状态 1绑定 2解绑 通用联名电子卡不可解绑',
- 70 |   `face_value` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '面值',
- 71 |   PRIMARY KEY (`id`) USING BTREE,
- 72 |   UNIQUE KEY `card_no` (`card_no`) USING BTREE
- 73 | ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='卡';
- 74 | /*!40101 SET character_set_client = @saved_cs_client */;
- 75 | 
- 76 | --
- 77 | -- Dumping data for table `card`
- 78 | --
- 79 | 
- 80 | 
- 81 | --
- 82 | -- Table structure for table `category`
- 83 | --
- 84 | 
- 85 | DROP TABLE IF EXISTS `category`;
- 86 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
- 87 | /*!50503 SET character_set_client = utf8mb4 */;
- 88 | CREATE TABLE `category` (
- 89 |   `id` int NOT NULL AUTO_INCREMENT COMMENT '类别id',
- 90 |   `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '类别名称',
- 91 |   `parent_id` int DEFAULT '0' COMMENT '上级id',
- 92 |   `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分类图片',
- 93 |   `level` int DEFAULT '0' COMMENT '层级',
- 94 |   `state` int DEFAULT '1' COMMENT '状态1可用2不可用',
- 95 |   PRIMARY KEY (`id`) USING BTREE
- 96 | ) ENGINE=InnoDB AUTO_INCREMENT=777709 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='分类表';
- 97 | /*!40101 SET character_set_client = @saved_cs_client */;
- 98 | 
- 99 | --
-100 | -- Dumping data for table `category`
-101 | --
-102 | 
-103 | 
-104 | --
-105 | -- Table structure for table `city`
-106 | --
-107 | 
-108 | DROP TABLE IF EXISTS `city`;
-109 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-110 | /*!50503 SET character_set_client = utf8mb4 */;
-111 | CREATE TABLE `city` (
-112 |   `id` bigint DEFAULT NULL COMMENT '地区id',
-113 |   `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '地区名称',
-114 |   `level` int DEFAULT '0' COMMENT '层级省市区县1,2,3,4',
-115 |   `parent_id` bigint DEFAULT '0' COMMENT '上级id',
-116 |   `state` int DEFAULT '1' COMMENT '状态1可用',
-117 |   `sort` int DEFAULT '0' COMMENT '排序数值越大越靠前'
-118 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='省、市、区、街道';
-119 | /*!40101 SET character_set_client = @saved_cs_client */;
-120 | 
-121 | --
-122 | -- Dumping data for table `city`
-123 | --
-124 | 
-125 | --
-126 | -- Table structure for table `config`
-127 | --
-128 | 
-129 | DROP TABLE IF EXISTS `config`;
-130 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-131 | /*!50503 SET character_set_client = utf8mb4 */;
-132 | CREATE TABLE `config` (
-133 |   `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-134 |   `key` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '名称',
-135 |   `value` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '值',
-136 |   `state` int DEFAULT '2' COMMENT '状态 1可用 2禁用',
-137 |   PRIMARY KEY (`id`),
-138 |   UNIQUE KEY `key_state` (`key`,`state`) USING BTREE COMMENT 'key_state唯一'
-139 | ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-140 | /*!40101 SET character_set_client = @saved_cs_client */;
-141 | 
-142 | --
-143 | -- Dumping data for table `config`
-144 | --
-145 | 
-146 | 
-147 | --
-148 | -- Table structure for table `delivery_address`
-149 | --
-150 | 
-151 | DROP TABLE IF EXISTS `delivery_address`;
-152 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-153 | /*!50503 SET character_set_client = utf8mb4 */;
-154 | CREATE TABLE `delivery_address` (
-155 |   `id` int NOT NULL AUTO_INCREMENT COMMENT '收货地址id',
-156 |   `user_id` int DEFAULT '0' COMMENT '用户id',
-157 |   `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
-158 |   `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '手机号',
-159 |   `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '详细地址',
-160 |   `receiver_province` bigint DEFAULT '0' COMMENT '省',
-161 |   `receiver_city` bigint DEFAULT '0' COMMENT '市',
-162 |   `receiver_district` bigint DEFAULT '0' COMMENT '区',
-163 |   `receiver_town` bigint DEFAULT '0' COMMENT '街道',
-164 |   `state` int DEFAULT '1' COMMENT '是否可用1正常2禁用3删除(不显示)',
-165 |   `is_default` int DEFAULT '0' COMMENT '是否常用1是 2否',
-166 |   PRIMARY KEY (`id`) USING BTREE
-167 | ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='用户收货地址表';
-168 | /*!40101 SET character_set_client = @saved_cs_client */;
-169 | 
-170 | --
-171 | -- Dumping data for table `delivery_address`
-172 | --
-173 | 
-174 | 
-175 | 
-176 | --
-177 | -- Table structure for table `express_company`
-178 | --
-179 | 
-180 | DROP TABLE IF EXISTS `express_company`;
-181 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-182 | /*!50503 SET character_set_client = utf8mb4 */;
-183 | CREATE TABLE `express_company` (
-184 |   `id` int NOT NULL AUTO_INCREMENT COMMENT '表序号',
-185 |   `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '物流公司名称',
-186 |   `code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '物流编号',
-187 |   `state` int NOT NULL DEFAULT '1' COMMENT '使用状态 1可用 2禁用',
-188 |   `sort` int DEFAULT NULL COMMENT '优先级 值越大越优先',
-189 |   PRIMARY KEY (`id`) USING BTREE
-190 | ) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci AVG_ROW_LENGTH=420 ROW_FORMAT=COMPACT COMMENT='物流公司';
-191 | /*!40101 SET character_set_client = @saved_cs_client */;
-192 | 
-193 | --
-194 | -- Dumping data for table `express_company`
-195 | --
-196 | 
-197 | 
-198 | --
-199 | -- Table structure for table `goods`
-200 | --
-201 | 
-202 | DROP TABLE IF EXISTS `goods`;
-203 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-204 | /*!50503 SET character_set_client = utf8mb4 */;
-205 | CREATE TABLE `goods` (
-206 |   `id` int NOT NULL AUTO_INCREMENT,
-207 |   `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品名称',
-208 |   `price` decimal(10,2) DEFAULT '0.00' COMMENT '售卖价',
-209 |   `cost_price` decimal(10,2) DEFAULT '0.00' COMMENT '成本价',
-210 |   `sales_num` bigint DEFAULT '0' COMMENT '销售数量',
-211 |   `click_num` bigint DEFAULT '0' COMMENT '点击次数',
-212 |   `category_id1` int DEFAULT '0' COMMENT '一级类别id',
-213 |   `category_id2` int DEFAULT '0' COMMENT '二级类别id',
-214 |   `category_id3` int DEFAULT '0' COMMENT '三级类别id',
-215 |   `goods_type` int DEFAULT '1' COMMENT '订单类型 1实物产品 2虚拟产品',
-216 |   `supplier_id` int DEFAULT NULL COMMENT '所属供应商id',
-217 |   `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品主图',
-218 |   `slide_image` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品轮播(多个用,隔开)',
-219 |   `detail` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '商品详情',
-220 |   `instructions` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '简介',
-221 |   `sort` int DEFAULT '0' COMMENT '排序',
-222 |   `state` int DEFAULT '1' COMMENT '状态1可用2不可用',
-223 |   `stock` bigint DEFAULT '0' COMMENT '库存',
-224 |   `spu_id` int DEFAULT '0' COMMENT '主商品ID',
-225 |   `spu_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '主商品名称',
-226 |   `lowest_buy` int DEFAULT '1' COMMENT '最小起购量',
-227 |   `create_time` int DEFAULT '0' COMMENT '创建时间',
-228 |   `update_time` int DEFAULT '0' COMMENT '修改时间',
-229 |   PRIMARY KEY (`id`) USING BTREE
-230 | ) ENGINE=InnoDB AUTO_INCREMENT=10007 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='商品表';
-231 | /*!40101 SET character_set_client = @saved_cs_client */;
-232 | 
-233 | --
-234 | -- Dumping data for table `goods`
-235 | --
-236 | 
-237 | 
-238 | 
-239 | --
-240 | -- Table structure for table `merchant`
-241 | --
-242 | 
-243 | DROP TABLE IF EXISTS `merchant`;
-244 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-245 | /*!50503 SET character_set_client = utf8mb4 */;
-246 | CREATE TABLE `merchant` (
-247 |   `id` int unsigned NOT NULL AUTO_INCREMENT,
-248 |   `number` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '编号',
-249 |   `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '名称',
-250 |   `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
-251 |   `salt` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '随机码',
-252 |   `login_num` int DEFAULT '0' COMMENT '登录次数',
-253 |   `login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '登录时间',
-254 |   `login_ip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '登录ip',
-255 |   `last_login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '上次登录时间',
-256 |   `last_login_ip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上次登录ip',
-257 |   `rsa_public_key` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公钥',
-258 |   `aes_key` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'aes秘钥',
-259 |   `create_time` int unsigned DEFAULT NULL COMMENT '创建时间',
-260 |   `update_time` int unsigned DEFAULT '0' COMMENT '修改时间',
-261 |   `state` int DEFAULT NULL COMMENT '状态 1可用 2禁用',
-262 |   PRIMARY KEY (`id`) USING BTREE,
-263 |   UNIQUE KEY `number` (`number`) USING BTREE
-264 | ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='商户';
-265 | /*!40101 SET character_set_client = @saved_cs_client */;
-266 | 
-267 | --
-268 | -- Dumping data for table `merchant`
-269 | --
-270 | 
-271 | 
-272 | 
-273 | --
-274 | -- Table structure for table `orders`
-275 | --
-276 | 
-277 | DROP TABLE IF EXISTS `orders`;
-278 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-279 | /*!50503 SET character_set_client = utf8mb4 */;
-280 | CREATE TABLE `orders` (
-281 |   `id` int NOT NULL AUTO_INCREMENT COMMENT '订单id',
-282 |   `order_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单号',
-283 |   `user_id` int DEFAULT '0' COMMENT '用户ID',
-284 |   `auth_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '付款码',
-285 |   `card_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '卡号',
-286 |   `sjt_card_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '盛京通卡号',
-287 |   `amount` decimal(10,2) DEFAULT '0.00' COMMENT '订单金额',
-288 |   `cost_amount` decimal(10,2) DEFAULT '0.00' COMMENT '成本金额',
-289 |   `freight_amount` decimal(10,2) DEFAULT '0.00' COMMENT '运费',
-290 |   `discount_amount` decimal(10,2) DEFAULT '0.00' COMMENT '优惠金额',
-291 |   `pay_amount` decimal(10,2) DEFAULT '0.00' COMMENT '实际支付金额',
-292 |   `device_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '设备编号',
-293 |   `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单描述',
-294 |   `goods_detail` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单详情 json',
-295 |   `goods_tag` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单优惠标记',
-296 |   `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '地址',
-297 |   `order_type` int DEFAULT '1' COMMENT '订单类型 1实物订单 2虚拟订单',
-298 |   `pay_type` int DEFAULT '0' COMMENT '支付类型1积分2礼券',
-299 |   `pay_state` int DEFAULT '0' COMMENT '0未支付1支付中2支付成功3已退款4支付失败5订单关闭',
-300 |   `state` int DEFAULT '0' COMMENT '订单状态0未发货1已发货2收货成功3已退货',
-301 |   `user_phone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户手机号',
-302 |   `merchant_id` int DEFAULT '0' COMMENT '商户id',
-303 |   `merchant_no` int DEFAULT NULL COMMENT '商户号',
-304 |   `supplier_id` int DEFAULT '0' COMMENT '供货商id',
-305 |   `address_id` int DEFAULT '0' COMMENT '地址id',
-306 |   `receiver_mobile` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '收货人手机号',
-307 |   `recevier_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '收货人姓名',
-308 |   `recevier_province` bigint DEFAULT '0' COMMENT '收货人所在省',
-309 |   `recevier_city` bigint DEFAULT '0' COMMENT '收货人所在市',
-310 |   `recevier_district` bigint DEFAULT '0' COMMENT '收货人所在区',
-311 |   `recevier_town` bigint DEFAULT '0' COMMENT '收货人所在街道',
-312 |   `create_time` int DEFAULT '0' COMMENT '创建时间',
-313 |   `update_time` int DEFAULT '0' COMMENT '更新时间',
-314 |   `refund_time` int DEFAULT '0' COMMENT '退款时间',
-315 |   `close_time` int DEFAULT '0' COMMENT '订单关闭时间',
-316 |   `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '管理员备注信息',
-317 |   PRIMARY KEY (`id`) USING BTREE,
-318 |   UNIQUE KEY `order_no` (`order_no`) USING BTREE COMMENT '订单号唯一'
-319 | ) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='订单表';
-320 | /*!40101 SET character_set_client = @saved_cs_client */;
-321 | 
-322 | --
-323 | -- Dumping data for table `orders`
-324 | --
-325 | 
-326 | 
-327 | 
-328 | --
-329 | -- Table structure for table `orders_goods`
-330 | --
-331 | 
-332 | DROP TABLE IF EXISTS `orders_goods`;
-333 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-334 | /*!50503 SET character_set_client = utf8mb4 */;
-335 | CREATE TABLE `orders_goods` (
-336 |   `id` int NOT NULL AUTO_INCREMENT COMMENT '订单商品表id',
-337 |   `order_id` int DEFAULT '0' COMMENT '订单表id',
-338 |   `order_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单号',
-339 |   `goods_id` int DEFAULT '0' COMMENT '商品id',
-340 |   `goods_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品名称',
-341 |   `goods_image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品图片',
-342 |   `goods_type` int DEFAULT '1' COMMENT '1实物产品2虚拟订单',
-343 |   `supplier_id` int DEFAULT '0' COMMENT '供货商id',
-344 |   `cost_price` decimal(10,2) DEFAULT '0.00' COMMENT '成本价',
-345 |   `price` decimal(10,2) DEFAULT '0.00' COMMENT '售价',
-346 |   `num` int DEFAULT '0' COMMENT '数量',
-347 |   `freight_amount` decimal(10,2) DEFAULT '0.00' COMMENT '运费',
-348 |   `state` int DEFAULT '0' COMMENT '状态(0未发货、1已发货)',
-349 |   `express_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '快递名称',
-350 |   `express_no` int DEFAULT NULL COMMENT '单号',
-351 |   `create_time` int DEFAULT '0' COMMENT '创建时间',
-352 |   `update_time` int DEFAULT '0' COMMENT '修改时间',
-353 |   PRIMARY KEY (`id`) USING BTREE
-354 | ) ENGINE=InnoDB AUTO_INCREMENT=97 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='订单商品表';
-355 | /*!40101 SET character_set_client = @saved_cs_client */;
-356 | 
-357 | --
-358 | -- Dumping data for table `orders_goods`
-359 | --
-360 | 
-361 | 
-362 | 
-363 | --
-364 | -- Table structure for table `orders_refund`
-365 | --
-366 | 
-367 | DROP TABLE IF EXISTS `orders_refund`;
-368 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-369 | /*!50503 SET character_set_client = utf8mb4 */;
-370 | CREATE TABLE `orders_refund` (
-371 |   `id` int NOT NULL COMMENT 'id',
-372 |   `order_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单号',
-373 |   `refund_order_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '退款订单号',
-374 |   `refund_amount` decimal(10,2) DEFAULT NULL COMMENT '退款金额',
-375 |   `create_time` int DEFAULT NULL COMMENT '退款时间',
-376 |   `update_time` int DEFAULT NULL COMMENT '更新时间',
-377 |   `state` int DEFAULT NULL COMMENT '0未退款1退款中2退款成功3退款失败',
-378 |   PRIMARY KEY (`id`) USING BTREE,
-379 |   UNIQUE KEY `refund_order_no` (`refund_order_no`) USING BTREE COMMENT 'refund_order_no'
-380 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='退款';
-381 | /*!40101 SET character_set_client = @saved_cs_client */;
-382 | 
-383 | --
-384 | -- Dumping data for table `orders_refund`
-385 | --
-386 | 
-387 | 
-388 | --
-389 | -- Table structure for table `organization`
-390 | --
-391 | 
-392 | DROP TABLE IF EXISTS `organization`;
-393 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-394 | /*!50503 SET character_set_client = utf8mb4 */;
-395 | CREATE TABLE `organization` (
-396 |   `id` int NOT NULL AUTO_INCREMENT COMMENT '分行网点id',
-397 |   `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分行网点名称',
-398 |   `parent_id` int DEFAULT '0' COMMENT '上级id',
-399 |   `level` int DEFAULT '4' COMMENT '层级',
-400 |   `create_time` int DEFAULT '0' COMMENT '床渐渐时间',
-401 |   `update_time` int DEFAULT '0' COMMENT '修改时间',
-402 |   `state` int DEFAULT '1' COMMENT '状态1可用2不可用',
-403 |   PRIMARY KEY (`id`) USING BTREE
-404 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='组织架构表';
-405 | /*!40101 SET character_set_client = @saved_cs_client */;
-406 | 
-407 | --
-408 | -- Dumping data for table `organization`
-409 | --
-410 | 
-411 | 
-412 | --
-413 | -- Table structure for table `supplier`
-414 | --
-415 | 
-416 | DROP TABLE IF EXISTS `supplier`;
-417 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-418 | /*!50503 SET character_set_client = utf8mb4 */;
-419 | CREATE TABLE `supplier` (
-420 |   `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-421 |   `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '供货商名称',
-422 |   `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
-423 |   `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
-424 |   `salt` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '随机码',
-425 |   `phone` char(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '手机号码',
-426 |   `realname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
-427 |   `login_num` int DEFAULT '0' COMMENT '登录次数',
-428 |   `login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '登录时间',
-429 |   `login_ip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '登录ip',
-430 |   `last_login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '上次登录时间',
-431 |   `last_login_ip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上次登录ip',
-432 |   `create_time` int unsigned NOT NULL COMMENT '创建时间',
-433 |   `update_time` int unsigned NOT NULL DEFAULT '0' COMMENT '修改时间',
-434 |   `state` tinyint unsigned DEFAULT '2' COMMENT '1 启用 2 禁用',
-435 |   PRIMARY KEY (`id`) USING BTREE,
-436 |   UNIQUE KEY `username` (`username`) USING BTREE
-437 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='管理员';
-438 | /*!40101 SET character_set_client = @saved_cs_client */;
-439 | 
-440 | --
-441 | -- Dumping data for table `supplier`
-442 | --
-443 | 
-444 | --
-445 | -- Table structure for table `user`
-446 | --
-447 | 
-448 | 
-449 | -- Dumping data for table `user`
-450 | --
-451 | 
-452 | 
-453 | --
-454 | -- Table structure for table `user_card`
-455 | --
-456 | 
-457 | DROP TABLE IF EXISTS `user_card`;
-458 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-459 | /*!50503 SET character_set_client = utf8mb4 */;
-460 | CREATE TABLE `user_card` (
-461 |   `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-462 |   `user_id` int unsigned NOT NULL COMMENT '用户id',
-463 |   `agent_id` int DEFAULT NULL COMMENT '代理商',
-464 |   `card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '卡号',
-465 |   `sjt_card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '盛京通卡卡号',
-466 |   `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
-467 |   `auth_code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '付款码70_75开头16位随机数',
-468 |   `create_time` int unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
-469 |   `update_time` int unsigned NOT NULL DEFAULT '0' COMMENT '修改时间',
-470 |   `state` int unsigned NOT NULL DEFAULT '1' COMMENT '状态 1绑定 2解绑 通用联名电子卡不可解绑',
-471 |   `balance` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '余额',
-472 |   `is_default` int DEFAULT '2' COMMENT '默认  1 是 2否',
-473 |   PRIMARY KEY (`id`) USING BTREE
-474 | ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='用户卡';
-475 | /*!40101 SET character_set_client = @saved_cs_client */;
-476 | 
-477 | --
-478 | -- Dumping data for table `user_card`
-479 | --
-480 | 
-481 | --
-482 | -- Table structure for table `user_card_balance_record`
-483 | --
-484 | 
-485 | DROP TABLE IF EXISTS `user_card_balance_record`;
-486 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-487 | /*!50503 SET character_set_client = utf8mb4 */;
-488 | CREATE TABLE `user_card_balance_record` (
-489 |   `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-490 |   `user_id` int unsigned NOT NULL COMMENT '用户id',
-491 |   `card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '卡号',
-492 |   `amount` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '变动金额',
-493 |   `amount_before` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '变动前金额',
-494 |   `amount_after` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '变动后金额',
-495 |   `order_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单号',
-496 |   `type` int NOT NULL COMMENT '类型 1消费 2退款',
-497 |   `remark` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
-498 |   `create_time` int unsigned NOT NULL COMMENT '创建时间',
-499 |   `update_time` int unsigned NOT NULL DEFAULT '0' COMMENT '修改时间',
-500 |   PRIMARY KEY (`id`) USING BTREE
-501 | ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='卡余额变动';
-502 | /*!40101 SET character_set_client = @saved_cs_client */;
-503 | 
-504 | --
-505 | -- Dumping data for table `user_card_balance_record`
-506 | --
-507 | 
-508 | --
-509 | -- Table structure for table `xt_orders`
-510 | --
-511 | 
-512 | DROP TABLE IF EXISTS `xt_orders`;
-513 | /*!40101 SET @saved_cs_client     = @@character_set_client */;
-514 | /*!50503 SET character_set_client = utf8mb4 */;
-515 | CREATE TABLE `xt_orders` (
-516 |   `id` int NOT NULL COMMENT 'id',
-517 |   `order_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单号',
-518 |   `order_no_sort` varchar(34) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '子订单号',
-519 |   `card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '卡号',
-520 |   `amount` decimal(10,2) DEFAULT NULL COMMENT '金额',
-521 |   `create_time` int DEFAULT NULL COMMENT '创建时间',
-522 |   `update_time` int DEFAULT NULL COMMENT '更新时间',
-523 |   `state` int DEFAULT NULL COMMENT '支付状态 1待处理 2处理中 3支付成功 4支付失败',
-524 |   `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
-525 |   PRIMARY KEY (`id`) USING BTREE
-526 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='新天订单';
-527 | /*!40101 SET character_set_client = @saved_cs_client */;
-528 | 
-</content>
-</file>
-</files>
-<environment_details>
-# VSCode Visible Files
-docs/旧数据表.sql
-
-# VSCode Open Tabs
-docs/旧数据表.sql
-
-# Current Time
-Current time in ISO 8601 UTC format: 2025-08-13T03:09:21.910Z
-User time zone: UTC, UTC+0:00
-
-# Current Cost
-$0.29
-
-# Current Mode
-<slug>code</slug>
-<name>💻 代码</name>
-<model>d8d-ai-model</model>
-You have not created a todo list yet. Create one with `update_todo_list` if your task is complicated or involves multiple steps.
-</environment_details>
-
----
-
-**Assistant:**
-
-我需要分析旧数据表结构,并基于通用CRUD规范创建相应的实体和API。让我创建一个todo列表来系统性地完成这个任务。
-
-<update_todo_list>
-<todos>
-[x] 分析旧数据表结构
-[ ] 创建商品实体 (goods)
-[ ] 创建商品分类实体 (category)
-[ ] 创建订单实体 (orders)
-[ ] 创建订单商品实体 (orders_goods)
-[ ] 创建商户实体 (merchant)
-[ ] 创建供应商实体 (supplier)
-[ ] 创建用户卡实体 (user_card)
-[ ] 创建卡实体 (card)
-[ ] 创建收货地址实体 (delivery_address)
-[ ] 创建物流公司实体 (express_company)
-[ ] 创建配置实体 (config)
-[ ] 注册所有实体到数据源
-[ ] 创建所有实体的通用CRUD路由
-[ ] 注册所有路由到API
-[ ] 创建管理后台页面
-[ ] 注册路由和菜单
-</todos>
-</update_todo_list>
-
----
-
-**User:**
-
-[update_todo_list] Result:
-Todo list updated successfully.
-<environment_details>
-# VSCode Visible Files
-docs/旧数据表.sql
-
-# VSCode Open Tabs
-docs/旧数据表.sql
-
-# Current Time
-Current time in ISO 8601 UTC format: 2025-08-13T03:09:48.483Z
-User time zone: UTC, UTC+0:00
-
-# Current Cost
-$0.64
-
-# Current Mode
-<slug>code</slug>
-<name>💻 代码</name>
-<model>d8d-ai-model</model>
-====
-
-REMINDERS
-
-Below is your current list of reminders for this task. Keep them updated as you progress.
-
-| # | Content | Status |
-|---|---------|--------|
-| 1 | 分析旧数据表结构 | Completed |
-| 2 | 创建商品实体 (goods) | Pending |
-| 3 | 创建商品分类实体 (category) | Pending |
-| 4 | 创建订单实体 (orders) | Pending |
-| 5 | 创建订单商品实体 (orders_goods) | Pending |
-| 6 | 创建商户实体 (merchant) | Pending |
-| 7 | 创建供应商实体 (supplier) | Pending |
-| 8 | 创建用户卡实体 (user_card) | Pending |
-| 9 | 创建卡实体 (card) | Pending |
-| 10 | 创建收货地址实体 (delivery_address) | Pending |
-| 11 | 创建物流公司实体 (express_company) | Pending |
-| 12 | 创建配置实体 (config) | Pending |
-| 13 | 注册所有实体到数据源 | Pending |
-| 14 | 创建所有实体的通用CRUD路由 | Pending |
-| 15 | 注册所有路由到API | Pending |
-| 16 | 创建管理后台页面 | Pending |
-| 17 | 注册路由和菜单 | Pending |
-
-
-IMPORTANT: When task status changes, remember to call the `update_todo_list` tool to update your progress.
-
-</environment_details>
-
----
-
-**Assistant:**
-
-现在开始创建商品实体。让我从商品实体开始,按照通用CRUD规范创建。
-
-<write_to_file>
-<path>src/server/modules/products/goods.entity.ts</path>
-<content>import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';
-import { File } from '@/server/modules/files/file.entity';
-
-@Entity('goods')
-export class Goods {
-  @PrimaryGeneratedColumn({ unsigned: true })
-  id!: number;
-
-  @Column({ name: 'name', type: 'varchar', length: 255, comment: '商品名称' })
-  name!: string;
-
-  @Column({ name: 'price', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '售卖价' })
-  price!: number;
-
-  @Column({ name: 'cost_price', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '成本价' })
-  costPrice!: number;
-
-  @Column({ name: 'sales_num', type: 'bigint', default: 0, comment: '销售数量' })
-  salesNum!: number;
-
-  @Column({ name: 'click_num', type: 'bigint', default: 0, comment: '点击次数' })
-  clickNum!: number;
-
-  @Column({ name: 'category_id1', type: 'int', default: 0, comment: '一级类别id' })
-  categoryId1!: number;
-
-  @Column({ name: 'category_id2', type: 'int', default: 0, comment: '二级类别id' })
-  categoryId2!: number;
-
-  @Column({ name: 'category_id3', type: 'int', default: 0, comment: '三级类别id' })
-  categoryId3!: number;
-
-  @Column({ name: 'goods_type', type: 'int', default: 1, comment: '订单类型 1实物产品 2虚拟产品' })
-  goodsType!: number;
-
-  @Column({ name: 'supplier_id', type: 'int', nullable: true, comment: '所属供应商id' })
-  supplierId!: number | null;
-
-  @Column({ name: 'image', type: 'varchar', length: 255, nullable: true, comment: '商品主图' })
-  image!: string | null;
-
-  @Column({ name: 'slide_image', type: 'varchar', length: 2000, nullable: true, comment: '商品轮播(多个用,隔开)' })
-  slideImage!: string | null;
-
-  @Column({ name: 'detail', type: 'text', nullable: true, comment: '商品详情' })
-  detail!: string | null;
-
-  @Column({ name: 'instructions', type: 'varchar', length: 255, nullable: true, comment: '简介' })
-  instructions!: string | null;
-
-  @Column({ name: 'sort', type: 'int', default: 0, comment: '排序' })
-  sort!: number;
-
-  @Column({ name: 'state', type: 'int', default: 1, comment: '状态1可用2不可用' })
-  state!: number;
-
-  @Column({ name: 'stock', type: 'bigint', default: 0, comment: '库存' })
-  stock!: number;
-
-  @Column({ name: 'spu_id', type: 'int', default: 0, comment: '主商品ID' })
-  spuId!: number;
-
-  @Column({ name: 'spu_name', type: 'varchar', length: 255, nullable: true, comment: '主商品名称' })
-  spuName!: string | null;
-
-  @Column({ name: 'lowest_buy', type: 'int', default: 1, comment: '最小起购量' })
-  lowestBuy!: number;
-
-  @Column({ name: 'image_file_id', type: 'int', unsigned: true, nullable: true, comment: '商品主图文件ID' })
-  imageFileId!: number | null;
-
-  @ManyToOne(() => File, { nullable: true })
-  @JoinColumn({ name: 'image_file_id', referencedColumnName: 'id' })
-  imageFile!: File | null;
-
-  @Column({ name: 'created_at', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP', comment: '创建时间' })
-  createdAt!: Date;
-
-  @Column({ name: 'updated_at', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP', onUpdate: 'CURRENT_TIMESTAMP', comment: '更新时间' })
-  updatedAt!: Date;
-}
-</content>
-<line_count>82</line_count>
-</write_to_file>
-
----
-
-**User:**
-
-[write_to_file for 'src/server/modules/products/goods.entity.ts'] Result:
-<file_write_result>
-<path>src/server/modules/products/goods.entity.ts</path>
-<operation>created</operation>
-<notice>
-<i>You do not need to re-read the file, as you have seen all changes</i>
-<i>Proceed with the task using these changes as the new baseline.</i>
-</notice>
-</file_write_result>
-
-<environment_details>
-# VSCode Visible Files
-docs/旧数据表.sql
-
-# VSCode Open Tabs
-docs/旧数据表.sql
-
-# Current Time
-Current time in ISO 8601 UTC format: 2025-08-13T03:11:17.432Z
-User time zone: UTC, UTC+0:00
-
-# Current Cost
-$1.02
-
-# Current Mode
-<slug>code</slug>
-<name>💻 代码</name>
-<model>d8d-ai-model</model>
-====
-
-REMINDERS
-
-Below is your current list of reminders for this task. Keep them updated as you progress.
-
-| # | Content | Status |
-|---|---------|--------|
-| 1 | 分析旧数据表结构 | Completed |
-| 2 | 创建商品实体 (goods) | Pending |
-| 3 | 创建商品分类实体 (category) | Pending |
-| 4 | 创建订单实体 (orders) | Pending |
-| 5 | 创建订单商品实体 (orders_goods) | Pending |
-| 6 | 创建商户实体 (merchant) | Pending |
-| 7 | 创建供应商实体 (supplier) | Pending |
-| 8 | 创建用户卡实体 (user_card) | Pending |
-| 9 | 创建卡实体 (card) | Pending |
-| 10 | 创建收货地址实体 (delivery_address) | Pending |
-| 11 | 创建物流公司实体 (express_company) | Pending |
-| 12 | 创建配置实体 (config) | Pending |
-| 13 | 注册所有实体到数据源 | Pending |
-| 14 | 创建所有实体的通用CRUD路由 | Pending |
-| 15 | 注册所有路由到API | Pending |
-| 16 | 创建管理后台页面 | Pending |
-| 17 | 注册路由和菜单 | Pending |
-
-
-IMPORTANT: When task status changes, remember to call the `update_todo_list` tool to update your progress.
-
-</environment_details>
-
----
-
-**Assistant:**
-
-现在创建商品实体的Zod Schema定义:
-
-<write_to_file>
-<path>src/server/modules/products/goods.schema.ts</path>
-<content>import { z } from '@hono/zod-openapi';
-
-// 商品信息Schema
-export const GoodsSchema = z.object({
-  id: z.number().int().positive().openapi({
-    description: '商品ID',
-    example: 1
-  }),
-  name: z.string().max(255).openapi({
-    description: '商品名称',
-    example: '精美商品'
-  }),
-  price: z.number().multipleOf(0.01).openapi({
-    description: '售卖价',
-    example: 99.99
-  }),
-  costPrice: z.number().multipleOf(0.01).openapi({
-    description: '成本价',
-    example: 50.00
-  }),
-  salesNum: z.number().int().min(0).openapi({
-    description: '销售数量',
-    example: 100
-  }),
-  clickNum: z.number().int().min(0).openapi({
-    description: '点击次数',
-    example: 1000
-  }),
-  categoryId1: z.number().int().min(0).openapi({
-    description: '一级类别id',
-    example: 1
-  }),
-  categoryId2: z.number().int().min(0).openapi({
-    description: '二级类别id',
-    example: 2
-  }),
-  categoryId3: z.number().int().min(0).openapi({
-    description: '三级类别id',
-    example: 3
-  }),
-  goodsType: z.number().int().min(1).max(2).openapi({
-    description: '订单类型 1实物产品 2虚拟产品',
-    example: 1
-  }),
-  supplierId: z.number().int().positive().nullable().openapi({
-    description: '所属供应商id',
-    example: 1
-  }),
-  image: z.string().max(255).nullable().openapi({
-    description: '商品主图',
-    example: 'https://example.com/image.jpg'
-  }),
-  slideImage: z.string().max(2000).nullable().openapi({
-    description: '商品轮播图(多个用,隔开)',
-    example: 'image1.jpg,image2.jpg,image3.jpg'
-  }),
-  detail: z.string().nullable().openapi({
-    description: '商品详情',
-    example: '<p>商品详细描述</p>'
-  }),
-  instructions: z.string().max(255).nullable().openapi({
-    description: '简介',
-    example: '优质商品,值得信赖'
-  }),
-  sort: z.number().int().min(0).openapi({
-    description: '排序',
-    example: 0
-  }),
-  state: z.number().int().min(1).max(2).openapi({
-    description: '状态1可用2不可用',
-    example: 1
-  }),
-  stock: z.number().int().min(0).openapi({
-    description: '库存',
-    example: 100
-  }),
-  spuId: z.number().int().min(0).openapi({
-    description: '主商品ID',
-    example: 0
-  }),
-  spuName: z.string().max(255).nullable().openapi({
-    description: '主商品名称',
-    example: null
-  }),
-  lowestBuy: z.number().int().min(1).openapi({
-    description: '最小起购量',
-    example: 1
-  }),
-  imageFileId: z.number().int().positive().nullable().openapi({
-    description: '商品主图文件ID',
-    example: 1
-  }),
-  imageFile: z.object({
-    id: z.number().int().positive().openapi({ description: '文件ID' }),
-    name: z.string().max(255).openapi({ description: '文件名', example: 'product.jpg' }),
-    fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/product.jpg' }),
-    type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }),
-    size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
-  }).nullable().optional().openapi({
-    description: '商品主图文件信息'
-  }),
-  createdAt: z.date().openapi({
-    description: '创建时间',
-    example: '2024-01-01T00:00:00Z'
-  }),
-  updatedAt: z.date().openapi({
-    description: '更新时间',
-    example: '2024-01-01T00:00:00Z'
-  })
-});
-
-// 创建商品DTO
-export const CreateGoodsDto = z.object({
-  name: z.string().max(255).openapi({
-    description: '商品名称',
-    example: '精美商品'
-  }),
-  price: z.coerce.number().multipleOf(0.01).openapi({
-    description: '售卖价',
-    example: 99.99
-  }),
-  costPrice: z.coerce.number().multipleOf(0.01).openapi({
-    description: '成本价',
-    example: 50.00
-  }),
-  categoryId1: z.coerce.number().int().min(0).openapi({
-    description: '一级类别id',
-    example: 1
-  }),
-  categoryId2: z.coerce.number().int().min(0).optional().openapi({
-    description: '二级类别id',
-    example: 2
-  }),
-  categoryId3: z.coerce.number().int().min(0).optional().openapi({
-    description: '三级类别id',
-    example: 3
-  }),
-  goodsType: z.coerce.number().int().min(1).max(2).default(1).openapi({
-    description: '订单类型 1实物产品 2虚拟产品',
-    example: 1
-  }),
-  supplierId: z.coerce.number().int().positive().optional().openapi({
-    description: '所属供应商id',
-    example: 1
-  }),
-  image: z.string().max(255).optional().openapi({
-    description: '商品主图',
-    example: 'https://example.com/image.jpg'
-  }),
-  slideImage: z.string().max(2000).optional().openapi({
-    description: '商品轮播图(多个用,隔开)',
-    example: 'image1.jpg,image2.jpg,image3.jpg'
-  }),
-  detail: z.string().optional().openapi({
-    description: '商品详情',
-    example: '<p>商品详细描述</p>'
-  }),
-  instructions: z.string().max(255).optional().openapi({
-    description: '简介',
-    example: '优质商品,值得信赖'
-  }),
-  sort: z.coerce.number().int().min(0).default(0).openapi({
-    description: '排序',
-    example: 0
-  }),
-  state: z.coerce.number().int().min(1).max(2).default(1).openapi({
-    description: '状态1可用2不可用',
-    example: 1
-  }),
-  stock: z.coerce.number().int().min(0).default(0).openapi({
-    description: '库存',
-    example: 100
-  }),
-  spuId: z.coerce.number().int().min(0).default(0).openapi({
-    description: '主商品ID',
-    example: 0
-  }),
-  spuName: z.string().max(255).optional().openapi({
-    description: '主商品名称',
-    example: null
-  }),
-  lowestBuy: z.coerce.number().int().min(1).default(1).openapi({
-    description: '最小起购量',
-    example: 1
-  }),
-  imageFileId: z.coerce.number().int().positive().optional().openapi({
-    description: '商品主图文件ID',
-    example: 1
-  })
-});
-
-// 更新商品DTO
-export const UpdateGoodsDto = z.object({
-  name: z.string().max(255).optional().openapi({
-    description: '商品名称',
-    example: '精美商品'
-  }),
-  price: z.coerce.number().multipleOf(0.01).optional().openapi({
-    description: '售卖价',
-    example: 99.99
-  }),
-  costPrice: z.coerce.number().multipleOf(0.01).optional().openapi({
-    description: '成本价',
-    example: 50.00
-  }),
-  categoryId1: z.coerce.number().int().min(0).optional().openapi({
-    description: '一级类别id',
-    example: 1
-  }),
-  categoryId2: z.coerce.number().int().min(0).optional().openapi({
-    description: '二级类别id',
-    example: 2
-  }),
-  categoryId3: z.coerce.number().int().min(0).optional().openapi({
-    description: '三级类别id',
-    example: 3
-  }),
-  goodsType: z.coerce.number().int().min(1).max(2).optional().openapi({
-    description: '订单类型 1实物产品 2虚拟产品',
-    example: 1
-  }),
-  supplierId: z.coerce.number().int().positive().optional().openapi({
-    description: '所属供应商id',
-    example: 1
-  }),
-  image: z.string().max(255).optional().openapi({
-    description: '商品主图',
-    example: 'https://example.com/image.jpg'
-  }),
-  slideImage: z.string().max(2000).optional().openapi({
-    description: '商品轮播图(多个用,隔开)',
-    example: 'image1.jpg,image2.jpg,image3.jpg'
-  }),
-  detail: z.string().optional().openapi({
-    description: '商品详情',
-    example: '<p>商品详细描述</p>'
-  }),
-  instructions: z.string().max(255).optional().openapi({
-    description: '简介',
-    example: '优质商品,值得信赖'
-  }),
-  sort: z.coerce.number().int().min(0).optional().openapi({
-    description: '排序',
-    example: 0
-  }),
-  state: z.coerce.number().int().min(1).max(2).optional().openapi({
-    description: '状态1可用2不可用',
-    example: 1
-  }),
-  stock: z.coerce.number().int().min(0).optional().openapi({
-    description: '库存',
-    example: 100
-  }),
-  spuId: z.coerce.number().int().min(0).optional().openapi({
-    description: '主商品ID',
-    example: 0
-  }),
-  spuName: z.string().max(255).optional().openapi({
-    description: '主商品名称',
-    example: null
-  }),
-  lowestBuy: z.coerce.number().int().min(1).optional().openapi({
-    description: '最小起购量',
-    example: 1
-  }),
-  imageFileId: z.coerce.number().int().positive().optional().openapi({
-    description: '商品主图文件ID',
-    example: 1
-  })
-});
-</content>
-<line_count>150</line_count>
-</write_to_file>
-
----
-
-**User:**
-
-[write_to_file for 'src/server/modules/products/goods.schema.ts'] Result:
-<file_write_result>
-<path>src/server/modules/products/goods.schema.ts</path>
-<operation>created</operation>
-<notice>
-<i>You do not need to re-read the file, as you have seen all changes</i>
-<i>Proceed with the task using these changes as the new baseline.</i>
-</notice>
-</file_write_result>
-
-<environment_details>
-# VSCode Visible Files
-docs/旧数据表.sql
-
-# VSCode Open Tabs
-docs/旧数据表.sql
-
-# Current Time
-Current time in ISO 8601 UTC format: 2025-08-13T03:13:52.757Z
-User time zone: UTC, UTC+0:00
-
-# Current Cost
-$1.46
-
-# Current Mode
-<slug>code</slug>
-<name>💻 代码</name>
-<model>d8d-ai-model</model>
-====
-
-REMINDERS
-
-Below is your current list of reminders for this task. Keep them updated as you progress.
-
-| # | Content | Status |
-|---|---------|--------|
-| 1 | 分析旧数据表结构 | Completed |
-| 2 | 创建商品实体 (goods) | Pending |
-| 3 | 创建商品分类实体 (category) | Pending |
-| 4 | 创建订单实体 (orders) | Pending |
-| 5 | 创建订单商品实体 (orders_goods) | Pending |
-| 6 | 创建商户实体 (merchant) | Pending |
-| 7 | 创建供应商实体 (supplier) | Pending |
-| 8 | 创建用户卡实体 (user_card) | Pending |
-| 9 | 创建卡实体 (card) | Pending |
-| 10 | 创建收货地址实体 (delivery_address) | Pending |
-| 11 | 创建物流公司实体 (express_company) | Pending |
-| 12 | 创建配置实体 (config) | Pending |
-| 13 | 注册所有实体到数据源 | Pending |
-| 14 | 创建所有实体的通用CRUD路由 | Pending |
-| 15 | 注册所有路由到API | Pending |
-| 16 | 创建管理后台页面 | Pending |
-| 17 | 注册路由和菜单 | Pending |
-
-
-IMPORTANT: When task status changes, remember to call the `update_todo_list` tool to update your progress.
-
-</environment_details>
-
----
-
-**Assistant:**
-
-<update_todo_list>
-<todos>
-[x] 分析旧数据表结构
-[x] 创建商品实体 (goods)
-[ ] 创建商品分类实体 (category)
-[ ] 创建订单实体 (orders)
-[ ] 创建订单商品实体 (orders_goods)
-[ ] 创建商户实体 (merchant)
-[ ] 创建供应商实体 (supplier)
-[ ] 创建用户卡实体 (user_card)
-[ ] 创建卡实体 (card)
-[ ] 创建收货地址实体 (delivery_address)
-[ ] 创建物流公司实体 (express_company)
-[ ] 创建配置实体 (config)
-[ ] 注册所有实体到数据源
-[ ] 创建所有实体的通用CRUD路由
-[ ] 注册所有路由到API
-[ ] 创建管理后台页面
-[ ] 注册路由和菜单
-</todos>
-</update_todo_list>
-
----
-
-**User:**
-
-[update_todo_list] Result:
-Todo list updated successfully.
-<environment_details>
-# VSCode Visible Files
-docs/旧数据表.sql
-
-# VSCode Open Tabs
-docs/旧数据表.sql
-
-# Current Time
-Current time in ISO 8601 UTC format: 2025-08-13T03:14:08.469Z
-User time zone: UTC, UTC+0:00
-
-# Current Cost
-$1.84
-
-# Current Mode
-<slug>code</slug>
-<name>💻 代码</name>
-<model>d8d-ai-model</model>
-====
-
-REMINDERS
-
-Below is your current list of reminders for this task. Keep them updated as you progress.
-
-| # | Content | Status |
-|---|---------|--------|
-| 1 | 分析旧数据表结构 | Completed |
-| 2 | 创建商品实体 (goods) | Completed |
-| 3 | 创建商品分类实体 (category) | Pending |
-| 4 | 创建订单实体 (orders) | Pending |
-| 5 | 创建订单商品实体 (orders_goods) | Pending |
-| 6 | 创建商户实体 (merchant) | Pending |
-| 7 | 创建供应商实体 (supplier) | Pending |
-| 8 | 创建用户卡实体 (user_card) | Pending |
-| 9 | 创建卡实体 (card) | Pending |
-| 10 | 创建收货地址实体 (delivery_address) | Pending |
-| 11 | 创建物流公司实体 (express_company) | Pending |
-| 12 | 创建配置实体 (config) | Pending |
-| 13 | 注册所有实体到数据源 | Pending |
-| 14 | 创建所有实体的通用CRUD路由 | Pending |
-| 15 | 注册所有路由到API | Pending |
-| 16 | 创建管理后台页面 | Pending |
-| 17 | 注册路由和菜单 | Pending |
-
-
-IMPORTANT: When task status changes, remember to call the `update_todo_list` tool to update your progress.
-
-</environment_details>
-
----
-
-**Assistant:**
-
-现在创建商品分类实体:
-
-<write_to_file>
-<path>src/server/modules/products/category.entity.ts</path>
-<content>import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinColumn } from 'typeorm';
-import { File } from '@/server/modules/files/file.entity';
-
-@Entity('category')
-export class Category {
-  @PrimaryGeneratedColumn({ unsigned: true })
-  id!: number;
-
-  @Column({ name: 'name', type: 'varchar', length: 255, comment: '类别名称' })
-  name!: string;
-
-  @Column({ name: 'parent_id', type: 'int', default: 0, comment: '上级id' })
-  parentId!: number;
-
-  @Column({ name: 'level', type: 'int', default: 0, comment: '层级' })
-  level!: number;
-
-  @Column({ name: 'state', type: 'int', default: 1, comment: '状态1可用2不可用' })
-  state!: number;
-
-  @Column({ name: 'image', type: 'varchar', length: 255, nullable: true, comment: '分类图片' })
-  image!: string | null;
-
-  @Column({ name: 'image_file_id', type: 'int', unsigned: true, nullable: true, comment: '分类图片文件ID' })
-  imageFileId!: number | null;
-
-  @ManyToOne(() => File, { nullable: true })
-  @JoinColumn({ name: 'image_file_id', referencedColumnName: 'id' })
-  imageFile!: File | null;
-
-  @Column({ name: 'created_at', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP', comment: '创建时间' })
-  createdAt!: Date;
-
-  @Column({ name: 'updated_at', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP', onUpdate: 'CURRENT_TIMESTAMP', comment: '更新时间' })
-  updatedAt!: Date;
-}
-</content>
-<line_count>33</line_count>
-</write_to_file>
-

+ 0 - 85
docs/tailwind-merge.md

@@ -1,85 +0,0 @@
-tailwind-merge
-tailwind-merge 是一个用于处理和优化 Tailwind CSS 类的工具,它的主要功能是合并和去除冗余或冲突的 CSS 类。
-
-我们平常在使用 Tailwind CSS 时,有时会出现重复或冲突的类名,特别是在动态应用类时,手动管理这些类可能会变得很复杂。
-
-tailwind-merge 可以帮助自动化这一过程,确保最终应用的 CSS 类是唯一且不会发生冲突。
-
-tailwind-merge 是完全运行时的方案,在运行时进行处理,而 tailwindcss 是编译时
-
-使用场景
-动态类名:当你在 JavaScript 或 React 等框架中动态生成类名时,tailwind-merge 可以帮助你合并和优化这些类名,避免冗余或冲突。
-条件类名:在基于某些条件添加 CSS 类时,tailwind-merge 确保条件类之间不会发生冲突,比如在响应式设计中或主题切换时。
-开发效率:开发人员可以节省大量的时间,不必手动检查和优化 Tailwind CSS 类的组合,确保样式一致且符合预期。
-它特别适合你开发组件的时候,对原有组件的 class 进行覆盖,所以像 shadcn/ui 这种 UI 库 直接把它作为了直接依赖。
-
-H5 使用方式
-import { twMerge } from 'tailwind-merge'
-
-twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
-// → 'hover:bg-dark-red p-3 bg-[#B91C1C]'
-
-小程序中的使用方式
-@weapp-tailwindcss/merge 是一个 tailwind-merge 的小程序版本,需要和 weapp-tailwindcss 一起使用
-
-其中 weapp-tailwindcss 为 @weapp-tailwindcss/merge 提供编译时支持。
-
-安装
-npm
-Yarn
-pnpm
-Bun
-pnpm add @weapp-tailwindcss/merge
-
-使用方式
-使用方式和 tailwind-merge 几乎完全相同
-
-import { twMerge } from '@weapp-tailwindcss/merge'
-
-twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
-// → 'hovercbg-dark-red p-3 bg-_hB91C1C_'
-
-从 @weapp-tailwindcss/merge 导出的方法和 tailwind-merge 相同
-
-另外目前编译时是以调用方法的名称作为寻址索引的,如果你需要方法重命名,
-
-比如把 twMerge -> cn,需要设置这个 ignoreCallExpressionIdentifiers 配置项
-
-特性
-@weapp-tailwindcss/merge 内置了 tailwind-merge@2(对应 tailwindcss@3) 和 tailwind-merge@3(对应 tailwindcss@4) 2 个版本,
-
-在安装的时候,根据你的 tailwindcss 版本自动进行切换。
-
-如果你需要手动指定,你可以从下列路径中导出
-
-// tailwindcss v3
-import { twMerge } from '@weapp-tailwindcss/merge/v3'
-// tailwindcss v4
-import { twMerge } from '@weapp-tailwindcss/merge/v4'
-
-另外 @weapp-tailwindcss/merge 还内置了 cva 功能 (class-variance-authority)
-
-import { cva } from '@weapp-tailwindcss/merge/cva'
-
-假如你熟悉原子类组件封装,你就知道这是什么了。
-
-跨多端使用
-import { create } from '@weapp-tailwindcss/merge';
-
-const { twMerge } = create(
-  {
-    // 在当前环境为只有小程序的环境的时候,需要转义,其他就禁止
-    disableEscape: true
-  }
-)
-
-const x = twMerge('px-2 py-1 bg-red hover:bg-dark-red', 'p-3 bg-[#B91C1C]')
-
-实时编辑器
-function () {
-  return <MergeDemo/>
-}
-结果
-参数 disableEscape:false
-点我切换参数
-结果:hovercbg-dark-red p-3 bg-_hB91C1C_

+ 0 - 443
docs/旧数据表.sql

@@ -1,443 +0,0 @@
--- 统一改为 TypeORM 标准时间字段格式
--- 使用 @CreateDateColumn({ name: 'created_at', type: 'timestamp' }) 和 @UpdateDateColumn({ name: 'updated_at', type: 'timestamp' })
-
--- 广告表
-DROP TABLE IF EXISTS `ad`;
-CREATE TABLE `ad` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT,
-  `title` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '标题',
-  `type_id` int DEFAULT NULL COMMENT '广告类型',
-  `code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '调用别名',
-  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'url',
-  `img` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '图片',
-  `sort` int DEFAULT '0' COMMENT '排序',
-  `created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  `status` int unsigned DEFAULT '0' COMMENT '状态',
-  `action_type` int DEFAULT '1' COMMENT '跳转类型 0 不跳转 1webview 2小程序页面',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='广告';
-
--- 广告类型表
-DROP TABLE IF EXISTS `ad_type`;
-CREATE TABLE `ad_type` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT,
-  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '类型名称',
-  `code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '调用别名',
-  `remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
-  `created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  `status` int DEFAULT '0' COMMENT '状态',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='广告类型';
-
--- 卡表
-DROP TABLE IF EXISTS `card`;
-CREATE TABLE `card` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `agent_id` int DEFAULT NULL,
-  `card_type` int DEFAULT NULL COMMENT '1盛京通卡 2通用联名电子卡',
-  `card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '卡号',
-  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
-  `created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
-  `state` int unsigned NOT NULL DEFAULT '1' COMMENT '状态 1绑定 2解绑 通用联名电子卡不可解绑',
-  `face_value` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '面值',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE KEY `card_no` (`card_no`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='卡';
-
--- 商品分类表
-DROP TABLE IF EXISTS `goods_category`;
-CREATE TABLE `goods_category` (
-  `id` int NOT NULL AUTO_INCREMENT COMMENT '类别id',
-  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '类别名称',
-  `parent_id` int DEFAULT '0' COMMENT '上级id',
-  `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分类图片',
-  `level` int DEFAULT '0' COMMENT '层级',
-  `state` int DEFAULT '1' COMMENT '状态1可用2不可用',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=777709 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='分类表';
-
--- 城市表
-DROP TABLE IF EXISTS `city`;
-CREATE TABLE `city` (
-  `id` bigint DEFAULT NULL COMMENT '地区id',
-  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '地区名称',
-  `level` int DEFAULT '0' COMMENT '层级省市区县1,2,3,4',
-  `parent_id` bigint DEFAULT '0' COMMENT '上级id',
-  `state` int DEFAULT '1' COMMENT '状态1可用',
-  `sort` int DEFAULT '0' COMMENT '排序数值越大越靠前'
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='省、市、区、街道';
-
--- 配置表
-DROP TABLE IF EXISTS `config`;
-CREATE TABLE `config` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `key` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '名称',
-  `value` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '值',
-  `state` int DEFAULT '2' COMMENT '状态 1可用 2禁用',
-  `created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`),
-  UNIQUE KEY `key_state` (`key`,`state`) USING BTREE COMMENT 'key_state唯一'
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-
--- 收货地址表
-DROP TABLE IF EXISTS `delivery_address`;
-CREATE TABLE `delivery_address` (
-  `id` int NOT NULL AUTO_INCREMENT COMMENT '收货地址id',
-  `user_id` int DEFAULT '0' COMMENT '用户id',
-  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
-  `phone` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '手机号',
-  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '详细地址',
-  `receiver_province` bigint DEFAULT '0' COMMENT '省',
-  `receiver_city` bigint DEFAULT '0' COMMENT '市',
-  `receiver_district` bigint DEFAULT '0' COMMENT '区',
-  `receiver_town` bigint DEFAULT '0' COMMENT '街道',
-  `state` int DEFAULT '1' COMMENT '是否可用1正常2禁用3删除(不显示)',
-  `is_default` int DEFAULT '0' COMMENT '是否常用1是 2否',
-  `created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='用户收货地址表';
-
--- 快递公司表
-DROP TABLE IF EXISTS `express_company`;
-CREATE TABLE `express_company` (
-  `id` int NOT NULL AUTO_INCREMENT COMMENT '表序号',
-  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '物流公司名称',
-  `code` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '物流编号',
-  `state` int NOT NULL DEFAULT '1' COMMENT '使用状态 1可用 2禁用',
-  `sort` int DEFAULT NULL COMMENT '优先级 值越大越优先',
-  `created_at` timestamp DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-  `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci AVG_ROW_LENGTH=420 ROW_FORMAT=COMPACT COMMENT='物流公司';
-
--- 商品表
-DROP TABLE IF EXISTS `goods`;
-CREATE TABLE `goods` (
-  `id` int NOT NULL AUTO_INCREMENT,
-  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品名称',
-  `price` decimal(10,2) DEFAULT '0.00' COMMENT '售卖价',
-  `cost_price` decimal(10,2) DEFAULT '0.00' COMMENT '成本价',
-  `sales_num` bigint DEFAULT '0' COMMENT '销售数量',
-  `click_num` bigint DEFAULT '0' COMMENT '点击次数',
-  `category_id1` int DEFAULT '0' COMMENT '一级类别id',
-  `category_id2` int DEFAULT '0' COMMENT '二级类别id',
-  `category_id3` int DEFAULT '0' COMMENT '三级类别id',
-  `goods_type` int DEFAULT '1' COMMENT '订单类型 1实物产品 2虚拟产品',
-  `supplier_id` int DEFAULT NULL COMMENT '所属供应商id',
-  `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品主图',
-  `slide_image` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品轮播(多个用,隔开)',
-  `detail` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '商品详情',
-  `instructions` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '简介',
-  `sort` int DEFAULT '0' COMMENT '排序',
-  `state` int DEFAULT '1' COMMENT '状态1可用2不可用',
-  `stock` bigint DEFAULT '0' COMMENT '库存',
-  `spu_id` int DEFAULT '0' COMMENT '主商品ID',
-  `spu_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '主商品名称',
-  `lowest_buy` int DEFAULT '1' COMMENT '最小起购量',
-  `create_time` int DEFAULT '0' COMMENT '创建时间',
-  `update_time` int DEFAULT '0' COMMENT '修改时间',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=10007 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='商品表';
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `goods`
---
-
-
-
---
--- Table structure for table `merchant`
---
-
-DROP TABLE IF EXISTS `merchant`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!50503 SET character_set_client = utf8mb4 */;
-CREATE TABLE `merchant` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT,
-  `number` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '编号',
-  `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '名称',
-  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
-  `salt` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '随机码',
-  `login_num` int DEFAULT '0' COMMENT '登录次数',
-  `login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '登录时间',
-  `login_ip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '登录ip',
-  `last_login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '上次登录时间',
-  `last_login_ip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上次登录ip',
-  `rsa_public_key` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公钥',
-  `aes_key` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'aes秘钥',
-  `create_time` int unsigned DEFAULT NULL COMMENT '创建时间',
-  `update_time` int unsigned DEFAULT '0' COMMENT '修改时间',
-  `state` int DEFAULT NULL COMMENT '状态 1可用 2禁用',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE KEY `number` (`number`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='商户';
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `merchant`
---
-
-
-
---
--- Table structure for table `orders`
---
-
-DROP TABLE IF EXISTS `orders`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!50503 SET character_set_client = utf8mb4 */;
-CREATE TABLE `orders` (
-  `id` int NOT NULL AUTO_INCREMENT COMMENT '订单id',
-  `order_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单号',
-  `user_id` int DEFAULT '0' COMMENT '用户ID',
-  `auth_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '付款码',
-  `card_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '卡号',
-  `sjt_card_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '盛京通卡号',
-  `amount` decimal(10,2) DEFAULT '0.00' COMMENT '订单金额',
-  `cost_amount` decimal(10,2) DEFAULT '0.00' COMMENT '成本金额',
-  `freight_amount` decimal(10,2) DEFAULT '0.00' COMMENT '运费',
-  `discount_amount` decimal(10,2) DEFAULT '0.00' COMMENT '优惠金额',
-  `pay_amount` decimal(10,2) DEFAULT '0.00' COMMENT '实际支付金额',
-  `device_no` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '设备编号',
-  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单描述',
-  `goods_detail` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单详情 json',
-  `goods_tag` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单优惠标记',
-  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '地址',
-  `order_type` int DEFAULT '1' COMMENT '订单类型 1实物订单 2虚拟订单',
-  `pay_type` int DEFAULT '0' COMMENT '支付类型1积分2礼券',
-  `pay_state` int DEFAULT '0' COMMENT '0未支付1支付中2支付成功3已退款4支付失败5订单关闭',
-  `state` int DEFAULT '0' COMMENT '订单状态0未发货1已发货2收货成功3已退货',
-  `user_phone` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户手机号',
-  `merchant_id` int DEFAULT '0' COMMENT '商户id',
-  `merchant_no` int DEFAULT NULL COMMENT '商户号',
-  `supplier_id` int DEFAULT '0' COMMENT '供货商id',
-  `address_id` int DEFAULT '0' COMMENT '地址id',
-  `receiver_mobile` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '收货人手机号',
-  `recevier_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '收货人姓名',
-  `recevier_province` bigint DEFAULT '0' COMMENT '收货人所在省',
-  `recevier_city` bigint DEFAULT '0' COMMENT '收货人所在市',
-  `recevier_district` bigint DEFAULT '0' COMMENT '收货人所在区',
-  `recevier_town` bigint DEFAULT '0' COMMENT '收货人所在街道',
-  `create_time` int DEFAULT '0' COMMENT '创建时间',
-  `update_time` int DEFAULT '0' COMMENT '更新时间',
-  `refund_time` int DEFAULT '0' COMMENT '退款时间',
-  `close_time` int DEFAULT '0' COMMENT '订单关闭时间',
-  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '管理员备注信息',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE KEY `order_no` (`order_no`) USING BTREE COMMENT '订单号唯一'
-) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='订单表';
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `orders`
---
-
-
-
---
--- Table structure for table `orders_goods`
---
-
-DROP TABLE IF EXISTS `orders_goods`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!50503 SET character_set_client = utf8mb4 */;
-CREATE TABLE `orders_goods` (
-  `id` int NOT NULL AUTO_INCREMENT COMMENT '订单商品表id',
-  `order_id` int DEFAULT '0' COMMENT '订单表id',
-  `order_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单号',
-  `goods_id` int DEFAULT '0' COMMENT '商品id',
-  `goods_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品名称',
-  `goods_image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品图片',
-  `goods_type` int DEFAULT '1' COMMENT '1实物产品2虚拟订单',
-  `supplier_id` int DEFAULT '0' COMMENT '供货商id',
-  `cost_price` decimal(10,2) DEFAULT '0.00' COMMENT '成本价',
-  `price` decimal(10,2) DEFAULT '0.00' COMMENT '售价',
-  `num` int DEFAULT '0' COMMENT '数量',
-  `freight_amount` decimal(10,2) DEFAULT '0.00' COMMENT '运费',
-  `state` int DEFAULT '0' COMMENT '状态(0未发货、1已发货)',
-  `express_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '快递名称',
-  `express_no` int DEFAULT NULL COMMENT '单号',
-  `create_time` int DEFAULT '0' COMMENT '创建时间',
-  `update_time` int DEFAULT '0' COMMENT '修改时间',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=97 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='订单商品表';
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `orders_goods`
---
-
-
-
---
--- Table structure for table `orders_refund`
---
-
-DROP TABLE IF EXISTS `orders_refund`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!50503 SET character_set_client = utf8mb4 */;
-CREATE TABLE `orders_refund` (
-  `id` int NOT NULL COMMENT 'id',
-  `order_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '订单号',
-  `refund_order_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '退款订单号',
-  `refund_amount` decimal(10,2) DEFAULT NULL COMMENT '退款金额',
-  `create_time` int DEFAULT NULL COMMENT '退款时间',
-  `update_time` int DEFAULT NULL COMMENT '更新时间',
-  `state` int DEFAULT NULL COMMENT '0未退款1退款中2退款成功3退款失败',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE KEY `refund_order_no` (`refund_order_no`) USING BTREE COMMENT 'refund_order_no'
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='退款';
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `orders_refund`
---
-
-
---
--- Table structure for table `organization`
---
-
-DROP TABLE IF EXISTS `organization`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!50503 SET character_set_client = utf8mb4 */;
-CREATE TABLE `organization` (
-  `id` int NOT NULL AUTO_INCREMENT COMMENT '分行网点id',
-  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '分行网点名称',
-  `parent_id` int DEFAULT '0' COMMENT '上级id',
-  `level` int DEFAULT '4' COMMENT '层级',
-  `create_time` int DEFAULT '0' COMMENT '床渐渐时间',
-  `update_time` int DEFAULT '0' COMMENT '修改时间',
-  `state` int DEFAULT '1' COMMENT '状态1可用2不可用',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='组织架构表';
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `organization`
---
-
-
---
--- Table structure for table `supplier`
---
-
-DROP TABLE IF EXISTS `supplier`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!50503 SET character_set_client = utf8mb4 */;
-CREATE TABLE `supplier` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '供货商名称',
-  `username` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
-  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
-  `salt` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '随机码',
-  `phone` char(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '手机号码',
-  `realname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '姓名',
-  `login_num` int DEFAULT '0' COMMENT '登录次数',
-  `login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '登录时间',
-  `login_ip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '登录ip',
-  `last_login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '上次登录时间',
-  `last_login_ip` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '上次登录ip',
-  `create_time` int unsigned NOT NULL COMMENT '创建时间',
-  `update_time` int unsigned NOT NULL DEFAULT '0' COMMENT '修改时间',
-  `state` tinyint unsigned DEFAULT '2' COMMENT '1 启用 2 禁用',
-  PRIMARY KEY (`id`) USING BTREE,
-  UNIQUE KEY `username` (`username`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='管理员';
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `supplier`
---
-
---
--- Table structure for table `user`
---
-
-
--- Dumping data for table `user`
---
-
-
---
--- Table structure for table `user_card`
---
-
-DROP TABLE IF EXISTS `user_card`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!50503 SET character_set_client = utf8mb4 */;
-CREATE TABLE `user_card` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `user_id` int unsigned NOT NULL COMMENT '用户id',
-  `agent_id` int DEFAULT NULL COMMENT '代理商',
-  `card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '卡号',
-  `sjt_card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '盛京通卡卡号',
-  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
-  `auth_code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '付款码70_75开头16位随机数',
-  `create_time` int unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
-  `update_time` int unsigned NOT NULL DEFAULT '0' COMMENT '修改时间',
-  `state` int unsigned NOT NULL DEFAULT '1' COMMENT '状态 1绑定 2解绑 通用联名电子卡不可解绑',
-  `balance` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '余额',
-  `is_default` int DEFAULT '2' COMMENT '默认  1 是 2否',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='用户卡';
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `user_card`
---
-
---
--- Table structure for table `user_card_balance_record`
---
-
-DROP TABLE IF EXISTS `user_card_balance_record`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!50503 SET character_set_client = utf8mb4 */;
-CREATE TABLE `user_card_balance_record` (
-  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
-  `user_id` int unsigned NOT NULL COMMENT '用户id',
-  `card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '卡号',
-  `amount` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '变动金额',
-  `amount_before` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '变动前金额',
-  `amount_after` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '变动后金额',
-  `order_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单号',
-  `type` int NOT NULL COMMENT '类型 1消费 2退款',
-  `remark` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
-  `create_time` int unsigned NOT NULL COMMENT '创建时间',
-  `update_time` int unsigned NOT NULL DEFAULT '0' COMMENT '修改时间',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='卡余额变动';
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `user_card_balance_record`
---
-
---
--- Table structure for table `xt_orders`
---
-
-DROP TABLE IF EXISTS `xt_orders`;
-/*!40101 SET @saved_cs_client     = @@character_set_client */;
-/*!50503 SET character_set_client = utf8mb4 */;
-CREATE TABLE `xt_orders` (
-  `id` int NOT NULL COMMENT 'id',
-  `order_no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '订单号',
-  `order_no_sort` varchar(34) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '子订单号',
-  `card_no` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '卡号',
-  `amount` decimal(10,2) DEFAULT NULL COMMENT '金额',
-  `create_time` int DEFAULT NULL COMMENT '创建时间',
-  `update_time` int DEFAULT NULL COMMENT '更新时间',
-  `state` int DEFAULT NULL COMMENT '支付状态 1待处理 2处理中 3支付成功 4支付失败',
-  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
-  PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPACT COMMENT='新天订单';
-/*!40101 SET character_set_client = @saved_cs_client */;
-