| @@ -3,6 +3,7 @@ package com.xueyi.nlt.api.nlt.feign; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.xueyi.common.core.constant.basic.SecurityConstants; | |||
| import com.xueyi.common.core.constant.basic.ServiceConstants; | |||
| import com.xueyi.common.core.web.result.AjaxResult; | |||
| import com.xueyi.common.core.web.result.R; | |||
| import com.xueyi.nlt.api.netty.domain.vo.DmWebSocketMessageVo; | |||
| import com.xueyi.nlt.api.nlt.domain.vo.DmIntentVo; | |||
| @@ -25,4 +26,7 @@ public interface RemoteIntentService { | |||
| @PostMapping("/intent/inner/taskGenerativeKnowledge") | |||
| public R taskGenerativeKnowledge(); | |||
| @PostMapping("/intent/inner/generateContextTask") | |||
| public AjaxResult generateContextTask(); | |||
| } | |||
| @@ -58,4 +58,7 @@ public class DmSkillPo extends TBaseEntity { | |||
| /** 离开时打招呼 */ | |||
| protected String leavingResp; | |||
| /** 是否开启大模型生成招呼(0:不开启;1:开启)*/ | |||
| protected String genarationByLlm; | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| package com.xueyi.system.api.holiday.feign; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.xueyi.system.api.holiday.feign.factory.RemoteHolidayFallbackFactory; | |||
| import org.springframework.cloud.openfeign.FeignClient; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| import org.springframework.web.bind.annotation.RequestParam; | |||
| /** | |||
| * 短信发送服务 | |||
| * | |||
| * @author yrx | |||
| */ | |||
| @FeignClient(url = "https://www.iamwawa.cn",name = "solar", fallbackFactory = RemoteHolidayFallbackFactory.class) | |||
| public interface RemoteSolarService { | |||
| @GetMapping("/nongli/api") | |||
| JSONObject getSolar(@RequestParam("type") String type, @RequestParam("year") Integer year, @RequestParam("month") Integer month, @RequestParam("day") Integer day); | |||
| } | |||
| @@ -14,6 +14,9 @@ import org.springframework.stereotype.Component; | |||
| public class DmGenerativeKnowledgeTask { | |||
| @Autowired | |||
| RemoteIntentService remoteIntentService; | |||
| @Autowired | |||
| /** | |||
| * 触发条件:* 0/1 * * * * | |||
| * 每分钟执行一次 | |||
| @@ -21,4 +24,13 @@ public class DmGenerativeKnowledgeTask { | |||
| public void generativeKnowledge() { | |||
| remoteIntentService.taskGenerativeKnowledge(); | |||
| } | |||
| /** | |||
| * 触发条件:* * * 0/1 * * | |||
| * 每天执行一次 | |||
| */ | |||
| public void generativeWelcome() { | |||
| remoteIntentService.generateContextTask(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,58 @@ | |||
| package com.xueyi.nlt.nlt.constant; | |||
| import com.baomidou.mybatisplus.core.toolkit.StringUtils; | |||
| import java.time.LocalDateTime; | |||
| /** | |||
| * 提示词常量 | |||
| * | |||
| * @author xueyi | |||
| */ | |||
| public class PromptsConstants { | |||
| /** | |||
| * 日期提示词常量 | |||
| * @auther yinruoxi | |||
| * @param datetime | |||
| * @return | |||
| */ | |||
| public static String getDateFormat(LocalDateTime datetime) { | |||
| // 如果date为null,则返回日期为今天 | |||
| if (datetime == null) { | |||
| datetime = LocalDateTime.now(); | |||
| } | |||
| // 返回格式化内容:今天是2021年1月1日,星期五 | |||
| return "今天是" + datetime.getYear() + "年" + datetime.getMonthValue() + "月" + datetime.getDayOfMonth() + "日,星期" + datetime.getDayOfWeek().getValue() + ","; | |||
| } | |||
| /** | |||
| * 节日提示词常量 | |||
| * @auther yinruoxi | |||
| * @param holiday | |||
| * @return | |||
| */ | |||
| public static String getFestivalFormat(String holiday) { | |||
| String result = ""; | |||
| // 如果holiday不为null,则返回字符串:今天是xx节,否则返回空字符串 | |||
| if (StringUtils.isNotBlank(holiday)) { | |||
| result = "今天是" + holiday + ","; | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * 农历节气提示词常量 | |||
| * @auther yinruoxi | |||
| * @param solarTerm | |||
| * @return | |||
| */ | |||
| public static String getSolarTermFormat(String solarTerm) { | |||
| String result = ""; | |||
| // 如果solarTerm不为null,则返回字符串:今天是xx节,否则返回空字符串 | |||
| if (StringUtils.isNotBlank(solarTerm)) { | |||
| result = "今天是" + solarTerm + ","; | |||
| } | |||
| return result; | |||
| } | |||
| } | |||
| @@ -80,6 +80,7 @@ import org.springframework.web.bind.annotation.RestController; | |||
| import java.io.Serializable; | |||
| import java.text.DateFormat; | |||
| import java.text.SimpleDateFormat; | |||
| import java.time.format.DateTimeFormatter; | |||
| import java.util.Arrays; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| @@ -131,6 +132,9 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| @Autowired | |||
| private GenerativeKnowledgeTemplate generativeKnowledgeTemplate; | |||
| @Autowired | |||
| private GenerativeWelcomeTemplate generativeWelcomeTemplate; | |||
| @Autowired | |||
| private FreeChatTemplate freeChatTemplate; | |||
| @@ -943,6 +947,48 @@ public class DmIntentController extends BaseController<DmIntentQuery, DmIntentDt | |||
| return AjaxResult.error(res); | |||
| } | |||
| @PostMapping("/inner/generateContextTask") | |||
| @ResponseBody | |||
| public AjaxResult generateContextTask() { | |||
| LocalDateTime dateTime = LocalDateTime.now(); | |||
| List<String> contentList = new ArrayList<>(); | |||
| GenerativeWelcomeTemplate.lunar = ""; | |||
| GenerativeWelcomeTemplate.term = null; | |||
| try { | |||
| for (int i = 0; i < 5 && contentList.size() < 10; i++) { | |||
| JSONObject jo = generativeWelcomeTemplate.handle("1", ""); | |||
| String content = ""; | |||
| if (jo != null) { | |||
| content = jo.getString("msg"); | |||
| } | |||
| if (StringUtils.isNotEmpty(content)) { | |||
| JSONArray contents = JSONArray.parseArray(content); | |||
| for (int j = 0; j < contents.size(); j++) { | |||
| String contentStr = contents.getJSONObject(j).getString("content"); | |||
| // 如过contentList中包含content,则不添加 | |||
| if (contentList.contains(contentStr)) { | |||
| continue; | |||
| } | |||
| // 如果content的长度长于30,则不添加 | |||
| if (contentStr.length() > 30) { | |||
| continue; | |||
| } | |||
| if (contentList.size() >= 10) { | |||
| break; | |||
| } | |||
| contentList.add(contentStr); | |||
| } | |||
| } | |||
| } | |||
| //格式化日期:yyyy-MM-dd | |||
| String date = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); | |||
| redisTemplate2.opsForHash().put("group:task" + ":generate", date, contentList); | |||
| } catch (Exception e) { | |||
| log.error("生成任务失败:{}",e.getMessage()); | |||
| return AjaxResult.error("生成任务失败"); | |||
| } | |||
| return success(); | |||
| } | |||
| interface Auth { | |||
| /** 系统 - 意图管理 | |||
| @@ -0,0 +1,99 @@ | |||
| package com.xueyi.nlt.nlt.template; | |||
| import com.alibaba.fastjson2.JSON; | |||
| import com.alibaba.fastjson2.JSONArray; | |||
| import com.alibaba.fastjson2.JSONException; | |||
| import com.alibaba.fastjson2.JSONObject; | |||
| import com.baomidou.mybatisplus.core.toolkit.StringUtils; | |||
| import com.xueyi.common.core.constant.basic.SecurityConstants; | |||
| import com.xueyi.common.core.web.result.AjaxResult; | |||
| import com.xueyi.nlt.netty.client.WebSocketClientManager; | |||
| import com.xueyi.nlt.nlt.constant.PromptsConstants; | |||
| import com.xueyi.nlt.nlt.domain.LlmContext; | |||
| import com.xueyi.nlt.nlt.domain.LlmParam; | |||
| import com.xueyi.nlt.nlt.domain.LlmResponse; | |||
| import com.xueyi.nlt.nlt.service.ISysLlmService; | |||
| import com.xueyi.system.api.holiday.domain.po.DmHolidayPo; | |||
| import com.xueyi.system.api.holiday.feign.FeignHolidayService; | |||
| import com.xueyi.system.api.holiday.feign.RemoteSolarService; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.data.redis.core.RedisTemplate; | |||
| import org.springframework.stereotype.Service; | |||
| import static com.xueyi.nlt.nlt.constant.PromptsConstants.*; | |||
| import java.time.LocalDateTime; | |||
| @Service("generative-welcome") | |||
| public class GenerativeWelcomeTemplate implements BaseTemplate{ | |||
| private static final Logger log = LoggerFactory.getLogger(GenerativeWelcomeTemplate.class); | |||
| public static String lunar = ""; | |||
| public static String term = null; | |||
| @Autowired | |||
| WebSocketClientManager webSocketClientManager; | |||
| @Autowired | |||
| private ISysLlmService sysLlmService; | |||
| @Autowired | |||
| private FeignHolidayService feignHolidayService; | |||
| @Autowired | |||
| private RemoteSolarService remoteSolarService; | |||
| @Autowired | |||
| private RedisTemplate<String,String> redisTemplate; | |||
| @Override | |||
| public JSONObject handle(String devId, String content) { | |||
| JSONObject jsonObject = new JSONObject(); | |||
| String holiday = ""; | |||
| LocalDateTime now = LocalDateTime.now(); | |||
| if (StringUtils.isBlank(lunar)) { | |||
| // 调用接口获取农历信息 | |||
| JSONObject solarJson = remoteSolarService.getSolar("solar",now.getYear(),now.getMonthValue(),now.getDayOfMonth()); | |||
| if (solarJson != null && solarJson.get("data") != null){ | |||
| lunar = solarJson.getJSONObject("data").getString("lunar"); | |||
| term = solarJson.getJSONObject("data").getString("term"); | |||
| if (term == null) { | |||
| term = ""; | |||
| } | |||
| } | |||
| } | |||
| AjaxResult result = feignHolidayService.todayIsWorkDay(SecurityConstants.INNER); | |||
| if (result !=null && result.get("data") != null){ | |||
| DmHolidayPo po = JSON.parseObject(JSON.toJSONString(result.get("data")), DmHolidayPo.class); | |||
| holiday = po.getName(); | |||
| } | |||
| // 根据content内容调用模版并返回结果 | |||
| String prefix = "假设你是公司前台," + getDateFormat(now) + getFestivalFormat(holiday) + getSolarTermFormat(term) + "当你看到公司员工时,请根据以上信息生成简短的话和他打招呼。生成十句打招呼内容,输出为一个JSON数组[{}],每个元素是一个JSON:{“content”:}。不要给出任何解释说明。"; | |||
| String suffix = ""; | |||
| log.info(prefix + content + suffix); | |||
| LlmContext llmContext = new LlmContext(prefix + content + suffix); | |||
| llmContext.setDevId(devId); | |||
| LlmParam llmParam = new LlmParam(); | |||
| LlmResponse response = sysLlmService.chat(llmContext,llmParam); | |||
| try { | |||
| jsonObject.put("msg",response.getContent()); | |||
| return jsonObject; | |||
| } catch (JSONException je) { | |||
| // 返回结果错误,计日志,存log,返回空结果 | |||
| log.error(je.getMessage(),je); | |||
| } | |||
| return jsonObject; | |||
| } | |||
| @Override | |||
| public JSONObject handle(String dev, String content, Long tenantId) { | |||
| return null; | |||
| } | |||
| } | |||
| @@ -19,7 +19,7 @@ import java.util.List; | |||
| public interface DmSkillMapper extends BaseMapper<DmSkillQuery, DmSkillDto, DmSkillPo> { | |||
| //public List<DmSkillDto> selectSkillListByH5(@Param("manId")Long manId, @Param("timestamp") String timestamp); | |||
| public List<DmSkillDto> selectSkillListByH5(DmSyncDigitalmanVo vo); | |||
| public List<DmSkillPo> selectSkillListByH5(DmSyncDigitalmanVo vo); | |||
| public DmSkillPo selectSkillByCode(String skillCode); | |||
| } | |||
| @@ -1,11 +1,13 @@ | |||
| package com.xueyi.system.digitalmans.service.impl; | |||
| import com.alibaba.nacos.common.utils.StringUtils; | |||
| import com.xueyi.common.web.entity.service.impl.BaseServiceImpl; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmInitSkillDto; | |||
| import com.xueyi.system.api.digitalmans.domain.dto.DmSkillDto; | |||
| import com.xueyi.system.api.digitalmans.domain.po.DmSkillPo; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmCustomMadeDto; | |||
| import com.xueyi.system.digitalmans.domain.dto.DmDigitalmanDto; | |||
| import com.xueyi.system.digitalmans.domain.model.DmSkillConverter; | |||
| import com.xueyi.system.digitalmans.domain.query.DmInitSkillQuery; | |||
| import com.xueyi.system.digitalmans.domain.query.DmSkillQuery; | |||
| import com.xueyi.system.digitalmans.domain.vo.DmSyncDigitalmanVo; | |||
| @@ -15,9 +17,13 @@ import com.xueyi.system.digitalmans.manager.impl.DmSkillManager; | |||
| import com.xueyi.system.digitalmans.mapper.DmSkillMapper; | |||
| import com.xueyi.system.digitalmans.service.IDmSkillService; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.data.redis.core.RedisTemplate; | |||
| import org.springframework.stereotype.Service; | |||
| import java.time.LocalDateTime; | |||
| import java.time.format.DateTimeFormatter; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.List; | |||
| /** | |||
| @@ -37,6 +43,12 @@ public class DmSkillServiceImpl extends BaseServiceImpl<DmSkillQuery, DmSkillDto | |||
| @Autowired | |||
| DmSkillManager skillManager; | |||
| @Autowired | |||
| RedisTemplate redisTemplate; | |||
| @Autowired | |||
| DmSkillConverter skillConverter; | |||
| /** | |||
| * 查询技能对象列表 | 数据权限 | |||
| * | |||
| @@ -54,7 +66,18 @@ public class DmSkillServiceImpl extends BaseServiceImpl<DmSkillQuery, DmSkillDto | |||
| DmSyncDigitalmanVo vo = new DmSyncDigitalmanVo(); | |||
| vo.setTimestamp(timestamp); | |||
| vo.setManId(manId); | |||
| List<DmSkillDto> list = skillMapper.selectSkillListByH5(vo); | |||
| List<DmSkillPo> polist = skillMapper.selectSkillListByH5(vo); | |||
| List<DmSkillDto> list = skillConverter.mapperDto(polist); | |||
| // 根据今天日期从redis中的Hash类型group:task:generate中获取列表 | |||
| String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); | |||
| List<String> generationlist = (List<String>) redisTemplate.opsForHash().get("group:task:generate" , date); | |||
| // 将generationlist以间隔符|拼成字符串 | |||
| String generationStr = StringUtils.join(generationlist, "|"); | |||
| for (DmSkillDto dto : list) { | |||
| if (dto.getGenarationByLlm() != null && dto.getGenarationByLlm().equals("1")) { | |||
| dto.setResp(dto.getResp() + "|" + generationStr); | |||
| } | |||
| } | |||
| return list; | |||
| } | |||
| @@ -17,12 +17,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||
| <result property="status" column="status" /> | |||
| <result property="leavingResp" column="leaving_resp" /> | |||
| <result property="welcomByMeetingTime" column="welcom_by_meeting_time" /> | |||
| <result property="genarationByLlm" column="genaration_by_llm" /> | |||
| </resultMap> | |||
| <select id="selectSkillListByH5" parameterType="DmSyncDigitalmanVo" resultMap="DmSkillResult"> | |||
| select s.id, s.man_id,s.status, s.first_call, s.skill_code, s.info, s.del_flag, s.resp, s.motion_id, s.motion_name,s.leaving_resp,s.welcom_by_meeting_time from dm_skills s | |||
| select s.id, s.man_id,s.status, s.first_call, s.skill_code, s.info, s.del_flag, s.resp, s.motion_id, s.motion_name,s.leaving_resp,s.welcom_by_meeting_time,s.genaration_by_llm from dm_skills s | |||
| where (UNIX_TIMESTAMP(s.update_time) * 1000 > #{timestamp} or UNIX_TIMESTAMP(s.create_time) * 1000 > #{timestamp} ) and man_id = #{manId} | |||
| </select> | |||