From 1e381b06ee5d394e7868412a8633503fb72e552b Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Fri, 7 Feb 2025 11:19:20 +0800
Subject: [PATCH 01/21] Fixed: Export Button Logic Differentiation

---
 src/components/Table/ListTable/TableAction/RightSide.vue | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/components/Table/ListTable/TableAction/RightSide.vue b/src/components/Table/ListTable/TableAction/RightSide.vue
index dc8fa1417..bcc8e85e5 100644
--- a/src/components/Table/ListTable/TableAction/RightSide.vue
+++ b/src/components/Table/ListTable/TableAction/RightSide.vue
@@ -155,13 +155,20 @@ export default {
       })
     },
     iExportOptions() {
+      if (this.$route.name === 'AssetAccountList') {
+        // 在账号列表中,第一次点击 export 时的 url 是 /accounts/account-secrets/ 都导致无法出现对话框
+        return assignIfNot(this.exportOptions, { url: this.tableUrl })
+      }
+
       /**
        *  原本是使用 assignIfNot 此函数内部使用 partialRight, 该函数
        *  只在目标对象的属性未定义时才从源对象复制属性,如果目标对象已经有值,则保留原值
        *  那如果首次点击的树节点,那么此时 url 就会被确定,后续点击的树节点,那么 url 就不会
        *  改变了
+       *
+       *  主要是在资产列表中,切换节点的时候
        */
-      return Object.assign({}, this.exportOptions, { url: this.tableUrl })
+      return Object.assign(this.exportOptions, { url: this.tableUrl })
     }
   },
   methods: {

From 906a1accd1a7bd3b4894ecb11e71e9670ab26ef0 Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Fri, 7 Feb 2025 11:35:31 +0800
Subject: [PATCH 02/21] feat: Chat ai setting

---
 src/views/settings/Feature/Chat.vue | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/views/settings/Feature/Chat.vue b/src/views/settings/Feature/Chat.vue
index dc740de88..a202279ab 100644
--- a/src/views/settings/Feature/Chat.vue
+++ b/src/views/settings/Feature/Chat.vue
@@ -41,7 +41,9 @@ export default {
       encryptedFields: ['VAULT_HCP_TOKEN'],
       fields: [
         'CHAT_AI_ENABLED',
+        'CHAT_AI_TYPE',
         'GPT_MODEL',
+        'DEEPSEEK_MODEL',
         'GPT_BASE_URL',
         'GPT_API_KEY',
         'GPT_PROXY'
@@ -57,6 +59,16 @@ export default {
             autocomplete: 'new-password'
           }
         },
+        GPT_MODEL: {
+          hidden: (formValue) => {
+            return formValue.CHAT_AI_TYPE !== 'gpt'
+          }
+        },
+        DEEPSEEK_MODEL: {
+          hidden: (formValue) => {
+            return formValue.CHAT_AI_TYPE !== 'deep-seek'
+          }
+        },
         GPT_PROXY: {
         }
       },

From 0e53d7e6570684783bd57ae07a5c85ae6ec87dfa Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Sat, 8 Feb 2025 14:51:44 +0800
Subject: [PATCH 03/21] Perf: Support DeepSeek

---
 src/assets/img/deepSeek.png                   | Bin 0 -> 3904 bytes
 .../components/ChitChat/ChatMessage.vue       | 305 ++++++++++++------
 .../Apps/ChatAi/components/ChitChat/index.vue |  12 +-
 src/store/modules/chat.js                     |  23 +-
 4 files changed, 231 insertions(+), 109 deletions(-)
 create mode 100644 src/assets/img/deepSeek.png

diff --git a/src/assets/img/deepSeek.png b/src/assets/img/deepSeek.png
new file mode 100644
index 0000000000000000000000000000000000000000..963048589f554982ea9ba305345d70bb5389068b
GIT binary patch
literal 3904
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
IHFS&n5BDKf00000

literal 0
HcmV?d00001

diff --git a/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue b/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue
index 500275440..a4b09edc8 100644
--- a/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue
+++ b/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue
@@ -1,42 +1,71 @@
 <template>
-  <div :class="{'user-role': isUserRole}" class="chat-item">
-    <div class="avatar">
-      <el-avatar :src="isUserRole ? userUrl : chatUrl" class="header-avatar" />
-    </div>
-    <div class="content">
-      <div class="operational">
-        <span class="date">
-          {{ $moment(item.message.create_time).format('YYYY-MM-DD HH:mm:ss') }}
-        </span>
+  <div :class="{ 'user-role': isUserRole }" class="chat-item">
+    <div class="chart-item-container">
+      <div class="avatar">
+        <el-avatar
+          :src="isUserRole ? userUrl : chatUrl"
+          class="header-avatar"
+        />
       </div>
-      <div class="message">
-        <div class="message-content">
-          <span v-if="isSystemError" class="error">
-            {{ item.message.content }}
-          </span>
-          <span v-else class="chat-text">
-            <MessageText :message="item.message" />
-          </span>
+      <div class="content">
+        <div class="operational">
+          <div v-if="!item.reasoning" class="date">
+            {{
+              $moment(item.message.create_time).format("YYYY-MM-DD HH:mm:ss")
+            }}
+          </div>
+
+          <div v-else class="thinking-time">已深度思考</div>
         </div>
-        <div class="action">
-          <el-tooltip
-            v-if="isSystemError && isLoading"
-            :content="$tc('Reconnect')"
-            :open-delay="500"
-            placement="top"
-          >
-            <svg-icon icon-class="refresh" @click="onRefresh" />
-          </el-tooltip>
-          <el-dropdown v-else size="small" @command="handleCommand">
-            <span class="el-dropdown-link">
-              <i class="fa fa-ellipsis-v" />
-            </span>
-            <el-dropdown-menu slot="dropdown">
-              <el-dropdown-item v-for="i in dropdownOptions" :key="i.action" :command="i.action">
-                {{ i.label }}
-              </el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
+        <div :class="item.reasoning ? 'reasoning' : 'message'">
+          <div class="message-content">
+            <div v-if="!item.reasoning">
+              <span v-if="isSystemError" class="error">
+                {{ item.message.content }}
+              </span>
+              <span v-else class="chat-text">
+                <MessageText :message="item.message" />
+              </span>
+            </div>
+
+            <div v-else class="thinking-wrapper">
+              <div class="thinking-content">
+                <!-- eslint-disable-next-line -->
+                <div class="divider"></div>
+                <p>
+                  <MessageText :message="item.reasoning" />
+                </p>
+              </div>
+
+              <div class="thinking-result">
+                <MessageText :message="item.result" />
+              </div>
+            </div>
+          </div>
+          <div class="action">
+            <el-tooltip
+              v-if="isSystemError && isLoading"
+              :content="$tc('Reconnect')"
+              :open-delay="500"
+              placement="top"
+            >
+              <svg-icon icon-class="refresh" @click="onRefresh" />
+            </el-tooltip>
+            <el-dropdown v-else size="small" @command="handleCommand">
+              <span class="el-dropdown-link">
+                <i class="fa fa-ellipsis-v" />
+              </span>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item
+                  v-for="i in dropdownOptions"
+                  :key="i.action"
+                  :command="i.action"
+                >
+                  {{ i.label }}
+                </el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+          </div>
         </div>
       </div>
     </div>
@@ -45,7 +74,7 @@
 
 <script>
 import MessageText from './MessageText.vue'
-import { mapState } from 'vuex'
+import { mapGetters, mapState } from 'vuex'
 import { copy } from '@/utils/common'
 import { useChat } from '../../useChat.js'
 import { reconnect } from '@/utils/socket'
@@ -65,7 +94,6 @@ export default {
   },
   data() {
     return {
-      chatUrl: require('@/assets/img/chat.png'),
       userUrl: '/api/v1/settings/logo/',
       dropdownOptions: [
         {
@@ -79,11 +107,21 @@ export default {
     ...mapState({
       isLoading: state => state.chat.loading
     }),
+    ...mapGetters([
+      'publicSettings'
+    ]),
     isUserRole() {
       return this.item.message?.role === 'user'
     },
     isSystemError() {
-      return this.item.type === 'error' && this.item.message?.role === 'assistant'
+      return (
+        this.item.type === 'error' && this.item?.role === 'assistant'
+      )
+    },
+    chatUrl() {
+      return this.publicSettings.CHAT_AI_TYPE === 'gpt'
+        ? require('@/assets/img/chat.png')
+        : require('@/assets/img/deepSeek.png')
     }
   },
   methods: {
@@ -94,7 +132,7 @@ export default {
     },
     handleCommand(value) {
       if (value === 'copy') {
-        copy(this.item.message.content)
+        copy(this.item.result.content)
       }
     }
   }
@@ -104,101 +142,160 @@ export default {
 <style lang="scss" scoped>
 .chat-item {
   display: flex;
-  padding: 16px 14px 0;
+  padding: 0.5rem;
 
-  &:last-child {
-    padding-bottom: 16px;
-  }
+  .chart-item-container {
+    display: flex;
+    gap: 0.5rem;
 
-  .avatar {
-    width: 22px;
-    height: 22px;
-    margin-top: 2px;
+    .avatar {
+      width: 24px;
+      height: 24px;
+      margin-top: 2px;
 
-    .header-avatar {
-      width: 100%;
-      height: 100%;
+      .header-avatar {
+        width: 100%;
+        height: 100%;
+        border-radius: 50%;
 
-      &::v-deep img {
-        background-color: #e5e5e7;
+        &::v-deep img {
+          background-color: #fff;
+        }
       }
     }
-  }
 
-  .content {
-    margin-left: 6px;
-    overflow: hidden;
-
-    .operational {
+    .content {
       display: flex;
-      justify-content: space-between;
+      flex-direction: column;
+      gap: 0.5rem;
       overflow: hidden;
 
-      .copy {
-        float: right;
-        cursor: pointer;
-      }
-    }
+      .operational {
+        display: flex;
+        justify-content: space-between;
+        overflow: hidden;
 
-    .message {
-      display: -webkit-box;
-
-      .message-content {
-        flex: 1;
-        padding: 6px 10px;
-        border-radius: 2px 12px 12px;
-        background-color: #f0f1f5;
-      }
-
-      .action {
-        .svg-icon {
-          transform: translateY(50%);
-          margin-left: 3px;
-          cursor: pointer;
+        .date {
+          padding-top: 5px;
         }
 
-        .el-dropdown {
-          height: 32px;
-          line-height: 37px;
-          font-size: 13px;
+        .thinking-time {
+          width: 6rem;
+          display: flex;
+          justify-content: center;
+          padding: 5px 10px;
+          border-radius: 0.5rem;
+          background-color: #f5f5f5;
+        }
 
-          .el-dropdown-link {
-            i {
-              padding: 4px 5px;
-              font-size: 15px;
-              color: #8d9091;
+        .copy {
+          float: right;
+          cursor: pointer;
+        }
+      }
 
-              &:hover {
-                color: #7b8085
+      .reasoning {
+        display: flex;
+        gap: 0.5rem;
+        align-items: flex-end;
+
+        .message-content .thinking-wrapper {
+          display: flex;
+          flex-direction: column;
+          gap: 0.5rem;
+
+          .thinking-content {
+            position: relative;
+            color: #8b8b8b;
+
+            .divider {
+              position: absolute;
+              top: 0;
+              left: 0;
+              height: 100%;
+              border-left: 2px solid #e5e5e5;
+            }
+
+            p {
+              margin: unset;
+              padding-left: 0.5rem;
+
+              ::v-deep p {
+                color: #8b8b8b;
               }
             }
           }
         }
       }
 
-      .error {
-        color: red;
+      .message {
+        display: -webkit-box;
+
+        .message-content {
+          flex: 1;
+          padding: 6px 10px;
+          border-radius: 2px 12px 12px;
+          background-color: #f0f1f5;
+        }
+
+        .action {
+          .svg-icon {
+            transform: translateY(50%);
+            margin-left: 3px;
+            cursor: pointer;
+          }
+
+          .el-dropdown {
+            height: 32px;
+            line-height: 37px;
+            font-size: 13px;
+
+            .el-dropdown-link {
+              i {
+                padding: 4px 5px;
+                font-size: 15px;
+                color: #8d9091;
+
+                &:hover {
+                  color: #7b8085;
+                }
+              }
+            }
+          }
+        }
+
+        .error {
+          color: red;
+        }
       }
     }
   }
-}
 
-.user-role {
-  flex-direction: row-reverse;
+  &:last-child {
+    padding-bottom: 16px;
+  }
 
-  .content {
-    margin-right: 10px;
+  &.user-role {
+    flex-direction: row-reverse;
 
-    .operational {
+    .chart-item-container {
       flex-direction: row-reverse;
     }
 
-    .message {
-      flex-direction: row-reverse;
+    .content {
+      margin-right: 10px;
 
-      .message-content {
-        background-color: var(--menu-hover);
-        border-radius: 12px 2px 12px 12px;
+      .operational {
+        flex-direction: row-reverse;
+      }
+
+      .message {
+        flex-direction: row-reverse;
+
+        .message-content {
+          background-color: var(--menu-hover);
+          border-radius: 12px 2px 12px 12px;
+        }
       }
     }
   }
diff --git a/src/components/Apps/ChatAi/components/ChitChat/index.vue b/src/components/Apps/ChatAi/components/ChitChat/index.vue
index 34198fc1e..0ab535e9b 100644
--- a/src/components/Apps/ChatAi/components/ChitChat/index.vue
+++ b/src/components/Apps/ChatAi/components/ChitChat/index.vue
@@ -123,7 +123,17 @@ export default {
         setLoading(true)
         removeLoadingMessageInChat()
         this.conversationId = data.id
-        updateChaMessageContentById(data.message.id, data)
+
+        const newFragment = {
+          message: { id: data.message.id },
+          reasoning: { content: data.message.is_reasoning ? data.message.content : '' },
+          result: { content: data.message.is_reasoning ? '' : data.message.content },
+          role: data.message.role,
+          type: data.message.type,
+          create_time: data.message.create_time
+        }
+
+        updateChaMessageContentById(data.message.id, newFragment)
       }
       if (data.message?.type === 'finish') {
         setLoading(false)
diff --git a/src/store/modules/chat.js b/src/store/modules/chat.js
index 979360154..398926924 100644
--- a/src/store/modules/chat.js
+++ b/src/store/modules/chat.js
@@ -40,11 +40,26 @@ const mutations = {
 
   updateChaMessageContentById(state, { id, data }) {
     const chats = state.activeChat.chats || []
-    const filterChat = chats.filter((chat) => chat.message.id === id)?.[0] || {}
-    if (Object.keys(filterChat).length > 0) {
-      filterChat.message.content = data.message.content
+    const index = chats.findIndex((chat) => chat.message.id === data.message.id)
+
+    if (index === -1) {
+      // 如果没有记录,直接添加新消息
+      chats.push({
+        message: { id: data.message.id },
+        reasoning: { content: data.reasoning.content },
+        result: { content: data.result.content },
+        role: data.role,
+        type: data.type,
+        create_time: data.create_time
+      })
     } else {
-      chats?.push(data)
+      if (data.reasoning.content !== '') {
+        chats[index].reasoning.content = data.reasoning.content
+      }
+
+      if (data.result.content !== '') {
+        chats[index].result.content = data.result.content
+      }
     }
   }
 }

From 9e768f4ef4ed385f20e57b84503f2b010c0f6ea0 Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Sat, 8 Feb 2025 15:30:39 +0800
Subject: [PATCH 04/21] Fixed: Fixed time and thinking tip

---
 src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue | 2 +-
 src/components/Apps/ChatAi/components/ChitChat/index.vue       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue b/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue
index a4b09edc8..953676bdc 100644
--- a/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue
+++ b/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue
@@ -9,7 +9,7 @@
       </div>
       <div class="content">
         <div class="operational">
-          <div v-if="!item.reasoning" class="date">
+          <div v-if="!item.message.is_reasoning" class="date">
             {{
               $moment(item.message.create_time).format("YYYY-MM-DD HH:mm:ss")
             }}
diff --git a/src/components/Apps/ChatAi/components/ChitChat/index.vue b/src/components/Apps/ChatAi/components/ChitChat/index.vue
index 0ab535e9b..f01c559fe 100644
--- a/src/components/Apps/ChatAi/components/ChitChat/index.vue
+++ b/src/components/Apps/ChatAi/components/ChitChat/index.vue
@@ -125,7 +125,7 @@ export default {
         this.conversationId = data.id
 
         const newFragment = {
-          message: { id: data.message.id },
+          message: { id: data.message.id, is_reasoning: data.message.is_reasoning },
           reasoning: { content: data.message.is_reasoning ? data.message.content : '' },
           result: { content: data.message.is_reasoning ? '' : data.message.content },
           role: data.message.role,

From 4bc039185cb79dbbba5de326ad4f176240bc0cfc Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Mon, 10 Feb 2025 16:11:14 +0800
Subject: [PATCH 05/21] Fixed: Fixed Fix account template redirection error in
 remote applications

---
 .../components/AccountTemplateDialog.vue                  | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/views/assets/Asset/AssetCreateUpdate/components/AccountTemplateDialog.vue b/src/views/assets/Asset/AssetCreateUpdate/components/AccountTemplateDialog.vue
index 2fc96d42a..a2adfedd5 100644
--- a/src/views/assets/Asset/AssetCreateUpdate/components/AccountTemplateDialog.vue
+++ b/src/views/assets/Asset/AssetCreateUpdate/components/AccountTemplateDialog.vue
@@ -65,9 +65,11 @@ export default {
         columns: ['name', 'username', 'secret_type', 'privileged'],
         columnsMeta: {
           name: {
-            formatterArgs: {
-              route: 'AccountTemplateDetail'
-            }
+            formatter: (row) => <span>{row.name}</span>
+            // 暂禁用远程应用中账号模板的详情跳转
+            // formatterArgs: {
+            //   route: 'AccountTemplateDetail'
+            // }
           },
           privileged: {
             width: '120px'

From 5d5e87595b35aaf4ef69d85a2b024a9301b6a8c0 Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Mon, 10 Feb 2025 17:44:05 +0800
Subject: [PATCH 06/21] perf: Login acl del license

---
 src/router/console/acls.js                | 1 -
 src/views/users/User/UserDetail/index.vue | 3 +--
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/router/console/acls.js b/src/router/console/acls.js
index 25a601845..b0aa222f2 100644
--- a/src/router/console/acls.js
+++ b/src/router/console/acls.js
@@ -24,7 +24,6 @@ export default [
         meta: {
           title: i18n.t('BaseUserLoginAclList'),
           app: 'acls',
-          licenseRequired: true,
           resource: 'loginacl',
           disableOrgsChange: true
         },
diff --git a/src/views/users/User/UserDetail/index.vue b/src/views/users/User/UserDetail/index.vue
index c4e3ee285..9a27da422 100644
--- a/src/views/users/User/UserDetail/index.vue
+++ b/src/views/users/User/UserDetail/index.vue
@@ -19,7 +19,6 @@ import AssetPermissionAsset from '@/views/perms/AssetPermission/AssetPermissionD
 import AssetPermissionDetail from '@/views/perms/AssetPermission/AssetPermissionDetail/index.vue'
 import AssetPermissionAccount from '@/views/perms/AssetPermission/AssetPermissionDetail/AssetPermissionAccount.vue'
 import UserAssetPermissionRules from './UserAssetPermissionRules'
-import store from '@/store'
 
 export default {
   components: {
@@ -64,7 +63,7 @@ export default {
           {
             title: this.$t('UserAclLists'),
             name: 'UserLoginAcl',
-            hidden: () => !vm.$hasPerm('acls.view_loginacl') || !store.getters.publicSettings.XPACK_LICENSE_IS_VALID
+            hidden: () => !vm.$hasPerm('acls.view_loginacl')
           },
           {
             title: this.$t('UserSession'),

From e93979ab5f8dafdfd3a3fa618980325dee582e3b Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Mon, 10 Feb 2025 19:12:44 +0800
Subject: [PATCH 07/21] perf: perm filter translate

---
 src/views/perms/const.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/views/perms/const.js b/src/views/perms/const.js
index e359d326d..6d892ab47 100644
--- a/src/views/perms/const.js
+++ b/src/views/perms/const.js
@@ -9,21 +9,21 @@ export const UserAssetPermissionListPageSearchConfigOptions = [
   { label: i18n.t('AssetAddress'), value: 'address' },
   { label: i18n.t('Account'), value: 'accounts' },
   {
-    label: i18n.t('isValid'), value: 'is_valid',
+    label: i18n.t('Valid'), value: 'is_valid',
     children: [
       { value: '1', label: i18n.t('Yes') },
       { value: '0', label: i18n.t('No') }
     ]
   },
   {
-    label: i18n.t('isEffective'), value: 'is_effective',
+    label: i18n.t('Effective'), value: 'is_effective',
     children: [
       { value: '1', label: i18n.t('Yes') },
       { value: '0', label: i18n.t('No') }
     ]
   },
   {
-    label: i18n.t('fromTicket'), value: 'from_ticket',
+    label: i18n.t('FromTicket'), value: 'from_ticket',
     children: [
       { value: '1', label: i18n.t('Yes') },
       { value: '0', label: i18n.t('No') }

From d94752a0212aedebb6e00f5fa5f3aedd890e1e17 Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Thu, 13 Feb 2025 11:28:23 +0800
Subject: [PATCH 08/21] perf: chat help text

---
 src/views/settings/Feature/Chat.vue | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/views/settings/Feature/Chat.vue b/src/views/settings/Feature/Chat.vue
index a202279ab..c7b51ded7 100644
--- a/src/views/settings/Feature/Chat.vue
+++ b/src/views/settings/Feature/Chat.vue
@@ -59,6 +59,9 @@ export default {
             autocomplete: 'new-password'
           }
         },
+        CHAT_AI_TYPE: {
+          helpText: this.$t('ChatAITypeHelpText')
+        },
         GPT_MODEL: {
           hidden: (formValue) => {
             return formValue.CHAT_AI_TYPE !== 'gpt'

From d6c28b82862c785cdc905a98e38123cae8e2c00c Mon Sep 17 00:00:00 2001
From: fit2bot <68588906+fit2bot@users.noreply.github.com>
Date: Thu, 13 Feb 2025 15:55:58 +0800
Subject: [PATCH 09/21] Fixed: Fixed PT-BR language adaptation issue (#4636)

* Fixed: Fixed PT-BR language adaptation issue

* Fiexed: Fixed En languange ACL Page adapation issue

---------

Co-authored-by: zhaojisen <1301338853@qq.com>
---
 src/components/Form/FormFields/DatetimeRangePicker.vue | 6 ++++++
 src/components/QuickActions/index.vue                  | 3 +--
 src/views/accounts/Account/AccountList.vue             | 7 ++++++-
 src/views/acl/UserLoginACL/UserLoginACLTable.vue       | 1 +
 src/views/assets/Asset/AssetDetail/PermUser.vue        | 1 +
 src/views/dashboard/Console/RankSummary.vue            | 4 ++--
 src/views/dashboard/components/RankTable.vue           | 5 +++--
 7 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/src/components/Form/FormFields/DatetimeRangePicker.vue b/src/components/Form/FormFields/DatetimeRangePicker.vue
index 1e2d85286..d392c6871 100644
--- a/src/components/Form/FormFields/DatetimeRangePicker.vue
+++ b/src/components/Form/FormFields/DatetimeRangePicker.vue
@@ -84,6 +84,12 @@ export default {
 </script>
 
 <style lang='scss' scoped>
+html:lang(pt-br) {
+  .datepicker ::v-deep .el-range-separator {
+    padding: 0 10px;
+  }
+}
+
 .datepicker {
   margin-left: 10px;
   width: 233px;
diff --git a/src/components/QuickActions/index.vue b/src/components/QuickActions/index.vue
index 2e5ea7fe9..47f9b92a7 100644
--- a/src/components/QuickActions/index.vue
+++ b/src/components/QuickActions/index.vue
@@ -76,8 +76,7 @@ export default {
     font-size: 13px;
 
     span {
-      overflow: hidden;
-      white-space: nowrap; /* 控制文本不换行 */
+      white-space: nowrap;
       text-overflow: ellipsis;
       display: block;
     }
diff --git a/src/views/accounts/Account/AccountList.vue b/src/views/accounts/Account/AccountList.vue
index a4a0de620..b8618d4a1 100644
--- a/src/views/accounts/Account/AccountList.vue
+++ b/src/views/accounts/Account/AccountList.vue
@@ -24,7 +24,12 @@ export default {
       tableConfig: {
         url: '/api/v1/accounts/accounts/',
         hasLeftActions: true,
-        hasImport: true
+        hasImport: true,
+        columnsMeta: {
+          actions: {
+            width: this.$i18n.locale === 'pt-br' ? '120px' : '100px'
+          }
+        }
       },
       treeSetting: {
         showMenu: false,
diff --git a/src/views/acl/UserLoginACL/UserLoginACLTable.vue b/src/views/acl/UserLoginACL/UserLoginACLTable.vue
index f9392ece1..c3dc004bd 100644
--- a/src/views/acl/UserLoginACL/UserLoginACLTable.vue
+++ b/src/views/acl/UserLoginACL/UserLoginACLTable.vue
@@ -37,6 +37,7 @@ export default {
             label: this.$t('ApproverNumbers')
           },
           actions: {
+            width: (this.$i18n.locale === 'pt-br' || this.$i18n.locale === 'en') ? '120px' : '100px',
             formatterArgs: {
               hasClone: false,
               updateRoute: ({ row }) => {
diff --git a/src/views/assets/Asset/AssetDetail/PermUser.vue b/src/views/assets/Asset/AssetDetail/PermUser.vue
index 8cb3d439d..bfeed652e 100644
--- a/src/views/assets/Asset/AssetDetail/PermUser.vue
+++ b/src/views/assets/Asset/AssetDetail/PermUser.vue
@@ -103,6 +103,7 @@ export default {
             width: '200px'
           },
           actions: {
+            width: this.$i18n.locale === 'pt-br' ? '120px' : '100px',
             formatterArgs: {
               hasUpdate: false,
               hasDelete: false,
diff --git a/src/views/dashboard/Console/RankSummary.vue b/src/views/dashboard/Console/RankSummary.vue
index 459f30249..f1f42242e 100644
--- a/src/views/dashboard/Console/RankSummary.vue
+++ b/src/views/dashboard/Console/RankSummary.vue
@@ -33,7 +33,7 @@ export default {
           {
             prop: 'total',
             label: this.$t('LoginCount'),
-            width: '120px'
+            width: this.$i18n.locale === 'zh-CN' ? '120px' : '220px'
           }
         ]
       },
@@ -50,7 +50,7 @@ export default {
           {
             prop: 'total',
             label: this.$t('NumberOfVisits'),
-            width: '140px'
+            width: this.$i18n.locale === 'zh-CN' ? '140px' : '140px'
           }
         ]
       }
diff --git a/src/views/dashboard/components/RankTable.vue b/src/views/dashboard/components/RankTable.vue
index 9b66c4dff..a25e4fa18 100644
--- a/src/views/dashboard/components/RankTable.vue
+++ b/src/views/dashboard/components/RankTable.vue
@@ -9,13 +9,14 @@
       class="table"
       style="width: 100%"
     >
-      <el-table-column :label="$tc('Ranking')" width="80px">
-        <template v-slot="scope" #header>
+      <el-table-column :label="$tc('Ranking')" :width="this.$i18n.locale === 'zh-CN' ? '80px' : '110px'">
+        <template #header>
           <el-tooltip :content="$t('Ranking')" placement="top" :open-delay="500">
             <span style="cursor: pointer;">{{ $t('Ranking') }}</span>
           </el-tooltip>
         </template>
       </el-table-column>
+
       <el-table-column
         v-for="i in config.columns"
         :key="i.prop"

From 1c222c3ce0e47cdef07db3d42fb22392defe49c4 Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Thu, 13 Feb 2025 16:17:37 +0800
Subject: [PATCH 10/21] Fixed: PT-BR languange adaptation issue

---
 .../AccountBackupExecution/AccountBackupExecutionList.vue        | 1 +
 .../AccountChangeSecretExecutionList.vue                         | 1 +
 .../accounts/AccountGather/TaskDetail/TaskExecutionList.vue      | 1 +
 src/views/accounts/AccountPush/AccountPushExecutionList.vue      | 1 +
 4 files changed, 4 insertions(+)

diff --git a/src/views/accounts/AccountBackup/AccountBackupDetail/AccountBackupExecution/AccountBackupExecutionList.vue b/src/views/accounts/AccountBackup/AccountBackupDetail/AccountBackupExecution/AccountBackupExecutionList.vue
index aa2206f5d..8f149c6fc 100644
--- a/src/views/accounts/AccountBackup/AccountBackupDetail/AccountBackupExecution/AccountBackupExecutionList.vue
+++ b/src/views/accounts/AccountBackup/AccountBackupDetail/AccountBackupExecution/AccountBackupExecutionList.vue
@@ -59,6 +59,7 @@ export default {
             }
           },
           actions: {
+            width: (this.$i18n.locale === 'pt-br' || this.$i18n.locale === 'en') ? '160px' : '100px',
             formatterArgs: {
               hasDelete: false,
               hasUpdate: false,
diff --git a/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue b/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue
index 48b3164ba..db55c5638 100644
--- a/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue
+++ b/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue
@@ -74,6 +74,7 @@ export default {
             }
           },
           actions: {
+            width: (this.$i18n.locale === 'pt-br' || this.$i18n.locale === 'en') ? '160px' : '100px',
             formatterArgs: {
               hasDelete: false,
               hasUpdate: false,
diff --git a/src/views/accounts/AccountGather/TaskDetail/TaskExecutionList.vue b/src/views/accounts/AccountGather/TaskDetail/TaskExecutionList.vue
index 2fe356eca..10eaa69e8 100644
--- a/src/views/accounts/AccountGather/TaskDetail/TaskExecutionList.vue
+++ b/src/views/accounts/AccountGather/TaskDetail/TaskExecutionList.vue
@@ -57,6 +57,7 @@ export default {
             width: null
           },
           actions: {
+            width: (this.$i18n.locale === 'pt-br' || this.$i18n.locale === 'en') ? '160px' : '100px',
             formatterArgs: {
               hasDelete: false,
               hasUpdate: false,
diff --git a/src/views/accounts/AccountPush/AccountPushExecutionList.vue b/src/views/accounts/AccountPush/AccountPushExecutionList.vue
index 38322c1d3..d34a833f3 100644
--- a/src/views/accounts/AccountPush/AccountPushExecutionList.vue
+++ b/src/views/accounts/AccountPush/AccountPushExecutionList.vue
@@ -74,6 +74,7 @@ export default {
             }
           },
           actions: {
+            width: (this.$i18n.locale === 'pt-br' || this.$i18n.locale === 'en') ? '160px' : '100px',
             formatterArgs: {
               hasDelete: false,
               hasUpdate: false,

From f2e6f89c089099699bc9716611672abf4bed41e9 Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Thu, 13 Feb 2025 16:25:52 +0800
Subject: [PATCH 11/21] Fixed: Fixed PT-BR language adaptation issue

---
 src/components/Table/AutoDataTable/index.vue       | 14 ++++++++++++--
 src/views/accounts/Account/AccountList.vue         |  7 +------
 .../AccountBackupExecutionList.vue                 |  1 -
 .../AccountChangeSecretExecutionList.vue           |  1 -
 .../AccountGather/TaskDetail/TaskExecutionList.vue |  1 -
 .../AccountPush/AccountPushExecutionList.vue       |  1 -
 src/views/acl/UserLoginACL/UserLoginACLTable.vue   |  1 -
 src/views/assets/Asset/AssetDetail/PermUser.vue    |  1 -
 8 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/src/components/Table/AutoDataTable/index.vue b/src/components/Table/AutoDataTable/index.vue
index 5cda1a284..850b672d1 100644
--- a/src/components/Table/AutoDataTable/index.vue
+++ b/src/components/Table/AutoDataTable/index.vue
@@ -65,7 +65,17 @@ export default {
       isDeactivated: false
     }
   },
-  computed: {},
+  computed: {
+    dynamicActionWidth() {
+      if (this.$i18n.locale === 'en') {
+        return '120px'
+      }
+      if (this.$i18n.locale === 'pt-br') {
+        return '160px'
+      }
+      return '100px'
+    }
+  },
   watch: {
     config: {
       handler: _.debounce(function(iNew, iOld) {
@@ -131,7 +141,7 @@ export default {
             prop: 'actions',
             label: i18n.t('Actions'),
             align: 'center',
-            width: '100px',
+            width: this.dynamicActionWidth,
             formatter: ActionsFormatter,
             fixed: 'right',
             formatterArgs: {}
diff --git a/src/views/accounts/Account/AccountList.vue b/src/views/accounts/Account/AccountList.vue
index b8618d4a1..a4a0de620 100644
--- a/src/views/accounts/Account/AccountList.vue
+++ b/src/views/accounts/Account/AccountList.vue
@@ -24,12 +24,7 @@ export default {
       tableConfig: {
         url: '/api/v1/accounts/accounts/',
         hasLeftActions: true,
-        hasImport: true,
-        columnsMeta: {
-          actions: {
-            width: this.$i18n.locale === 'pt-br' ? '120px' : '100px'
-          }
-        }
+        hasImport: true
       },
       treeSetting: {
         showMenu: false,
diff --git a/src/views/accounts/AccountBackup/AccountBackupDetail/AccountBackupExecution/AccountBackupExecutionList.vue b/src/views/accounts/AccountBackup/AccountBackupDetail/AccountBackupExecution/AccountBackupExecutionList.vue
index 8f149c6fc..aa2206f5d 100644
--- a/src/views/accounts/AccountBackup/AccountBackupDetail/AccountBackupExecution/AccountBackupExecutionList.vue
+++ b/src/views/accounts/AccountBackup/AccountBackupDetail/AccountBackupExecution/AccountBackupExecutionList.vue
@@ -59,7 +59,6 @@ export default {
             }
           },
           actions: {
-            width: (this.$i18n.locale === 'pt-br' || this.$i18n.locale === 'en') ? '160px' : '100px',
             formatterArgs: {
               hasDelete: false,
               hasUpdate: false,
diff --git a/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue b/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue
index db55c5638..48b3164ba 100644
--- a/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue
+++ b/src/views/accounts/AccountChangeSecret/AccountChangeSecretDetail/AccountChangeSecretExecution/AccountChangeSecretExecutionList.vue
@@ -74,7 +74,6 @@ export default {
             }
           },
           actions: {
-            width: (this.$i18n.locale === 'pt-br' || this.$i18n.locale === 'en') ? '160px' : '100px',
             formatterArgs: {
               hasDelete: false,
               hasUpdate: false,
diff --git a/src/views/accounts/AccountGather/TaskDetail/TaskExecutionList.vue b/src/views/accounts/AccountGather/TaskDetail/TaskExecutionList.vue
index 10eaa69e8..2fe356eca 100644
--- a/src/views/accounts/AccountGather/TaskDetail/TaskExecutionList.vue
+++ b/src/views/accounts/AccountGather/TaskDetail/TaskExecutionList.vue
@@ -57,7 +57,6 @@ export default {
             width: null
           },
           actions: {
-            width: (this.$i18n.locale === 'pt-br' || this.$i18n.locale === 'en') ? '160px' : '100px',
             formatterArgs: {
               hasDelete: false,
               hasUpdate: false,
diff --git a/src/views/accounts/AccountPush/AccountPushExecutionList.vue b/src/views/accounts/AccountPush/AccountPushExecutionList.vue
index d34a833f3..38322c1d3 100644
--- a/src/views/accounts/AccountPush/AccountPushExecutionList.vue
+++ b/src/views/accounts/AccountPush/AccountPushExecutionList.vue
@@ -74,7 +74,6 @@ export default {
             }
           },
           actions: {
-            width: (this.$i18n.locale === 'pt-br' || this.$i18n.locale === 'en') ? '160px' : '100px',
             formatterArgs: {
               hasDelete: false,
               hasUpdate: false,
diff --git a/src/views/acl/UserLoginACL/UserLoginACLTable.vue b/src/views/acl/UserLoginACL/UserLoginACLTable.vue
index c3dc004bd..f9392ece1 100644
--- a/src/views/acl/UserLoginACL/UserLoginACLTable.vue
+++ b/src/views/acl/UserLoginACL/UserLoginACLTable.vue
@@ -37,7 +37,6 @@ export default {
             label: this.$t('ApproverNumbers')
           },
           actions: {
-            width: (this.$i18n.locale === 'pt-br' || this.$i18n.locale === 'en') ? '120px' : '100px',
             formatterArgs: {
               hasClone: false,
               updateRoute: ({ row }) => {
diff --git a/src/views/assets/Asset/AssetDetail/PermUser.vue b/src/views/assets/Asset/AssetDetail/PermUser.vue
index bfeed652e..8cb3d439d 100644
--- a/src/views/assets/Asset/AssetDetail/PermUser.vue
+++ b/src/views/assets/Asset/AssetDetail/PermUser.vue
@@ -103,7 +103,6 @@ export default {
             width: '200px'
           },
           actions: {
-            width: this.$i18n.locale === 'pt-br' ? '120px' : '100px',
             formatterArgs: {
               hasUpdate: false,
               hasDelete: false,

From 5708aa25c4cf278b098035838e45adb0f112370f Mon Sep 17 00:00:00 2001
From: feng <1304903146@qq.com>
Date: Thu, 13 Feb 2025 15:57:43 +0800
Subject: [PATCH 12/21] perf: Deepseek

---
 src/views/settings/Feature/Chat.vue | 42 ++++++++++++++++++++++++-----
 1 file changed, 36 insertions(+), 6 deletions(-)

diff --git a/src/views/settings/Feature/Chat.vue b/src/views/settings/Feature/Chat.vue
index c7b51ded7..4f93f2825 100644
--- a/src/views/settings/Feature/Chat.vue
+++ b/src/views/settings/Feature/Chat.vue
@@ -42,37 +42,67 @@ export default {
       fields: [
         'CHAT_AI_ENABLED',
         'CHAT_AI_TYPE',
-        'GPT_MODEL',
+        'DEEPSEEK_BASE_URL',
+        'DEEPSEEK_API_KEY',
+        'DEEPSEEK_PROXY',
         'DEEPSEEK_MODEL',
         'GPT_BASE_URL',
         'GPT_API_KEY',
-        'GPT_PROXY'
+        'GPT_PROXY',
+        'GPT_MODEL'
       ],
       fieldsMeta: {
         GPT_BASE_URL: {
           el: {
             autocomplete: 'new-password'
+          },
+          hidden: (formValue) => {
+            return formValue.CHAT_AI_TYPE !== 'gpt'
           }
         },
         GPT_API_KEY: {
           el: {
             autocomplete: 'new-password'
+          },
+          hidden: (formValue) => {
+            return formValue.CHAT_AI_TYPE !== 'gpt'
           }
         },
-        CHAT_AI_TYPE: {
-          helpText: this.$t('ChatAITypeHelpText')
+        GPT_PROXY: {
+          hidden: (formValue) => {
+            return formValue.CHAT_AI_TYPE !== 'gpt'
+          }
         },
         GPT_MODEL: {
           hidden: (formValue) => {
             return formValue.CHAT_AI_TYPE !== 'gpt'
           }
         },
-        DEEPSEEK_MODEL: {
+        DEEPSEEK_BASE_URL: {
+          el: {
+            autocomplete: 'new-password'
+          },
           hidden: (formValue) => {
             return formValue.CHAT_AI_TYPE !== 'deep-seek'
           }
         },
-        GPT_PROXY: {
+        DEEPSEEK_API_KEY: {
+          el: {
+            autocomplete: 'new-password'
+          },
+          hidden: (formValue) => {
+            return formValue.CHAT_AI_TYPE !== 'deep-seek'
+          }
+        },
+        DEEPSEEK_PROXY: {
+          hidden: (formValue) => {
+            return formValue.CHAT_AI_TYPE !== 'deep-seek'
+          }
+        },
+        DEEPSEEK_MODEL: {
+          hidden: (formValue) => {
+            return formValue.CHAT_AI_TYPE !== 'deep-seek'
+          }
         }
       },
       submitMethod() {

From 60b8748b951e0eeefb298343c72f8556d007fdcc Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Thu, 13 Feb 2025 17:01:34 +0800
Subject: [PATCH 13/21] Fixed: PT-BR languange in Setting Show Tooltip

---
 .../Table/AutoDataTable/components/ColumnSettingPopover.vue      | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/Table/AutoDataTable/components/ColumnSettingPopover.vue b/src/components/Table/AutoDataTable/components/ColumnSettingPopover.vue
index 03ff6e253..b5f455e06 100644
--- a/src/components/Table/AutoDataTable/components/ColumnSettingPopover.vue
+++ b/src/components/Table/AutoDataTable/components/ColumnSettingPopover.vue
@@ -36,6 +36,7 @@
           <el-checkbox
             :disabled="item.prop==='actions' || minColumns.indexOf(item.prop)!==-1"
             :label="item.prop"
+            :title="item.label"
           >
             {{ item.label }}
           </el-checkbox>

From 59945ad7988d26a6846f5ff1f0edf1a275569b62 Mon Sep 17 00:00:00 2001
From: w940853815 <940853815@qq.com>
Date: Mon, 17 Feb 2025 11:14:20 +0800
Subject: [PATCH 14/21] fix: When select_default_value is null, editing the
 playbook reports an error

---
 src/views/ops/Template/components/Variable.vue | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/views/ops/Template/components/Variable.vue b/src/views/ops/Template/components/Variable.vue
index 7cd46ce6c..843709691 100644
--- a/src/views/ops/Template/components/Variable.vue
+++ b/src/views/ops/Template/components/Variable.vue
@@ -1,4 +1,4 @@
-<template>
+~<template>
   <div>
     <div class="variables el-data-table">
       <el-table :data="variables" class="el-table--fit el-table--border">
@@ -81,7 +81,7 @@ export default {
         if (oldVal === undefined) return
         if (newVal.length > 0 || !this.initial) {
           newVal.map((item) => {
-            item.default_value = item.text_default_value || item.select_default_value
+            item.default_value = item.text_default_value || item.select_default_value || undefined
           })
           this.$emit('input', newVal)
         }

From 910bef6695f1a6f4bf69528e901b16a5d760a4e0 Mon Sep 17 00:00:00 2001
From: jiangweidong <1053570670@qq.com>
Date: Mon, 17 Feb 2025 15:08:05 +0800
Subject: [PATCH 15/21] fix: When the scheduled synchronization interval is
 empty, the submission fails

---
 src/views/assets/Cloud/Account/components/TimingPanel.vue | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/views/assets/Cloud/Account/components/TimingPanel.vue b/src/views/assets/Cloud/Account/components/TimingPanel.vue
index a89b2af24..5f11330a4 100644
--- a/src/views/assets/Cloud/Account/components/TimingPanel.vue
+++ b/src/views/assets/Cloud/Account/components/TimingPanel.vue
@@ -71,10 +71,9 @@ export default {
       form.validate((valid) => {
         if (valid) {
           btn.loading = true
+          this.$refs.form.$refs.form.dataForm.submitForm('form', false)
         }
       })
-      form.value.interval = parseInt(form.value.interval, 10)
-      this.$refs.form.$refs.form.dataForm.submitForm('form', false)
     },
     handleSubmitSuccess(res) {
       this.$emit('update:visible', false)

From eddff3d75be109b264e4a38db26967f86619eda7 Mon Sep 17 00:00:00 2001
From: jiangweidong <1053570670@qq.com>
Date: Mon, 17 Feb 2025 15:48:25 +0800
Subject: [PATCH 16/21] perf: Optimize the display of labels in strategy
 actions

---
 .../Cloud/Strategy/components/ActionInput.vue | 27 ++++++++++---------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/views/assets/Cloud/Strategy/components/ActionInput.vue b/src/views/assets/Cloud/Strategy/components/ActionInput.vue
index eab9b9ee6..c3d55fce8 100644
--- a/src/views/assets/Cloud/Strategy/components/ActionInput.vue
+++ b/src/views/assets/Cloud/Strategy/components/ActionInput.vue
@@ -39,8 +39,7 @@ export default {
         submitBtnSize: 'mini',
         submitBtnText: this.$t('Add'),
         hasReset: false,
-        onSubmit: () => {
-        },
+        onSubmit: () => {},
         submitMethod: () => 'post',
         getUrl: () => '',
         cleanFormValue(data) {
@@ -110,26 +109,30 @@ export default {
                 url: '',
                 clearable: false,
                 transformOption: (item) => {
-                  let label
+                  let display
                   switch (this.resourceType) {
                     case 'platform':
-                      label = item?.name
+                      display = item?.name
                       this.globalProtocols[item.id] = item.protocols
-                      this.globalResource[item.id] = label
+                      this.globalResource[item.id] = display
                       break
                     case 'account_template':
-                      label = `${item.name}(${item.username})`
-                      this.globalResource[item.id] = label
+                      display = `${item.name}(${item.username})`
+                      this.globalResource[item.id] = display
                       break
                     case 'node':
-                      label = item?.full_value
-                      this.globalResource[item.id] = label
+                      display = item?.full_value
+                      this.globalResource[item.id] = display
+                      break
+                    case 'label':
+                      display = `${item.name}:${item.value}`
+                      this.globalResource[item.id] = display
                       break
                     default:
-                      label = item?.name
-                      this.globalResource[item.id] = label
+                      display = item?.name
+                      this.globalResource[item.id] = display
                   }
-                  return { label: label, value: item.id }
+                  return { label: display, value: item.id }
                 }
               },
               multiple: false

From 494c4c575325a4ba7bcbeaea1e011622592ca84a Mon Sep 17 00:00:00 2001
From: Aaron3S <chenyang@fit2cloud.com>
Date: Tue, 18 Feb 2025 15:08:30 +0800
Subject: [PATCH 17/21] feat: add i18n

---
 src/components/Apps/UserConfirmDialog/index.vue | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/components/Apps/UserConfirmDialog/index.vue b/src/components/Apps/UserConfirmDialog/index.vue
index 2ac0d5777..02e57f2ae 100644
--- a/src/components/Apps/UserConfirmDialog/index.vue
+++ b/src/components/Apps/UserConfirmDialog/index.vue
@@ -99,6 +99,7 @@
             @click="handleFaceCapture"
           >
             开始人脸识别
+            {{ this.$tc('VerifyFace') }}
           </el-button>
         </el-col>
       </el-row>

From 19469508f7502daece5b418d94cdd27c754e616d Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Tue, 18 Feb 2025 15:22:33 +0800
Subject: [PATCH 18/21] Fixed: PR-BT

---
 src/views/ops/Execution/index.vue           |  2 +-
 src/views/sessions/SessionList/BaseList.vue | 10 +++++++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/views/ops/Execution/index.vue b/src/views/ops/Execution/index.vue
index 57012a8bc..dab9969fa 100644
--- a/src/views/ops/Execution/index.vue
+++ b/src/views/ops/Execution/index.vue
@@ -76,7 +76,7 @@ export default {
             }
           },
           actions: {
-            width: '120px',
+            width: '130px',
             formatterArgs: {
               hasUpdate: false,
               hasDelete: false,
diff --git a/src/views/sessions/SessionList/BaseList.vue b/src/views/sessions/SessionList/BaseList.vue
index 535076a5c..3aa26eefc 100644
--- a/src/views/sessions/SessionList/BaseList.vue
+++ b/src/views/sessions/SessionList/BaseList.vue
@@ -136,7 +136,7 @@ export default {
           actions: {
             prop: 'actions',
             label: this.$t('Actions'),
-            width: '130px',
+            width: this.dynamicActionWidth,
             formatter: ActionsFormatter,
             formatterArgs: {
               hasEdit: false,
@@ -159,6 +159,14 @@ export default {
         }
       }
     }
+  },
+  computed: {
+    dynamicActionWidth() {
+      if (this.$i18n.locale === 'pt-br') {
+        return '160px'
+      }
+      return '130px'
+    }
   }
 }
 </script>

From e6efd9141422c7a41134f602bbc241350b4e33f7 Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Tue, 18 Feb 2025 15:57:09 +0800
Subject: [PATCH 19/21] Fixed: Dashboard PRBP

---
 src/views/dashboard/Console/RankSummary.vue  | 10 ++--------
 src/views/dashboard/components/RankTable.vue | 20 ++++++++++++++++++--
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/src/views/dashboard/Console/RankSummary.vue b/src/views/dashboard/Console/RankSummary.vue
index f1f42242e..a007c562d 100644
--- a/src/views/dashboard/Console/RankSummary.vue
+++ b/src/views/dashboard/Console/RankSummary.vue
@@ -32,8 +32,7 @@ export default {
           },
           {
             prop: 'total',
-            label: this.$t('LoginCount'),
-            width: this.$i18n.locale === 'zh-CN' ? '120px' : '220px'
+            label: this.$t('LoginCount')
           }
         ]
       },
@@ -49,8 +48,7 @@ export default {
           },
           {
             prop: 'total',
-            label: this.$t('NumberOfVisits'),
-            width: this.$i18n.locale === 'zh-CN' ? '140px' : '140px'
+            label: this.$t('NumberOfVisits')
           }
         ]
       }
@@ -58,7 +56,3 @@ export default {
   }
 }
 </script>
-
-<style scoped>
-
-</style>
diff --git a/src/views/dashboard/components/RankTable.vue b/src/views/dashboard/components/RankTable.vue
index a25e4fa18..2f97e5e58 100644
--- a/src/views/dashboard/components/RankTable.vue
+++ b/src/views/dashboard/components/RankTable.vue
@@ -9,19 +9,22 @@
       class="table"
       style="width: 100%"
     >
-      <el-table-column :label="$tc('Ranking')" :width="this.$i18n.locale === 'zh-CN' ? '80px' : '110px'">
+      <el-table-column :label="$tc('Ranking')">
         <template #header>
           <el-tooltip :content="$t('Ranking')" placement="top" :open-delay="500">
             <span style="cursor: pointer;">{{ $t('Ranking') }}</span>
           </el-tooltip>
         </template>
+        <template #default="scope">
+          {{ scope.$index + 1 }}
+        </template>
       </el-table-column>
 
       <el-table-column
         v-for="i in config.columns"
         :key="i.prop"
         :prop="i.prop"
-        :width="i.width"
+        :width="getColumnWidth(i)"
       >
         <template #header>
           <el-tooltip :content="i.label" placement="top" :open-delay="500">
@@ -64,6 +67,19 @@ export default {
     this.getList()
   },
   methods: {
+    getColumnWidth(column) {
+      if (column.prop === 'total') {
+        const locale = this.$i18n.locale
+        switch (locale) {
+          case 'en':
+            return '120px'
+          case 'pt-br':
+            return '220px'
+          default:
+            return '100px'
+        }
+      }
+    },
     getList() {
       this.$axios.get(this.tableUrl).then(res => {
         this.tableData = this.config.data ? res?.[this.config.data] : res

From 9e4afd527110895b98d7562529d7b2ea2cbd18fe Mon Sep 17 00:00:00 2001
From: zhaojisen <1301338853@qq.com>
Date: Wed, 19 Feb 2025 16:34:23 +0800
Subject: [PATCH 20/21] Fixed: Fixed Tabel Export

---
 .../components/ChitChat/ChatMessage.vue       | 12 +++++++++--
 .../Table/ListTable/TableAction/RightSide.vue | 20 +++++++++----------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue b/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue
index 953676bdc..89c4d62b8 100644
--- a/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue
+++ b/src/components/Apps/ChatAi/components/ChitChat/ChatMessage.vue
@@ -15,7 +15,7 @@
             }}
           </div>
 
-          <div v-else class="thinking-time">已深度思考</div>
+          <div v-else class="thinking-time">{{ $i18n.t('DeeplyThoughtAbout') }}</div>
         </div>
         <div :class="item.reasoning ? 'reasoning' : 'message'">
           <div class="message-content">
@@ -38,6 +38,9 @@
               </div>
 
               <div class="thinking-result">
+                <span v-if="isServerError" class="error">
+                  {{ isServerError }}
+                </span>
                 <MessageText :message="item.result" />
               </div>
             </div>
@@ -118,6 +121,11 @@ export default {
         this.item.type === 'error' && this.item?.role === 'assistant'
       )
     },
+    isServerError() {
+      return (this.item.type === 'finish' && this.item.result.content === '')
+        ? this.$i18n.t('ServerBusyRetry')
+        : ''
+    },
     chatUrl() {
       return this.publicSettings.CHAT_AI_TYPE === 'gpt'
         ? require('@/assets/img/chat.png')
@@ -167,7 +175,7 @@ export default {
     .content {
       display: flex;
       flex-direction: column;
-      gap: 0.5rem;
+      // gap: 0.5rem;
       overflow: hidden;
 
       .operational {
diff --git a/src/components/Table/ListTable/TableAction/RightSide.vue b/src/components/Table/ListTable/TableAction/RightSide.vue
index bcc8e85e5..d4848ed3c 100644
--- a/src/components/Table/ListTable/TableAction/RightSide.vue
+++ b/src/components/Table/ListTable/TableAction/RightSide.vue
@@ -40,8 +40,8 @@ export default {
     handleExportClick: {
       type: Function,
       default: function({ selectedRows }) {
-        const { exportOptions, tableUrl } = this
-        const url = exportOptions?.url ? exportOptions.url : tableUrl
+        // const { exportOptions, tableUrl } = this
+        const url = this.iExportOptions.url
         this.dialogExportVisible = true
         this.$nextTick(() => {
           this.$eventBus.$emit('showExportDialog', { selectedRows, url, name: this.name })
@@ -155,20 +155,18 @@ export default {
       })
     },
     iExportOptions() {
-      if (this.$route.name === 'AssetAccountList') {
-        // 在账号列表中,第一次点击 export 时的 url 是 /accounts/account-secrets/ 都导致无法出现对话框
-        return assignIfNot(this.exportOptions, { url: this.tableUrl })
-      }
-
       /**
        *  原本是使用 assignIfNot 此函数内部使用 partialRight, 该函数
        *  只在目标对象的属性未定义时才从源对象复制属性,如果目标对象已经有值,则保留原值
-       *  那如果首次点击的树节点,那么此时 url 就会被确定,后续点击的树节点,那么 url 就不会
-       *  改变了
+       *  那如果首次点击的树节点,那么此时 url 就会被确定,后续点击的树节点,那么 url 就将不会携带节点信息
        *
-       *  主要是在资产列表中,切换节点的时候
        */
-      return Object.assign(this.exportOptions, { url: this.tableUrl })
+      // return assignIfNot(this.exportOptions, { url: this.tableUrl })
+
+      return {
+        ...this.exportOptions,
+        url: this.tableUrl
+      }
     }
   },
   methods: {

From 45532a3eb61f0738e2f403d9dcc5bcc253e26303 Mon Sep 17 00:00:00 2001
From: Aaron3S <chenyang@fit2cloud.com>
Date: Wed, 19 Feb 2025 19:06:06 +0800
Subject: [PATCH 21/21] fix: fix error i18n

---
 src/components/Apps/UserConfirmDialog/index.vue | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/components/Apps/UserConfirmDialog/index.vue b/src/components/Apps/UserConfirmDialog/index.vue
index 02e57f2ae..2116defbe 100644
--- a/src/components/Apps/UserConfirmDialog/index.vue
+++ b/src/components/Apps/UserConfirmDialog/index.vue
@@ -98,7 +98,6 @@
             type="primary"
             @click="handleFaceCapture"
           >
-            开始人脸识别
             {{ this.$tc('VerifyFace') }}
           </el-button>
         </el-col>