diff --git a/database/migrations/2024_10_27_070707_create_web_socket_dialog_msg_translates_table.php b/database/migrations/2024_10_27_070707_create_web_socket_dialog_msg_translates_table.php index feef35d32..71676c591 100644 --- a/database/migrations/2024_10_27_070707_create_web_socket_dialog_msg_translates_table.php +++ b/database/migrations/2024_10_27_070707_create_web_socket_dialog_msg_translates_table.php @@ -13,6 +13,9 @@ class CreateWebSocketDialogMsgTranslatesTable extends Migration */ public function up() { + if (Schema::hasTable('web_socket_dialog_msg_translates')) + return; + Schema::create('web_socket_dialog_msg_translates', function (Blueprint $table) { $table->bigIncrements('id'); $table->bigInteger('dialog_id')->nullable()->default(0)->comment('对话ID'); diff --git a/language/original-web.txt b/language/original-web.txt index ad3021c51..beb613c0a 100644 --- a/language/original-web.txt +++ b/language/original-web.txt @@ -1751,3 +1751,5 @@ WiFi签到延迟时长为±1分钟。 你确定要删除子任务【(*)】吗? 你确定要归档子任务【(*)】吗? 你确定要还原归档子任务【(*)】吗? + +请使用(*)移动端扫描二维码。 diff --git a/language/translate-gpt.php b/language/translate-gpt.php index 2341c9525..3f7a60c9f 100755 --- a/language/translate-gpt.php +++ b/language/translate-gpt.php @@ -2,92 +2,143 @@ @error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING); require __DIR__ . '/vendor/autoload.php'; + use Orhanerday\OpenAi\OpenAi; -require_once ("config.php"); +require_once("config.php"); -try { - // 译文 - $translations = []; - if (file_exists( "translate.json")) { - $tmps = json_decode(file_get_contents("translate.json"), true); - foreach ($tmps as $tmp) { - if (!isset($tmp['key'])) { - continue; - } - $translations[$tmp['key']] = $tmp; - } - } - foreach (['api', 'web'] as $type) { - // 读取文件 - $content = file_exists("original-{$type}.txt") ? file_get_contents("original-{$type}.txt") : ""; - $array = array_values(array_filter(array_unique(explode("\n", $content)))); - // 提取要翻译的 - $datas = []; - $needs = []; - foreach ($array as $text) { - $text = trim($text); - if ($tmp = json_decode($text, true)) { - $key = key($tmp); - $value = current($tmp); - } else { - $key = $value = $text; - } - if (isset($translations[$key])) { - $datas[] = $translations[$key]; - } else { - $needs[$key] = $value; - } - } - $waits = array_chunk($needs, 100, true); - // 分组翻译 - foreach ($waits as $items) { - print_r(implode("\n", array_values($items))); - print_r("\n\n-------------------\n\n"); - $content = implode("\n", $items); - $open_ai = new OpenAi(OPEN_AI_KEY); - $open_ai->setProxy(OPEN_AI_PROXY); - - $chat = $open_ai->chat([ - 'model' => 'gpt-4o', - 'messages' => [ - [ - "role" => "user", - "content" => $content . ' - ------- - -请帮我翻译以上内容,翻译的结果尽量符合“项目任务管理系统”的使用,每行一个,按照下面的格式翻译成对应的语言,原内容放到key,zh留空,zh-CHT为繁体中文,en为英语,ko为韩语,ja为日语,de为德语,fr为法语,id为印度尼西亚语,ru为俄语。 另外要注意的是其中的(*)为占位符,翻译时不要删除,也不要翻译这个占位符。 请帮我一次性翻译完。 - -[ - { - "key": "", - "zh": "", - "zh-CHT": "", - "en": "", - "ko": "", - "ja": "", - "de": "", - "fr": "", - "id": "", - "ru": "" - }, -]' - ], - ], - 'temperature' => 1.0, - 'max_tokens' => 4000, - 'frequency_penalty' => 0, - 'presence_penalty' => 0, - ]); - - $d = json_decode($chat); - file_put_contents('translate-gpt.md', $d->choices[0]->message->content . "\n\n\n", FILE_APPEND); - } - } - -} catch (Exception $e) { - print_r("[$type] error, " . $e->getMessage()); +// 读取所有要翻译的内容 +$array = []; +foreach (['api', 'web'] as $type) { + $content = file_exists("original-{$type}.txt") ? file_get_contents("original-{$type}.txt") : ""; + $array = array_merge($array, array_values(array_filter(array_unique(explode("\n", $content))))); } +// 判定是否存在translate.json文件 +if (!file_exists("translate.json")) { + print_r("translate.json not exists"); + exit; +} + +$translations = []; // 翻译数据 +$regrror = []; // 正则匹配错误的数据 +$redundants = []; // 多余的数据 +$needs = []; // 需要翻译的数据 + +$tmps = json_decode(file_get_contents("translate.json"), true); +foreach ($tmps as $tmp) { + if (!isset($tmp['key'])) { + continue; + } + $key = $tmp['key']; + $translations[$key] = $tmp; + if (in_array($key, $array)) { + $count = substr_count($key, '(*)'); + if ($count > 0) { + foreach ($tmp as $k => $v) { + if ($k == 'zh' || $k == 'key') { + continue; + } + if ($count != substr_count($v, '(*)')) { + $regrror[$key] = $tmp; + continue 2; + } + } + } + } else { + $redundants[$key] = $tmp; + } +} +foreach ($array as $text) { + $key = trim($text); + if (!isset($translations[$key])) { + $needs[$key] = $key; + } +} + +if (count($needs) > 0) { + $waits = array_chunk($needs, 100, true); + foreach ($waits as $index => $items) { + if ($index > 0) { + print_r("\n"); + } + print_r("正在翻译:" . count($items) . "/" . count($needs) . "\n"); + $content = implode("\n", $items); + $open_ai = new OpenAi(OPEN_AI_KEY); + $open_ai->setProxy(OPEN_AI_PROXY); + $chat = $open_ai->chat([ + 'model' => 'gpt-4o', + 'messages' => [ + [ + "role" => "system", + "content" => << "user", + "content" => $content, + ], + ], + 'temperature' => 1.0, + 'max_tokens' => 4000, + 'frequency_penalty' => 0, + 'presence_penalty' => 0, + ]); + $obj = json_decode($chat); + $arr = json_decode($obj->choices[0]->message->content, true); + if (!$arr || !is_array($arr)) { + print_r("翻译失败:\n"); + print_r($content . "\n"); + continue; + } + + foreach ($arr as $item) { + foreach (['key', 'zh', 'zh-CHT', 'en', 'ko', 'ja', 'de', 'fr', 'id', 'ru'] as $lang) { + if (!isset($item[$lang])) { + print_r("翻译结果不符合规范:{$item['key']},缺少:{$lang}\n"); + continue 2; + } + } + if (empty($item['key'])) { + print_r("翻译结果不符合规范:{$item['key']},key为空\n"); + continue; + } + $count = substr_count($item['key'], '(*)'); + if ($count > 0) { + foreach ($item as $k => $v) { + if ($k == 'zh' || $k == 'key') { + continue; + } + if ($count != substr_count($v, '(*)')) { + print_r("翻译结果不符合规范:{$item['key']},正则匹配错误:{$k} => {$v}\n"); + continue 2; + } + } + } + $item['zh'] = ""; + $translations[$item['key']] = $item; + } + file_put_contents("translate.json", json_encode(array_values($translations), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); + print_r("翻译完成:" . count($items) . "/" . count($needs) . "\n"); + } +} diff --git a/package.json b/package.json index 94a5a2211..39c10da93 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "stylus-loader": "^7.1.0", "tinymce": "^5.10.3", "tui-calendar-hi": "^1.15.1-5", - "view-design-hi": "^4.7.0-56", + "view-design-hi": "^4.7.0-57", "vite": "^2.9.15", "vite-plugin-file-copy": "^1.0.0", "vite-plugin-require": "^1.1.10", diff --git a/resources/assets/js/pages/login.vue b/resources/assets/js/pages/login.vue index 712d4c4a4..ac527b84b 100644 --- a/resources/assets/js/pages/login.vue +++ b/resources/assets/js/pages/login.vue @@ -97,8 +97,8 @@ -
{{$L('已经有帐号?')}}{{$L('登录帐号')}}
-
{{$L('还没有帐号?')}}{{$L('注册帐号')}}
+
{{$L('已经有帐号?')}} {{$L('登录帐号')}}
+
{{$L('还没有帐号?')}} {{$L('注册帐号')}}
@@ -141,7 +141,7 @@ -
{{$L('忘记密码了?')}}{{$L('重置密码')}}
+
{{$L('忘记密码了?')}} {{$L('重置密码')}}
diff --git a/resources/assets/js/pages/manage/application.vue b/resources/assets/js/pages/manage/application.vue index 2e34971fb..aba0ff335 100644 --- a/resources/assets/js/pages/manage/application.vue +++ b/resources/assets/js/pages/manage/application.vue @@ -67,7 +67,7 @@ - +
diff --git a/resources/assets/sass/pages/page-apply.scss b/resources/assets/sass/pages/page-apply.scss index 5454916db..e5697a859 100644 --- a/resources/assets/sass/pages/page-apply.scss +++ b/resources/assets/sass/pages/page-apply.scss @@ -319,24 +319,6 @@ } } - // - .ivu-tabs { - display: flex; - flex-direction: column; - height: 100%; - margin: 0 -30px; - - .ivu-tabs-bar { - padding: 0 10px; - } - - .ivu-tabs-content { - height: 100%; - flex: 1; - } - } - - // .ivu-modal-wrap-ul { list-style-type: none; overflow: hidden; @@ -421,9 +403,29 @@ } // 机器人 - .aibot-warp { - position: relative; - height: 100%; + .ai-tabs { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + flex: 1; + display: flex; + flex-direction: column; + + .ivu-tabs-bar { + padding: 0 10px; + } + + .ivu-tabs-content { + height: 0; + flex: 1; + + .aibot-warp { + position: relative; + height: 100%; + } + } } } }