Commit 60943b099a008f0caae49e323eda01b787412cc0

Authored by guzijian
1 parent bbbd710c

feat: 增加定时任务,计算签到未签人员

ruoyi-admin/src/main/java/com/ruoyi/controller/ReportController.java
... ... @@ -7,7 +7,6 @@ import com.ruoyi.pojo.request.ReportViewRequestVo;
7 7 import com.ruoyi.pojo.request.ReportErrorRequestVo;
8 8 import com.ruoyi.pojo.response.ExportReportViewResponseVo;
9 9 import com.ruoyi.pojo.response.ReportErrorResponseVo;
10   -import com.ruoyi.pojo.response.ReportViewResponseVo;
11 10 import com.ruoyi.service.ReportService;
12 11 import com.ruoyi.system.domain.SysNotice;
13 12 import io.swagger.annotations.Api;
... ... @@ -19,9 +18,6 @@ import org.springframework.web.bind.annotation.*;
19 18 import javax.annotation.Resource;
20 19 import javax.servlet.http.HttpServletResponse;
21 20 import java.util.List;
22   -import java.util.stream.Collectors;
23   -
24   -import static com.ruoyi.common.ConstSignInConstSignInProperties.EXPORT;
25 21  
26 22 /**
27 23 * @author 20412
... ... @@ -69,8 +65,8 @@ public class ReportController {
69 65  
70 66 @ApiOperation("告警通知")
71 67 @GetMapping("/alarm/notice")
72   - public Result<?> getAlarmNotice(){
73   - return Result.OK(reportService.getAlarmNotice());
  68 + public Result<?> getAlarmNotice(@RequestParam(value = "type",required = false) Integer type){
  69 + return Result.OK(reportService.getAlarmNoticeByType(type));
74 70 }
75 71  
76 72  
... ...
ruoyi-admin/src/main/java/com/ruoyi/driver/service/IDriverService.java
... ... @@ -107,4 +107,9 @@ public interface IDriverService
107 107 * @param jobList
108 108 */
109 109 void deleteNotEmptyJob(List<String> jobList);
  110 +
  111 + /**
  112 + * 计算异常班次
  113 + */
  114 + void computedExceptionScheduling();
110 115 }
... ...
ruoyi-admin/src/main/java/com/ruoyi/driver/service/impl/DriverServiceImpl.java
... ... @@ -12,6 +12,7 @@ import java.util.stream.Collectors;
12 12 import cn.hutool.core.collection.CollectionUtil;
13 13 import cn.hutool.http.HttpUtil;
14 14 import com.github.pagehelper.util.StringUtil;
  15 +import com.ruoyi.common.cache.NowSchedulingCache;
15 16 import com.ruoyi.common.cache.SchedulingCache;
16 17 import com.ruoyi.common.config.RuoYiConfig;
17 18 import com.ruoyi.common.core.domain.AjaxResult;
... ... @@ -19,6 +20,7 @@ import com.ruoyi.common.core.redis.RedisCache;
19 20 import com.ruoyi.common.exception.file.InvalidExtensionException;
20 21 import com.ruoyi.common.global.Result;
21 22 import com.ruoyi.common.global.ResultCode;
  23 +import com.ruoyi.common.utils.DateUtils;
22 24 import com.ruoyi.common.utils.file.FileUploadUtils;
23 25 import com.ruoyi.common.utils.file.FileUtils;
24 26 import com.ruoyi.common.utils.file.MimeTypeUtils;
... ... @@ -35,6 +37,8 @@ import com.ruoyi.pojo.response.DriverResponseVo;
35 37 import com.ruoyi.pojo.response.ResponseSchedulingDto;
36 38 import com.ruoyi.service.SchedulingService;
37 39 import com.ruoyi.service.ThreadJobService;
  40 +import com.ruoyi.system.domain.SysNotice;
  41 +import com.ruoyi.system.service.ISysNoticeService;
38 42 import com.ruoyi.utils.ConstDateUtil;
39 43 import com.ruoyi.utils.ListUtils;
40 44 import org.apache.commons.io.FilenameUtils;
... ... @@ -70,6 +74,9 @@ public class DriverServiceImpl implements IDriverService {
70 74  
71 75 private Logger log = LoggerFactory.getLogger(DriverServiceImpl.class);
72 76  
  77 + @Autowired
  78 + private ISysNoticeService noticeService;
  79 +
73 80 @Value("${api.url.getSchedulingInfo}")
74 81 private String schedulingInfoUrl;
75 82 @Value("${api.config.password}")
... ... @@ -80,6 +87,9 @@ public class DriverServiceImpl implements IDriverService {
80 87 private SchedulingCache schedulingCache;
81 88  
82 89 @Resource
  90 + private NowSchedulingCache nowSchedulingCache;
  91 +
  92 + @Resource
83 93 private SchedulingService schedulingService;
84 94  
85 95 @Autowired
... ... @@ -131,20 +141,9 @@ public class DriverServiceImpl implements IDriverService {
131 141 }
132 142  
133 143 private DriverSignInRecommendation checkTime(List<DriverScheduling> dto, Long now) {
134   - Map<Integer, DriverSignInRecommendation> timeMap = new HashMap<>();
135   - for (int i = 0; i < dto.size(); i++) {
136   - timeMap.put(i, new DriverSignInRecommendation(dto.get(i), i));
137   - }
138   - long minDiff = Long.MAX_VALUE;
139 144 Integer index = 0;
140   - // 迭代比较每个时间戳与当前时间戳的差值
141   - for (Integer i : timeMap.keySet()) {
142   - long diff = Math.abs(now - timeMap.get(i).getTimestamps());
143   - if (diff < minDiff) {
144   - minDiff = diff;
145   - index = i;
146   - }
147   - }
  145 + Map<Integer, DriverSignInRecommendation> timeMap = new HashMap<>();
  146 + index = handleSchedulingMap(dto, now, timeMap);
148 147  
149 148 LocalDateTime nowTime = ConstDateUtil.getLocalDateTimeByLongTime(now);
150 149 LocalDateTime signTime = ConstDateUtil.getLocalDateTimeByLongTime(timeMap.get(index).getTimestamps());
... ... @@ -173,6 +172,23 @@ public class DriverServiceImpl implements IDriverService {
173 172 return timeMap.get(index);
174 173 }
175 174  
  175 + private static Integer handleSchedulingMap(List<DriverScheduling> dto, Long now, Map<Integer, DriverSignInRecommendation> timeMap) {
  176 + Integer index = 0;
  177 + for (int i = 0; i < dto.size(); i++) {
  178 + timeMap.put(i, new DriverSignInRecommendation(dto.get(i), i));
  179 + }
  180 + long minDiff = Long.MAX_VALUE;
  181 + // 迭代比较每个时间戳与当前时间戳的差值
  182 + for (Integer i : timeMap.keySet()) {
  183 + long diff = Math.abs(now - timeMap.get(i).getTimestamps());
  184 + if (diff < minDiff) {
  185 + minDiff = diff;
  186 + index = i;
  187 + }
  188 + }
  189 + return index;
  190 + }
  191 +
176 192  
177 193 /**
178 194 * 新增驾驶员信息
... ... @@ -233,7 +249,7 @@ public class DriverServiceImpl implements IDriverService {
233 249 // 获取考勤表进行比对,因为排班数据是会变化的
234 250 List<DriverScheduling> dto = schedulingService.queryScheduling(jobCode, now);
235 251 log.info("获取到排班数据:{}", cacheMapValue);
236   - if (jobCode.equals("700001")){
  252 + if (jobCode.equals("700001")) {
237 253 return AjaxResult.success("");
238 254 }
239 255 // 优先从缓存中读取
... ... @@ -335,15 +351,15 @@ public class DriverServiceImpl implements IDriverService {
335 351 dto = schedulingService.queryScheduling(item.getJobCode(), now);
336 352 DriverResponseVo vo = handlerRecommendation(item, now, dto, schedulingFlag, alcoholFlag);
337 353 // 针对指定用户操作
338   - if ( item.getJobCode().equals("722717") || item.getJobCode().equals("700001")) {
339   - if (!CollectionUtil.isEmpty(dto) && vo.getPlanAction().equals(SIGN_IN_STRING) ){
  354 + if (item.getJobCode().equals("722717") || item.getJobCode().equals("700001")) {
  355 + if (!CollectionUtil.isEmpty(dto) && vo.getPlanAction().equals(SIGN_IN_STRING)) {
340 356 vos.add(DriverResponseVo.createDriverResponseVo(null, item, SIGN_IN_STRING, needCheckAlcoholDevice, true, "测试", "测试", "测试"));
341   - }else if (!CollectionUtil.isEmpty(dto)){
  357 + } else if (!CollectionUtil.isEmpty(dto)) {
342 358 vos.add(vo);
343   - }else {
  359 + } else {
344 360 vos.add(DriverResponseVo.createDriverResponseVo(null, item, SIGN_IN_STRING, needCheckAlcoholDevice, true, "测试", "测试", "测试"));
345 361 }
346   - }else {
  362 + } else {
347 363 // 无排班
348 364 if (Objects.isNull(vo)) {
349 365 vos.add(DriverResponseVo.createDriverResponseVo(null, item, null, false, false, "", "", ""));
... ... @@ -359,15 +375,16 @@ public class DriverServiceImpl implements IDriverService {
359 375  
360 376 /**
361 377 * 100一下的都设置为有酒精测试的设备
  378 + *
362 379 * @param deviceId
363 380 * @return
364 381 */
365 382 public static boolean doCheckDevice(String deviceId) {
366   - if (StringUtil.isEmpty(deviceId)){
  383 + if (StringUtil.isEmpty(deviceId)) {
367 384 return true;
368 385 }
369 386 int num = Integer.parseInt(deviceId);
370   - if (num < 101){
  387 + if (num < 101) {
371 388 return true;
372 389 }
373 390 return false;
... ... @@ -512,6 +529,57 @@ public class DriverServiceImpl implements IDriverService {
512 529 driverMapper.deleteNotEmptyJob(jobList);
513 530 }
514 531  
  532 + @Override
  533 + public void computedExceptionScheduling() {
  534 + // 从当前缓存种读取所有的签到数据 遍历每个工号的打卡集合
  535 + Map<String, List<DriverScheduling>> map = nowSchedulingCache.getCacheScheduling(ConstDateUtil.formatDate(new Date()));
  536 + List<DriverSignInRecommendation> nowTimerList = new ArrayList<>();
  537 + Long now = System.currentTimeMillis();
  538 + for (Map.Entry<String, List<DriverScheduling>> entry : map.entrySet()) {
  539 + List<DriverScheduling> value = entry.getValue();
  540 + // 匹配
  541 + Map<Integer, DriverSignInRecommendation> timeMap = new HashMap<>();
  542 + Integer index = handleSchedulingMap(value, now, timeMap);
  543 + nowTimerList.add(timeMap.get(index));
  544 + }
  545 + // 处理当前时间段未签人员
  546 + nowTimerList = handleTimeOutPerson(nowTimerList);
  547 + sendNotice(nowTimerList);
  548 + }
  549 +
  550 + private void sendNotice(List<DriverSignInRecommendation> nowTimerList) {
  551 + List<SysNotice> noticeList = new ArrayList<>(nowTimerList.size());
  552 + for (DriverSignInRecommendation item : nowTimerList) {
  553 + SysNotice notice = new SysNotice();
  554 + notice.setCreateBy("system");
  555 + notice.setUpdateBy("system");
  556 + notice.setNoticeTitle("应签未签通知");
  557 + String jobCode = "工号:" + item.getJobCode() + "\n";
  558 + String name = "姓名:" + item.getName() + "\n";
  559 + String posts = "工种:" + item.getPosts() + "\n";
  560 + String fleetName = "车队:" + item.getFleetName() + "\n";
  561 + String scheduling = "排班:" + "有排班" + "\n";
  562 + String signDate = "计划签到时间:" + ConstDateUtil.formatDate("yyyy-MM-dd HH:mm:ss", new Date(item.getTimestamps())) + "\n";
  563 + String content = jobCode + name + posts + fleetName + scheduling + signDate;
  564 + notice.setNoticeContent(content);
  565 + notice.setNoticeType("1");
  566 + notice.setStatus("0");
  567 + notice.setCreateTime(DateUtils.getNowDate());
  568 + notice.setUpdateTime(DateUtils.getNowDate());
  569 + notice.setPlanTime(new Date(item.getTimestamps()));
  570 + notice.setJobCode(item.getJobCode());
  571 + noticeList.add(notice);
  572 + }
  573 + noticeService.saveBatch(noticeList);
  574 + }
  575 +
  576 + private List<DriverSignInRecommendation> handleTimeOutPerson(List<DriverSignInRecommendation> nowTimerList) {
  577 + return nowTimerList.stream()
  578 + // 筛选应签未签人员
  579 + .filter(item -> Objects.isNull(item.getSignTime()) || item.getTimestamps() - item.getSignTime() < 0)
  580 + .collect(Collectors.toList());
  581 + }
  582 +
515 583 /**
516 584 * 获取新的imageUrl
517 585 *
... ...
ruoyi-admin/src/main/java/com/ruoyi/job/DriverJob.java
... ... @@ -274,6 +274,13 @@ public class DriverJob implements InitializingBean {
274 274 }
275 275  
276 276 /**
  277 + * 计算异常班次 : 当前应当打卡但是未打卡人员
  278 + */
  279 + public void computedExceptionScheduling() {
  280 + DRIVER_SERVICE.computedExceptionScheduling();
  281 + }
  282 +
  283 + /**
277 284 * 生成排班
278 285 */
279 286 public void createAttendance() {
... ...
ruoyi-admin/src/main/java/com/ruoyi/pojo/DriverSignInRecommendation.java
... ... @@ -3,6 +3,8 @@ package com.ruoyi.pojo;
3 3 import com.ruoyi.domain.DriverScheduling;
4 4 import lombok.Data;
5 5  
  6 +import java.util.Objects;
  7 +
6 8 import static com.ruoyi.common.ConstDriverProperties.BC_TYPE_OUT;
7 9  
8 10 /**
... ... @@ -22,15 +24,23 @@ public class DriverSignInRecommendation {
22 24 private String nbbm;
23 25 private String lpName;
24 26 private String lineName;
  27 + private Long signTime;
  28 + private String jobCode;
  29 + private String name;
  30 + private String fleetName;
25 31  
26 32 public DriverSignInRecommendation() {
27 33 }
28 34  
29 35 public DriverSignInRecommendation(DriverScheduling dto, Integer index) {
30 36 this.setIndex(index);
  37 + this.setFleetName(dto.getFleetName());
31 38 this.setBcType(dto.getBcType());
  39 + this.setJobCode(dto.getJobCode());
  40 + this.setName(dto.getName());
32 41 this.setTimestamps(BC_TYPE_OUT.equals(dto.getBcType()) ? dto.getFcsjT() : dto.getZdsjT());
33 42 this.setSignInId(dto.getSignInId());
  43 + this.setSignTime(Objects.isNull(dto.getSignTime()) ? null : dto.getSignTime().getTime());
34 44 this.setPosts(dto.getPosts());
35 45 this.setExType(dto.getExType());
36 46 this.setLineName(dto.getLineName());
... ...
ruoyi-admin/src/main/java/com/ruoyi/service/ReportService.java
... ... @@ -195,9 +195,9 @@ public class ReportService {
195 195 return vos;
196 196 }
197 197  
198   - public SysNotice getAlarmNotice() {
  198 + public SysNotice getAlarmNoticeByType(Integer type) {
199 199 String username = SecurityUtils.getUsername();
200   - return noticeService.getAlarmNotice(username);
  200 + return noticeService.getAlarmNotice(username,type);
201 201 }
202 202  
203 203 public Object sureNotice(SysNotice notice) {
... ...
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysNotice.java
... ... @@ -7,6 +7,8 @@ import org.apache.commons.lang3.builder.ToStringStyle;
7 7 import com.ruoyi.common.core.domain.BaseEntity;
8 8 import com.ruoyi.common.xss.Xss;
9 9  
  10 +import java.util.Date;
  11 +
10 12 /**
11 13 * 通知公告表 sys_notice
12 14 *
... ... @@ -34,6 +36,26 @@ public class SysNotice extends BaseEntity
34 36 /** 公告状态(0正常 1关闭) */
35 37 private String status;
36 38  
  39 + private String jobCode;
  40 +
  41 + public String getJobCode() {
  42 + return jobCode;
  43 + }
  44 +
  45 + public void setJobCode(String jobCode) {
  46 + this.jobCode = jobCode;
  47 + }
  48 +
  49 + public Date getPlanTime() {
  50 + return planTime;
  51 + }
  52 +
  53 + public void setPlanTime(Date planTime) {
  54 + this.planTime = planTime;
  55 + }
  56 +
  57 + private Date planTime;
  58 +
37 59 public Long getNoticeId()
38 60 {
39 61 return noticeId;
... ... @@ -98,6 +120,8 @@ public class SysNotice extends BaseEntity
98 120 .append("updateBy", getUpdateBy())
99 121 .append("updateTime", getUpdateTime())
100 122 .append("remark", getRemark())
  123 + .append("jobCode", getJobCode())
  124 + .append("planTime", getPlanTime())
101 125 .toString();
102 126 }
103 127 }
... ...
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysNoticeMapper.java
... ... @@ -2,6 +2,7 @@ package com.ruoyi.system.mapper;
2 2  
3 3 import java.util.List;
4 4 import com.ruoyi.system.domain.SysNotice;
  5 +import org.apache.ibatis.annotations.Param;
5 6  
6 7 /**
7 8 * 通知公告表 数据层
... ... @@ -60,8 +61,14 @@ public interface SysNoticeMapper
60 61  
61 62 /**
62 63 * 获取当前用户未读通告
63   - * @param username
  64 + * @param type
64 65 * @return
65 66 */
66   - List<SysNotice> getAlarmNotice(String username);
  67 + List<SysNotice> getAlarmNoticeByType(@Param("type") Integer type);
  68 +
  69 + /**
  70 + * 批量保存
  71 + * @param noticeList
  72 + */
  73 + void saveBatch(@Param("list") List<SysNotice> noticeList);
67 74 }
... ...
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysNoticeService.java
... ... @@ -60,8 +60,16 @@ public interface ISysNoticeService
60 60  
61 61 /**
62 62 * 获取当前用户为已读的通告
  63 + *
63 64 * @param username
  65 + * @param type
64 66 * @return
65 67 */
66   - SysNotice getAlarmNotice(String username);
  68 + SysNotice getAlarmNotice(String username, Integer type);
  69 +
  70 + /**
  71 + * 批量插入
  72 + * @param noticeList
  73 + */
  74 + void saveBatch(List<SysNotice> noticeList);
67 75 }
... ...
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysNoticeServiceImpl.java
... ... @@ -3,6 +3,7 @@ package com.ruoyi.system.service.impl;
3 3 import java.util.List;
4 4  
5 5 import com.ruoyi.common.utils.StringUtils;
  6 +import org.apache.commons.collections4.CollectionUtils;
6 7 import org.springframework.beans.factory.annotation.Autowired;
7 8 import org.springframework.stereotype.Service;
8 9 import com.ruoyi.system.domain.SysNotice;
... ... @@ -11,98 +12,97 @@ import com.ruoyi.system.service.ISysNoticeService;
11 12  
12 13 /**
13 14 * 公告 服务层实现
14   - *
  15 + *
15 16 * @author ruoyi
16 17 */
17 18 @Service
18   -public class SysNoticeServiceImpl implements ISysNoticeService
19   -{
  19 +public class SysNoticeServiceImpl implements ISysNoticeService {
20 20 @Autowired
21 21 private SysNoticeMapper noticeMapper;
22 22  
23 23 /**
24 24 * 查询公告信息
25   - *
  25 + *
26 26 * @param noticeId 公告ID
27 27 * @return 公告信息
28 28 */
29 29 @Override
30   - public SysNotice selectNoticeById(Long noticeId)
31   - {
  30 + public SysNotice selectNoticeById(Long noticeId) {
32 31 return noticeMapper.selectNoticeById(noticeId);
33 32 }
34 33  
35 34 /**
36 35 * 查询公告列表
37   - *
  36 + *
38 37 * @param notice 公告信息
39 38 * @return 公告集合
40 39 */
41 40 @Override
42   - public List<SysNotice> selectNoticeList(SysNotice notice)
43   - {
  41 + public List<SysNotice> selectNoticeList(SysNotice notice) {
44 42 return noticeMapper.selectNoticeList(notice);
45 43 }
46 44  
47 45 /**
48 46 * 新增公告
49   - *
  47 + *
50 48 * @param notice 公告信息
51 49 * @return 结果
52 50 */
53 51 @Override
54   - public int insertNotice(SysNotice notice)
55   - {
  52 + public int insertNotice(SysNotice notice) {
56 53 return noticeMapper.insertNotice(notice);
57 54 }
58 55  
59 56 /**
60 57 * 修改公告
61   - *
  58 + *
62 59 * @param notice 公告信息
63 60 * @return 结果
64 61 */
65 62 @Override
66   - public int updateNotice(SysNotice notice)
67   - {
  63 + public int updateNotice(SysNotice notice) {
68 64 return noticeMapper.updateNotice(notice);
69 65 }
70 66  
71 67 /**
72 68 * 删除公告对象
73   - *
  69 + *
74 70 * @param noticeId 公告ID
75 71 * @return 结果
76 72 */
77 73 @Override
78   - public int deleteNoticeById(Long noticeId)
79   - {
  74 + public int deleteNoticeById(Long noticeId) {
80 75 return noticeMapper.deleteNoticeById(noticeId);
81 76 }
82 77  
83 78 /**
84 79 * 批量删除公告信息
85   - *
  80 + *
86 81 * @param noticeIds 需要删除的公告ID
87 82 * @return 结果
88 83 */
89 84 @Override
90   - public int deleteNoticeByIds(Long[] noticeIds)
91   - {
  85 + public int deleteNoticeByIds(Long[] noticeIds) {
92 86 return noticeMapper.deleteNoticeByIds(noticeIds);
93 87 }
94 88  
95 89 @Override
96   - public SysNotice getAlarmNotice(String username) {
97   - List<SysNotice> noticeList = noticeMapper.getAlarmNotice(username);
98   - if (noticeList.size() > 0){
99   - for (int i = noticeList.size(); i >= 0; i--) {
100   - SysNotice notice = noticeList.get(0);
101   - if (StringUtils.isEmpty(notice.getRemark()) || !notice.getRemark().contains(username)){
  90 + public SysNotice getAlarmNotice(String username, Integer type) {
  91 + List<SysNotice> noticeList = noticeMapper.getAlarmNoticeByType(type);
  92 + if (CollectionUtils.isNotEmpty(noticeList)) {
  93 + for (SysNotice notice : noticeList) {
  94 + if (StringUtils.isEmpty(notice.getRemark()) || !notice.getRemark().contains(username)) {
102 95 return notice;
103 96 }
104 97 }
105 98 }
106 99 return null;
107 100 }
  101 +
  102 + @Override
  103 + public void saveBatch(List<SysNotice> noticeList) {
  104 + if (CollectionUtils.isNotEmpty(noticeList)) {
  105 + noticeMapper.saveBatch(noticeList);
  106 + }
  107 + }
108 108 }
... ...
ruoyi-system/src/main/resources/mapper/system/SysNoticeMapper.xml
... ... @@ -41,11 +41,13 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
41 41 </if>
42 42 </where>
43 43 </select>
44   - <select id="getAlarmNotice" resultType="com.ruoyi.system.domain.SysNotice">
  44 + <select id="getAlarmNoticeByType" resultType="com.ruoyi.system.domain.SysNotice">
45 45 select * from sys_notice
  46 + where DATE_FORMAT(create_time,'%y-%m-%d') = DATE_FORMAT(now(),'%y-%m-%d')
  47 + <if test="type != null">
  48 + and notice_type = #{type}
  49 + </if>
46 50 order by create_time desc
47   - limit 10
48   -
49 51 </select>
50 52  
51 53 <insert id="insertNotice" parameterType="SysNotice">
... ... @@ -67,7 +69,35 @@ PUBLIC &quot;-//mybatis.org//DTD Mapper 3.0//EN&quot;
67 69 sysdate()
68 70 )
69 71 </insert>
70   -
  72 + <insert id="saveBatch">
  73 + insert into sys_notice (
  74 + notice_title,
  75 + notice_type,
  76 + notice_content,
  77 + status,
  78 + remark,
  79 + create_by,
  80 + job_code,
  81 + plan_time,
  82 + create_time
  83 + )values
  84 + <foreach collection="list" index="index" item="item" separator=",">
  85 + (
  86 + #{item.noticeTitle},
  87 + #{item.noticeType},
  88 + #{item.noticeContent},
  89 + #{item.status},
  90 + #{item.remark},
  91 + #{item.createBy},
  92 + #{item.jobCode},
  93 + #{item.planTime},
  94 + sysdate()
  95 + )
  96 + </foreach>
  97 + on duplicate key update
  98 + job_code = values(job_code)
  99 + </insert>
  100 +
71 101 <update id="updateNotice" parameterType="SysNotice">
72 102 update sys_notice
73 103 <set>
... ...