1cf88d43994ec7ec403319032a9d118b39fe3571..4513ef24bf9b188c2a77d6ce94f1a6b7e9ebf0e6
10 小时以前 zuoxiao
fix(irrigatePlan): 修正灌溉计划开始时间逻辑
4513ef 对比 | 目录
12 小时以前 zhubaomin
各轮灌组开阀时间提前10分钟,第一组除外,改为配置文件设置
d0b51c 对比 | 目录
13 小时以前 liurunyu
表阀一体机与测控一体阀协议中的阀门状态不兼容,做兼容处理。
7f85ca 对比 | 目录
17 小时以前 liurunyu
MyBatis拦截器测试修改
cdc35c 对比 | 目录
17 小时以前 liurunyu
虚拟卡占用状态设置拦截器修改
3d14a1 对比 | 目录
17 小时以前 liurunyu
虚拟卡占用状态设置拦截器修改
d3e363 对比 | 目录
17 小时以前 liurunyu
虚拟卡占用状态设置拦截器修改
c31cea 对比 | 目录
17 小时以前 liurunyu
MyBatis拦截器测试
880cb7 对比 | 目录
17 小时以前 liurunyu
MyBatis拦截器测试
20f9fa 对比 | 目录
20 小时以前 liurunyu
SSO登录逻辑再修改
7634d7 对比 | 目录
20 小时以前 liurunyu
SSO登录逻辑再修改
f44135 对比 | 目录
20 小时以前 liurunyu
SSO登录逻辑再修改
d5e287 对比 | 目录
20 小时以前 liurunyu
回退配置
4f99f5 对比 | 目录
20 小时以前 liurunyu
修改拦载器
ca2417 对比 | 目录
20 小时以前 liurunyu
@Value注解增加默认值
dc3a3b 对比 | 目录
21 小时以前 liurunyu
1、增加一个MyBatis拦截器,这个拦截器可配置启用,拦截器实现设置虚拟卡占用状态时,统一设置为非占用状态; 2、完善代码。
6a6fdb 对比 | 目录
10个文件已修改
5个文件已添加
366 ■■■■■ 已修改文件
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/global/GlParse.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mybatis/AutoGenerateIdInterceptor.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/MyBatisGlConfig.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/VirtualCardInUseInterceptor.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-common-web(121服务器).yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-common-web(233服务器).yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-common-web.yml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaUserMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoCtrl.java 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-temp/src/main/java/com/dy/pipIrrTemp/testFun/Test4VirtualCardSetInUseCtrl.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-temp/src/main/java/com/dy/pipIrrTemp/testFun/Test4VirtualCardSetInUseSv.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/irrigatePlan/IrrigatePlanCtrl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/irrigatePlan/IrrigatePlanSv.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/文档/README.md 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/global/GlParse.java
@@ -61,6 +61,14 @@
    public static void parseAlarmAndState(byte[] bs, int index, AlarmVo vo){
        byte b = bs[index] ;
        vo.statePump = (byte)(b & 0x1) ;
        //与测控一体阀兼容
        if(vo.statePump == 0){
            vo.statePump = (byte)1;
        }else{
            vo.statePump = (byte)0;
        }
        vo.alarmWaterRemain = (byte)((b >> 1) & 1) ;
        vo.alarm0WaterRemain = (byte)((b >> 2) & 1) ;
        vo.alarmExceedYear = (byte)((b >> 3) & 1) ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mybatis/AutoGenerateIdInterceptor.java
@@ -1,8 +1,5 @@
package com.dy.common.mybatis;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.dy.common.po.BaseEntity;
import com.dy.common.util.IDLongGenerator;
import org.apache.ibatis.executor.Executor;
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/MyBatisGlConfig.java
New file
@@ -0,0 +1,35 @@
package com.dy.pipIrrGlobal.config;
import jakarta.annotation.PostConstruct;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import java.util.List;
/**
 * @Author: liurunyu
 * @Date: 2025/4/27 9:31
 * @Description
 */
@Configuration
public class MyBatisGlConfig {
    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;
    @Value("${common.virtual_card_disable_set_inuse:false}")
    private Boolean disableSetInUse;
    /**
     * æ ¹æ®é…ç½®æ–‡ä»¶é…ç½®ï¼Œé…ç½®æ‹¦æˆªå™¨
     */
    @PostConstruct
    public void addMyInterceptor() {
        for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
            if (disableSetInUse != null && disableSetInUse.booleanValue()) {
                sqlSessionFactory.getConfiguration().addInterceptor(new VirtualCardInUseInterceptor());
            }
        }
    }
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/config/VirtualCardInUseInterceptor.java
New file
@@ -0,0 +1,61 @@
package com.dy.pipIrrGlobal.config;
/**
 * @Author: liurunyu
 * @Date: 2025/4/27 9:19
 * @Description
 */
import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import java.lang.reflect.Method;
/**
 * æ‹¦æˆªè™šæ‹Ÿå¡è¡¨çš„æ›´æ–°æ“ä½œï¼Œä½¿ä¸èƒ½è®¾ç½®å ç”¨çŠ¶æ€æ“ä½œã€‚
 */
@Intercepts({
        @Signature(
                type = Executor.class,
                method = "update",
                args = {
                        MappedStatement.class,
                        Object.class
                }
        )
})
@Slf4j
public class VirtualCardInUseInterceptor  implements Interceptor {
    static int MAPPED_STATEMENT_INDEX = 0;
    static int PARAMETER_INDEX = 1;
    static String BASE_FIELD_SET_PRIMARY_KEY_FUNTION_SETINUSE = "setInUse";
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object entity = invocation.getArgs()[PARAMETER_INDEX];
        if (entity instanceof SeVirtualCard) {
            MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[MAPPED_STATEMENT_INDEX];
            SqlCommandType commandType = mappedStatement.getSqlCommandType();
            if (commandType.equals(SqlCommandType.UPDATE)) {
                Class<?> entityClass = entity.getClass();
                Method setInUse = null;
                try {
                    setInUse = entityClass.getMethod(BASE_FIELD_SET_PRIMARY_KEY_FUNTION_SETINUSE, Byte.class);
                } catch (Exception e) {
                    //当entityClass没有setInUse方法时,会抛出异常
                }
                if (setInUse != null) {
                    setInUse.invoke(entity, (byte)0);
                }
                invocation.getArgs()[PARAMETER_INDEX] = entity;
            }
        }
        return invocation.proceed();
    }
}
pipIrr-platform/pipIrr-global/src/main/resources/application-common-web(121·þÎñÆ÷).yml
@@ -2,3 +2,8 @@
  # 233服务器:ym,mj,sp,test
  # 121服务器:mq,yq,hlj,gz,lz,jc
  spring_main_datasource_names: mq,yq,hlj,gz,lz,jc
  # è™šæ‹Ÿå¡è¡¨å­—段in_use意为占用状态,当为true时统一设置值为0
  # 233服务器:false
  # 121服务器:true
  virtual_card_disable_set_inuse: true
pipIrr-platform/pipIrr-global/src/main/resources/application-common-web(233·þÎñÆ÷).yml
@@ -2,3 +2,8 @@
  # 233服务器:ym,mj,sp,test
  # 121服务器:mq,yq,hlj,gz,lz,jc
  spring_main_datasource_names: ym,mj,sp,test
  # è™šæ‹Ÿå¡è¡¨å­—段in_use意为占用状态,当为true时统一设置值为0
  # 233服务器:false
  # 121服务器:true
  virtual_card_disable_set_inuse: false
pipIrr-platform/pipIrr-global/src/main/resources/application-common-web.yml
@@ -2,3 +2,8 @@
  # 233服务器:ym,mj,sp,test
  # 121服务器:mq,yq,hlj,gz,lz,jc
  spring_main_datasource_names: ym,mj,sp,test
  # è™šæ‹Ÿå¡è¡¨å­—段in_use意为占用状态,当为true时统一设置值为0
  # 233服务器:false
  # 121服务器:true
  virtual_card_disable_set_inuse: false
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml
@@ -477,4 +477,9 @@
#虚拟卡配置参数
vc:
    #虚拟卡最低余额报警值
    alarmValue: 10
    alarmValue: 10
#轮灌配置
rotation:
    #轮灌组提前开阀时间
    preOpeningTime: 10
pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaUserMapper.xml
@@ -373,8 +373,7 @@
        COUNT(*) AS recordCount
        FROM ba_user user
        <where>
            user.supperAdmin != 1
            AND user.deleted = 0
            user.deleted = 0
            <if test = "phone != null and phone !=''">
                AND user.phone= #{phone}
            </if>
pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoCtrl.java
@@ -113,25 +113,24 @@
        if(vo.orgTag == null || vo.orgTag.trim().length() == 0){
            return BaseResponseUtils.buildErrorMsg("未选择组织单位");
        }
        if(vo.token == null || vo.token.trim().length() == 0){
            return BaseResponseUtils.buildErrorMsg("无token");
        }
        if(vo.code == null || vo.code.trim().length() == 0){
            return BaseResponseUtils.buildErrorMsg("请输入验证码");
        }
        //把组织单位标签作为数据源名称
        DataSourceContext.set(vo.orgTag);
        // ä»Žæ•°æ®åº“获取验证码
        Map map = sv.getCodeByToken(vo.token);
        Long expiration = Long.parseLong(map.get("expiration").toString());
        Long currentTimestamp = System.currentTimeMillis();
        if(currentTimestamp > expiration) {
            return BaseResponseUtils.buildErrorMsg("验证码已超时");
        }
        String localCode = map.get("code").toString();
        if(!vo.code.equals(localCode)) {
            return BaseResponseUtils.buildErrorMsg("验证码错误");
        if(vo.token != null && vo.token.trim().length() > 0) {
            // ä»Žsession中获取验证码
            //HttpSession session = (HttpSession) request.getSession();
            //String localCode = session.getAttribute(token).toString();
            // ä»Žæ•°æ®åº“获取验证码
            Map map = sv.getCodeByToken(vo.token);
            Long expiration = Long.parseLong(map.get("expiration").toString());
            Long currentTimestamp = System.currentTimeMillis();
            if(currentTimestamp > expiration) {
                return BaseResponseUtils.buildErrorMsg("验证码已超时");
            }
            String localCode = map.get("code").toString();
            if(!vo.code.equals(localCode)) {
                return BaseResponseUtils.buildErrorMsg("验证码错误");
            }
        }
        if(!sv.existPhone(vo.phone)){
pipIrr-platform/pipIrr-web/pipIrr-web-temp/src/main/java/com/dy/pipIrrTemp/testFun/Test4VirtualCardSetInUseCtrl.java
New file
@@ -0,0 +1,40 @@
package com.dy.pipIrrTemp.testFun;
import com.dy.common.aop.SsoAop;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @Author: liurunyu
 * @Date: 2025/4/27 10:25
 * @Description
 */
@Slf4j
@RestController
@RequestMapping(path = "test4Vir")
public class Test4VirtualCardSetInUseCtrl {
    private Test4VirtualCardSetInUseSv sv;
    @Autowired
    private void setSv(Test4VirtualCardSetInUseSv sv) {
        this.sv = sv;
    }
    /**
     * åˆ é™¤ä¸€äº›æ¼æŸç»Ÿè®¡
     * @return
     */
    @GetMapping(path = "doSome")
    @SsoAop()
    public BaseResponse<Boolean> doSome(){
        this.sv.doSome();
        return BaseResponseUtils.buildSuccess(true);
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-temp/src/main/java/com/dy/pipIrrTemp/testFun/Test4VirtualCardSetInUseSv.java
New file
@@ -0,0 +1,28 @@
package com.dy.pipIrrTemp.testFun;
import com.dy.pipIrrGlobal.daoSe.SeVirtualCardMapper;
import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * @Author: liurunyu
 * @Date: 2025/4/27 10:26
 * @Description
 */
@Slf4j
@Service
public class Test4VirtualCardSetInUseSv {
    @Autowired
    private SeVirtualCardMapper seVirtualCardMapper;
    @Transactional(rollbackFor = Exception.class)
    public void doSome(){
        SeVirtualCard po = new SeVirtualCard();
        po.setId(Long.parseLong("2025042116533800009"));
        po.setInUse((byte) 1);
        seVirtualCardMapper.updateByPrimaryKeySelective(po) ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/irrigatePlan/IrrigatePlanCtrl.java
@@ -22,6 +22,7 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/irrigatePlan/IrrigatePlanSv.java
@@ -74,6 +74,9 @@
    private static final Integer irrPlanDelayDefault = 5 ;//轮灌中计划开阀的默认延迟时长
    @Value("${rotation.preOpeningTime}")
    private Long preOpeningTime;
    /**
     * æ·»åŠ çŒæº‰è®¡åˆ’
     * @param po
@@ -218,8 +221,13 @@
            // è®¡ç®—下一组的开始时间
            LocalDateTime LocalscheduleStartTime = scheduleStartTime.toInstant().atZone(ZoneId.systemDefault()) .toLocalDateTime();
            LocalscheduleStartTime = LocalscheduleStartTime.plusMinutes(schedule.getDuration());
            LocalscheduleStartTime = LocalscheduleStartTime.minusMinutes(2);
            LocalscheduleStartTime = LocalscheduleStartTime.minusMinutes(preOpeningTime);
            scheduleStartTime = Date.from(LocalscheduleStartTime.atZone(ZoneId.systemDefault()).toInstant());
            // ç¡®ä¿ä¸‹ä¸€ç»„的开始时间不早于计划开始时间
            if(scheduleStartTime.before(planStartTime)) {
                scheduleStartTime = planStartTime;
            }
        }
        // æ·»åŠ çŒæº‰è®¡åˆ’æ“ä½œè®°å½•
pipIrr-platform/Îĵµ/README.md
New file
@@ -0,0 +1,124 @@
# pipIrr æ™ºèƒ½çŒæº‰ç³»ç»Ÿ
## é¡¹ç›®æ¦‚è¿°
pipIrr是一套基于Java的智能管道灌溉系统解决方案,用于实现水资源的智能化管理与灌溉控制。系统集成了远程终端控制、GIS地理信息、水资源监测与分析、微信接入等多种功能,为智慧农业和水利工程提供全面的技术支持。
## ç³»ç»Ÿæž¶æž„
系统采用微服务架构,基于Spring Boot 3构建,主要包括以下几个核心部分:
- **前端应用层**:提供Web界面、移动应用、微信公众号等多种交互方式
- **业务服务层**:处理核心业务逻辑,包括灌溉管理、项目管理、数据统计等
- **中间件层**:提供RTU(远程终端单元)通信、第三方系统集成等功能
- **基础设施层**:提供数据存储、缓存、消息队列等基础服务
## æ¨¡å—说明
### çˆ¶æ¨¡å— (pipIrr-platform)
作为整个项目的父模块,管理依赖版本和构建配置。
### æ ¸å¿ƒå­æ¨¡å—
- **pipIrr-common**: å…¬å…±ç»„件,提供工具类、通用配置等
- **pipIrr-global**: å…¨å±€é…ç½®å’ŒæœåŠ¡
- **pipIrr-web**: Web应用模块集合
  - pipIrr-web-base: åŸºç¡€æ•°æ®æœåŠ¡
  - pipIrr-web-sso: å•点登录服务
  - pipIrr-web-irrigate: çŒæº‰ç®¡ç†
  - pipIrr-web-gis: GIS地理信息服务
  - pipIrr-web-project: é¡¹ç›®ç®¡ç†
  - pipIrr-web-statistics: æ•°æ®ç»Ÿè®¡åˆ†æž
  - pipIrr-web-remote: è¿œç¨‹æŽ§åˆ¶
  - pipIrr-web-wechat: å¾®ä¿¡é›†æˆ
  - pipIrr-web-app: ç§»åŠ¨åº”ç”¨æœåŠ¡
  - pipIrr-web-file: æ–‡ä»¶ç®¡ç†
  - pipIrr-web-operation: è¿ç»´ç®¡ç†
  - pipIrr-web-sell: é”€å”®ç®¡ç†
  - pipIrr-web-temp: ä¸´æ—¶æ¨¡å—
- **pipIrr-mw**: ä¸­é—´ä»¶æœåŠ¡
  - pipIrr-mw-rtu: RTU设备通信
  - pipIrr-mw-rtu3rd: ç¬¬ä¸‰æ–¹RTU集成
  - pipIrr-mw-simulate-rtu: RTU模拟器
  - pipIrr-mwTest-server: æµ‹è¯•服务器
  - pipIrr-mwTest-client: æµ‹è¯•客户端
## æŠ€æœ¯æ ˆ
- **基础框架**: Spring Boot 3.1.3
- **JDK版本**: Java 20
- **Web服务**: Tomcat 10.1.12
- **数据库**: MySQL 8.0.33
- **ORM框架**: MyBatis-Plus 3.5.3.2
- **数据库连接池**: Druid 1.2.20
- **API文档**: SpringDoc OpenAPI 2.2.0
- **JSON处理**: FastJSON 2.0.40
- **对象映射**: MapStruct 1.5.5.Final
- **工具集**: Hutool 5.8.22
- **日志框架**: Log4j2 2.20.0
## å¼€å‘环境搭建
### å‰ç½®æ¡ä»¶
- JDK 20
- Maven 3.8+
- MySQL 8.0+
- IDE推荐: IntelliJ IDEA
### æž„建步骤
1. å…‹éš†ä»£ç åº“
   ```bash
   git clone <repository-url>
   ```
2. å¯¼å…¥é¡¹ç›®åˆ°IDE
   ä½¿ç”¨IDEA导入Maven项目
3. é…ç½®æ•°æ®åº“
   åœ¨ç›¸åº”配置文件中设置数据库连接信息
4. ç¼–译项目
   ```bash
   mvn clean package
   ```
## éƒ¨ç½²è¯´æ˜Ž
### å¼€å‘环境
```bash
mvn spring-boot:run -Dspring.profiles.active=dev
```
### ç”Ÿäº§çŽ¯å¢ƒ
1. æ‰“包应用
   ```bash
   mvn clean package -Dspring.profiles.active=prod
   ```
2. è¿è¡Œjar包
   ```bash
   java -jar <模块名>-<版本号>.jar
   ```
## é¡¹ç›®æ–‡æ¡£
详细的项目文档位于 `pipIrr-platform/文档/` ç›®å½•下,包括:
- API接口文档
- æ•°æ®åº“设计
- éƒ¨ç½²æŒ‡å—
- ç¼–码规范
## ç‰ˆæœ¬ä¿¡æ¯
当前版本: 1.0.0
## è´¡çŒ®æŒ‡å—
1. Fork æœ¬ä»“库
2. åˆ›å»ºåŠŸèƒ½åˆ†æ”¯ (`git checkout -b feature/AmazingFeature`)
3. æäº¤å˜æ›´ (`git commit -m 'Add some AmazingFeature'`)
4. æŽ¨é€åˆ°åˆ†æ”¯ (`git push origin feature/AmazingFeature`)
5. åˆ›å»ºPull Request