소스 검색

Merge branch 'master' of http://gitlab.smartai.com/zhupei/smartai2dian0

张涛 1 년 전
부모
커밋
0dec34dde4
32개의 변경된 파일733개의 추가작업 그리고 222개의 파일을 삭제
  1. 4 1
      public/i18n/lang-en.json
  2. 3 1
      public/i18n/lang-zh.json
  3. BIN
      src/assets/image/management/intellFrame1.png
  4. BIN
      src/assets/image/management/intellFrame2.png
  5. BIN
      src/assets/image/management/intellFrame3.png
  6. BIN
      src/assets/image/management/intellFrame4.png
  7. BIN
      src/assets/image/management/intellFrame5.png
  8. BIN
      src/assets/image/management/intellFrame6.png
  9. 5 1
      src/modules/conversation-board/BoardAgentItem.vue
  10. 1 52
      src/modules/conversation-board/BoardAgentList.vue
  11. 38 6
      src/modules/conversation-board/BoardTags.vue
  12. 3 3
      src/modules/conversation-board/BoardWelcome.vue
  13. 71 6
      src/modules/conversation-board/api-conversation-board.js
  14. 61 0
      src/modules/conversation-board/use-tag-list.js
  15. 38 24
      src/modules/conversation-chat/DialogList.vue
  16. 9 0
      src/modules/conversation-dialog/api-dialog.js
  17. 0 18
      src/modules/conversation-dialog/example-api-agent-sessions.json
  18. 2 2
      src/modules/conversation-history/HistoryTypeDropdown.vue
  19. 59 0
      src/modules/intelligent/CardDefault.vue
  20. 0 1
      src/modules/intelligent/ManageTags.vue
  21. 18 1
      src/modules/intelligent/MessageBody.vue
  22. 79 0
      src/modules/intelligent/ModalAddIntel.vue
  23. 0 52
      src/modules/intelligent/ModalItem.vue
  24. 119 0
      src/modules/intelligent/ModalSelectIcon.vue
  25. 79 0
      src/modules/intelligent/ModelAddItem.vue
  26. 24 2
      src/modules/intelligent/TopSetting.vue
  27. 35 0
      src/utils/use-ele-size.js
  28. 2 25
      src/views/common/Header.vue
  29. 1 1
      src/views/common/header-btns/BtnCurrentUser.vue
  30. 26 15
      src/views/conversation/ConversationBoardContainer.vue
  31. 24 11
      src/views/conversation/ConversationChatContainer.vue
  32. 32 0
      src/views/manage/common.js

+ 4 - 1
public/i18n/lang-en.json

@@ -88,6 +88,9 @@
     "history_earlier": "Earlier",
     "history_loadmore": "Load more",
     "history_nomore": "No more",
-    "history_empty": "Empty"
+    "history_empty": "Empty",
+
+    "hello": "Welcome",
+    "nice_day": "Let's spend a wonderful day together"
   }
 }

+ 3 - 1
public/i18n/lang-zh.json

@@ -88,6 +88,8 @@
     "history_earlier": "更早以前",
     "history_loadmore": "加载更多",
     "history_nomore": "没有更多了",
-    "history_empty": "暂无数据"
+    "history_empty": "暂无数据",
+    "hello": "你好",
+    "nice_day": "让我们一起度过美好的一天"
   }
 }

BIN
src/assets/image/management/intellFrame1.png


BIN
src/assets/image/management/intellFrame2.png


BIN
src/assets/image/management/intellFrame3.png


BIN
src/assets/image/management/intellFrame4.png


BIN
src/assets/image/management/intellFrame5.png


BIN
src/assets/image/management/intellFrame6.png


+ 5 - 1
src/modules/conversation-board/BoardAgentItem.vue

@@ -25,7 +25,6 @@ const handleClick = () => {
 
 <style lang="css" scoped>
 .conversation-agent-item {
-  /* background-color: #fff; */
   background-color: var(--color-bg-1);
   padding: 30px 40px 30px 40px;
   border-radius: 20px;
@@ -43,6 +42,8 @@ const handleClick = () => {
 
   margin-right: 5px;
 
+  flex-shrink: 0;
+
   cursor: pointer;
 }
 
@@ -58,5 +59,8 @@ const handleClick = () => {
 }
 
 .agent-item-intro-desc {
+  /* white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis; */
 }
 </style>

+ 1 - 52
src/modules/conversation-board/BoardAgentList.vue

@@ -4,7 +4,7 @@
       v-for="(item, index) of list"
       :key="index"
       :title="item.name"
-      :desc="item.type"
+      :desc="item.description"
       :id="item.id"
       @active="handleActive"
     />
@@ -20,57 +20,6 @@ const props = defineProps({
 
 const emit = defineEmits(['itemActive']);
 
-// const list = [
-//   {
-//     title: '智能问答',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '智能客服',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '出题组卷',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '以文生图',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '数据分析',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '报告自动生成',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '智能问答',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '文档创作',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '设备检测',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '智能客服',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '以文生图',
-//     desc: '你说一句话,我写万字长文'
-//   },
-//   {
-//     title: '出题组卷',
-//     desc: '你说一句话,我写万字长文'
-//   }
-// ];
-
 const handleActive = (target_id) => {
   emit('itemActive', target_id);
 };

+ 38 - 6
src/modules/conversation-board/BoardTags.vue

@@ -1,18 +1,45 @@
 <template>
   <div class="conversation-board-tags">
-    <div class="board-tag" @click="handleClick"><span>分类名称</span></div>
-    <div class="board-tag" @click="handleClick"><span>会话</span></div>
-    <div class="board-tag" @click="handleClick"><span>知识库管理</span></div>
-    <div class="board-tag" @click="handleClick"><span>AI会话</span></div>
+    <div
+      v-for="(item, index) of list_labels"
+      class="board-tag"
+      :class="{ 'is-active': item.labelId === current_id }"
+      :key="item.labelId"
+      @click="handleClick(item)"
+    >
+      <span>{{ item.labelName }}</span>
+    </div>
   </div>
 </template>
 
 <script setup>
+import { ref, onMounted } from 'vue';
+
+import useTagList from './use-tag-list';
+
 const emits = defineEmits(['change']);
 
-const handleClick = (type) => {
-  emits('change', type);
+const current_id = ref('');
+
+const handleClick = (item) => {
+  const target_id = item.labelId;
+
+  if (target_id === current_id.value) {
+    // 已经选中了
+    current_id.value = '';
+  } else {
+    // 没有选中
+    current_id.value = target_id;
+  }
+
+  emits('change', current_id.value);
 };
+
+const { getTagList, api_status, api_message, list_labels } = useTagList();
+
+onMounted(() => {
+  getTagList();
+});
 </script>
 
 <style lang="css" scoped>
@@ -38,4 +65,9 @@ const handleClick = (type) => {
   background-color: var(--color-bg-1);
   color: var(--color-text-1);
 }
+
+.conversation-board-tags .board-tag.is-active {
+  background-color: rgb(var(--primary-6));
+  color: #fff;
+}
 </style>

+ 3 - 3
src/modules/conversation-board/BoardWelcome.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="conversation-board-welcome">
-    <div>你好,{{ current_u_name }}</div>
-    <div>让我们一起度过美好的一天</div>
+    <div>{{ $t('conversation.hello') }},{{ current_u_name }}</div>
+    <div>{{ $t('conversation.nice_day') }}</div>
   </div>
 </template>
 
@@ -12,7 +12,7 @@ import { useCurrentUserStore } from '../../base/store/use-current-user';
 const curUserStore = useCurrentUserStore();
 
 const current_u_name = computed(() => {
-  return curUserStore.name;
+  return curUserStore.username;
 });
 </script>
 

+ 71 - 6
src/modules/conversation-board/api-conversation-board.js

@@ -1,4 +1,4 @@
-import { jsonStringify } from '../../utils/utils';
+import ajax from '../../base/ajax';
 
 const res_list_example = {
   code: 200,
@@ -69,13 +69,78 @@ const res_list_example = {
 
 /**
  * 获取所有对话可用的智能体
+ * @see https://app.apifox.com/link/project/5404857/apis/api-233232945
  */
-export const conversationBoardList = () => {
-  // http://192.168.20.119:9301/api/agent/list
+export const conversationBoardAgentList = (params) => {
+  const request_url = `/api/dialog/list`;
+
+  const send_data = {
+    status: 1,
+    current: 1,
+    pageSize: 50 // 后端默认是 10,此处需要一次性返回
+  };
+
+  if ('search' in params && params.search) {
+    send_data.keyword = params.search;
+  }
+
+  if ('label' in params && params.label) {
+    send_data.label = params.label;
+  }
+
+  return new Promise((resolve, reject) => {
+    ajax({
+      url: request_url,
+      method: 'get',
+      params: send_data
+    })
+      .then((res) => {
+        if (res.code / 1 === 200) {
+          resolve({
+            code: res.code,
+            data: res.data.rows,
+            msg: res.msg
+          });
+        } else {
+          resolve(res);
+        }
+      })
+      .catch(reject);
+  });
+};
+
+/**
+ * 获取标签列表
+ * @see https://app.apifox.com/link/project/5404857/apis/api-243257552
+ * @param {object} params
+ * @returns
+ */
+export const conversationBoardTagList = (params) => {
+  const request_url = `/api/label/list`;
+
+  const send_data = {};
+
+  if ('search' in params && params.search) {
+    send_data.keyword = params.search;
+  }
 
   return new Promise((resolve, reject) => {
-    setTimeout(() => {
-      resolve(res_list_example);
-    }, 1000);
+    ajax({
+      url: request_url,
+      method: 'get',
+      params: send_data
+    })
+      .then((res) => {
+        if (res.code / 1 === 200) {
+          resolve({
+            code: res.code,
+            data: res.data.rows,
+            msg: res.msg
+          });
+        } else {
+          resolve(res);
+        }
+      })
+      .catch(reject);
   });
 };

+ 61 - 0
src/modules/conversation-board/use-tag-list.js

@@ -0,0 +1,61 @@
+import { ref } from 'vue';
+
+import { conversationBoardTagList } from './api-conversation-board';
+
+export default function useTagList() {
+  // api请求的状态
+  const api_status = ref(1); // api状态 1 请求未启动 2 请求进心中 3 请求已成功 4 请求失败(网络成功,但是code不等于200) 5 请求出错
+  const api_message = ref(''); // 请求消息 与 api_status 对应的 message 消息内容
+
+  // 历史记录列表数据
+  const list_labels = ref([]); // 历史记录的列表数据
+
+  /**
+   * 处理请求参数
+   */
+  const formatListOptions = () => {
+    return {};
+  };
+
+  /**
+   * 调用api请求
+   */
+  const handleApiRequest = () => {
+    // 处理查询参数
+    const opts = formatListOptions();
+
+    // 进入加载状态
+    api_status.value = 2;
+    api_message.value = '';
+    conversationBoardTagList(opts)
+      .then((res) => {
+        if (res.code / 1 === 200) {
+          // 成功
+          const res_list = res.data; // 历史记录列表
+
+          list_labels.value = res_list;
+
+          // api请求成功
+          api_status.value = 3;
+          api_message.value = 'success';
+        } else {
+          // api请求成功,但是业务失败
+          api_status.value = 4;
+          api_message.value = res.msg;
+        }
+      })
+      .catch((err) => {
+        console.log(err);
+        // api请求出错
+        api_status.value = 5;
+        api_message.value = err.message;
+      });
+  };
+
+  return {
+    getTagList: handleApiRequest,
+    api_status,
+    api_message,
+    list_labels
+  };
+}

+ 38 - 24
src/modules/conversation-chat/DialogList.vue

@@ -1,32 +1,46 @@
 <template>
-  <div class="dialog-list">
-    <DialogItem />
-
-    <DialogItem />
-
-    <DialogItem />
-
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-    <DialogItem />
-  </div>
+  <a-scrollbar type="track" :style="container_style">
+    <div class="dialog-list">
+      <DialogItem />
+
+      <DialogItem />
+
+      <DialogItem />
+
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+      <DialogItem />
+    </div>
+  </a-scrollbar>
 </template>
 
 <script setup>
+import { computed } from 'vue';
 import DialogItem from './DialogItem.vue';
+
+const props = defineProps({
+  height: Number
+});
+
+const container_style = computed(() => {
+  return {
+    height: props.height + 'px',
+    overflow: 'auto'
+  };
+});
 </script>
 
 <style lang="css" scoped>

+ 9 - 0
src/modules/conversation-dialog/api-dialog.js

@@ -2,3 +2,12 @@
  * 获取会话历史记录,来自于小数系统
  * http://192.168.20.119:9301/api/agent/90d533729c0211efbf6b0242ac160006/sessions
  */
+
+/**
+ * 获取某个对话的记录 http://192.168.20.119:9301/api/agent/42e4fcdc9bea11efac300242ac160006/c0f286901bcb48b3a1fb04c5d6f1871b/session_log
+ */
+
+/**
+ * 新建会话
+ * http://192.168.20.119:9301/api/agent/get-chat-id/42e4fcdc9bea11efac300242ac160006
+ */

+ 0 - 18
src/modules/conversation-dialog/example-api-agent-sessions.json

@@ -1,18 +0,0 @@
-{
-  "code": 200,
-  "msg": "",
-  "data": [
-    {
-      "id": "a7d63ccf38fe4d3d958aa202482d54c3",
-      "updated_time": 1732857994295,
-      "update_date": "2024-11-29 13:26:34",
-      "name": "什么情况啊"
-    },
-    {
-      "id": "5b50f408cbe5449da3ec8b3bff226442",
-      "updated_time": 1732176887294,
-      "update_date": "2024-11-21 16:14:47",
-      "name": "你好"
-    }
-  ]
-}

+ 2 - 2
src/modules/conversation-history/HistoryTypeDropdown.vue

@@ -18,7 +18,7 @@
 
 <script setup>
 import { ref, computed, onMounted } from 'vue';
-import { conversationBoardList } from '../conversation-board/api-conversation-board';
+import { conversationBoardAgentList } from '../conversation-board/api-conversation-board';
 
 import { useAllAgentStore } from '../../base/store/use-all-agents';
 
@@ -90,7 +90,7 @@ const handleApiRequest = () => {
   // 进入加载状态
   api_status.value = 2;
   api_message.value = '';
-  conversationBoardList(opts)
+  conversationBoardAgentList(opts)
     .then((res) => {
       if (res.code / 1 === 200) {
         // 成功

+ 59 - 0
src/modules/intelligent/CardDefault.vue

@@ -0,0 +1,59 @@
+<template>
+  <div class="card-default">
+    <div class="header">
+      <img class="icon" :src="img_src" alt="" />
+      <div class="title">{{ name }}</div>
+    </div>
+    <div class="section">
+      <div>{{ description }}</div>
+      <div class="labels">{{ labels }}</div>
+    </div>
+    <div class="footer">
+      <slot name="footer"></slot>
+    </div>
+  </div>
+</template>
+
+<script setup>
+const props = defineProps({
+  name: {
+    type: String,
+    default: '问答助理',
+    required: true
+  },
+  img_src: {
+    type: String,
+    default: '../../assets/image/management/intelligent-frame1.png'
+  },
+  description: {
+    type: String,
+    default: 'EMBEDDING,SPEECH2TEXT,MODERATION'
+  },
+  labels: {
+    type: String,
+    default: 'LLM,TEXT'
+  }
+});
+</script>
+<style scoped lang="css">
+.card-default {
+  border: 1px solid var(--color-neutral-3);
+  padding: 20px;
+}
+.header {
+  display: flex;
+  align-items: center;
+  gap: 15px;
+}
+.header .icon {
+  width: 44px;
+}
+.header .title {
+  font-size: 16px;
+  font-weight: bold;
+}
+.section {
+  margin: 20px 0;
+  color: var(--color-neutral-6);
+}
+</style>

+ 0 - 1
src/modules/intelligent/ManageTags.vue

@@ -76,7 +76,6 @@ const handleDelete = (tag) => {
   tags.value = tags.value.filter((t) => t.name !== tag.name);
 };
 const handleCancel = () => {
-  i;
   emit('update:visible', false);
 };
 

+ 18 - 1
src/modules/intelligent/MessageBody.vue

@@ -26,9 +26,13 @@
       <template #bottom>
         <div class="bottom">
           <div class="user"><icon-user /> {{ $t('management.createUser') }}:{{ item.user }}</div>
-          <div class="tools">
+          <div class="tools" v-if="item.online">
             <icon-more :style="{ fontSize: '20px' }" />
           </div>
+          <div class="tools" v-if="!item.online">
+            <icon-settings :style="{ fontSize: '20px', cursor: 'pointer' }" @click="editIntelligent" />
+            <icon-delete :style="{ fontSize: '20px', cursor: 'pointer' }" @click="deleteIntelligent" />
+          </div>
         </div>
       </template>
     </CardItem>
@@ -104,6 +108,15 @@ const scrollHandler = (e) => {
 const openManageTags = () => {
   visible.value = true;
 };
+
+const editIntelligent = () => {
+  // TODO:微前端执行编辑页面
+  console.log('editIntelligent');
+};
+const deleteIntelligent = () => {
+  console.log('deleteIntelligent');
+};
+
 bus_intelligentSearch.on((text) => {
   search_text.value = text;
   moke_data.value = [];
@@ -156,4 +169,8 @@ onBeforeUnmount(() => {
   grid-row-start: auto;
   text-align: center;
 }
+.tools {
+  display: flex;
+  gap: 5px;
+}
 </style>

+ 79 - 0
src/modules/intelligent/ModalAddIntel.vue

@@ -0,0 +1,79 @@
+<template>
+  <a-modal
+    v-model:visible="showModal"
+    title-align="start"
+    :align-center="false"
+    :esc-to-close="false"
+    :footer="false"
+    top="15vh"
+    width="60vw"
+    @before-cancel="handleCancel"
+  >
+    <template #title>
+      <div class="model-title">新建智能体</div>
+    </template>
+    <div class="section">
+      <CardDefault
+        v-for="item in default_intelligent"
+        :key="item.name"
+        :name="item.name"
+        :description="item.description"
+        :labels="item.labels"
+      >
+        <template #footer>
+          <a-button class="add-btn" @click="addNewIntelligent(item)"> <icon-plus /> 新建 </a-button>
+        </template>
+      </CardDefault>
+    </div>
+  </a-modal>
+</template>
+
+<script setup>
+import { ref, computed } from 'vue';
+import CardDefault from './CardDefault.vue';
+import { getDefaultIntelligent } from '../../views/manage/common';
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false
+  }
+});
+const emit = defineEmits(['update:visible']);
+
+const showModal = computed(() => props.visible);
+
+const default_intelligent = getDefaultIntelligent();
+
+const handleCancel = () => {
+  emit('update:visible', false);
+};
+
+const addNewIntelligent = (item) => {
+  // TODO: 根据item中的type区分新建智能体的类型
+  emit('update:visible', false);
+  emit('add-intelligent', item);
+};
+</script>
+<style scoped lang="css">
+.model-title {
+  font-size: 16px;
+  font-weight: bold;
+}
+.section {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  justify-content: flex-start;
+  gap: 20px 20px;
+}
+.section .add-btn {
+  width: 100%;
+}
+.section .add-btn:hover {
+  background-color: rgb(var(--arcoblue-6));
+  color: var(--color-bg-1);
+}
+.arco-form-item-content-wrapper {
+  border-color: var(--color-neutral-4);
+}
+</style>

+ 0 - 52
src/modules/intelligent/ModalItem.vue

@@ -1,52 +0,0 @@
-<template>
-  <a-modal
-    v-model:visible="showModal"
-    title="添加智能体"
-    title-align="start"
-    :align-center="false"
-    top="15vh"
-    @cancel="handleCancel"
-    @before-ok="handleBeforeOk"
-  >
-    <a-form :model="form">
-      <a-form-item field="name" label="名称" validate-trigger="input" required>
-        <a-input v-model="form.name" placeholder="请输入名称" />
-      </a-form-item>
-    </a-form>
-  </a-modal>
-</template>
-
-<script setup>
-import { ref, computed } from 'vue';
-
-const props = defineProps({
-  visible: {
-    type: Boolean,
-    default: false
-  }
-});
-
-const emit = defineEmits(['update:visible']);
-
-const form = ref({
-  name: ''
-});
-const showModal = computed(() => props.visible);
-const handleBeforeOk = (done) => {
-  if (form.value.name.trim().length) {
-    // TODO:添加智能体
-    done();
-  } else {
-    return false;
-  }
-};
-const handleCancel = () => {
-  form.value.name = '';
-  emit('update:visible', false);
-};
-</script>
-<style scoped lang="css">
-.arco-form-item-content-wrapper {
-  border-color: var(--color-neutral-4);
-}
-</style>

+ 119 - 0
src/modules/intelligent/ModalSelectIcon.vue

@@ -0,0 +1,119 @@
+<template>
+  <a-modal
+    v-model:visible="showModal"
+    :align-center="false"
+    top="15vh"
+    @cancel="handleCancel"
+    @before-ok="handleBeforeOk"
+  >
+    <template #title>替换图标</template>
+    <div class="section">
+      <div class="labels">全部图标</div>
+      <div class="icons">
+        <div
+          class="icon-border"
+          v-for="icon in icons"
+          :key="icon.icon"
+          :class="{ 'icon-border-active': icon.id === target_icon }"
+          @click="changeItem(icon.id)"
+        >
+          <img class="icon" :src="icon.icon" alt="" />
+        </div>
+      </div>
+    </div>
+  </a-modal>
+</template>
+
+<script setup>
+import { ref, computed } from 'vue';
+import intellFrame1 from '../../assets/image/management/intellFrame1.png';
+import intellFrame2 from '../../assets/image/management/intellFrame2.png';
+import intellFrame3 from '../../assets/image/management/intellFrame3.png';
+import intellFrame4 from '../../assets/image/management/intellFrame4.png';
+import intellFrame5 from '../../assets/image/management/intellFrame5.png';
+import intellFrame6 from '../../assets/image/management/intellFrame6.png';
+
+const props = defineProps({
+  show_select_icon: {
+    type: Boolean,
+    default: false
+  }
+});
+const icons = ref([
+  {
+    id: 1,
+    icon: intellFrame1
+  },
+  {
+    id: 2,
+    icon: intellFrame2
+  },
+  {
+    id: 3,
+    icon: intellFrame3
+  },
+  {
+    id: 4,
+    icon: intellFrame4
+  },
+  {
+    id: 5,
+    icon: intellFrame5
+  },
+  {
+    id: 6,
+    icon: intellFrame6
+  }
+]);
+
+const target_icon = ref(icons.value[0].id);
+const emit = defineEmits(['update:show_model_item', 'sendIcon']);
+
+const showModal = computed(() => props.show_select_icon);
+
+const changeItem = (id) => {
+  target_icon.value = id;
+};
+const handleBeforeOk = (done) => {
+  emit('sendIcon', icons.value.filter((icon) => icon.id === target_icon.value)[0].icon);
+  emit('update:show_select_icon', false);
+  done();
+};
+const handleCancel = () => {
+  emit('update:show_select_icon', false);
+};
+</script>
+<style scoped lang="css">
+.section {
+  height: 200px;
+  padding: 0 20px;
+}
+.icons {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+  margin-top: 10px;
+}
+.icons .icon-border {
+  /* width: 50px;
+  height: 50px; */
+  padding: 5px 10px;
+  cursor: pointer;
+}
+.icon-border:hover {
+  border: 1px solid var(--color-neutral-4);
+  border-radius: 5px;
+}
+.icon-border .icon {
+  width: 44px;
+  height: 44px;
+}
+.icon-border-active {
+  border: 1px solid var(--color-neutral-4);
+  border-radius: 5px;
+}
+.arco-input-wrapper {
+  height: 32px;
+  background-color: var(--color-neutral-3);
+}
+</style>

+ 79 - 0
src/modules/intelligent/ModelAddItem.vue

@@ -0,0 +1,79 @@
+<template>
+  <a-modal
+    v-model:visible="showModal"
+    :align-center="false"
+    top="15vh"
+    @cancel="handleCancel"
+    @before-ok="handleBeforeOk"
+  >
+    <template #title> 新建 </template>
+    <div class="section">
+      <div class="form-item">
+        <div class="label">图标&名称</div>
+        <div class="value">
+          <img class="icon" :src="target_icon" alt="" @click="handleSelectIcon" />
+          <a-input v-model:value="form.name" placeholder="请输入名称" />
+        </div>
+      </div>
+      <div class="form-item">
+        <div class="label">描述</div>
+        <a-input v-model:value="form.description" placeholder="请输入名称" />
+      </div>
+    </div>
+  </a-modal>
+</template>
+
+<script setup>
+import { ref, computed } from 'vue';
+
+const props = defineProps({
+  show_model_item: {
+    type: Boolean,
+    default: false
+  },
+  target_icon: {
+    type: String,
+    default: '../../assets/image/management/intelligent-frame1.png'
+  }
+});
+const form = ref({
+  name: '',
+  description: ''
+});
+
+const emit = defineEmits(['update:show_model_item', 'select_icon']);
+
+const showModal = computed(() => props.show_model_item);
+const handleBeforeOk = (done) => {};
+const handleCancel = () => {
+  form.value.name = '';
+  emit('update:show_model_item', false);
+};
+const handleSelectIcon = () => {
+  emit('select_icon');
+};
+</script>
+<style scoped lang="css">
+.section {
+  padding: 0 20px;
+}
+.form-item {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+  margin-top: 20px;
+}
+.value {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+.value .icon {
+  width: 44px;
+  cursor: pointer;
+}
+.arco-input-wrapper {
+  height: 32px;
+  background-color: var(--color-neutral-3);
+}
+</style>

+ 24 - 2
src/modules/intelligent/TopSetting.vue

@@ -18,17 +18,28 @@
       {{ $t('management.createIntelligent') }}
     </a-button>
   </a-space>
-  <ModalItem v-model:visible="visible"></ModalItem>
+  <ModalAddIntel v-model:visible="visible" @add-intelligent="addIntelligent"></ModalAddIntel>
+  <ModelAddItem
+    v-model:show_model_item="show_model_item"
+    :target_icon="target_icon"
+    @select_icon="selectIcon"
+  ></ModelAddItem>
+  <ModelSelectIcon v-model:show_select_icon="show_select_icon" @sendIcon="sendIcon"></ModelSelectIcon>
 </template>
 
 <script setup>
 import { ref } from 'vue';
-import ModalItem from './ModalItem.vue';
+import ModalAddIntel from './ModalAddIntel.vue';
+import ModelAddItem from './ModelAddItem.vue';
+import ModelSelectIcon from './ModalSelectIcon.vue';
 import { funcDebounce } from '../../utils/utils';
 import { bus_intelligentSearch } from '../../base/event-bus';
 
 const searchText = ref('');
 const visible = ref(false);
+const show_model_item = ref(false);
+const show_select_icon = ref(false);
+const target_icon = ref('../../assets/image/management/intelligent-frame1.png');
 // 搜索
 const handleSearch = funcDebounce(
   () => {
@@ -41,6 +52,17 @@ const handleSearch = funcDebounce(
 const handleCreate = () => {
   visible.value = true;
 };
+
+const addIntelligent = (data) => {
+  show_model_item.value = true;
+};
+const selectIcon = () => {
+  show_select_icon.value = true;
+};
+const sendIcon = (icon) => {
+  console.log('sendIcon', icon);
+  target_icon.value = icon;
+};
 </script>
 <style scoped lang="scss"></style>
 <style>

+ 35 - 0
src/utils/use-ele-size.js

@@ -0,0 +1,35 @@
+import { ref, getCurrentInstance, onMounted, onUnmounted, computed } from 'vue';
+
+/**
+ * 获取对话区域的DOM元素尺寸
+ * @param {string} ref_name
+ * @returns
+ */
+export default function useEleSize(ref_name) {
+  const ele_height = ref(0);
+  const ele_width = ref(0);
+
+  const { proxy } = getCurrentInstance();
+
+  const getDOMElementSize = () => {
+    const ele = proxy.$refs[ref_name];
+
+    ele_height.value = ele.offsetHeight;
+    ele_width.value = ele.offsetWidth;
+  };
+
+  onMounted(() => {
+    getDOMElementSize();
+
+    window.addEventListener('resize', getDOMElementSize);
+  });
+
+  onUnmounted(() => {
+    window.removeEventListener('resize', getDOMElementSize);
+  });
+
+  return {
+    height: ele_height,
+    width: ele_width
+  };
+}

+ 2 - 25
src/views/common/Header.vue

@@ -55,28 +55,6 @@ import BtnCurrentUser from './header-btns/BtnCurrentUser.vue';
 
 const currentUser = useCurrentUserStore();
 
-/**
- * 设置系统语言
- * @param lange - 语言 zh/en
- */
-const handleLangaugeChange = (lange) => {
-  setI18nLanguage(lange);
-};
-
-/**
- * 设置系统主题
- * @param {string} theme - 主题 dark/theme
- */
-const handleThemeChange = (theme) => {
-  if (theme === 'dark') {
-    setThemeDark();
-  }
-
-  if (theme === 'light') {
-    setThemeLight();
-  }
-};
-
 /**
  * 请求网页全屏
  */
@@ -85,9 +63,8 @@ const handleFullScreen = () => {
 };
 
 const handleNameChange = () => {
-  const nm = Math.random() * 99989 + '';
-
-  currentUser.updateName(nm);
+  // const nm = Math.random() * 99989 + '';
+  // currentUser.updateName(nm);
 };
 </script>
 

+ 1 - 1
src/views/common/header-btns/BtnCurrentUser.vue

@@ -1,7 +1,7 @@
 <template>
   <a-dropdown trigger="hover" @select="handleSelect">
     <div class="header-right-profile">
-      <span>{{ currentUser.name }}</span>
+      <span>{{ currentUser.username }}</span>
     </div>
 
     <template #content>

+ 26 - 15
src/views/conversation/ConversationBoardContainer.vue

@@ -7,14 +7,15 @@
 
       <BoardTags @change="handleTagChange" />
 
-      <BoardAgentList @itemActive="handleItemActive" :list="list_agents" />
       <template v-if="api_status === 2">
         <div class="infomations-container">
           <a-spin :size="32" />
         </div>
       </template>
-      <template v-if="api_status === 3 && list_agents.length === 0">
-        <div class="infomations-container">
+      <template v-if="api_status === 3">
+        <BoardAgentList @itemActive="handleItemActive" :list="list_agents" />
+
+        <div class="infomations-container" v-if="list_agents.length === 0">
           <a-empty> {{ $t('conversation.history_empty') }} </a-empty>
         </div>
       </template>
@@ -43,11 +44,13 @@ import BoardWelcome from '../../modules/conversation-board/BoardWelcome.vue';
 import BoardTags from '../../modules/conversation-board/BoardTags.vue';
 import BoardAgentList from '../../modules/conversation-board/BoardAgentList.vue';
 
-import { conversationBoardList } from '../../modules/conversation-board/api-conversation-board';
+import { conversationBoardAgentList } from '../../modules/conversation-board/api-conversation-board';
 import { useAllAgentStore } from '../../base/store/use-all-agents';
 
 const emit = defineEmits(['agentActive']);
 
+const selected_id = ref('');
+
 // api请求的状态
 const api_status = ref(1); // api状态 1 请求未启动 2 请求进心中 3 请求已成功 4 请求失败(网络成功,但是code不等于200) 5 请求出错
 const api_message = ref(''); // 请求消息 与 api_status 对应的 message 消息内容
@@ -58,8 +61,10 @@ const list_agents = ref([]); // 历史记录的列表数据
 // store中保存的agents
 const allAgents = useAllAgentStore();
 
-const handleTagChange = (type) => {
-  console.log(type);
+const handleTagChange = (tag_id) => {
+  selected_id.value = tag_id;
+
+  handleApiRequest();
 };
 
 const handleItemActive = (target_id) => {
@@ -70,18 +75,24 @@ const handleItemActive = (target_id) => {
  * 处理请求参数
  */
 const formatListOptions = () => {
-  return {};
+  const obj = {};
+
+  if (selected_id.value) {
+    obj.label = selected_id.value;
+  }
+
+  return obj;
 };
 
 /**
  * 调用api请求
  */
 const handleApiRequest = () => {
-  const cache_agents = allAgents.agents;
-  if (cache_agents.length !== 0) {
-    list_agents.value = cache_agents;
-    return;
-  }
+  // const cache_agents = allAgents.agents;
+  // if (cache_agents.length !== 0) {
+  //   list_agents.value = cache_agents;
+  //   return;
+  // }
 
   // 处理查询参数
   const opts = formatListOptions();
@@ -89,15 +100,15 @@ const handleApiRequest = () => {
   // 进入加载状态
   api_status.value = 2;
   api_message.value = '';
-  conversationBoardList(opts)
+  conversationBoardAgentList(opts)
     .then((res) => {
       if (res.code / 1 === 200) {
         // 成功
         const res_list = res.data; // 历史记录列表
 
         list_agents.value = res_list;
-        // 在store中缓存数据
-        allAgents.setList(res_list);
+        // // 在store中缓存数据
+        // allAgents.setList(res_list);
 
         // api请求成功
         api_status.value = 3;

+ 24 - 11
src/views/conversation/ConversationChatContainer.vue

@@ -4,16 +4,16 @@
       <DialogAsideLeft />
     </div>
 
-    <div class="conversation-chat-main">
-      <DialogHeader />
+    <div class="conversation-chat-main" ref="chat_main">
+      <DialogHeader class="conversation-chat-header" :style="{ height: header_height + 'px' }" />
 
       <div class="conversation-chat-content">
-        <DialogList class="conversation-chat-list" />
+        <DialogList class="conversation-chat-list" :height="list_height" />
 
-        <DialogInput class="conversation-chat-input" />
+        <DialogInput class="conversation-chat-input" :style="{ height: input_height + 'px' }" />
       </div>
 
-      <DialogFooter />
+      <DialogFooter class="conversation-chat-footer" :style="{ height: footer_height + 'px' }" />
     </div>
 
     <div class="conversation-chat-right">
@@ -23,7 +23,7 @@
 </template>
 
 <script setup>
-import { ref, onMounted } from 'vue';
+import { ref, getCurrentInstance, onMounted, onUnmounted, computed } from 'vue';
 
 import DialogAsideLeft from '../../modules/conversation-chat/DialogAsideLeft.vue';
 import DialogHeader from '../../modules/conversation-chat/DialogHeader.vue';
@@ -32,6 +32,8 @@ import DialogInput from '../../modules/conversation-chat/DialogInput.vue';
 import DialogFooter from '../../modules/conversation-chat/DialogFooter.vue';
 import DialogAsideRight from '../../modules/conversation-chat/DialogAsideRight.vue';
 
+import useEleSize from '../../utils/use-ele-size';
+
 /**
  * 1. 历史会话进入此页面,展示历史会话内容
  * 2. 点击智能体,新建会话
@@ -44,6 +46,19 @@ const props = defineProps({
    */
   chat_id: String
 });
+
+const header_height = 30;
+const footer_height = 30;
+const input_height = 100;
+
+const { width: chat_width, height: chat_height } = useEleSize('chat_main');
+
+/**
+ * 对话列表区域的高度
+ */
+const list_height = computed(() => {
+  return chat_height.value - header_height - footer_height - input_height;
+});
 </script>
 
 <style lang="css" scoped>
@@ -66,7 +81,6 @@ const props = defineProps({
   flex-shrink: 0;
 }
 .conversation-chat-main {
-  /* width: 60%; */
   flex-grow: 1;
   height: 100%;
   margin-left: auto;
@@ -76,8 +90,6 @@ const props = defineProps({
   flex-direction: column;
 
   background-color: #aaa;
-
-  /* overflow: hidden; */
 }
 .conversation-chat-content {
   flex-grow: 1;
@@ -88,11 +100,12 @@ const props = defineProps({
   overflow: hidden;
 }
 .conversation-chat-list {
-  overflow-y: auto;
+  flex-grow: 1;
+  overflow: auto;
 }
 .conversation-chat-input {
   height: 100px;
-  background-color: #aaa;
+  background-color: #a67777;
   flex-shrink: 0;
 }
 </style>

+ 32 - 0
src/views/manage/common.js

@@ -38,3 +38,35 @@ export const getImageKnowLedge = (avatar) => {
 export const getImageIntelligent = (avatar) => {
   return image_intelligent_map[avatar] || intelligentFrame1;
 };
+
+/**
+ * @description: 默认智能体数据
+ */
+export const getDefaultIntelligent = () => {
+  return [
+    {
+      name: '问答助理',
+      description: 'EMBEDDING,SPEECH2TEXT,MODERATION',
+      labels: 'LLM,TEXT',
+      type: 'QA'
+    },
+    {
+      name: '工作流助手',
+      description: 'EMBEDDING,SPEECH2TEXT,MODERATION',
+      labels: 'LLM,TEXT',
+      type: 'ZS'
+    },
+    {
+      name: '智能Agent',
+      description: 'EMBEDDING,SPEECH2TEXT,MODERATION',
+      labels: 'LLM,TEXT',
+      type: 'AG'
+    },
+    {
+      name: '工作流应用',
+      description: 'EMBEDDING,SPEECH2TEXT,MODERATION',
+      labels: 'LLM,TEXT',
+      type: 'YY'
+    }
+  ];
+};