Bläddra i källkod

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

zhupei@smartai.com 1 år sedan
förälder
incheckning
9a934a0043

+ 11 - 0
public/i18n/lang-en.json

@@ -227,6 +227,7 @@
     "test_content": "Test Text",
     "test_btn": "Test",
     "test_result_head": "Selected Files",
+    "test_success": "Test successful",
     "test_preview": "Preview",
     "hybrid_similarity": "Hybrid Similarity",
     "keyword_similarity": "Keyword Similarity",
@@ -235,11 +236,21 @@
     "label_name": "Knowledge Base Name",
     "input_placeholder": "Please enter",
     "label_desc": "Knowledge Base Description",
+    "label_permission": "Permission",
+    "permission_tooltip": "If the permission is set to 'Team', all team members can operate the knowledge base.",
+    "permission_item_1": "Only Me",
+    "permission_item_2": "Team",
     "label_model": "Embedded Model",
     "label_parser": "Parsing Method",
     "label_layout": "Layout Recognition",
     "label_prompt_placeholder": "Please fill in the prompt",
     "save_btn": "Save",
+    "config_success": "Configuration successful",
+    "config_form_rule": {
+      "rule_1": "Knowledge base name cannot be empty",
+      "rule_2": "Please select",
+      "rule_3": "Prompt word cannot be empty"
+    },
     "config_info": {
       "h4_1": "Block Method Description",
       "h4_2": "Example",

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

@@ -65,7 +65,6 @@
     "delete": "删除",
     "online": "上线",
     "offline": "下线",
-
     "delete_success": "删除成功",
     "delete_fail": "删除失败",
     "create_success": "创建成功",
@@ -220,6 +219,7 @@
     "select_placeholder": "请选择...",
     "test_content": "测试文本",
     "test_btn": "测试",
+    "test_success": "测试成功",
     "test_result_head": "选定的文件",
     "test_preview": "预览",
     "hybrid_similarity": "混合相似度",
@@ -229,11 +229,21 @@
     "label_name": "知识库名称",
     "input_placeholder": "请输入",
     "label_desc": "知识库描述",
+    "label_permission": "权限",
+    "permission_tooltip": "如果权限是“团队”,则所有团队成员都可以操作知识库。",
+    "permission_item_1": "只有我",
+    "permission_item_2": "团队",
     "label_model": "嵌入模型",
     "label_parser": "解析方法",
     "label_layout": "布局识别",
     "label_prompt_placeholder": "请填写提示词",
     "save_btn": "保存",
+    "config_success": "配置成功",
+    "config_form_rule": {
+      "rule_1": "知识库名称不允许为空",
+      "rule_2": "请选择",
+      "rule_3": "提示词不允许为空"
+    },
     "config_info": {
       "h4_1": "分块方法说明",
       "h4_2": "示例",

+ 1 - 2
src/modules/dify/MessageBody.vue

@@ -29,8 +29,7 @@ onMounted(async () => {
         JSON.stringify({
           type: 'insertStyle',
           value: `
-            body > div > div > div.sticky.top-0.left-0.right-0.z-30 > div{display:none;}
-            body > div > div > div.style_app___hJq8.flex.overflow-hidden{margin-top: -65px;}
+            body > div > div > div.sticky.top-0.left-0.right-0.z-30{display:none;}
             .style_app___hJq8 > div:first-of-type > div:first-of-type{display:none;}
             .style_app___hJq8 > div:first-of-type > nav> a:nth-child(2){display:none;}
             .style_app___hJq8 > div:first-of-type > nav> a:nth-child(3){display:none;}

+ 1 - 1
src/modules/knowledge/MessageBody.vue

@@ -130,7 +130,7 @@ const getKnowledge = async () => {
       const data = res.data.rows.map((item) => {
         return {
           ...item,
-          time: new Date(item.create_time).toLocaleString('zh-CN'),
+          time: item.create_time,
           img_src: getImageKnowLedge(item.icon),
           count: item.documents ? item.documents : 0
         };

+ 9 - 0
src/modules/knowledge/rgflow/knowledgeLib/add.vue

@@ -44,6 +44,9 @@ import { Message } from '@arco-design/web-vue';
 import axios from 'axios';
 import { kbdocumentupload } from '../../../../apis/rgflow-dify';
 import { toSyncOwnKnowledge } from './asyc.js';
+import { useI18n } from 'vue-i18n';
+
+const { t } = useI18n();
 
 let CancelToken = axios.CancelToken;
 let source = null;
@@ -67,7 +70,13 @@ const acceptNameList = computed(() => {
   return '.word, .pdf, .ppt, .excel, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .pptx, .ppt, .pdf, .mp4, .avi, .mp3,.wav, .wma, .wmv, .rm,';
 });
 // 上传文件
+console.log(props, 11);
 const submitForm = async (done) => {
+  if (!props.kbobj.id) {
+    Message.error(t('management.no_permission'));
+    done(false);
+    return;
+  }
   if (files.value && files.value.length > 0) {
     files.value.map((item) => {
       const formData = new FormData();

+ 52 - 32
src/modules/knowledge/rgflow/knowledgeLib/config.vue

@@ -24,6 +24,17 @@
           <a-form-item field="section" :label="$t('knowledgeLib.label_desc')">
             <a-textarea placeholder="" v-model="form.description" allow-clear />
           </a-form-item>
+          <!-- 权限 -->
+          <a-form-item
+            field="permission"
+            :tooltip="$t('knowledgeLib.permission_tooltip')"
+            :label="$t('knowledgeLib.label_permission')"
+          >
+            <a-radio-group v-model="form.permission">
+              <a-radio value="me">{{ $t('knowledgeLib.permission_item_1') }}</a-radio>
+              <a-radio value="team">{{ $t('knowledgeLib.permission_item_2') }}</a-radio>
+            </a-radio-group>
+          </a-form-item>
           <!-- 嵌入模型 -->
           <a-form-item field="embd_id" :label="$t('knowledgeLib.label_model')">
             <a-select
@@ -206,15 +217,14 @@
 </template>
 
 <script setup>
-import { onMounted, onBeforeMount, reactive, ref, nextTick } from 'vue';
-import Upload from './components/Upload.vue';
+import { onMounted, onBeforeMount, reactive, ref, nextTick, computed } from 'vue';
 import { Message } from '@arco-design/web-vue';
 import { queryModelList, kbUpdate, getKnowledgeBaseModel } from '../../../../apis/rgflow-dify';
 import { toSyncOwnKnowledge } from './asyc.js';
-import message from '@arco-design/web-vue/es/message';
 import useLoading from './loading';
-import step1 from '../../../../assets/image/management/step1.png';
-import step2 from '../../../../assets/image/management/step2.png';
+import { useI18n } from 'vue-i18n';
+
+const { t } = useI18n();
 
 const { loading, setLoading } = useLoading(true);
 const scrollContainer = ref();
@@ -252,32 +262,40 @@ const form = reactive({
   layout_recognize: true
 });
 
-const rules = {
-  name: [
-    {
-      required: true,
-      message: '知识库名称不允许为空'
-    }
-  ],
-  embd_id: [
-    {
-      required: true,
-      message: '请选择'
-    }
-  ],
-  parser_id: [
-    {
-      required: true,
-      message: '请选择'
-    }
-  ],
-  prompt: [
-    {
-      required: true,
-      message: '提示词不允许为空'
-    }
-  ]
-};
+const rules = computed(() => {
+  return {
+    name: [
+      {
+        required: true,
+        message: t('knowledgeLib.config_form_rule.rule_1')
+      }
+    ],
+    embd_id: [
+      {
+        required: true,
+        message: t('knowledgeLib.config_form_rule.rule_2')
+      }
+    ],
+    permission: [
+      {
+        required: true,
+        message: t('knowledgeLib.config_form_rule.rule_2')
+      }
+    ],
+    parser_id: [
+      {
+        required: true,
+        message: t('knowledgeLib.config_form_rule.rule_2')
+      }
+    ],
+    prompt: [
+      {
+        required: true,
+        message: t('knowledgeLib.config_form_rule.rule_3')
+      }
+    ]
+  };
+});
 let visible = ref(false);
 const formRef = ref();
 const modelList = ref({});
@@ -330,11 +348,13 @@ const handleSubmit = async ({ values, errors }) => {
     setLoading(true);
     const data = await kbUpdate(parms);
     if (data.retcode == '0') {
-      Message.success('配置成功');
+      Message.success(t('knowledgeLib.config_success'));
       // window.location.reload();
       emit('saveConfig');
       //TODO 同步数据
       toSyncOwnKnowledge(kbObj.id);
+    } else {
+      Message.error(t('management.no_permission'));
     }
     setLoading(false);
   } catch (err) {

+ 12 - 4
src/modules/knowledge/rgflow/knowledgeLib/test.vue

@@ -123,6 +123,9 @@
 import { onMounted, onBeforeMount, reactive, ref, watch, computed } from 'vue';
 import { Message } from '@arco-design/web-vue';
 import { kbretrievalTest, queryModelList } from '../../../../apis/rgflow-dify';
+import { useI18n } from 'vue-i18n';
+
+const { t } = useI18n();
 
 let visible = ref(false);
 let loading = ref(false);
@@ -177,19 +180,24 @@ const handleSubmit = async ({ values, errors }) => {
     loading.value = true;
     const data = await kbretrievalTest(formObj);
     if (data.retcode == 0) {
-      Message.success('测试成功');
+      Message.success(t('knowledgeLib.test_success'));
       all_chunks.value = data.data.chunks;
       docList.value = data.data.doc_aggs;
-      checked_list.value.push(docList.value[0].doc_id);
-      chunks.value = all_chunks.value.filter((item) => item.doc_id == checked_list.value[0]);
+      if (docList.value.length) {
+        checked_list.value.push(docList.value[0].doc_id);
+      }
+      if (all_chunks.value.length) {
+        chunks.value = all_chunks.value?.filter((item) => item?.doc_id == checked_list.value[0]);
+      }
       doc_pagination_props.total = docList.value.length;
       doc_total.value = data.data.doc_aggs.length;
       chunk_total.value = data.data.chunks.length;
     } else {
-      Message.error('测试失败');
+      Message.error(data.retmsg);
     }
     loading.value = false;
   } catch (err) {
+    console.log(err);
     Message.error(err.message);
     loading.value = false;
   }

+ 51 - 6
src/views/Xiaoshu.vue

@@ -1,7 +1,7 @@
 <template>
   <!-- <LayoutExperience> -->
   <ContentContainer :containerStyle="containerStyle">
-    <template v-if="!is_mounted"></template>
+    <template v-if="!is_mounted"> </template>
 
     <WujieVue
       v-if="is_mounted"
@@ -21,7 +21,6 @@
 import { ref, onMounted } from 'vue';
 import { useRouter } from 'vue-router';
 import WujieVue from 'wujie-vue3';
-import LayoutExperience from './layout/LayoutExperience.vue';
 import ContentContainer from './layout/ContentContainer.vue';
 
 import useLogout from './account/use-logout';
@@ -209,6 +208,52 @@ onMounted(() => {
     }
   `;
 
+  // 插入的loading样式
+  const insert_loading_style_str = `
+  .xiaoshu-loading-container {
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: rgba(205, 230, 248, 0.5);
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    z-index: 9999;
+  }
+
+  .xiaoshu-loading-spinner {
+    border: 4px solid #f3f3f3;
+    border-top: 4px solid #3498db;
+    border-radius: 50%;
+    width: 40px;
+    height: 40px;
+    animation: spin 2s linear infinite;
+  }
+
+  @keyframes spin {
+    0% { transform: rotate(0deg); }
+    100% { transform: rotate(360deg); }
+  }
+`;
+
+  // 插入的脚本,用于显示和隐藏 loading 效果
+  const insert_loading_script_before_str = `
+  // 显示 loading 层
+  document.body.insertAdjacentHTML('afterbegin', '<div class="xiaoshu-loading-container"><div class="xiaoshu-loading-spinner"></div></div>');
+`;
+
+  // 插入的脚本,用于隐藏 loading 效果
+  const insert_loading_script_after_str = `
+  // 页面加载完成后,移除 loading 层
+  window.addEventListener('load', function() {
+    const loadingContainer = document.querySelector('.xiaoshu-loading-container');
+    if (loadingContainer) {
+      loadingContainer.style.display = 'none';
+    }
+  });`;
+
   /**
    * 监听子系统的事件
    */
@@ -225,14 +270,13 @@ onMounted(() => {
   bus.$on('xiaoshuAsideLogout', function () {
     logout();
   });
-
   plugins.value = [
     {
       /**
        * 在子应用所有的js之前
        * @see https://wujie-micro.github.io/doc/guide/plugin.html#js-before-loaders
        */
-      jsBeforeLoaders: [{ content: insert_script_before_str }]
+      jsBeforeLoaders: [{ content: insert_script_before_str }, { content: insert_loading_script_before_str }]
     },
 
     {
@@ -240,12 +284,13 @@ onMounted(() => {
        * 在子应用所有的js之后
        * @see https://wujie-micro.github.io/doc/guide/plugin.html#js-after-loader
        */
-      jsAfterLoaders: [{ content: insert_script_after_str }]
+      jsAfterLoaders: [{ content: insert_script_after_str }, { content: insert_loading_script_after_str }]
     },
     {
       cssAfterLoaders: [
         //在加载html所有样式之后添加一个内联样式
-        { content: insert_style_str }
+        { content: insert_style_str },
+        { content: insert_loading_style_str }
       ]
     }
   ];