diff --git a/src/config/config.default.ts b/src/config/config.default.ts index 5b40f3a..b3db33d 100644 --- a/src/config/config.default.ts +++ b/src/config/config.default.ts @@ -75,7 +75,7 @@ export default { // 国际化配置 i18n: { // 是否开启 - enable: false, + enable: true, // 语言 languages: ['zh-cn', 'zh-tw', 'en'], }, diff --git a/src/config/config.local.ts b/src/config/config.local.ts index bb22421..ac7a215 100644 --- a/src/config/config.local.ts +++ b/src/config/config.local.ts @@ -22,6 +22,24 @@ export default { entities, subscribers: [TenantSubscriber], }, + // default: { + // type: 'mysql', + // host: '127.0.0.1', + // port: 3306, + // username: 'root', + // password: '123456', + // database: 'cool', + // // 自动建表 注意:线上部署的时候不要使用,有可能导致数据丢失 + // synchronize: true, + // // 打印日志 + // logging: false, + // // 字符集 + // charset: 'utf8mb4', + // // 是否开启缓存 + // cache: true, + // // 实体路径 + // entities: ['**/modules/*/entity'], + // }, }, }, cool: { diff --git a/src/locales/dict/.lock b/src/locales/dict/.lock new file mode 100644 index 0000000..61411da --- /dev/null +++ b/src/locales/dict/.lock @@ -0,0 +1 @@ +2025-01-21T11:32:10.104Z \ No newline at end of file diff --git a/src/locales/dict/info/en.json b/src/locales/dict/info/en.json new file mode 100644 index 0000000..e45bf5b --- /dev/null +++ b/src/locales/dict/info/en.json @@ -0,0 +1,11 @@ +{ + "COOL": "COOL", + "闪酷": "Flashy", + "法师": "Mage", + "战士": "Warrior", + "坦克": "Tank", + "刺客": "Assassin", + "射手": "Shooter", + "幻影刺客": "Phantom Assassin", + "你好": "Hello" +} \ No newline at end of file diff --git a/src/locales/dict/info/zh-cn.json b/src/locales/dict/info/zh-cn.json new file mode 100644 index 0000000..e00ee0a --- /dev/null +++ b/src/locales/dict/info/zh-cn.json @@ -0,0 +1,11 @@ +{ + "COOL": "COOL", + "闪酷": "闪酷", + "法师": "法师", + "战士": "战士", + "坦克": "坦克", + "刺客": "刺客", + "射手": "射手", + "幻影刺客": "幻影刺客", + "你好": "你好" +} \ No newline at end of file diff --git a/src/locales/dict/info/zh-tw.json b/src/locales/dict/info/zh-tw.json new file mode 100644 index 0000000..7d2d36f --- /dev/null +++ b/src/locales/dict/info/zh-tw.json @@ -0,0 +1,11 @@ +{ + "COOL": "酷", + "闪酷": "閃酷", + "法师": "法師", + "战士": "戰士", + "坦克": "坦克", + "刺客": "刺客", + "射手": "射手", + "幻影刺客": "幻影刺客", + "你好": "你好" +} \ No newline at end of file diff --git a/src/locales/dict/type/en.json b/src/locales/dict/type/en.json new file mode 100644 index 0000000..3ed3063 --- /dev/null +++ b/src/locales/dict/type/en.json @@ -0,0 +1,4 @@ +{ + "品牌": "Brand", + "职业": "Job" +} \ No newline at end of file diff --git a/src/locales/dict/type/zh-cn.json b/src/locales/dict/type/zh-cn.json new file mode 100644 index 0000000..c3d17a4 --- /dev/null +++ b/src/locales/dict/type/zh-cn.json @@ -0,0 +1,4 @@ +{ + "品牌": "品牌", + "职业": "职业" +} \ No newline at end of file diff --git a/src/locales/dict/type/zh-tw.json b/src/locales/dict/type/zh-tw.json new file mode 100644 index 0000000..03f80ed --- /dev/null +++ b/src/locales/dict/type/zh-tw.json @@ -0,0 +1,4 @@ +{ + "品牌": "品牌", + "职业": "職業" +} \ No newline at end of file diff --git a/src/locales/menu/.lock b/src/locales/menu/.lock new file mode 100644 index 0000000..35a9bdb --- /dev/null +++ b/src/locales/menu/.lock @@ -0,0 +1 @@ +2025-01-21T11:32:17.870Z \ No newline at end of file diff --git a/src/locales/menu/en.json b/src/locales/menu/en.json new file mode 100644 index 0000000..4f8544d --- /dev/null +++ b/src/locales/menu/en.json @@ -0,0 +1,47 @@ +{ + "系统管理": "System", + "权限管理": "Auth", + "菜单列表": "Menu", + "新增": "Add", + "删除": "Del", + "查询": "Search", + "参数": "Param", + "编辑": "Edit", + "角色列表": "Role", + "修改": "Modify", + "用户列表": "User", + "部门列表": "Dept", + "新增部门": "Add Dept", + "更新部门": "Update Dept", + "删除部门": "Del Dept", + "部门排序": "Sort Dept", + "用户转移": "Transfer", + "参数配置": "Config", + "参数列表": "Param List", + "查看": "View", + "监控管理": "Monitor", + "请求日志": "Log", + "权限": "Auth", + "任务管理": "Task", + "任务列表": "Task List", + "框架教程": "Tutorial", + "文档官网": "Docs", + "crud 示例": "CRUD", + "通用": "Common", + "图片上传": "Upload", + "首页": "Home", + "数据管理": "Data", + "字典管理": "Dict", + "获得字典数据": "Get Dict", + "单个信息": "Single", + "列表查询": "List", + "分页查询": "Page", + "组权限": "Group", + "字典类型": "Dict Type", + "数据回收站": "Recycle", + "恢复数据": "Restore", + "文件管理": "File", + "用户管理": "User", + "扩展管理": "Extend", + "插件列表": "Plugin" +} \ No newline at end of file diff --git a/src/locales/menu/zh-cn.json b/src/locales/menu/zh-cn.json new file mode 100644 index 0000000..8a848f5 --- /dev/null +++ b/src/locales/menu/zh-cn.json @@ -0,0 +1,47 @@ +{ + "系统管理": "系统管理", + "权限管理": "权限管理", + "菜单列表": "菜单列表", + "新增": "新增", + "删除": "删除", + "查询": "查询", + "参数": "参数", + "编辑": "编辑", + "角色列表": "角色列表", + "修改": "修改", + "用户列表": "用户列表", + "部门列表": "部门列表", + "新增部门": "新增部门", + "更新部门": "更新部门", + "删除部门": "删除部门", + "部门排序": "部门排序", + "用户转移": "用户转移", + "参数配置": "参数配置", + "参数列表": "参数列表", + "查看": "查看", + "监控管理": "监控管理", + "请求日志": "请求日志", + "权限": "权限", + "任务管理": "任务管理", + "任务列表": "任务列表", + "框架教程": "框架教程", + "文档官网": "文档官网", + "crud 示例": "crud 示例", + "通用": "通用", + "图片上传": "图片上传", + "首页": "首页", + "数据管理": "数据管理", + "字典管理": "字典管理", + "获得字典数据": "获得字典数据", + "单个信息": "单个信息", + "列表查询": "列表查询", + "分页查询": "分页查询", + "组权限": "组权限", + "字典类型": "字典类型", + "数据回收站": "数据回收站", + "恢复数据": "恢复数据", + "文件管理": "文件管理", + "用户管理": "用户管理", + "扩展管理": "扩展管理", + "插件列表": "插件列表" +} \ No newline at end of file diff --git a/src/locales/menu/zh-tw.json b/src/locales/menu/zh-tw.json new file mode 100644 index 0000000..36eeca8 --- /dev/null +++ b/src/locales/menu/zh-tw.json @@ -0,0 +1,47 @@ +{ + "系统管理": "系統管理", + "权限管理": "權限管理", + "菜单列表": "選單列表", + "新增": "新增", + "删除": "刪除", + "查询": "查詢", + "参数": "參數", + "编辑": "編輯", + "角色列表": "角色列表", + "修改": "修改", + "用户列表": "用戶列表", + "部门列表": "部門列表", + "新增部门": "新增部門", + "更新部门": "更新部門", + "删除部门": "刪除部門", + "部门排序": "部門排序", + "用户转移": "用戶轉移", + "参数配置": "參數配置", + "参数列表": "參數列表", + "查看": "查看", + "监控管理": "監控管理", + "请求日志": "請求日誌", + "权限": "權限", + "任务管理": "任務管理", + "任务列表": "任務列表", + "框架教程": "框架教程", + "文档官网": "文件官網", + "crud 示例": "crud 示例", + "通用": "通用", + "图片上传": "圖片上傳", + "首页": "首頁", + "数据管理": "數據管理", + "字典管理": "字典管理", + "获得字典数据": "獲得字典數據", + "单个信息": "單個信息", + "列表查询": "列表查詢", + "分页查询": "分頁查詢", + "组权限": "組權限", + "字典类型": "字典類型", + "数据回收站": "數據回收站", + "恢复数据": "恢復數據", + "文件管理": "文件管理", + "用户管理": "用戶管理", + "扩展管理": "擴展管理", + "插件列表": "插件列表" +} \ No newline at end of file diff --git a/src/locales/msg/.lock b/src/locales/msg/.lock new file mode 100644 index 0000000..d8479e6 --- /dev/null +++ b/src/locales/msg/.lock @@ -0,0 +1 @@ +2025-01-21T11:32:17.869Z \ No newline at end of file diff --git a/src/locales/msg/en.json b/src/locales/msg/en.json new file mode 100644 index 0000000..cfcfe42 --- /dev/null +++ b/src/locales/msg/en.json @@ -0,0 +1,27 @@ +{ + "登录失效~": "Login expired~", + "登录失效或无权限访问~": "Login expired or no access~", + "账户或密码不正确~": "Incorrect account or password~", + "该用户未设置任何角色,无法登录~": "No role set, cannot login~", + "验证码不正确": "Incorrect code", + "代码结构不正确,请检查": "Invalid code structure, check", + "存在相同的keyName": "Duplicate keyName", + "非法操作~": "Illegal operation~", + "用户名已经存在~": "Username exists~", + "用户不存在": "User not found", + "原密码错误": "Wrong old password", + "非法的key值": "Invalid key", + "上传文件为空": "Empty upload", + "插件信息不完整": "Incomplete plugin info", + "插件key不能为plugin,请更换其他key": "Plugin key cannot be 'plugin', change it", + "更新失败,参数错误或者手机号已存在": "Update failed, wrong params or phone exists", + "验证码错误": "Wrong code", + "图片验证码错误": "Wrong image code", + "获得手机号失败,请检查配置": "Failed to get phone, check config", + "token类型非refreshToken": "Token type not refreshToken", + "账号或密码错误": "Wrong account or password", + "发送过于频繁,请稍后再试": "Too frequent, try later", + "用户不存在或已被禁用": "User not found or disabled", + "登录失败,请重试": "Login failed, retry", + "获取手机号失败,请刷新重试": "Failed to get phone, refresh and retry" +} \ No newline at end of file diff --git a/src/locales/msg/zh-cn.json b/src/locales/msg/zh-cn.json new file mode 100644 index 0000000..9725c03 --- /dev/null +++ b/src/locales/msg/zh-cn.json @@ -0,0 +1,27 @@ +{ + "登录失效~": "登录失效~", + "登录失效或无权限访问~": "登录失效或无权限访问~", + "账户或密码不正确~": "账户或密码不正确~", + "该用户未设置任何角色,无法登录~": "该用户未设置任何角色,无法登录~", + "验证码不正确": "验证码不正确", + "代码结构不正确,请检查": "代码结构不正确,请检查", + "存在相同的keyName": "存在相同的keyName", + "非法操作~": "非法操作~", + "用户名已经存在~": "用户名已经存在~", + "用户不存在": "用户不存在", + "原密码错误": "原密码错误", + "非法的key值": "非法的key值", + "上传文件为空": "上传文件为空", + "插件信息不完整": "插件信息不完整", + "插件key不能为plugin,请更换其他key": "插件key不能为plugin,请更换其他key", + "更新失败,参数错误或者手机号已存在": "更新失败,参数错误或者手机号已存在", + "验证码错误": "验证码错误", + "图片验证码错误": "图片验证码错误", + "获得手机号失败,请检查配置": "获得手机号失败,请检查配置", + "token类型非refreshToken": "token类型非refreshToken", + "账号或密码错误": "账号或密码错误", + "发送过于频繁,请稍后再试": "发送过于频繁,请稍后再试", + "用户不存在或已被禁用": "用户不存在或已被禁用", + "登录失败,请重试": "登录失败,请重试", + "获取手机号失败,请刷新重试": "获取手机号失败,请刷新重试" +} \ No newline at end of file diff --git a/src/locales/msg/zh-tw.json b/src/locales/msg/zh-tw.json new file mode 100644 index 0000000..8ab073d --- /dev/null +++ b/src/locales/msg/zh-tw.json @@ -0,0 +1,27 @@ +{ + "登录失效~": "登入失效~", + "登录失效或无权限访问~": "登入失效或無權限訪問~", + "账户或密码不正确~": "帳號或密碼不正確~", + "该用户未设置任何角色,无法登录~": "該用戶未設置任何角色,無法登入~", + "验证码不正确": "驗證碼不正確", + "代码结构不正确,请检查": "代碼結構不正確,請檢查", + "存在相同的keyName": "存在相同的keyName", + "非法操作~": "非法操作~", + "用户名已经存在~": "用戶名已經存在~", + "用户不存在": "用戶不存在", + "原密码错误": "原密碼錯誤", + "非法的key值": "非法的key值", + "上传文件为空": "上傳文件為空", + "插件信息不完整": "插件信息不完整", + "插件key不能为plugin,请更换其他key": "插件key不能為plugin,請更換其他key", + "更新失败,参数错误或者手机号已存在": "更新失敗,參數錯誤或手機號已存在", + "验证码错误": "驗證碼錯誤", + "图片验证码错误": "圖片驗證碼錯誤", + "获得手机号失败,请检查配置": "獲取手機號失敗,請檢查配置", + "token类型非refreshToken": "token類型非refreshToken", + "账号或密码错误": "帳號或密碼錯誤", + "发送过于频繁,请稍后再试": "發送過於頻繁,請稍後再試", + "用户不存在或已被禁用": "用戶不存在或已被禁用", + "登录失败,请重试": "登入失敗,請重試", + "获取手机号失败,请刷新重试": "獲取手機號失敗,請刷新重試" +} \ No newline at end of file diff --git a/src/modules/base/middleware/translate.ts b/src/modules/base/middleware/translate.ts index d94e248..a9f883c 100644 --- a/src/modules/base/middleware/translate.ts +++ b/src/modules/base/middleware/translate.ts @@ -30,7 +30,7 @@ export class BaseTranslateMiddleware resolve() { return async (ctx, next: NextFunction) => { const url = ctx.url; - const language = 'en'; + const language = ctx.get('language'); let data; try { data = await next(); @@ -58,7 +58,6 @@ export class BaseTranslateMiddleware } // 处理菜单翻译 if (url == '/admin/base/comm/permmenu') { - console.log(data); for (const menu of data.data.menus) { if (menu.name) { menu.name = await this.baseTranslateService.translate( @@ -69,6 +68,47 @@ export class BaseTranslateMiddleware } } } + if (url == '/admin/base/sys/menu/list') { + for (const menu of data.data) { + if (menu.name) { + menu.name = await this.baseTranslateService.translate( + 'menu', + language, + menu.name + ); + } + } + } + // 处理字典翻译 + if (url == '/admin/dict/info/list') { + for (const dict of data.data) { + dict.name = await this.baseTranslateService.translate( + 'dict:info', + language, + dict.name + ); + } + } + if (url == '/admin/dict/type/page') { + for (const dict of data.data.list) { + dict.name = await this.baseTranslateService.translate( + 'dict:type', + language, + dict.name + ); + } + } + if (url == '/admin/dict/info/data' || url == '/app/dict/info/data') { + for (const key in data.data) { + for (const item of data.data[key]) { + item.name = await this.baseTranslateService.translate( + 'dict:info', + language, + item.name + ); + } + } + } }; } } diff --git a/src/modules/base/service/translate.ts b/src/modules/base/service/translate.ts index 0dc910d..b8cda57 100644 --- a/src/modules/base/service/translate.ts +++ b/src/modules/base/service/translate.ts @@ -15,6 +15,8 @@ import { import * as path from 'path'; import * as fs from 'fs'; import axios from 'axios'; +import { DictInfoEntity } from '../../dict/entity/info'; +import { DictTypeEntity } from '../../dict/entity/type'; /** * 翻译服务 */ @@ -24,6 +26,12 @@ export class BaseTranslateService { @InjectEntityModel(BaseSysMenuEntity) baseSysMenuEntity: Repository; + @InjectEntityModel(DictInfoEntity) + dictInfoEntity: Repository; + + @InjectEntityModel(DictTypeEntity) + dictTypeEntity: Repository; + // 基础路径 basePath: string; @@ -47,6 +55,9 @@ export class BaseTranslateService { msgMap: Record = {}; + // 添加字典映射 + dictMap: Record = {}; + /** * 检查是否存在锁文件 */ @@ -71,33 +82,65 @@ export class BaseTranslateService { this.basePath = path.join(this.app.getBaseDir(), '..', 'src', 'locales'); } + // 清空现有映射 + this.menuMap = {}; + this.msgMap = {}; + this.dictMap = {}; + // 加载菜单翻译 - const menuDir = path.join(this.basePath, 'menu'); - if (fs.existsSync(menuDir)) { - const files = fs.readdirSync(menuDir); + await this.loadTypeTranslations('menu', this.menuMap); + + // 加载消息翻译 + await this.loadTypeTranslations('msg', this.msgMap); + + // 加载字典翻译 + await this.loadDictTranslations(); + } + + /** + * 加载指定类型的翻译 + * @param type 翻译类型 + * @param map 映射对象 + */ + private async loadTypeTranslations( + type: 'menu' | 'msg', + map: Record + ) { + const dirPath = path.join(this.basePath, type); + if (fs.existsSync(dirPath)) { + const files = fs.readdirSync(dirPath); for (const file of files) { if (file.endsWith('.json')) { const language = file.replace('.json', ''); - const content = fs.readFileSync(path.join(menuDir, file), 'utf-8'); + const content = fs.readFileSync(path.join(dirPath, file), 'utf-8'); const translations = JSON.parse(content); for (const [key, value] of Object.entries(translations)) { - this.menuMap[`${language}:${key}`] = value as string; + map[`${language}:${key}`] = value as string; } } } } + } - // 加载消息翻译 - const msgDir = path.join(this.basePath, 'msg'); - if (fs.existsSync(msgDir)) { - const files = fs.readdirSync(msgDir); - for (const file of files) { - if (file.endsWith('.json')) { - const language = file.replace('.json', ''); - const content = fs.readFileSync(path.join(msgDir, file), 'utf-8'); - const translations = JSON.parse(content); - for (const [key, value] of Object.entries(translations)) { - this.msgMap[`${language}:${key}`] = value as string; + /** + * 加载字典翻译 + */ + private async loadDictTranslations() { + const dictTypes = ['info', 'type']; + + for (const dictType of dictTypes) { + const dirPath = path.join(this.basePath, 'dict', dictType); + if (fs.existsSync(dirPath)) { + const files = fs.readdirSync(dirPath); + for (const file of files) { + if (file.endsWith('.json')) { + const language = file.replace('.json', ''); + const content = fs.readFileSync(path.join(dirPath, file), 'utf-8'); + const translations = JSON.parse(content); + for (const [key, value] of Object.entries(translations)) { + this.dictMap[`${language}:dict:${dictType}:${key}`] = + value as string; + } } } } @@ -126,12 +169,23 @@ export class BaseTranslateService { /** * 翻译 - * @param type 类型 menu | msg + * @param type 类型 menu | msg | dict * @param language 语言 * @param text 原文 * @returns 翻译后的文本 */ - translate(type: 'menu' | 'msg', language: string, text: string): string { + translate( + type: 'menu' | 'msg' | 'dict:info' | 'dict:type', + language: string, + text: string + ): string { + // 处理字典翻译 + if (type === 'dict:info' || type === 'dict:type') { + const key = `${language}:${type}:${text}`; + return this.dictMap[key] || text.split(':').pop() || text; + } + + // 处理菜单和消息翻译 const map = type === 'menu' ? this.menuMap : this.msgMap; const key = `${language}:${text}`; return map[key] || text; @@ -146,8 +200,9 @@ export class BaseTranslateService { const menuLockExists = this.checkLockFile('menu'); const msgLockExists = this.checkLockFile('msg'); + const dictLockExists = this.checkDictLockFile(); - if (!menuLockExists || !msgLockExists) { + if (!menuLockExists || !msgLockExists || !dictLockExists) { const tasks = []; if (!msgLockExists) { tasks.push(this.genBaseMsg()); @@ -155,14 +210,145 @@ export class BaseTranslateService { if (!menuLockExists) { tasks.push(this.genBaseMenu()); } + if (!dictLockExists) { + tasks.push(this.genBaseDict()); + } await Promise.all(tasks); this.logger.info('All translations completed successfully'); // 更新翻译映射 await this.loadTranslations(); + await this.loadDictTranslations(); } else { this.logger.info('Translation lock files exist, skipping translation'); // 直接加载翻译文件到内存 await this.loadTranslations(); + await this.loadDictTranslations(); + } + } + } + + /** + * 检查字典锁文件 + */ + private checkDictLockFile(): boolean { + const lockFile = path.join(this.basePath, 'dict', '.lock'); + return fs.existsSync(lockFile); + } + + /** + * 创建字典锁文件 + */ + private createDictLockFile(): void { + const lockFile = path.join(this.basePath, 'dict', '.lock'); + fs.writeFileSync(lockFile, new Date().toISOString()); + } + + /** + * 生成基础字典 + */ + async genBaseDict() { + try { + // 检查是否存在锁文件 + if (this.checkDictLockFile()) { + this.logger.info('Dictionary lock file exists, skipping translation'); + return; + } + + const infos = await this.dictInfoEntity.find(); + const types = await this.dictTypeEntity.find(); + + // 确保目录存在 + const infoDir = path.join(this.basePath, 'dict', 'info'); + const typeDir = path.join(this.basePath, 'dict', 'type'); + fs.mkdirSync(infoDir, { recursive: true }); + fs.mkdirSync(typeDir, { recursive: true }); + + // 生成中文基础文件 + const infoContent = {}; + const typeContent = {}; + + for (const info of infos) { + infoContent[info.name] = info.name; + } + for (const type of types) { + typeContent[type.name] = type.name; + } + + const infoFile = path.join(infoDir, 'zh-cn.json'); + const typeFile = path.join(typeDir, 'zh-cn.json'); + + const infoText = JSON.stringify(infoContent, null, 2); + const typeText = JSON.stringify(typeContent, null, 2); + + fs.writeFileSync(infoFile, infoText); + fs.writeFileSync(typeFile, typeText); + + this.logger.info('Base dictionary files generated successfully'); + + // 翻译其他语言 + if (this.config?.enable && this.config.languages) { + const translatePromises = []; + + for (const language of this.config.languages) { + if (language !== 'zh-cn') { + // 翻译 info 字典 + translatePromises.push( + this.invokeTranslate(infoText, language, infoDir, 'dict') + ); + + // 翻译 type 字典 + translatePromises.push( + this.invokeTranslate(typeText, language, typeDir, 'dict') + ); + } + } + + await Promise.all(translatePromises); + this.logger.info('Dictionary translations completed successfully'); + } + + // 创建锁文件 + this.createDictLockFile(); + + // 更新翻译映射 + await this.loadDictTranslations(); + } catch (error) { + this.logger.error('Failed to generate dictionary:', error); + throw error; + } + } + + /** + * 更新字典翻译映射 + * @param language 语言 + */ + async updateDictTranslationMap(language: string) { + const infoFile = path.join( + this.basePath, + 'dict', + 'info', + `${language}.json` + ); + const typeFile = path.join( + this.basePath, + 'dict', + 'type', + `${language}.json` + ); + + if (fs.existsSync(infoFile)) { + const content = fs.readFileSync(infoFile, 'utf-8'); + const translations = JSON.parse(content); + for (const [key, value] of Object.entries(translations)) { + this.dictMap[`${language}:dict:info:${key}`] = value as string; + } + } + + if (fs.existsSync(typeFile)) { + const content = fs.readFileSync(typeFile, 'utf-8'); + const translations = JSON.parse(content); + for (const [key, value] of Object.entries(translations)) { + this.dictMap[`${language}:dict:type:${key}`] = value as string; } } } @@ -277,7 +463,7 @@ export class BaseTranslateService { text: string, language: string, dirPath: string, - type: 'menu' | 'msg' = 'msg' + type: 'menu' | 'msg' | 'dict' = 'msg' ) { this.logger.info(`${type} ${language} translate start`); const response = await axios.post(I18N.DEFAULT_SERVICE_URL, { diff --git a/src/modules/demo/controller/admin/goods.ts b/src/modules/demo/controller/admin/goods.ts index 5c60567..f729434 100644 --- a/src/modules/demo/controller/admin/goods.ts +++ b/src/modules/demo/controller/admin/goods.ts @@ -2,6 +2,7 @@ import { CoolController, BaseController } from '@cool-midway/core'; import { DemoGoodsEntity } from '../../entity/goods'; import { Get, Inject } from '@midwayjs/core'; import { DemoGoodsService } from '../../service/goods'; +import { UserInfoEntity } from '../../../user/entity/info'; /** * 商品模块-商品信息 @@ -9,6 +10,19 @@ import { DemoGoodsService } from '../../service/goods'; @CoolController({ api: ['add', 'delete', 'update', 'info', 'list', 'page'], entity: DemoGoodsEntity, + pageQueryOp: { + keyWordLikeFields: ['a.description'], + fieldEq: ['a.status'], + fieldLike: ['a.title'], + select: ['a.*', 'b.nickName as userName'], + join: [ + { + entity: UserInfoEntity, + alias: 'b', + condition: 'a.id = b.id', + }, + ], + }, }) export class AdminDemoGoodsController extends BaseController { @Inject() diff --git a/src/modules/demo/controller/open/goods.ts b/src/modules/demo/controller/open/goods.ts index ff02264..d2fb311 100644 --- a/src/modules/demo/controller/open/goods.ts +++ b/src/modules/demo/controller/open/goods.ts @@ -12,6 +12,9 @@ import { Repository } from 'typeorm'; api: ['add', 'delete', 'update', 'info', 'list', 'page'], entity: DemoGoodsEntity, service: DemoGoodsService, + pageQueryOp: { + fieldLike: ['title'], + }, }) export class OpenDemoGoodsController extends BaseController { @InjectEntityModel(DemoGoodsEntity) diff --git a/src/modules/demo/entity/goods.ts b/src/modules/demo/entity/goods.ts index d031bbd..dc9529c 100644 --- a/src/modules/demo/entity/goods.ts +++ b/src/modules/demo/entity/goods.ts @@ -24,6 +24,12 @@ export class DemoGoodsEntity extends BaseEntity { @Column({ comment: '主图', nullable: true }) mainImage: string; + @Column({ comment: '分类', dict: 'goodsType' }) + type: number; + + @Column({ comment: '状态', dict: ['禁用', '启用'], default: 1 }) + status: number; + @Column({ comment: '示例图', nullable: true, type: 'json' }) exampleImages: string[]; diff --git a/src/modules/plugin/entity/info.ts b/src/modules/plugin/entity/info.ts index ddb0ad0..5349ad6 100644 --- a/src/modules/plugin/entity/info.ts +++ b/src/modules/plugin/entity/info.ts @@ -1,7 +1,5 @@ import { BaseEntity } from '../../base/entity/base'; -import { Column, Entity, DataSource, Index } from 'typeorm'; - -console.log(DataSource); +import { Column, Entity, Index } from 'typeorm'; /** * 插件信息 diff --git a/src/modules/user/controller/admin/info.ts b/src/modules/user/controller/admin/info.ts index 12f1480..4bd8828 100644 --- a/src/modules/user/controller/admin/info.ts +++ b/src/modules/user/controller/admin/info.ts @@ -1,5 +1,6 @@ import { CoolController, BaseController } from '@cool-midway/core'; import { UserInfoEntity } from '../../entity/info'; +import { DemoGoodsEntity } from '../../../demo/entity/goods'; /** * 用户信息 @@ -9,7 +10,16 @@ import { UserInfoEntity } from '../../entity/info'; entity: UserInfoEntity, pageQueryOp: { fieldEq: ['status', 'gender', 'loginType'], + fieldLike: ['b.title'], keyWordLikeFields: ['nickName', 'phone'], + select: ['a.*', 'b.title as goodsName'], + join: [ + { + entity: DemoGoodsEntity, + alias: 'b', + condition: 'a.id = b.id', + }, + ], }, }) export class AdminUserInfoController extends BaseController {} diff --git a/src/modules/user/entity/info.ts b/src/modules/user/entity/info.ts index 45effe3..21d9b24 100644 --- a/src/modules/user/entity/info.ts +++ b/src/modules/user/entity/info.ts @@ -20,15 +20,18 @@ export class UserInfoEntity extends BaseEntity { @Column({ comment: '手机号', nullable: true }) phone: string; - @Column({ comment: '性别 0-未知 1-男 2-女', default: 0 }) + @Column({ comment: '性别', dict: ['未知', '男', '女'], default: 0 }) gender: number; - @Column({ comment: '状态 0-禁用 1-正常 2-已注销', default: 1 }) + @Column({ comment: '状态', dict: ['禁用', '正常', '已注销'], default: 1 }) status: number; - @Column({ comment: '登录方式 0-小程序 1-公众号 2-H5', default: 0 }) + @Column({ comment: '登录方式', dict: ['小程序', '公众号', 'H5'], default: 0 }) loginType: number; + @Column({ comment: '来源', dict: 'sourceType', default: 0 }) + source: number; + @Column({ comment: '密码', nullable: true }) password: string; }