diff --git a/ruoyi-admin/src/main/java/org/dromara/web/controller/HomeController.java b/ruoyi-admin/src/main/java/org/dromara/web/controller/HomeController.java index 37f85f7..3da0bd4 100644 --- a/ruoyi-admin/src/main/java/org/dromara/web/controller/HomeController.java +++ b/ruoyi-admin/src/main/java/org/dromara/web/controller/HomeController.java @@ -54,16 +54,23 @@ public class HomeController { bizStatCateService.statByDate(cateBo); - BizReportInfoBo bo = new BizReportInfoBo(); - bo.setOldType("dcl"); if (user.getRolePermission().contains("report_manager")){ + BizReportInfoBo bo = new BizReportInfoBo(); + bo.setOldType("dcl"); bo.setOldTable("xxbs"); + result.put("dbxxbslist", bizReportInfoService.queryPageList(bo, pageQuery)); }else{ - bo.setOldTable("xxcl"); + result.put("dbxxbslist", null); } - result.put("dblist", bizReportInfoService.queryPageList(bo, pageQuery)); - + if (user.getRolePermission().contains("report_user")){ + BizReportInfoBo bo2 = new BizReportInfoBo(); + bo2.setOldType("dcl"); + bo2.setOldTable("xxcl"); + result.put("dbxxcllist", bizReportInfoService.queryPageList(bo2, pageQuery)); + }else{ + result.put("dbxxcllist", null); + } return R.ok(result); } diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 97da963..96e24dc 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -52,7 +52,7 @@ spring: url: jdbc:mysql://127.0.0.1:3306/xxbsdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true # url: jdbc:mysql://192.168.0.49:3306/xxbsdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root - password: root + password: ruansee # type: ${spring.datasource.type} # driverClassName: org.postgresql.Driver # url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index 279501a..6190705 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -55,7 +55,7 @@ spring: url: jdbc:mysql://127.0.0.1:3306/xxbsdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true # url: jdbc:mysql://192.168.0.49:3306/xxbsdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root - password: root + password: ruansee # # 从库数据源 # slave: # lazy: true diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 3142f4e..c0bcfb0 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -76,9 +76,9 @@ spring: servlet: multipart: # 单个文件大小 - max-file-size: 10MB + max-file-size: 100MB # 设置总上传的文件大小 - max-request-size: 20MB + max-request-size: 200MB mvc: # 设置静态资源路径 防止所有请求都去查静态资源 static-path-pattern: /static/** diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Helper.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Helper.java index e7ba225..6878d9c 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Helper.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/Helper.java @@ -108,7 +108,7 @@ public class Helper { Pattern p1 = null; Pattern p2 = null; Matcher m = null; - p1 = Pattern.compile("^((1[3-9]{1})+\\d{8})?$"); + p1 = Pattern.compile("^((1[3-9]{1})+\\d{9})?$"); p2 = Pattern.compile("^(0[0-9]{2,3}\\-)?([1-9][0-9]{6,7})$"); if("0".equals(checkType)){ System.out.println(phoneNum.length()); diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml index 86a2dfa..38203a0 100644 --- a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml +++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-dev.yml @@ -5,7 +5,7 @@ spring: url: jdbc:mysql://127.0.0.1:3306/xxbsdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true # url: jdbc:mysql://192.168.0.49:3306/xxbsdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root - password: root + password: ruansee # type: com.zaxxer.hikari.HikariDataSource # driver-class-name: org.postgresql.Driver # url: jdbc:postgresql://localhost:5432/postgres?useUnicode=true&characterEncoding=utf8&useSSL=true&autoReconnect=true&reWriteBatchedInserts=true diff --git a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml index 7f9d1f5..12209af 100644 --- a/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml +++ b/ruoyi-extend/ruoyi-snailjob-server/src/main/resources/application-prod.yml @@ -5,7 +5,7 @@ spring: url: jdbc:mysql://127.0.0.1:3306/xxbsdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true # url: jdbc:mysql://192.168.0.49:3306/xxbsdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root - password: root + password: ruansee hikari: connection-timeout: 30000 validation-timeout: 5000 diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/controller/BizDutyController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/controller/BizDutyController.java index d497ef9..7213c94 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/controller/BizDutyController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/controller/BizDutyController.java @@ -6,6 +6,8 @@ import lombok.RequiredArgsConstructor; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.constraints.*; import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.common.core.utils.Helper; +import org.dromara.common.satoken.utils.LoginHelper; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import org.dromara.common.idempotent.annotation.RepeatSubmit; @@ -42,6 +44,8 @@ public class BizDutyController extends BaseController { @SaCheckPermission("biz:duty:list") @GetMapping("/list") public TableDataInfo list(BizDutyBo bo, PageQuery pageQuery) { + if (bo.getDeptId()==null || Helper.NStr(bo.getDeptId()).equals("")) + bo.setDeptId(LoginHelper.getDeptId()); return bizDutyService.queryPageList(bo, pageQuery); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/controller/RPAController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/controller/RPAController.java index 4ed85dd..27816f0 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/controller/RPAController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/controller/RPAController.java @@ -63,7 +63,7 @@ public class RPAController extends BaseController { */ @GetMapping("/smstest") public R smstest() { - return R.ok(SmsUtils.sendSMS("18655101696", "您有一条新的报送信息待处理,请前往查看")); + return R.ok(SmsUtils.sendSMS("18655101696", "您有一条新的信息待签收,请前往综合情报信息报送处理系统处理")); } /** diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizDutyServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizDutyServiceImpl.java index a0f2f37..12be19a 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizDutyServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizDutyServiceImpl.java @@ -6,7 +6,10 @@ import org.dromara.common.core.service.DeptService; import org.dromara.common.core.service.UserService; import org.dromara.common.core.utils.Helper; import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.annotation.DataColumn; +import org.dromara.common.mybatis.annotation.DataPermission; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -14,6 +17,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.system.domain.SysDept; +import org.dromara.system.domain.SysUser; +import org.dromara.system.mapper.SysDeptMapper; import org.dromara.system.mapper.SysUserMapper; import org.springframework.stereotype.Service; import org.dromara.biz.domain.bo.BizDutyBo; @@ -44,6 +50,7 @@ public class BizDutyServiceImpl implements IBizDutyService { private final DeptService deptService; private final SysUserMapper userMapper; + private final SysDeptMapper deptMapper; /** * 查询值班信息 @@ -54,10 +61,14 @@ public class BizDutyServiceImpl implements IBizDutyService { @Override public BizDutyVo queryById(Long id){ BizDutyVo duty = baseMapper.selectVoById(id); - duty.setLeader(userMapper.selectById(duty.getLeaderId())); - duty.setChairman(userMapper.selectById(duty.getChairmanId())); - duty.setMonitor(userMapper.selectById(duty.getMonitorId())); - duty.setWatchkeeperList(userMapper.selectByIds(convertIds(duty.getWatchkeeperIds()))); + if (Helper.FInt(duty.getLeaderId())>0) + duty.setLeader(userMapper.selectById(duty.getLeaderId())); + if (Helper.FInt(duty.getChairmanId())>0) + duty.setChairman(userMapper.selectById(duty.getChairmanId())); + if (Helper.FInt(duty.getMonitorId())>0) + duty.setMonitor(userMapper.selectById(duty.getMonitorId())); + if (duty.getWatchkeeperIds()!=null && duty.getWatchkeeperIds().length()>0) + duty.setWatchkeeperList(userMapper.selectByIds(convertIds(duty.getWatchkeeperIds()))); return duty; } @@ -79,6 +90,9 @@ public class BizDutyServiceImpl implements IBizDutyService { * @return 值班信息分页列表 */ @Override + @DataPermission({ + @DataColumn(key = "deptName", value = "dept_id"), + }) public TableDataInfo queryPageList(BizDutyBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); @@ -92,6 +106,9 @@ public class BizDutyServiceImpl implements IBizDutyService { * @return 值班信息列表 */ @Override + @DataPermission({ + @DataColumn(key = "deptName", value = "dept_id"), + }) public List queryList(BizDutyBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); @@ -104,7 +121,15 @@ public class BizDutyServiceImpl implements IBizDutyService { lqw.eq(bo.getDutyDate() != null, BizDuty::getDutyDate, bo.getDutyDate()); lqw.between(params.get("beginDutyDate") != null && params.get("endDutyDate") != null, BizDuty::getDutyDate ,params.get("beginDutyDate"), params.get("endDutyDate")); - lqw.eq(StringUtils.isNotBlank(bo.getDeptId()), BizDuty::getDeptId, bo.getDeptId()); + + if (bo.getDeptId()!=null && !Helper.NStr(bo.getDeptId()).equals("")) { + List deptList = deptMapper.selectListByParentId(bo.getDeptId()); + List ids = StreamUtils.toList(deptList, SysDept::getDeptId); + ids.add(bo.getDeptId()); + lqw.in(BizDuty::getDeptId, ids); + } + +// lqw.eq(StringUtils.isNotBlank(bo.getDeptId()), BizDuty::getDeptId, bo.getDeptId()); lqw.like(StringUtils.isNotBlank(bo.getDeptName()), BizDuty::getDeptName, bo.getDeptName()); lqw.eq(bo.getLeaderId() != null, BizDuty::getLeaderId, bo.getLeaderId()); lqw.like(StringUtils.isNotBlank(bo.getLeaderName()), BizDuty::getLeaderName, bo.getLeaderName()); @@ -137,10 +162,14 @@ public class BizDutyServiceImpl implements IBizDutyService { add.setDeptId(user.getDeptId()); add.setCreateUserId(user.getUserId()); - add.setLeaderName(userService.selectNicknameById(add.getLeaderId())); - add.setChairmanName(userService.selectNicknameById(add.getChairmanId())); - add.setMonitorName(userService.selectNicknameById(add.getMonitorId())); - add.setWatchkeeperNames(userService.selectNicknameByIds(add.getWatchkeeperIds())); + if (Helper.FInt(add.getLeaderId())>0) + add.setLeaderName(userService.selectNicknameById(add.getLeaderId())); + if (Helper.FInt(add.getChairmanId())>0) + add.setChairmanName(userService.selectNicknameById(add.getChairmanId())); + if (Helper.FInt(add.getMonitorId())>0) + add.setMonitorName(userService.selectNicknameById(add.getMonitorId())); + if (add.getWatchkeeperIds()!=null && add.getWatchkeeperIds().length()>0) + add.setWatchkeeperNames(userService.selectNicknameByIds(add.getWatchkeeperIds())); add.setDeptName(user.getDeptName()); validEntityBeforeSave(add); @@ -160,13 +189,13 @@ public class BizDutyServiceImpl implements IBizDutyService { @Override public Boolean updateByBo(BizDutyBo bo) { BizDuty update = MapstructUtils.convert(bo, BizDuty.class); - if(update.getLeaderId()!=null) + if (Helper.FInt(update.getLeaderId())>0) update.setLeaderName(userService.selectNicknameById(update.getLeaderId())); - if(update.getChairmanId()!=null) + if (Helper.FInt(update.getChairmanId())>0) update.setChairmanName(userService.selectNicknameById(update.getChairmanId())); - if(update.getMonitorId()!=null) + if (Helper.FInt(update.getMonitorId())>0) update.setMonitorName(userService.selectNicknameById(update.getMonitorId())); - if(update.getWatchkeeperIds()!=null) + if (update.getWatchkeeperIds()!=null && update.getWatchkeeperIds().length()>0) update.setWatchkeeperNames(userService.selectNicknameByIds(update.getWatchkeeperIds())); // update.setDeptName(deptService.selectDeptNameByIds(update.getDeptId())); validEntityBeforeSave(update); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizIcdsNoticeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizIcdsNoticeServiceImpl.java index 39f9fd2..7f5e625 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizIcdsNoticeServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizIcdsNoticeServiceImpl.java @@ -71,7 +71,7 @@ public class BizIcdsNoticeServiceImpl implements IBizIcdsNoticeService { private LambdaQueryWrapper buildQueryWrapper(BizIcdsNoticeBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByAsc(BizIcdsNotice::getId); + lqw.orderByDesc(BizIcdsNotice::getSendTime); lqw.eq(StringUtils.isNotBlank(bo.getOldId()), BizIcdsNotice::getOldId, bo.getOldId()); lqw.eq(StringUtils.isNotBlank(bo.getTitle()), BizIcdsNotice::getTitle, bo.getTitle()); lqw.eq(StringUtils.isNotBlank(bo.getFileUrl()), BizIcdsNotice::getFileUrl, bo.getFileUrl()); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizReportInfoServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizReportInfoServiceImpl.java index 5d32db0..54af8c4 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizReportInfoServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizReportInfoServiceImpl.java @@ -1,5 +1,8 @@ package org.dromara.biz.service.impl; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; import org.dromara.biz.domain.*; import org.dromara.biz.domain.bo.BizReportReceiverBo; import org.dromara.biz.domain.vo.BizReportReceiverVo; @@ -33,9 +36,12 @@ import org.dromara.biz.domain.bo.BizReportInfoBo; import org.dromara.biz.domain.vo.BizReportInfoVo; import org.dromara.biz.service.IBizReportInfoService; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * 报送信息Service业务层处理 @@ -45,6 +51,7 @@ import java.util.concurrent.TimeUnit; */ @RequiredArgsConstructor @Service +@Slf4j public class BizReportInfoServiceImpl implements IBizReportInfoService { private final BizReportInfoMapper baseMapper; @@ -167,8 +174,8 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService { }else { if (table.equals("xxcl")) { lqw.and(w -> { -// w.eq(user.getDeptId()!=null, BizReportInfo::getReportDeptId, user.getDeptId()); - w.likeRight(BizReportInfo::getReportDeptId, Helper.PrefixDeptid(user.getDeptId())); + w.eq(user.getDeptId()!=null, BizReportInfo::getReportDeptId, user.getDeptId()); +// w.eq(BizReportInfo::getReportDeptId, Helper.PrefixDeptid(user.getDeptId())); w.or(ww -> { ww.exists("select id from biz_report_receiver where dept_id = '" + Helper.NStr(user.getDeptId()) + "' and report_id = v.id "); }); @@ -219,15 +226,23 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService { if (bo.getOldTable().equals("xxbs")){ SysDept dept = deptMapper.selectById(deptid); String sjdept = dept.getParentId(); //deptid.substring(0, 4)+"00000000"; - BizReportReceiver receiver = new BizReportReceiver(); - receiver.setReportId(bo.getId()); - receiver.setDeptId(sjdept); - receiver.setDeptName(deptMapper.selectVoById(sjdept).getDeptName()); - receiver.setSendDeptId(user.getDeptId()); - receiver.setSendDeptName(deptMapper.selectVoById(user.getDeptId()).getDeptName()); + if (sjdept.equals("0")){ + bo.setReceiverDeptIds(null); + BizReportInfo dbinfo = new BizReportInfo(); + dbinfo.setId(bo.getId()); + dbinfo.setStatus(ReportInfoStatusEnum.FINISH.getStatus()); + baseMapper.updateById(dbinfo); + }else { + BizReportReceiver receiver = new BizReportReceiver(); + receiver.setReportId(bo.getId()); + receiver.setDeptId(sjdept); + receiver.setDeptName(deptMapper.selectVoById(sjdept).getDeptName()); + receiver.setSendDeptId(user.getDeptId()); + receiver.setSendDeptName(deptMapper.selectVoById(user.getDeptId()).getDeptName()); - bo.setReceiverDeptIds(new String[]{ sjdept }); - receiverMapper.insert(receiver); + bo.setReceiverDeptIds(new String[]{sjdept}); + receiverMapper.insert(receiver); + } } } @@ -265,20 +280,35 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService { SysUserBo userBo = new SysUserBo(); userBo.setDeptIds(bo.getReceiverDeptIds()); List list = userService.selectUserIdList(userBo); - List userIds = StreamUtils.toList(list, SysUserVo::getUserId); - scheduledExecutorService.schedule(() -> { - SseMessageDto dto = new SseMessageDto(); - dto.setMessage("您有新的待办信息,请前往查看!"); - dto.setType("todo"); - dto.setUserIds(userIds); - SseMessageUtils.publishMessage(dto); - }, 5, TimeUnit.SECONDS); + if(list!=null && list.size()>0) { + List userIds = StreamUtils.toList(list, SysUserVo::getUserId); - for (SysUserVo userVo : list) { - String phone = Helper.NStr(userVo.getPhonenumber()); - if (Helper.validPhoneNum("0", phone)){ - SmsUtils.sendSMS(phone, "您有一条新的报送信息待处理,请前往查看"); + String userIdStr = userIds.stream() + .map(item -> "" + item + "") + .collect(Collectors.joining(",")); + + HashMap item = new HashMap(); + item.put("id", bo.getId()); + item.put("title", bo.getTitle()); + item.put("time", bo.getReportTime()); + item.put("userIds", userIdStr); + log.info("推送任务: " + JSONUtil.toJsonStr(item)); + + scheduledExecutorService.schedule(() -> { + SseMessageDto dto = new SseMessageDto(); + dto.setMessage("您有新的待办信息,请前往查看!"); + dto.setType("todo"); + dto.setUserIds(userIds); + SseMessageUtils.publishMessage(dto); + }, 1, TimeUnit.SECONDS); + + for (SysUserVo userVo : list) { + String phone = Helper.NStr(userVo.getPhonenumber()); + if (Helper.validPhoneNum("0", phone)) { + + SmsUtils.sendSMS(phone, "您有一条新的信息待签收,请前往综合情报信息报送处理系统处理"); + } } } } @@ -435,7 +465,15 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(bo.getCategoryId() != null, BizReportInfo::getCategoryId, bo.getCategoryId()); lqw.eq(BizReportInfo::getReportDeptId, user.getDeptId()); - lqw.between(BizReportInfo::getReportTime , "", ""); + + LocalDate now = LocalDate.now(); + LocalDate first = now.withDayOfYear(1); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + String firstDay = first.format(formatter) + " 00:00:00"; + String lastDay = now.format(formatter) + " 23:59:59"; + System.out.println(firstDay + " ========= " + lastDay); + + lqw.between(BizReportInfo::getReportTime , firstDay, lastDay); int count = Helper.FInt(baseMapper.selectCount(lqw)); String result = String.format("%0" + 4 + "d", count+1); @@ -488,20 +526,33 @@ public class BizReportInfoServiceImpl implements IBizReportInfoService { SysUserBo userBo = new SysUserBo(); userBo.setDeptIds(bo.getReportInfo().getReceiverDeptIds()); List list = userService.selectUserIdList(userBo); - List userIds = StreamUtils.toList(list, SysUserVo::getUserId); + if(list!=null && list.size()>0) { + List userIds = StreamUtils.toList(list, SysUserVo::getUserId); - scheduledExecutorService.schedule(() -> { - SseMessageDto dto = new SseMessageDto(); - dto.setMessage("您有新的待办信息,请前往查看!"); - dto.setType("todo"); - dto.setUserIds(userIds); - SseMessageUtils.publishMessage(dto); - }, 5, TimeUnit.SECONDS); + String userIdStr = userIds.stream() + .map(item -> "" + item + "") + .collect(Collectors.joining(",")); - for (SysUserVo userVo : list) { - String phone = Helper.NStr(userVo.getPhonenumber()); - if (Helper.validPhoneNum("0", phone)){ - SmsUtils.sendSMS(phone, "您有一条新的报送信息待处理,请前往查看"); + HashMap item = new HashMap(); + item.put("id", bo.getReportId()); + item.put("title", "分局下发派出所"); + item.put("time", new Date()); + item.put("userIds", userIdStr); + log.info("推送任务: " + JSONUtil.toJsonStr(item)); + + scheduledExecutorService.schedule(() -> { + SseMessageDto dto = new SseMessageDto(); + dto.setMessage("您有新的待办信息,请前往查看!"); + dto.setType("todo"); + dto.setUserIds(userIds); + SseMessageUtils.publishMessage(dto); + }, 5, TimeUnit.SECONDS); + + for (SysUserVo userVo : list) { + String phone = Helper.NStr(userVo.getPhonenumber()); + if (Helper.validPhoneNum("0", phone)) { + SmsUtils.sendSMS(phone, "您有一条新的信息待签收,请前往综合情报信息报送处理系统处理"); + } } } } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizReportReceiverServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizReportReceiverServiceImpl.java index efa8533..11fd41b 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizReportReceiverServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/biz/service/impl/BizReportReceiverServiceImpl.java @@ -1,5 +1,7 @@ package org.dromara.biz.service.impl; +import cn.hutool.json.JSONUtil; +import lombok.extern.slf4j.Slf4j; import org.dromara.biz.domain.BizReportInfo; import org.dromara.biz.domain.BizReportReply; import org.dromara.biz.mapper.BizReportInfoMapper; @@ -9,6 +11,7 @@ import org.dromara.common.core.enums.ReportInfoStatusEnum; import org.dromara.common.core.enums.ReportLogTypeEnum; import org.dromara.common.core.utils.Helper; import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.PageQuery; @@ -17,6 +20,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.common.sse.dto.SseMessageDto; +import org.dromara.common.sse.utils.SseMessageUtils; +import org.dromara.system.domain.bo.SysUserBo; +import org.dromara.system.domain.vo.SysUserVo; +import org.dromara.system.service.ISysUserService; import org.springframework.stereotype.Service; import org.dromara.biz.domain.bo.BizReportReceiverBo; import org.dromara.biz.domain.vo.BizReportReceiverVo; @@ -24,10 +32,10 @@ import org.dromara.biz.domain.BizReportReceiver; import org.dromara.biz.mapper.BizReportReceiverMapper; import org.dromara.biz.service.IBizReportReceiverService; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Collection; +import java.util.*; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * 报送记录接收单位Service业务层处理 @@ -37,6 +45,7 @@ import java.util.Collection; */ @RequiredArgsConstructor @Service +@Slf4j public class BizReportReceiverServiceImpl implements IBizReportReceiverService { private final BizReportReceiverMapper baseMapper; @@ -44,6 +53,10 @@ public class BizReportReceiverServiceImpl implements IBizReportReceiverService { private final IBizReportLogService logService; + private final ISysUserService userService; + + private final ScheduledExecutorService scheduledExecutorService; + /** * 查询报送记录接收单位 * @@ -189,24 +202,56 @@ public class BizReportReceiverServiceImpl implements IBizReportReceiverService { // 添加日志 logService.saveLog(bo.getReportId(), ReportLogTypeEnum.SIGN.getStatus(), bo.getId().toString(), "签收"); - LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); - lqw.eq(BizReportReceiver::getReportId, bo.getReportId()); - lqw.eq(BizReportReceiver::getIsSign, 0); - Long notSignCount = baseMapper.selectCount(lqw); + BizReportInfo dbinfo = reportInfoMapper.selectById(bo.getReportId()); BizReportInfo info = new BizReportInfo(); info.setId(bo.getReportId()); - if (Helper.FInt(notSignCount)>0) - info.setStatus(ReportInfoStatusEnum.ANY_SIGN.getStatus()); - else { - LambdaQueryWrapper lqw2 = new LambdaQueryWrapper<>(); - lqw2.eq(BizReportReceiver::getReportId, bo.getReportId()); - lqw2.eq(BizReportReceiver::getIsFeedback, 1); - Long replyCount = baseMapper.selectCount(lqw2); - if (replyCount>0) - info.setStatus(ReportInfoStatusEnum.ANY_REPLY.getStatus()); - else - info.setStatus(ReportInfoStatusEnum.WAITING_REPLY.getStatus()); + + String[] deptIds = new String[]{ user.getDeptId() }; + SysUserBo userBo = new SysUserBo(); + userBo.setDeptIds(deptIds); + List list = userService.selectUserIdList(userBo); + List userIds = StreamUtils.toList(list, SysUserVo::getUserId); + + String userIdStr = userIds.stream() + .map(item -> "" + item + "") + .collect(Collectors.joining(",")); + + HashMap item = new HashMap(); + item.put("id", bo.getReportId()); + item.put("title", dbinfo.getTitle()); + item.put("time", new Date()); + item.put("userIds", userIdStr); + log.info("停止推送任务: "+ JSONUtil.toJsonStr(item)); + + scheduledExecutorService.schedule(() -> { + SseMessageDto dto = new SseMessageDto(); + dto.setMessage("停止播放提醒!"); + dto.setType("stop"); + dto.setUserIds(userIds); + SseMessageUtils.publishMessage(dto); + }, 1, TimeUnit.SECONDS); + + if (dbinfo.getOldTable().equals("xxbs")){ + info.setStatus(ReportInfoStatusEnum.FINISH.getStatus()); + }else { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + lqw.eq(BizReportReceiver::getReportId, bo.getReportId()); + lqw.eq(BizReportReceiver::getIsSign, 0); + Long notSignCount = baseMapper.selectCount(lqw); + + if (Helper.FInt(notSignCount) > 0) + info.setStatus(ReportInfoStatusEnum.ANY_SIGN.getStatus()); + else { + LambdaQueryWrapper lqw2 = new LambdaQueryWrapper<>(); + lqw2.eq(BizReportReceiver::getReportId, bo.getReportId()); + lqw2.eq(BizReportReceiver::getIsFeedback, 1); + Long replyCount = baseMapper.selectCount(lqw2); + if (replyCount > 0) + info.setStatus(ReportInfoStatusEnum.ANY_REPLY.getStatus()); + else + info.setStatus(ReportInfoStatusEnum.WAITING_REPLY.getStatus()); + } } reportInfoMapper.updateById(info); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java index cc03fbb..c62e7f8 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysUserController.java @@ -11,6 +11,7 @@ import lombok.RequiredArgsConstructor; import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.model.LoginUser; +import org.dromara.common.core.utils.Helper; import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.encrypt.annotation.ApiEncrypt; @@ -23,6 +24,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.tenant.helper.TenantHelper; import org.dromara.common.web.core.BaseController; +import org.dromara.system.domain.SysDept; import org.dromara.system.domain.bo.SysDeptBo; import org.dromara.system.domain.bo.SysPostBo; import org.dromara.system.domain.bo.SysRoleBo; @@ -111,6 +113,12 @@ public class SysUserController extends BaseController { TenantHelper.clearDynamic(); } SysUserVo user = userService.selectUserById(loginUser.getUserId()); + SysDeptVo dept = deptService.selectDeptById(user.getDeptId()); + String shortName = Helper.NStr(dept.getShortName()); + String deptName = Helper.NStr(dept.getDeptName()); + shortName = shortName.equals("") ? deptName : shortName; + user.setDeptShortName(shortName); + if (ObjectUtil.isNull(user)) { return R.fail("没有权限访问用户数据!"); } @@ -297,4 +305,12 @@ public class SysUserController extends BaseController { return R.ok(userService.selectUserListByDept(deptId)); } + /** + * 获取部门下的所有用户信息 + */ +// @SaCheckPermission("system:user:list") + @GetMapping("/listNotLeader/dept/{deptId}") + public R> listNotLeaderByDept(@PathVariable @NotNull String deptId) { + return R.ok(userService.selectUserListNotLeaderByDept(deptId)); + } } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java index 9b7fe03..f34085c 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysUser.java @@ -111,6 +111,11 @@ public class SysUser extends TenantEntity { */ private String remark; + /** + * 显示顺序 + */ + private Integer orderNum; + public SysUser(Long userId) { this.userId = userId; diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java index 7afadc9..8540a31 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysUserBo.java @@ -3,6 +3,7 @@ package org.dromara.system.domain.bo; import io.github.linpeilie.annotations.AutoMapper; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Data; import lombok.EqualsAndHashCode; @@ -130,4 +131,10 @@ public class SysUserBo extends BaseEntity { */ private String[] deptIds; + /** + * 显示顺序 + */ + @NotNull(message = "显示顺序不能为空") + private Integer orderNum; + } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java index 47700cc..a43f16a 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysUserVo.java @@ -152,4 +152,13 @@ public class SysUserVo implements Serializable { */ private Long roleId; + /** + * 部门简称 + */ + private String deptShortName; + + /** + * 显示顺序 + */ + private Integer orderNum; } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java index 56bef66..4bce915 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/SysUserMapper.java @@ -48,6 +48,9 @@ public interface SysUserMapper extends BaseMapperPlus { }) List selectUserList(@Param(Constants.WRAPPER) Wrapper queryWrapper); + + List selectBaseUserList(@Param(Constants.WRAPPER) Wrapper queryWrapper); + /** * 根据条件分页查询用户列表 * diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java index 04e3a66..efda5ec 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java @@ -221,4 +221,12 @@ public interface ISysUserService { * @return 结果 */ List selectUserListByDept(String deptId); + + /** + * 通过部门id查询当前部门所有用户(非领导 不是局领导角色用户) + * + * @param deptId 部门id + * @return 结果 + */ + List selectUserListNotLeaderByDept(String deptId); } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java index 18349a2..33e5fec 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDataScopeServiceImpl.java @@ -16,6 +16,7 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.util.List; +import java.util.stream.Collectors; /** * 数据权限 实现 @@ -50,6 +51,7 @@ public class SysDataScopeServiceImpl implements ISysDataScopeService { .eq(SysRoleDept::getRoleId, roleId)); if (CollUtil.isNotEmpty(list)) { return StreamUtils.join(list, rd -> Convert.toStr(rd.getDeptId())); + } return "-1"; } @@ -69,10 +71,15 @@ public class SysDataScopeServiceImpl implements ISysDataScopeService { List deptList = deptMapper.selectListByParentId(deptId); List ids = StreamUtils.toList(deptList, SysDept::getDeptId); ids.add(deptId); + if (CollUtil.isNotEmpty(ids)) { - return StreamUtils.join(ids, Convert::toStr); + String collect = ids.stream() + .map(item -> "'" + item + "'") + .collect(Collectors.joining(",")); + return collect; } return "-1"; } + } diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java index 2584fe1..c141e65 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java @@ -364,7 +364,7 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService { */ private void updateParentDeptStatusNormal(SysDept dept) { String ancestors = dept.getAncestors(); - Long[] deptIds = Convert.toLongArray(ancestors); + String[] deptIds = Convert.toStrArray(ancestors); baseMapper.update(null, new LambdaUpdateWrapper() .set(SysDept::getStatus, SystemConstants.NORMAL) .in(SysDept::getDeptId, Arrays.asList(deptIds))); diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java index 9cde6cd..9a70b0a 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java @@ -91,8 +91,9 @@ public class SysUserServiceImpl implements ISysUserService, UserService { } w.in("u.dept_id", ids); }) - .orderByAsc("u.user_id"); - List list = baseMapper.selectUserList(wrapper); + .orderByAsc("u.dept_id") + .orderByAsc("u.order_num"); + List list = baseMapper.selectBaseUserList(wrapper); return list; } @@ -123,7 +124,8 @@ public class SysUserServiceImpl implements ISysUserService, UserService { } w.in("u.dept_id", ids); }) - .orderByAsc("u.user_id"); + .orderByAsc("u.dept_id") + .orderByAsc("u.order_num"); if (StringUtils.isNotBlank(user.getExcludeUserIds())) { wrapper.notIn("u.user_id", StringUtils.splitTo(user.getExcludeUserIds(), Convert::toLong)); } @@ -144,7 +146,8 @@ public class SysUserServiceImpl implements ISysUserService, UserService { .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) .eq(StringUtils.isNotBlank(user.getStatus()), "u.status", user.getStatus()) .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) - .orderByAsc("u.user_id"); + .orderByAsc("u.dept_id") + .orderByAsc("u.order_num"); Page page = baseMapper.selectAllocatedList(pageQuery.build(), wrapper); return TableDataInfo.build(page); } @@ -164,7 +167,8 @@ public class SysUserServiceImpl implements ISysUserService, UserService { .notIn(CollUtil.isNotEmpty(userIds), "u.user_id", userIds) .like(StringUtils.isNotBlank(user.getUserName()), "u.user_name", user.getUserName()) .like(StringUtils.isNotBlank(user.getPhonenumber()), "u.phonenumber", user.getPhonenumber()) - .orderByAsc("u.user_id"); + .orderByAsc("u.dept_id") + .orderByAsc("u.order_num"); Page page = baseMapper.selectUnallocatedList(pageQuery.build(), wrapper); return TableDataInfo.build(page); } @@ -581,10 +585,62 @@ public class SysUserServiceImpl implements ISysUserService, UserService { public List selectUserListByDept(String deptId) { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(SysUser::getDeptId, deptId); - lqw.orderByAsc(SysUser::getUserId); + lqw.orderByAsc(SysUser::getOrderNum); return baseMapper.selectVoList(lqw); } + + /** + * 通过部门id查询当前部门所有用户(非领导 不是局领导角色用户) + * + * @param deptId 部门ID + * @return 用户信息集合信息 + */ + @Override + public List selectUserListNotLeaderByDept(String deptId) { + + // 屏蔽局领导角色 + LambdaQueryWrapper lqwr = Wrappers.lambdaQuery(); + lqwr.eq(SysRole::getRoleKey, "leader"); + SysRole role = roleMapper.selectOne(lqwr); + +// SysUserBo userBo = new SysUserBo(); +// userBo.setDeptId(LoginHelper.getDeptId()); +// userBo.setRoleId(Helper.FLong(role.getRoleId())); +// PageQuery pageQuery = new PageQuery(1000, 1); +// +// TableDataInfo userpage = selectUnallocatedList(userBo, pageQuery); +// List users = userpage.getRows(); + + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + + List deptList = deptMapper.selectListByParentId(deptId); + List ids = StreamUtils.toList(deptList, SysDept::getDeptId); + ids.add(deptId); + lqw.in(SysUser::getDeptId, ids); + + lqw.orderByAsc(SysUser::getOrderNum); + List users = baseMapper.selectVoList(lqw); + + List result = new ArrayList<>(); + + List roleIds = new ArrayList<>(); + roleIds.add(1L); // 屏蔽超级管理员 + if (role!=null && Helper.FInt(role.getRoleId())>0) { + roleIds.add(role.getRoleId()); + } + + List userIds = selectUserIdsByRoleIds(roleIds); + for (SysUserVo user : users) { + if (userIds.contains(user.getUserId())) + continue; + else + result.add(user); + } + + return result; + } + /** * 通过用户ID查询用户账户 * diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml index 4b8a469..f4f1ea7 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml @@ -18,7 +18,7 @@ u.user_id, u.work_dept_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, - u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark + u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num from sys_user u ${ew.getCustomSqlSegment} @@ -31,7 +31,21 @@ u.user_id, u.work_dept_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, - u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark + u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num + + from sys_user u + ${ew.getCustomSqlSegment} + + + + select u.user_id, u.work_dept_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, - u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, + u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.order_num, d.dept_name, d.leader, wd.dept_name work_dept_name, u1.user_name as leaderName from sys_user u left join sys_dept d on u.dept_id = d.dept_id @@ -49,7 +63,7 @@