正在显示
29 个修改的文件
包含
2413 行增加
和
75 行删除
| 1 | package com.zhonglai.luhui.openai.controller; | 1 | package com.zhonglai.luhui.openai.controller; |
| 2 | 2 | ||
| 3 | import cn.hutool.http.HttpUtil; | 3 | import cn.hutool.http.HttpUtil; |
| 4 | +import com.alibaba.fastjson.JSON; | ||
| 4 | import com.alibaba.fastjson.JSONObject; | 5 | import com.alibaba.fastjson.JSONObject; |
| 5 | import com.ruoyi.common.core.controller.BaseController; | 6 | import com.ruoyi.common.core.controller.BaseController; |
| 6 | import com.ruoyi.common.core.domain.AjaxResult; | 7 | import com.ruoyi.common.core.domain.AjaxResult; |
| @@ -20,12 +21,14 @@ import com.theokanning.openai.Usage; | @@ -20,12 +21,14 @@ import com.theokanning.openai.Usage; | ||
| 20 | import com.theokanning.openai.completion.CompletionChoice; | 21 | import com.theokanning.openai.completion.CompletionChoice; |
| 21 | import com.theokanning.openai.completion.CompletionResult; | 22 | import com.theokanning.openai.completion.CompletionResult; |
| 22 | import com.zhonglai.luhui.openai.dto.*; | 23 | import com.zhonglai.luhui.openai.dto.*; |
| 24 | +import com.zhonglai.luhui.openai.service.VipServiceImpl; | ||
| 23 | import com.zhonglai.luhui.openai.utils.OpenAiUtils; | 25 | import com.zhonglai.luhui.openai.utils.OpenAiUtils; |
| 24 | import com.zhonglai.luhui.openai.utils.SysConfigKeyType; | 26 | import com.zhonglai.luhui.openai.utils.SysConfigKeyType; |
| 25 | import io.swagger.annotations.Api; | 27 | import io.swagger.annotations.Api; |
| 26 | import io.swagger.annotations.ApiOperation; | 28 | import io.swagger.annotations.ApiOperation; |
| 27 | import okhttp3.Request; | 29 | import okhttp3.Request; |
| 28 | import okhttp3.Response; | 30 | import okhttp3.Response; |
| 31 | +import org.apache.catalina.Session; | ||
| 29 | import org.apache.commons.io.input.ReaderInputStream; | 32 | import org.apache.commons.io.input.ReaderInputStream; |
| 30 | import org.springframework.beans.factory.annotation.Autowired; | 33 | import org.springframework.beans.factory.annotation.Autowired; |
| 31 | import org.springframework.transaction.annotation.Transactional; | 34 | import org.springframework.transaction.annotation.Transactional; |
| @@ -38,10 +41,7 @@ import java.io.ByteArrayOutputStream; | @@ -38,10 +41,7 @@ import java.io.ByteArrayOutputStream; | ||
| 38 | import java.io.IOException; | 41 | import java.io.IOException; |
| 39 | import java.io.InputStream; | 42 | import java.io.InputStream; |
| 40 | import java.math.BigDecimal; | 43 | import java.math.BigDecimal; |
| 41 | -import java.util.ArrayList; | ||
| 42 | -import java.util.List; | ||
| 43 | -import java.util.Map; | ||
| 44 | -import java.util.Optional; | 44 | +import java.util.*; |
| 45 | import java.util.stream.Collectors; | 45 | import java.util.stream.Collectors; |
| 46 | 46 | ||
| 47 | @Api(tags = "chatGPT接口") | 47 | @Api(tags = "chatGPT接口") |
| @@ -51,9 +51,14 @@ public class ChatGPTController extends BaseController { | @@ -51,9 +51,14 @@ public class ChatGPTController extends BaseController { | ||
| 51 | @Autowired | 51 | @Autowired |
| 52 | private PublicService publicService; | 52 | private PublicService publicService; |
| 53 | 53 | ||
| 54 | - @ApiOperation("与AI机器进行聊天") | 54 | + @Autowired |
| 55 | + private VipServiceImpl vipService; | ||
| 56 | + | ||
| 57 | + private static String sessionkey = "CHAT_HISTORY_CONTEXT";//上下文关联存放地址 | ||
| 58 | + | ||
| 59 | + @ApiOperation("与AI机器进行聊天(废弃)") | ||
| 55 | @RequestMapping(value = "/aiChatbot",method = RequestMethod.POST) | 60 | @RequestMapping(value = "/aiChatbot",method = RequestMethod.POST) |
| 56 | - public Message aiChatbot(HttpServletRequest httpServletRequest, @RequestBody String data) | 61 | + public AjaxResult aiChatbot(HttpServletRequest httpServletRequest, @RequestBody String data) |
| 57 | { | 62 | { |
| 58 | HttpSession session = httpServletRequest.getSession(); | 63 | HttpSession session = httpServletRequest.getSession(); |
| 59 | if(session!=null) | 64 | if(session!=null) |
| @@ -66,10 +71,10 @@ public class ChatGPTController extends BaseController { | @@ -66,10 +71,10 @@ public class ChatGPTController extends BaseController { | ||
| 66 | i+=completionChoice.getText().length(); | 71 | i+=completionChoice.getText().length(); |
| 67 | } | 72 | } |
| 68 | logger.info("{}请求的流量:{},回复的流量:{}",session.getId(),data.length(),i); | 73 | logger.info("{}请求的流量:{},回复的流量:{}",session.getId(),data.length(),i); |
| 69 | - return new Message(MessageCode.DEFAULT_SUCCESS_CODE,list); | 74 | + return AjaxResult.success(list); |
| 70 | } | 75 | } |
| 71 | List<CompletionChoice> list = OpenAiUtils.getAiChatbot(data); | 76 | List<CompletionChoice> list = OpenAiUtils.getAiChatbot(data); |
| 72 | - return new Message(MessageCode.DEFAULT_SUCCESS_CODE,list); | 77 | + return AjaxResult.success(list); |
| 73 | } | 78 | } |
| 74 | 79 | ||
| 75 | private ChatRoomMessages mapToChatRoomMessages(Map<String,Object> src) | 80 | private ChatRoomMessages mapToChatRoomMessages(Map<String,Object> src) |
| @@ -79,58 +84,80 @@ public class ChatGPTController extends BaseController { | @@ -79,58 +84,80 @@ public class ChatGPTController extends BaseController { | ||
| 79 | return chatRoomMessages; | 84 | return chatRoomMessages; |
| 80 | } | 85 | } |
| 81 | 86 | ||
| 82 | - @ApiOperation("chatgpt3.5") | 87 | + @ApiOperation(value = "历史记录",notes = "默认获取最新5条记录") |
| 83 | @Transactional | 88 | @Transactional |
| 84 | - @RequestMapping(value = "/chatgptV3_5",method = RequestMethod.POST) | ||
| 85 | - public Message chatgptV3_5(HttpServletRequest httpServletRequest, @RequestBody String data) | 89 | + @RequestMapping(value = "/roomHistory",method = RequestMethod.GET) |
| 90 | + public AjaxResult roomHistory() | ||
| 86 | { | 91 | { |
| 92 | + //跟进用户信息生成入口参数 | ||
| 87 | OpenAiLoginUser userInfo = (OpenAiLoginUser) getLoginUser(); | 93 | OpenAiLoginUser userInfo = (OpenAiLoginUser) getLoginUser(); |
| 88 | Integer user_id= userInfo.getUserId().intValue(); | 94 | Integer user_id= userInfo.getUserId().intValue(); |
| 89 | - OpenAiUserInfo openAiUserInfo = (OpenAiUserInfo) userInfo.getUser(); | ||
| 90 | - if(openAiUserInfo.getFlow_packet_remain()<=0) | ||
| 91 | - { | ||
| 92 | - return new Message(MessageCode.DEFAULT_FAIL_CODE,"余量不足"); | 95 | + String room_id = String.valueOf(user_id); |
| 96 | + List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT * FROM `lk_openai`.`gpt_message` WHERE room_id="+room_id+" AND user_id="+user_id+" order by create_time desc 5"); | ||
| 97 | + Collections.reverse(list); | ||
| 98 | + return AjaxResult.success(list); | ||
| 93 | } | 99 | } |
| 94 | 100 | ||
| 95 | - List<Map<String,Object>> unitpriceList = publicService.getObjectListBySQL("select `key`,`value` from `lk_openai`.`sys_config` where `key_type`='"+SysConfigKeyType.gpt_3_5_unitprice+"'"); | ||
| 96 | - BigDecimal openaiUnitprice = new BigDecimal(0); | ||
| 97 | - BigDecimal realityUnitprice = new BigDecimal(0); | ||
| 98 | - if(null != unitpriceList && unitpriceList.size() !=0) | ||
| 99 | - { | ||
| 100 | - for(Map<String,Object> map:unitpriceList) | ||
| 101 | - { | ||
| 102 | - if("openai".equals(map.get("key"))) | 101 | + @ApiOperation(value = "chatgpt3.5",notes = "上下文关联,要实现上下问关联就需要记录整个聊天的提问记录,目前只支持相同session的上下文关联,就是说,如果聊天页面关闭以后再打开,是没有上下文关联的") |
| 102 | + @Transactional | ||
| 103 | + @RequestMapping(value = "/chatgptV3_5",method = RequestMethod.POST) | ||
| 104 | + public AjaxResult chatgptV3_5(HttpServletRequest httpServletRequest,@RequestBody String data) | ||
| 103 | { | 105 | { |
| 104 | - openaiUnitprice = new BigDecimal(map.get("value").toString()); | ||
| 105 | - }else if("reality".equals(map.get("key"))) | 106 | + //跟进用户信息生成入口参数 |
| 107 | + OpenAiLoginUser userInfo = (OpenAiLoginUser) getLoginUser(); | ||
| 108 | + Integer user_id= userInfo.getUserId().intValue(); | ||
| 109 | + String room_id = String.valueOf(user_id); | ||
| 110 | + | ||
| 111 | + OpenAiUserInfo openAiUserInfo = (OpenAiUserInfo) userInfo.getUser(); | ||
| 112 | + | ||
| 113 | + List<CompletionChoiceMessage3_5> rlist = new ArrayList<>(); | ||
| 114 | + | ||
| 115 | + //验证余额是否充足 | ||
| 116 | + if(vipService.isCharging(openAiUserInfo.getVip_level()) && openAiUserInfo.getFlow_packet_remain()<=0) | ||
| 106 | { | 117 | { |
| 107 | - realityUnitprice = new BigDecimal(map.get("value").toString()); | ||
| 108 | - } | ||
| 109 | - } | 118 | + CompletionChoiceMessage3_5 completionChoiceMessage3_5 = new CompletionChoiceMessage3_5(); |
| 119 | + completionChoiceMessage3_5.setRole("assistant"); | ||
| 120 | + StringBuffer stringBuffer = new StringBuffer(); | ||
| 121 | + stringBuffer.append("您的余额不足请联系管理员或者点击链接充值:\\n\\n"); | ||
| 122 | + stringBuffer.append("https://充值链接.com"); | ||
| 123 | + completionChoiceMessage3_5.setContent(stringBuffer.toString()); | ||
| 124 | + rlist.add(completionChoiceMessage3_5); | ||
| 125 | + | ||
| 126 | + return AjaxResult.success(rlist); | ||
| 110 | } | 127 | } |
| 128 | + | ||
| 129 | + BigDecimal[] bs = vipService.getUnitprice(); | ||
| 130 | + BigDecimal openaiUnitprice = bs[0]; | ||
| 131 | + BigDecimal realityUnitprice = bs[1]; | ||
| 111 | if(openaiUnitprice.intValue()==0 || realityUnitprice.intValue()==0) | 132 | if(openaiUnitprice.intValue()==0 || realityUnitprice.intValue()==0) |
| 112 | { | 133 | { |
| 113 | - return new Message(MessageCode.DEFAULT_FAIL_CODE,"系统未配置流量单价,请联系管理员"); | 134 | + rlist.add(new CompletionChoiceMessage3_5("assistant","系统未配置流量单价,请联系管理员")); |
| 135 | + return AjaxResult.success(rlist); | ||
| 114 | } | 136 | } |
| 115 | 137 | ||
| 116 | - String room_id = String.valueOf(user_id); | ||
| 117 | logger.info("{}生成聊天会话:",room_id); | 138 | logger.info("{}生成聊天会话:",room_id); |
| 118 | 139 | ||
| 119 | - List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT send_role role,send_content content FROM `lk_openai`.`gpt_message` WHERE room_id='"+room_id+"' AND user_id="+user_id+" order by create_time asc limit 5"); | ||
| 120 | - | ||
| 121 | - List<ChatRoomMessages> messageList = Optional.ofNullable(list).orElse(new ArrayList<>()).stream().map(item->mapToChatRoomMessages(item)).collect(Collectors.toList()); | ||
| 122 | - | 140 | + //上下文关联 |
| 141 | + HttpSession session = httpServletRequest.getSession(); | ||
| 142 | + List<ChatRoomMessages> messageList = Optional.ofNullable((List<Map<String, Object>>) session.getAttribute(sessionkey)).orElse(new ArrayList<>()).stream().map(item->mapToChatRoomMessages(item)).collect(Collectors.toList()); | ||
| 123 | ChatRoomMessages chatRoomMessages = new ChatRoomMessages(); | 143 | ChatRoomMessages chatRoomMessages = new ChatRoomMessages(); |
| 124 | chatRoomMessages.setRole("user"); | 144 | chatRoomMessages.setRole("user"); |
| 125 | chatRoomMessages.setContent(data); | 145 | chatRoomMessages.setContent(data); |
| 126 | messageList.add(chatRoomMessages); | 146 | messageList.add(chatRoomMessages); |
| 147 | + session.setAttribute(sessionkey,messageList); | ||
| 127 | 148 | ||
| 128 | //获取返回参数 | 149 | //获取返回参数 |
| 129 | - CompletionResult3_5 completionResult3_5 = sendGPTAi(messageList); | 150 | + CompletionResult3_5 completionResult3_5 = null; |
| 151 | + if(vipService.isfree(openAiUserInfo.getVip_level())) | ||
| 152 | + { | ||
| 153 | + completionResult3_5 = sendGPTAi(messageList); | ||
| 154 | + }else{ | ||
| 155 | + completionResult3_5 = sendFreeGPTAi(messageList); | ||
| 156 | + } | ||
| 157 | + | ||
| 130 | Usage usage = completionResult3_5.getUsage(); | 158 | Usage usage = completionResult3_5.getUsage(); |
| 131 | 159 | ||
| 132 | List<CompletionChoice3_5> list3_5 = completionResult3_5.getChoices(); | 160 | List<CompletionChoice3_5> list3_5 = completionResult3_5.getChoices(); |
| 133 | - List<CompletionChoiceMessage3_5> rlist = new ArrayList<>(); | ||
| 134 | 161 | ||
| 135 | if(null != list3_5 && list3_5.size() !=0 ) | 162 | if(null != list3_5 && list3_5.size() !=0 ) |
| 136 | { | 163 | { |
| @@ -150,6 +177,7 @@ public class ChatGPTController extends BaseController { | @@ -150,6 +177,7 @@ public class ChatGPTController extends BaseController { | ||
| 150 | //统计代币 | 177 | //统计代币 |
| 151 | gptMessage.setCompletion_tokens(usage.getCompletionTokens()); | 178 | gptMessage.setCompletion_tokens(usage.getCompletionTokens()); |
| 152 | gptMessage.setPrompt_tokens(usage.getPromptTokens()); | 179 | gptMessage.setPrompt_tokens(usage.getPromptTokens()); |
| 180 | + gptMessage.setTotal_tokens(usage.getTotalTokens()); | ||
| 153 | }else{ | 181 | }else{ |
| 154 | gptMessage.setSend_size(0); | 182 | gptMessage.setSend_size(0); |
| 155 | } | 183 | } |
| @@ -183,18 +211,31 @@ public class ChatGPTController extends BaseController { | @@ -183,18 +211,31 @@ public class ChatGPTController extends BaseController { | ||
| 183 | UserFlowPacketRemainLog userFlowPacketRemainLog = new UserFlowPacketRemainLog(); | 211 | UserFlowPacketRemainLog userFlowPacketRemainLog = new UserFlowPacketRemainLog(); |
| 184 | userFlowPacketRemainLog.setCreate_time(DateUtils.getNowTimeMilly()); | 212 | userFlowPacketRemainLog.setCreate_time(DateUtils.getNowTimeMilly()); |
| 185 | userFlowPacketRemainLog.setUser_id(openAiUserInfo.getId()); | 213 | userFlowPacketRemainLog.setUser_id(openAiUserInfo.getId()); |
| 186 | - userFlowPacketRemainLog.setRoom_id(room_id); | ||
| 187 | - userFlowPacketRemainLog.setPrompt_tokens(usage.getPromptTokens()); | ||
| 188 | - userFlowPacketRemainLog.setCompletion_tokens(usage.getCompletionTokens()); | 214 | + userFlowPacketRemainLog.setType(2); //消费 |
| 215 | + | ||
| 216 | + StringBuffer stringBuffer = new StringBuffer(); | ||
| 217 | + stringBuffer.append("房间号:"); | ||
| 218 | + stringBuffer.append(room_id); | ||
| 219 | + stringBuffer.append("发送代币:"); | ||
| 220 | + stringBuffer.append(usage.getPromptTokens()); | ||
| 221 | + stringBuffer.append("返回代币:"); | ||
| 222 | + stringBuffer.append(usage.getCompletionTokens()); | ||
| 223 | + userFlowPacketRemainLog.setDescribe(stringBuffer.toString()); | ||
| 189 | userFlowPacketRemainLog.setTotal_tokens(usage.getTotalTokens()); | 224 | userFlowPacketRemainLog.setTotal_tokens(usage.getTotalTokens()); |
| 225 | + | ||
| 190 | userFlowPacketRemainLog.setOpenai_money(openaiUnitprice.multiply(new BigDecimal(usage.getTotalTokens())).divide(new BigDecimal(1000),6)); | 226 | userFlowPacketRemainLog.setOpenai_money(openaiUnitprice.multiply(new BigDecimal(usage.getTotalTokens())).divide(new BigDecimal(1000),6)); |
| 191 | userFlowPacketRemainLog.setReality_money(realityUnitprice.multiply(new BigDecimal(usage.getTotalTokens())).divide(new BigDecimal(1000),6)); | 227 | userFlowPacketRemainLog.setReality_money(realityUnitprice.multiply(new BigDecimal(usage.getTotalTokens())).divide(new BigDecimal(1000),6)); |
| 192 | publicService.insertToTable(userFlowPacketRemainLog,"`lk_openai`.`user_flow_packet_remain_log`"); | 228 | publicService.insertToTable(userFlowPacketRemainLog,"`lk_openai`.`user_flow_packet_remain_log`"); |
| 193 | } | 229 | } |
| 194 | - return new Message(MessageCode.DEFAULT_FAIL_CODE,rlist); | 230 | + return AjaxResult.success(rlist); |
| 195 | } | 231 | } |
| 196 | 232 | ||
| 197 | 233 | ||
| 234 | + /** | ||
| 235 | + * 付费接口 | ||
| 236 | + * @param messageList | ||
| 237 | + * @return | ||
| 238 | + */ | ||
| 198 | private CompletionResult3_5 sendGPTAi(List<ChatRoomMessages> messageList) | 239 | private CompletionResult3_5 sendGPTAi(List<ChatRoomMessages> messageList) |
| 199 | { | 240 | { |
| 200 | JSONObject jsonObject = new JSONObject(); | 241 | JSONObject jsonObject = new JSONObject(); |
| @@ -205,6 +246,21 @@ public class ChatGPTController extends BaseController { | @@ -205,6 +246,21 @@ public class ChatGPTController extends BaseController { | ||
| 205 | return completionResult; | 246 | return completionResult; |
| 206 | } | 247 | } |
| 207 | 248 | ||
| 249 | + /** | ||
| 250 | + * 免费接口 | ||
| 251 | + * @param messageList | ||
| 252 | + * @return | ||
| 253 | + */ | ||
| 254 | + private CompletionResult3_5 sendFreeGPTAi(List<ChatRoomMessages> messageList) | ||
| 255 | + { | ||
| 256 | + JSONObject jsonObject = new JSONObject(); | ||
| 257 | + jsonObject.put("model","gpt-3.5-turbo-0301"); | ||
| 258 | + jsonObject.put("messages",messageList); | ||
| 259 | + String str = HttpUtil.post("https://free.chatgpt.njlaikun.com/v1/chat/completions",jsonObject.toString()); | ||
| 260 | + CompletionResult3_5 completionResult = JSONObject.parseObject(str, CompletionResult3_5.class); | ||
| 261 | + return completionResult; | ||
| 262 | + } | ||
| 263 | + | ||
| 208 | public static byte[] readInputStream(InputStream inputStream) throws IOException { | 264 | public static byte[] readInputStream(InputStream inputStream) throws IOException { |
| 209 | byte[] buffer = new byte[1024]; | 265 | byte[] buffer = new byte[1024]; |
| 210 | int len = 0; | 266 | int len = 0; |
| @@ -3,15 +3,20 @@ package com.zhonglai.luhui.openai.controller; | @@ -3,15 +3,20 @@ package com.zhonglai.luhui.openai.controller; | ||
| 3 | import cn.hutool.http.HttpUtil; | 3 | import cn.hutool.http.HttpUtil; |
| 4 | import com.alibaba.fastjson.JSON; | 4 | import com.alibaba.fastjson.JSON; |
| 5 | import com.ruoyi.common.constant.Constants; | 5 | import com.ruoyi.common.constant.Constants; |
| 6 | +import com.ruoyi.common.constant.HttpStatus; | ||
| 6 | import com.ruoyi.common.core.controller.BaseController; | 7 | import com.ruoyi.common.core.controller.BaseController; |
| 8 | +import com.ruoyi.common.core.domain.AjaxResult; | ||
| 7 | import com.ruoyi.common.core.domain.Message; | 9 | import com.ruoyi.common.core.domain.Message; |
| 8 | import com.ruoyi.common.core.domain.MessageCode; | 10 | import com.ruoyi.common.core.domain.MessageCode; |
| 11 | +import com.ruoyi.common.utils.DESUtil; | ||
| 12 | +import com.ruoyi.common.utils.DateUtils; | ||
| 9 | import com.ruoyi.system.login.service.LoginService; | 13 | import com.ruoyi.system.login.service.LoginService; |
| 10 | import io.swagger.annotations.Api; | 14 | import io.swagger.annotations.Api; |
| 11 | import io.swagger.annotations.ApiImplicitParam; | 15 | import io.swagger.annotations.ApiImplicitParam; |
| 12 | import io.swagger.annotations.ApiImplicitParams; | 16 | import io.swagger.annotations.ApiImplicitParams; |
| 13 | import io.swagger.annotations.ApiOperation; | 17 | import io.swagger.annotations.ApiOperation; |
| 14 | import org.springframework.beans.factory.annotation.Autowired; | 18 | import org.springframework.beans.factory.annotation.Autowired; |
| 19 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 15 | import org.springframework.web.bind.annotation.PostMapping; | 20 | import org.springframework.web.bind.annotation.PostMapping; |
| 16 | import org.springframework.web.bind.annotation.RequestMapping; | 21 | import org.springframework.web.bind.annotation.RequestMapping; |
| 17 | import org.springframework.web.bind.annotation.RestController; | 22 | import org.springframework.web.bind.annotation.RestController; |
| @@ -24,28 +29,29 @@ import java.util.Map; | @@ -24,28 +29,29 @@ import java.util.Map; | ||
| 24 | @RequestMapping("/openAiUserLogin") | 29 | @RequestMapping("/openAiUserLogin") |
| 25 | public class OpenAiUserLoginController extends BaseController { | 30 | public class OpenAiUserLoginController extends BaseController { |
| 26 | private static String user_pass = "123456"; | 31 | private static String user_pass = "123456"; |
| 32 | + | ||
| 33 | + public static String ENCODE_KEY = "com/zhonglai"; | ||
| 27 | @Autowired | 34 | @Autowired |
| 28 | private LoginService loginService; | 35 | private LoginService loginService; |
| 29 | - @ApiOperation("手机验证码登陆") | 36 | + @ApiOperation(value = "手机验证码登陆",notes = "返回token和longtoken,token是接口操作令牌失效时间端,长期本地缓存推荐存储longtoken,longtoken可以通过/openAiUserLogin/getTokenFromLongtoken接口换取token") |
| 30 | @ApiImplicitParams({ | 37 | @ApiImplicitParams({ |
| 31 | @ApiImplicitParam(value = "手机号",name = "phone"), | 38 | @ApiImplicitParam(value = "手机号",name = "phone"), |
| 32 | @ApiImplicitParam(value = "验证码",name = "code"), | 39 | @ApiImplicitParam(value = "验证码",name = "code"), |
| 33 | }) | 40 | }) |
| 34 | @PostMapping("/userpassLogin") | 41 | @PostMapping("/userpassLogin") |
| 35 | - public Message userpassLogin(String phone, String code,String key) | 42 | + public AjaxResult userpassLogin(String phone, String code, String key) |
| 36 | { | 43 | { |
| 37 | //验证验证码 | 44 | //验证验证码 |
| 38 | String str = HttpUtil.get("http://ly.userlogin.yu2le.com/userLogin/verificationCode?key="+key+"&code="+code); | 45 | String str = HttpUtil.get("http://ly.userlogin.yu2le.com/userLogin/verificationCode?key="+key+"&code="+code); |
| 39 | Message message = JSON.parseObject(str,Message.class); | 46 | Message message = JSON.parseObject(str,Message.class); |
| 40 | if(message.getCode()!=MessageCode.DEFAULT_SUCCESS_CODE.code) | 47 | if(message.getCode()!=MessageCode.DEFAULT_SUCCESS_CODE.code) |
| 41 | { | 48 | { |
| 42 | - return message; | 49 | + return AjaxResult.error(message.getMessage()); |
| 43 | } | 50 | } |
| 44 | //生成令牌 | 51 | //生成令牌 |
| 45 | String token = loginService.openaiLoginByPass(phone,user_pass); | 52 | String token = loginService.openaiLoginByPass(phone,user_pass); |
| 46 | - Map<String,Object> map = new HashMap<>(); | ||
| 47 | - map.put(Constants.TOKEN, token); | ||
| 48 | - return new Message(MessageCode.DEFAULT_SUCCESS_CODE,map); | 53 | + String longtoken = DESUtil.encode(phone+"_"+ DateUtils.getNowTimeMilly(),ENCODE_KEY); |
| 54 | + return AjaxResult.success().put(Constants.TOKEN, token).put("longtoken", longtoken); | ||
| 49 | } | 55 | } |
| 50 | 56 | ||
| 51 | 57 | ||
| @@ -54,11 +60,34 @@ public class OpenAiUserLoginController extends BaseController { | @@ -54,11 +60,34 @@ public class OpenAiUserLoginController extends BaseController { | ||
| 54 | @ApiImplicitParam(value = "手机号",name = "phone"), | 60 | @ApiImplicitParam(value = "手机号",name = "phone"), |
| 55 | }) | 61 | }) |
| 56 | @PostMapping("/sendPhoneCode") | 62 | @PostMapping("/sendPhoneCode") |
| 57 | - public Message sendPhoneCode(String phone) | 63 | + public AjaxResult sendPhoneCode(String phone) |
| 58 | { | 64 | { |
| 59 | //生成令牌 | 65 | //生成令牌 |
| 60 | String str = HttpUtil.get("http://ly.userlogin.yu2le.com/userLogin/getPhoneCode/1/"+phone); | 66 | String str = HttpUtil.get("http://ly.userlogin.yu2le.com/userLogin/getPhoneCode/1/"+phone); |
| 61 | - return JSON.parseObject(str,Message.class); | 67 | + Message message = JSON.parseObject(str,Message.class); |
| 68 | + if(message.getCode()!=MessageCode.DEFAULT_SUCCESS_CODE.code) | ||
| 69 | + { | ||
| 70 | + return AjaxResult.error(message.getMessage()); | ||
| 71 | + } | ||
| 72 | + return AjaxResult.success(message.getMessage()).put("data",message.getData()); | ||
| 62 | } | 73 | } |
| 63 | 74 | ||
| 75 | + @ApiOperation(value = "长期token获取短期token",notes = "此接口也会返回一个长token,推荐用此接口更新本地存储的长token,可以延长长token的使用时间") | ||
| 76 | + @ApiImplicitParams({ | ||
| 77 | + @ApiImplicitParam(value = "长token(为接口 /openAiUserLogin/userpassLogin 返回的 longtoken)",name = "longtoken"), | ||
| 78 | + }) | ||
| 79 | + @GetMapping("/getTokenFromLongtoken") | ||
| 80 | + public AjaxResult getTokenFromLongtoken(String longtoken) | ||
| 81 | + { | ||
| 82 | + String str = DESUtil.decode(longtoken,ENCODE_KEY); | ||
| 83 | + String[] ss = str.split("_"); | ||
| 84 | + Integer time = 5184000; //60天 | ||
| 85 | + if(DateUtils.getNowTimeMilly()-Integer.parseInt(ss[1])>time) | ||
| 86 | + { | ||
| 87 | + return AjaxResult.error(HttpStatus.FORBIDDEN,"长token过期,请重新用手机号登陆"); | ||
| 88 | + } | ||
| 89 | + String token = loginService.openaiLoginByPass(ss[0],user_pass); | ||
| 90 | + String agenlongtoken = DESUtil.encode(ss[0]+"_"+ DateUtils.getNowTimeMilly(),ENCODE_KEY); | ||
| 91 | + return AjaxResult.success().put(Constants.TOKEN, token).put("longtoken", agenlongtoken); | ||
| 92 | + } | ||
| 64 | } | 93 | } |
| 1 | +package com.zhonglai.luhui.openai.controller; | ||
| 2 | + | ||
| 3 | +import com.ruoyi.common.core.controller.BaseController; | ||
| 4 | +import com.ruoyi.common.core.domain.AjaxResult; | ||
| 5 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
| 6 | +import com.ruoyi.system.service.PublicService; | ||
| 7 | +import io.swagger.annotations.Api; | ||
| 8 | +import io.swagger.annotations.ApiOperation; | ||
| 9 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 10 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 11 | +import org.springframework.web.bind.annotation.PostMapping; | ||
| 12 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 13 | +import org.springframework.web.bind.annotation.RestController; | ||
| 14 | + | ||
| 15 | +import java.util.List; | ||
| 16 | +import java.util.Map; | ||
| 17 | + | ||
| 18 | +@Api(tags = "用户管理") | ||
| 19 | +@RestController | ||
| 20 | +@RequestMapping("/userInfo") | ||
| 21 | +public class UserInfoController extends BaseController { | ||
| 22 | + @Autowired | ||
| 23 | + private PublicService publicService; | ||
| 24 | + @ApiOperation("获取用户信息") | ||
| 25 | + @GetMapping("/getUserInfo") | ||
| 26 | + public AjaxResult getUserInfo() | ||
| 27 | + { | ||
| 28 | + return AjaxResult.success(getLoginUser().getUser()); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + @ApiOperation("修改头像") | ||
| 32 | + @PostMapping("/upimgurl") | ||
| 33 | + public AjaxResult upimgurl(String img_url) | ||
| 34 | + { | ||
| 35 | + publicService.updateBySql("UPDATE `lk_openai`.`user_info` SET img_url='"+img_url+"' WHERE id="+getUserId().intValue()); | ||
| 36 | + return AjaxResult.success(); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + @ApiOperation("修改昵称") | ||
| 40 | + @PostMapping("/upnickname") | ||
| 41 | + public AjaxResult upnickname(String nickname) | ||
| 42 | + { | ||
| 43 | + publicService.updateBySql("UPDATE `lk_openai`.`user_info` SET nickname='"+nickname+"' WHERE id="+getUserId().intValue()); | ||
| 44 | + return AjaxResult.success(); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + @ApiOperation("代币使用记录") | ||
| 48 | + @GetMapping("/userFlowPacketRemainLog") | ||
| 49 | + public TableDataInfo useFlowPacketRemainLog() | ||
| 50 | + { | ||
| 51 | + startPage(); | ||
| 52 | + List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT * FROM `lk_openai`.`user_flow_packet_remain_log` WHERE `user_id=`"+getUserId().intValue()+" and `type`=2 order by create_time desc"); | ||
| 53 | + return getDataTable(list); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + @ApiOperation("代币充值记录") | ||
| 57 | + @GetMapping("/rechargeFlowPacketRemainLog") | ||
| 58 | + public TableDataInfo rechargeFlowPacketRemainLog() | ||
| 59 | + { | ||
| 60 | + startPage(); | ||
| 61 | + List<Map<String,Object>> list = publicService.getObjectListBySQL("SELECT * FROM `lk_openai`.`user_flow_packet_remain_log` WHERE `user_id`="+getUserId().intValue()+" and `type`=1 order by create_time desc"); | ||
| 62 | + return getDataTable(list); | ||
| 63 | + } | ||
| 64 | +} |
| @@ -4,6 +4,14 @@ public class CompletionChoiceMessage3_5 { | @@ -4,6 +4,14 @@ public class CompletionChoiceMessage3_5 { | ||
| 4 | private String role; | 4 | private String role; |
| 5 | private String content; | 5 | private String content; |
| 6 | 6 | ||
| 7 | + public CompletionChoiceMessage3_5() { | ||
| 8 | + } | ||
| 9 | + | ||
| 10 | + public CompletionChoiceMessage3_5(String role, String content) { | ||
| 11 | + this.role = role; | ||
| 12 | + this.content = content; | ||
| 13 | + } | ||
| 14 | + | ||
| 7 | public String getRole() { | 15 | public String getRole() { |
| 8 | return role; | 16 | return role; |
| 9 | } | 17 | } |
| @@ -14,6 +14,16 @@ public class GptMessage { | @@ -14,6 +14,16 @@ public class GptMessage { | ||
| 14 | private Long prompt_tokens; //输入代币 | 14 | private Long prompt_tokens; //输入代币 |
| 15 | private Long completion_tokens; //输出代币 | 15 | private Long completion_tokens; //输出代币 |
| 16 | 16 | ||
| 17 | + private Long total_tokens; //bigint(20) DEFAULT NULL COMMENT '总代币', | ||
| 18 | + | ||
| 19 | + public Long getTotal_tokens() { | ||
| 20 | + return total_tokens; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + public void setTotal_tokens(Long total_tokens) { | ||
| 24 | + this.total_tokens = total_tokens; | ||
| 25 | + } | ||
| 26 | + | ||
| 17 | public Long getPrompt_tokens() { | 27 | public Long getPrompt_tokens() { |
| 18 | return prompt_tokens; | 28 | return prompt_tokens; |
| 19 | } | 29 | } |
| @@ -5,13 +5,28 @@ import java.math.BigDecimal; | @@ -5,13 +5,28 @@ import java.math.BigDecimal; | ||
| 5 | public class UserFlowPacketRemainLog { | 5 | public class UserFlowPacketRemainLog { |
| 6 | private Integer id; //int(11) DEFAULT NULL COMMENT '主键', | 6 | private Integer id; //int(11) DEFAULT NULL COMMENT '主键', |
| 7 | private Integer user_id; //int(11) DEFAULT NULL COMMENT '用户', | 7 | private Integer user_id; //int(11) DEFAULT NULL COMMENT '用户', |
| 8 | - private String room_id; //varchar(50) DEFAULT NULL COMMENT '房间号', | ||
| 9 | private Integer create_time; //int(11) DEFAULT NULL COMMENT '创建时间', | 8 | private Integer create_time; //int(11) DEFAULT NULL COMMENT '创建时间', |
| 10 | - private Long prompt_tokens; //bigint(20) DEFAULT NULL COMMENT '发起代币', | ||
| 11 | - private Long completion_tokens; //bigint(20) DEFAULT NULL COMMENT '完成代币', | ||
| 12 | private Long total_tokens; //bigint(20) DEFAULT NULL COMMENT '总代币', | 9 | private Long total_tokens; //bigint(20) DEFAULT NULL COMMENT '总代币', |
| 13 | private BigDecimal openai_money; //bigint(20) DEFAULT NULL COMMENT 'openai费用(美元)', | 10 | private BigDecimal openai_money; //bigint(20) DEFAULT NULL COMMENT 'openai费用(美元)', |
| 14 | private BigDecimal reality_money; //bigint(20) DEFAULT NULL COMMENT '实际费用(人民币)' | 11 | private BigDecimal reality_money; //bigint(20) DEFAULT NULL COMMENT '实际费用(人民币)' |
| 12 | + private String describe; //描述 | ||
| 13 | + private Integer type; //int(11) DEFAULT NULL COMMENT '类型(1充值,2消费)', | ||
| 14 | + | ||
| 15 | + public Integer getType() { | ||
| 16 | + return type; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + public void setType(Integer type) { | ||
| 20 | + this.type = type; | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + public String getDescribe() { | ||
| 24 | + return describe; | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + public void setDescribe(String describe) { | ||
| 28 | + this.describe = describe; | ||
| 29 | + } | ||
| 15 | 30 | ||
| 16 | public Integer getId() { | 31 | public Integer getId() { |
| 17 | return id; | 32 | return id; |
| @@ -29,13 +44,6 @@ public class UserFlowPacketRemainLog { | @@ -29,13 +44,6 @@ public class UserFlowPacketRemainLog { | ||
| 29 | this.user_id = user_id; | 44 | this.user_id = user_id; |
| 30 | } | 45 | } |
| 31 | 46 | ||
| 32 | - public String getRoom_id() { | ||
| 33 | - return room_id; | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | - public void setRoom_id(String room_id) { | ||
| 37 | - this.room_id = room_id; | ||
| 38 | - } | ||
| 39 | 47 | ||
| 40 | public Integer getCreate_time() { | 48 | public Integer getCreate_time() { |
| 41 | return create_time; | 49 | return create_time; |
| @@ -45,22 +53,6 @@ public class UserFlowPacketRemainLog { | @@ -45,22 +53,6 @@ public class UserFlowPacketRemainLog { | ||
| 45 | this.create_time = create_time; | 53 | this.create_time = create_time; |
| 46 | } | 54 | } |
| 47 | 55 | ||
| 48 | - public Long getPrompt_tokens() { | ||
| 49 | - return prompt_tokens; | ||
| 50 | - } | ||
| 51 | - | ||
| 52 | - public void setPrompt_tokens(Long prompt_tokens) { | ||
| 53 | - this.prompt_tokens = prompt_tokens; | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - public Long getCompletion_tokens() { | ||
| 57 | - return completion_tokens; | ||
| 58 | - } | ||
| 59 | - | ||
| 60 | - public void setCompletion_tokens(Long completion_tokens) { | ||
| 61 | - this.completion_tokens = completion_tokens; | ||
| 62 | - } | ||
| 63 | - | ||
| 64 | public Long getTotal_tokens() { | 56 | public Long getTotal_tokens() { |
| 65 | return total_tokens; | 57 | return total_tokens; |
| 66 | } | 58 | } |
| 1 | +package com.zhonglai.luhui.openai.service; | ||
| 2 | + | ||
| 3 | +import com.ruoyi.common.core.domain.Message; | ||
| 4 | +import com.ruoyi.common.core.domain.MessageCode; | ||
| 5 | +import com.ruoyi.system.service.PublicService; | ||
| 6 | +import com.zhonglai.luhui.openai.dto.CompletionChoiceMessage3_5; | ||
| 7 | +import com.zhonglai.luhui.openai.utils.SysConfigKeyType; | ||
| 8 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 9 | +import org.springframework.stereotype.Service; | ||
| 10 | +import org.springframework.web.bind.annotation.PostMapping; | ||
| 11 | + | ||
| 12 | +import javax.annotation.PostConstruct; | ||
| 13 | +import java.math.BigDecimal; | ||
| 14 | +import java.util.ArrayList; | ||
| 15 | +import java.util.List; | ||
| 16 | +import java.util.Map; | ||
| 17 | + | ||
| 18 | +/** | ||
| 19 | + * vip业务 | ||
| 20 | + */ | ||
| 21 | +@Service | ||
| 22 | +public class VipServiceImpl { | ||
| 23 | + | ||
| 24 | + @Autowired | ||
| 25 | + private PublicService publicService; | ||
| 26 | + | ||
| 27 | + private static List<Boolean> freeList = new ArrayList<>(); //是否免费 | ||
| 28 | + private static List<Boolean> chargingList = new ArrayList<>(); //是否计费 | ||
| 29 | + private static List<Boolean> timingList = new ArrayList<>(); //是否计计时 | ||
| 30 | + | ||
| 31 | + @PostConstruct | ||
| 32 | + public void init() | ||
| 33 | + { | ||
| 34 | + /** | ||
| 35 | + * vip0(试用用户默认有免费30000代币试用,调用的接口是免费接口响应慢可能会失败) | ||
| 36 | + * vip1(充值用户拥有代币充值记录的用户,调用的接口是免费接口响应慢可能会失败) | ||
| 37 | + * vip2(升级接口通道,按月支付。响应速度和成功率都有保证) | ||
| 38 | + * vip3(包月用户,使用vip2的接口) | ||
| 39 | + * vip4(包季,使用vip2的接口) | ||
| 40 | + * vip5(包年,使用vip2的接口) | ||
| 41 | + */ | ||
| 42 | + | ||
| 43 | + freeList.add(0,true); | ||
| 44 | + freeList.add(1,true); | ||
| 45 | + freeList.add(2,false); | ||
| 46 | + freeList.add(3,false); | ||
| 47 | + freeList.add(4,false); | ||
| 48 | + freeList.add(5,false); | ||
| 49 | + | ||
| 50 | + chargingList.add(0,true); | ||
| 51 | + chargingList.add(1,true); | ||
| 52 | + chargingList.add(2,false); | ||
| 53 | + chargingList.add(3,false); | ||
| 54 | + chargingList.add(4,false); | ||
| 55 | + chargingList.add(5,false); | ||
| 56 | + | ||
| 57 | + timingList.add(0,false); | ||
| 58 | + timingList.add(1,false); | ||
| 59 | + timingList.add(2,true); | ||
| 60 | + timingList.add(3,true); | ||
| 61 | + timingList.add(4,true); | ||
| 62 | + timingList.add(5,true); | ||
| 63 | + } | ||
| 64 | + public boolean isfree(Integer vipLevel) | ||
| 65 | + { | ||
| 66 | + return freeList.get(vipLevel); | ||
| 67 | + } | ||
| 68 | + public boolean isCharging(Integer vipLevel) | ||
| 69 | + { | ||
| 70 | + return chargingList.get(vipLevel); | ||
| 71 | + } | ||
| 72 | + public boolean isTiming(Integer vipLevel) | ||
| 73 | + { | ||
| 74 | + return timingList.get(vipLevel); | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + public BigDecimal[] getUnitprice() | ||
| 78 | + { | ||
| 79 | + List<Map<String,Object>> unitpriceList = publicService.getObjectListBySQL("select `key`,`value` from `lk_openai`.`sys_config` where `key_type`='"+ SysConfigKeyType.gpt_3_5_unitprice+"'"); | ||
| 80 | + BigDecimal openaiUnitprice = new BigDecimal(0); | ||
| 81 | + BigDecimal realityUnitprice = new BigDecimal(0); | ||
| 82 | + if(null != unitpriceList && unitpriceList.size() !=0) | ||
| 83 | + { | ||
| 84 | + for(Map<String,Object> map:unitpriceList) | ||
| 85 | + { | ||
| 86 | + if("openai".equals(map.get("key"))) | ||
| 87 | + { | ||
| 88 | + openaiUnitprice = new BigDecimal(map.get("value").toString()); | ||
| 89 | + }else if("reality".equals(map.get("key"))) | ||
| 90 | + { | ||
| 91 | + realityUnitprice = new BigDecimal(map.get("value").toString()); | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | + } | ||
| 95 | + return new BigDecimal[]{openaiUnitprice,realityUnitprice}; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | +} |
| 1 | -# 项目相关配置 jhlt: # 名称 name: zhonglai # 版本 version: 3.8.2 # 版权年份 copyrightYear: 2022 # 获取ip地址开关 addressEnabled: false # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8082 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Spring配置 spring: # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: druid # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # redis 配置 redis: # 地址 host: 47.112.163.61 # 端口,默认为6379 port: 9527 # 数据库索引 database: 1 # 密码 password: Luhui586 # 连接超时时间 timeout: 10s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 1440 rediskey: lh-openai # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* mqtt: client: device_life: 180 # NameServer地址 rocketmq: name-server: 47.115.144.179:9876 # 默认的消息组 producer: group: deviceCommand send-message-timeout: 30000 send-topic: lh-chat-gpt send-tags: 1 sys: ## // 对于登录login 注册register 验证码captchaImage 允许匿名访问 antMatchers: /login,/register,/captchaImage,/getCacheObject,/v2/api-docs,/chatgpt/aiChatbot,/chatgpt/chatgptV3_5, chatgpt: token: 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 timeout: 5000 | ||
| 1 | +# 项目相关配置 jhlt: # 名称 name: zhonglai # 版本 version: 3.8.2 # 版权年份 copyrightYear: 2022 # 获取ip地址开关 addressEnabled: false # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8082 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Spring配置 spring: # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: druid # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # redis 配置 redis: # 地址 host: 47.112.163.61 # 端口,默认为6379 port: 9527 # 数据库索引 database: 1 # 密码 password: Luhui586 # 连接超时时间 timeout: 10s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 1440 rediskey: lh-openai # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* mqtt: client: device_life: 180 # NameServer地址 rocketmq: name-server: 47.115.144.179:9876 # 默认的消息组 producer: group: deviceCommand send-message-timeout: 30000 send-topic: lh-chat-gpt send-tags: 1 sys: ## // 对于登录login 注册register 验证码captchaImage 允许匿名访问 antMatchers: /login,/register,/captchaImage,/getCacheObject,/v2/api-docs chatgpt: token: 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 timeout: 5000 |
lh-quartz/pom.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| 4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| 5 | + <parent> | ||
| 6 | + <groupId>com.zhonglai.luhui</groupId> | ||
| 7 | + <artifactId>Luhui</artifactId> | ||
| 8 | + <version>1.0-SNAPSHOT</version> | ||
| 9 | + </parent> | ||
| 10 | + <modelVersion>4.0.0</modelVersion> | ||
| 11 | + | ||
| 12 | + <artifactId>lh-quartz</artifactId> | ||
| 13 | + | ||
| 14 | + <description> | ||
| 15 | + quartz定时任务 | ||
| 16 | + </description> | ||
| 17 | + | ||
| 18 | + <dependencies> | ||
| 19 | + | ||
| 20 | + <!-- 定时任务 --> | ||
| 21 | + <dependency> | ||
| 22 | + <groupId>org.quartz-scheduler</groupId> | ||
| 23 | + <artifactId>quartz</artifactId> | ||
| 24 | + <exclusions> | ||
| 25 | + <exclusion> | ||
| 26 | + <groupId>com.mchange</groupId> | ||
| 27 | + <artifactId>c3p0</artifactId> | ||
| 28 | + </exclusion> | ||
| 29 | + </exclusions> | ||
| 30 | + </dependency> | ||
| 31 | + | ||
| 32 | + <!-- 通用工具--> | ||
| 33 | + <dependency> | ||
| 34 | + <groupId>com.zhonglai.luhui</groupId> | ||
| 35 | + <artifactId>ruoyi-common</artifactId> | ||
| 36 | + </dependency> | ||
| 37 | + | ||
| 38 | + </dependencies> | ||
| 39 | + | ||
| 40 | +</project> |
| 1 | +package com.ruoyi.quartz.config; | ||
| 2 | + | ||
| 3 | +import org.springframework.context.annotation.Bean; | ||
| 4 | +import org.springframework.context.annotation.Configuration; | ||
| 5 | +import org.springframework.scheduling.quartz.SchedulerFactoryBean; | ||
| 6 | +import javax.sql.DataSource; | ||
| 7 | +import java.util.Properties; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) | ||
| 11 | + * | ||
| 12 | + * @author ruoyi | ||
| 13 | + */ | ||
| 14 | +@Configuration | ||
| 15 | +public class ScheduleConfig | ||
| 16 | +{ | ||
| 17 | + @Bean | ||
| 18 | + public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) | ||
| 19 | + { | ||
| 20 | + SchedulerFactoryBean factory = new SchedulerFactoryBean(); | ||
| 21 | + factory.setDataSource(dataSource); | ||
| 22 | + | ||
| 23 | + // quartz参数 | ||
| 24 | + Properties prop = new Properties(); | ||
| 25 | + prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); | ||
| 26 | + prop.put("org.quartz.scheduler.instanceId", "AUTO"); | ||
| 27 | + // 线程池配置 | ||
| 28 | + prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); | ||
| 29 | + prop.put("org.quartz.threadPool.threadCount", "20"); | ||
| 30 | + prop.put("org.quartz.threadPool.threadPriority", "5"); | ||
| 31 | + // JobStore配置 | ||
| 32 | +// prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX"); | ||
| 33 | + // 集群配置 | ||
| 34 | + prop.put("org.quartz.jobStore.isClustered", "true"); | ||
| 35 | + prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); | ||
| 36 | + prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); | ||
| 37 | + prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); | ||
| 38 | + | ||
| 39 | + // sqlserver 启用 | ||
| 40 | + // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); | ||
| 41 | + prop.put("org.quartz.jobStore.misfireThreshold", "12000"); | ||
| 42 | + prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); | ||
| 43 | + factory.setQuartzProperties(prop); | ||
| 44 | + | ||
| 45 | + factory.setSchedulerName("RuoyiScheduler"); | ||
| 46 | + // 延时启动 | ||
| 47 | + factory.setStartupDelay(1); | ||
| 48 | + factory.setApplicationContextSchedulerContextKey("applicationContextKey"); | ||
| 49 | + // 可选,QuartzScheduler | ||
| 50 | + // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 | ||
| 51 | + factory.setOverwriteExistingJobs(true); | ||
| 52 | + // 设置自动启动,默认为true | ||
| 53 | + factory.setAutoStartup(true); | ||
| 54 | + | ||
| 55 | + return factory; | ||
| 56 | + } | ||
| 57 | +} |
| 1 | +package com.ruoyi.quartz.controller; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | +import javax.servlet.http.HttpServletResponse; | ||
| 5 | + | ||
| 6 | +import io.swagger.annotations.Api; | ||
| 7 | +import io.swagger.annotations.ApiOperation; | ||
| 8 | +import org.quartz.SchedulerException; | ||
| 9 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 10 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 11 | +import org.springframework.web.bind.annotation.DeleteMapping; | ||
| 12 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 13 | +import org.springframework.web.bind.annotation.PathVariable; | ||
| 14 | +import org.springframework.web.bind.annotation.PostMapping; | ||
| 15 | +import org.springframework.web.bind.annotation.PutMapping; | ||
| 16 | +import org.springframework.web.bind.annotation.RequestBody; | ||
| 17 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 18 | +import org.springframework.web.bind.annotation.RestController; | ||
| 19 | +import com.ruoyi.common.annotation.Log; | ||
| 20 | +import com.ruoyi.common.constant.Constants; | ||
| 21 | +import com.ruoyi.common.core.controller.BaseController; | ||
| 22 | +import com.ruoyi.common.core.domain.AjaxResult; | ||
| 23 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
| 24 | +import com.ruoyi.common.enums.BusinessType; | ||
| 25 | +import com.ruoyi.common.exception.job.TaskException; | ||
| 26 | +import com.ruoyi.common.utils.StringUtils; | ||
| 27 | +import com.ruoyi.common.utils.poi.ExcelUtil; | ||
| 28 | +import com.ruoyi.quartz.domain.SysJob; | ||
| 29 | +import com.ruoyi.quartz.service.ISysJobService; | ||
| 30 | +import com.ruoyi.quartz.util.CronUtils; | ||
| 31 | + | ||
| 32 | +/** | ||
| 33 | + * 调度任务信息操作处理 | ||
| 34 | + * | ||
| 35 | + * @author ruoyi | ||
| 36 | + */ | ||
| 37 | +@Api(tags = "调度任务信息操作处理") | ||
| 38 | +@RestController | ||
| 39 | +@RequestMapping("/monitor/job") | ||
| 40 | +public class SysJobController extends BaseController | ||
| 41 | +{ | ||
| 42 | + @Autowired | ||
| 43 | + private ISysJobService jobService; | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * 查询定时任务列表 | ||
| 47 | + */ | ||
| 48 | + @ApiOperation("查询定时任务列表") | ||
| 49 | + @PreAuthorize("@ss.hasPermi('monitor:job:list')") | ||
| 50 | + @GetMapping("/list") | ||
| 51 | + public TableDataInfo list(SysJob sysJob) | ||
| 52 | + { | ||
| 53 | + startPage(); | ||
| 54 | + List<SysJob> list = jobService.selectJobList(sysJob); | ||
| 55 | + return getDataTable(list); | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + /** | ||
| 59 | + * 导出定时任务列表 | ||
| 60 | + */ | ||
| 61 | + @ApiOperation("导出定时任务列表") | ||
| 62 | + @PreAuthorize("@ss.hasPermi('monitor:job:export')") | ||
| 63 | + @Log(title = "定时任务", businessType = BusinessType.EXPORT) | ||
| 64 | + @PostMapping("/export") | ||
| 65 | + public void export(HttpServletResponse response, SysJob sysJob) | ||
| 66 | + { | ||
| 67 | + List<SysJob> list = jobService.selectJobList(sysJob); | ||
| 68 | + ExcelUtil<SysJob> util = new ExcelUtil<SysJob>(SysJob.class); | ||
| 69 | + util.exportExcel(response, list, "定时任务"); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + /** | ||
| 73 | + * 获取定时任务详细信息 | ||
| 74 | + */ | ||
| 75 | + @ApiOperation("获取定时任务详细信息") | ||
| 76 | + @PreAuthorize("@ss.hasPermi('monitor:job:query')") | ||
| 77 | + @GetMapping(value = "/{jobId}") | ||
| 78 | + public AjaxResult getInfo(@PathVariable("jobId") Long jobId) | ||
| 79 | + { | ||
| 80 | + return AjaxResult.success(jobService.selectJobById(jobId)); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + /** | ||
| 84 | + * 新增定时任务 | ||
| 85 | + */ | ||
| 86 | + @ApiOperation("新增定时任务") | ||
| 87 | + @PreAuthorize("@ss.hasPermi('monitor:job:add')") | ||
| 88 | + @Log(title = "定时任务", businessType = BusinessType.INSERT) | ||
| 89 | + @PostMapping | ||
| 90 | + public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException | ||
| 91 | + { | ||
| 92 | + if (!CronUtils.isValid(job.getCronExpression())) | ||
| 93 | + { | ||
| 94 | + return error("新增任务'" + job.getJobName() + "'失败,Cron表达式不正确"); | ||
| 95 | + } | ||
| 96 | + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) | ||
| 97 | + { | ||
| 98 | + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi://'调用"); | ||
| 99 | + } | ||
| 100 | + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_LDAP)) | ||
| 101 | + { | ||
| 102 | + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap://'调用"); | ||
| 103 | + } | ||
| 104 | + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) | ||
| 105 | + { | ||
| 106 | + return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)//'调用"); | ||
| 107 | + } | ||
| 108 | + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) | ||
| 109 | + { | ||
| 110 | + return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规"); | ||
| 111 | + } | ||
| 112 | + job.setCreateBy(getUsername()); | ||
| 113 | + return toAjax(jobService.insertJob(job)); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + /** | ||
| 117 | + * 修改定时任务 | ||
| 118 | + */ | ||
| 119 | + @ApiOperation("修改定时任务") | ||
| 120 | + @PreAuthorize("@ss.hasPermi('monitor:job:edit')") | ||
| 121 | + @Log(title = "定时任务", businessType = BusinessType.UPDATE) | ||
| 122 | + @PutMapping | ||
| 123 | + public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException | ||
| 124 | + { | ||
| 125 | + if (!CronUtils.isValid(job.getCronExpression())) | ||
| 126 | + { | ||
| 127 | + return error("修改任务'" + job.getJobName() + "'失败,Cron表达式不正确"); | ||
| 128 | + } | ||
| 129 | + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) | ||
| 130 | + { | ||
| 131 | + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi://'调用"); | ||
| 132 | + } | ||
| 133 | + else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_LDAP)) | ||
| 134 | + { | ||
| 135 | + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap://'调用"); | ||
| 136 | + } | ||
| 137 | + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), new String[] { Constants.HTTP, Constants.HTTPS })) | ||
| 138 | + { | ||
| 139 | + return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)//'调用"); | ||
| 140 | + } | ||
| 141 | + else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) | ||
| 142 | + { | ||
| 143 | + return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规"); | ||
| 144 | + } | ||
| 145 | + job.setUpdateBy(getUsername()); | ||
| 146 | + return toAjax(jobService.updateJob(job)); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + /** | ||
| 150 | + * 定时任务状态修改 | ||
| 151 | + */ | ||
| 152 | + @ApiOperation("定时任务状态修改") | ||
| 153 | + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") | ||
| 154 | + @Log(title = "定时任务", businessType = BusinessType.UPDATE) | ||
| 155 | + @PutMapping("/changeStatus") | ||
| 156 | + public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException | ||
| 157 | + { | ||
| 158 | + SysJob newJob = jobService.selectJobById(job.getJobId()); | ||
| 159 | + newJob.setStatus(job.getStatus()); | ||
| 160 | + return toAjax(jobService.changeStatus(newJob)); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + /** | ||
| 164 | + * 定时任务立即执行一次 | ||
| 165 | + */ | ||
| 166 | + @ApiOperation("定时任务立即执行一次") | ||
| 167 | + @PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')") | ||
| 168 | + @Log(title = "定时任务", businessType = BusinessType.UPDATE) | ||
| 169 | + @PutMapping("/run") | ||
| 170 | + public AjaxResult run(@RequestBody SysJob job) throws SchedulerException | ||
| 171 | + { | ||
| 172 | + jobService.run(job); | ||
| 173 | + return AjaxResult.success(); | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + /** | ||
| 177 | + * 删除定时任务 | ||
| 178 | + */ | ||
| 179 | + @ApiOperation("删除定时任务") | ||
| 180 | + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") | ||
| 181 | + @Log(title = "定时任务", businessType = BusinessType.DELETE) | ||
| 182 | + @DeleteMapping("/{jobIds}") | ||
| 183 | + public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException | ||
| 184 | + { | ||
| 185 | + jobService.deleteJobByIds(jobIds); | ||
| 186 | + return AjaxResult.success(); | ||
| 187 | + } | ||
| 188 | +} |
| 1 | +package com.ruoyi.quartz.controller; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | +import javax.servlet.http.HttpServletResponse; | ||
| 5 | + | ||
| 6 | +import io.swagger.annotations.Api; | ||
| 7 | +import io.swagger.annotations.ApiOperation; | ||
| 8 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 9 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 10 | +import org.springframework.web.bind.annotation.DeleteMapping; | ||
| 11 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 12 | +import org.springframework.web.bind.annotation.PathVariable; | ||
| 13 | +import org.springframework.web.bind.annotation.PostMapping; | ||
| 14 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 15 | +import org.springframework.web.bind.annotation.RestController; | ||
| 16 | +import com.ruoyi.common.annotation.Log; | ||
| 17 | +import com.ruoyi.common.core.controller.BaseController; | ||
| 18 | +import com.ruoyi.common.core.domain.AjaxResult; | ||
| 19 | +import com.ruoyi.common.core.page.TableDataInfo; | ||
| 20 | +import com.ruoyi.common.enums.BusinessType; | ||
| 21 | +import com.ruoyi.common.utils.poi.ExcelUtil; | ||
| 22 | +import com.ruoyi.quartz.domain.SysJobLog; | ||
| 23 | +import com.ruoyi.quartz.service.ISysJobLogService; | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + * 调度日志操作处理 | ||
| 27 | + * | ||
| 28 | + * @author ruoyi | ||
| 29 | + */ | ||
| 30 | +@Api(tags = "调度日志操作处理") | ||
| 31 | +@RestController | ||
| 32 | +@RequestMapping("/monitor/jobLog") | ||
| 33 | +public class SysJobLogController extends BaseController | ||
| 34 | +{ | ||
| 35 | + @Autowired | ||
| 36 | + private ISysJobLogService jobLogService; | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 查询定时任务调度日志列表 | ||
| 40 | + */ | ||
| 41 | + @ApiOperation("查询定时任务调度日志列表") | ||
| 42 | + @PreAuthorize("@ss.hasPermi('monitor:job:list')") | ||
| 43 | + @GetMapping("/list") | ||
| 44 | + public TableDataInfo list(SysJobLog sysJobLog) | ||
| 45 | + { | ||
| 46 | + startPage(); | ||
| 47 | + List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog); | ||
| 48 | + return getDataTable(list); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * 导出定时任务调度日志列表 | ||
| 53 | + */ | ||
| 54 | + @ApiOperation("导出定时任务调度日志列表") | ||
| 55 | + @PreAuthorize("@ss.hasPermi('monitor:job:export')") | ||
| 56 | + @Log(title = "任务调度日志", businessType = BusinessType.EXPORT) | ||
| 57 | + @PostMapping("/export") | ||
| 58 | + public void export(HttpServletResponse response, SysJobLog sysJobLog) | ||
| 59 | + { | ||
| 60 | + List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog); | ||
| 61 | + ExcelUtil<SysJobLog> util = new ExcelUtil<SysJobLog>(SysJobLog.class); | ||
| 62 | + util.exportExcel(response, list, "调度日志"); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * 根据调度编号获取详细信息 | ||
| 67 | + */ | ||
| 68 | + @ApiOperation("根据调度编号获取详细信息") | ||
| 69 | + @PreAuthorize("@ss.hasPermi('monitor:job:query')") | ||
| 70 | + @GetMapping(value = "/{configId}") | ||
| 71 | + public AjaxResult getInfo(@PathVariable Long jobLogId) | ||
| 72 | + { | ||
| 73 | + return AjaxResult.success(jobLogService.selectJobLogById(jobLogId)); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * 删除定时任务调度日志 | ||
| 79 | + */ | ||
| 80 | + @ApiOperation("删除定时任务调度日志") | ||
| 81 | + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") | ||
| 82 | + @Log(title = "定时任务调度日志", businessType = BusinessType.DELETE) | ||
| 83 | + @DeleteMapping("/{jobLogIds}") | ||
| 84 | + public AjaxResult remove(@PathVariable Long[] jobLogIds) | ||
| 85 | + { | ||
| 86 | + return toAjax(jobLogService.deleteJobLogByIds(jobLogIds)); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + /** | ||
| 90 | + * 清空定时任务调度日志 | ||
| 91 | + */ | ||
| 92 | + @ApiOperation("清空定时任务调度日志") | ||
| 93 | + @PreAuthorize("@ss.hasPermi('monitor:job:remove')") | ||
| 94 | + @Log(title = "调度日志", businessType = BusinessType.CLEAN) | ||
| 95 | + @DeleteMapping("/clean") | ||
| 96 | + public AjaxResult clean() | ||
| 97 | + { | ||
| 98 | + jobLogService.cleanJobLog(); | ||
| 99 | + return AjaxResult.success(); | ||
| 100 | + } | ||
| 101 | +} |
| 1 | +package com.ruoyi.quartz.domain; | ||
| 2 | + | ||
| 3 | +import java.util.Date; | ||
| 4 | +import javax.validation.constraints.NotBlank; | ||
| 5 | +import javax.validation.constraints.Size; | ||
| 6 | + | ||
| 7 | +import com.ruoyi.system.domain.tool.BaseEntity; | ||
| 8 | +import org.apache.commons.lang3.builder.ToStringBuilder; | ||
| 9 | +import org.apache.commons.lang3.builder.ToStringStyle; | ||
| 10 | +import com.fasterxml.jackson.annotation.JsonFormat; | ||
| 11 | +import com.ruoyi.common.annotation.Excel; | ||
| 12 | +import com.ruoyi.common.annotation.Excel.ColumnType; | ||
| 13 | +import com.ruoyi.common.constant.ScheduleConstants; | ||
| 14 | +import com.ruoyi.common.utils.StringUtils; | ||
| 15 | +import com.ruoyi.quartz.util.CronUtils; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * 定时任务调度表 sys_job | ||
| 19 | + * | ||
| 20 | + * @author ruoyi | ||
| 21 | + */ | ||
| 22 | +public class SysJob extends BaseEntity | ||
| 23 | +{ | ||
| 24 | + private static final long serialVersionUID = 1L; | ||
| 25 | + | ||
| 26 | + /** 任务ID */ | ||
| 27 | + @Excel(name = "任务序号", cellType = ColumnType.NUMERIC) | ||
| 28 | + private Long jobId; | ||
| 29 | + | ||
| 30 | + /** 任务名称 */ | ||
| 31 | + @Excel(name = "任务名称") | ||
| 32 | + private String jobName; | ||
| 33 | + | ||
| 34 | + /** 任务组名 */ | ||
| 35 | + @Excel(name = "任务组名") | ||
| 36 | + private String jobGroup; | ||
| 37 | + | ||
| 38 | + /** 调用目标字符串 */ | ||
| 39 | + @Excel(name = "调用目标字符串") | ||
| 40 | + private String invokeTarget; | ||
| 41 | + | ||
| 42 | + /** cron执行表达式 */ | ||
| 43 | + @Excel(name = "执行表达式 ") | ||
| 44 | + private String cronExpression; | ||
| 45 | + | ||
| 46 | + /** cron计划策略 */ | ||
| 47 | + @Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行") | ||
| 48 | + private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT; | ||
| 49 | + | ||
| 50 | + /** 是否并发执行(0允许 1禁止) */ | ||
| 51 | + @Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止") | ||
| 52 | + private String concurrent; | ||
| 53 | + | ||
| 54 | + /** 任务状态(0正常 1暂停) */ | ||
| 55 | + @Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停") | ||
| 56 | + private String status; | ||
| 57 | + | ||
| 58 | + public Long getJobId() | ||
| 59 | + { | ||
| 60 | + return jobId; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + public void setJobId(Long jobId) | ||
| 64 | + { | ||
| 65 | + this.jobId = jobId; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + @NotBlank(message = "任务名称不能为空") | ||
| 69 | + @Size(min = 0, max = 64, message = "任务名称不能超过64个字符") | ||
| 70 | + public String getJobName() | ||
| 71 | + { | ||
| 72 | + return jobName; | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + public void setJobName(String jobName) | ||
| 76 | + { | ||
| 77 | + this.jobName = jobName; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + public String getJobGroup() | ||
| 81 | + { | ||
| 82 | + return jobGroup; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + public void setJobGroup(String jobGroup) | ||
| 86 | + { | ||
| 87 | + this.jobGroup = jobGroup; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + @NotBlank(message = "调用目标字符串不能为空") | ||
| 91 | + @Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符") | ||
| 92 | + public String getInvokeTarget() | ||
| 93 | + { | ||
| 94 | + return invokeTarget; | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + public void setInvokeTarget(String invokeTarget) | ||
| 98 | + { | ||
| 99 | + this.invokeTarget = invokeTarget; | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + @NotBlank(message = "Cron执行表达式不能为空") | ||
| 103 | + @Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符") | ||
| 104 | + public String getCronExpression() | ||
| 105 | + { | ||
| 106 | + return cronExpression; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + public void setCronExpression(String cronExpression) | ||
| 110 | + { | ||
| 111 | + this.cronExpression = cronExpression; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") | ||
| 115 | + public Date getNextValidTime() | ||
| 116 | + { | ||
| 117 | + if (StringUtils.isNotEmpty(cronExpression)) | ||
| 118 | + { | ||
| 119 | + return CronUtils.getNextExecution(cronExpression); | ||
| 120 | + } | ||
| 121 | + return null; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + public String getMisfirePolicy() | ||
| 125 | + { | ||
| 126 | + return misfirePolicy; | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + public void setMisfirePolicy(String misfirePolicy) | ||
| 130 | + { | ||
| 131 | + this.misfirePolicy = misfirePolicy; | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + public String getConcurrent() | ||
| 135 | + { | ||
| 136 | + return concurrent; | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + public void setConcurrent(String concurrent) | ||
| 140 | + { | ||
| 141 | + this.concurrent = concurrent; | ||
| 142 | + } | ||
| 143 | + | ||
| 144 | + public String getStatus() | ||
| 145 | + { | ||
| 146 | + return status; | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + public void setStatus(String status) | ||
| 150 | + { | ||
| 151 | + this.status = status; | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + @Override | ||
| 155 | + public String toString() { | ||
| 156 | + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) | ||
| 157 | + .append("jobId", getJobId()) | ||
| 158 | + .append("jobName", getJobName()) | ||
| 159 | + .append("jobGroup", getJobGroup()) | ||
| 160 | + .append("cronExpression", getCronExpression()) | ||
| 161 | + .append("nextValidTime", getNextValidTime()) | ||
| 162 | + .append("misfirePolicy", getMisfirePolicy()) | ||
| 163 | + .append("concurrent", getConcurrent()) | ||
| 164 | + .append("status", getStatus()) | ||
| 165 | + .append("createBy", getCreateBy()) | ||
| 166 | + .append("createTime", getCreateTime()) | ||
| 167 | + .append("updateBy", getUpdateBy()) | ||
| 168 | + .append("updateTime", getUpdateTime()) | ||
| 169 | + .append("remark", getRemark()) | ||
| 170 | + .toString(); | ||
| 171 | + } | ||
| 172 | +} |
| 1 | +package com.ruoyi.quartz.domain; | ||
| 2 | + | ||
| 3 | +import java.util.Date; | ||
| 4 | + | ||
| 5 | +import com.ruoyi.system.domain.tool.BaseEntity; | ||
| 6 | +import org.apache.commons.lang3.builder.ToStringBuilder; | ||
| 7 | +import org.apache.commons.lang3.builder.ToStringStyle; | ||
| 8 | +import com.ruoyi.common.annotation.Excel; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 定时任务调度日志表 sys_job_log | ||
| 12 | + * | ||
| 13 | + * @author ruoyi | ||
| 14 | + */ | ||
| 15 | +public class SysJobLog extends BaseEntity | ||
| 16 | +{ | ||
| 17 | + private static final long serialVersionUID = 1L; | ||
| 18 | + | ||
| 19 | + /** ID */ | ||
| 20 | + @Excel(name = "日志序号") | ||
| 21 | + private Long jobLogId; | ||
| 22 | + | ||
| 23 | + /** 任务名称 */ | ||
| 24 | + @Excel(name = "任务名称") | ||
| 25 | + private String jobName; | ||
| 26 | + | ||
| 27 | + /** 任务组名 */ | ||
| 28 | + @Excel(name = "任务组名") | ||
| 29 | + private String jobGroup; | ||
| 30 | + | ||
| 31 | + /** 调用目标字符串 */ | ||
| 32 | + @Excel(name = "调用目标字符串") | ||
| 33 | + private String invokeTarget; | ||
| 34 | + | ||
| 35 | + /** 日志信息 */ | ||
| 36 | + @Excel(name = "日志信息") | ||
| 37 | + private String jobMessage; | ||
| 38 | + | ||
| 39 | + /** 执行状态(0正常 1失败) */ | ||
| 40 | + @Excel(name = "执行状态", readConverterExp = "0=正常,1=失败") | ||
| 41 | + private String status; | ||
| 42 | + | ||
| 43 | + /** 异常信息 */ | ||
| 44 | + @Excel(name = "异常信息") | ||
| 45 | + private String exceptionInfo; | ||
| 46 | + | ||
| 47 | + /** 开始时间 */ | ||
| 48 | + private Date startTime; | ||
| 49 | + | ||
| 50 | + /** 停止时间 */ | ||
| 51 | + private Date stopTime; | ||
| 52 | + | ||
| 53 | + public Long getJobLogId() | ||
| 54 | + { | ||
| 55 | + return jobLogId; | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + public void setJobLogId(Long jobLogId) | ||
| 59 | + { | ||
| 60 | + this.jobLogId = jobLogId; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + public String getJobName() | ||
| 64 | + { | ||
| 65 | + return jobName; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + public void setJobName(String jobName) | ||
| 69 | + { | ||
| 70 | + this.jobName = jobName; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + public String getJobGroup() | ||
| 74 | + { | ||
| 75 | + return jobGroup; | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + public void setJobGroup(String jobGroup) | ||
| 79 | + { | ||
| 80 | + this.jobGroup = jobGroup; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + public String getInvokeTarget() | ||
| 84 | + { | ||
| 85 | + return invokeTarget; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + public void setInvokeTarget(String invokeTarget) | ||
| 89 | + { | ||
| 90 | + this.invokeTarget = invokeTarget; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + public String getJobMessage() | ||
| 94 | + { | ||
| 95 | + return jobMessage; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + public void setJobMessage(String jobMessage) | ||
| 99 | + { | ||
| 100 | + this.jobMessage = jobMessage; | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + public String getStatus() | ||
| 104 | + { | ||
| 105 | + return status; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + public void setStatus(String status) | ||
| 109 | + { | ||
| 110 | + this.status = status; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + public String getExceptionInfo() | ||
| 114 | + { | ||
| 115 | + return exceptionInfo; | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + public void setExceptionInfo(String exceptionInfo) | ||
| 119 | + { | ||
| 120 | + this.exceptionInfo = exceptionInfo; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + public Date getStartTime() | ||
| 124 | + { | ||
| 125 | + return startTime; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + public void setStartTime(Date startTime) | ||
| 129 | + { | ||
| 130 | + this.startTime = startTime; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + public Date getStopTime() | ||
| 134 | + { | ||
| 135 | + return stopTime; | ||
| 136 | + } | ||
| 137 | + | ||
| 138 | + public void setStopTime(Date stopTime) | ||
| 139 | + { | ||
| 140 | + this.stopTime = stopTime; | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + @Override | ||
| 144 | + public String toString() { | ||
| 145 | + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) | ||
| 146 | + .append("jobLogId", getJobLogId()) | ||
| 147 | + .append("jobName", getJobName()) | ||
| 148 | + .append("jobGroup", getJobGroup()) | ||
| 149 | + .append("jobMessage", getJobMessage()) | ||
| 150 | + .append("status", getStatus()) | ||
| 151 | + .append("exceptionInfo", getExceptionInfo()) | ||
| 152 | + .append("startTime", getStartTime()) | ||
| 153 | + .append("stopTime", getStopTime()) | ||
| 154 | + .toString(); | ||
| 155 | + } | ||
| 156 | +} |
| 1 | +package com.ruoyi.quartz.mapper; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | +import com.ruoyi.quartz.domain.SysJobLog; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 调度任务日志信息 数据层 | ||
| 8 | + * | ||
| 9 | + * @author ruoyi | ||
| 10 | + */ | ||
| 11 | +public interface SysJobLogMapper | ||
| 12 | +{ | ||
| 13 | + /** | ||
| 14 | + * 获取quartz调度器日志的计划任务 | ||
| 15 | + * | ||
| 16 | + * @param jobLog 调度日志信息 | ||
| 17 | + * @return 调度任务日志集合 | ||
| 18 | + */ | ||
| 19 | + public List<SysJobLog> selectJobLogList(SysJobLog jobLog); | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * 查询所有调度任务日志 | ||
| 23 | + * | ||
| 24 | + * @return 调度任务日志列表 | ||
| 25 | + */ | ||
| 26 | + public List<SysJobLog> selectJobLogAll(); | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * 通过调度任务日志ID查询调度信息 | ||
| 30 | + * | ||
| 31 | + * @param jobLogId 调度任务日志ID | ||
| 32 | + * @return 调度任务日志对象信息 | ||
| 33 | + */ | ||
| 34 | + public SysJobLog selectJobLogById(Long jobLogId); | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * 新增任务日志 | ||
| 38 | + * | ||
| 39 | + * @param jobLog 调度日志信息 | ||
| 40 | + * @return 结果 | ||
| 41 | + */ | ||
| 42 | + public int insertJobLog(SysJobLog jobLog); | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * 批量删除调度日志信息 | ||
| 46 | + * | ||
| 47 | + * @param logIds 需要删除的数据ID | ||
| 48 | + * @return 结果 | ||
| 49 | + */ | ||
| 50 | + public int deleteJobLogByIds(Long[] logIds); | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * 删除任务日志 | ||
| 54 | + * | ||
| 55 | + * @param jobId 调度日志ID | ||
| 56 | + * @return 结果 | ||
| 57 | + */ | ||
| 58 | + public int deleteJobLogById(Long jobId); | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * 清空任务日志 | ||
| 62 | + */ | ||
| 63 | + public void cleanJobLog(); | ||
| 64 | +} |
| 1 | +package com.ruoyi.quartz.mapper; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | +import com.ruoyi.quartz.domain.SysJob; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 调度任务信息 数据层 | ||
| 8 | + * | ||
| 9 | + * @author ruoyi | ||
| 10 | + */ | ||
| 11 | +public interface SysJobMapper | ||
| 12 | +{ | ||
| 13 | + /** | ||
| 14 | + * 查询调度任务日志集合 | ||
| 15 | + * | ||
| 16 | + * @param job 调度信息 | ||
| 17 | + * @return 操作日志集合 | ||
| 18 | + */ | ||
| 19 | + public List<SysJob> selectJobList(SysJob job); | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * 查询所有调度任务 | ||
| 23 | + * | ||
| 24 | + * @return 调度任务列表 | ||
| 25 | + */ | ||
| 26 | + public List<SysJob> selectJobAll(); | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * 通过调度ID查询调度任务信息 | ||
| 30 | + * | ||
| 31 | + * @param jobId 调度ID | ||
| 32 | + * @return 角色对象信息 | ||
| 33 | + */ | ||
| 34 | + public SysJob selectJobById(Long jobId); | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * 通过调度ID删除调度任务信息 | ||
| 38 | + * | ||
| 39 | + * @param jobId 调度ID | ||
| 40 | + * @return 结果 | ||
| 41 | + */ | ||
| 42 | + public int deleteJobById(Long jobId); | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * 批量删除调度任务信息 | ||
| 46 | + * | ||
| 47 | + * @param ids 需要删除的数据ID | ||
| 48 | + * @return 结果 | ||
| 49 | + */ | ||
| 50 | + public int deleteJobByIds(Long[] ids); | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * 修改调度任务信息 | ||
| 54 | + * | ||
| 55 | + * @param job 调度任务信息 | ||
| 56 | + * @return 结果 | ||
| 57 | + */ | ||
| 58 | + public int updateJob(SysJob job); | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * 新增调度任务信息 | ||
| 62 | + * | ||
| 63 | + * @param job 调度任务信息 | ||
| 64 | + * @return 结果 | ||
| 65 | + */ | ||
| 66 | + public int insertJob(SysJob job); | ||
| 67 | +} |
| 1 | +package com.ruoyi.quartz.service; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | +import com.ruoyi.quartz.domain.SysJobLog; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 定时任务调度日志信息信息 服务层 | ||
| 8 | + * | ||
| 9 | + * @author ruoyi | ||
| 10 | + */ | ||
| 11 | +public interface ISysJobLogService | ||
| 12 | +{ | ||
| 13 | + /** | ||
| 14 | + * 获取quartz调度器日志的计划任务 | ||
| 15 | + * | ||
| 16 | + * @param jobLog 调度日志信息 | ||
| 17 | + * @return 调度任务日志集合 | ||
| 18 | + */ | ||
| 19 | + public List<SysJobLog> selectJobLogList(SysJobLog jobLog); | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * 通过调度任务日志ID查询调度信息 | ||
| 23 | + * | ||
| 24 | + * @param jobLogId 调度任务日志ID | ||
| 25 | + * @return 调度任务日志对象信息 | ||
| 26 | + */ | ||
| 27 | + public SysJobLog selectJobLogById(Long jobLogId); | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * 新增任务日志 | ||
| 31 | + * | ||
| 32 | + * @param jobLog 调度日志信息 | ||
| 33 | + */ | ||
| 34 | + public void addJobLog(SysJobLog jobLog); | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * 批量删除调度日志信息 | ||
| 38 | + * | ||
| 39 | + * @param logIds 需要删除的日志ID | ||
| 40 | + * @return 结果 | ||
| 41 | + */ | ||
| 42 | + public int deleteJobLogByIds(Long[] logIds); | ||
| 43 | + | ||
| 44 | + /** | ||
| 45 | + * 删除任务日志 | ||
| 46 | + * | ||
| 47 | + * @param jobId 调度日志ID | ||
| 48 | + * @return 结果 | ||
| 49 | + */ | ||
| 50 | + public int deleteJobLogById(Long jobId); | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * 清空任务日志 | ||
| 54 | + */ | ||
| 55 | + public void cleanJobLog(); | ||
| 56 | +} |
| 1 | +package com.ruoyi.quartz.service; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | +import org.quartz.SchedulerException; | ||
| 5 | +import com.ruoyi.common.exception.job.TaskException; | ||
| 6 | +import com.ruoyi.quartz.domain.SysJob; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * 定时任务调度信息信息 服务层 | ||
| 10 | + * | ||
| 11 | + * @author ruoyi | ||
| 12 | + */ | ||
| 13 | +public interface ISysJobService | ||
| 14 | +{ | ||
| 15 | + /** | ||
| 16 | + * 获取quartz调度器的计划任务 | ||
| 17 | + * | ||
| 18 | + * @param job 调度信息 | ||
| 19 | + * @return 调度任务集合 | ||
| 20 | + */ | ||
| 21 | + public List<SysJob> selectJobList(SysJob job); | ||
| 22 | + | ||
| 23 | + /** | ||
| 24 | + * 通过调度任务ID查询调度信息 | ||
| 25 | + * | ||
| 26 | + * @param jobId 调度任务ID | ||
| 27 | + * @return 调度任务对象信息 | ||
| 28 | + */ | ||
| 29 | + public SysJob selectJobById(Long jobId); | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * 暂停任务 | ||
| 33 | + * | ||
| 34 | + * @param job 调度信息 | ||
| 35 | + * @return 结果 | ||
| 36 | + */ | ||
| 37 | + public int pauseJob(SysJob job) throws SchedulerException; | ||
| 38 | + | ||
| 39 | + /** | ||
| 40 | + * 恢复任务 | ||
| 41 | + * | ||
| 42 | + * @param job 调度信息 | ||
| 43 | + * @return 结果 | ||
| 44 | + */ | ||
| 45 | + public int resumeJob(SysJob job) throws SchedulerException; | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * 删除任务后,所对应的trigger也将被删除 | ||
| 49 | + * | ||
| 50 | + * @param job 调度信息 | ||
| 51 | + * @return 结果 | ||
| 52 | + */ | ||
| 53 | + public int deleteJob(SysJob job) throws SchedulerException; | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * 批量删除调度信息 | ||
| 57 | + * | ||
| 58 | + * @param jobIds 需要删除的任务ID | ||
| 59 | + * @return 结果 | ||
| 60 | + */ | ||
| 61 | + public void deleteJobByIds(Long[] jobIds) throws SchedulerException; | ||
| 62 | + | ||
| 63 | + /** | ||
| 64 | + * 任务调度状态修改 | ||
| 65 | + * | ||
| 66 | + * @param job 调度信息 | ||
| 67 | + * @return 结果 | ||
| 68 | + */ | ||
| 69 | + public int changeStatus(SysJob job) throws SchedulerException; | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * 立即运行任务 | ||
| 73 | + * | ||
| 74 | + * @param job 调度信息 | ||
| 75 | + * @return 结果 | ||
| 76 | + */ | ||
| 77 | + public void run(SysJob job) throws SchedulerException; | ||
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * 新增任务 | ||
| 81 | + * | ||
| 82 | + * @param job 调度信息 | ||
| 83 | + * @return 结果 | ||
| 84 | + */ | ||
| 85 | + public int insertJob(SysJob job) throws SchedulerException, TaskException; | ||
| 86 | + | ||
| 87 | + /** | ||
| 88 | + * 更新任务 | ||
| 89 | + * | ||
| 90 | + * @param job 调度信息 | ||
| 91 | + * @return 结果 | ||
| 92 | + */ | ||
| 93 | + public int updateJob(SysJob job) throws SchedulerException, TaskException; | ||
| 94 | + | ||
| 95 | + /** | ||
| 96 | + * 校验cron表达式是否有效 | ||
| 97 | + * | ||
| 98 | + * @param cronExpression 表达式 | ||
| 99 | + * @return 结果 | ||
| 100 | + */ | ||
| 101 | + public boolean checkCronExpressionIsValid(String cronExpression); | ||
| 102 | +} |
| 1 | +package com.ruoyi.quartz.service.impl; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 5 | +import org.springframework.stereotype.Service; | ||
| 6 | +import com.ruoyi.quartz.domain.SysJobLog; | ||
| 7 | +import com.ruoyi.quartz.mapper.SysJobLogMapper; | ||
| 8 | +import com.ruoyi.quartz.service.ISysJobLogService; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 定时任务调度日志信息 服务层 | ||
| 12 | + * | ||
| 13 | + * @author ruoyi | ||
| 14 | + */ | ||
| 15 | +@Service | ||
| 16 | +public class SysJobLogServiceImpl implements ISysJobLogService | ||
| 17 | +{ | ||
| 18 | + @Autowired | ||
| 19 | + private SysJobLogMapper jobLogMapper; | ||
| 20 | + | ||
| 21 | + /** | ||
| 22 | + * 获取quartz调度器日志的计划任务 | ||
| 23 | + * | ||
| 24 | + * @param jobLog 调度日志信息 | ||
| 25 | + * @return 调度任务日志集合 | ||
| 26 | + */ | ||
| 27 | + @Override | ||
| 28 | + public List<SysJobLog> selectJobLogList(SysJobLog jobLog) | ||
| 29 | + { | ||
| 30 | + return jobLogMapper.selectJobLogList(jobLog); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * 通过调度任务日志ID查询调度信息 | ||
| 35 | + * | ||
| 36 | + * @param jobLogId 调度任务日志ID | ||
| 37 | + * @return 调度任务日志对象信息 | ||
| 38 | + */ | ||
| 39 | + @Override | ||
| 40 | + public SysJobLog selectJobLogById(Long jobLogId) | ||
| 41 | + { | ||
| 42 | + return jobLogMapper.selectJobLogById(jobLogId); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * 新增任务日志 | ||
| 47 | + * | ||
| 48 | + * @param jobLog 调度日志信息 | ||
| 49 | + */ | ||
| 50 | + @Override | ||
| 51 | + public void addJobLog(SysJobLog jobLog) | ||
| 52 | + { | ||
| 53 | + jobLogMapper.insertJobLog(jobLog); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + /** | ||
| 57 | + * 批量删除调度日志信息 | ||
| 58 | + * | ||
| 59 | + * @param logIds 需要删除的数据ID | ||
| 60 | + * @return 结果 | ||
| 61 | + */ | ||
| 62 | + @Override | ||
| 63 | + public int deleteJobLogByIds(Long[] logIds) | ||
| 64 | + { | ||
| 65 | + return jobLogMapper.deleteJobLogByIds(logIds); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + /** | ||
| 69 | + * 删除任务日志 | ||
| 70 | + * | ||
| 71 | + * @param jobId 调度日志ID | ||
| 72 | + */ | ||
| 73 | + @Override | ||
| 74 | + public int deleteJobLogById(Long jobId) | ||
| 75 | + { | ||
| 76 | + return jobLogMapper.deleteJobLogById(jobId); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * 清空任务日志 | ||
| 81 | + */ | ||
| 82 | + @Override | ||
| 83 | + public void cleanJobLog() | ||
| 84 | + { | ||
| 85 | + jobLogMapper.cleanJobLog(); | ||
| 86 | + } | ||
| 87 | +} |
| 1 | +package com.ruoyi.quartz.service.impl; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | +import javax.annotation.PostConstruct; | ||
| 5 | +import org.quartz.JobDataMap; | ||
| 6 | +import org.quartz.JobKey; | ||
| 7 | +import org.quartz.Scheduler; | ||
| 8 | +import org.quartz.SchedulerException; | ||
| 9 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 10 | +import org.springframework.stereotype.Service; | ||
| 11 | +import org.springframework.transaction.annotation.Transactional; | ||
| 12 | +import com.ruoyi.common.constant.ScheduleConstants; | ||
| 13 | +import com.ruoyi.common.exception.job.TaskException; | ||
| 14 | +import com.ruoyi.quartz.domain.SysJob; | ||
| 15 | +import com.ruoyi.quartz.mapper.SysJobMapper; | ||
| 16 | +import com.ruoyi.quartz.service.ISysJobService; | ||
| 17 | +import com.ruoyi.quartz.util.CronUtils; | ||
| 18 | +import com.ruoyi.quartz.util.ScheduleUtils; | ||
| 19 | + | ||
| 20 | +/** | ||
| 21 | + * 定时任务调度信息 服务层 | ||
| 22 | + * | ||
| 23 | + * @author ruoyi | ||
| 24 | + */ | ||
| 25 | +@Service | ||
| 26 | +public class SysJobServiceImpl implements ISysJobService | ||
| 27 | +{ | ||
| 28 | + @Autowired | ||
| 29 | + private Scheduler scheduler; | ||
| 30 | + | ||
| 31 | + @Autowired | ||
| 32 | + private SysJobMapper jobMapper; | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理(注:不能手动修改数据库ID和任务组名,否则会导致脏数据) | ||
| 36 | + */ | ||
| 37 | + @PostConstruct | ||
| 38 | + public void init() throws SchedulerException, TaskException | ||
| 39 | + { | ||
| 40 | + scheduler.clear(); | ||
| 41 | + List<SysJob> jobList = jobMapper.selectJobAll(); | ||
| 42 | + for (SysJob job : jobList) | ||
| 43 | + { | ||
| 44 | + ScheduleUtils.createScheduleJob(scheduler, job); | ||
| 45 | + } | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + /** | ||
| 49 | + * 获取quartz调度器的计划任务列表 | ||
| 50 | + * | ||
| 51 | + * @param job 调度信息 | ||
| 52 | + * @return | ||
| 53 | + */ | ||
| 54 | + @Override | ||
| 55 | + public List<SysJob> selectJobList(SysJob job) | ||
| 56 | + { | ||
| 57 | + return jobMapper.selectJobList(job); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + /** | ||
| 61 | + * 通过调度任务ID查询调度信息 | ||
| 62 | + * | ||
| 63 | + * @param jobId 调度任务ID | ||
| 64 | + * @return 调度任务对象信息 | ||
| 65 | + */ | ||
| 66 | + @Override | ||
| 67 | + public SysJob selectJobById(Long jobId) | ||
| 68 | + { | ||
| 69 | + return jobMapper.selectJobById(jobId); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + /** | ||
| 73 | + * 暂停任务 | ||
| 74 | + * | ||
| 75 | + * @param job 调度信息 | ||
| 76 | + */ | ||
| 77 | + @Override | ||
| 78 | + @Transactional(rollbackFor = Exception.class) | ||
| 79 | + public int pauseJob(SysJob job) throws SchedulerException | ||
| 80 | + { | ||
| 81 | + Long jobId = job.getJobId(); | ||
| 82 | + String jobGroup = job.getJobGroup(); | ||
| 83 | + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); | ||
| 84 | + int rows = jobMapper.updateJob(job); | ||
| 85 | + if (rows > 0) | ||
| 86 | + { | ||
| 87 | + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); | ||
| 88 | + } | ||
| 89 | + return rows; | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + /** | ||
| 93 | + * 恢复任务 | ||
| 94 | + * | ||
| 95 | + * @param job 调度信息 | ||
| 96 | + */ | ||
| 97 | + @Override | ||
| 98 | + @Transactional(rollbackFor = Exception.class) | ||
| 99 | + public int resumeJob(SysJob job) throws SchedulerException | ||
| 100 | + { | ||
| 101 | + Long jobId = job.getJobId(); | ||
| 102 | + String jobGroup = job.getJobGroup(); | ||
| 103 | + job.setStatus(ScheduleConstants.Status.NORMAL.getValue()); | ||
| 104 | + int rows = jobMapper.updateJob(job); | ||
| 105 | + if (rows > 0) | ||
| 106 | + { | ||
| 107 | + scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup)); | ||
| 108 | + } | ||
| 109 | + return rows; | ||
| 110 | + } | ||
| 111 | + | ||
| 112 | + /** | ||
| 113 | + * 删除任务后,所对应的trigger也将被删除 | ||
| 114 | + * | ||
| 115 | + * @param job 调度信息 | ||
| 116 | + */ | ||
| 117 | + @Override | ||
| 118 | + @Transactional(rollbackFor = Exception.class) | ||
| 119 | + public int deleteJob(SysJob job) throws SchedulerException | ||
| 120 | + { | ||
| 121 | + Long jobId = job.getJobId(); | ||
| 122 | + String jobGroup = job.getJobGroup(); | ||
| 123 | + int rows = jobMapper.deleteJobById(jobId); | ||
| 124 | + if (rows > 0) | ||
| 125 | + { | ||
| 126 | + scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup)); | ||
| 127 | + } | ||
| 128 | + return rows; | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + /** | ||
| 132 | + * 批量删除调度信息 | ||
| 133 | + * | ||
| 134 | + * @param jobIds 需要删除的任务ID | ||
| 135 | + * @return 结果 | ||
| 136 | + */ | ||
| 137 | + @Override | ||
| 138 | + @Transactional(rollbackFor = Exception.class) | ||
| 139 | + public void deleteJobByIds(Long[] jobIds) throws SchedulerException | ||
| 140 | + { | ||
| 141 | + for (Long jobId : jobIds) | ||
| 142 | + { | ||
| 143 | + SysJob job = jobMapper.selectJobById(jobId); | ||
| 144 | + deleteJob(job); | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + /** | ||
| 149 | + * 任务调度状态修改 | ||
| 150 | + * | ||
| 151 | + * @param job 调度信息 | ||
| 152 | + */ | ||
| 153 | + @Override | ||
| 154 | + @Transactional(rollbackFor = Exception.class) | ||
| 155 | + public int changeStatus(SysJob job) throws SchedulerException | ||
| 156 | + { | ||
| 157 | + int rows = 0; | ||
| 158 | + String status = job.getStatus(); | ||
| 159 | + if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) | ||
| 160 | + { | ||
| 161 | + rows = resumeJob(job); | ||
| 162 | + } | ||
| 163 | + else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) | ||
| 164 | + { | ||
| 165 | + rows = pauseJob(job); | ||
| 166 | + } | ||
| 167 | + return rows; | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + /** | ||
| 171 | + * 立即运行任务 | ||
| 172 | + * | ||
| 173 | + * @param job 调度信息 | ||
| 174 | + */ | ||
| 175 | + @Override | ||
| 176 | + @Transactional(rollbackFor = Exception.class) | ||
| 177 | + public void run(SysJob job) throws SchedulerException | ||
| 178 | + { | ||
| 179 | + Long jobId = job.getJobId(); | ||
| 180 | + String jobGroup = job.getJobGroup(); | ||
| 181 | + SysJob properties = selectJobById(job.getJobId()); | ||
| 182 | + // 参数 | ||
| 183 | + JobDataMap dataMap = new JobDataMap(); | ||
| 184 | + dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties); | ||
| 185 | + scheduler.triggerJob(ScheduleUtils.getJobKey(jobId, jobGroup), dataMap); | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + /** | ||
| 189 | + * 新增任务 | ||
| 190 | + * | ||
| 191 | + * @param job 调度信息 调度信息 | ||
| 192 | + */ | ||
| 193 | + @Override | ||
| 194 | + @Transactional(rollbackFor = Exception.class) | ||
| 195 | + public int insertJob(SysJob job) throws SchedulerException, TaskException | ||
| 196 | + { | ||
| 197 | + job.setStatus(ScheduleConstants.Status.PAUSE.getValue()); | ||
| 198 | + int rows = jobMapper.insertJob(job); | ||
| 199 | + if (rows > 0) | ||
| 200 | + { | ||
| 201 | + ScheduleUtils.createScheduleJob(scheduler, job); | ||
| 202 | + } | ||
| 203 | + return rows; | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + /** | ||
| 207 | + * 更新任务的时间表达式 | ||
| 208 | + * | ||
| 209 | + * @param job 调度信息 | ||
| 210 | + */ | ||
| 211 | + @Override | ||
| 212 | + @Transactional(rollbackFor = Exception.class) | ||
| 213 | + public int updateJob(SysJob job) throws SchedulerException, TaskException | ||
| 214 | + { | ||
| 215 | + SysJob properties = selectJobById(job.getJobId()); | ||
| 216 | + int rows = jobMapper.updateJob(job); | ||
| 217 | + if (rows > 0) | ||
| 218 | + { | ||
| 219 | + updateSchedulerJob(job, properties.getJobGroup()); | ||
| 220 | + } | ||
| 221 | + return rows; | ||
| 222 | + } | ||
| 223 | + | ||
| 224 | + /** | ||
| 225 | + * 更新任务 | ||
| 226 | + * | ||
| 227 | + * @param job 任务对象 | ||
| 228 | + * @param jobGroup 任务组名 | ||
| 229 | + */ | ||
| 230 | + public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException | ||
| 231 | + { | ||
| 232 | + Long jobId = job.getJobId(); | ||
| 233 | + // 判断是否存在 | ||
| 234 | + JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup); | ||
| 235 | + if (scheduler.checkExists(jobKey)) | ||
| 236 | + { | ||
| 237 | + // 防止创建时存在数据问题 先移除,然后在执行创建操作 | ||
| 238 | + scheduler.deleteJob(jobKey); | ||
| 239 | + } | ||
| 240 | + ScheduleUtils.createScheduleJob(scheduler, job); | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + /** | ||
| 244 | + * 校验cron表达式是否有效 | ||
| 245 | + * | ||
| 246 | + * @param cronExpression 表达式 | ||
| 247 | + * @return 结果 | ||
| 248 | + */ | ||
| 249 | + @Override | ||
| 250 | + public boolean checkCronExpressionIsValid(String cronExpression) | ||
| 251 | + { | ||
| 252 | + return CronUtils.isValid(cronExpression); | ||
| 253 | + } | ||
| 254 | +} |
| 1 | +package com.ruoyi.quartz.task; | ||
| 2 | + | ||
| 3 | +import org.springframework.stereotype.Component; | ||
| 4 | +import com.ruoyi.common.utils.StringUtils; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 定时任务调度测试 | ||
| 8 | + * | ||
| 9 | + * @author ruoyi | ||
| 10 | + */ | ||
| 11 | +@Component("ryTask") | ||
| 12 | +public class RyTask | ||
| 13 | +{ | ||
| 14 | + public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) | ||
| 15 | + { | ||
| 16 | + System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i)); | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + public void ryParams(String params) | ||
| 20 | + { | ||
| 21 | + System.out.println("执行有参方法:" + params); | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + public void ryNoParams() | ||
| 25 | + { | ||
| 26 | + System.out.println("执行无参方法"); | ||
| 27 | + } | ||
| 28 | +} |
| 1 | +package com.ruoyi.quartz.util; | ||
| 2 | + | ||
| 3 | +import java.util.Date; | ||
| 4 | +import org.quartz.Job; | ||
| 5 | +import org.quartz.JobExecutionContext; | ||
| 6 | +import org.quartz.JobExecutionException; | ||
| 7 | +import org.slf4j.Logger; | ||
| 8 | +import org.slf4j.LoggerFactory; | ||
| 9 | +import com.ruoyi.common.constant.Constants; | ||
| 10 | +import com.ruoyi.common.constant.ScheduleConstants; | ||
| 11 | +import com.ruoyi.common.utils.ExceptionUtil; | ||
| 12 | +import com.ruoyi.common.utils.StringUtils; | ||
| 13 | +import com.ruoyi.common.utils.bean.BeanUtils; | ||
| 14 | +import com.ruoyi.common.utils.spring.SpringUtils; | ||
| 15 | +import com.ruoyi.quartz.domain.SysJob; | ||
| 16 | +import com.ruoyi.quartz.domain.SysJobLog; | ||
| 17 | +import com.ruoyi.quartz.service.ISysJobLogService; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * 抽象quartz调用 | ||
| 21 | + * | ||
| 22 | + * @author ruoyi | ||
| 23 | + */ | ||
| 24 | +public abstract class AbstractQuartzJob implements Job | ||
| 25 | +{ | ||
| 26 | + private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class); | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * 线程本地变量 | ||
| 30 | + */ | ||
| 31 | + private static ThreadLocal<Date> threadLocal = new ThreadLocal<>(); | ||
| 32 | + | ||
| 33 | + @Override | ||
| 34 | + public void execute(JobExecutionContext context) throws JobExecutionException | ||
| 35 | + { | ||
| 36 | + SysJob sysJob = new SysJob(); | ||
| 37 | + BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES)); | ||
| 38 | + try | ||
| 39 | + { | ||
| 40 | + before(context, sysJob); | ||
| 41 | + if (sysJob != null) | ||
| 42 | + { | ||
| 43 | + doExecute(context, sysJob); | ||
| 44 | + } | ||
| 45 | + after(context, sysJob, null); | ||
| 46 | + } | ||
| 47 | + catch (Exception e) | ||
| 48 | + { | ||
| 49 | + log.error("任务执行异常 - :", e); | ||
| 50 | + after(context, sysJob, e); | ||
| 51 | + } | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * 执行前 | ||
| 56 | + * | ||
| 57 | + * @param context 工作执行上下文对象 | ||
| 58 | + * @param sysJob 系统计划任务 | ||
| 59 | + */ | ||
| 60 | + protected void before(JobExecutionContext context, SysJob sysJob) | ||
| 61 | + { | ||
| 62 | + threadLocal.set(new Date()); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * 执行后 | ||
| 67 | + * | ||
| 68 | + * @param context 工作执行上下文对象 | ||
| 69 | + * @param sysJob 系统计划任务 | ||
| 70 | + */ | ||
| 71 | + protected void after(JobExecutionContext context, SysJob sysJob, Exception e) | ||
| 72 | + { | ||
| 73 | + Date startTime = threadLocal.get(); | ||
| 74 | + threadLocal.remove(); | ||
| 75 | + | ||
| 76 | + final SysJobLog sysJobLog = new SysJobLog(); | ||
| 77 | + sysJobLog.setJobName(sysJob.getJobName()); | ||
| 78 | + sysJobLog.setJobGroup(sysJob.getJobGroup()); | ||
| 79 | + sysJobLog.setInvokeTarget(sysJob.getInvokeTarget()); | ||
| 80 | + sysJobLog.setStartTime(startTime); | ||
| 81 | + sysJobLog.setStopTime(new Date()); | ||
| 82 | + long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime(); | ||
| 83 | + sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒"); | ||
| 84 | + if (e != null) | ||
| 85 | + { | ||
| 86 | + sysJobLog.setStatus(Constants.FAIL); | ||
| 87 | + String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000); | ||
| 88 | + sysJobLog.setExceptionInfo(errorMsg); | ||
| 89 | + } | ||
| 90 | + else | ||
| 91 | + { | ||
| 92 | + sysJobLog.setStatus(Constants.SUCCESS); | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + // 写入数据库当中 | ||
| 96 | + SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + /** | ||
| 100 | + * 执行方法,由子类重载 | ||
| 101 | + * | ||
| 102 | + * @param context 工作执行上下文对象 | ||
| 103 | + * @param sysJob 系统计划任务 | ||
| 104 | + * @throws Exception 执行过程中的异常 | ||
| 105 | + */ | ||
| 106 | + protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception; | ||
| 107 | +} |
| 1 | +package com.ruoyi.quartz.util; | ||
| 2 | + | ||
| 3 | +import java.text.ParseException; | ||
| 4 | +import java.util.Date; | ||
| 5 | +import org.quartz.CronExpression; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * cron表达式工具类 | ||
| 9 | + * | ||
| 10 | + * @author ruoyi | ||
| 11 | + * | ||
| 12 | + */ | ||
| 13 | +public class CronUtils | ||
| 14 | +{ | ||
| 15 | + /** | ||
| 16 | + * 返回一个布尔值代表一个给定的Cron表达式的有效性 | ||
| 17 | + * | ||
| 18 | + * @param cronExpression Cron表达式 | ||
| 19 | + * @return boolean 表达式是否有效 | ||
| 20 | + */ | ||
| 21 | + public static boolean isValid(String cronExpression) | ||
| 22 | + { | ||
| 23 | + return CronExpression.isValidExpression(cronExpression); | ||
| 24 | + } | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 返回一个字符串值,表示该消息无效Cron表达式给出有效性 | ||
| 28 | + * | ||
| 29 | + * @param cronExpression Cron表达式 | ||
| 30 | + * @return String 无效时返回表达式错误描述,如果有效返回null | ||
| 31 | + */ | ||
| 32 | + public static String getInvalidMessage(String cronExpression) | ||
| 33 | + { | ||
| 34 | + try | ||
| 35 | + { | ||
| 36 | + new CronExpression(cronExpression); | ||
| 37 | + return null; | ||
| 38 | + } | ||
| 39 | + catch (ParseException pe) | ||
| 40 | + { | ||
| 41 | + return pe.getMessage(); | ||
| 42 | + } | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * 返回下一个执行时间根据给定的Cron表达式 | ||
| 47 | + * | ||
| 48 | + * @param cronExpression Cron表达式 | ||
| 49 | + * @return Date 下次Cron表达式执行时间 | ||
| 50 | + */ | ||
| 51 | + public static Date getNextExecution(String cronExpression) | ||
| 52 | + { | ||
| 53 | + try | ||
| 54 | + { | ||
| 55 | + CronExpression cron = new CronExpression(cronExpression); | ||
| 56 | + return cron.getNextValidTimeAfter(new Date(System.currentTimeMillis())); | ||
| 57 | + } | ||
| 58 | + catch (ParseException e) | ||
| 59 | + { | ||
| 60 | + throw new IllegalArgumentException(e.getMessage()); | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | +} |
| 1 | +package com.ruoyi.quartz.util; | ||
| 2 | + | ||
| 3 | +import java.lang.reflect.InvocationTargetException; | ||
| 4 | +import java.lang.reflect.Method; | ||
| 5 | +import java.util.LinkedList; | ||
| 6 | +import java.util.List; | ||
| 7 | +import com.ruoyi.common.utils.StringUtils; | ||
| 8 | +import com.ruoyi.common.utils.spring.SpringUtils; | ||
| 9 | +import com.ruoyi.quartz.domain.SysJob; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 任务执行工具 | ||
| 13 | + * | ||
| 14 | + * @author ruoyi | ||
| 15 | + */ | ||
| 16 | +public class JobInvokeUtil | ||
| 17 | +{ | ||
| 18 | + /** | ||
| 19 | + * 执行方法 | ||
| 20 | + * | ||
| 21 | + * @param sysJob 系统任务 | ||
| 22 | + */ | ||
| 23 | + public static void invokeMethod(SysJob sysJob) throws Exception | ||
| 24 | + { | ||
| 25 | + String invokeTarget = sysJob.getInvokeTarget(); | ||
| 26 | + String beanName = getBeanName(invokeTarget); | ||
| 27 | + String methodName = getMethodName(invokeTarget); | ||
| 28 | + List<Object[]> methodParams = getMethodParams(invokeTarget); | ||
| 29 | + | ||
| 30 | + if (!isValidClassName(beanName)) | ||
| 31 | + { | ||
| 32 | + Object bean = SpringUtils.getBean(beanName); | ||
| 33 | + invokeMethod(bean, methodName, methodParams); | ||
| 34 | + } | ||
| 35 | + else | ||
| 36 | + { | ||
| 37 | + Object bean = Class.forName(beanName).newInstance(); | ||
| 38 | + invokeMethod(bean, methodName, methodParams); | ||
| 39 | + } | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + /** | ||
| 43 | + * 调用任务方法 | ||
| 44 | + * | ||
| 45 | + * @param bean 目标对象 | ||
| 46 | + * @param methodName 方法名称 | ||
| 47 | + * @param methodParams 方法参数 | ||
| 48 | + */ | ||
| 49 | + private static void invokeMethod(Object bean, String methodName, List<Object[]> methodParams) | ||
| 50 | + throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, | ||
| 51 | + InvocationTargetException | ||
| 52 | + { | ||
| 53 | + if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) | ||
| 54 | + { | ||
| 55 | + Method method = bean.getClass().getDeclaredMethod(methodName, getMethodParamsType(methodParams)); | ||
| 56 | + method.invoke(bean, getMethodParamsValue(methodParams)); | ||
| 57 | + } | ||
| 58 | + else | ||
| 59 | + { | ||
| 60 | + Method method = bean.getClass().getDeclaredMethod(methodName); | ||
| 61 | + method.invoke(bean); | ||
| 62 | + } | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * 校验是否为为class包名 | ||
| 67 | + * | ||
| 68 | + * @param str 名称 | ||
| 69 | + * @return true是 false否 | ||
| 70 | + */ | ||
| 71 | + public static boolean isValidClassName(String invokeTarget) | ||
| 72 | + { | ||
| 73 | + return StringUtils.countMatches(invokeTarget, ".") > 1; | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + /** | ||
| 77 | + * 获取bean名称 | ||
| 78 | + * | ||
| 79 | + * @param invokeTarget 目标字符串 | ||
| 80 | + * @return bean名称 | ||
| 81 | + */ | ||
| 82 | + public static String getBeanName(String invokeTarget) | ||
| 83 | + { | ||
| 84 | + String beanName = StringUtils.substringBefore(invokeTarget, "("); | ||
| 85 | + return StringUtils.substringBeforeLast(beanName, "."); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + /** | ||
| 89 | + * 获取bean方法 | ||
| 90 | + * | ||
| 91 | + * @param invokeTarget 目标字符串 | ||
| 92 | + * @return method方法 | ||
| 93 | + */ | ||
| 94 | + public static String getMethodName(String invokeTarget) | ||
| 95 | + { | ||
| 96 | + String methodName = StringUtils.substringBefore(invokeTarget, "("); | ||
| 97 | + return StringUtils.substringAfterLast(methodName, "."); | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + /** | ||
| 101 | + * 获取method方法参数相关列表 | ||
| 102 | + * | ||
| 103 | + * @param invokeTarget 目标字符串 | ||
| 104 | + * @return method方法相关参数列表 | ||
| 105 | + */ | ||
| 106 | + public static List<Object[]> getMethodParams(String invokeTarget) | ||
| 107 | + { | ||
| 108 | + String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")"); | ||
| 109 | + if (StringUtils.isEmpty(methodStr)) | ||
| 110 | + { | ||
| 111 | + return null; | ||
| 112 | + } | ||
| 113 | + String[] methodParams = methodStr.split(",(?=(?:[^\']*\"[^\']*\')*[^\']*$)"); | ||
| 114 | + List<Object[]> classs = new LinkedList<>(); | ||
| 115 | + for (int i = 0; i < methodParams.length; i++) | ||
| 116 | + { | ||
| 117 | + String str = StringUtils.trimToEmpty(methodParams[i]); | ||
| 118 | + // String字符串类型,包含' | ||
| 119 | + if (StringUtils.contains(str, "'")) | ||
| 120 | + { | ||
| 121 | + classs.add(new Object[] { StringUtils.replace(str, "'", ""), String.class }); | ||
| 122 | + } | ||
| 123 | + // boolean布尔类型,等于true或者false | ||
| 124 | + else if (StringUtils.equals(str, "true") || StringUtils.equalsIgnoreCase(str, "false")) | ||
| 125 | + { | ||
| 126 | + classs.add(new Object[] { Boolean.valueOf(str), Boolean.class }); | ||
| 127 | + } | ||
| 128 | + // long长整形,包含L | ||
| 129 | + else if (StringUtils.containsIgnoreCase(str, "L")) | ||
| 130 | + { | ||
| 131 | + classs.add(new Object[] { Long.valueOf(StringUtils.replaceIgnoreCase(str, "L", "")), Long.class }); | ||
| 132 | + } | ||
| 133 | + // double浮点类型,包含D | ||
| 134 | + else if (StringUtils.containsIgnoreCase(str, "D")) | ||
| 135 | + { | ||
| 136 | + classs.add(new Object[] { Double.valueOf(StringUtils.replaceIgnoreCase(str, "D", "")), Double.class }); | ||
| 137 | + } | ||
| 138 | + // 其他类型归类为整形 | ||
| 139 | + else | ||
| 140 | + { | ||
| 141 | + classs.add(new Object[] { Integer.valueOf(str), Integer.class }); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + return classs; | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + /** | ||
| 148 | + * 获取参数类型 | ||
| 149 | + * | ||
| 150 | + * @param methodParams 参数相关列表 | ||
| 151 | + * @return 参数类型列表 | ||
| 152 | + */ | ||
| 153 | + public static Class<?>[] getMethodParamsType(List<Object[]> methodParams) | ||
| 154 | + { | ||
| 155 | + Class<?>[] classs = new Class<?>[methodParams.size()]; | ||
| 156 | + int index = 0; | ||
| 157 | + for (Object[] os : methodParams) | ||
| 158 | + { | ||
| 159 | + classs[index] = (Class<?>) os[1]; | ||
| 160 | + index++; | ||
| 161 | + } | ||
| 162 | + return classs; | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + /** | ||
| 166 | + * 获取参数值 | ||
| 167 | + * | ||
| 168 | + * @param methodParams 参数相关列表 | ||
| 169 | + * @return 参数值列表 | ||
| 170 | + */ | ||
| 171 | + public static Object[] getMethodParamsValue(List<Object[]> methodParams) | ||
| 172 | + { | ||
| 173 | + Object[] classs = new Object[methodParams.size()]; | ||
| 174 | + int index = 0; | ||
| 175 | + for (Object[] os : methodParams) | ||
| 176 | + { | ||
| 177 | + classs[index] = (Object) os[0]; | ||
| 178 | + index++; | ||
| 179 | + } | ||
| 180 | + return classs; | ||
| 181 | + } | ||
| 182 | +} |
| 1 | +package com.ruoyi.quartz.util; | ||
| 2 | + | ||
| 3 | +import org.quartz.DisallowConcurrentExecution; | ||
| 4 | +import org.quartz.JobExecutionContext; | ||
| 5 | +import com.ruoyi.quartz.domain.SysJob; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 定时任务处理(禁止并发执行) | ||
| 9 | + * | ||
| 10 | + * @author ruoyi | ||
| 11 | + * | ||
| 12 | + */ | ||
| 13 | +@DisallowConcurrentExecution | ||
| 14 | +public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob | ||
| 15 | +{ | ||
| 16 | + @Override | ||
| 17 | + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception | ||
| 18 | + { | ||
| 19 | + JobInvokeUtil.invokeMethod(sysJob); | ||
| 20 | + } | ||
| 21 | +} |
| 1 | +package com.ruoyi.quartz.util; | ||
| 2 | + | ||
| 3 | +import org.quartz.JobExecutionContext; | ||
| 4 | +import com.ruoyi.quartz.domain.SysJob; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 定时任务处理(允许并发执行) | ||
| 8 | + * | ||
| 9 | + * @author ruoyi | ||
| 10 | + * | ||
| 11 | + */ | ||
| 12 | +public class QuartzJobExecution extends AbstractQuartzJob | ||
| 13 | +{ | ||
| 14 | + @Override | ||
| 15 | + protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception | ||
| 16 | + { | ||
| 17 | + JobInvokeUtil.invokeMethod(sysJob); | ||
| 18 | + } | ||
| 19 | +} |
| 1 | +package com.ruoyi.quartz.util; | ||
| 2 | + | ||
| 3 | +import org.quartz.CronScheduleBuilder; | ||
| 4 | +import org.quartz.CronTrigger; | ||
| 5 | +import org.quartz.Job; | ||
| 6 | +import org.quartz.JobBuilder; | ||
| 7 | +import org.quartz.JobDetail; | ||
| 8 | +import org.quartz.JobKey; | ||
| 9 | +import org.quartz.Scheduler; | ||
| 10 | +import org.quartz.SchedulerException; | ||
| 11 | +import org.quartz.TriggerBuilder; | ||
| 12 | +import org.quartz.TriggerKey; | ||
| 13 | +import com.ruoyi.common.constant.ScheduleConstants; | ||
| 14 | +import com.ruoyi.common.exception.job.TaskException; | ||
| 15 | +import com.ruoyi.common.exception.job.TaskException.Code; | ||
| 16 | +import com.ruoyi.quartz.domain.SysJob; | ||
| 17 | + | ||
| 18 | +/** | ||
| 19 | + * 定时任务工具类 | ||
| 20 | + * | ||
| 21 | + * @author ruoyi | ||
| 22 | + * | ||
| 23 | + */ | ||
| 24 | +public class ScheduleUtils | ||
| 25 | +{ | ||
| 26 | + /** | ||
| 27 | + * 得到quartz任务类 | ||
| 28 | + * | ||
| 29 | + * @param sysJob 执行计划 | ||
| 30 | + * @return 具体执行任务类 | ||
| 31 | + */ | ||
| 32 | + private static Class<? extends Job> getQuartzJobClass(SysJob sysJob) | ||
| 33 | + { | ||
| 34 | + boolean isConcurrent = "0".equals(sysJob.getConcurrent()); | ||
| 35 | + return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class; | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 构建任务触发对象 | ||
| 40 | + */ | ||
| 41 | + public static TriggerKey getTriggerKey(Long jobId, String jobGroup) | ||
| 42 | + { | ||
| 43 | + return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * 构建任务键对象 | ||
| 48 | + */ | ||
| 49 | + public static JobKey getJobKey(Long jobId, String jobGroup) | ||
| 50 | + { | ||
| 51 | + return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + /** | ||
| 55 | + * 创建定时任务 | ||
| 56 | + */ | ||
| 57 | + public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException | ||
| 58 | + { | ||
| 59 | + Class<? extends Job> jobClass = getQuartzJobClass(job); | ||
| 60 | + // 构建job信息 | ||
| 61 | + Long jobId = job.getJobId(); | ||
| 62 | + String jobGroup = job.getJobGroup(); | ||
| 63 | + JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build(); | ||
| 64 | + | ||
| 65 | + // 表达式调度构建器 | ||
| 66 | + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); | ||
| 67 | + cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); | ||
| 68 | + | ||
| 69 | + // 按新的cronExpression表达式构建一个新的trigger | ||
| 70 | + CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup)) | ||
| 71 | + .withSchedule(cronScheduleBuilder).build(); | ||
| 72 | + | ||
| 73 | + // 放入参数,运行时的方法可以获取 | ||
| 74 | + jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job); | ||
| 75 | + | ||
| 76 | + // 判断是否存在 | ||
| 77 | + if (scheduler.checkExists(getJobKey(jobId, jobGroup))) | ||
| 78 | + { | ||
| 79 | + // 防止创建时存在数据问题 先移除,然后在执行创建操作 | ||
| 80 | + scheduler.deleteJob(getJobKey(jobId, jobGroup)); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + scheduler.scheduleJob(jobDetail, trigger); | ||
| 84 | + | ||
| 85 | + // 暂停任务 | ||
| 86 | + if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) | ||
| 87 | + { | ||
| 88 | + scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup)); | ||
| 89 | + } | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + /** | ||
| 93 | + * 设置定时任务策略 | ||
| 94 | + */ | ||
| 95 | + public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) | ||
| 96 | + throws TaskException | ||
| 97 | + { | ||
| 98 | + switch (job.getMisfirePolicy()) | ||
| 99 | + { | ||
| 100 | + case ScheduleConstants.MISFIRE_DEFAULT: | ||
| 101 | + return cb; | ||
| 102 | + case ScheduleConstants.MISFIRE_IGNORE_MISFIRES: | ||
| 103 | + return cb.withMisfireHandlingInstructionIgnoreMisfires(); | ||
| 104 | + case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED: | ||
| 105 | + return cb.withMisfireHandlingInstructionFireAndProceed(); | ||
| 106 | + case ScheduleConstants.MISFIRE_DO_NOTHING: | ||
| 107 | + return cb.withMisfireHandlingInstructionDoNothing(); | ||
| 108 | + default: | ||
| 109 | + throw new TaskException("The task misfire policy '" + job.getMisfirePolicy() | ||
| 110 | + + "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR); | ||
| 111 | + } | ||
| 112 | + } | ||
| 113 | +} |
| 1 | +<?xml version="1.0" encoding="UTF-8" ?> | ||
| 2 | +<!DOCTYPE mapper | ||
| 3 | +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | ||
| 4 | +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||
| 5 | +<mapper namespace="com.ruoyi.quartz.mapper.SysJobLogMapper"> | ||
| 6 | + | ||
| 7 | + <resultMap type="SysJobLog" id="SysJobLogResult"> | ||
| 8 | + <id property="jobLogId" column="job_log_id" /> | ||
| 9 | + <result property="jobName" column="job_name" /> | ||
| 10 | + <result property="jobGroup" column="job_group" /> | ||
| 11 | + <result property="invokeTarget" column="invoke_target" /> | ||
| 12 | + <result property="jobMessage" column="job_message" /> | ||
| 13 | + <result property="status" column="status" /> | ||
| 14 | + <result property="exceptionInfo" column="exception_info" /> | ||
| 15 | + <result property="createTime" column="create_time" /> | ||
| 16 | + </resultMap> | ||
| 17 | + | ||
| 18 | + <sql id="selectJobLogVo"> | ||
| 19 | + select job_log_id, job_name, job_group, invoke_target, job_message, status, exception_info, create_time | ||
| 20 | + from sys_job_log | ||
| 21 | + </sql> | ||
| 22 | + | ||
| 23 | + <select id="selectJobLogList" parameterType="SysJobLog" resultMap="SysJobLogResult"> | ||
| 24 | + <include refid="selectJobLogVo"/> | ||
| 25 | + <where> | ||
| 26 | + <if test="jobName != null and jobName != ''"> | ||
| 27 | + AND job_name like concat('%', #{jobName}, '%') | ||
| 28 | + </if> | ||
| 29 | + <if test="jobGroup != null and jobGroup != ''"> | ||
| 30 | + AND job_group = #{jobGroup} | ||
| 31 | + </if> | ||
| 32 | + <if test="status != null and status != ''"> | ||
| 33 | + AND status = #{status} | ||
| 34 | + </if> | ||
| 35 | + <if test="invokeTarget != null and invokeTarget != ''"> | ||
| 36 | + AND invoke_target like concat('%', #{invokeTarget}, '%') | ||
| 37 | + </if> | ||
| 38 | + <if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 --> | ||
| 39 | + and date_format(create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d') | ||
| 40 | + </if> | ||
| 41 | + <if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 --> | ||
| 42 | + and date_format(create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d') | ||
| 43 | + </if> | ||
| 44 | + </where> | ||
| 45 | + </select> | ||
| 46 | + | ||
| 47 | + <select id="selectJobLogAll" resultMap="SysJobLogResult"> | ||
| 48 | + <include refid="selectJobLogVo"/> | ||
| 49 | + </select> | ||
| 50 | + | ||
| 51 | + <select id="selectJobLogById" parameterType="Long" resultMap="SysJobLogResult"> | ||
| 52 | + <include refid="selectJobLogVo"/> | ||
| 53 | + where job_log_id = #{jobLogId} | ||
| 54 | + </select> | ||
| 55 | + | ||
| 56 | + <delete id="deleteJobLogById" parameterType="Long"> | ||
| 57 | + delete from sys_job_log where job_log_id = #{jobLogId} | ||
| 58 | + </delete> | ||
| 59 | + | ||
| 60 | + <delete id="deleteJobLogByIds" parameterType="Long"> | ||
| 61 | + delete from sys_job_log where job_log_id in | ||
| 62 | + <foreach collection="array" item="jobLogId" open="(" separator="," close=")"> | ||
| 63 | + #{jobLogId} | ||
| 64 | + </foreach> | ||
| 65 | + </delete> | ||
| 66 | + | ||
| 67 | + <update id="cleanJobLog"> | ||
| 68 | + truncate table sys_job_log | ||
| 69 | + </update> | ||
| 70 | + | ||
| 71 | + <insert id="insertJobLog" parameterType="SysJobLog"> | ||
| 72 | + insert into sys_job_log( | ||
| 73 | + <if test="jobLogId != null and jobLogId != 0">job_log_id,</if> | ||
| 74 | + <if test="jobName != null and jobName != ''">job_name,</if> | ||
| 75 | + <if test="jobGroup != null and jobGroup != ''">job_group,</if> | ||
| 76 | + <if test="invokeTarget != null and invokeTarget != ''">invoke_target,</if> | ||
| 77 | + <if test="jobMessage != null and jobMessage != ''">job_message,</if> | ||
| 78 | + <if test="status != null and status != ''">status,</if> | ||
| 79 | + <if test="exceptionInfo != null and exceptionInfo != ''">exception_info,</if> | ||
| 80 | + create_time | ||
| 81 | + )values( | ||
| 82 | + <if test="jobLogId != null and jobLogId != 0">#{jobLogId},</if> | ||
| 83 | + <if test="jobName != null and jobName != ''">#{jobName},</if> | ||
| 84 | + <if test="jobGroup != null and jobGroup != ''">#{jobGroup},</if> | ||
| 85 | + <if test="invokeTarget != null and invokeTarget != ''">#{invokeTarget},</if> | ||
| 86 | + <if test="jobMessage != null and jobMessage != ''">#{jobMessage},</if> | ||
| 87 | + <if test="status != null and status != ''">#{status},</if> | ||
| 88 | + <if test="exceptionInfo != null and exceptionInfo != ''">#{exceptionInfo},</if> | ||
| 89 | + sysdate() | ||
| 90 | + ) | ||
| 91 | + </insert> | ||
| 92 | + | ||
| 93 | +</mapper> |
| 1 | +<?xml version="1.0" encoding="UTF-8" ?> | ||
| 2 | +<!DOCTYPE mapper | ||
| 3 | +PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | ||
| 4 | +"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | ||
| 5 | +<mapper namespace="com.ruoyi.quartz.mapper.SysJobMapper"> | ||
| 6 | + | ||
| 7 | + <resultMap type="SysJob" id="SysJobResult"> | ||
| 8 | + <id property="jobId" column="job_id" /> | ||
| 9 | + <result property="jobName" column="job_name" /> | ||
| 10 | + <result property="jobGroup" column="job_group" /> | ||
| 11 | + <result property="invokeTarget" column="invoke_target" /> | ||
| 12 | + <result property="cronExpression" column="cron_expression" /> | ||
| 13 | + <result property="misfirePolicy" column="misfire_policy" /> | ||
| 14 | + <result property="concurrent" column="concurrent" /> | ||
| 15 | + <result property="status" column="status" /> | ||
| 16 | + <result property="createBy" column="create_by" /> | ||
| 17 | + <result property="createTime" column="create_time" /> | ||
| 18 | + <result property="updateBy" column="update_by" /> | ||
| 19 | + <result property="updateTime" column="update_time" /> | ||
| 20 | + <result property="remark" column="remark" /> | ||
| 21 | + </resultMap> | ||
| 22 | + | ||
| 23 | + <sql id="selectJobVo"> | ||
| 24 | + select job_id, job_name, job_group, invoke_target, cron_expression, misfire_policy, concurrent, status, create_by, create_time, remark | ||
| 25 | + from sys_job | ||
| 26 | + </sql> | ||
| 27 | + | ||
| 28 | + <select id="selectJobList" parameterType="SysJob" resultMap="SysJobResult"> | ||
| 29 | + <include refid="selectJobVo"/> | ||
| 30 | + <where> | ||
| 31 | + <if test="jobName != null and jobName != ''"> | ||
| 32 | + AND job_name like concat('%', #{jobName}, '%') | ||
| 33 | + </if> | ||
| 34 | + <if test="jobGroup != null and jobGroup != ''"> | ||
| 35 | + AND job_group = #{jobGroup} | ||
| 36 | + </if> | ||
| 37 | + <if test="status != null and status != ''"> | ||
| 38 | + AND status = #{status} | ||
| 39 | + </if> | ||
| 40 | + <if test="invokeTarget != null and invokeTarget != ''"> | ||
| 41 | + AND invoke_target like concat('%', #{invokeTarget}, '%') | ||
| 42 | + </if> | ||
| 43 | + </where> | ||
| 44 | + </select> | ||
| 45 | + | ||
| 46 | + <select id="selectJobAll" resultMap="SysJobResult"> | ||
| 47 | + <include refid="selectJobVo"/> | ||
| 48 | + </select> | ||
| 49 | + | ||
| 50 | + <select id="selectJobById" parameterType="Long" resultMap="SysJobResult"> | ||
| 51 | + <include refid="selectJobVo"/> | ||
| 52 | + where job_id = #{jobId} | ||
| 53 | + </select> | ||
| 54 | + | ||
| 55 | + <delete id="deleteJobById" parameterType="Long"> | ||
| 56 | + delete from sys_job where job_id = #{jobId} | ||
| 57 | + </delete> | ||
| 58 | + | ||
| 59 | + <delete id="deleteJobByIds" parameterType="Long"> | ||
| 60 | + delete from sys_job where job_id in | ||
| 61 | + <foreach collection="array" item="jobId" open="(" separator="," close=")"> | ||
| 62 | + #{jobId} | ||
| 63 | + </foreach> | ||
| 64 | + </delete> | ||
| 65 | + | ||
| 66 | + <update id="updateJob" parameterType="SysJob"> | ||
| 67 | + update sys_job | ||
| 68 | + <set> | ||
| 69 | + <if test="jobName != null and jobName != ''">job_name = #{jobName},</if> | ||
| 70 | + <if test="jobGroup != null and jobGroup != ''">job_group = #{jobGroup},</if> | ||
| 71 | + <if test="invokeTarget != null and invokeTarget != ''">invoke_target = #{invokeTarget},</if> | ||
| 72 | + <if test="cronExpression != null and cronExpression != ''">cron_expression = #{cronExpression},</if> | ||
| 73 | + <if test="misfirePolicy != null and misfirePolicy != ''">misfire_policy = #{misfirePolicy},</if> | ||
| 74 | + <if test="concurrent != null and concurrent != ''">concurrent = #{concurrent},</if> | ||
| 75 | + <if test="status !=null">status = #{status},</if> | ||
| 76 | + <if test="remark != null and remark != ''">remark = #{remark},</if> | ||
| 77 | + <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if> | ||
| 78 | + update_time = sysdate() | ||
| 79 | + </set> | ||
| 80 | + where job_id = #{jobId} | ||
| 81 | + </update> | ||
| 82 | + | ||
| 83 | + <insert id="insertJob" parameterType="SysJob" useGeneratedKeys="true" keyProperty="jobId"> | ||
| 84 | + insert into sys_job( | ||
| 85 | + <if test="jobId != null and jobId != 0">job_id,</if> | ||
| 86 | + <if test="jobName != null and jobName != ''">job_name,</if> | ||
| 87 | + <if test="jobGroup != null and jobGroup != ''">job_group,</if> | ||
| 88 | + <if test="invokeTarget != null and invokeTarget != ''">invoke_target,</if> | ||
| 89 | + <if test="cronExpression != null and cronExpression != ''">cron_expression,</if> | ||
| 90 | + <if test="misfirePolicy != null and misfirePolicy != ''">misfire_policy,</if> | ||
| 91 | + <if test="concurrent != null and concurrent != ''">concurrent,</if> | ||
| 92 | + <if test="status != null and status != ''">status,</if> | ||
| 93 | + <if test="remark != null and remark != ''">remark,</if> | ||
| 94 | + <if test="createBy != null and createBy != ''">create_by,</if> | ||
| 95 | + create_time | ||
| 96 | + )values( | ||
| 97 | + <if test="jobId != null and jobId != 0">#{jobId},</if> | ||
| 98 | + <if test="jobName != null and jobName != ''">#{jobName},</if> | ||
| 99 | + <if test="jobGroup != null and jobGroup != ''">#{jobGroup},</if> | ||
| 100 | + <if test="invokeTarget != null and invokeTarget != ''">#{invokeTarget},</if> | ||
| 101 | + <if test="cronExpression != null and cronExpression != ''">#{cronExpression},</if> | ||
| 102 | + <if test="misfirePolicy != null and misfirePolicy != ''">#{misfirePolicy},</if> | ||
| 103 | + <if test="concurrent != null and concurrent != ''">#{concurrent},</if> | ||
| 104 | + <if test="status != null and status != ''">#{status},</if> | ||
| 105 | + <if test="remark != null and remark != ''">#{remark},</if> | ||
| 106 | + <if test="createBy != null and createBy != ''">#{createBy},</if> | ||
| 107 | + sysdate() | ||
| 108 | + ) | ||
| 109 | + </insert> | ||
| 110 | + | ||
| 111 | +</mapper> |
-
请 注册 或 登录 后发表评论