Browse Source

风暴潮预报

ZhuDeKang 2 months ago
parent
commit
b88a6d7a01

+ 16 - 45
ruoyi-admin/src/test/java/com/ruoyi/JasyptTest.java

@@ -3,7 +3,6 @@ package com.ruoyi;
 import com.ruoyi.common.core.domain.entity.SysDept;
 import com.ruoyi.common.core.domain.entity.SysDept;
 import com.ruoyi.common.core.domain.entity.SysRole;
 import com.ruoyi.common.core.domain.entity.SysRole;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.entity.SysUser;
-import com.ruoyi.common.utils.SM2EnhancedUtil;
 import com.ruoyi.common.utils.SM4Util;
 import com.ruoyi.common.utils.SM4Util;
 import com.ruoyi.interfaces.domain.MdModelInfo;
 import com.ruoyi.interfaces.domain.MdModelInfo;
 import com.ruoyi.interfaces.domain.PtService;
 import com.ruoyi.interfaces.domain.PtService;
@@ -48,40 +47,15 @@ public class JasyptTest {
     @Autowired
     @Autowired
     private SysRoleMapper roleMapper;
     private SysRoleMapper roleMapper;
 
 
-    @Autowired
-    private SM2EnhancedUtil sm2Util;
-
 
 
     @Test
     @Test
     public void test() {
     public void test() {
 
 
-        System.out.println("=== SM2签名验签测试 ===");
-
-        // 测试数据
-        String testData = "33f50ef2fc52f9a5a554a39c91854f20";
-
-        // 生成签名
-        String signature = sm2Util.sign(testData);
-        System.out.println("原始数据: " + testData);
-        System.out.println("签名结果: " + signature);
-
-        // 验证签名
-        boolean isValid = sm2Util.verify(testData, signature);
-        System.out.println("签名验证: " + isValid);
-
-        // 测试篡改数据
-        boolean isTamperedValid = sm2Util.verify("被篡改的数据", signature);
-        System.out.println("篡改数据验证: " + isTamperedValid);
 
 
-        // 显示密钥信息
-        System.out.println("公钥长度: " + sm2Util.getPublicKeyBase64().length());
-        System.out.println("私钥长度: " + sm2Util.getPrivateKeyBase64().length());
-        System.out.println("自检结果: " + sm2Util.selfCheck());
-    }
-    //System.out.println(sm4Util.encrypt("Gw#$1601"));
+        //System.out.println(sm4Util.encrypt("Gw#$1601"));
 
 
-/*List<MdModelInfo> mdModelInfos = modelMapper.selectMdModelInfoList(new MdModelInfo());
-        mdModelInfos.forEach(p->{
+/*        List<MdModelInfo> mdModelInfos = modelMapper.selectMdModelInfoList(new MdModelInfo());
+        mdModelInfos.forEach(p -> {
             p.sign();
             p.sign();
             modelMapper.updateMdModelInfo(p);
             modelMapper.updateMdModelInfo(p);
         });*/
         });*/
@@ -92,32 +66,35 @@ public class JasyptTest {
             ptServiceMapper.updateByPrimaryKeySelective(p);
             ptServiceMapper.updateByPrimaryKeySelective(p);
         });*/
         });*/
 
 
-
 /*
 /*
+
         List<SysMetaDatasource> sysMetaDatasources = datasourceMapper.selectSysMetaDatasourceList(new SysMetaDatasource());
         List<SysMetaDatasource> sysMetaDatasources = datasourceMapper.selectSysMetaDatasourceList(new SysMetaDatasource());
         sysMetaDatasources.forEach(p -> {
         sysMetaDatasources.forEach(p -> {
                 p.sign();
                 p.sign();
             datasourceMapper.updateSysMetaDatasource(p);
             datasourceMapper.updateSysMetaDatasource(p);
         });
         });
-
 */
 */
 
 
 
 
-/*
         List<SysRole> sysRoles = roleMapper.selectRoleList(new SysRole());
         List<SysRole> sysRoles = roleMapper.selectRoleList(new SysRole());
-        sysRoles.forEach( p ->{
+        sysRoles.forEach(p -> {
             p.sign();
             p.sign();
             roleMapper.updateRole(p);
             roleMapper.updateRole(p);
         });
         });
-*/
 
 
-/*
         List<SysDept> sysDepts = deptMapper.selectDeptList(new SysDept());
         List<SysDept> sysDepts = deptMapper.selectDeptList(new SysDept());
-        sysDepts.forEach(p->{
+        sysDepts.forEach(p -> {
             p.sign();
             p.sign();
             deptMapper.updateDept(p);
             deptMapper.updateDept(p);
         });
         });
-*/
+
+        List<SysUser> sysUsers = userService.selectUserList(new SysUser());
+        sysUsers.forEach(p -> {
+            p.setEmail(sm4Util.encrypt(p.getEmail()));
+            p.sign();
+            System.out.println(p.getEmail());
+            System.out.println(p.getDataSignature());
+        });
 
 
 /*
 /*
 
 
@@ -134,13 +111,7 @@ public class JasyptTest {
         String prettyJsonString = JSONUtils.toPrettyJsonString(sysMetaDatasources);
         String prettyJsonString = JSONUtils.toPrettyJsonString(sysMetaDatasources);
         System.out.println(prettyJsonString);
         System.out.println(prettyJsonString);
 */
 */
-/*        List<SysUser> sysUsers = userService.selectUserList(new SysUser());
-        sysUsers.forEach(p->{
-            p.setEmail(sm4Util.encrypt(p.getEmail()));
-            p.sign();
-            System.out.println(    p.getEmail());
-            System.out.println(    p.getDataSignature());
-        });*/
+
 
 
 
 
 /*
 /*
@@ -151,5 +122,5 @@ public class JasyptTest {
         System.out.println(common);
         System.out.println(common);
 */
 */
 
 
-
+    }
 }
 }

+ 117 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/controller/MdForecastStormTideController.java

@@ -0,0 +1,117 @@
+package com.ruoyi.interfaces.controller;
+
+import java.util.List;
+
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.interfaces.domain.MdForecastStormTide;
+import com.ruoyi.interfaces.service.IMdForecastStormTideService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 风暴潮预报Controller
+ * 
+ * @author ruoyi
+ * @date 2025-11-12
+ */
+@RestController
+@RequestMapping("/storm/tide")
+public class MdForecastStormTideController extends BaseController
+{
+    @Autowired
+    private IMdForecastStormTideService mdForecastStormTideService;
+
+    /**
+     * 查询风暴潮预报列表
+     */
+    @GetMapping("/list")
+    public AjaxResult list(MdForecastStormTide mdForecastStormTide)
+    {
+        List<MdForecastStormTide> list = mdForecastStormTideService.selectMdForecastStormTideList(mdForecastStormTide);
+        return success(list);
+    }
+
+    @GetMapping("/stcdList")
+    public AjaxResult stcdList(MdForecastStormTide mdForecastStormTide){
+        List<MdForecastStormTide> list = mdForecastStormTideService.selectStcdList(mdForecastStormTide);
+        return success(list);
+    }
+
+
+    /**
+     * 导出风暴潮预报列表
+     */
+    @Log(title = "风暴潮预报", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(MdForecastStormTide mdForecastStormTide)
+    {
+        List<MdForecastStormTide> list = mdForecastStormTideService.selectMdForecastStormTideList(mdForecastStormTide);
+        ExcelUtil<MdForecastStormTide> util = new ExcelUtil<MdForecastStormTide>(MdForecastStormTide.class);
+        return util.exportExcel(list, "风暴潮预报数据");
+    }
+
+
+    @PostMapping("/importData")
+    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
+    {
+        ExcelUtil<MdForecastStormTide> util = new ExcelUtil<MdForecastStormTide>(MdForecastStormTide.class);
+        List<MdForecastStormTide> userList = util.importExcel(file.getInputStream());
+        String message = mdForecastStormTideService.importStormTide(userList, updateSupport);
+        return success(message);
+    }
+
+
+    /**
+     * 获取风暴潮预报详细信息
+     */
+    @GetMapping(value = "/{stcd}")
+    public AjaxResult getInfo(@PathVariable("stcd") String stcd)
+    {
+        return AjaxResult.success(mdForecastStormTideService.selectMdForecastStormTideByStcd(stcd));
+    }
+
+    /**
+     * 新增风暴潮预报
+     */
+    @Log(title = "风暴潮预报", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody MdForecastStormTide mdForecastStormTide)
+    {
+        return toAjax(mdForecastStormTideService.insertMdForecastStormTide(mdForecastStormTide));
+    }
+
+    /**
+     * 修改风暴潮预报
+     */
+    @Log(title = "风暴潮预报", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody MdForecastStormTide mdForecastStormTide)
+    {
+        return toAjax(mdForecastStormTideService.updateMdForecastStormTide(mdForecastStormTide));
+    }
+
+    /**
+     * 删除风暴潮预报
+     */
+    @Log(title = "风暴潮预报", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{stcds}")
+    public AjaxResult remove(@PathVariable String[] stcds)
+    {
+        return toAjax(mdForecastStormTideService.deleteMdForecastStormTideByStcds(stcds));
+    }
+}

+ 279 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/domain/MdForecastStormTide.java

@@ -0,0 +1,279 @@
+package com.ruoyi.interfaces.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 风暴潮预报对象 md_forecast_storm_tide
+ * 
+ * @author ruoyi
+ * @date 2025-11-12
+ */
+public class MdForecastStormTide extends BaseEntity
+{
+    private static final Long serialVersionUID = 1L;
+
+    /** 站点序号 */
+    @Excel(name = "站点序号")
+    private String stcd;
+
+    /** 站点名称 */
+    @Excel(name = "站点名称")
+    private String stnm;
+
+    /** 经度 */
+    @Excel(name = "经度")
+    private Double lgtd;
+
+    /** 维度 */
+    @Excel(name = "维度")
+    private Double lttd;
+
+    /** 时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date tm;
+
+    /** 预报时效 */
+    @Excel(name = "预报时效")
+    private Long forecastTime;
+
+    /** ECMWF_水位(m) */
+    @Excel(name = "ECMWF_水位" )
+    private Double ecmwfZ;
+
+    /** ECMWF_增水(m) */
+    @Excel(name = "ECMWF_增水")
+    private Double ecmwfAddz;
+
+    /** ECMWF_风速(m/s) */
+    @Excel(name = "ECMWF_风速")
+    private Double ecmwfWndv;
+
+    /** ECMWF_风向(°) */
+    @Excel(name = "ECMWF_风向")
+    private Double ecmwfWnddir;
+
+    /** WRF_水位(m) */
+    @Excel(name = "WRF_水位")
+    private Double wrfZ;
+
+    /** WRF_增水(m) */
+    @Excel(name = "WRF_增水")
+    private Double wrfAddz;
+
+    /** WRF_风速(m/s) */
+    @Excel(name = "WRF_风速")
+    private Double wrfWndv;
+
+    /** WRF_风向(°) */
+    @Excel(name = "WRF_风向")
+    private Double wrfWnddir;
+
+    /** GFS_水位(m) */
+    @Excel(name = "GFS_水位")
+    private Double gfsZ;
+
+    /** GFS_增水(m) */
+    @Excel(name = "GFS_增水")
+    private Double gfsAddz;
+
+    /** GFS_风速(m/s) */
+    @Excel(name = "GFS_风速")
+    private Double gfsWndv;
+
+    /** GFS_风向(°) */
+    @Excel(name = "GFS_风向")
+    private Double gfsWnddir;
+
+    public void setStcd(String stcd) 
+    {
+        this.stcd = stcd;
+    }
+
+    public String getStcd() 
+    {
+        return stcd;
+    }
+    public void setStnm(String stnm) 
+    {
+        this.stnm = stnm;
+    }
+
+    public String getStnm() 
+    {
+        return stnm;
+    }
+    public void setLgtd(Double lgtd) 
+    {
+        this.lgtd = lgtd;
+    }
+
+    public Double getLgtd() 
+    {
+        return lgtd;
+    }
+    public void setLttd(Double lttd) 
+    {
+        this.lttd = lttd;
+    }
+
+    public Double getLttd() 
+    {
+        return lttd;
+    }
+    public void setTm(Date tm) 
+    {
+        this.tm = tm;
+    }
+
+    public Date getTm() 
+    {
+        return tm;
+    }
+    public void setForecastTime(Long forecastTime)
+    {
+        this.forecastTime = forecastTime;
+    }
+
+    public Long getForecastTime()
+    {
+        return forecastTime;
+    }
+    public void setEcmwfZ(Double ecmwfZ) 
+    {
+        this.ecmwfZ = ecmwfZ;
+    }
+
+    public Double getEcmwfZ() 
+    {
+        return ecmwfZ;
+    }
+    public void setEcmwfAddz(Double ecmwfAddz) 
+    {
+        this.ecmwfAddz = ecmwfAddz;
+    }
+
+    public Double getEcmwfAddz() 
+    {
+        return ecmwfAddz;
+    }
+    public void setEcmwfWndv(Double ecmwfWndv) 
+    {
+        this.ecmwfWndv = ecmwfWndv;
+    }
+
+    public Double getEcmwfWndv() 
+    {
+        return ecmwfWndv;
+    }
+    public void setEcmwfWnddir(Double ecmwfWnddir) 
+    {
+        this.ecmwfWnddir = ecmwfWnddir;
+    }
+
+    public Double getEcmwfWnddir() 
+    {
+        return ecmwfWnddir;
+    }
+    public void setWrfZ(Double wrfZ) 
+    {
+        this.wrfZ = wrfZ;
+    }
+
+    public Double getWrfZ() 
+    {
+        return wrfZ;
+    }
+    public void setWrfAddz(Double wrfAddz) 
+    {
+        this.wrfAddz = wrfAddz;
+    }
+
+    public Double getWrfAddz() 
+    {
+        return wrfAddz;
+    }
+    public void setWrfWndv(Double wrfWndv) 
+    {
+        this.wrfWndv = wrfWndv;
+    }
+
+    public Double getWrfWndv() 
+    {
+        return wrfWndv;
+    }
+    public void setWrfWnddir(Double wrfWnddir) 
+    {
+        this.wrfWnddir = wrfWnddir;
+    }
+
+    public Double getWrfWnddir() 
+    {
+        return wrfWnddir;
+    }
+    public void setGfsZ(Double gfsZ) 
+    {
+        this.gfsZ = gfsZ;
+    }
+
+    public Double getGfsZ() 
+    {
+        return gfsZ;
+    }
+    public void setGfsAddz(Double gfsAddz) 
+    {
+        this.gfsAddz = gfsAddz;
+    }
+
+    public Double getGfsAddz() 
+    {
+        return gfsAddz;
+    }
+    public void setGfsWndv(Double gfsWndv) 
+    {
+        this.gfsWndv = gfsWndv;
+    }
+
+    public Double getGfsWndv() 
+    {
+        return gfsWndv;
+    }
+    public void setGfsWnddir(Double gfsWnddir) 
+    {
+        this.gfsWnddir = gfsWnddir;
+    }
+
+    public Double getGfsWnddir() 
+    {
+        return gfsWnddir;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("stcd", getStcd())
+            .append("stnm", getStnm())
+            .append("lgtd", getLgtd())
+            .append("lttd", getLttd())
+            .append("tm", getTm())
+            .append("forecastTime", getForecastTime())
+            .append("ecmwfZ", getEcmwfZ())
+            .append("ecmwfAddz", getEcmwfAddz())
+            .append("ecmwfWndv", getEcmwfWndv())
+            .append("ecmwfWnddir", getEcmwfWnddir())
+            .append("wrfZ", getWrfZ())
+            .append("wrfAddz", getWrfAddz())
+            .append("wrfWndv", getWrfWndv())
+            .append("wrfWnddir", getWrfWnddir())
+            .append("gfsZ", getGfsZ())
+            .append("gfsAddz", getGfsAddz())
+            .append("gfsWndv", getGfsWndv())
+            .append("gfsWnddir", getGfsWnddir())
+            .toString();
+    }
+}

+ 67 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/mapper/MdForecastStormTideMapper.java

@@ -0,0 +1,67 @@
+package com.ruoyi.interfaces.mapper;
+
+import com.ruoyi.common.annotation.DataSource;
+import com.ruoyi.common.enums.DataSourceType;
+import com.ruoyi.interfaces.domain.MdForecastStormTide;
+
+import java.util.List;
+
+/**
+ * 风暴潮预报Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-11-12
+ */
+@DataSource(DataSourceType.SLAVE)
+public interface MdForecastStormTideMapper 
+{
+    /**
+     * 查询风暴潮预报
+     * 
+     * @param stcd 风暴潮预报主键
+     * @return 风暴潮预报
+     */
+    public MdForecastStormTide selectMdForecastStormTideByStcd(String stcd);
+
+    /**
+     * 查询风暴潮预报列表
+     * 
+     * @param mdForecastStormTide 风暴潮预报
+     * @return 风暴潮预报集合
+     */
+    public List<MdForecastStormTide> selectMdForecastStormTideList(MdForecastStormTide mdForecastStormTide);
+
+    /**
+     * 新增风暴潮预报
+     * 
+     * @param mdForecastStormTide 风暴潮预报
+     * @return 结果
+     */
+    public int insertMdForecastStormTide(MdForecastStormTide mdForecastStormTide);
+
+    /**
+     * 修改风暴潮预报
+     * 
+     * @param mdForecastStormTide 风暴潮预报
+     * @return 结果
+     */
+    public int updateMdForecastStormTide(MdForecastStormTide mdForecastStormTide);
+
+    /**
+     * 删除风暴潮预报
+     * 
+     * @param stcd 风暴潮预报主键
+     * @return 结果
+     */
+    public int deleteMdForecastStormTideByStcd(String stcd);
+
+    /**
+     * 批量删除风暴潮预报
+     * 
+     * @param stcds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteMdForecastStormTideByStcds(String[] stcds);
+
+    List<MdForecastStormTide> selectStcdList(MdForecastStormTide mdForecastStormTide);
+}

+ 66 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/IMdForecastStormTideService.java

@@ -0,0 +1,66 @@
+package com.ruoyi.interfaces.service;
+
+import com.ruoyi.interfaces.domain.MdForecastStormTide;
+
+import java.util.List;
+
+/**
+ * 风暴潮预报Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-11-12
+ */
+public interface IMdForecastStormTideService 
+{
+    /**
+     * 查询风暴潮预报
+     * 
+     * @param stcd 风暴潮预报主键
+     * @return 风暴潮预报
+     */
+    public MdForecastStormTide selectMdForecastStormTideByStcd(String stcd);
+
+    /**
+     * 查询风暴潮预报列表
+     * 
+     * @param mdForecastStormTide 风暴潮预报
+     * @return 风暴潮预报集合
+     */
+    public List<MdForecastStormTide> selectMdForecastStormTideList(MdForecastStormTide mdForecastStormTide);
+
+    /**
+     * 新增风暴潮预报
+     * 
+     * @param mdForecastStormTide 风暴潮预报
+     * @return 结果
+     */
+    public int insertMdForecastStormTide(MdForecastStormTide mdForecastStormTide);
+
+    /**
+     * 修改风暴潮预报
+     * 
+     * @param mdForecastStormTide 风暴潮预报
+     * @return 结果
+     */
+    public int updateMdForecastStormTide(MdForecastStormTide mdForecastStormTide);
+
+    /**
+     * 批量删除风暴潮预报
+     * 
+     * @param stcds 需要删除的风暴潮预报主键集合
+     * @return 结果
+     */
+    public int deleteMdForecastStormTideByStcds(String[] stcds);
+
+    /**
+     * 删除风暴潮预报信息
+     * 
+     * @param stcd 风暴潮预报主键
+     * @return 结果
+     */
+    public int deleteMdForecastStormTideByStcd(String stcd);
+
+    String importStormTide(List<MdForecastStormTide> userList, boolean updateSupport);
+
+    List<MdForecastStormTide> selectStcdList(MdForecastStormTide mdForecastStormTide);
+}

+ 106 - 0
ruoyi-api-patform/src/main/java/com/ruoyi/interfaces/service/impl/MdForecastStormTideServiceImpl.java

@@ -0,0 +1,106 @@
+package com.ruoyi.interfaces.service.impl;
+
+import java.util.Collections;
+import java.util.List;
+
+import com.ruoyi.interfaces.domain.MdForecastStormTide;
+import com.ruoyi.interfaces.mapper.MdForecastStormTideMapper;
+import com.ruoyi.interfaces.service.IMdForecastStormTideService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 风暴潮预报Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-11-12
+ */
+@Service
+public class MdForecastStormTideServiceImpl implements IMdForecastStormTideService
+{
+    @Autowired
+    private MdForecastStormTideMapper mdForecastStormTideMapper;
+
+    /**
+     * 查询风暴潮预报
+     * 
+     * @param stcd 风暴潮预报主键
+     * @return 风暴潮预报
+     */
+    @Override
+    public MdForecastStormTide selectMdForecastStormTideByStcd(String stcd)
+    {
+        return mdForecastStormTideMapper.selectMdForecastStormTideByStcd(stcd);
+    }
+
+    /**
+     * 查询风暴潮预报列表
+     * 
+     * @param mdForecastStormTide 风暴潮预报
+     * @return 风暴潮预报
+     */
+    @Override
+    public List<MdForecastStormTide> selectMdForecastStormTideList(MdForecastStormTide mdForecastStormTide)
+    {
+        return mdForecastStormTideMapper.selectMdForecastStormTideList(mdForecastStormTide);
+    }
+
+    /**
+     * 新增风暴潮预报
+     * 
+     * @param mdForecastStormTide 风暴潮预报
+     * @return 结果
+     */
+    @Override
+    public int insertMdForecastStormTide(MdForecastStormTide mdForecastStormTide)
+    {
+        return mdForecastStormTideMapper.insertMdForecastStormTide(mdForecastStormTide);
+    }
+
+    /**
+     * 修改风暴潮预报
+     * 
+     * @param mdForecastStormTide 风暴潮预报
+     * @return 结果
+     */
+    @Override
+    public int updateMdForecastStormTide(MdForecastStormTide mdForecastStormTide)
+    {
+        return mdForecastStormTideMapper.updateMdForecastStormTide(mdForecastStormTide);
+    }
+
+    /**
+     * 批量删除风暴潮预报
+     * 
+     * @param stcds 需要删除的风暴潮预报主键
+     * @return 结果
+     */
+    @Override
+    public int deleteMdForecastStormTideByStcds(String[] stcds)
+    {
+        return mdForecastStormTideMapper.deleteMdForecastStormTideByStcds(stcds);
+    }
+
+    /**
+     * 删除风暴潮预报信息
+     * 
+     * @param stcd 风暴潮预报主键
+     * @return 结果
+     */
+    @Override
+    public int deleteMdForecastStormTideByStcd(String stcd)
+    {
+        return mdForecastStormTideMapper.deleteMdForecastStormTideByStcd(stcd);
+    }
+
+    @Override
+    public String importStormTide(List<MdForecastStormTide> userList, boolean updateSupport) {
+        userList.forEach(mdForecastStormTideMapper::insertMdForecastStormTide);
+        return "";
+    }
+
+    @Override
+    public List<MdForecastStormTide> selectStcdList(MdForecastStormTide mdForecastStormTide) {
+        return mdForecastStormTideMapper.selectStcdList(mdForecastStormTide);
+    }
+}

+ 145 - 0
ruoyi-api-patform/src/main/resources/mapper/interfaces/MdForecastStormTideMapper.xml

@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.interfaces.mapper.MdForecastStormTideMapper">
+
+    <resultMap type="com.ruoyi.interfaces.domain.MdForecastStormTide" id="MdForecastStormTideResult">
+        <result property="stcd"    column="stcd"    />
+        <result property="stnm"    column="stnm"    />
+        <result property="lgtd"    column="lgtd"    />
+        <result property="lttd"    column="lttd"    />
+        <result property="tm"    column="tm"    />
+        <result property="forecastTime"    column="forecast_time"    />
+        <result property="ecmwfZ"    column="ecmwf_z"    />
+        <result property="ecmwfAddz"    column="ecmwf_addz"    />
+        <result property="ecmwfWndv"    column="ecmwf_wndv"    />
+        <result property="ecmwfWnddir"    column="ecmwf_wnddir"    />
+        <result property="wrfZ"    column="wrf_z"    />
+        <result property="wrfAddz"    column="wrf_addz"    />
+        <result property="wrfWndv"    column="wrf_wndv"    />
+        <result property="wrfWnddir"    column="wrf_wnddir"    />
+        <result property="gfsZ"    column="gfs_z"    />
+        <result property="gfsAddz"    column="gfs_addz"    />
+        <result property="gfsWndv"    column="gfs_wndv"    />
+        <result property="gfsWnddir"    column="gfs_wnddir"    />
+    </resultMap>
+
+    <sql id="selectMdForecastStormTideVo">
+        select stcd, stnm, lgtd, lttd, tm, forecast_time, ecmwf_z, ecmwf_addz, ecmwf_wndv, ecmwf_wnddir, wrf_z, wrf_addz, wrf_wndv, wrf_wnddir, gfs_z, gfs_addz, gfs_wndv, gfs_wnddir from md_forecast_storm_tide
+    </sql>
+
+    <select id="selectMdForecastStormTideList" parameterType="com.ruoyi.interfaces.domain.MdForecastStormTide" resultMap="MdForecastStormTideResult">
+        <include refid="selectMdForecastStormTideVo"/>
+        <where>
+            <if test="stcd != null  and stcd != ''"> and stcd = #{stcd}</if>
+            <if test="stnm != null  and stnm != ''"> and stnm = #{stnm}</if>
+            <if test="lgtd != null "> and lgtd = #{lgtd}</if>
+            <if test="lttd != null "> and lttd = #{lttd}</if>
+            <if test="tm != null "> and tm = #{tm}</if>
+            <if test="forecastTime != null "> and forecast_time = #{forecastTime}</if>
+            <if test="ecmwfZ != null "> and ecmwf_z = #{ecmwfZ}</if>
+            <if test="ecmwfAddz != null "> and ecmwf_addz = #{ecmwfAddz}</if>
+            <if test="ecmwfWndv != null "> and ecmwf_wndv = #{ecmwfWndv}</if>
+            <if test="ecmwfWnddir != null "> and ecmwf_wnddir = #{ecmwfWnddir}</if>
+            <if test="wrfZ != null "> and wrf_z = #{wrfZ}</if>
+            <if test="wrfAddz != null "> and wrf_addz = #{wrfAddz}</if>
+            <if test="wrfWndv != null "> and wrf_wndv = #{wrfWndv}</if>
+            <if test="wrfWnddir != null "> and wrf_wnddir = #{wrfWnddir}</if>
+            <if test="gfsZ != null "> and gfs_z = #{gfsZ}</if>
+            <if test="gfsAddz != null "> and gfs_addz = #{gfsAddz}</if>
+            <if test="gfsWndv != null "> and gfs_wndv = #{gfsWndv}</if>
+            <if test="gfsWnddir != null "> and gfs_wnddir = #{gfsWnddir}</if>
+        </where>
+        order by stcd,tm
+    </select>
+
+    <select id="selectMdForecastStormTideByStcd" parameterType="String" resultMap="MdForecastStormTideResult">
+        <include refid="selectMdForecastStormTideVo"/>
+        where stcd = #{stcd}
+    </select>
+    <select id="selectStcdList" resultType="com.ruoyi.interfaces.domain.MdForecastStormTide">
+        select stcd, stnm, lgtd, lttd from md_forecast_storm_tide group
+                                                                      by stcd, stnm, lgtd, lttd
+
+    </select>
+
+    <insert id="insertMdForecastStormTide" parameterType="com.ruoyi.interfaces.domain.MdForecastStormTide">
+        insert into md_forecast_storm_tide
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="stcd != null">stcd,</if>
+            <if test="stnm != null">stnm,</if>
+            <if test="lgtd != null">lgtd,</if>
+            <if test="lttd != null">lttd,</if>
+            <if test="tm != null">tm,</if>
+            <if test="forecastTime != null">forecast_time,</if>
+            <if test="ecmwfZ != null">ecmwf_z,</if>
+            <if test="ecmwfAddz != null">ecmwf_addz,</if>
+            <if test="ecmwfWndv != null">ecmwf_wndv,</if>
+            <if test="ecmwfWnddir != null">ecmwf_wnddir,</if>
+            <if test="wrfZ != null">wrf_z,</if>
+            <if test="wrfAddz != null">wrf_addz,</if>
+            <if test="wrfWndv != null">wrf_wndv,</if>
+            <if test="wrfWnddir != null">wrf_wnddir,</if>
+            <if test="gfsZ != null">gfs_z,</if>
+            <if test="gfsAddz != null">gfs_addz,</if>
+            <if test="gfsWndv != null">gfs_wndv,</if>
+            <if test="gfsWnddir != null">gfs_wnddir,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="stcd != null">#{stcd},</if>
+            <if test="stnm != null">#{stnm},</if>
+            <if test="lgtd != null">#{lgtd},</if>
+            <if test="lttd != null">#{lttd},</if>
+            <if test="tm != null">#{tm},</if>
+            <if test="forecastTime != null">#{forecastTime},</if>
+            <if test="ecmwfZ != null">#{ecmwfZ},</if>
+            <if test="ecmwfAddz != null">#{ecmwfAddz},</if>
+            <if test="ecmwfWndv != null">#{ecmwfWndv},</if>
+            <if test="ecmwfWnddir != null">#{ecmwfWnddir},</if>
+            <if test="wrfZ != null">#{wrfZ},</if>
+            <if test="wrfAddz != null">#{wrfAddz},</if>
+            <if test="wrfWndv != null">#{wrfWndv},</if>
+            <if test="wrfWnddir != null">#{wrfWnddir},</if>
+            <if test="gfsZ != null">#{gfsZ},</if>
+            <if test="gfsAddz != null">#{gfsAddz},</if>
+            <if test="gfsWndv != null">#{gfsWndv},</if>
+            <if test="gfsWnddir != null">#{gfsWnddir},</if>
+        </trim>
+    </insert>
+
+    <update id="updateMdForecastStormTide" parameterType="com.ruoyi.interfaces.domain.MdForecastStormTide">
+        update md_forecast_storm_tide
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="stnm != null">stnm = #{stnm},</if>
+            <if test="lgtd != null">lgtd = #{lgtd},</if>
+            <if test="lttd != null">lttd = #{lttd},</if>
+            <if test="tm != null">tm = #{tm},</if>
+            <if test="forecastTime != null">forecast_time = #{forecastTime},</if>
+            <if test="ecmwfZ != null">ecmwf_z = #{ecmwfZ},</if>
+            <if test="ecmwfAddz != null">ecmwf_addz = #{ecmwfAddz},</if>
+            <if test="ecmwfWndv != null">ecmwf_wndv = #{ecmwfWndv},</if>
+            <if test="ecmwfWnddir != null">ecmwf_wnddir = #{ecmwfWnddir},</if>
+            <if test="wrfZ != null">wrf_z = #{wrfZ},</if>
+            <if test="wrfAddz != null">wrf_addz = #{wrfAddz},</if>
+            <if test="wrfWndv != null">wrf_wndv = #{wrfWndv},</if>
+            <if test="wrfWnddir != null">wrf_wnddir = #{wrfWnddir},</if>
+            <if test="gfsZ != null">gfs_z = #{gfsZ},</if>
+            <if test="gfsAddz != null">gfs_addz = #{gfsAddz},</if>
+            <if test="gfsWndv != null">gfs_wndv = #{gfsWndv},</if>
+            <if test="gfsWnddir != null">gfs_wnddir = #{gfsWnddir},</if>
+        </trim>
+        where stcd = #{stcd}
+    </update>
+
+    <delete id="deleteMdForecastStormTideByStcd" parameterType="String">
+        delete from md_forecast_storm_tide where stcd = #{stcd}
+    </delete>
+
+    <delete id="deleteMdForecastStormTideByStcds" parameterType="String">
+        delete from md_forecast_storm_tide where stcd in
+        <foreach item="stcd" collection="array" open="(" separator="," close=")">
+            #{stcd}
+        </foreach>
+    </delete>
+</mapper>

+ 0 - 138
ruoyi-common/src/main/java/com/ruoyi/common/utils/SM2EnhancedUtil.java

@@ -1,138 +0,0 @@
-/*
-package com.ruoyi.common.utils;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-
-import javax.annotation.PostConstruct;
-import java.security.KeyPair;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-
-*/
-/**
- * 增强版SM2工具类
- *//*
-
-@Component
-public class SM2EnhancedUtil {
-
-    @Value("${sm2.private-key}")
-    private String configPrivateKey;
-
-    @Value("${sm2.public-key}")
-    private String configPublicKey;
-
-    private PrivateKey privateKey;
-    private PublicKey publicKey;
-    private KeyPair keyPair;
-
-    @PostConstruct
-    public void init() {
-        // 如果配置了密钥,则使用配置的密钥
-        if (configPrivateKey != null && !configPrivateKey.trim().isEmpty() &&
-            configPublicKey != null && !configPublicKey.trim().isEmpty()) {
-            this.privateKey = SM2Util.loadPrivateKey(configPrivateKey);
-            this.publicKey = SM2Util.loadPublicKey(configPublicKey);
-            this.keyPair = new KeyPair(publicKey, privateKey);
-        } else {
-            // 否则生成新的密钥对
-            this.keyPair = SM2Util.generateKeyPair();
-            this.privateKey = keyPair.getPrivate();
-            this.publicKey = keyPair.getPublic();
-            
-            // 输出生成的密钥(仅用于开发环境)
-            System.out.println("生成的SM2公钥: " + getPublicKeyBase64());
-            System.out.println("生成的SM2私钥: " + getPrivateKeyBase64());
-        }
-    }
-
-    */
-/**
-     * 使用配置的私钥签名
-     *//*
-
-    public String sign(String data) {
-        return SM2Util.sign(data.getBytes(), privateKey);
-    }
-
-    */
-/**
-     * 使用配置的公钥验签
-     *//*
-
-    public boolean verify(String data, String signature) {
-        return SM2Util.verify(data.getBytes(), signature, publicKey);
-    }
-
-    */
-/**
-     * 使用配置的私钥签名(字节数组)
-     *//*
-
-    public String sign(byte[] data) {
-        return SM2Util.sign(data, privateKey);
-    }
-
-    */
-/**
-     * 使用配置的公钥验签(字节数组)
-     *//*
-
-    public boolean verify(byte[] data, String signature) {
-        return SM2Util.verify(data, signature, publicKey);
-    }
-
-    */
-/**
-     * 获取当前使用的私钥(Base64)
-     *//*
-
-    public String getPrivateKeyBase64() {
-        return SM2Util.privateKeyToString(privateKey);
-    }
-
-    */
-/**
-     * 获取当前使用的公钥(Base64)
-     *//*
-
-    public String getPublicKeyBase64() {
-        return SM2Util.publicKeyToString(publicKey);
-    }
-
-    */
-/**
-     * 获取密钥对
-     *//*
-
-    public KeyPair getKeyPair() {
-        return keyPair;
-    }
-
-    */
-/**
-     * 生成新的密钥对并更新当前实例
-     *//*
-
-    public void generateNewKeyPair() {
-        this.keyPair = SM2Util.generateKeyPair();
-        this.privateKey = keyPair.getPrivate();
-        this.publicKey = keyPair.getPublic();
-    }
-
-    */
-/**
-     * 验证工具类是否正常工作
-     *//*
-
-    public boolean selfCheck() {
-        try {
-            String testData = "SM2签名测试数据";
-            String signature = sign(testData);
-            return verify(testData, signature);
-        } catch (Exception e) {
-            return false;
-        }
-    }
-}*/

+ 0 - 127
ruoyi-common/src/main/java/com/ruoyi/common/utils/SM2Util.java

@@ -1,127 +0,0 @@
-/*
-package com.ruoyi.common.utils;
-
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
-import org.springframework.stereotype.Component;
-
-import java.security.*;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Base64;
-
-*/
-/**
- * SM2非对称加密工具类 - 兼容版本
- *//*
-
-@Component
-public class SM2Util {
-
-    static {
-        Security.addProvider(new BouncyCastleProvider());
-    }
-
-    */
-/**
-     * 生成SM2密钥对
-     *//*
-
-    public static KeyPair generateKeyPair() {
-        try {
-            // 使用标准的KeyPairGenerator
-            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");
-
-            // 使用SM2参数
-            keyPairGenerator.initialize(256); // SM2使用256位
-
-            return keyPairGenerator.generateKeyPair();
-        } catch (Exception e) {
-            throw new RuntimeException("生成SM2密钥对失败", e);
-        }
-    }
-
-    */
-/**
-     * 使用私钥对数据进行签名
-     *//*
-
-    public static String sign(byte[] data, PrivateKey privateKey) {
-        try {
-            Signature signature = Signature.getInstance("SM3withSM2", "BC");
-            signature.initSign(privateKey);
-            signature.update(data);
-            byte[] signBytes = signature.sign();
-            return Base64.getEncoder().encodeToString(signBytes);
-        } catch (Exception e) {
-            throw new RuntimeException("SM2签名失败", e);
-        }
-    }
-
-    */
-/**
-     * 使用公钥验证签名
-     *//*
-
-    public static boolean verify(byte[] data, String signature, PublicKey publicKey) {
-        try {
-            Signature verifier = Signature.getInstance("SM3withSM2", "BC");
-            verifier.initVerify(publicKey);
-            verifier.update(data);
-            byte[] signatureBytes = Base64.getDecoder().decode(signature);
-            return verifier.verify(signatureBytes);
-        } catch (Exception e) {
-            throw new RuntimeException("SM2验签失败", e);
-        }
-    }
-
-    */
-/**
-     * 从Base64字符串加载私钥
-     *//*
-
-    public static PrivateKey loadPrivateKey(String base64PrivateKey) {
-        try {
-            byte[] keyBytes = Base64.getDecoder().decode(base64PrivateKey);
-            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
-            KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
-            return keyFactory.generatePrivate(keySpec);
-        } catch (Exception e) {
-            System.out.println(ExceptionUtil.getRootErrorMessage(e));
-            throw new RuntimeException("加载SM2私钥失败", e);
-        }
-    }
-
-    */
-/**
-     * 从Base64字符串加载公钥
-     *//*
-
-    public static PublicKey loadPublicKey(String base64PublicKey) {
-        try {
-            byte[] keyBytes = Base64.getDecoder().decode(base64PublicKey);
-            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
-            KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
-            return keyFactory.generatePublic(keySpec);
-        } catch (Exception e) {
-            throw new RuntimeException("加载SM2公钥失败", e);
-        }
-    }
-
-    */
-/**
-     * 将私钥转换为Base64字符串
-     *//*
-
-    public static String privateKeyToString(PrivateKey privateKey) {
-        return Base64.getEncoder().encodeToString(privateKey.getEncoded());
-    }
-
-    */
-/**
-     * 将公钥转换为Base64字符串
-     *//*
-
-    public static String publicKeyToString(PublicKey publicKey) {
-        return Base64.getEncoder().encodeToString(publicKey.getEncoded());
-    }
-}*/

+ 0 - 35
ruoyi-common/src/main/java/com/ruoyi/common/utils/SignUtil.java

@@ -1,35 +0,0 @@
-package com.ruoyi.common.utils;
-
-import org.springframework.util.DigestUtils;
-
-import java.nio.charset.StandardCharsets;
-import java.util.StringJoiner;
-
-/**
- * 数据签名工具类
- */
-public class SignUtil {
-    
-    /**
-     * 生成MD5签名
-     */
-    public static String generateSign(String... fields) {
-        StringJoiner joiner = new StringJoiner("|");
-        for (String field : fields) {
-            joiner.add(field != null ? field : "");
-        }
-        String signContent = joiner.toString();
-        return DigestUtils.md5DigestAsHex(signContent.getBytes(StandardCharsets.UTF_8));
-    }
-    
-    /**
-     * 验证签名
-     */
-    public static boolean verifySign(String signature, String... fields) {
-        if (signature == null) {
-            return false;
-        }
-        String calculatedSign = generateSign(fields);
-        return signature.equals(calculatedSign);
-    }
-}

+ 174 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/Sm2Utils.java

@@ -0,0 +1,174 @@
+package com.ruoyi.common.utils;
+ 
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+ 
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.digests.SM3Digest;
+import org.bouncycastle.crypto.engines.SM2Engine;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+ 
+/**
+ * SM2工具类
+ */
+public class Sm2Utils {
+    
+    /**
+     * 加签
+     * @param plainText
+     * @return
+     */
+    public static String sign(String plainText, String privateKeyStr) {
+        BouncyCastleProvider provider = new BouncyCastleProvider();
+        try {   
+            // 获取椭圆曲线KEY生成器
+            KeyFactory keyFactory = KeyFactory.getInstance("EC", provider);
+            byte[] privateKeyData = Base64.getDecoder().decode(privateKeyStr);
+            PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyData);
+            Signature rsaSignature = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), provider);
+            rsaSignature.initSign(keyFactory.generatePrivate(privateKeySpec));
+            rsaSignature.update(plainText.getBytes());
+            byte[] signed = rsaSignature.sign();
+            return Base64.getEncoder().encodeToString(signed);
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException | SignatureException e) {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    /**
+     * 验签
+     * @param plainText
+     * @param signatureValue
+     * @return
+     */
+    public static boolean verify(String plainText, String signatureValue, String publicKeyStr) {
+        BouncyCastleProvider provider = new BouncyCastleProvider();
+        try {
+            // 获取椭圆曲线KEY生成器
+            KeyFactory keyFactory = KeyFactory.getInstance("EC", provider);
+            byte[] publicKeyData = Base64.getDecoder().decode(publicKeyStr);
+            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyData);
+            // 初始化为验签状态
+            Signature signature = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), provider);
+            signature.initVerify(keyFactory.generatePublic(publicKeySpec));
+            signature.update(Hex.decodeHex(plainText.toCharArray()));
+            return signature.verify(Hex.decodeHex(signatureValue.toCharArray()));
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException | SignatureException e) {
+            throw new RuntimeException(e);
+        } catch (IllegalArgumentException e) {
+            return false;
+        } catch (DecoderException e) {
+            return false;
+        }
+    }
+    
+    /**
+     * 加密
+     * @param plainText
+     * @return
+     */
+    public static byte[] encrypt(String plainText, String publicKeyStr) throws Exception {
+        Security.addProvider(new BouncyCastleProvider());
+        try {   
+            // 获取椭圆曲线KEY生成器
+            KeyFactory keyFactory = KeyFactory.getInstance("EC");
+            byte[] publicKeyData = Base64.getDecoder().decode(publicKeyStr);
+            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyData);
+            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
+            CipherParameters publicKeyParamerters = ECUtil.generatePublicKeyParameter(publicKey);
+            //数据加密
+            StandardSM2Engine engine = new StandardSM2Engine(new SM3Digest(), SM2Engine.Mode.C1C3C2);
+            engine.init(true, new ParametersWithRandom(publicKeyParamerters));
+            byte[] encryptData = engine.processBlock(plainText.getBytes(), 0, plainText.getBytes().length);
+            return encryptData;
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException 
+                | InvalidKeyException | InvalidCipherTextException e) {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    /**
+     * 解密
+     * @param encryptedText
+     * @return
+     */
+    public static String decrypt(byte[] encryptedData, String privateKeyStr) {
+        Security.addProvider(new BouncyCastleProvider());
+        try {   
+            // 获取椭圆曲线KEY生成器
+            KeyFactory keyFactory = KeyFactory.getInstance("EC");
+            byte[] privateKeyData = Base64.getDecoder().decode(privateKeyStr);
+            PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyData);
+            PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
+            CipherParameters privateKeyParamerters = ECUtil.generatePrivateKeyParameter(privateKey);
+            //数据解密
+            StandardSM2Engine engine = new StandardSM2Engine(new SM3Digest(), SM2Engine.Mode.C1C3C2);
+            engine.init(false, privateKeyParamerters);
+            byte[] plainText = engine.processBlock(encryptedData, 0, encryptedData.length);
+            return new String(plainText);
+        } catch (NoSuchAlgorithmException | InvalidKeySpecException 
+                | InvalidKeyException | InvalidCipherTextException e) {
+            throw new RuntimeException(e);
+        }
+    }
+    
+    /**
+     * SM2算法生成密钥对
+     * @return 密钥对信息
+     */
+    public static KeyPair generateSm2KeyPair() {
+        try {
+            final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
+            // 获取一个椭圆曲线类型的密钥对生成器
+            final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
+            SecureRandom random = new SecureRandom();
+            // 使用SM2的算法区域初始化密钥生成器
+            kpg.initialize(sm2Spec, random);
+            // 获取密钥对
+            KeyPair keyPair = kpg.generateKeyPair();
+            return keyPair;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+    
+    public static void main(String[] args) throws Exception {
+        KeyPair keyPair = generateSm2KeyPair();
+        String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
+        String publicKey  = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
+        String data = "{\"daId\":\"123456\"}";
+        String encryptedJsonStr =  Hex.encodeHexString(encrypt(data, publicKey)) + "";//16进制字符串
+        String decryptedJsonStr = decrypt(Hex.decodeHex(encryptedJsonStr), privateKey);
+        String sign = Hex.encodeHexString(Base64.getDecoder().decode(sign(data, privateKey)));
+        boolean flag = verify(Hex.encodeHexString(data.getBytes()), sign, publicKey);
+        System.out.println("base64后privateKey:" + privateKey);
+        System.out.println("base64后publicKey:" + publicKey);
+        System.out.println("加密前数据:" + data);
+        System.out.println("公钥加密后16进制字符串:" + encryptedJsonStr);
+        System.out.println("私钥解密后数据:" + decryptedJsonStr);
+        System.out.println("私钥加签后数据(16进制):" + sign);
+        System.out.println("公钥验签结果:" + flag);
+        
+    }
+ 
+}

+ 314 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/StandardSM2Engine.java

@@ -0,0 +1,314 @@
+package com.ruoyi.common.utils;
+ 
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.SecureRandom;
+ 
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1InputStream;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1OctetString;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DEROctetString;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.Digest;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.digests.SM3Digest;
+import org.bouncycastle.crypto.engines.SM2Engine.Mode;
+import org.bouncycastle.crypto.params.ECDomainParameters;
+import org.bouncycastle.crypto.params.ECKeyParameters;
+import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
+import org.bouncycastle.crypto.params.ECPublicKeyParameters;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.math.ec.ECFieldElement;
+import org.bouncycastle.math.ec.ECMultiplier;
+import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.FixedPointCombMultiplier;
+import org.bouncycastle.util.Arrays;
+import org.bouncycastle.util.BigIntegers;
+import org.bouncycastle.util.Memoable;
+import org.bouncycastle.util.Pack;
+ 
+/**
+ * 自定义SM2Engine类,对加密解密数据进行了ASN.1编码
+ */
+public class StandardSM2Engine {
+ 
+    private final Digest digest;
+    private final Mode mode;
+ 
+    private boolean forEncryption;
+    private ECKeyParameters ecKey;
+    private ECDomainParameters ecParams;
+    private int curveLength;
+    private SecureRandom random;
+ 
+    public StandardSM2Engine() {
+        this(new SM3Digest());
+    }
+ 
+    public StandardSM2Engine(Mode mode) {
+        this(new SM3Digest(), mode);
+    }
+ 
+    public StandardSM2Engine(Digest digest) {
+        this(digest, Mode.C1C2C3);
+    }
+ 
+    public StandardSM2Engine(Digest digest, Mode mode) {
+        if (mode == null) {
+            throw new IllegalArgumentException("mode cannot be NULL");
+        }
+        this.digest = digest;
+        this.mode = mode;
+    }
+ 
+    public void init(boolean forEncryption, CipherParameters param) {
+        this.forEncryption = forEncryption;
+ 
+        if (forEncryption) {
+            ParametersWithRandom rParam = (ParametersWithRandom) param;
+ 
+            ecKey = (ECKeyParameters) rParam.getParameters();
+            ecParams = ecKey.getParameters();
+ 
+            ECPoint s = ((ECPublicKeyParameters) ecKey).getQ().multiply(ecParams.getH());
+            if (s.isInfinity()) {
+                throw new IllegalArgumentException("invalid key: [h]Q at infinity");
+            }
+ 
+            random = rParam.getRandom();
+        } else {
+            ecKey = (ECKeyParameters) param;
+            ecParams = ecKey.getParameters();
+        }
+ 
+        curveLength = (ecParams.getCurve().getFieldSize() + 7) / 8;
+    }
+ 
+    public byte[] processBlock(byte[] in, int inOff, int inLen) throws InvalidCipherTextException {
+        if (forEncryption) {
+            return encrypt(in, inOff, inLen);
+        } else {
+            return decrypt(in, inOff, inLen);
+        }
+    }
+ 
+    public int getOutputSize(int inputLen) {
+        return (1 + 2 * curveLength) + inputLen + digest.getDigestSize();
+    }
+ 
+    protected ECMultiplier createBasePointMultiplier() {
+        return new FixedPointCombMultiplier();
+    }
+ 
+    /**
+     * 加密
+     * 
+     * @param in
+     * @param inOff
+     * @param inLen
+     * @return
+     * @throws InvalidCipherTextException
+     */
+    private byte[] encrypt(byte[] in, int inOff, int inLen) throws InvalidCipherTextException {
+        byte[] c2 = new byte[inLen];
+ 
+        System.arraycopy(in, inOff, c2, 0, c2.length);
+ 
+        ECMultiplier multiplier = createBasePointMultiplier();
+ 
+        ECPoint c1P;
+        ECPoint kPB;
+        do {
+            BigInteger k = nextK();
+ 
+            c1P = multiplier.multiply(ecParams.getG(), k).normalize();
+ 
+            kPB = ((ECPublicKeyParameters) ecKey).getQ().multiply(k).normalize();
+ 
+            kdf(digest, kPB, c2);
+        } while (notEncrypted(c2, in, inOff));
+ 
+        byte[] c3 = new byte[digest.getDigestSize()];
+ 
+        addFieldElement(digest, kPB.getAffineXCoord());
+        digest.update(in, inOff, inLen);
+        addFieldElement(digest, kPB.getAffineYCoord());
+ 
+        digest.doFinal(c3, 0);
+ 
+        return convertToASN1(c1P, c2, c3);
+    }
+ 
+    /**
+     * 解密
+     * 
+     * @param in
+     * @param inOff
+     * @param inLen
+     * @return
+     * @throws InvalidCipherTextException
+     */
+    private byte[] decrypt(byte[] in, int inOff, int inLen) throws InvalidCipherTextException {
+        byte[] decryptData = new byte[inLen];
+        System.arraycopy(in, inOff, decryptData, 0, decryptData.length);
+ 
+        BigInteger x;
+        BigInteger y;
+        byte[] originC3;
+        byte[] c2;
+        ECPoint c1P;
+        byte[] c1;
+        try (ASN1InputStream aIn = new ASN1InputStream(decryptData)) {
+            ASN1Sequence seq;
+            try {
+                seq = (ASN1Sequence) aIn.readObject();
+            } catch (IOException e) {
+                throw new InvalidCipherTextException();
+            }
+            x = ASN1Integer.getInstance(seq.getObjectAt(0)).getValue();
+            y = ASN1Integer.getInstance(seq.getObjectAt(1)).getValue();
+            c1P = ecParams.getCurve().validatePoint(x, y);
+            c1 = c1P.getEncoded(false);
+            if (mode == Mode.C1C3C2) {
+                originC3 = ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets();
+                c2 = ASN1OctetString.getInstance(seq.getObjectAt(3)).getOctets();
+            } else {
+                c2 = ASN1OctetString.getInstance(seq.getObjectAt(2)).getOctets();
+                originC3 = ASN1OctetString.getInstance(seq.getObjectAt(3)).getOctets();
+            }
+        } catch (IOException e) {
+            throw new InvalidCipherTextException();
+        }
+ 
+        ECPoint s = c1P.multiply(ecParams.getH());
+        if (s.isInfinity()) {
+            throw new InvalidCipherTextException("[h]C1 at infinity");
+        }
+ 
+        c1P = c1P.multiply(((ECPrivateKeyParameters) ecKey).getD()).normalize();
+ 
+        kdf(digest, c1P, c2);
+ 
+        byte[] c3 = new byte[digest.getDigestSize()];
+ 
+        addFieldElement(digest, c1P.getAffineXCoord());
+        digest.update(c2, 0, c2.length);
+        addFieldElement(digest, c1P.getAffineYCoord());
+ 
+        digest.doFinal(c3, 0);
+ 
+        int check = 0;
+        for (int i = 0; i != c3.length; i++) {
+            check |= c3[i] ^ originC3[i];
+        }
+ 
+        Arrays.fill(c1, (byte) 0);
+        Arrays.fill(c3, (byte) 0);
+ 
+        if (check != 0) {
+            Arrays.fill(c2, (byte) 0);
+            throw new InvalidCipherTextException("invalid cipher text");
+        }
+ 
+        return c2;
+    }
+ 
+    private boolean notEncrypted(byte[] encData, byte[] in, int inOff) {
+        for (int i = 0; i != encData.length; i++) {
+            if (encData[i] != in[inOff + i]) {
+                return false;
+            }
+        }
+ 
+        return true;
+    }
+ 
+    private void kdf(Digest digest, ECPoint c1, byte[] encData) {
+        int digestSize = digest.getDigestSize();
+        byte[] buf = new byte[Math.max(4, digestSize)];
+        int off = 0;
+ 
+        Memoable memo = null;
+        Memoable copy = null;
+ 
+        if (digest instanceof Memoable) {
+            addFieldElement(digest, c1.getAffineXCoord());
+            addFieldElement(digest, c1.getAffineYCoord());
+            memo = (Memoable) digest;
+            copy = memo.copy();
+        }
+ 
+        int ct = 0;
+ 
+        while (off < encData.length) {
+            if (memo != null) {
+                memo.reset(copy);
+            } else {
+                addFieldElement(digest, c1.getAffineXCoord());
+                addFieldElement(digest, c1.getAffineYCoord());
+            }
+ 
+            Pack.intToBigEndian(++ct, buf, 0);
+            digest.update(buf, 0, 4);
+            digest.doFinal(buf, 0);
+ 
+            int xorLen = Math.min(digestSize, encData.length - off);
+            xor(encData, buf, off, xorLen);
+            off += xorLen;
+        }
+    }
+ 
+    private void xor(byte[] data, byte[] kdfOut, int dOff, int dRemaining) {
+        for (int i = 0; i != dRemaining; i++) {
+            data[dOff + i] ^= kdfOut[i];
+        }
+    }
+ 
+    private BigInteger nextK() {
+        int qBitLength = ecParams.getN().bitLength();
+ 
+        BigInteger k;
+        do {
+            k = BigIntegers.createRandomBigInteger(qBitLength, random);
+        } while (k.equals(BigIntegers.ZERO) || k.compareTo(ecParams.getN()) >= 0);
+ 
+        return k;
+    }
+ 
+    private void addFieldElement(Digest digest, ECFieldElement v) {
+        byte[] p = BigIntegers.asUnsignedByteArray(curveLength, v.toBigInteger());
+ 
+        digest.update(p, 0, p.length);
+    }
+ 
+    private byte[] convertToASN1(ECPoint c1P, byte[] c2, byte[] c3) {
+        ASN1Integer x = new ASN1Integer(c1P.getXCoord().toBigInteger());
+        ASN1Integer y = new ASN1Integer(c1P.getYCoord().toBigInteger());
+        DEROctetString derDig = new DEROctetString(c3);
+        DEROctetString derEnc = new DEROctetString(c2);
+        ASN1EncodableVector v = new ASN1EncodableVector();
+        switch (mode) {
+        case C1C3C2:
+            v.add(x);
+            v.add(y);
+            v.add(derDig);
+            v.add(derEnc);
+            break;
+        default:
+            v.add(x);
+            v.add(y);
+            v.add(derEnc);
+            v.add(derDig);
+        }
+        DERSequence seq = new DERSequence(v);
+        try {
+            return seq.getEncoded();
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+ 
+}