diff --git a/healthlink-his-ui/package.json b/healthlink-his-ui/package.json index dcc6f0f49..04072c176 100755 --- a/healthlink-his-ui/package.json +++ b/healthlink-his-ui/package.json @@ -65,6 +65,7 @@ "vue": "^3.5.25", "vue-area-linkage": "^5.1.0", "vue-cropper": "^1.1.1", + "vue-i18n": "^11.4.6", "vue-plugin-hiprint": "^0.0.60", "vue-router": "^4.6.4", "vxe-pc-ui": "^4.14.26", diff --git a/healthlink-his-ui/src/i18n/index.js b/healthlink-his-ui/src/i18n/index.js new file mode 100644 index 000000000..694dd27ed --- /dev/null +++ b/healthlink-his-ui/src/i18n/index.js @@ -0,0 +1,71 @@ +import { createI18n } from 'vue-i18n' +import Cookies from 'js-cookie' +import { ElMessageBox } from 'element-plus' + +const messages = { + 'zh-CN': {}, + 'en': {}, + 'vi': {} +} + +// Lazy load locale messages +const loadLocaleMessages = async () => { + const localeFiles = import.meta.glob('./locales/*.json', { eager: true }) + for (const path in localeFiles) { + const localeName = path.match(/\.\/locales\/(.+)\.json$/)?.[1] + if (!localeName) continue + + let isoCode + if (localeName === 'zhCN') isoCode = 'zh-CN' + else if (localeName === 'enUS') isoCode = 'en' + else if (localeName === 'viVN') isoCode = 'vi' + else { + isoCode = localeName.replace(/([A-Z])/g, '-$1').toLowerCase() + } + + if (!messages[isoCode]) messages[isoCode] = {} + messages[isoCode] = { ...messages[isoCode], ...localeFiles[path].default } + } +} + +const getSavedLocale = () => { + return Cookies.get('lang') || localStorage.getItem('lang') || 'zh-CN' +} + +let i18nInstance = null + +export const initI18n = async () => { + await loadLocaleMessages() + const locale = getSavedLocale() + + i18nInstance = createI18n({ + legacy: false, + locale: locale, + fallbackLocale: 'zh-CN', + messages, + silentFallbackWarn: true, + silentTranslationWarn: true + }) + + return i18nInstance +} + +export const getI18nInstance = () => i18nInstance + +export const changeLocale = async (newLocale) => { + if (!i18nInstance) return + + i18nInstance.global.locale.value = newLocale + + Cookies.set('lang', newLocale, { expires: 365 }) + localStorage.setItem('lang', newLocale) + + // Reload locale messages if needed + await loadLocaleMessages() +} + +export const t = (key, ...params) => { + if (!i18nInstance) return key + const { t: tFunc } = i18nInstance.global + return tFunc(key, ...params) +} diff --git a/healthlink-his-ui/src/i18n/locales/enUS.json b/healthlink-his-ui/src/i18n/locales/enUS.json new file mode 100644 index 000000000..71acb88e5 --- /dev/null +++ b/healthlink-his-ui/src/i18n/locales/enUS.json @@ -0,0 +1,212 @@ +{ + "nav": { + "dashboard": "Dashboard", + "system": "System Settings", + "userManagement": "User Management", + "roleManagement": "Role Management", + "menuManagement": "Menu Management", + "dictionaryManagement": "Dictionary Management", + "organizationManagement": "Organization", + "onlineUsers": "Online Users", + "jobManagement": "Job Management", + "druid": "Data Monitoring", + "operationalLogs": "Operational Logs", + "codeGeneration": "Code Generation", + "interfaceManagement": "Interface Management" + }, + "login": { + "title": "Login", + "username": "Username", + "password": "Password", + "captcha": "Verification Code", + "rememberMe": "Remember Me", + "forgetPassword": "Forgot Password", + "loginButton": "Login", + "placeholderUsername": "Enter username", + "placeholderPassword": "Enter password", + "placeholderCaptcha": "Enter verification code", + "placeholderTenantId": "Enter tenant ID", + "tenantId": "Tenant ID", + "noTenant": "No tenant selection needed", + "loginSuccess": "Login successful", + "logoutSuccess": "Logged out", + "pleaseSelectTenant": "Please select tenant" + }, + "common": { + "add": "Add", + "edit": "Edit", + "delete": "Delete", + "search": "Search", + "reset": "Reset", + "confirm": "OK", + "cancel": "Cancel", + "submit": "Submit", + "save": "Save", + "close": "Close", + "export": "Export", + "import": "Import", + "detail": "Detail", + "view": "View", + "operation": "Operation", + "status": "Status", + "enabled": "Enabled", + "disabled": "Disabled", + "normal": "Normal", + "stop": "Stopped", + "tip": "Tip", + "warning": "Warning", + "error": "Error", + "success": "Success", + "message": "Operation successful", + "confirmDelete": "Confirm to delete this item?", + "confirmBatchDelete": "Confirm to delete selected items?", + "noPermission": "No permission", + "loading": "Loading...", + "noData": "No data", + "pleaseSelect": "Please select", + "pleaseEnter": "Please enter", + "queryTime": "Query Time", + "createTime": "Create Time", + "updateTime": "Update Time", + "operationTime": "Operation Time", + "remark": "Remark", + "operator": "Operator", + "startPage": "First", + "prevPage": "Prev", + "nextPage": "Next", + "endPage": "Last", + "itemPerPage": "items/page", + "pageNum": "Page", + "totalPages": "Total", + "pages": "pages", + "totalItems": "Total", + "items": "items", + "expandColumn": "Expand", + "columnSetting": "Columns", + "refresh": "Refresh", + "collapse": "Collapse", + "expand": "Expand", + "yes": "Yes", + "no": "No" + }, + "system": { + "user": { + "userId": "User ID", + "userName": "Username", + "userType": "User Type", + "nickName": "Nickname", + "deptId": "Department", + "phone": "Phone", + "email": "Email", + "sex": "Gender", + "status": "Status", + "onlineStatus": "Online Status", + "loginIp": "Last Login IP", + "loginDate": "Last Login Time", + "comment": "Remark", + "resetPwd": "Reset Password", + "batchDisable": "Batch Disable", + "batchEnable": "Batch Enable", + "disable": "Disable", + "enable": "Enable", + "authRole": "Assign Roles", + "importTemplate": "Download Template", + "selectDept": "Select Department" + }, + "role": { + "roleId": "Role ID", + "roleName": "Role Name", + "roleKey": "Role Key", + "roleSort": "Sort", + "status": "Status", + "menuPermission": "Menu Permission", + "dataScope": "Data Scope", + "allData": "All Data", + "customData": "Custom Data", + "deptdata": "Dept Data", + "deptAndChildrenData": "Dept & Sub-dept", + "selfData": "Self Only" + }, + "menu": { + "menuId": "Menu ID", + "menuName": "Menu Name", + "parentMenu": "Parent Menu", + "menuType": "Menu Type", + "menuTypeDir": "Directory", + "menuTypeMenu": "Menu", + "menuTypeButton": "Button", + "menuIcon": "Icon", + "menuPath": "Route Path", + "menuComponent": "Component", + "menuPermi": "Permission", + "menuStatus": "Status", + "menuSort": "Sort", + "menuVisible": "Visible", + "menuKeepAlive": "Cache", + "menuHidden": "Hidden", + "menuChild": "Children", + "menuLayout": "Outer Layout", + "menuAlways": "Always Show" + }, + "dict": { + "dictCode": "Dict Code", + "dictName": "Dict Name", + "dictType": "Dict Type", + "dictStatus": "Status", + "dictSort": "Sort", + "dictValue": "Dict Value", + "dictLabel": "Dict Label", + "dictComment": "Remark", + "addDictData": "Add Dict Data", + "editDictData": "Edit Dict Data", + "addDictType": "Add Dict Type", + "editDictType": "Edit Dict Type", + "englishValue": "English Value", + "vietnameseValue": "Vietnamese Value" + } + }, + "dict": { + "sex": "Gender", + "male": "Male", + "female": "Female", + "noticeType": "Notice Type", + "noticeStatus": "Notice Status", + "statusNormal": "Normal", + "statusDisabled": "Disabled", + "yes": "Yes", + "no": "No", + "resultSuccess": "Success", + "resultFail": "Fail" + }, + "message": { + "addSuccess": "Added successfully", + "editSuccess": "Edited successfully", + "deleteSuccess": "Deleted successfully", + "exportSuccess": "Exported successfully", + "importSuccess": "Imported successfully", + "resetSuccess": "Reset successfully", + "confirmDeleteTitle": "Delete Confirmation", + "confirmDeleteContent": "Are you sure to delete this record?", + "confirmBatchDeleteTitle": "Batch Delete Confirmation", + "confirmBatchDeleteContent": "Are you sure to delete {0} selected records?", + "operationFailed": "Operation failed", + "noDataSelected": "Please select data first", + "uploadFailed": "Upload failed", + "downloadFailed": "Download failed", + "copySuccess": "Copied successfully", + "copyFailed": "Copy failed" + }, + "table": { + "index": "#", + "action": "Action", + "actions": "Actions", + "more": "More", + "singleDelete": "Delete", + "batchDelete": "Batch Delete", + "enable": "Enable", + "disable": "Disable", + "assign": "Assign", + "authorization": "Authorization", + "resetPassword": "Reset Password" + } +} diff --git a/healthlink-his-ui/src/i18n/locales/viVN.json b/healthlink-his-ui/src/i18n/locales/viVN.json new file mode 100644 index 000000000..ce39e8a70 --- /dev/null +++ b/healthlink-his-ui/src/i18n/locales/viVN.json @@ -0,0 +1,212 @@ +{ + "nav": { + "dashboard": "Bảng Điều Khiển", + "system": "Cài Đặt Hệ Thống", + "userManagement": "Quản Lý Người Dùng", + "roleManagement": "Quản Lý Vai Trò", + "menuManagement": "Quản Lý Menu", + "dictionaryManagement": "Quản Lý Từ Điển", + "organizationManagement": "Tổ Chức", + "onlineUsers": "Người Dùng Trực Tuyến", + "jobManagement": "Quản Lý Tác Vụ", + "druid": "Giám Sát Dữ Liệu", + "operationalLogs": "Nhật Ký Vận Hành", + "codeGeneration": "Tạo Mã", + "interfaceManagement": "Quản Lý Giao Diện" + }, + "login": { + "title": "Đăng Nhập", + "username": "Tên Đăng Nhập", + "password": "Mật Khẩu", + "captcha": "Mã Xác Minh", + "rememberMe": "Nhớ Tôi", + "forgetPassword": "Quên Mật Khẩu", + "loginButton": "Đăng Nhập", + "placeholderUsername": "Nhập tên đăng nhập", + "placeholderPassword": "Nhập mật khẩu", + "placeholderCaptcha": "Nhập mã xác minh", + "placeholderTenantId": "Nhập mã thuê bao", + "tenantId": "Mã Thuê Bao", + "noTenant": "Không cần chọn thuê bao", + "loginSuccess": "Đăng nhập thành công", + "logoutSuccess": "Đã đăng xuất", + "pleaseSelectTenant": "Vui lòng chọn thuê bao" + }, + "common": { + "add": "Thêm", + "edit": "Sửa", + "delete": "Xóa", + "search": "Tìm Kiếm", + "reset": "Đặt Lại", + "confirm": "Xác Nhận", + "cancel": "Hủy Bỏ", + "submit": "Gửi", + "save": "Lưu", + "close": "Đóng", + "export": "Xuất", + "import": "Nhập", + "detail": "Chi Tiết", + "view": "Xem", + "operation": "Thao Tác", + "status": "Trạng Thái", + "enabled": "Kích Hoạt", + "disabled": "Vô Hiệu Hóa", + "normal": "Bình Thường", + "stop": "Dừng", + "tip": "Mẹo", + "warning": "Cảnh Báo", + "error": "Lỗi", + "success": "Thành Công", + "message": "Thao tác thành công", + "confirmDelete": "Xác nhận xóa mục này?", + "confirmBatchDelete": "Xác nhận xóa các mục đã chọn?", + "noPermission": "Không có quyền", + "loading": "Đang tải...", + "noData": "Không có dữ liệu", + "pleaseSelect": "Vui lòng chọn", + "pleaseEnter": "Vui lòng nhập", + "queryTime": "Thời Gian Truy Vấn", + "createTime": "Thời Gian Tạo", + "updateTime": "Thời Gian Cập Nhật", + "operationTime": "Thời Gian Thao Tác", + "remark": "Ghi Chú", + "operator": "Người Thao Tác", + "startPage": "Đầu", + "prevPage": "Trước", + "nextPage": "Sau", + "endPage": "Cuối", + "itemPerPage": "mục/trang", + "pageNum": "Trang", + "totalPages": "Tổng cộng", + "pages": "trang", + "totalItems": "Tổng cộng", + "items": "mục", + "expandColumn": "Mở rộng", + "columnSetting": "Cột", + "refresh": "Làm Mới", + "collapse": "Thu gọn", + "expand": "Mở rộng", + "yes": "Có", + "no": "Không" + }, + "system": { + "user": { + "userId": "ID Người Dùng", + "userName": "Tên Người Dùng", + "userType": "Loại Người Dùng", + "nickName": "Tên Hiển Thị", + "deptId": "Bộ Phận", + "phone": "Số Điện Thoại", + "email": "Email", + "sex": "Giới Tính", + "status": "Trạng Thái", + "onlineStatus": "Trạng Thái Trực Tuyến", + "loginIp": "IP Đăng Nhập Cuối", + "loginDate": "Thời Gian Đăng Nhập Cuối", + "comment": "Ghi Chú", + "resetPwd": "Đặt Lại Mật Khẩu", + "batchDisable": "Vô Hiệu Hóa Hàng Loạt", + "batchEnable": "Kích Hoạt Hàng Loạt", + "disable": "Vô Hiệu Hóa", + "enable": "Kích Hoạt", + "authRole": "Phân Vai Trò", + "importTemplate": "Tải Mẫu", + "selectDept": "Chọn Bộ Phận" + }, + "role": { + "roleId": "ID Vai Trò", + "roleName": "Tên Vai Trò", + "roleKey": "Mã Vai Trò", + "roleSort": "Sắp Xếp", + "status": "Trạng Thái", + "menuPermission": "Quyền Menu", + "dataScope": "Phạm Vi Dữ Liệu", + "allData": "Tất Cả Dữ Liệu", + "customData": "Tùy Chỉnh", + "deptdata": "Dữ Liệu Bộ Phận", + "deptAndChildrenData": "Bộ Phận & Cấp Dưới", + "selfData": "Chỉ Bản Thân" + }, + "menu": { + "menuId": "ID Menu", + "menuName": "Tên Menu", + "parentMenu": "Menu Cha", + "menuType": "Loại Menu", + "menuTypeDir": "Thư Mục", + "menuTypeMenu": "Menu", + "menuTypeButton": "Nút", + "menuIcon": "Biểu Tượng", + "menuPath": "Đường Dẫn Route", + "menuComponent": "Thành Phần", + "menuPermi": "Quyền Hạn", + "menuStatus": "Trạng Thái", + "menuSort": "Sắp Xếp", + "menuVisible": "Hiển Thị", + "menuKeepAlive": "Bộ Nhớ Đệm", + "menuHidden": "Ẩn", + "menuChild": "Con", + "menuLayout": "Layout Ngoài", + "menuAlways": "Luôn Hiển Thị" + }, + "dict": { + "dictCode": "Mã Từ Điển", + "dictName": "Tên Từ Điển", + "dictType": "Loại Từ Điển", + "dictStatus": "Trạng Thái", + "dictSort": "Sắp Xếp", + "dictValue": "Giá Trị Từ Điển", + "dictLabel": "Nhãn Từ Điển", + "dictComment": "Ghi Chú", + "addDictData": "Thêm Dữ Liệu Từ Điển", + "editDictData": "Sửa Dữ Liệu Từ Điển", + "addDictType": "Thêm Loại Từ Điển", + "editDictType": "Sửa Loại Từ Điển", + "englishValue": "Giá Trị Tiếng Anh", + "vietnameseValue": "Giá Trị Tiếng Việt" + } + }, + "dict": { + "sex": "Giới Tính", + "male": "Nam", + "female": "Nữ", + "noticeType": "Loại Thông Báo", + "noticeStatus": "Trạng Thái Thông Báo", + "statusNormal": "Bình Thường", + "statusDisabled": "Vô Hiệu Hóa", + "yes": "Có", + "no": "Không", + "resultSuccess": "Thành Công", + "resultFail": "Thất Bại" + }, + "message": { + "addSuccess": "Thêm thành công", + "editSuccess": "Sửa thành công", + "deleteSuccess": "Xóa thành công", + "exportSuccess": "Xuất thành công", + "importSuccess": "Nhập thành công", + "resetSuccess": "Đặt lại thành công", + "confirmDeleteTitle": "Xác Nhận Xóa", + "confirmDeleteContent": "Bạn có chắc chắn muốn xóa bản ghi này?", + "confirmBatchDeleteTitle": "Xác Nhận Xóa Hàng Loạt", + "confirmBatchDeleteContent": "Bạn có chắc chắn muốn xóa {0} bản ghi đã chọn?", + "operationFailed": "Thao tác thất bại", + "noDataSelected": "Vui lòng chọn dữ liệu trước", + "uploadFailed": "Tải lên thất bại", + "downloadFailed": "Tải xuống thất bại", + "copySuccess": "Sao chép thành công", + "copyFailed": "Sao chép thất bại" + }, + "table": { + "index": "#", + "action": "Hành Động", + "actions": "Hành Động", + "more": "Thêm", + "singleDelete": "Xóa", + "batchDelete": "Xóa Hàng Loạt", + "enable": "Kích Hoạt", + "disable": "Vô Hiệu Hóa", + "assign": "Phân Bổ", + "authorization": "Ủy Quyền", + "resetPassword": "Đặt Lại Mật Khẩu" + } +} diff --git a/healthlink-his-ui/src/i18n/locales/zhCN.json b/healthlink-his-ui/src/i18n/locales/zhCN.json new file mode 100644 index 000000000..797e5a1a3 --- /dev/null +++ b/healthlink-his-ui/src/i18n/locales/zhCN.json @@ -0,0 +1,214 @@ +{ + "nav": { + "dashboard": "系统仪表盘", + "system": "系统设置", + "userManagement": "用户管理", + "roleManagement": "角色管理", + "menuManagement": "菜单管理", + "dictionaryManagement": "字典管理", + "organizationManagement": "组织机构", + "onlineUsers": "在线用户", + "jobManagement": "定时任务", + "druid": "数据监控", + "operationalLogs": "操作日志", + "codeGeneration": "代码生成", + "interfaceManagement": "接口管理" + }, + "login": { + "title": "登录", + "username": "用户名", + "password": "密码", + "captcha": "验证码", + "rememberMe": "记住我", + "forgetPassword": "忘记密码", + "loginButton": "登录", + "placeholderUsername": "请输入用户名", + "placeholderPassword": "请输入密码", + "placeholderCaptcha": "请输入验证码", + "placeholderTenantId": "请输入租户编号", + "tenantId": "租户编号", + "noTenant": "无需选择租户", + "loginSuccess": "登录成功", + "logoutSuccess": "退出成功", + "pleaseSelectTenant": "请选择租户" + }, + "common": { + "add": "新增", + "edit": "编辑", + "delete": "删除", + "search": "搜索", + "reset": "重置", + "confirm": "确定", + "cancel": "取消", + "submit": "提交", + "save": "保存", + "close": "关闭", + "export": "导出", + "import": "导入", + "detail": "详情", + "view": "查看", + "operation": "操作", + "status": "状态", + "enabled": "启用", + "disabled": "停用", + "normal": "正常", + "stop": "停用", + "tip": "提示", + "warning": "警告", + "error": "错误", + "success": "成功", + "message": "操作成功", + "confirmDelete": "确认删除该项吗?", + "confirmBatchDelete": "确认删除选中的数据项吗?", + "noPermission": "暂无权限", + "loading": "加载中...", + "noData": "暂无数据", + "pleaseSelect": "请选择", + "pleaseEnter": "请输入", + "queryTime": "查询时间", + "createTime": "创建时间", + "updateTime": "更新时间", + "operationTime": "操作时间", + "remark": "备注", + "operator": "操作人员", + "startPage": "首页", + "prevPage": "上一页", + "nextPage": "下一页", + "endPage": "末页", + "itemPerPage": "条/页", + "pageNum": "页码", + "totalPages": "共", + "pages": "页", + "totalItems": "共", + "items": "条", + "expandColumn": "展开列", + "columnSetting": "列设置", + "refresh": "刷新", + "collapse": "收起", + "expand": "展开", + "yes": "是", + "no": "否" + }, + "system": { + "user": { + "userId": "用户ID", + "userName": "用户名称", + "userType": "用户类型", + "nickName": "用户昵称", + "deptId": "归属部门", + "phone": "手机号码", + "email": "邮箱", + "sex": "性别", + "status": "状态", + "onlineStatus": "在线状态", + "loginIp": "最后登录IP", + "loginDate": "最后登录时间", + "comment": "用户备注", + "resetPwd": "重置密码", + "batchDisable": "批量停用", + "batchEnable": "批量启用", + "disable": "停用", + "enable": "启用", + "authRole": "授权角色", + "importTemplate": "下载模板", + "selectDept": "请选择部门" + }, + "role": { + "roleId": "角色ID", + "roleName": "角色名称", + "roleKey": "角色代码", + "roleSort": "角色排序", + "status": "角色状态", + "menuPermission": "菜单权限", + "dataScope": "数据权限", + "allData": "全部数据", + "customData": "自定义数据", + "deptData": "本部门数据", + "deptAndChildrenData": "本部门及下级数据", + "selfData": "仅本人数据", + "assignUser": "分配用户", + "assignUserBatch": "批量分配" + }, + "menu": { + "menuId": "菜单ID", + "menuName": "菜单名称", + "parentMenu": "上级菜单", + "menuType": "菜单类型", + "menuTypeDir": "目录", + "menuTypeMenu": "菜单", + "menuTypeButton": "按钮", + "menuIcon": "菜单图标", + "menuPath": "路由地址", + "menuComponent": "组件路径", + "menuPermi": "权限标识", + "menuStatus": "菜单状态", + "menuSort": "显示排序", + "menuVisible": "显示状态", + "menuKeepAlive": "缓存状态", + "menuHidden": "隐藏状态", + "menuChild": "子菜单", + "menuLayout": "外层菜单", + "menuAlways": "始终显示" + }, + "dict": { + "dictCode": "字典编码", + "dictName": "字典名称", + "dictType": "字典类型", + "dictStatus": "字典状态", + "dictSort": "字典排序", + "dictValue": "字典值", + "dictLabel": "字典标签", + "dictComment": "备注", + "addDictData": "新增字典数据", + "editDictData": "编辑字典数据", + "addDictType": "新增字典类型", + "editDictType": "编辑字典类型", + "englishValue": "英文值", + "vietnameseValue": "越南文值" + } + }, + "dict": { + "sex": "性别", + "male": "男", + "female": "女", + "noticeType": "通知类型", + "noticeStatus": "通知状态", + "statusNormal": "正常", + "statusDisabled": "停用", + "yes": "是", + "no": "否", + "resultSuccess": "成功", + "resultFail": "失败" + }, + "message": { + "addSuccess": "新增成功", + "editSuccess": "编辑成功", + "deleteSuccess": "删除成功", + "exportSuccess": "导出成功", + "importSuccess": "导入成功", + "resetSuccess": "重置成功", + "confirmDeleteTitle": "删除确认", + "confirmDeleteContent": "确定要删除这条记录吗?", + "confirmBatchDeleteTitle": "批量删除确认", + "confirmBatchDeleteContent": "确定要删除选中的{0}条记录吗?", + "operationFailed": "操作失败", + "noDataSelected": "请先选择数据", + "uploadFailed": "上传失败", + "downloadFailed": "下载失败", + "copySuccess": "复制成功", + "copyFailed": "复制失败" + }, + "table": { + "index": "#", + "action": "操作", + "actions": "操作", + "more": "更多", + "singleDelete": "删除", + "batchDelete": "批量删除", + "enable": "启用", + "disable": "停用", + "assign": "分配", + "authorization": "授权", + "resetPassword": "重置密码" + } +}