Browse Source

调整多语言架构;新增繁体中文

tsurumure 3 months ago
parent
commit
f4af0593b2

+ 0 - 17
db/__ai_chat_config.sql

@@ -1,17 +0,0 @@
-# /**
-# Source Server Version: 8.0.31
-# Source Database: backendsys
-# Date: 2023/05/23 17:09:22
-# */
-#
-# DROP TABLE IF EXISTS `ai_chat_config`;
-# CREATE TABLE `ai_chat_config` (
-#     PRIMARY KEY (`id`),
-#     `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
-#     `config_key` VARCHAR(255) COMMENT '配置名称',
-#     `config_value` VARCHAR(255) COMMENT '配置值'
-# ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='AI助手配置表';
-#
-# INSERT INTO ai_chat_config(config_key, config_value) VALUES
-#     ('expired_time', 30)
-# ;

+ 41 - 0
db/__b2c_goods.sql

@@ -0,0 +1,41 @@
+/**
+Source Server Version: 8.0.31
+Source Database: backendsys
+Date: 2023/08/18 12:51:10
+*/
+
+DROP TABLE IF EXISTS `b2c_goods`;
+CREATE TABLE `b2c_goods` (
+    PRIMARY KEY (`id`),
+    `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
+    `category_id` BIGINT NOT NULL COMMENT '商品分类ID',
+    `brand_id` BIGINT COMMENT '商品品牌ID',
+    `unit_id` BIGINT COMMENT '商品单位ID',
+    `good_name` VARCHAR(20) NOT NULL COMMENT '商品名称',
+    `good_description` VARCHAR(200) COMMENT '商品描述',
+    `good_content` TEXT COMMENT '商品内容',
+    `good_thumb` VARCHAR(1000) DEFAULT NULL COMMENT '商品缩略图',
+    `good_images` TEXT DEFAULT NULL COMMENT '商品图片',
+    `meta_keyword` VARCHAR(100) COMMENT 'SEO-Keyword',
+    `meta_description` VARCHAR(200) COMMENT 'SEO-Description',
+    `status` TINYINT(1) DEFAULT '-1' COMMENT '商品状态 (-1下架, 1上架)',
+    `del_flag` TINYINT(1) DEFAULT '-1' COMMENT '删除标志 (-1未删除, 1删除)',
+    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+    INDEX `idx_good_name` (`good_name`)
+) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='商品表';
+
+INSERT INTO b2c_goods(category_id, brand_id, unit_id, good_name, good_description, good_content, status) VALUES
+    (1, 1, 1, '测试商品-1', '测试商品描述描述-1', '测试商品详情内容内容内容内容-1', 1),
+    (1, 1, 1, '测试商品-2', '测试商品描述描述-2', '测试商品详情内容内容内容内容-2', -1),
+    (1, 1, 1, '测试商品-3', '测试商品描述描述-3', '测试商品详情内容内容内容内容-3', -1),
+    (1, 1, 1, '测试商品-4', '测试商品描述描述-4', '测试商品详情内容内容内容内容-4', -1),
+    (1, 1, 1, '测试商品-5', '测试商品描述描述-5', '测试商品详情内容内容内容内容-5', -1),
+    (1, 1, 1, '测试商品-6', '测试商品描述描述-6', '测试商品详情内容内容内容内容-6', -1),
+    (1, 1, 1, '测试商品-7', '测试商品描述描述-7', '测试商品详情内容内容内容内容-7', -1),
+    (1, 1, 1, '测试商品-8', '测试商品描述描述-8', '测试商品详情内容内容内容内容-8', -1),
+    (1, 1, 1, '测试商品-9', '测试商品描述描述-9', '测试商品详情内容内容内容内容-9', -1),
+    (1, 1, 1, '测试商品-10', '测试商品描述描述-10', '测试商品详情内容内容内容内容-10', -1),
+    (1, 1, 1, '测试商品-11', '测试商品描述描述-11', '测试商品详情内容内容内容内容-11', -1),
+    (1, 1, 1, '测试商品-12', '测试商品描述描述-12', '测试商品详情内容内容内容内容-12', -1)
+;

+ 0 - 30
db/__ds_chat.sql

@@ -1,30 +0,0 @@
-# /**
-# Source Server Version: 8.0.31
-# Source Database: backendsys
-# Date: 2023/05/23 17:09:22
-# */
-#
-# DROP TABLE IF EXISTS `ds_chat`;
-# CREATE TABLE `ds_chat` (
-#     PRIMARY KEY (`id`),
-#     `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
-#     `model` VARCHAR(255) COMMENT '模型',
-#     `history_code` VARCHAR(64) NOT NULL COMMENT '对话历史记录ID',
-#     `user_id` BIGINT COMMENT '用户ID',
-#     `user_nickname` VARCHAR(255) COMMENT '用户名',
-#     `role` VARCHAR(255) COMMENT '对话角色 (user, assistant, system, tool)',
-#     `content` VARCHAR(5000) NOT NULL COMMENT '对话内容',
-#     `content_type` VARCHAR(255) NOT NULL COMMENT '对话内容类型 (LOADING-加载中, SEARCH-搜索, REPLY-回复, REPLY-回复, REPLY_ABORT-回复中止, THINK-思考, THINK_ABORT-思考中止)',
-#     `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-#     INDEX `idx_history_code` (`history_code`),
-#     INDEX `idx_user_id` (`user_id`),
-#     INDEX `idx_model` (`model`)
-# ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Deepseek对话表';
-#
-# INSERT INTO ds_chat(model, history_code, user_id, user_nickname, role, content_type, content) VALUES
-#     ('deepseek-reasoner', '5670822e-f0f7-4635-b766-c9c61edef0fa', 1, '超人', 'user', 'REPLY', '生成一条关于制作蛋糕的文案,适用于家用,用料是纯天然无添加剂,主打绿色健康美味的理念'),
-#     ('deepseek-reasoner', '5670822e-f0f7-4635-b766-c9c61edef0fa', null, null, null, 'THINK', '让我想想用户说这段话的含义'),
-#     ('deepseek-reasoner', '5670822e-f0f7-4635-b766-c9c61edef0fa', null, null, 'assistant', 'REPLY', '在家也能享受绿色健康美味!用纯天然无添加剂的食材,带给你和家人最纯净的美味。从选购新鲜食材到烘焙出炉,每一步都充满温馨与乐趣。让我们一起回归自然,享受绿色健康的蛋糕时光!'),
-#     ('deepseek-chat', '4e69922c-f0e7-4f82-905d-0b375e094092', 1, '超人', 'user', 'REPLY', '你好'),
-#     ('deepseek-chat', '4e69922c-f0e7-4f82-905d-0b375e094092', null, null, 'assistant', 'REPLY', '你好,朋友')
-# ;

+ 0 - 23
db/__ds_chat_history.sql

@@ -1,23 +0,0 @@
-# /**
-# Source Server Version: 8.0.31
-# Source Database: backendsys
-# Date: 2023/05/23 17:09:22
-# */
-#
-# DROP TABLE IF EXISTS `ds_chat_history`;
-# CREATE TABLE `ds_chat_history` (
-#     PRIMARY KEY (`id`),
-#     `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
-#     `history_code` VARCHAR(36) NOT NULL COMMENT '对话历史记录ID',
-#     `user_id` BIGINT NOT NULL COMMENT '用户ID',
-#     `last_content` VARCHAR(255) NOT NULL COMMENT '最后一次的对话内容',
-#     `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-#     `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
-#     INDEX `idx_user_id` (`user_id`)
-# ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='Deepseek对话历史记录表';
-#
-# INSERT INTO ds_chat_history(history_code, user_id, last_content) VALUES
-#     ('5670822e-f0f7-4635-b766-c9c61edef0fa', 1, '生成一条关于制作蛋糕的文案,适用于家用,用料是纯天然无添加剂,主打绿色健康美味的理念'),
-#     ('3e69922c-f0e7-4f82-905d-0b375e09409c', 1, '你好'),
-#     ('bd55b4e6-9a4b-4904-99cc-b474bc0a86e4', 2, 'Hello')
-# ;

+ 0 - 27
db/__sys_file.sql

@@ -1,27 +0,0 @@
-# /**
-# Source Server Version: 8.0.31
-# Source Database: backendsys
-# Date: 2023/05/23 17:09:22
-# */
-#
-# DROP TABLE IF EXISTS `sys_file`;
-# CREATE TABLE `sys_file` (
-#     PRIMARY KEY (`id`),
-#     `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
-#     `category_id` BIGINT COMMENT '分类ID',
-#     `user_id` BIGINT COMMENT '拥有者',
-#     `name` VARCHAR(255) NOT NULL COMMENT '文件名称',
-#     `file_local_path` VARCHAR(255) COMMENT '本地路径',
-#     `file_remote_path` VARCHAR(255) COMMENT '远程路径',
-#     `file_remote_path_thumb` VARCHAR(255) COMMENT '远程路径 (缩略图)',
-#     `file_key` VARCHAR(255) COMMENT '腾讯云COS路径',
-#     `size` INT COMMENT '文件大小',
-#     `md5` VARCHAR(255) COMMENT '文件MD5',
-#     `chunk_upload_id` VARCHAR(255) COMMENT '文件分片任务ID',
-#     `chunk_count` INT COMMENT '文件分片数量',
-#     `chunk_current_index` INT COMMENT '当前文件分片索引',
-#     `notes` VARCHAR(255) COMMENT '备注',
-#     `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
-#     `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
-# ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='系统文件表';
-#

+ 0 - 21
db/__sys_file_category.sql

@@ -1,21 +0,0 @@
-# /**
-# Source Server Version: 8.0.31
-# Source Database: backendsys
-# Date: 2023/05/23 17:09:22
-# */
-#
-# DROP TABLE IF EXISTS `sys_file_category`;
-# CREATE TABLE `sys_file_category` (
-#     PRIMARY KEY (`id`),
-#     `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
-#     `category_name` VARCHAR(255) NOT NULL COMMENT '分类名称',
-#     `suffix` VARCHAR(1000) NOT NULL COMMENT '文件后缀',
-#     `sort` INT DEFAULT '1' COMMENT '排序',
-#     `status` TINYINT(1) DEFAULT '1' COMMENT '资讯状态 (-1禁用, 1启用)'
-# ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='系统文件分类表';
-#
-# INSERT INTO sys_file_category(category_name, suffix) VALUES
-#     ('图片', 'jpg, jpeg, png, gif, bmp, tiff, webp'),
-#     ('视频', 'mp4, avi, mov, mkv, wmv, flv, webm'),
-#     ('音频', 'mp3, wav, ogg, aac')
-# ;

+ 6 - 2
db/cms_article_category_i18n.sql

@@ -16,14 +16,18 @@ CREATE TABLE `cms_article_category_i18n` (
 
 INSERT INTO cms_article_category_i18n (article_category_id, language, category_name, category_description) VALUES
     (1, 'zh', '科技创新', '前沿科技与创新动态'),
+    (1, 'zh-tw', '科技創新', '前沿科技與創新動態'),
     (1, 'en', 'Technological Innovation', 'Frontier Technology and Innovation Trends'),
     (2, 'zh', '健康生活', '为你解析情感与人际关系'),
+    (2, 'zh-tw', '健康生活', '為你解析情感與人際關係'),
     (2, 'en', 'Healthy life', 'For you to analyze emotions and relationships'),
     (3, 'zh', '情感关系', '为你解析情感与人际关系'),
+    (3, 'zh-tw', '情感關係', '為你解析情感與人際關係'),
     (3, 'en', 'Emotional Relationships', 'Analyze Emotions and Interpersonal Relationships'),
     (4, 'zh', '旅行探索', '探索世界各地的旅行分享'),
+    (4, 'zh-tw', '旅行探索', '探索世界各地的旅行分享'),
     (4, 'en', 'Travel Exploration', 'Discover Travel Experiences from Around the World'),
     (5, 'zh', '美食烹饪', '养眼美食与烹饪技巧'),
+    (5, 'zh-tw', '美食烹飪', '養眼美食與烹飪技巧'),
     (5, 'en', 'Culinary Delights', 'Eye-pleasing Dishes and Cooking Techniques')
-;
-
+;

+ 12 - 0
db/cms_article_i18n.sql

@@ -19,27 +19,39 @@ CREATE TABLE `cms_article_i18n` (
 
 INSERT INTO cms_article_i18n(article_id, language, title, description, content, meta_keyword, meta_description) VALUES
     (1, 'zh', '夏日户外露营指南', '如何在户外享受舒适露营', '<h2>夏日户外露营指南</h2><p>夏天是露营的最佳季节,以下是一些实用的露营技巧:</p><ul><li><strong>选择合适的露营地:</strong>选择一个平坦、靠近水源且远离野生动物的地方。</li><li><strong>准备必要的装备:</strong>帐篷、睡袋、防潮垫、头灯、驱蚊剂等。</li><li><strong>注意安全:</strong>在户外要注意防火、防虫、防野生动物。</li></ul><p>希望这些技巧能帮助你在大自然中度过一个愉快的露营之旅!</p>', '露营,户外,指南', '一份全面的户外露营指南,帮助你享受大自然'),
+    (1, 'zh-tw', '夏日戶外露營指南', '如何在戶外享受舒適露營', '<h2>夏日戶外露營指南</h2><p>夏天是露營的最佳季節,以下是一些實用的露營技巧:</p><ul><li><strong>選擇合適的露營地:</strong>選擇一個平坦、靠近水源且遠離野生動物的地方。</li><li><strong>準備必要的裝備:</strong>帳篷、睡袋、防潮墊、頭燈、驅蚊劑等。</li><li><strong>注意安全:</strong>在戶外要注意防火、防蟲、防野生動物。</li></ul><p>希望這些技巧能幫助你在大自然中度過一個愉快的露營之旅!</p>', '露營,戶外,指南', '一份全面的戶外露營指南,幫助你享受大自然'),
     (1, 'en', 'Summer Camping Guide', 'How to enjoy comfortable camping outdoors', '<h2>Summer Camping Guide</h2><p>Summer is the perfect season for camping. Here are some useful camping tips:</p><ul><li><strong>Choose the right campsite:</strong> Select a flat area near water and away from wildlife.</li><li><strong>Prepare necessary gear:</strong> Tent, sleeping bag, ground pad, headlamp, insect repellent, etc.</li><li><strong>Pay attention to safety:</strong> Be cautious of fire, insects, and wildlife while camping.</li></ul><p>Hope these tips help you enjoy a pleasant camping trip in nature!</p>', 'Camping, outdoors, guide', 'A comprehensive camping guide to help you enjoy nature'),
     (2, 'zh', '城市夜景摄影技巧', '捕捉城市夜晚的美丽瞬间', '<h2>城市夜景摄影技巧</h2><p>城市夜景摄影可以捕捉到独特的光影效果,以下是一些技巧:</p><ul><li><strong>选择合适的拍摄地点:</strong>高楼大厦的顶部或桥梁是绝佳的拍摄点。</li><li><strong>使用三脚架:</strong>稳定相机,避免手抖影响照片质量。</li><li><strong>调整相机设置:</strong>使用低ISO、小光圈和慢快门,以获得清晰的夜景照片。</li></ul><p>通过这些技巧,你可以拍摄出令人惊叹的城市夜景照片!</p>', '摄影,夜景,技巧', '捕捉城市夜晚的美丽瞬间'),
+    (2, 'zh-tw', '城市夜景攝影技巧', '捕捉城市夜晚的美麗瞬間', '<h2>城市夜景攝影技巧</h2><p>城市夜景攝影可以捕捉到獨特的光影效果,以下是一些技巧:</p><ul><li><strong>選擇合適的拍攝地點:</strong>高樓大廈的頂部或橋梁是絕佳的拍攝點。</li><li><strong>使用三腳架:</strong>穩定相機,避免手抖影響照片質量。</li><li><strong>調整相機設置:</strong>使用低ISO、小光圈和慢快門,以獲得清晰的夜景照片。</li></ul><p>通過這些技巧,你可以拍攝出令人驚嘆的城市夜景照片!</p>', '攝影,夜景,技巧', '捕捉城市夜晚的美麗瞬間'),
     (2, 'en', 'Urban Night Photography Tips', 'Capturing the beauty of the city at night', '<h2>Urban Night Photography Tips</h2><p>Capturing the beauty of urban night scenes can produce unique lighting effects. Here are some tips:</p><ul><li><strong>Choose the right shooting location:</strong> The tops of skyscrapers or bridges are excellent spots.</li><li><strong>Use a tripod:</strong> Stabilize the camera to avoid blurry photos due to hand shake.</li><li><strong>Adjust camera settings:</strong> Use low ISO, small aperture, and slow shutter speed for clear night photos.</li></ul><p>With these tips, you can capture amazing urban night photos!</p>', 'Photography, night view, tips', 'Capturing the beauty of the city at night'),
     (3, 'zh', '春季赏花好去处', '推荐几个适合赏花的地方', '<h2>春季赏花好去处</h2><p>春天是赏花的好季节,以下是一些国内最美的赏花地点:</p><ul><li><strong>武汉大学樱花大道:</strong>每年三月,樱花盛开,如粉色云霞。</li><li><strong>婺源油菜花田:</strong>金黄的油菜花与古村落相映成趣。</li><li><strong>林芝桃花沟:</strong>桃花盛开时,漫山遍野,如诗如画。</li></ul><p>这些地方不仅能让你欣赏到美丽的花朵,还能感受春天的气息。</p>', '赏花,春季,地点', '推荐几个适合赏花的地方'),
+    (3, 'zh-tw', '春季賞花好去處', '推薦幾個適合賞花的地方', '<h2>春季賞花好去處</h2><p>春天是賞花的好季節,以下是一些國內最美的賞花地點:</p><ul><li><strong>武漢大學櫻花大道:</strong>每年三月,櫻花盛開,如粉色雲霞。</li><li><strong>婺源油菜花田:</strong>金黃的油菜花與古村落相映成趣。</li><li><strong>林芝桃花溝:</strong>桃花盛開時,漫山遍野,如詩如畫。</li></ul><p>這些地方不僅能讓你欣賞到美麗的花朵,還能感受春天的氣息。</p>', '賞花,春季,地點', '推薦幾個適合賞花的地方'),
     (3, 'en', 'Best Flower Viewing Spots in Spring', 'Recommend some great places for flower viewing', '<h2>Best Flower Viewing Spots in Spring</h2><p>Spring is the perfect season for flower viewing. Here are some of the most beautiful flower viewing spots in the country:</p><ul><li><strong>Wuhan University Cherry Blossom Avenue:</strong> In March every year, the cherry blossoms bloom like pink clouds.</li><li><strong>Wuyuan Rapeseed Flower Fields:</strong> The golden rapeseed flowers contrast beautifully with ancient villages.</li><li><strong>Linzhi Peach Blossom Valley:</strong> When the peach blossoms bloom, the mountains are covered in a picturesque scene.</li></ul><p>These places not only allow you to enjoy beautiful flowers but also let you feel the spring atmosphere.</p>', 'Flower viewing, spring, locations', 'Recommend some great places for flower viewing'),
     (4, 'zh', '健身新手入门指南', '如何开始你的健身之旅', '<h2>健身新手入门指南</h2><p>健身可以改善身体素质和健康状况,以下是一些入门建议:</p><ul><li><strong>设定目标:</strong>明确你的健身目标,如增肌、减脂或提高体能。</li><li><strong>制定计划:</strong>根据目标制定合理的训练和饮食计划。</li><li><strong>逐步开始:</strong>从简单的动作开始,逐渐增加难度和强度。</li></ul><p>希望这些指南能帮助你迈出健身的第一步!</p>', '健身,新手,指南', '帮助你开始健身之旅'),
+    (4, 'zh-tw', '健身新手入門指南', '如何開始你的健身之旅', '<h2>健身新手入門指南</h2><p>健身可以改善身體素質和健康狀況,以下是一些入門建議:</p><ul><li><strong>設定目標:</strong>明確你的健身目標,如增肌、減脂或提高體能。</li><li><strong>制定計劃:</strong>根據目標制定合理的訓練和飲食計劃。</li><li><strong>逐步開始:</strong>從簡單的動作開始,逐漸增加難度和強度。</li></ul><p>希望這些指南能幫助你邁出健身的第一步!</p>', '健身,新手,指南', '幫助你開始健身之旅'),
     (4, 'en', 'Fitness Beginner\'s Guide', 'How to start your fitness journey', '<h2>Fitness Beginner\'s Guide</h2><p>Fitness can improve physical fitness and health. Here are some tips for getting started:</p><ul><li><strong>Set goals:</strong> Clarify your fitness goals, such as muscle building, fat loss, or improving physical fitness.</li><li><strong>Make a plan:</strong> Create a reasonable training and diet plan based on your goals.</li><li><strong>Start gradually:</strong> Begin with simple exercises and gradually increase the difficulty and intensity.</li></ul><p>Hope these guides help you take the first step in fitness!</p>', 'Fitness, beginner, guide', 'Help you start your fitness journey'),
     (5, 'zh', '冬季滑雪攻略', '如何享受滑雪的乐趣', '<h2>冬季滑雪攻略</h2><p>冬季是滑雪的最佳季节,以下是一些滑雪技巧:</p><ul><li><strong>选择合适的滑雪场:</strong>根据自己的水平选择适合的滑雪场。</li><li><strong>准备必要的装备:</strong>滑雪板、滑雪靴、护具、头盔等。</li><li><strong>注意安全:</strong>遵循滑雪场的规则,避免危险动作。</li></ul><p>希望这些攻略能帮助你在雪地上尽情驰骋!</p>', '滑雪,冬季,攻略', '享受滑雪的乐趣'),
+    (5, 'zh-tw', '冬季滑雪攻略', '如何享受滑雪的樂趣', '<h2>冬季滑雪攻略</h2><p>冬季是滑雪的最佳季節,以下是一些滑雪技巧:</p><ul><li><strong>選擇合適的滑雪場:</strong>根據自己的水平選擇適合的滑雪場。</li><li><strong>準備必要的裝備:</strong>滑雪板、滑雪靴、護具、頭盔等。</li><li><strong>注意安全:</strong>遵循滑雪場的規則,避免危險動作。</li></ul><p>希望這些攻略能幫助你在雪地上盡情馳騁!</p>', '滑雪,冬季,攻略', '享受滑雪的樂趣'),
     (5, 'en', 'Winter Skiing Tips', 'How to enjoy skiing', '<h2>Winter Skiing Tips</h2><p>Winter is the perfect season for skiing. Here are some skiing tips:</p><ul><li><strong>Choose the right ski resort:</strong> Select a ski resort suitable for your skill level.</li><li><strong>Prepare necessary gear:</strong> Skis, ski boots, protective gear, helmet, etc.</li><li><strong>Pay attention to safety:</strong> Follow the ski resort rules and avoid dangerous maneuvers.</li></ul><p>Hope these tips help you enjoy skiing on the snow!</p>', 'Skiing, winter, tips', 'Enjoy skiing'),
     (6, 'zh', '春季养生小贴士', '春季如何保持健康', '<h2>春季养生小贴士</h2><p>春季是万物复苏的季节,也是养生的好时机。以下是一些春季养生的小贴士:</p><ul><li><strong>饮食清淡:</strong>多吃蔬菜水果,少吃油腻食物。</li><li><strong>适当运动:</strong>选择适合自己的运动方式,如散步、慢跑等。</li><li><strong>保持心情舒畅:</strong>避免情绪波动,保持心态平和。</li></ul><p>希望这些小贴士能帮助你度过一个健康的春季!</p>', '春季,养生,健康', '春季养生小贴士,帮助你保持健康'),
+    (6, 'zh-tw', '春季養生小貼士', '春季如何保持健康', '<h2>春季養生小貼士</h2><p>春季是萬物復甦的季節,也是養生的好時機。以下是一些春季養生的小貼士:</p><ul><li><strong>飲食清淡:</strong>多吃蔬菜水果,少吃油膩食物。</li><li><strong>適當運動:</strong>選擇適合自己的運動方式,如散步、慢跑等。</li><li><strong>保持心情舒暢:</strong>避免情緒波動,保持心態平和。</li></ul><p>希望這些小貼士能幫助你度過一個健康的春季!</p>', '春季,養生,健康', '春季養生小貼士,幫助你保持健康'),
     (6, 'en', 'Spring Health Tips', 'How to stay healthy in spring', '<h2>Spring Health Tips</h2><p>Spring is the season of renewal and a great time for health maintenance. Here are some tips for staying healthy in spring:</p><ul><li><strong>Eat lightly:</strong> Focus on vegetables and fruits, and avoid greasy foods.</li><li><strong>Exercise moderately:</strong> Choose activities like walking or jogging.</li><li><strong>Stay in good spirits:</strong> Avoid emotional fluctuations and maintain a peaceful mindset.</li></ul><p>Hope these tips help you have a healthy spring!</p>', 'Spring, health, tips', 'Spring health tips to keep you in good shape'),
     (7, 'zh', '家庭园艺入门指南', '如何打造自己的小花园', '<h2>家庭园艺入门指南</h2><p>园艺不仅能美化环境,还能带来乐趣。以下是一些家庭园艺的入门建议:</p><ul><li><strong>选择合适的植物:</strong>根据光照条件选择适合的植物。</li><li><strong>准备基本工具:</strong>铲子、喷壶、花盆等。</li><li><strong>定期浇水和施肥:</strong>保持土壤湿润,适时补充养分。</li></ul><p>希望这些指南能帮助你打造一个美丽的小花园!</p>', '园艺,家庭,入门', '家庭园艺入门指南,打造你的小花园'),
+    (7, 'zh-tw', '家庭園藝入門指南', '如何打造自己的小花園', '<h2>家庭園藝入門指南</h2><p>園藝不仅能美化環境,還能帶來樂趣。以下是一些家庭園藝的入門建議:</p><ul><li><strong>選擇合適的植物:</strong>根據光照條件選擇適合的植物。</li><li><strong>準備基本工具:</strong>鏟子、噴壺、花盆等。</li><li><strong>定期澆水和施肥:</strong>保持土壤濕潤,適時補充養分。</li></ul><p>希望這些指南能幫助你打造一個美麗的小花園!</p>', '園藝,家庭,入門', '家庭園藝入門指南,打造你的小花園'),
     (7, 'en', 'Home Gardening Beginner\'s Guide', 'How to create your own little garden', '<h2>Home Gardening Beginner\'s Guide</h2><p>Gardening not only beautifies the environment but also brings joy. Here are some tips for getting started with home gardening:</p><ul><li><strong>Choose the right plants:</strong> Select plants based on your light conditions.</li><li><strong>Prepare basic tools:</strong> Trowel, watering can, pots, etc.</li><li><strong>Water and fertilize regularly:</strong> Keep the soil moist and add nutrients as needed.</li></ul><p>Hope these guides help you create a beautiful little garden!</p>', 'Gardening, home, beginner', 'Home gardening guide to create your own garden'),
     (8, 'zh', '夏季防晒全攻略', '如何有效防晒', '<h2>夏季防晒全攻略</h2><p>夏季阳光强烈,防晒至关重要。以下是一些防晒建议:</p><ul><li><strong>选择合适的防晒霜:</strong>SPF 30 以上,PA+++ 为佳。</li><li><strong>定时补涂:</strong>每 2-3 小时补涂一次。</li><li><strong>避免长时间暴晒:</strong>尽量减少在紫外线最强时段外出。</li></ul><p>希望这些攻略能帮助你有效防晒,享受夏日阳光!</p>', '防晒,夏季,攻略', '夏季防晒全攻略,保护你的皮肤'),
+    (8, 'zh-tw', '夏季防曬全攻略', '如何有效防曬', '<h2>夏季防曬全攻略</h2><p>夏季陽光強烈,防曬至關重要。以下是一些防曬建議:</p><ul><li><strong>選擇合適的防曬霜:</strong>SPF 30 以上,PA+++ 為佳。</li><li><strong>定時補塗:</strong>每 2-3 小時補塗一次。</li><li><strong>避免長時間暴曬:</strong>盡量減少在紫外線最強時段外出。</li></ul><p>希望這些攻略能幫助你有效防曬,享受夏日陽光!</p>', '防曬,夏季,攻略', '夏季防曬全攻略,保護你的皮膚'),
     (8, 'en', 'Summer Sun Protection Guide', 'How to protect your skin from the sun', '<h2>Summer Sun Protection Guide</h2><p>With intense summer sun, sun protection is essential. Here are some tips:</p><ul><li><strong>Choose the right sunscreen:</strong> SPF 30 or higher, PA+++ is recommended.</li><li><strong>Reapply regularly:</strong> Every 2-3 hours.</li><li><strong>Avoid prolonged exposure:</strong> Minimize outdoor activities during peak UV hours.</li></ul><p>Hope these tips help you enjoy the summer sun while staying protected!</p>', 'Sun protection, summer, guide', 'Summer sun protection guide to keep your skin safe'),
     (9, 'zh', '秋季美食推荐', '秋季不可错过的美食', '<h2>秋季美食推荐</h2><p>秋季是丰收的季节,有许多美味的食物值得一试:</p><ul><li><strong>大闸蟹:</strong>肉质鲜美,营养丰富。</li><li><strong>栗子:</strong>香甜可口,适合烤制或煮食。</li><li><strong>南瓜:</strong>口感软糯,可做多种菜肴。</li></ul><p>这些美食不仅能满足味蕾,还能补充营养,让你享受秋季的丰收喜悦!</p>', '美食,秋季,推荐', '秋季美食推荐,享受丰收的美味'),
+    (9, 'zh-tw', '秋季美食推薦', '秋季不可錯過的美食', '<h2>秋季美食推薦</h2><p>秋季是豐收的季節,有許多美味的食物值得一試:</p><ul><li><strong>大閘蟹:</strong>肉質鮮美,營養豐富。</li><li><strong>栗子:</strong>香甜可口,適合烤制或煮食。</li><li><strong>南瓜:</strong>口感軟糯,可做多種菜肴。</li></ul><p>這些美食不僅能滿足味蕾,還能補充營養,讓你享受秋季的豐收喜悅!</p>', '美食,秋季,推薦', '秋季美食推薦,享受豐收的美味'),
     (9, 'en', 'Autumn Food Recommendations', 'Delicious foods to enjoy in autumn', '<h2>Autumn Food Recommendations</h2><p>Autumn is the season of harvest, with many delicious foods to try:</p><ul><li><strong>Crab:</strong> Tender and nutritious.</li><li><strong>Chestnuts:</strong> Sweet and delicious, perfect for roasting or boiling.</li><li><strong>Pumpkin:</strong> Soft and versatile, great for various dishes.</li></ul><p>These foods not only satisfy your taste buds but also provide nutrition, letting you enjoy the joy of autumn harvest!</p>', 'Food, autumn, recommendations', 'Autumn food recommendations to enjoy the harvest'),
     (10, 'zh', '冬季保暖小妙招', '如何在寒冷中保持温暖', '<h2>冬季保暖小妙招</h2><p>冬季寒冷,保暖很重要。以下是一些保暖小妙招:</p><ul><li><strong>穿多层衣物:</strong>增加保暖效果。</li><li><strong>戴帽子和围巾:</strong>减少头部热量散失。</li><li><strong>保持室内温暖:</strong>使用暖气或电热毯。</li></ul><p>希望这些小妙招能帮助你在寒冷的冬季保持温暖!</p>', '保暖,冬季,小妙招', '冬季保暖小妙招,让你温暖过冬'),
+    (10, 'zh-tw', '冬季保暖小妙招', '如何在寒冷中保持溫暖', '<h2>冬季保暖小妙招</h2><p>冬季寒冷,保暖很重要。以下是一些保暖小妙招:</p><ul><li><strong>穿多層衣物:</strong>增加保暖效果。</li><li><strong>戴帽子和圍巾:</strong>減少頭部熱量散失。</li><li><strong>保持室內溫暖:</strong>使用暖氣或電熱毯。</li></ul><p>希望這些小妙招能幫助你在寒冷的冬季保持溫暖!</p>', '保暖,冬季,小妙招', '冬季保暖小妙招,讓你溫暖過冬'),
     (10, 'en', 'Winter Warmth Tips', 'How to stay warm in the cold', '<h2>Winter Warmth Tips</h2><p>Winter is cold, and staying warm is crucial. Here are some tips:</p><ul><li><strong>Wear multiple layers:</strong> Enhance warmth.</li><li><strong>Wear hats and scarves:</strong> Reduce heat loss from the head.</li><li><strong>Keep indoor warmth:</strong> Use heating or electric blankets.</li></ul><p>Hope these tips help you stay warm in the cold winter!</p>', 'Warmth, winter, tips', 'Winter warmth tips to keep you cozy'),
     (11, 'zh', '春季户外徒步指南', '如何享受徒步的乐趣', '<h2>春季户外徒步指南</h2><p>春季是徒步的好季节,以下是一些徒步建议:</p><ul><li><strong>选择合适的路线:</strong>根据自己的体力选择合适的徒步路线。</li><li><strong>准备必要的装备:</strong>舒适的徒步鞋、背包、水和食物。</li><li><strong>注意安全:</strong>告知他人你的行程,避免独自前往危险区域。</li></ul><p>希望这些指南能帮助你享受徒步的乐趣!</p>', '徒步,春季,指南', '春季户外徒步指南,享受徒步的乐趣'),
+    (11, 'zh-tw', '春季戶外徒步指南', '如何享受徒步的樂趣', '<h2>春季戶外徒步指南</h2><p>春季是徒步的好季節,以下是一些徒步建議:</p><ul><li><strong>選擇合適的路線:</strong>根據自己的體力選擇合適的徒步路線。</li><li><strong>準備必要的裝備:</strong>舒適的徒步鞋、背包、水和食物。</li><li><strong>注意安全:</strong>告知他人你的行程,避免獨自前往危險區域。</li></ul><p>希望這些指南能幫助你享受徒步的樂趣!</p>', '徒步,春季,指南', '春季戶外徒步指南,享受徒步的樂趣'),
     (11, 'en', 'Spring Hiking Guide', 'How to enjoy hiking', '<h2>Spring Hiking Guide</h2><p>Spring is a great season for hiking. Here are some tips:</p><ul><li><strong>Choose the right trail:</strong> Select a trail based on your physical condition.</li><li><strong>Prepare necessary gear:</strong> Comfortable hiking shoes, backpack, water, and food.</li><li><strong>Pay attention to safety:</strong> Inform someone of your itinerary and avoid dangerous areas alone.</li></ul><p>Hope these guides help you enjoy hiking!</p>', 'Hiking, spring, guide', 'Spring hiking guide to enjoy the outdoors'),
     (12, 'zh', '家居收纳技巧大全', '如何打造整洁有序的家', '<h2>家居收纳技巧大全</h2><p>一个整洁有序的家能让人感到舒适和放松。以下是一些实用的家居收纳技巧:</p><ul><li><strong>分类整理:</strong>将物品按照类别进行分类,方便查找。</li><li><strong>利用收纳工具:</strong>如收纳盒、挂钩、置物架等。</li><li><strong>定期清理:</strong>定期检查并清理不需要的物品。</li></ul><p>希望这些技巧能帮助你打造一个整洁有序的家!</p>', '家居,收纳,技巧', '家居收纳技巧大全,打造整洁有序的家'),
+    (12, 'zh-tw', '家居收納技巧大全', '如何打造整潔有序的家', '<h2>家居收納技巧大全</h2><p>一個整潔有序的家能讓人感到舒適和放鬆。以下是一些實用的家居收納技巧:</p><ul><li><strong>分類整理:</strong>將物品按照類別進行分類,方便查找。</li><li><strong>利用收納工具:</strong>如收納盒、掛鉤、置物架等。</li><li><strong>定期清理:</strong>定期檢查並清理不需要的物品。</li></ul><p>希望這些技巧能幫助你打造一個整潔有序的家!</p>', '家居,收納,技巧', '家居收納技巧大全,打造整潔有序的家'),
     (12, 'en', 'Home Organization Tips', 'How to create a tidy and organized home', '<h2>Home Organization Tips</h2><p>A tidy and organized home can bring comfort and relaxation. Here are some practical tips for home organization:</p><ul><li><strong>Sort and categorize:</strong> Organize items by category for easy access.</li><li><strong>Use storage tools:</strong> Such as storage boxes, hooks, and shelves.</li><li><strong>Regular decluttering:</strong> Periodically check and remove items you no longer need.</li></ul><p>Hope these tips help you create a tidy and organized home!</p>', 'Home, organization, tips', 'Home organization tips to keep your space tidy')
 ;

+ 2 - 1
db/cms_banner_i18n.sql

@@ -17,6 +17,7 @@ CREATE TABLE `cms_banner_i18n` (
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='幻灯片表 (翻译)';
 
 INSERT INTO cms_banner_i18n(banner_id, language, title, link, image, image_thumb) VALUES
-    (1, 'zh', '枯在斯柯达欠妥', '/PageDao/index/index', '/uploads/banners/banners.1680162484582.png', '/uploads/banners/banners.1680162484582.png'),
+    (1, 'zh', '幻灯片-A', '/PageDao/index/index', '/uploads/banners/banners.1680162484582.png', '/uploads/banners/banners.1680162484582.png'),
+    (1, 'zh-tw', '幻燈片-A', '/PageDao/index/index', '/uploads/banners/banners.1680162484582.png', '/uploads/banners/banners.1680162484582.png'),
     (1, 'en', 'aaaadfqwea', '/PageDao/index/index', '/uploads/banners/banners.1680162484582.png', '/uploads/banners/banners.1680162484582.png')
 ;

+ 29 - 25
db/cms_navigation_i18n.sql

@@ -1,27 +1,31 @@
-/**
-Source Server Version: 8.0.31
-Source Database: backendsys
-Date: 2023/05/23 17:09:22
-*/
+    /**
+    Source Server Version: 8.0.31
+    Source Database: backendsys
+    Date: 2023/05/23 17:09:22
+    */
 
-DROP TABLE IF EXISTS `cms_navigation_i18n`;
-CREATE TABLE `cms_navigation_i18n` (
-    PRIMARY KEY (`id`),
-    `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
-    `navigation_id` BIGINT NOT NULL COMMENT '导航ID',
-    `language` VARCHAR(10) NOT NULL COMMENT '语种',
-    `navigation_name` VARCHAR(255) NOT NULL COMMENT '菜单名称',
-    `link` VARCHAR(1000) COMMENT '链接',
-    `link_start_with` text COMMENT '链接匹配路径'
-) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='导航翻译表';
+    DROP TABLE IF EXISTS `cms_navigation_i18n`;
+    CREATE TABLE `cms_navigation_i18n` (
+        PRIMARY KEY (`id`),
+        `id` BIGINT AUTO_INCREMENT COMMENT 'ID',
+        `navigation_id` BIGINT NOT NULL COMMENT '导航ID',
+        `language` VARCHAR(10) NOT NULL COMMENT '语种',
+        `navigation_name` VARCHAR(255) NOT NULL COMMENT '菜单名称',
+        `link` VARCHAR(1000) COMMENT '链接',
+        `link_start_with` text COMMENT '链接匹配路径'
+    ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='导航翻译表';
 
-INSERT INTO cms_navigation_i18n(navigation_id, language, navigation_name, link, link_start_with) VALUES
-    (1, 'zh', '首页', '/', null),
-    (1, 'en', 'Home', '/', null),
-    (2, 'zh', '关于我们', '/page/about', null),
-    (2, 'en', 'About', '/page/about', null),
-    (3, 'zh', '资讯中心', '/article/list', '/article'),
-    (3, 'en', 'Article', '/article/list', '/article'),
-    (3, 'zh', '联系我们', '/page/contact', null),
-    (3, 'en', 'Concat us', '/page/contact', null)
-;
+    INSERT INTO cms_navigation_i18n(navigation_id, language, navigation_name, link, link_start_with) VALUES
+        (1, 'zh', '首页', '/', null),
+        (1, 'zh-tw', '首頁', '/', null),
+        (1, 'en', 'Home', '/', null),
+        (2, 'zh', '关于我们', '/page/about', null),
+        (2, 'zh-tw', '關於我們', '/page/about', null),
+        (2, 'en', 'About', '/page/about', null),
+        (3, 'zh', '资讯中心', '/article/list', '/article'),
+        (3, 'zh-tw', '資訊中心', '/article/list', '/article'),
+        (3, 'en', 'Article', '/article/list', '/article'),
+        (3, 'zh', '联系我们', '/page/contact', null),
+        (3, 'zh-tw', '聯絡我們', '/page/contact', null),
+        (3, 'en', 'Concat us', '/page/contact', null)
+    ;

+ 2 - 0
db/cms_page_i18n.sql

@@ -14,7 +14,9 @@ CREATE TABLE `cms_page_i18n` (
 
 INSERT INTO cms_page_i18n(page_sign, language, title, description, content) VALUES
     ('about', 'zh', '关于我们', '一家致力于为用户提供智能生活解决方案的科技公司', '是一家致力于为用户提供智能生活解决方案的科技公司。我们的使命是利用最先进的人工智能技术,使每个人都能享受更智能、更便捷的生活体验。无论是通过我们的智能助手或者其他创新产品,我们都致力于为大家提供优质的服务和技术。'),
+    ('about', 'zh-tw', '關於我們', '一家致力於為用戶提供智慧生活解決方案的科技公司', '是一家致力於為用戶提供智慧生活解決方案的科技公司。我們的使命是運用最先進的人工智慧技術,讓每個人都能享受更智慧、更便捷的生活體驗。無論是透過我們的智慧助手或其他創新產品,我們都致力於為大家提供優質的服務與技術。'),
     ('about', 'en', 'About us', 'A technology company dedicated to providing intelligent lifestyle solutions for users', 'WeTab is a technology company dedicated to providing intelligent lifestyle solutions for users. Our mission is to leverage cutting-edge artificial intelligence technology to enable everyone to enjoy a smarter and more convenient life experience. Whether through our smart assistant or other innovative products, we are committed to providing high-quality service and technology.'),
     ('contact', 'zh', '联系我们', '', '<p>联系电话:+1234567890</p><p>邮箱地址:info@WeTab.com</p><p>企业地址:XXXX街道,XX城市,XX国家</p>'),
+    ('contact', 'zh-tw', '聯絡我們', '', '<p>聯繫電話:+1234567890</p><p>郵箱地址:info@WeTab.com</p><p>企業地址:XXXX街道,XX城市,XX國家</p>'),
     ('contact', 'en', 'Contact us', '', '<p>Phone:+1234567890</p><p>Email:info@WeTab.com</p><p>Address: XXXX Street, XX City, XX Country</p>')
 ;

+ 1 - 0
db/cms_site_info.sql

@@ -20,6 +20,7 @@ CREATE TABLE `cms_site_info` (
 
 INSERT INTO cms_site_info(language, name, meta_keyword, meta_description, copyright, icp) VALUES
     ('zh', '示例网站', '示例网站, 网页设计, 网络技术, 用户体验', '这是一个示例网站,专注于网页设计和网络技术,致力于提供优质的用户体验。欢迎来到示例网站,探索我们的服务和创意。', 'Copyright &copy; 2024 示例网站. 保留所有权利.', '备案号: 京ICP备12345678号'),
+    ('zh-tw', '示例網站', '示例網站, 網頁設計, 網路技術, 使用體驗', '這是一個示例網站,專注於網頁設計和網路技術,致力於提供優質的使用體驗。歡迎來到示例網站,探索我們的服務和創意。', 'Copyright &copy; 2024 示例網站. 保留所有權利.', '備案號: 京ICP備12345678號'),
     ('en', 'Example Website', 'Example Website, Web Design, Web Technology, User Experience', 'This is an example website, focusing on web design and web technology. We are committed to providing a high-quality user experience. Welcome to Example Website, explore our services and creativity.', 'Copyright © 2024 Example Website. All rights reserved.', 'Record number: Beijing ICP No. 12345678')
 ;
 

+ 2 - 1
db/sys_language.sql

@@ -15,6 +15,7 @@ CREATE TABLE `sys_language` (
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='系统语言表';
 
 INSERT INTO sys_language(language, name, is_default, status) VALUES
-    ('zh', '中文', 1, 1),
+    ('zh', '简体中文', 1, 1),
+    ('zh-tw', '繁體中文', -1, 1),
     ('en', 'English', -1, 1)
 ;

+ 1 - 1
src/main/java/com/backendsys/modules/cms/template/ArticleViewController.java → src/main/java/com/backendsys/modules/cms/views/ArticleViewController.java

@@ -1,4 +1,4 @@
-package com.backendsys.modules.cms.template;
+package com.backendsys.modules.cms.views;
 
 import cn.hutool.core.convert.Convert;
 import com.backendsys.modules.cms.article.entity.Article;

+ 1 - 1
src/main/java/com/backendsys/modules/cms/template/IndexViewController.java → src/main/java/com/backendsys/modules/cms/views/IndexViewController.java

@@ -1,4 +1,4 @@
-package com.backendsys.modules.cms.template;
+package com.backendsys.modules.cms.views;
 
 import cn.hutool.core.convert.Convert;
 import com.backendsys.modules.common.aspect.Pages;

+ 1 - 5
src/main/java/com/backendsys/modules/cms/template/PageViewController.java → src/main/java/com/backendsys/modules/cms/views/PageViewController.java

@@ -1,20 +1,16 @@
-package com.backendsys.modules.cms.template;
+package com.backendsys.modules.cms.views;
 
 import cn.hutool.core.convert.Convert;
-import com.backendsys.modules.cms.article.entity.Article;
 import com.backendsys.modules.cms.page.entity.Page;
 import com.backendsys.modules.cms.page.service.PageService;
 import com.backendsys.modules.common.aspect.Pages;
 import io.swagger.v3.oas.annotations.Operation;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.MessageSource;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 
-import java.util.Locale;
-
 @Controller
 public class PageViewController {
 

+ 23 - 14
src/main/java/com/backendsys/modules/common/aspect/PagesAspect.java

@@ -6,8 +6,10 @@ import com.backendsys.modules.cms.navigation.entity.Navigation;
 import com.backendsys.modules.cms.navigation.service.NavigationService;
 import com.backendsys.modules.common.config.security.utils.HttpRequestUtil;
 import com.backendsys.modules.common.utils.CookieUtil;
+import com.backendsys.modules.system.service.SysLanguageService;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+import org.aspectj.lang.annotation.AfterThrowing;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.springframework.ui.Model;
 import com.backendsys.modules.cms.siteinfo.entity.SiteInfo;
@@ -21,6 +23,7 @@ import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 import org.springframework.web.method.HandlerMethod;
 
+import java.io.IOException;
 import java.lang.reflect.Method;
 import java.util.List;
 
@@ -33,17 +36,19 @@ public class PagesAspect {
 
 	@Autowired
 	private HttpRequestUtil httpRequestUtil;
+
+	@Autowired
+	private SysLanguageService sysLanguageService;
 	@Autowired
 	private SiteInfoService siteInfoService;
 	@Autowired
 	private NavigationService navigationService;
 
-
-
 	@Before("@annotation(org.springframework.web.bind.annotation.GetMapping) && @annotation(pages)")
-	public void beforeGet(JoinPoint joinPoint, Pages pages) {
+	public void beforeGet(JoinPoint joinPoint, Pages pages) throws IOException {
 
 		HttpServletRequest request = httpRequestUtil.getRequest();
+		HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
 
 		// 从 JoinPoint 获取控制器方法的参数
 		Object[] args = joinPoint.getArgs();
@@ -52,28 +57,32 @@ public class PagesAspect {
 				Model model = (Model) arg;
 
 				// [Cookie] 获取/设置默认语言 (默认是:中文)
-				String lang = CookieUtil.getCookie("lang", request);
-				String default_lang = "zh";
-				if (StrUtil.isEmpty(lang)) {
-					lang = default_lang;
-					CookieUtil.setCookie("lang", lang);
-				}
-				request.setAttribute("lang", lang);
-
+				String lang = CookieUtil.getCurrentLang(request);
 				model.addAttribute("lang", lang);
 
+				// [Get] 获取系统语言列表
+				model.addAttribute("sysLanguage", sysLanguageService.selectLanguageList());
+
 				// [Get] 获取站点信息
+				SiteInfo siteInfo = siteInfoService.selectSiteInfo(lang);
+				if (siteInfo == null) {
+					request.setAttribute("errorMessage", "站点信息不存在 " + "(" + lang + ")");
+					response.sendRedirect(request.getContextPath() + "/error");
+				}
 				model.addAttribute("siteInfo", siteInfoService.selectSiteInfo(lang));
+
 				// [Get] 获取导航
 				model.addAttribute("navigation", navigationService.selectNavigationTemplate(lang));
+
 				// 其他信息
-				model.addAttribute("timestamp", DateUtil.current());			// 当前时间戳
-				model.addAttribute("request_uri", request.getRequestURI());				// 当前访问路径
-				model.addAttribute("request_query_string", request.getQueryString());	// 当前访问路径参数
+				model.addAttribute("timestamp", DateUtil.current());            			// 当前时间戳
+				model.addAttribute("request_uri", request.getRequestURI());                 // 当前访问路径
+				model.addAttribute("request_query_string", request.getQueryString());    	// 当前访问路径参数
 
 				break;
 			}
 		}
+
 	}
 
 }

+ 24 - 7
src/main/java/com/backendsys/modules/common/config/security/filter/JwtAuthenticationFilter.java

@@ -2,6 +2,8 @@ package com.backendsys.modules.common.config.security.filter;
 
 import cn.hutool.core.util.ArrayUtil;
 import com.backendsys.modules.common.config.security.annotations.AnonymousProperties;
+import com.backendsys.modules.common.utils.CookieUtil;
+import com.backendsys.utils.response.ResultEnumService;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.backendsys.utils.response.Result;
 import com.backendsys.utils.response.ResultEnum;
@@ -22,6 +24,8 @@ import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
 import org.springframework.web.filter.OncePerRequestFilter;
 
 import java.io.IOException;
@@ -53,6 +57,9 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
      */
     private final UserDetailsService userDetailsService; // 从ApplicationConfig中创建的Bean对象获取
 
+    @Autowired
+    private ResultEnumService resultEnumService;
+
     @Value("#{'${whitelist.static}'.split(',')}")
     private final String[] STATIC_WHITELIST;
     @Value("#{'${whitelist.jwt}'.split(',')}")
@@ -109,7 +116,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
         final String authHeader = request.getHeader("Authorization");
         if(authHeader == null || !authHeader.startsWith("Bearer ")) {
             // [TOKEN_EMPTY_ERROR: 请先登录获取有效的Token]
-            handleError(response, ResultEnum.TOKEN_EMPTY_ERROR);
+            handleError(request, response, ResultEnum.TOKEN_EMPTY_ERROR);
             return;
         }
 
@@ -139,7 +146,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
                 Boolean isTokenValid = (stringRedisTemplate.opsForValue().get(redisKey) != null);
                 if (!isTokenValid) {
                     // [TOKEN_INVALID: Token已失效,请重新登录]
-                    handleError(response, ResultEnum.TOKEN_INVALID);
+                    handleError(request, response, ResultEnum.TOKEN_INVALID);
                     return ;
                 }
 
@@ -163,19 +170,29 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
 
         } catch (MalformedJwtException e) {
             // [TOKEN_FORMAT_EXCEPTION: Token格式异常]
-            handleError(response, ResultEnum.TOKEN_FORMAT_EXCEPTION);
+            handleError(request, response, ResultEnum.TOKEN_FORMAT_EXCEPTION);
         } catch (ExpiredJwtException e) {
             // [TOKEN_EXPIRED: Token过期]
-            handleError(response, ResultEnum.TOKEN_EXPIRED);
+            handleError(request, response, ResultEnum.TOKEN_EXPIRED);
         } catch (SignatureException e) {
             // [TOKEN_FORMAT_INCORRECT: Token格式不正确]
-            handleError(response, ResultEnum.TOKEN_FORMAT_INCORRECT);
+            handleError(request, response, ResultEnum.TOKEN_FORMAT_INCORRECT);
         }
 
     }
 
-    private void handleError(HttpServletResponse response, ResultEnum error) throws IOException {
-        Result result = Result.error(error.getCode(), error.getMessage());
+    private void handleError(HttpServletRequest request, HttpServletResponse response, ResultEnum resultEnum) throws IOException {
+
+//        String lang = CookieUtil.getCookie("lang", request);
+//        System.out.println("(handleError) lang = " + lang);
+//
+//        String message = resultEnumService.getMessage(resultEnum, lang);
+//        System.out.println("message = " + message);
+//
+//        Result result = Result.error(resultEnum.getCode(), message);
+
+        Result result = Result.error(resultEnum.getCode(), resultEnum.getMessage());
+
         response.setContentType("application/json;charset=utf-8");
         response.getWriter().write(new ObjectMapper().writeValueAsString(result));
     }

+ 15 - 0
src/main/java/com/backendsys/modules/common/utils/CookieUtil.java

@@ -1,5 +1,6 @@
 package com.backendsys.modules.common.utils;
 
+import cn.hutool.core.util.StrUtil;
 import jakarta.servlet.http.Cookie;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
@@ -32,6 +33,20 @@ public class CookieUtil {
         return value;
     }
 
+    /**
+     * [Cookie] 获取/设置默认语言 (默认是:中文)
+     */
+    public static String getCurrentLang(HttpServletRequest request) {
+        String lang = CookieUtil.getCookie("lang", request);
+        String default_lang = "zh";
+        if (StrUtil.isEmpty(lang)) {
+            lang = default_lang;
+            CookieUtil.setCookie("lang", lang);
+        }
+        request.setAttribute("lang", lang);
+        return lang;
+    }
+
     /**
      * 设置 Cookie 的值
      * @param name Cookie 名称

+ 11 - 1
src/main/java/com/backendsys/utils/response/ResultEnum.java

@@ -26,7 +26,8 @@ public enum ResultEnum {
     HTTP_BODY_EMPTY(420, "请求体参数不能为空"),
     HTTP_METHOD_ERROR(421, "请求方法不支持"),
 
-    TOKEN_EXPIRED(440, "Token已过期,请重新登录"),
+    TOKEN_EXPIRED(440, "Token已过期,请重新登录", "result.token.invalid"),
+
     TOKEN_INVALID(441, "Token已失效,请重新登录"),
     TOKEN_FORMAT_EXCEPTION(442, "Token格式异常"),
     TOKEN_FORMAT_INCORRECT(443, "Token格式不正确"),
@@ -46,6 +47,7 @@ public enum ResultEnum {
 
     private int code;
     private String message;
+    private String message_key;
 
 
     public int getCode() {
@@ -54,9 +56,17 @@ public enum ResultEnum {
     public String getMessage() {
         return this.message;
     }
+    public String getMessageKey() {
+        return this.message_key;
+    }
 
     ResultEnum(int code, String message) {
         this.code = code;
         this.message = message;
     }
+    ResultEnum(int code, String message, String message_key) {
+        this.code = code;
+        this.message = message;
+        this.message_key = message_key;
+    }
 }

+ 23 - 0
src/main/java/com/backendsys/utils/response/ResultEnumService.java

@@ -0,0 +1,23 @@
+package com.backendsys.utils.response;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.MessageSource;
+import org.springframework.context.i18n.LocaleContextHolder;
+import org.springframework.stereotype.Service;
+
+import java.util.Locale;
+
+/**
+ * 定义 ResultEnumService 获取国际化消息
+ */
+@Service
+public class ResultEnumService {
+
+    @Autowired
+    private MessageSource messageSource;
+
+    public String getMessage(ResultEnum resultEnum, String lang) {
+        return messageSource.getMessage(resultEnum.getMessageKey(), null, new Locale(lang));
+    }
+
+}

+ 3 - 1
src/main/resources/i18n/locale_en.properties

@@ -1,3 +1,5 @@
+result.token.invalid = Token is invalid, please log in again
+
 all = All
 more = More
 settop = Top
@@ -26,4 +28,4 @@ footer.menu.wechat = Wechat
 footer.menu.wechatinfo.text1 = Long press the QR code to add WeChat for contact.
 footer.menu.wechatinfo.text2 = Wechat
 
-search.input.placeholder = Enter the keyword to explore the ideal watch in your heart...
+search.input.placeholder = Enter the keyword to search...

+ 31 - 0
src/main/resources/i18n/locale_zh-tw.properties

@@ -0,0 +1,31 @@
+result.token.invalid = Token已失效,請重新登入
+
+all = 全部
+more = 更多
+settop = 置頂
+viewdetail = 查看詳情
+category = 分類
+back = 返回
+
+top.welcome = 歡迎諮詢,微信號:
+
+index.section1.title = 最新評測
+index.section2.title = 熱門評測
+
+index.title = 首頁
+article.title = 資訊中心
+articleDetail.title = 資訊詳情
+page.title = 內容中心
+
+sub.sider.title.nav = 導航
+
+footer.menu.home = 首頁
+footer.menu.product = 產品
+footer.menu.video = 視頻
+footer.menu.ce = 測評
+footer.menu.wechat = 微信
+
+footer.menu.wechatinfo.text1 = 長按二維碼添加微信諮詢
+footer.menu.wechatinfo.text2 = 微信號
+
+search.input.placeholder = 輸入關鍵字進行評測...

+ 3 - 1
src/main/resources/i18n/locale_zh.properties

@@ -1,3 +1,5 @@
+result.token.invalid = Token已失效,请重新登录
+
 all = 全部
 more = 更多
 settop = 置顶
@@ -26,4 +28,4 @@ footer.menu.wechat = 微信
 footer.menu.wechatinfo.text1 = 长按二维码添加微信咨询
 footer.menu.wechatinfo.text2 = 微信号
 
-search.input.placeholder = 输入关键字,探索您心中的理想手表..
+search.input.placeholder = 输入关键字进行搜索..

+ 27 - 7
src/main/resources/templates/components/language.html

@@ -1,16 +1,36 @@
 <div th:fragment="language">
 
   <ul class="flex items-center">
-    <li class="ml-4">
-      <a href="javascript:;" onclick="setLangAndRefresh('zh');"
-         th:classappend="${lang} == 'zh' ? 'font-bold' : ''">中文</a>
-    </li>
-    <li class="ml-4">
-      <a href="javascript:;" onclick="setLangAndRefresh('en');"
-         th:classappend="${lang} == 'en' ? 'font-bold' : ''">English</a>
+
+    <li th:each="sysLang, iterStat : ${sysLanguage}" class="ml-4">
+      <a href="javascript:;"
+         th:data-lang="${sysLang.language}"
+         th:classappend="(${lang} == ${sysLang.language} ? 'font-bold' : '')"
+         th:text="${sysLang.name}">
+      </a>
     </li>
+
+<!--    <li class="ml-4">-->
+<!--      <a href="javascript:;" onclick="setLangAndRefresh('zh');"-->
+<!--         th:classappend="${lang} == 'zh' ? 'font-bold' : ''">中文</a>-->
+<!--    </li>-->
+<!--    <li class="ml-4">-->
+<!--      <a href="javascript:;" onclick="setLangAndRefresh('en');"-->
+<!--         th:classappend="${lang} == 'en' ? 'font-bold' : ''">English</a>-->
+<!--    </li>-->
   </ul>
   <script>
+
+      document.addEventListener("DOMContentLoaded", function () {
+          const langLinks = document.querySelectorAll("a[data-lang]");
+          langLinks.forEach(link => {
+              // 监听导航栏语言点击事件
+              link.addEventListener("click", function () {
+                  setLangAndRefresh(this.dataset.lang)
+              });
+          });
+      });
+      // 设置语言Cookie,刷新页面
       function setLangAndRefresh(lang) {
           document.cookie = "lang=" + lang + ";max-age=2592000;path=/"
           location.reload()

File diff suppressed because it is too large
+ 1 - 0
src/main/resources/templates/error.html


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