Просмотр исходного кода

新增
1、增加dify工作流到数据库的映射
2、增加dify工作流增删改查接口
3、增加dify工作流通用调用接口
4、餐厅创建增加AI建议接口

liangwenxuan 2 месяцев назад
Родитель
Сommit
ea31dad99d
10 измененных файлов с 410 добавлено и 1 удалено
  1. 70 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dify/DifyWorkFlowRecordController.java
  2. 21 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dify/vo/DifyWorkFlowRecordPageReqVO.java
  3. 28 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dify/vo/DifyWorkFlowRecordRespVO.java
  4. 32 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dify/vo/DifyWorkFlowRecordSaveReqVO.java
  5. 19 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dify/vo/DifyWorkFlowRunReqVO.java
  6. 12 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/restaurant/RestaurantManagementController.java
  7. 52 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dify/DifyWorkFlowRecordDO.java
  8. 20 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dify/DifyWorkFlowRecordMapper.java
  9. 23 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dify/DifyWorkFlowRecordService.java
  10. 133 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dify/DifyWorkFlowRecordServiceImpl.java

+ 70 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dify/DifyWorkFlowRecordController.java

@@ -0,0 +1,70 @@
+package cn.iocoder.yudao.module.system.controller.admin.dify;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRecordPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRecordRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRecordSaveReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRunReqVO;
+import cn.iocoder.yudao.module.system.service.dify.DifyWorkFlowRecordService;
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - Dify 工作流记录")
+@RestController
+@RequestMapping("/dify-work-flow-record")
+@Validated
+public class DifyWorkFlowRecordController {
+
+    @Resource
+    private DifyWorkFlowRecordService difyWorkFlowRecordService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建 Dify 工作流记录")
+    public CommonResult<Long> create(@Valid @RequestBody DifyWorkFlowRecordSaveReqVO createReqVO) {
+        return success(difyWorkFlowRecordService.create(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新 Dify 工作流记录")
+    public CommonResult<Boolean> update(@Valid @RequestBody DifyWorkFlowRecordSaveReqVO updateReqVO) {
+        difyWorkFlowRecordService.update(updateReqVO);
+        return success(Boolean.TRUE);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除 Dify 工作流记录")
+    @Parameter(name = "id", description = "编号", required = true)
+    public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
+        difyWorkFlowRecordService.delete(id);
+        return success(Boolean.TRUE);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得 Dify 工作流记录")
+    @Parameter(name = "id", description = "编号", required = true, example = "1")
+    public CommonResult<DifyWorkFlowRecordRespVO> get(@RequestParam("id") Long id) {
+        return success(difyWorkFlowRecordService.get(id));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得 Dify 工作流记录分页")
+    public CommonResult<PageResult<DifyWorkFlowRecordRespVO>> getPage(@Valid DifyWorkFlowRecordPageReqVO pageReqVO) {
+        return success(difyWorkFlowRecordService.getPage(pageReqVO));
+    }
+
+    @PostMapping("/workflow-run")
+    @Operation(summary = "执行 Dify 工作流")
+    public CommonResult<JSONObject> workflowRun(@Valid @RequestBody DifyWorkFlowRunReqVO reqVO) {
+        return success(difyWorkFlowRecordService.workflowRun(reqVO));
+    }
+}

+ 21 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dify/vo/DifyWorkFlowRecordPageReqVO.java

@@ -0,0 +1,21 @@
+package cn.iocoder.yudao.module.system.controller.admin.dify.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+@Schema(description = "管理后台 - Dify 工作流记录分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class DifyWorkFlowRecordPageReqVO extends PageParam {
+
+    @Schema(description = "编号")
+    private String number;
+
+    @Schema(description = "名称")
+    private String name;
+}
+

+ 28 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dify/vo/DifyWorkFlowRecordRespVO.java

@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.system.controller.admin.dify.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - Dify 工作流记录 Response VO")
+@Data
+public class DifyWorkFlowRecordRespVO {
+
+    @Schema(description = "id", example = "1")
+    private Long id;
+
+    @Schema(description = "编号")
+    private String number;
+
+    @Schema(description = "名称")
+    private String name;
+
+    @Schema(description = "完整url")
+    private String apiUrl;
+
+    @Schema(description = "apikey")
+    private String apiKey;
+
+    @Schema(description = "描述")
+    private String description;
+}
+

+ 32 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dify/vo/DifyWorkFlowRecordSaveReqVO.java

@@ -0,0 +1,32 @@
+package cn.iocoder.yudao.module.system.controller.admin.dify.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Schema(description = "管理后台 - Dify 工作流记录新增/修改 Request VO")
+@Data
+public class DifyWorkFlowRecordSaveReqVO {
+
+    @Schema(description = "id", example = "1")
+    private Long id;
+
+    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "编号不能为空")
+    private String number;
+
+    @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "名称不能为空")
+    private String name;
+
+    @Schema(description = "完整url")
+    private String apiUrl;
+
+    @Schema(description = "apikey")
+    private String apiKey;
+
+    @Schema(description = "描述")
+    private String description;
+}
+

+ 19 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dify/vo/DifyWorkFlowRunReqVO.java

@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.module.system.controller.admin.dify.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Schema(description = "管理后台 - Dify 工作流运行 Request VO")
+@Data
+public class DifyWorkFlowRunReqVO {
+
+    @Schema(description = "租户id", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "tenantId 不能为空")
+    private Long tenantId;
+
+    @Schema(description = "工作流编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "workNumber 不能为空")
+    private String workNumber;
+}

+ 12 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/restaurant/RestaurantManagementController.java

@@ -3,10 +3,14 @@ package cn.iocoder.yudao.module.system.controller.admin.restaurant;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRunReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.restaurant.RestaurantManagementDO;
+import cn.iocoder.yudao.module.system.service.dify.DifyWorkFlowRecordService;
 import cn.iocoder.yudao.module.system.service.restaurant.RestaurantManagementService;
+import com.alibaba.fastjson.JSONObject;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
@@ -30,6 +34,8 @@ public class RestaurantManagementController {
     @Resource
     private RestaurantManagementService restaurantManagementService;
 
+    @Autowired
+    private DifyWorkFlowRecordService difyWorkFlowRecordService;
 
     @PostMapping("/create")
     @Operation(summary = "创建餐厅")
@@ -85,5 +91,10 @@ public class RestaurantManagementController {
 //        ExcelUtils.write(response, "餐厅管理.xls", "数据", RestaurantManagementRespVO.class,
 //                        BeanUtils.toBean(list, RestaurantManagementRespVO.class));
 //    }
-
+        @GetMapping("/getAiSuggest")
+        @Operation(summary = "获取ai建议")
+        @TenantIgnore
+        public CommonResult<JSONObject> getAiSuggest(@RequestParam(value = "tenantId",required = false) Long tenantId) {
+            return success(difyWorkFlowRecordService.workflowRun(new DifyWorkFlowRunReqVO().setTenantId(tenantId).setWorkNumber("restaurantManagementGetAiSuggest")));
+        }
 }

+ 52 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dify/DifyWorkFlowRecordDO.java

@@ -0,0 +1,52 @@
+package cn.iocoder.yudao.module.system.dal.dataobject.dify;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Dify 工作流记录 DO
+ */
+@TableName("dify_work_flow_record")
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class DifyWorkFlowRecordDO {
+
+    /**
+     * id
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 编号
+     */
+    private String number;
+
+    /**
+     * 名称
+     */
+    private String name;
+
+    /**
+     * 完整 url
+     */
+    private String apiUrl;
+
+    /**
+     * api key
+     */
+    private String apiKey;
+
+    /**
+     * 描述
+     */
+    private String description;
+}
+

+ 20 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dify/DifyWorkFlowRecordMapper.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.system.dal.mysql.dify;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRecordPageReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.dify.DifyWorkFlowRecordDO;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface DifyWorkFlowRecordMapper extends BaseMapperX<DifyWorkFlowRecordDO> {
+
+    default PageResult<DifyWorkFlowRecordDO> selectPage(DifyWorkFlowRecordPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<DifyWorkFlowRecordDO>()
+                .likeIfPresent(DifyWorkFlowRecordDO::getNumber, reqVO.getNumber())
+                .likeIfPresent(DifyWorkFlowRecordDO::getName, reqVO.getName())
+                .orderByDesc(DifyWorkFlowRecordDO::getId));
+    }
+}
+

+ 23 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dify/DifyWorkFlowRecordService.java

@@ -0,0 +1,23 @@
+package cn.iocoder.yudao.module.system.service.dify;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRecordPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRecordRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRecordSaveReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRunReqVO;
+import com.alibaba.fastjson.JSONObject;
+
+public interface DifyWorkFlowRecordService {
+
+    Long create(DifyWorkFlowRecordSaveReqVO createReqVO);
+
+    void update(DifyWorkFlowRecordSaveReqVO updateReqVO);
+
+    void delete(Long id);
+
+    DifyWorkFlowRecordRespVO get(Long id);
+
+    PageResult<DifyWorkFlowRecordRespVO> getPage(DifyWorkFlowRecordPageReqVO pageReqVO);
+
+    JSONObject workflowRun(DifyWorkFlowRunReqVO reqVO);
+}

+ 133 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/dify/DifyWorkFlowRecordServiceImpl.java

@@ -0,0 +1,133 @@
+package cn.iocoder.yudao.module.system.service.dify;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRecordPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRecordRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRecordSaveReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.dify.vo.DifyWorkFlowRunReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.dify.DifyWorkFlowRecordDO;
+import cn.iocoder.yudao.module.system.dal.mysql.dify.DifyWorkFlowRecordMapper;
+import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.client.RestTemplate;
+
+import javax.annotation.Resource;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exceptionCustomMsg;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.COMMON_ERROR;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.COMMON_NOT_FOUND;
+
+@Service
+@Validated
+@Slf4j
+public class DifyWorkFlowRecordServiceImpl implements DifyWorkFlowRecordService {
+
+    private static final String API_URL = "https://api.dify.ai/v1/workflows/run";
+
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+    @Resource
+    private DifyWorkFlowRecordMapper difyWorkFlowRecordMapper;
+
+    @Resource
+    private RestTemplate restTemplate;
+
+    @Autowired
+    private TenantMapper tenantMapper;
+    @Override
+    public Long create(DifyWorkFlowRecordSaveReqVO createReqVO) {
+        DifyWorkFlowRecordDO workFlowRecord = BeanUtils.toBean(createReqVO, DifyWorkFlowRecordDO.class);
+        difyWorkFlowRecordMapper.insert(workFlowRecord);
+        return workFlowRecord.getId();
+    }
+
+    @Override
+    public void update(DifyWorkFlowRecordSaveReqVO updateReqVO) {
+        validateExists(updateReqVO.getId());
+        DifyWorkFlowRecordDO updateObj = BeanUtils.toBean(updateReqVO, DifyWorkFlowRecordDO.class);
+        difyWorkFlowRecordMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void delete(Long id) {
+        validateExists(id);
+        difyWorkFlowRecordMapper.deleteById(id);
+    }
+
+    @Override
+    public DifyWorkFlowRecordRespVO get(Long id) {
+        DifyWorkFlowRecordDO workFlowRecord = difyWorkFlowRecordMapper.selectById(id);
+        if (workFlowRecord == null) {
+            return null;
+        }
+        return BeanUtils.toBean(workFlowRecord, DifyWorkFlowRecordRespVO.class);
+    }
+
+    @Override
+    public PageResult<DifyWorkFlowRecordRespVO> getPage(DifyWorkFlowRecordPageReqVO pageReqVO) {
+        PageResult<DifyWorkFlowRecordDO> pageResult = difyWorkFlowRecordMapper.selectPage(pageReqVO);
+        return BeanUtils.toBean(pageResult, DifyWorkFlowRecordRespVO.class);
+    }
+
+    @Override
+    public JSONObject workflowRun(DifyWorkFlowRunReqVO reqVO) {
+        try {
+            DifyWorkFlowRecordDO difyWorkFlowRecordDO = difyWorkFlowRecordMapper.selectOne(new LambdaQueryWrapperX<DifyWorkFlowRecordDO>()
+                    .eq(DifyWorkFlowRecordDO::getNumber, reqVO.getWorkNumber()));
+            if(difyWorkFlowRecordDO == null){
+                throw exceptionCustomMsg(COMMON_ERROR, "调用 Dify 工作流失败,不存在该工作流编号" + reqVO.getWorkNumber());
+            }
+            ObjectNode root = OBJECT_MAPPER.createObjectNode();
+            ObjectNode inputs = OBJECT_MAPPER.createObjectNode();
+            inputs.put("tenantName", getTenantName(reqVO.getTenantId()));
+            root.set("inputs", inputs);
+            root.put("response_mode", "blocking");
+            root.put("user", SecurityFrameworkUtils.getLoginUserNickname());
+            String requestBody = OBJECT_MAPPER.writeValueAsString(root);
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            headers.setAccept(java.util.Collections.singletonList(MediaType.APPLICATION_JSON));
+            headers.set("Authorization", "Bearer " + difyWorkFlowRecordDO.getApiKey());
+
+            HttpEntity<String> entity = new HttpEntity<>(requestBody, headers);
+            ResponseEntity<String> response = restTemplate.postForEntity(API_URL, entity, String.class);
+            String responseBody = response.getBody();
+            log.info("workflowRun status={}, response={}", response.getStatusCodeValue(), responseBody);
+
+            if (!response.getStatusCode().is2xxSuccessful() || responseBody == null) {
+                throw exceptionCustomMsg(COMMON_ERROR, "调用 Dify 工作流失败");
+            }
+
+            JsonNode data = OBJECT_MAPPER.readTree(responseBody);
+            return JSONObject.parseObject(data.path("data").path("outputs").path("text").asText());
+        } catch (Exception e) {
+            log.error("workflowRun 调用异常", e);
+            throw exceptionCustomMsg(COMMON_ERROR, "调用 Dify 工作流异常: " + e.getMessage());
+        }
+    }
+
+    private void validateExists(Long id) {
+        if (id == null || difyWorkFlowRecordMapper.selectById(id) == null) {
+            throw exception(COMMON_NOT_FOUND);
+        }
+    }
+
+    private String getTenantName(Long tenantId){
+        return tenantMapper.selectById(tenantId).getName();
+    }
+}