Quellcode durchsuchen

Merge remote-tracking branch 'origin/master'

徐滕 vor 1 Monat
Ursprung
Commit
073a2c2ec5

+ 26 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/config/AsyncConfig.java

@@ -0,0 +1,26 @@
+package com.jeeplus.modules.knowledgeSharing.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+
+
+@Configuration
+@EnableAsync
+public class AsyncConfig implements AsyncConfigurer {
+
+    @Override
+    public Executor getAsyncExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(5);
+        executor.setMaxPoolSize(10);
+        executor.setQueueCapacity(100);
+        executor.setThreadNamePrefix("Async-");
+        executor.initialize();
+        return executor;
+    }
+}

+ 33 - 6
src/main/java/com/jeeplus/modules/knowledgeSharing/dify/DifyApiClient.java

@@ -6,6 +6,7 @@ import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBase;
 import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBaseDoc;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpDelete;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.ContentType;
@@ -144,7 +145,7 @@ public class DifyApiClient {
         }
     }
 
-    public static Boolean createByFileDifyApi(InputStream fileInputStream, String fileName, String id) throws Exception {
+    public static JSONObject createByFileDifyApi(InputStream fileInputStream, String fileName, String id) throws Exception {
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
             String url = MessageFormat.format(
                     API_URL+"/{0}/document/create-by-file",
@@ -177,11 +178,11 @@ public class DifyApiClient {
             // 执行请求
             try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                 HttpEntity responseEntity = response.getEntity();
-                EntityUtils.toString(responseEntity, "UTF-8");
+                String result = EntityUtils.toString(responseEntity, "UTF-8");
                 if (response.getStatusLine().getStatusCode() == 200) {
-                    return true;
+                    return new JSONObject(result);
                 } else {
-                    return false;
+                    return new JSONObject(result);
                 }
             }
         }
@@ -273,8 +274,11 @@ public class DifyApiClient {
         // 创建 HTTP 客户端
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
 
-            // 创建 GET 请求,动态替换 URL 中的 page 和 limit 参数
-            String url = String.format(API_URL+"?page=%d&limit=%d", pageNo, pageSize);
+            String url = String.format(API_URL + "?page=%d&limit=%d", pageNo, pageSize);
+            if (StringUtils.isNotBlank(knowledgeBase.getName())) {
+                String keyword = knowledgeBase.getName();
+                url += "&keyword=" + keyword;
+            }
             HttpGet httpGet = new HttpGet(url);
 
             // 设置请求头
@@ -302,6 +306,29 @@ public class DifyApiClient {
      * @return
      * @throws Exception
      */
+    public static Boolean deleteDocument(String datasetId, String documentId) {
+        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+            String url = String.format(API_URL + "/%s/documents/%s", datasetId, documentId);
+            HttpDelete httpDelete = new HttpDelete(url);
+            httpDelete.setHeader("Authorization", "Bearer " + API_KEY);
+            try (CloseableHttpResponse response = httpClient.execute(httpDelete)) {
+                int statusCode = response.getStatusLine().getStatusCode();
+                return statusCode == 200;
+            }
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+
+
+
+    /**
+     * 知识库文档列表
+     *
+     * @return
+     * @throws Exception
+     */
     public static JSONObject findKnowledgeBaseById(int pageNo,int pageSize, String id,String fileName) throws Exception {
         // 创建 HTTP 客户端
         try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

+ 10 - 0
src/main/java/com/jeeplus/modules/knowledgeSharing/entity/KnowledgeSharingInfo.java

@@ -35,6 +35,16 @@ public class KnowledgeSharingInfo extends DataEntity<KnowledgeSharingInfo> {
     private String viewUserId;		// 查看人员id
     private String readFlag;		// 查看结果(是否已浏览)
 
+    private String isSync; //是否同步
+
+    public String getIsSync() {
+        return isSync;
+    }
+
+    public void setIsSync(String isSync) {
+        this.isSync = isSync;
+    }
+
     public String getColumnName() {
         return columnName;
     }

+ 321 - 18
src/main/java/com/jeeplus/modules/knowledgeSharing/service/KnowledgeSharingDetailsService.java

@@ -1,24 +1,39 @@
 package com.jeeplus.modules.knowledgeSharing.service;
 
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.jeeplus.common.config.Global;
+import com.jeeplus.common.oss.OSSClientUtil;
 import com.jeeplus.common.persistence.Page;
 import com.jeeplus.common.service.CrudService;
+import com.jeeplus.common.utils.MyBeanUtils;
 import com.jeeplus.common.utils.StringUtils;
 import com.jeeplus.modules.knowledgeSharing.dao.KnowledgeSharingDetailsDao;
-import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeSharingComment;
-import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeSharingInfo;
-import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeSharingView;
+import com.jeeplus.modules.knowledgeSharing.dify.DifyApiClient;
+import com.jeeplus.modules.knowledgeSharing.entity.*;
 import com.jeeplus.modules.sys.entity.Workattachment;
 import com.jeeplus.modules.sys.service.WorkattachmentService;
 import com.jeeplus.modules.sys.utils.UserUtils;
+import com.sun.org.apache.xpath.internal.operations.Bool;
+import org.json.JSONArray;
+import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
 
 /**
  * 知识分享Service
+ *
  * @author 徐滕
  * @create 2022-4-11 9:17
  */
@@ -41,10 +56,11 @@ public class KnowledgeSharingDetailsService extends CrudService<KnowledgeSharing
 
     /**
      * 获取附件信息
+     *
      * @param knowledgeSharingInfo
      */
-    public void queryDetails(KnowledgeSharingInfo knowledgeSharingInfo) {
-        if(knowledgeSharingInfo==null)return;
+    public void queryDetails(KnowledgeSharingInfo knowledgeSharingInfo) throws Exception {
+        if (knowledgeSharingInfo == null) return;
         Workattachment attchment = new Workattachment();
         attchment.setAttachmentId(knowledgeSharingInfo.getId());
         attchment.setAttachmentFlag("183");
@@ -52,11 +68,29 @@ public class KnowledgeSharingDetailsService extends CrudService<KnowledgeSharing
         attchment.setAttachmentFlag("79");
         List<Workattachment> attachmentTwos = workattachmentService.findList(attchment);
         attachments.addAll(attachmentTwos);
+        String columnId = knowledgeSharingInfo.getColumnId();
+        String datasetId = getTypeIdByColumnId(columnId);
         knowledgeSharingInfo.setWorkAttachments(attachments);
-        for (Workattachment clientAttachment:attachments){
-            if (clientAttachment.getCollectFlag().equals("1")){
-                for (Workattachment workattachment:knowledgeSharingInfo.getWorkAttachments()){
-                    if (clientAttachment.getId().equals(workattachment.getId())){
+        for (Workattachment clientAttachment : attachments) {
+            boolean allowedFileType = isAllowedFileType(clientAttachment.getAttachmentName());
+            if(!allowedFileType){
+                clientAttachment.setSyncDifySync("2");
+                continue;
+            }
+            //判断文件是否同步至dify
+            String nameOnly = clientAttachment.getAttachmentName().substring(0, clientAttachment.getAttachmentName().lastIndexOf("."));
+            JSONObject docItem = DifyApiClient.findKnowledgeBaseById(1, 999, datasetId, nameOnly);
+            JSONArray data = docItem.getJSONArray("data");
+            List<KnowledgeBaseDoc> knowledgeBaseDocArrayList = JSON.parseArray(data.toString(), KnowledgeBaseDoc.class);
+            if (knowledgeBaseDocArrayList != null && !knowledgeBaseDocArrayList.isEmpty()) {
+                clientAttachment.setSyncDifySync("1");
+            } else {
+                clientAttachment.setSyncDifySync("0");
+            }
+
+            if (clientAttachment.getCollectFlag().equals("1")) {
+                for (Workattachment workattachment : knowledgeSharingInfo.getWorkAttachments()) {
+                    if (clientAttachment.getId().equals(workattachment.getId())) {
                         workattachment.setCollectFlag("1");
                         break;
                     }
@@ -68,7 +102,7 @@ public class KnowledgeSharingDetailsService extends CrudService<KnowledgeSharing
 
     public Page<KnowledgeSharingInfo> findPage(Page<KnowledgeSharingInfo> page, KnowledgeSharingInfo knowledgeSharingInfo) {
         //处理登记人信息
-        if (knowledgeSharingInfo!=null && StringUtils.isNotBlank(knowledgeSharingInfo.getJordanswId())){
+        if (knowledgeSharingInfo != null && StringUtils.isNotBlank(knowledgeSharingInfo.getJordanswId())) {
             knowledgeSharingInfo.setJordanswName(UserUtils.get(knowledgeSharingInfo.getJordanswId()).getName());
         }
         int count = dao.queryCount(knowledgeSharingInfo);
@@ -88,17 +122,225 @@ public class KnowledgeSharingDetailsService extends CrudService<KnowledgeSharing
         super.save(knowledgeSharingInfo);
         //保存附件
         this.saveAttachments(knowledgeSharingInfo);
+    }
+
+    /**
+     * 根据id获取dify的分类id
+     */
+    public String getTypeIdByColumnId(String columnId) throws Exception {
+        String columnName;
+        switch (columnId) {
+            case "1":
+                columnName = "学习园地";
+                break;
+            case "9":
+                columnName = "国家标准及规范";
+                break;
+            case "7":
+                columnName = "行业标准及规范";
+                break;
+            case "8":
+                columnName = "公司内部发文和通知";
+                break;
+            case "2":
+                columnName = "请教专家";
+                break;
+            case "6":
+                columnName = "案例讨论";
+                break;
+            default:
+                columnName = "学习园地";
+                break;
+        }
+
+        KnowledgeBase knowledgeBase = new KnowledgeBase();
+        knowledgeBase.setName(columnName);
+        JSONObject jsonObject = DifyApiClient.selectKnowledgeBaseList(1, 999, knowledgeBase);
+        JSONArray data = jsonObject.getJSONArray("data");
+        List<KnowledgeBase> knowledgeBaseList = JSON.parseArray(data.toString(), KnowledgeBase.class);
+        return knowledgeBaseList.isEmpty() ? null : knowledgeBaseList.get(0).getId();
+    }
 
+
+    /**
+     * 判断文件类型
+     *
+     * @param fileName
+     * @return
+     */
+    public boolean isAllowedFileType(String fileName) {
+        // 允许的后缀名
+        List<String> allowedExtensions = Arrays.asList(
+                "txt", "markdown", "mdx", "pdf", "html", "xlsx", "xls",
+                "docx", "csv", "vtt", "properties", "md", "htm"
+        );        // 获取文件后缀
+        if (fileName == null || !fileName.contains(".")) {
+            return false;
+        }
+        String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
+        return allowedExtensions.contains(extension);
+    }
+
+    /**
+     * 将附件同步至dify
+     *
+     * @param knowledgeSharingInfo1
+     */
+    @Transactional(readOnly = false)
+    @Async
+    public void saveToDify(KnowledgeSharingInfo knowledgeSharingInfo1, String saveFlag) throws Exception {
+        try {
+            KnowledgeSharingInfo knowledgeSharingInfo = new KnowledgeSharingInfo();
+            knowledgeSharingInfo.setId(knowledgeSharingInfo1.getId());
+            knowledgeSharingInfo.setColumnId(knowledgeSharingInfo1.getColumnId());
+            List<Workattachment> workattachments = knowledgeSharingInfo1.getWorkAttachments();
+            //如果没有附件,默认同步成功,无需执行同步
+            if (workattachments.isEmpty()) {
+                knowledgeSharingInfo1.setIsSync("1");
+                return;
+            }
+            //找到对应的分类名称
+            String typeId = getTypeIdByColumnId(knowledgeSharingInfo.getColumnId());
+            //处理附件,转为输入流
+            String aliyunUrl = Global.getAliyunUrl();
+            String aliDownloadUrl = Global.getAliDownloadUrl();
+            // 判断文件是否完全同步的状态
+            String allSyncStatus = "1";
+            for (Workattachment attachment : workattachments) {
+                String file = attachment.getUrl();
+                String fileName = file.substring(file.lastIndexOf("/") + 1, file.length());
+                // 文件类型不合法的话,跳过当前文件
+                if (!isAllowedFileType(fileName)) {
+                    allSyncStatus = "0";
+                    continue;
+                }
+                String cons = "";
+                byte[] fileBytes;
+                if ("1".equals(saveFlag)) {
+                    //String key = file.split(cons + "/")[1];
+                    if (file.startsWith("/")) {
+                        file = file.substring(1);  // 去掉最前面的 "/"
+                    }
+                    // 转为 byte[] 数组
+                    fileBytes = new OSSClientUtil().downBytesByStream(file, fileName);
+                } else {
+                    if (file.contains(aliyunUrl)) {
+                        cons = aliyunUrl;
+                    } else if (file.contains("http://gangwan-app.oss-cn-hangzhou.aliyuncs.com")) {
+                        cons = "http://gangwan-app.oss-cn-hangzhou.aliyuncs.com";
+                    } else {
+                        cons = aliDownloadUrl;
+                    }
+                    String key = file.split(cons + "/")[1];
+                    fileBytes = new OSSClientUtil().downBytesByStream(key, fileName);
+                }
+                try (InputStream inputStream = new ByteArrayInputStream(fileBytes)) {
+                    DifyApiClient.createByFileDifyApi(inputStream, attachment.getAttachmentName(), typeId);
+                }
+            }
+                knowledgeSharingInfo1.setIsSync(allSyncStatus);
+        } catch (Exception e) {
+            knowledgeSharingInfo1.setIsSync("0");
+        }
+        KnowledgeSharingInfo t = get(knowledgeSharingInfo1.getId());//从数据库取出记录的值
+        MyBeanUtils.copyBeanNotNull2Bean(knowledgeSharingInfo1, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+        t.setOffice(UserUtils.getSelectOffice());
+        t.setCompany(UserUtils.getSelectCompany());
+        t.setModerator("系统管理员");
+        //添加信息
+        super.save(t);
+    }
+
+    /**
+     * 将附件同步至dify
+     *
+     * @param knowledgeSharingInfo
+     */
+    @Transactional(readOnly = false)
+    @Async
+    public void updateToDify(KnowledgeSharingInfo knowledgeSharingInfo) throws Exception {
+        try {
+            KnowledgeSharingInfo knowledgeSharingInfo1 = new KnowledgeSharingInfo();
+            knowledgeSharingInfo1.setColumnId(knowledgeSharingInfo.getColumnId());
+            knowledgeSharingInfo1.setId(knowledgeSharingInfo.getId());
+            //查询附件
+            queryDetails(knowledgeSharingInfo1);
+            //删除附件重新上传
+            List<Workattachment> workattachments = knowledgeSharingInfo1.getWorkAttachments();
+            //如果没有附件,默认同步成功,无需执行同步
+            if (workattachments.isEmpty()) {
+                knowledgeSharingInfo.setIsSync("1");
+                return;
+            }
+            //找到对应的分类名称
+            String typeId = getTypeIdByColumnId(knowledgeSharingInfo.getColumnId());
+            String allSyncStatus = "1";
+            String aliyunUrl = Global.getAliyunUrl();
+            String aliDownloadUrl = Global.getAliDownloadUrl();
+            //处理附件,转为输入流
+            for (Workattachment attachment : workattachments) {
+                // 转为 byte[] 数组
+                String file = attachment.getUrl();
+                String fileName = file.substring(file.lastIndexOf("/") + 1, file.length());
+                String cons = "";
+                // 文件类型不合法的话,跳过当前文件
+                if (!isAllowedFileType(fileName)) {
+                    allSyncStatus = "0";
+                    continue;
+                }
+                if (file.contains(aliyunUrl)) {
+                    cons = aliyunUrl;
+                } else if (file.contains("http://gangwan-app.oss-cn-hangzhou.aliyuncs.com")) {
+                    cons = "http://gangwan-app.oss-cn-hangzhou.aliyuncs.com";
+                } else {
+                    cons = aliDownloadUrl;
+                }
+                String key = file.split(cons + "/")[1];
+                byte[] fileBytes = new OSSClientUtil().downBytesByStream(key, fileName);
+                try (InputStream inputStream = new ByteArrayInputStream(fileBytes)) {
+                    DifyApiClient.createByFileDifyApi(inputStream, attachment.getAttachmentName(), typeId);
+                }
+            }
+            knowledgeSharingInfo.setIsSync(allSyncStatus);
+        } catch (Exception e) {
+            knowledgeSharingInfo.setIsSync("0");
+        }
+        //更新
+        KnowledgeSharingInfo dbInfo = get(knowledgeSharingInfo.getId());
+        MyBeanUtils.copyBeanNotNull2Bean(knowledgeSharingInfo, dbInfo);
+        knowledgeSharingInfo.setOffice(UserUtils.getSelectOffice());
+        knowledgeSharingInfo.setCompany(UserUtils.getSelectCompany());
+        knowledgeSharingInfo.setModerator("系统管理员");
+        super.save(knowledgeSharingInfo);
+    }
+
+    /**
+     * 将附件同步至dify
+     *
+     * @param knowledgeSharingInfo
+     */
+    @Transactional(readOnly = false)
+    @Async
+    public void syncToDify(KnowledgeSharingInfo knowledgeSharingInfo) {
+        try {
+            //查询附件
+            queryDetails(knowledgeSharingInfo);
+            //同步
+            saveToDify(knowledgeSharingInfo, "2");
+        } catch (Exception e) {
+            throw new RuntimeException("同步失败");
+        }
     }
 
     /**
      * 添加附件信息
+     *
      * @param knowledgeSharingInfo
      */
     @Transactional(readOnly = false)
     public void saveAttachments(KnowledgeSharingInfo knowledgeSharingInfo) {
         List<Workattachment> workattachments = knowledgeSharingInfo.getWorkAttachments();
-        if (workattachments!=null && workattachments.size()!=0) {
+        if (workattachments != null && workattachments.size() != 0) {
             for (Workattachment workattachment : workattachments) {
                 if (workattachment.getId() == null) {
                     continue;
@@ -121,32 +363,89 @@ public class KnowledgeSharingDetailsService extends CrudService<KnowledgeSharing
 
     /**
      * 删除方法
+     *
      * @param knowledgeSharingInfo
      */
     @Transactional(readOnly = false)
-    public void delete (KnowledgeSharingInfo knowledgeSharingInfo){
+    public void delete(KnowledgeSharingInfo knowledgeSharingInfo) {
+        //同步删除dify的附件
+        deleteToDify(knowledgeSharingInfo);
         dao.deleteByLogic(knowledgeSharingInfo);
     }
 
     /**
+     * 同步删除dify中的附件
+     *
+     * @param knowledgeSharingInfo1
+     */
+    @Transactional(readOnly = false)
+    public void deleteToDify(KnowledgeSharingInfo knowledgeSharingInfo1) {
+        try {
+            KnowledgeSharingInfo knowledgeSharingInfo = new KnowledgeSharingInfo();
+            knowledgeSharingInfo.setId(knowledgeSharingInfo1.getId());
+            knowledgeSharingInfo.setColumnId(knowledgeSharingInfo1.getColumnId());
+            queryDetails(knowledgeSharingInfo);
+            //获取附件
+            List<Workattachment> workAttachments = knowledgeSharingInfo.getWorkAttachments();
+            if (workAttachments.isEmpty()) {
+                return;
+            }
+            //获取dify的知识库id
+            String typeIdByColumnId = getTypeIdByColumnId(knowledgeSharingInfo.getColumnId());
+            // 获取文档id
+            for (Workattachment workAttachment : workAttachments) {
+                JSONObject jsonObject = DifyApiClient.findKnowledgeBaseById(1, 999, typeIdByColumnId, workAttachment.getAttachmentName());
+                JSONArray data = jsonObject.getJSONArray("data");
+                List<KnowledgeBase> knowledgeBaseList = JSON.parseArray(data.toString(), KnowledgeBase.class);
+                if (!knowledgeBaseList.isEmpty()) {
+                    DifyApiClient.deleteDocument(typeIdByColumnId, knowledgeBaseList.get(0).getId());
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 删除单个dify中的文件
+     */
+    @Transactional(readOnly = false)
+    public void deleteToDifyByOne(String attachmentName, String columnId) {
+        try {
+            //获取dify的知识库id
+            String typeIdByColumnId = getTypeIdByColumnId(columnId);
+            JSONObject jsonObject = DifyApiClient.findKnowledgeBaseById(1, 999, typeIdByColumnId, attachmentName);
+            JSONArray data = jsonObject.getJSONArray("data");
+            List<KnowledgeBase> knowledgeBaseList = JSON.parseArray(data.toString(), KnowledgeBase.class);
+            if (!knowledgeBaseList.isEmpty()) {
+                DifyApiClient.deleteDocument(typeIdByColumnId, knowledgeBaseList.get(0).getId());
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
      * 根据知识分享id和用户id查询查看知识分享信息数据
+     *
      * @param knowledgeSharingId
      * @param userId
      * @return
      */
-    public KnowledgeSharingView getOaNotifyView(String knowledgeSharingId, String userId){
+    public KnowledgeSharingView getOaNotifyView(String knowledgeSharingId, String userId) {
         return dao.getKnowledgeSharingView(knowledgeSharingId, userId);
 
     }
 
     /**
      * 保存修改知识分享阅读数据
+     *
      * @param knowledgeSharingView
      */
     @Transactional(readOnly = false)
-    public void saveKnowledgeSharingView(KnowledgeSharingView knowledgeSharingView,String knowledgeSharingId){
+    public void saveKnowledgeSharingView(KnowledgeSharingView knowledgeSharingView, String knowledgeSharingId) {
         //判断是否为空,若为空则该知识分享没看过 则对该知识分享进行添加基本数据
-        if(null == knowledgeSharingView){
+        if (null == knowledgeSharingView) {
             KnowledgeSharingView newKnowledgeSharingView = new KnowledgeSharingView();
             newKnowledgeSharingView.setKnowledgeSharingId(knowledgeSharingId);
             newKnowledgeSharingView.setUserId(UserUtils.getUser().getId());
@@ -155,7 +454,7 @@ public class KnowledgeSharingDetailsService extends CrudService<KnowledgeSharing
             newKnowledgeSharingView.setLastVisitTime(new Date());
             newKnowledgeSharingView.preInsert();
             dao.saveKnowledgeSharingView(newKnowledgeSharingView);
-        }else{
+        } else {
             //如果已经有查看记录则修改最后一次查看记录时间并修改查看次数
             knowledgeSharingView.setLastVisitTime(new Date());
             knowledgeSharingView.preUpdate();
@@ -165,21 +464,24 @@ public class KnowledgeSharingDetailsService extends CrudService<KnowledgeSharing
 
     /**
      * 根据知识分享id查询查看知识分享记录信息
+     *
      * @param knowledgeSharingId
      * @return
      */
-    public List<KnowledgeSharingView> getKnowledgeSharingViewList(String knowledgeSharingId){
+    public List<KnowledgeSharingView> getKnowledgeSharingViewList(String knowledgeSharingId) {
         return dao.getKnowledgeSharingViewList(knowledgeSharingId);
     }
 
     /**
      * 根据知识分享id查询知识分享评论信息
+     *
      * @param knowledgeSharingId
      * @return
      */
-    public List<KnowledgeSharingComment> getKnowledgeSharingCommentList(String knowledgeSharingId){
+    public List<KnowledgeSharingComment> getKnowledgeSharingCommentList(String knowledgeSharingId) {
         return dao.getKnowledgeSharingCommentList(knowledgeSharingId);
     }
+
     /**
      * 根据知识分享id 新增评论
      */
@@ -188,6 +490,7 @@ public class KnowledgeSharingDetailsService extends CrudService<KnowledgeSharing
         knowledgeSharingComment.preInsert();
         dao.saveComment(knowledgeSharingComment);
     }
+
     /**
      * 根据评论id 删除评论
      */

+ 2 - 4
src/main/java/com/jeeplus/modules/knowledgeSharing/web/KnowledgeBaseController.java

@@ -219,10 +219,8 @@ public class KnowledgeBaseController {
                     String fileName = files[i].getOriginalFilename();
                     if (fileName != null && !fileName.isEmpty()) {
                         // 获取文件内容的输入流
-                        try {
-                            InputStream fileInputStream = files[i].getInputStream();
-                            // 直接传递给其他接口,无需存储文件
-                            Boolean flag = DifyApiClient.createByFileDifyApi(fileInputStream, fileName, id);
+                        try (InputStream fileInputStream = files[i].getInputStream()) {
+                            DifyApiClient.createByFileDifyApi(fileInputStream, fileName, id);
                             messageStr.append(fileName).append(":上传成功");
                         } catch (Exception e) {
                             messageStr.append(fileName).append(":上传失败");

+ 81 - 56
src/main/java/com/jeeplus/modules/knowledgeSharing/web/KnowledgeSharingDetailsController.java

@@ -35,6 +35,7 @@ import java.util.Map;
 
 /**
  * 知识分享-列表Controller
+ *
  * @author 徐滕
  * @create 2022-04-15 14:20
  */
@@ -49,12 +50,12 @@ public class KnowledgeSharingDetailsController extends BaseController {
     private KnowledgeSharingTypeService typeService;
 
     @ModelAttribute
-    public KnowledgeSharingInfo get(@RequestParam(required=false) String id) {
+    public KnowledgeSharingInfo get(@RequestParam(required = false) String id) {
         KnowledgeSharingInfo entity = null;
-        if (StringUtils.isNotBlank(id)){
+        if (StringUtils.isNotBlank(id)) {
             entity = service.get(id);
         }
-        if (entity == null){
+        if (entity == null) {
             entity = new KnowledgeSharingInfo();
         }
         return entity;
@@ -66,7 +67,7 @@ public class KnowledgeSharingDetailsController extends BaseController {
     @RequiresPermissions("knowledgeSharing:knowledgeSharing:list")
     @RequestMapping(value = {"list", ""})
     public String list(KnowledgeSharingInfo knowledgeSharingInfo, HttpServletRequest request, HttpServletResponse response, Model model) {
-        if(StringUtils.isBlank(knowledgeSharingInfo.getColumnId())){
+        if (StringUtils.isBlank(knowledgeSharingInfo.getColumnId())) {
             knowledgeSharingInfo.setColumnId("7");
         }
         Page<KnowledgeSharingInfo> page = service.findPage(new Page<KnowledgeSharingInfo>(request, response), knowledgeSharingInfo);
@@ -79,16 +80,17 @@ public class KnowledgeSharingDetailsController extends BaseController {
 
     /**
      * 查看,增加,编辑业务提问表单页面
+     *
      * @param knowledgeSharingInfo
      * @param model
      * @return
      */
-    @RequiresPermissions(value={"knowledgeSharing:knowledgeSharing:add","knowledgeSharing:knowledgeSharing:edit"},logical= Logical.OR)
+    @RequiresPermissions(value = {"knowledgeSharing:knowledgeSharing:add", "knowledgeSharing:knowledgeSharing:edit"}, logical = Logical.OR)
     @RequestMapping(value = "form")
-    public String form(KnowledgeSharingInfo knowledgeSharingInfo, Model model) {
-        if (knowledgeSharingInfo!=null&&StringUtils.isNotBlank(knowledgeSharingInfo.getId())) {
+    public String form(KnowledgeSharingInfo knowledgeSharingInfo, Model model) throws Exception {
+        if (knowledgeSharingInfo != null && StringUtils.isNotBlank(knowledgeSharingInfo.getId())) {
             service.queryDetails(knowledgeSharingInfo);
-        }else {
+        } else {
             knowledgeSharingInfo.setCreateBy(UserUtils.getUser());
             knowledgeSharingInfo.setCreateDate(new Date());
         }
@@ -99,46 +101,65 @@ public class KnowledgeSharingDetailsController extends BaseController {
 
     /**
      * 保存
+     *
      * @param knowledgeSharingInfo
      * @param model
      * @param redirectAttributes
      * @return
      * @throws Exception
      */
-    @RequiresPermissions(value={"knowledgeSharing:knowledgeSharing:add","knowledgeSharing:knowledgeSharing:edit"},logical=Logical.OR)
+    @RequiresPermissions(value = {"knowledgeSharing:knowledgeSharing:add", "knowledgeSharing:knowledgeSharing:edit"}, logical = Logical.OR)
     @RequestMapping(value = "save")
-    public String save(KnowledgeSharingInfo knowledgeSharingInfo, Model model, RedirectAttributes redirectAttributes) throws Exception{
-        if (!beanValidator(model, knowledgeSharingInfo)){
-            return form(knowledgeSharingInfo, model);
-        }
-
-        if(!knowledgeSharingInfo.getIsNewRecord()){//编辑表单保存
-            KnowledgeSharingInfo t = service.get(knowledgeSharingInfo.getId());//从数据库取出记录的值
-            MyBeanUtils.copyBeanNotNull2Bean(knowledgeSharingInfo, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
-            service.save(t);//保存
-        }else{//新增表单保存
-            service.save(knowledgeSharingInfo);//保存
-        }
+    public String save(KnowledgeSharingInfo knowledgeSharingInfo, Model model, RedirectAttributes redirectAttributes) throws Exception {
+            if (!beanValidator(model, knowledgeSharingInfo)) {
+                return form(knowledgeSharingInfo, model);
+            }
+            if (!knowledgeSharingInfo.getIsNewRecord()) {//编辑表单保存
+                KnowledgeSharingInfo t = service.get(knowledgeSharingInfo.getId());//从数据库取出记录的值
+                MyBeanUtils.copyBeanNotNull2Bean(knowledgeSharingInfo, t);//将编辑表单中的非NULL值覆盖数据库记录中的值
+                service.save(t);//保存
+                service.updateToDify(t);
+            } else {//新增表单保存
+                service.save(knowledgeSharingInfo);//保存
+                service.saveToDify(knowledgeSharingInfo, "1");
+            }
         addMessage(redirectAttributes, "保存成功");
-        return "redirect:"+ Global.getAdminPath()+"/knowledgeSharingDetails/knowledgeSharingDetails/?repage";
+        return "redirect:" + Global.getAdminPath() + "/knowledgeSharingDetails/knowledgeSharingDetails/?repage";
+    }
+
+    /**
+     * 按钮同步
+     *
+     * @param info
+     * @param model
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "syncToDify")
+    @ResponseBody
+    public Object syncToDify(KnowledgeSharingInfo info, Model model) {
+        // 同步到 Dify
+        service.syncToDify(info);
+        model.addAttribute("success", true);
+        return "redirect:" + Global.getAdminPath() + "/knowledgeSharingDetails/knowledgeSharingDetails/?repage";
     }
 
     /**
      * 查看页面
      */
-    @RequiresPermissions(value={"knowledgeSharing:knowledgeSharing:view"},logical=Logical.OR)
+    @RequiresPermissions(value = {"knowledgeSharing:knowledgeSharing:view"}, logical = Logical.OR)
     @RequestMapping(value = "view")
-    public String view(KnowledgeSharingInfo knowledgeSharingInfo, Model model) {
-        if (knowledgeSharingInfo!=null&&StringUtils.isNotBlank(knowledgeSharingInfo.getId())) {
+    public String view(KnowledgeSharingInfo knowledgeSharingInfo, Model model) throws Exception {
+        if (knowledgeSharingInfo != null && StringUtils.isNotBlank(knowledgeSharingInfo.getId())) {
             service.queryDetails(knowledgeSharingInfo);
-        }else {
+        } else {
             knowledgeSharingInfo.setCreateBy(UserUtils.getUser());
             knowledgeSharingInfo.setCreateDate(new Date());
         }
 
         List<MainDictDetail> billingContentList = DictUtils.getMainDictList("column_name");
-        for (MainDictDetail dictDetail: billingContentList) {
-            if(knowledgeSharingInfo.getColumnId().equals(dictDetail.getValue())){
+        for (MainDictDetail dictDetail : billingContentList) {
+            if (knowledgeSharingInfo.getColumnId().equals(dictDetail.getValue())) {
                 knowledgeSharingInfo.setColumnName(dictDetail.getLabel());
                 break;
             }
@@ -147,51 +168,53 @@ public class KnowledgeSharingDetailsController extends BaseController {
         //查看登陆者访问该知识分享信息
         KnowledgeSharingView knowledgeSharingView = service.getOaNotifyView(knowledgeSharingInfo.getId(), UserUtils.getUser().getId());
         //更新查看知识分享已看数据
-        service.saveKnowledgeSharingView(knowledgeSharingView,knowledgeSharingInfo.getId());
+        service.saveKnowledgeSharingView(knowledgeSharingView, knowledgeSharingInfo.getId());
 
         //根据知识分享id查询查看知识分享记录信息(先修改查看记录 再进行查询)
         List<KnowledgeSharingView> knowledgeSharingViewList = service.getKnowledgeSharingViewList(knowledgeSharingInfo.getId());
         //查询知识分享评论信息
         List<KnowledgeSharingComment> knowledgeSharingCommentList = service.getKnowledgeSharingCommentList(knowledgeSharingInfo.getId());
-        for (KnowledgeSharingComment info: knowledgeSharingCommentList) {
-            if(null != info.getMinuteTime()){
+        for (KnowledgeSharingComment info : knowledgeSharingCommentList) {
+            if (null != info.getMinuteTime()) {
                 //判断评论时间是否小于60分钟
-                if(info.getMinuteTime() < 60){
+                if (info.getMinuteTime() < 60) {
                     info.setCommentDateStr(info.getMinuteTime() + "分钟");
-                }else{
+                } else {
                     //计算评论时间距今过去多少小时
-                    Long hour = info.getMinuteTime()/60;
+                    Long hour = info.getMinuteTime() / 60;
                     //判断小时数是否大于24
-                    if(hour > 24){
-                        Long day = hour/24;
+                    if (hour > 24) {
+                        Long day = hour / 24;
                         info.setCommentDateStr(day + "天");
-                    }else{
+                    } else {
                         info.setCommentDateStr(hour + "小时");
                     }
                 }
-            }else{
+            } else {
                 info.setCommentDateStr("0分钟");
             }
 
             //判断是否有删除权限(只有管理员和评论人可以删除评论)
             User loginUser = UserUtils.getUser();
-            if(loginUser.isAdmin() || info.getUser().getId().equals(loginUser.getId())){
+            if (loginUser.isAdmin() || info.getUser().getId().equals(loginUser.getId())) {
                 info.setFlag(1);
-            }else{
+            } else {
                 info.setFlag(0);
             }
 
         }
-        model.addAttribute("knowledgeSharingCommentList",knowledgeSharingCommentList);
-        model.addAttribute("knowledgeSharingCommentCount",knowledgeSharingCommentList.size());
-        model.addAttribute("toReadMyNotify",true);
-        model.addAttribute("knowledgeSharingViewList", knowledgeSharingViewList);;
+        model.addAttribute("knowledgeSharingCommentList", knowledgeSharingCommentList);
+        model.addAttribute("knowledgeSharingCommentCount", knowledgeSharingCommentList.size());
+        model.addAttribute("toReadMyNotify", true);
+        model.addAttribute("knowledgeSharingViewList", knowledgeSharingViewList);
+        ;
         model.addAttribute("knowledgeSharingInfo", knowledgeSharingInfo);
         return "modules/knowledgeSharing/knowledgeSharingView";
     }
 
     /**
      * 根据知识分享id 新增评论
+     *
      * @param knowledgeSharingComment
      * @return
      */
@@ -201,11 +224,11 @@ public class KnowledgeSharingDetailsController extends BaseController {
         Map map = new HashMap();
         try {
             service.saveComment(knowledgeSharingComment);
-            map.put("success",true);
+            map.put("success", true);
         } catch (Exception e) {
-            logger.error("Exception e:"+e);
+            logger.error("Exception e:" + e);
             e.printStackTrace();
-            map.put("success",false);
+            map.put("success", false);
         }
         return map;
     }
@@ -213,25 +236,27 @@ public class KnowledgeSharingDetailsController extends BaseController {
 
     /**
      * 删除
+     *
      * @return
      * @throws Exception
      */
-    @RequiresPermissions(value={"knowledgeSharing:knowledgeSharing:del"},logical=Logical.OR)
+    @RequiresPermissions(value = {"knowledgeSharing:knowledgeSharing:del"}, logical = Logical.OR)
     @RequestMapping(value = "delete")
     @ResponseBody
-    public Object delete(KnowledgeSharingInfo knowledgeSharingInfo){
-        Map<String,Object> map = new HashMap<>();
+    public Object delete(KnowledgeSharingInfo knowledgeSharingInfo) {
+        Map<String, Object> map = new HashMap<>();
         try {
             service.delete(knowledgeSharingInfo);//保存
-            map.put("success",true);
-        }catch (Exception e){
-            map.put("success",false);
+            map.put("success", true);
+        } catch (Exception e) {
+            map.put("success", false);
         }
         return map;
     }
 
     /**
      * 根据评论id 删除评论
+     *
      * @param id
      * @return
      */
@@ -241,11 +266,11 @@ public class KnowledgeSharingDetailsController extends BaseController {
         Map map = new HashMap();
         try {
             service.deleteComment(id);
-            map.put("success",true);
+            map.put("success", true);
         } catch (Exception e) {
-            logger.error("Exception e:"+e);
+            logger.error("Exception e:" + e);
             e.printStackTrace();
-            map.put("success",false);
+            map.put("success", false);
         }
         return map;
     }

+ 11 - 0
src/main/java/com/jeeplus/modules/sys/entity/Workattachment.java

@@ -35,6 +35,17 @@ public class Workattachment extends DataEntity<Workattachment> {
 	private String sort;	//排序
 	private String description;	//文件描述
 
+	//0:未成功,1:成功
+	private String syncDifySync;	//同步至dify的状态
+
+	public String getSyncDifySync() {
+		return syncDifySync;
+	}
+
+	public void setSyncDifySync(String syncDifySync) {
+		this.syncDifySync = syncDifySync;
+	}
+
 	public String getDivIdType() {
 		return divIdType;
 	}

+ 82 - 0
src/main/java/com/jeeplus/modules/sys/web/WorkattachmentController.java

@@ -3,6 +3,7 @@
  */
 package com.jeeplus.modules.sys.web;
 
+import com.alibaba.fastjson.JSON;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.jeeplus.common.config.Global;
@@ -15,6 +16,8 @@ import com.jeeplus.common.utils.excel.ExportExcel;
 import com.jeeplus.common.utils.excel.ImportExcel;
 import com.jeeplus.common.web.BaseController;
 import com.jeeplus.modules.externalUnit.entity.ExternalUnitWorkClientAttachment;
+import com.jeeplus.modules.knowledgeSharing.dify.DifyApiClient;
+import com.jeeplus.modules.knowledgeSharing.entity.KnowledgeBase;
 import com.jeeplus.modules.projectmaterialstorage.service.ProjectMaterialStorageService;
 import com.jeeplus.modules.ruralprojectrecords.entity.RuralProjectRecords;
 import com.jeeplus.modules.ruralprojectrecords.service.RuralProjectRecordsService;
@@ -25,6 +28,8 @@ import com.jeeplus.modules.utils.SftpClientUtil;
 import com.jeeplus.modules.workreimbursement.service.WorkReimbursementService;
 import org.apache.shiro.authz.annotation.Logical;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.json.JSONArray;
+import org.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
@@ -326,6 +331,83 @@ public class WorkattachmentController extends BaseController {
 		return map;
 	}
 
+	@RequestMapping("/deleteExterFileFromAliyunByDify")
+	@ResponseBody
+	public HashMap<Object, Object> deleteExterFileFromAliyunByDify(String id,String type,String url,String fileName,String difyId,Model model){
+		try {
+		ExternalUnitWorkClientAttachment workAttachment1 = workattachmentService.getExterFile(id);
+		if(StringUtils.isNotBlank(id)) {
+			ExternalUnitWorkClientAttachment workattachment = workattachmentService.getExterFile(id);
+			if("1".equals(uploadMode) || "2".equals(uploadMode)) {
+				//workattachmentService.deleteExterFileFromAliyun(workattachment, workattachment == null ? url : workattachment.getUrl());
+				//获取dify的知识库id
+				String columnName;
+				switch (difyId) {
+					case "1":
+						columnName = "学习园地";
+						break;
+					case "9":
+						columnName = "国家标准及规范";
+						break;
+					case "7":
+						columnName = "行业标准及规范";
+						break;
+					case "8":
+						columnName = "公司内部发文和通知";
+						break;
+					case "2":
+						columnName = "请教专家";
+						break;
+					case "6":
+						columnName = "案例讨论";
+						break;
+					default:
+						columnName = "学习园地";
+						break;
+				}
+
+				KnowledgeBase knowledgeBase = new KnowledgeBase();
+				knowledgeBase.setName(columnName);
+				//获取知识库
+                JSONObject jsonObject = null;
+                 jsonObject = DifyApiClient.selectKnowledgeBaseList(1, 999, knowledgeBase);
+                JSONArray data = jsonObject.getJSONArray("data");
+				List<KnowledgeBase> knowledgeBaseList = JSON.parseArray(data.toString(), KnowledgeBase.class);
+				//根据知识库id获取文件
+				JSONObject docListJson = DifyApiClient.findKnowledgeBaseById(1, 999, knowledgeBaseList.get(0).getId(), fileName);
+				JSONArray docListData = docListJson.getJSONArray("data");
+				List<KnowledgeBase> docList = JSON.parseArray(docListData.toString(), KnowledgeBase.class);
+				if (!docList.isEmpty()) {
+					//删除文件
+					DifyApiClient.deleteDocument( knowledgeBaseList.get(0).getId(),docList.get(0).getId());
+				}
+				workattachmentService.deleteById(id);
+			}else{
+				SftpClientUtil sftpClientUtil=new SftpClientUtil();
+				try {
+					if(null != workattachment){
+						sftpClientUtil.delete(workattachment.getUrl());
+					}else{
+						sftpClientUtil.delete(url);
+					}
+
+					if(workattachment != null){
+						workattachmentService.deleteExter(workattachment);
+					}
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+			workattachmentService.deleteUserFileByFileId(id);
+		}
+		HashMap<Object, Object> map = Maps.newHashMap();
+		map.put("str","success");
+		return map;
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
 	/**
 	 *  单个删除阿里云上的文件,同时更新相关对象的附件信息
 	 *  阿里云文件地址http://gangwan-app.oss-cn-hangzhou.aliyuncs.com/attachment-file/workBidingDocument/3fcf03e37b3ba0fd5c7821998e392395.doc

+ 8 - 2
src/main/resources/mappings/modules/knowledgeSharing/KnowledgeSharingDetailsDao.xml

@@ -12,6 +12,7 @@
 		a.remarks as "remarks",
 		a.del_flag as "delFlag",
 		a.column_id as "columnId",
+		a.is_sync as "isSync",
 		a.subject as "subject",
 		a.moderator as "moderator",
 		a.contents as "contents",
@@ -91,7 +92,8 @@
 			moderator,
 			contents,
 			office_id,
-			company_id
+			company_id,
+		    is_sync
 		) VALUES (
 			#{id},
 			#{createBy.id},
@@ -106,7 +108,8 @@
 			#{moderator},
 			#{contents},
 			#{office.id},
-			#{company.id}
+			#{company.id},
+			#{isSync}
 		)
 	</insert>
 
@@ -127,6 +130,9 @@
 		<if test="contents != null and contents != ''">
 			,contents = #{contents}
 		</if>
+		<if test="isSync != null and isSync != ''">
+			,is_sync = #{isSync}
+		</if>
 		WHERE id = #{id}
 	</update>
 

+ 219 - 0
src/main/webapp/static/oss/ossupload.js

@@ -244,6 +244,83 @@ function multipartUploadWithStsOnProcessAccessory(storeAs, file,attachmentId,att
     })
 };
 
+function multipartUploadWithStsToDify(storeAs, file,attachmentId,attachmentFlag,uploadPath,divId,size, cpt,idx,prefix,currentUser) {
+
+    console.log("-----------------------start");
+    console.log("-----------------------"+realPath);
+
+    file.name.replace(" ","")
+    file.name.replace(/—/g,"")
+    var fileName = file.name;
+    // 将单引号‘’都转换成',将双引号“”都转换成"
+    fileName = fileName.replace(/\’|\‘/g,"'").replace(/\“|\”/g,"");
+    // 将中括号【】转换成[],将大括号{}转换成{}
+    fileName = fileName.replace(/\【/g,"(").replace(/\】/g,")").replace(/\{/g,"(").replace(/\}/g,")");
+    fileName = fileName.replace(/\[/g,"(").replace(/\]/g,")").replace(/\{/g,"(").replace(/\}/g,")");
+    // 将逗号,转换成,,将:转换成:
+    fileName = fileName.replace(/,/g,",").replace(/:/g,":");
+    //将中文——转换为英文-
+    fileName = fileName.replace(/—/g,"-")
+    fileName = fileName.replace(/……/g,"")
+    fileName = fileName.replace(/±/g,"")
+    fileName = fileName.replace(/#/g,"")
+    fileName = fileName.replace(/%/g,"")
+    fileName = fileName.replace(/Π/g,"")
+    fileName = fileName.replace(/π/g,"")
+    fileName = fileName.replace(/·/g,".")
+    var dfl=new File([file],fileName,{type:file.type});
+    file = dfl
+
+    requestUrl = realPath+"/previewController/getAccess";
+    OSS.urllib.request(requestUrl, {method: 'GET'}, function (err, response) {
+        if (err) {
+            console.log(err);
+            $.ajax({
+                type:"post",
+                url:realPath+"/previewController/saveJSError",
+                data:{object:err.toString()},
+                async: false,
+                success:function(data){
+                }
+            });
+            return alert(err);
+        }
+        try {
+            result = JSON.parse(response);
+        } catch (e) {
+            errmsg = 'parse sts response info error: ' + e.message;
+            return alert(errmsg);
+        }
+        console.log("---------result"+result);
+
+        // 动态设置 timeout 时间,单位为毫秒
+        let timeout;
+        if (file.size <= 10 * 1024 * 1024) { // 小于10MB
+            timeout = 10000; // 10秒
+        } else if (file.size <= 100 * 1024 * 1024) { // 小于100MB
+            timeout = 30000; // 30秒
+        } else { // 大于100MB
+            timeout = 60000; // 60秒
+        }
+
+
+        client = new OSS.Wrapper({
+            accessKeyId: result.AccessKeyId,
+            accessKeySecret: result.AccessKeySecret,
+            stsToken: result.SecurityToken,
+            bucket: result.Bucket,
+            endpoint: result.Endpoint,
+            timeout:timeout
+        });
+        storeAs = "attachment-file/" + storeAs +"/"+today+new Date().getTime()+ file.name;
+        if(cpt == 1)
+            multitestFlag(client,storeAs, file,attachmentId,attachmentFlag,uploadPath.replace('http://dmtest-test.oss-cn-shanghai.aliyuncs.com', result.AliyunUrl),divId,size, cpt,idx,prefix,currentUser);
+        else
+            multitestToDify(client, storeAs, file,attachmentId,attachmentFlag,uploadPath.replace('http://dmtest-test.oss-cn-shanghai.aliyuncs.com', result.AliyunUrl),divId,size, cpt);
+    })
+};
+
+
 
 function multipartUploadWithSts(storeAs, file,attachmentId,attachmentFlag,uploadPath,divId,size, cpt,idx,prefix,currentUser) {
 
@@ -1380,6 +1457,148 @@ function multitest (ossClient, storeAs, file,attachmentId,attachmentFlag,uploadP
         console.log(err);
     });
 };
+
+function multitestToDify (ossClient, storeAs, file,attachmentId,attachmentFlag,uploadPath,divId, size,cpt) {
+
+    // 根据文件大小动态配置 parallel
+    let parallel;
+    if (file.size < 50 * 1024 * 1024) { // 小于 50 MB
+        parallel = 1;
+    } else if (file.size < 200 * 1024 * 1024) { // 50 MB 到 200 MB
+        parallel = 3;
+    } else if (file.size < 1024 * 1024 * 1024) { // 200 MB 到 1 GB
+        parallel = 5;
+    } else { // 大于 1 GB
+        parallel = 8;
+    }
+    var names =  storeAs.split("/");
+    var name = names[names.length-1];
+    ossClient.multipartUpload(storeAs, file,{
+        partSize: 1 * 1024 * 1024,
+        parallel: parallel,
+        progress: function* (percent, cpt) {
+            var p = Math.floor(percent*100);
+            $("#jindutiao"+divId).attr("style","width: "+p+"%");
+            $("#jindutiao"+divId).attr("aria-valuenow",p+"%");
+            $("#baifenbi"+divId).html(p+"%");
+            $("#fileName"+divId).html(file.name);
+            checkpoint_temp = cpt;
+        }
+    }).then(function (result) {
+        var fileLocation = "";
+        var lookUrl = "";
+        //获取文件存储位置(0:本地;1:百度云;2:阿里云)
+        $.ajax({
+            type:"get",
+            url:realPath+"/bos/getFileStorageLocation",
+            async: false,
+            success:function(data){
+                fileLocation = data.fileLocation;
+            }
+        });
+
+        returnUrl = realPath+"/sys/workattachment/saveAttachment";
+        $.ajax({
+            type:'post',
+            url:returnUrl,
+            data:{
+                "attachmentName":file['name'],
+                "attachmentId":attachmentId,
+                "attachmentFlag":attachmentFlag,
+                "fileSize":file['size'],
+                "url":"/"+storeAs,
+                "divIdType":divId
+            },
+            success:function(data){
+                var lowerType = data.type.toLowerCase();
+                if(data.status=="Success"){
+                    parent.layer.msg("上传成功!",{icon:1});
+                    var lenght =$(".trIdAdds").length;
+                    if (size != 0){
+                        lenght += size;
+                    }
+                    var addFile = "addFile"+divId;
+                    var str = '<tr class="trIdAdds">'+
+                        '<td class="text-center">' ;
+                    if(2 == fileLocation){
+                        $.ajax({
+                            type:"post",
+                            async:false,
+                            url:realPath+"/workfullmanage/workFullManage/getFileTemporaryLookUrl",
+                            data:{"file":data.url,},
+                            success:function(result){
+                                lookUrl = result.lookUrl;
+                                if (isContains("jpg,png,gif,bmp,jpeg",lowerType)){
+                                    str = str +'<img src="'+lookUrl+'" width="50" height="50" onclick="openDialogView(\'预览\',\''+ '/a/sys/picturepreview/picturePreview?url=' +lookUrl+ '\',\'90%\',\'90%\')" alt="'+data.attachmentName+'"/>';
+                                }else if(isContains("pdf",lowerType)){
+                                    str = str + '<a class="attention-info" href="javascript:void(0)" onclick="openPreview(\''+lookUrl+'\',1)">'+data.attachmentName+'</a>';
+                                }else if(isContains("rar,zip,jar,7z",lowerType)){
+                                    str = str + '<a class="attention-info" href="javascript:void(0)" onclick="openPreview(\''+lookUrl+'\',3)">'+data.attachmentName+'</a>';
+                                }else if(isContains("avi,wmv,mpg,mpeg,mov,rm,ram,swf,flv,mp4,rmvb",lowerType)){
+                                    str = str + '<a class="attention-info" href="javascript:void(0)" onclick="openDialogView(\'预览\',\''+ '/a/sys/picturepreview/videoPreview?url=' +lookUrl+ '\',\'90%\',\'90%\')">'+data.attachmentName+'</a>';
+                                }else {
+                                    str = str + '<a class="attention-info" href="javascript:void(0)" onclick="openPreview(\''+lookUrl+'\',2)">'+data.attachmentName+'</a>';
+                                }
+                            }
+                        });
+
+                    }else{
+                        if (isContains("jpg,png,gif,bmp,jpeg",lowerType)){
+                            str = str +'<img src="'+data.url+'" width="50" height="50" onclick="openDialogView(\'预览\',\''+realPath+ '/a/sys/picturepreview/picturePreview?url=' +data.url+ '\',\'90%\',\'90%\')" alt="'+data.attachmentName+'"/>';
+                        }else if(isContains("pdf",lowerType)){
+                            str = str + '<a class="attention-info" href="javascript:void(0)" onclick="openPreview(\''+data.url+'\',1)">'+data.attachmentName+'</a>';
+                        }else if(isContains("rar,zip,jar,7z",lowerType)){
+                            str = str + '<a class="attention-info" href="javascript:void(0)" onclick="openPreview(\''+data.url+'\',3)">'+data.attachmentName+'</a>';
+                        }else if(isContains("avi,wmv,mpg,mpeg,mov,rm,ram,swf,flv,mp4,rmvb",lowerType)){
+                            str = str + '<a class="attention-info" href="javascript:void(0)" onclick="openDialogView(\'预览\',\''+ '/a/sys/picturepreview/videoPreview?url=' +lookUrl+ '\',\'90%\',\'90%\')">'+data.attachmentName+'</a>';
+                        }else {
+                            str = str + '<a class="attention-info" href="javascript:void(0)" onclick="openPreview(\''+data.url+'\',2)">'+data.attachmentName+'</a>';
+                        }
+                    }
+                    str = str +'</td>'+
+                        '<td >'+data.createByName+'</td>'+
+                        '<td >'+data.createDate+
+                        '<input name="workAttachments['+lenght+'].id" type="hidden" readonly="readonly" maxlength="20" style="width:140px;" class="form-control" value=""/>'+
+                        '<input name="workAttachments['+lenght+'].attachmentId" type="hidden" readonly="readonly" maxlength="20" style="width:140px;" class="form-control" value="'+data.attachmentId+'"/>'+
+                        '<input name="workAttachments['+lenght+'].url" type="hidden" readonly="readonly" maxlength="20" style="width:140px;" class="form-control" value="'+data.url+'"/>'+
+                        '<input name="workAttachments['+lenght+'].temporaryUrl" type="hidden" readonly="readonly" maxlength="20" style="width:140px;" class="form-control" value="'+data.temporaryUrl+'"/>'+
+                        '<input name="workAttachments['+lenght+'].attachmentName" type="hidden" readonly="readonly" maxlength="20" style="width:140px;" class="form-control" value="'+data.attachmentName+'"/>'+
+                        '<input name="workAttachments['+lenght+'].createBy.id" type="hidden" readonly="readonly" maxlength="20" style="width:140px;" class="form-control" value="'+data.createBy+'"/>'+
+                        '<input name="workAttachments['+lenght+'].type" type="hidden" readonly="readonly" maxlength="20" style="width:140px;" class="form-control" value="'+data.type+'"/>'+
+                        '<input name="workAttachments['+lenght+'].attachmentFlag" type="hidden" readonly="readonly" maxlength="20" style="width:140px;" class="form-control" value="'+data.attachmentFlag+'"/>'+
+                        '<input name="workAttachments['+lenght+'].fileSize" type="hidden" readonly="readonly" maxlength="20" style="width:140px;" class="form-control" value="'+data.fileSize+'"/>'+
+                        '<input name="workAttachments['+lenght+'].divIdType" type="hidden" readonly="readonly" maxlength="20" style="width:140px;" class="form-control" value="'+data.divIdType+'"/>'+
+                        '</td>'+
+                        '<td >'+ ' <span class=\'layui-badge layui-bg-orange\'>未同步</span>'+'</td>'+
+                        '<td class="op-td">'+
+                        '<div class="op-btn-box">';
+                    if(2 == fileLocation){
+                        if(isContains("pdf",lowerType)){
+                            str = str +'<a href="'+lookUrl+'" target="_blank" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>';
+                        }else{
+                            str = str +'<a href="'+lookUrl+'" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>';
+                        }
+                    }else{
+                        str = str +'<a href="javascript:location.href=\''+realPath+'/a/workfullmanage/workFullManage/downLoadAttach?file=\'+encodeURIComponent(\''+data.url+'\');" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>';
+                    }
+                    /*str = str + '<a href="javascript:void(0)" onclick="ossCollectingAccessory(this,\''+realPath+'/projectAccessory/projectAccessory/saveCollectAccessory?url='+data.url+'&fileName='+data.attachmentName+'\',\''+addFile+'\',\''+data.createBy+'\')" class="op-btn op-btn-delete" style="background-color: #FFB800"><i class="layui-icon layui-icon-rate"></i>&nbsp;收藏</a>'+*/
+                    str = str + '<a href="javascript:void(0)" onclick="deleteFileFromAliyun1(this,\''+realPath+'/sys/workattachment/deleteFileFromAliyun?url='+encodeURIComponent(data.url)+'&id='+data.id+'&type=2\',\''+addFile+'\',\''+divId+'\')" class="op-btn op-btn-delete" ><i class="fa fa-trash"></i>&nbsp;删除</a>'+
+                        '</div>' +
+                        '</td>'+
+                        '</tr>';
+                    $("#file"+divId).append(str);
+                }else {
+                    parent.layer.msg("上传失败!",{icon:2});
+                }
+
+                $("#flagFile").val(true);
+            }
+        })
+    }).catch(function (err) {
+        console.log("err------ err:");
+        console.log(err);
+    });
+};
 function CollectMultitest (ossClient, storeAs, file,attachmentId,attachmentFlag,uploadPath,divId, size,cpt) {
     // 根据文件大小动态配置 parallel
     let parallel;

+ 1 - 1
src/main/webapp/webpage/modules/knowledgeSharing/knowledgeBaseList.jsp

@@ -200,7 +200,7 @@
 				// {field:'tags', align:'center', width:120, title: '标签'},
 				// {field:'embeddingModelProvider', align:'center', width:80, title: '嵌入模型提供方'},
 				{field:'wordCount', align:'center', width:120, title: '字符数'},
-				{field:'updatedAt', align:'center', title: '更新时间'},
+				{field:'updatedAt', align:'center', width:180, title: '更新时间'},
 				// {field:'provider', align:'center', title: '提供方'},
 				// {field:'updatedBy', align:'center', width:80, title: '更新人'},
 				// {field:'externalKnowledgeInfo', align:'center', width:80, title: '外部知识信息'},

+ 126 - 44
src/main/webapp/webpage/modules/knowledgeSharing/knowledgeSharingDetailsForm.jsp

@@ -1,5 +1,5 @@
 <%@ page contentType="text/html;charset=UTF-8" %>
-<%@ include file="/webpage/include/taglib.jsp"%>
+<%@ include file="/webpage/include/taglib.jsp" %>
 
 <html>
 <head>
@@ -10,35 +10,38 @@
     <script type="text/javascript" src="${ctxStatic}/layui/layui.js"></script>
     <script src="${ctxStatic}/common/html/js/script.js"></script>
 
-    <link rel='stylesheet' type="text/css" href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
+    <link rel='stylesheet' type="text/css"
+          href="${ctxStatic}/helloweba_editable-select/jquery.editable-select.min.css"/>
     <link rel='stylesheet' type="text/css" href="${ctxStatic}/layui/css/layui.css"/>
 
     <script type="text/javascript">
         var validateForm;
         var isMasterClient = true;//是否是委托方
         var clientCount = 0;
-        function doSubmit(i){//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
-            if(validateForm.form()){
+
+        function doSubmit(i) {//回调函数,在编辑和保存动作时,供openDialog调用提交表单。
+            if (validateForm.form()) {
                 $("#inputForm").submit();
                 return true;
             }
 
             return false;
         }
-        $(document).ready(function() {
+
+        $(document).ready(function () {
             layui.use(['form', 'layer'], function () {
                 var form = layui.form;
 
             });
             validateForm = $("#inputForm").validate({
-                submitHandler: function(form){
+                submitHandler: function (form) {
                     loading('正在提交,请稍等...');
                     form.submit();
                 },
                 errorContainer: "#messageBox",
-                errorPlacement: function(error, element) {
+                errorPlacement: function (error, element) {
                     $("#messageBox").text("输入有误,请先更正。");
-                    if (element.is(":checkbox")||element.is(":radio")||element.parent().is(".input-append")){
+                    if (element.is(":checkbox") || element.is(":radio") || element.parent().is(".input-append")) {
                         error.appendTo(element.parent().parent());
                     } else {
                         error.insertAfter(element);
@@ -52,18 +55,22 @@
         });
 
 
-        function insertTitle(tValue){
-            var files = $("#attachment_file")[0].files;            for(var i = 0;i<files.length;i++) {                var file = files[i];
+        function insertTitle(tValue) {
+            console.log(files)
+            var files = $("#attachment_file")[0].files;
+            for (var i = 0; i < files.length; i++) {
+                var file = files[i];
                 var attachmentId = "";
                 var attachmentFlag = "183";
                 console.log(file);
-                var timestamp=new Date().getTime();
+                var timestamp = new Date().getTime();
 
                 var storeAs = "knowledgeSharingInfo";
-                var uploadPath="http://gangwan-app.oss-cn-hangzhou.aliyuncs.com/"+storeAs;/*将这段字符串存到数据库即可*/
+                var uploadPath = "http://gangwan-app.oss-cn-hangzhou.aliyuncs.com/" + storeAs;/*将这段字符串存到数据库即可*/
                 var divId = "_attachment";
-                $("#addFile"+divId).show();
-                multipartUploadWithSts(storeAs, file,attachmentId,attachmentFlag,uploadPath,divId,0);}
+                $("#addFile" + divId).show();
+                multipartUploadWithStsToDify(storeAs, file, attachmentId, attachmentFlag, uploadPath, divId, 0);
+            }
         }
 
     </script>
@@ -72,7 +79,9 @@
 <div class="single-form">
     <div class="container">
         <sys:message content="${message}"/>
-        <form:form id="inputForm" modelAttribute="knowledgeSharingInfo" action="${ctx}/knowledgeSharingDetails/knowledgeSharingDetails/save" method="post" class="form-horizontal layui-form">
+        <form:form id="inputForm" modelAttribute="knowledgeSharingInfo"
+                   action="${ctx}/knowledgeSharingDetails/knowledgeSharingDetails/save" method="post"
+                   class="form-horizontal layui-form">
             <form:hidden path="id"/>
             <form:hidden path="columnId"/>
 
@@ -82,9 +91,11 @@
                 <div class="layui-item layui-col-sm6 lw6">
                     <label class="layui-form-label"><span class="require-item">*</span>栏目名称:</label>
                     <div class="layui-input-block">
-                        <form:select path="columnId" class="form-control editable-select layui-input required" disabled="true">
+                        <form:select path="columnId" class="form-control editable-select layui-input required"
+                                     disabled="true">
                             <form:option value=""/>
-                            <form:options items="${fns:getMainDictList('column_name')}" itemLabel="label" itemValue="value" htmlEscape="false"/>
+                            <form:options items="${fns:getMainDictList('column_name')}" itemLabel="label"
+                                          itemValue="value" htmlEscape="false"/>
                         </form:select>
                     </div>
                 </div>
@@ -92,14 +103,16 @@
                 <div class="layui-item layui-col-sm6 lw6">
                     <label class="layui-form-label"><span class="require-item">*</span>主题:</label>
                     <div class="layui-input-block">
-                        <form:input path="subject" placeholder="请输入主题" htmlEscape="false"  class="form-control layui-input required"/>
+                        <form:input path="subject" placeholder="请输入主题" htmlEscape="false"
+                                    class="form-control layui-input required"/>
                     </div>
                 </div>
 
                 <div class="layui-item layui-col-sm12" style="padding-bottom: 20px;">
                     <label class="layui-form-label">问题内容:</label>
                     <div class="layui-input-block">
-                        <form:textarea path="contents" htmlEscape="false"  colspan="3" rows="6"  maxlength="550" class="form-control "/>
+                        <form:textarea path="contents" htmlEscape="false" colspan="3" rows="6" maxlength="550"
+                                       class="form-control "/>
                         <sys:ckeditor replace="contents" uploadPath="/oa/oa"/>
                     </div>
                 </div>
@@ -107,34 +120,39 @@
                     <div class="form-group-label"><h2>知识分享附件</h2></div>
                     <div class="layui-item nav-btns">
                         <a id="attachment_btn" class="nav-btn nav-btn-add" title="添加附件"><i class="fa fa-plus"></i>&nbsp;添加附件</a>
-                        <%--<sys:collectSelect  id="linkman" url="${ctx}/workclientinfo/workClientInfo/linkmanList"
-                                            name="linkman.id"  title="选择资料库"
-                                            cssClass="form-control judgment" fieldLabels="资料库" fieldKeys="name"
-                                            searchLabel="资料库" searchKey="fileName"></sys:collectSelect>--%>
+                            <%--<sys:collectSelect  id="linkman" url="${ctx}/workclientinfo/workClientInfo/linkmanList"
+                                                name="linkman.id"  title="选择资料库"
+                                                cssClass="form-control judgment" fieldLabels="资料库" fieldKeys="name"
+                                                searchLabel="资料库" searchKey="fileName"></sys:collectSelect>--%>
                     </div>
                     <div id="addFile_attachment" style="display: none" class="upload-progress">
-                        <span id="fileName_attachment" ></span>
-                        <b><span id="baifenbi_attachment" ></span></b>
+                        <span id="fileName_attachment"></span>
+                        <b><span id="baifenbi_attachment"></span></b>
                         <div class="progress">
                             <div id="jindutiao_attachment" class="progress-bar" style="width: 0%" aria-valuenow="0">
                             </div>
                         </div>
                     </div>
-                    <input id="attachment_file" type="file" name="attachment_file" multiple="multiple" style="display: none;" onChange="if(this.value)insertTitle(this.value);"/>
+                    <input id="attachment_file" type="file" name="attachment_file" multiple="multiple"
+                           style="display: none;" onChange="if(this.value)insertTitle(this.value);"/>
                     <span id="attachment_title"></span>
                     <div class="layui-item layui-col-xs12" style="padding:0 16px;">
                         <table id="listAttachment" class="table table-bordered table-condensed details">
                             <thead>
                             <tr>
-                                    <%-- <th>序号</th>--%>
+                                <!-- <th>序号</th> -->
                                 <th>文件预览</th>
                                 <th>上传人</th>
                                 <th>上传时间</th>
+                                <c:if test="${not empty knowledgeSharingInfo.id}">
+                                    <th>同步状态</th>
+                                </c:if>
                                 <th width="200px">操作</th>
                             </tr>
                             </thead>
                             <tbody id="file_attachment">
-                            <c:forEach items="${knowledgeSharingInfo.workAttachments}" var = "workClientAttachment" varStatus="status">
+                            <c:forEach items="${knowledgeSharingInfo.workAttachments}" var="workClientAttachment"
+                                       varStatus="status">
                                 <tr>
 
                                         <%-- <td>${status.index + 1}</td>--%>
@@ -151,7 +169,9 @@
                                                 <c:otherwise>
                                                     <c:choose>
                                                         <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
-                                                            <td><a class="attention-info" href="javascript:void(0)" onclick="openPreview('${workClientAttachment.temporaryUrl}',1)">${workClientAttachment.attachmentName}</a></td>
+                                                            <td><a class="attention-info" href="javascript:void(0)"
+                                                                   onclick="openPreview('${workClientAttachment.temporaryUrl}',1)">${workClientAttachment.attachmentName}</a>
+                                                            </td>
                                                         </c:when>
                                                         <c:otherwise>
                                                             <c:choose>
@@ -159,10 +179,16 @@
                                                        or fn:containsIgnoreCase(workClientAttachment.attachmentName,'zip')
                                                        or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jar')
                                                        or fn:containsIgnoreCase(workClientAttachment.attachmentName,'7z')}">
-                                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="openPreview('${workClientAttachment.temporaryUrl}',3)">${workClientAttachment.attachmentName}</a></td>
+                                                                    <td><a class="attention-info"
+                                                                           href="javascript:void(0)"
+                                                                           onclick="openPreview('${workClientAttachment.temporaryUrl}',3)">${workClientAttachment.attachmentName}</a>
+                                                                    </td>
                                                                 </c:when>
                                                                 <c:otherwise>
-                                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="openPreview('${workClientAttachment.temporaryUrl}',2)">${workClientAttachment.attachmentName}</a></td>
+                                                                    <td><a class="attention-info"
+                                                                           href="javascript:void(0)"
+                                                                           onclick="openPreview('${workClientAttachment.temporaryUrl}',2)">${workClientAttachment.attachmentName}</a>
+                                                                    </td>
                                                                 </c:otherwise>
                                                             </c:choose>
                                                         </c:otherwise>
@@ -182,7 +208,9 @@
                                                 <c:otherwise>
                                                     <c:choose>
                                                         <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
-                                                            <td><a class="attention-info" href="javascript:void(0)" onclick="openPreview('${workClientAttachment.url}',1)">${workClientAttachment.attachmentName}</a></td>
+                                                            <td><a class="attention-info" href="javascript:void(0)"
+                                                                   onclick="openPreview('${workClientAttachment.url}',1)">${workClientAttachment.attachmentName}</a>
+                                                            </td>
                                                         </c:when>
                                                         <c:otherwise>
                                                             <c:choose>
@@ -198,7 +226,10 @@
                                                                         <c:otherwise>
                                                                             <c:choose>
                                                                                 <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
-                                                                                    <td><a class="attention-info" href="javascript:void(0)" onclick="openPreview('${workClientAttachment.temporaryUrl}',1)">${workClientAttachment.attachmentName}</a></td>
+                                                                                    <td><a class="attention-info"
+                                                                                           href="javascript:void(0)"
+                                                                                           onclick="openPreview('${workClientAttachment.temporaryUrl}',1)">${workClientAttachment.attachmentName}</a>
+                                                                                    </td>
                                                                                 </c:when>
                                                                                 <c:otherwise>
                                                                                     <c:choose>
@@ -206,10 +237,18 @@
                                                        or fn:containsIgnoreCase(workClientAttachment.attachmentName,'zip')
                                                        or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jar')
                                                        or fn:containsIgnoreCase(workClientAttachment.attachmentName,'7z')}">
-                                                                                            <td><a class="attention-info" href="javascript:void(0)" onclick="openPreview('${workClientAttachment.temporaryUrl}',3)">${workClientAttachment.attachmentName}</a></td>
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.temporaryUrl}',3)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
                                                                                         </c:when>
                                                                                         <c:otherwise>
-                                                                                            <td><a class="attention-info" href="javascript:void(0)" onclick="openPreview('${workClientAttachment.temporaryUrl}',2)">${workClientAttachment.attachmentName}</a></td>
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.temporaryUrl}',2)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
                                                                                         </c:otherwise>
                                                                                     </c:choose>
                                                                                 </c:otherwise>
@@ -229,7 +268,9 @@
                                                                         <c:otherwise>
                                                                             <c:choose>
                                                                                 <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
-                                                                                    <td><a href="javascript:void(0)" onclick="openPreview('${workClientAttachment.url}',1)">${workClientAttachment.attachmentName}</a></td>
+                                                                                    <td><a href="javascript:void(0)"
+                                                                                           onclick="openPreview('${workClientAttachment.url}',1)">${workClientAttachment.attachmentName}</a>
+                                                                                    </td>
                                                                                 </c:when>
                                                                                 <c:otherwise>
                                                                                     <c:choose>
@@ -237,10 +278,18 @@
                                                        or fn:containsIgnoreCase(workClientAttachment.attachmentName,'zip')
                                                        or fn:containsIgnoreCase(workClientAttachment.attachmentName,'jar')
                                                        or fn:containsIgnoreCase(workClientAttachment.attachmentName,'7z')}">
-                                                                                            <td><a class="attention-info" href="javascript:void(0)" onclick="openPreview('${workClientAttachment.url}',3)">${workClientAttachment.attachmentName}</a></td>
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.url}',3)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
                                                                                         </c:when>
                                                                                         <c:otherwise>
-                                                                                            <td><a class="attention-info" href="javascript:void(0)" onclick="openPreview('${workClientAttachment.url}',2)">${workClientAttachment.attachmentName}</a></td>
+                                                                                            <td>
+                                                                                                <a class="attention-info"
+                                                                                                   href="javascript:void(0)"
+                                                                                                   onclick="openPreview('${workClientAttachment.url}',2)">${workClientAttachment.attachmentName}</a>
+                                                                                            </td>
                                                                                         </c:otherwise>
                                                                                     </c:choose>
                                                                                 </c:otherwise>
@@ -258,29 +307,62 @@
 
                                     <td>${workClientAttachment.createBy.name}</td>
                                     <td><fmt:formatDate value="${workClientAttachment.createDate}" type="both"/></td>
+                                    <c:if test="${not empty knowledgeSharingInfo.id}">
+                                        <td>
+                                            <c:choose>
+                                                <c:when test="${not empty workClientAttachment.syncDifySync}">
+                                                    <c:choose>
+                                                        <c:when test="${workClientAttachment.syncDifySync == '1'}">
+                                                            <span class='layui-badge layui-bg-green'>已同步</span>
+                                                        </c:when>
+                                                        <c:when test="${workClientAttachment.syncDifySync == '2'}">
+                                                            <span class='layui-badge'>无法同步</span>
+                                                        </c:when>
+                                                        <c:otherwise>
+                                                            <span class='layui-badge layui-bg-orange'>未同步</span>
+                                                        </c:otherwise>
+                                                    </c:choose>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <span class='layui-badge'>未同步</span>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </td>
+                                    </c:if>
                                     <td class="op-td">
-                                        <div class="op-btn-box" >
+                                        <div class="op-btn-box">
                                                 <%--附件下载删除--%>
                                             <c:choose>
                                                 <c:when test="${knowledgeSharingInfo.uploadMode == 2}">
                                                     <c:choose>
                                                         <c:when test="${fn:containsIgnoreCase(workClientAttachment.attachmentName,'pdf')}">
-                                                            <a href="${workClientAttachment.temporaryUrl}" target="_blank" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                            <a href="${workClientAttachment.temporaryUrl}"
+                                                               target="_blank" class="op-btn op-btn-download"><i
+                                                                    class="fa fa-download"></i>&nbsp;下载</a>
                                                         </c:when>
                                                         <c:otherwise>
-                                                            <a href="${workClientAttachment.temporaryUrl}" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                            <a href="${workClientAttachment.temporaryUrl}"
+                                                               class="op-btn op-btn-download"><i
+                                                                    class="fa fa-download"></i>&nbsp;下载</a>
                                                         </c:otherwise>
                                                     </c:choose>
                                                 </c:when>
                                                 <c:otherwise>
-                                                    <a href="javascript:location.href='${ctx}/workfullmanage/workFullManage/downLoadAttach?file='+encodeURIComponent('${workClientAttachment.url}');" class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
+                                                    <a href="javascript:location.href='${ctx}/workfullmanage/workFullManage/downLoadAttach?file='+encodeURIComponent('${workClientAttachment.url}');"
+                                                       class="op-btn op-btn-download"><i class="fa fa-download"></i>&nbsp;下载</a>
                                                 </c:otherwise>
                                             </c:choose>
                                             <c:if test="${workClientAttachment.collectFlag != 1}">
-                                                <a href="javascript:void(0)" onclick="collectingAccessory(this,'${ctx}/projectAccessory/projectAccessory/saveCollectAccessory','${workClientAttachment.url}','${workClientAttachment.createBy.id}','${workClientAttachment.fileSize}')" class="op-btn op-btn-delete" style="background-color: #FFB800"><i class="layui-icon layui-icon-rate"></i>&nbsp;收藏</a>
+                                                <a href="javascript:void(0)"
+                                                   onclick="collectingAccessory(this,'${ctx}/projectAccessory/projectAccessory/saveCollectAccessory','${workClientAttachment.url}','${workClientAttachment.createBy.id}','${workClientAttachment.fileSize}')"
+                                                   class="op-btn op-btn-delete" style="background-color: #FFB800"><i
+                                                        class="layui-icon layui-icon-rate"></i>&nbsp;收藏</a>
                                             </c:if>
                                             <c:if test="${workClientAttachment.createBy.id eq fns:getUser().id}">
-                                                <a href="javascript:void(0)" onclick="deleteFileFromAliyun(this,'${ctx}/sys/workattachment/deleteFileFromAliyun?url=${workClientAttachment.url}&id=${workClientAttachment.id}&type=2','addFile_attachment','_attachment')" class="op-btn op-btn-delete" ><i class="fa fa-trash"></i>&nbsp;删除</a>
+                                                <a href="javascript:void(0)"
+                                                   onclick="deleteFileFromAliyun(this,'${ctx}/sys/workattachment/deleteExterFileFromAliyunByDify?url=${workClientAttachment.url}&id=${workClientAttachment.id}&type=2&fileName=${workClientAttachment.attachmentName}&difyId=${knowledgeSharingInfo.columnId}','addFile_attachment','_attachment')"
+                                                   class="op-btn op-btn-delete"><i
+                                                        class="fa fa-trash"></i>&nbsp;删除</a>
                                             </c:if>
 
                                         </div>

+ 32 - 5
src/main/webapp/webpage/modules/knowledgeSharing/knowledgeSharingDetailsList.jsp

@@ -91,7 +91,7 @@
 			});
 		}
 
-		function deleteInfo(title,id) {
+		function deleteInfo(title,id,columnId) {
 
 			layer.open({
 				title: title,
@@ -102,7 +102,7 @@
 				btn1: function(index, layero){
 					$.ajax({
 						type:"post",
-						url:"${ctx}/knowledgeSharingDetails/knowledgeSharingDetails/delete?id="+ id,
+						url:"${ctx}/knowledgeSharingDetails/knowledgeSharingDetails/delete?id="+ id+"&columnId="+columnId,
 						success:function(data){
 							if(data.success) {
 								parent.layer.msg('删除成功', {icon: 1});
@@ -119,6 +119,29 @@
 			});
 		}
 
+		// 同步附件至dify
+		function syncToDify(title,id) {
+
+			layer.open({
+				title: title,
+				maxmin: true, //开启最大化最小化按钮
+				content: '确认同步附件信息?',
+				skin: 'two-btns',
+				btn: ['确定', '取消'],
+				btn1: function(index, layero){
+					$.ajax({
+						type:"post",
+						url:"${ctx}/knowledgeSharingDetails/knowledgeSharingDetails/syncToDify?id="+ id,
+					})
+					parent.layer.msg('同步中,请稍后', {icon: 1});
+					layer.close(index);
+					document.getElementById("refreshBtn").click();
+				},
+				btn2: function (index) {
+				}
+			});
+		}
+
 
 		//打开对话框(查看)
 		function openDialogListView(title,url,width,height){
@@ -220,7 +243,7 @@
 						<shiro:hasPermission name="knowledgeSharing:knowledgeSharing:add">
 							<table:addRow label="新发帖" url="${ctx}/knowledgeSharingDetails/knowledgeSharingDetails/form?columnId=${columnId}" title="新发帖" height="95%;" width="95%;"></table:addRow><!-- 增加按钮 -->
 						</shiro:hasPermission>
-						<button class="layui-btn layui-btn-sm" data-toggle="tooltip" data-placement="left" onclick="sortOrRefresh()" title="刷新"> 刷新</button>
+						<button id="refreshBtn"  class="layui-btn layui-btn-sm" data-toggle="tooltip" data-placement="left" onclick="sortOrRefresh()" title="刷新"> 刷新</button>
 					</div>
 				</div>
 				<table class="oa-table layui-table" id="contentTable"></table>
@@ -253,14 +276,16 @@
 				,{field:'createDate',align:'center', title: '发帖时间', width:150}
 				,{field:'readCount',align:'center', title: '阅读数', width:100}
 				,{field:'replyCount', align:'center',title: '回复数', width:100}
+				,{field:'isSyncText', align:'center',title: '是否同步到知识库', width:130}
 				,{align:'center',title:"操作",width:150,templet:function(d){
 						////对操作进行初始化
 						var xml = "<div class=\"layui-btn-group\">";
+						if(  d.isAdmin == "1" && d.isSync == "0")
+							xml += "<a href=\"javascript:void(0)\" onclick=\"syncToDify('同步',  '"+d.id+"')\"   class=\"layui-btn layui-btn-xs layui-bg-blue\"> 同步</a>";
 						if(d.canedit != undefined && d.canedit == "1")
 							xml += "<a href=\"javascript:void(0)\" onclick=\"openDialog('修改发帖信息', '${ctx}/knowledgeSharingDetails/knowledgeSharingDetails/form?id="+ d.id +"','95%', '95%')\"   class=\"layui-btn layui-btn-xs  layui-bg-green\"> 编辑</a>";
-
 						if((d.candelete != undefined && d.candelete == "1") || d.isAdmin == "1")
-							xml += "<a href=\"javascript:void(0)\" onclick=\"deleteInfo('删除',  '"+d.id+"')\"   class=\"layui-btn layui-btn-xs layui-bg-red\"> 删除</a>";
+							xml += "<a href=\"javascript:void(0)\" onclick=\"deleteInfo('删除',  '"+d.id+"',  '"+d.columnId+"')\"   class=\"layui-btn layui-btn-xs layui-bg-red\"> 删除</a>";
 							/*xml += "<a href=\"${ctx}/knowledgeSharingDetails/knowledgeSharingDetails/delete?id="+ d.id +"\" onclick=\"return confirmx('确认要删除该帖子吗?', this.href)\"   class=\"layui-btn layui-btn-xs layui-bg-red\"> 删除</a>";*/
 						xml+="</div>"
 						return xml;
@@ -283,6 +308,8 @@
 					,"lastPublish":"${knowledgeSharingInfo.lastPublish}"
 					,"readCount":"${knowledgeSharingInfo.readCount}"
 					,"replyCount":"${knowledgeSharingInfo.replyCount}"
+                    ,"isSync": "${knowledgeSharingInfo.isSync}"
+                    ,"isSyncText": "${knowledgeSharingInfo.isSync == '1' ? '<span class=\'layui-badge layui-bg-green\'>已同步</span>' : '<span class=\'layui-badge\'>未同步</span>'}"
 					,"isAdmin":"${knowledgeSharingInfo.isAdmin}"
 					<shiro:hasPermission name="knowledgeSharing:knowledgeSharing:edit">,"canedit":<c:choose><c:when test="${fns:getUser().id == knowledgeSharingInfo.createBy.id}">"1"</c:when><c:otherwise>"0"</c:otherwise></c:choose></shiro:hasPermission>
 					<shiro:hasPermission name="knowledgeSharing:knowledgeSharing:del">,"candelete":<c:choose><c:when test="${fns:getUser().id == knowledgeSharingInfo.createBy.id}">"1"</c:when><c:otherwise>"0"</c:otherwise></c:choose></shiro:hasPermission>

+ 23 - 2
src/main/webapp/webpage/modules/knowledgeSharing/knowledgeSharingView.jsp

@@ -95,7 +95,8 @@
                                 <%-- <th>序号</th>--%>
                             <th>文件预览</th>
                             <th>上传人</th>
-                            <th>上传时间</th>
+                                    <th>上传时间</th>
+                                    <th>同步状态</th>
                             <th width="150px">操作</th>
                         </tr>
                         </thead>
@@ -210,7 +211,27 @@
 
                                 <td>${workClientAttachment.createBy.name}</td>
                                 <td><fmt:formatDate value="${workClientAttachment.createDate}" type="both"/></td>
-                                <td class="op-td">
+                                        <td>
+                                            <c:choose>
+                                                <c:when test="${not empty workClientAttachment.syncDifySync}">
+                                                    <c:choose>
+                                                        <c:when test="${workClientAttachment.syncDifySync == '1'}">
+                                                            <span class='layui-badge layui-bg-green'>已同步</span>
+                                                        </c:when>
+                                                        <c:when test="${workClientAttachment.syncDifySync == '2'}">
+                                                            <span class='layui-badge '>无法同步</span>
+                                                        </c:when>
+                                                        <c:otherwise>
+                                                            <span class='layui-badge  layui-bg-orange'>未同步</span>
+                                                        </c:otherwise>
+                                                    </c:choose>
+                                                </c:when>
+                                                <c:otherwise>
+                                                    <span class='layui-badge'>未同步</span>
+                                                </c:otherwise>
+                                            </c:choose>
+                                        </td>
+                                        <td class="op-td">
                                     <div class="op-btn-box">
                                             <%--附件下载删除--%>
                                         <c:choose>