From 7b4211d813e06b810c99bed7552d732dd31b4041 Mon Sep 17 00:00:00 2001
From: maven <2163098428@qq.com>
Date: 星期二, 03 三月 2026 17:56:36 +0800
Subject: [PATCH] yys  商机管理优化

---
 src/main/java/com/ruoyi/project/system/domain/SysNotice.java                      |  100 +++-----
 src/main/java/com/ruoyi/project/system/service/SysUserClientService.java          |   19 +
 src/main/resources/application-prod.yml                                           |    9 
 src/main/java/com/ruoyi/project/system/domain/SysUser.java                        |   11 
 src/main/java/com/ruoyi/sales/pojo/BusinessOpportunity.java                       |    7 
 pom.xml                                                                           |    8 
 src/main/java/com/ruoyi/project/system/controller/SysUserClientController.java    |   42 +++
 src/main/java/com/ruoyi/project/system/domain/SysMenu.java                        |   10 
 src/main/java/com/ruoyi/sales/controller/BusinessOpportunityController.java       |   31 ++
 src/main/java/com/ruoyi/project/system/domain/GetuiConfig.java                    |   46 +++
 src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java                  |    7 
 src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java           |  208 +++++++++++++++++
 src/main/resources/mapper/system/SysMenuMapper.xml                                |   11 
 src/main/resources/mapper/system/SysUserMapper.xml                                |   44 +++
 src/main/resources/application-dev.yml                                            |    9 
 src/main/java/com/ruoyi/project/system/service/impl/SysUserClientServiceImpl.java |   43 +++
 src/main/java/com/ruoyi/sales/pojo/BusinessDescription.java                       |    1 
 src/main/java/com/ruoyi/project/system/domain/SysUserClient.java                  |   47 +++
 src/main/java/com/ruoyi/project/system/mapper/SysUserClientMapper.java            |   18 +
 19 files changed, 601 insertions(+), 70 deletions(-)

diff --git a/pom.xml b/pom.xml
index 17973d1..e6c1ebe 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,6 +43,7 @@
         <spring-security.version>5.7.12</spring-security.version>
         <spring-framework.version>5.3.39</spring-framework.version>
         <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
+        <getui-sdk.version>1.0.7.0</getui-sdk.version>
     </properties>
 
     <dependencies>
@@ -53,6 +54,13 @@
             <version>3.0.3</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.getui.push</groupId>
+            <artifactId>restful-sdk</artifactId>
+            <version>${getui-sdk.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
         <!-- SpringBoot 鏍稿績鍖� -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
diff --git a/src/main/java/com/ruoyi/project/system/controller/SysUserClientController.java b/src/main/java/com/ruoyi/project/system/controller/SysUserClientController.java
new file mode 100644
index 0000000..6ce6394
--- /dev/null
+++ b/src/main/java/com/ruoyi/project/system/controller/SysUserClientController.java
@@ -0,0 +1,42 @@
+package com.ruoyi.project.system.controller;
+
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.framework.web.controller.BaseController;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.project.system.domain.SysUserClient;
+import com.ruoyi.project.system.service.SysUserClientService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 鐢ㄦ埛瀹夊崜璁惧绠$悊鎺у埗灞�
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/2/9
+ */
+@Api(tags = "鐢ㄦ埛璁惧缁戝畾")
+@RestController
+@RequestMapping("/system/client")
+public class SysUserClientController extends BaseController {
+
+    @Autowired
+    private SysUserClientService sysUserClientService;
+
+    /**
+     * 娣诲姞/鏇存柊鐢ㄦ埛cid
+     */
+    @PostMapping("/addOrUpdateClientId")
+    @ApiOperation("娣诲姞/鏇存柊鐢ㄦ埛cid")
+    public AjaxResult addOrUpdateClientId(@RequestBody SysUserClient sysUserClient) {
+        Long userId = SecurityUtils.getUserId();
+        sysUserClient.setUserId(userId);
+        boolean result = sysUserClientService.addOrUpdateClientId(sysUserClient);
+        return result ? success() : error("璁惧缁戝畾澶辫触");
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/project/system/domain/GetuiConfig.java b/src/main/java/com/ruoyi/project/system/domain/GetuiConfig.java
new file mode 100644
index 0000000..f5ba300
--- /dev/null
+++ b/src/main/java/com/ruoyi/project/system/domain/GetuiConfig.java
@@ -0,0 +1,46 @@
+package com.ruoyi.project.system.domain;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * <p>
+ * 涓帹 (Unipush v2) 娑堟伅鎺ㄩ�侀厤缃被
+ * </p>
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/2/9
+ */
+@Data
+@Component
+@ConfigurationProperties(prefix = "ruoyi.getui")
+public class GetuiConfig {
+
+    /**
+     * AppID
+     */
+    private String appId;
+
+    /**
+     * AppKey
+     */
+    private String appKey;
+
+    /**
+     * MasterSecret
+     */
+    private String masterSecret;
+
+    /**
+     * 涓帹 RESTful API 鍩熷悕鍦板潃
+     */
+    private String domain;
+
+    /**
+     * 绂荤嚎鎺ㄩ�� Intent 鐩爣缁勪欢鍚�
+     * 鏍煎紡: 鍖呭悕/鍏ュ彛Activity鍚�
+     */
+    private String intentComponent;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/project/system/domain/SysMenu.java b/src/main/java/com/ruoyi/project/system/domain/SysMenu.java
index d6e8b3a..caad5bc 100644
--- a/src/main/java/com/ruoyi/project/system/domain/SysMenu.java
+++ b/src/main/java/com/ruoyi/project/system/domain/SysMenu.java
@@ -18,6 +18,16 @@
 {
     private static final long serialVersionUID = 1L;
 
+    private String appComponent;
+
+    public String getAppComponent() {
+        return appComponent;
+    }
+
+    public void setAppComponent(String appComponent) {
+        this.appComponent = appComponent;
+    }
+
     /** 鑿滃崟ID */
     private Long menuId;
 
diff --git a/src/main/java/com/ruoyi/project/system/domain/SysNotice.java b/src/main/java/com/ruoyi/project/system/domain/SysNotice.java
index 635e691..b88a57c 100644
--- a/src/main/java/com/ruoyi/project/system/domain/SysNotice.java
+++ b/src/main/java/com/ruoyi/project/system/domain/SysNotice.java
@@ -2,21 +2,30 @@
 
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.Size;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 import com.ruoyi.common.xss.Xss;
 import com.ruoyi.framework.web.domain.BaseEntity;
 
+import java.time.LocalDateTime;
+
 /**
  * 閫氱煡鍏憡琛� sys_notice
- * 
+ *
  * @author ruoyi
  */
-public class SysNotice extends BaseEntity
+@Data
+@TableName("sys_notice")
+public class SysNotice
 {
     private static final long serialVersionUID = 1L;
 
     /** 鍏憡ID */
+    @TableId(value = "notice_id", type = IdType.AUTO)
     private Long noticeId;
 
     /** 鍏憡鏍囬 */
@@ -31,72 +40,43 @@
     /** 鍏憡鐘舵�侊紙0姝e父 1鍏抽棴锛� */
     private String status;
 
-    public Long getNoticeId()
-    {
-        return noticeId;
-    }
+    /** 鍙戦�佷汉id */
+    private Long senderId;
 
-    public void setNoticeId(Long noticeId)
-    {
-        this.noticeId = noticeId;
-    }
+    /** 鏀朵欢浜篿d */
+    private Long consigneeId;
 
-    public void setNoticeTitle(String noticeTitle)
-    {
-        this.noticeTitle = noticeTitle;
-    }
+    /** 璺宠浆璺緞 */
+    private String jumpPath;
 
-    @Xss(message = "鍏憡鏍囬涓嶈兘鍖呭惈鑴氭湰瀛楃")
-    @NotBlank(message = "鍏憡鏍囬涓嶈兘涓虹┖")
-    @Size(min = 0, max = 50, message = "鍏憡鏍囬涓嶈兘瓒呰繃50涓瓧绗�")
-    public String getNoticeTitle()
-    {
-        return noticeTitle;
-    }
+    /** APP璺宠浆璺緞 */
+    private String appJumpPath;
 
-    public void setNoticeType(String noticeType)
-    {
-        this.noticeType = noticeType;
-    }
+    /** 鍒涘缓鑰� */
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
 
-    public String getNoticeType()
-    {
-        return noticeType;
-    }
+    /** 鍒涘缓鏃堕棿 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
 
-    public void setNoticeContent(String noticeContent)
-    {
-        this.noticeContent = noticeContent;
-    }
+    /** 鏇存柊鑰� */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private String updateBy;
 
-    public String getNoticeContent()
-    {
-        return noticeContent;
-    }
+    /** 鏇存柊鏃堕棿 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
 
-    public void setStatus(String status)
-    {
-        this.status = status;
-    }
+    /** 澶囨敞 */
+    private String remark;
 
-    public String getStatus()
-    {
-        return status;
-    }
+    /**
+     * 绉熸埛id
+     */
+    private Long tenantId;
 
-    @Override
-    public String toString() {
-        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
-            .append("noticeId", getNoticeId())
-            .append("noticeTitle", getNoticeTitle())
-            .append("noticeType", getNoticeType())
-            .append("noticeContent", getNoticeContent())
-            .append("status", getStatus())
-            .append("createBy", getCreateBy())
-            .append("createTime", getCreateTime())
-            .append("updateBy", getUpdateBy())
-            .append("updateTime", getUpdateTime())
-            .append("remark", getRemark())
-            .toString();
-    }
+
 }
diff --git a/src/main/java/com/ruoyi/project/system/domain/SysUser.java b/src/main/java/com/ruoyi/project/system/domain/SysUser.java
index b568471..c58a65b 100644
--- a/src/main/java/com/ruoyi/project/system/domain/SysUser.java
+++ b/src/main/java/com/ruoyi/project/system/domain/SysUser.java
@@ -23,6 +23,17 @@
 {
     private static final long serialVersionUID = 1L;
 
+    public String getPostCode() {
+        return postCode;
+    }
+
+    public void setPostCode(String postCode) {
+        this.postCode = postCode;
+    }
+
+    @TableField(exist = false)
+    private String postCode;
+
     /** 鐢ㄦ埛ID */
     @Excel(name = "鐢ㄦ埛搴忓彿", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "鐢ㄦ埛缂栧彿")
     private Long userId;
diff --git a/src/main/java/com/ruoyi/project/system/domain/SysUserClient.java b/src/main/java/com/ruoyi/project/system/domain/SysUserClient.java
new file mode 100644
index 0000000..faa26b2
--- /dev/null
+++ b/src/main/java/com/ruoyi/project/system/domain/SysUserClient.java
@@ -0,0 +1,47 @@
+package com.ruoyi.project.system.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <br>
+ * 鐢ㄦ埛瀹夊崜璁惧鍏宠仈瀵硅薄 sys_user_client
+ * </br>
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/2/9
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("sys_user_client")
+public class SysUserClient implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    @TableId(type = IdType.INPUT)
+    private Long userId;
+
+    /**
+     * 涓帹璁惧鏍囪瘑 (CID)
+     */
+    private String cid;
+
+    /**
+     * 鏈�鍚庢椿璺冩椂闂�
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java b/src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java
index 3a0857d..4d3341f 100644
--- a/src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java
+++ b/src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java
@@ -122,4 +122,11 @@
      * @return 缁撴灉
      */
     public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId);
+    /**
+     * 鏍规嵁璺敱鍦板潃鏌ヨ鑿滃崟
+     *
+     * @param lastSegment 璺敱鍦板潃
+     * @return 鑿滃崟
+     */
+    SysMenu selectMenuByPath(String lastSegment);
 }
diff --git a/src/main/java/com/ruoyi/project/system/mapper/SysUserClientMapper.java b/src/main/java/com/ruoyi/project/system/mapper/SysUserClientMapper.java
new file mode 100644
index 0000000..b48e2e7
--- /dev/null
+++ b/src/main/java/com/ruoyi/project/system/mapper/SysUserClientMapper.java
@@ -0,0 +1,18 @@
+package com.ruoyi.project.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.project.system.domain.SysUserClient;
+
+/**
+ * <br>
+ * 鐢ㄦ埛瀹夊崜璁惧鍏宠仈mapper
+ * </br>
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/2/9
+ */
+
+public interface SysUserClientMapper extends BaseMapper<SysUserClient> {
+
+}
diff --git a/src/main/java/com/ruoyi/project/system/service/SysUserClientService.java b/src/main/java/com/ruoyi/project/system/service/SysUserClientService.java
new file mode 100644
index 0000000..0ff0009
--- /dev/null
+++ b/src/main/java/com/ruoyi/project/system/service/SysUserClientService.java
@@ -0,0 +1,19 @@
+package com.ruoyi.project.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.project.system.domain.SysUserClient;
+
+/**
+ * <br>
+ * 鐢ㄦ埛瀹夊崜璁惧鍏宠仈鎺ュ彛
+ * </br>
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/2/9
+ */
+
+public interface SysUserClientService extends IService<SysUserClient> {
+
+    boolean addOrUpdateClientId(SysUserClient sysUserClient);
+}
diff --git a/src/main/java/com/ruoyi/project/system/service/impl/SysUserClientServiceImpl.java b/src/main/java/com/ruoyi/project/system/service/impl/SysUserClientServiceImpl.java
new file mode 100644
index 0000000..7130bf4
--- /dev/null
+++ b/src/main/java/com/ruoyi/project/system/service/impl/SysUserClientServiceImpl.java
@@ -0,0 +1,43 @@
+package com.ruoyi.project.system.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.project.system.domain.SysUserClient;
+import com.ruoyi.project.system.mapper.SysUserClientMapper;
+import com.ruoyi.project.system.service.SysUserClientService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+
+/**
+ * 鐢ㄦ埛瀹夊崜璁惧鍏宠仈鎺ュ彛瀹炵幇绫�
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/2/9
+ */
+@Service
+public class SysUserClientServiceImpl extends ServiceImpl<SysUserClientMapper, SysUserClient> implements SysUserClientService {
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean addOrUpdateClientId(SysUserClient sysUserClient) {
+        if (sysUserClient == null || sysUserClient.getUserId() == null || StringUtils.isEmpty(sysUserClient.getCid())) {
+            return false;
+        }
+
+        String cid = sysUserClient.getCid();
+        Long userId = sysUserClient.getUserId();
+
+        remove(new LambdaQueryWrapper<SysUserClient>().eq(SysUserClient::getCid, cid).ne(SysUserClient::getUserId, userId));
+
+        SysUserClient userClient = new SysUserClient();
+        userClient.setUserId(userId);
+        userClient.setCid(cid);
+        userClient.setUpdateTime(new Date());
+
+        return saveOrUpdate(userClient);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java b/src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java
new file mode 100644
index 0000000..4dc2a85
--- /dev/null
+++ b/src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java
@@ -0,0 +1,208 @@
+package com.ruoyi.project.system.service.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.getui.push.v2.sdk.ApiHelper;
+import com.getui.push.v2.sdk.GtApiConfiguration;
+import com.getui.push.v2.sdk.api.PushApi;
+import com.getui.push.v2.sdk.common.ApiResult;
+import com.getui.push.v2.sdk.dto.req.Audience;
+import com.getui.push.v2.sdk.dto.req.message.PushChannel;
+import com.getui.push.v2.sdk.dto.req.message.PushDTO;
+import com.getui.push.v2.sdk.dto.req.message.PushMessage;
+import com.getui.push.v2.sdk.dto.req.message.android.AndroidDTO;
+import com.getui.push.v2.sdk.dto.req.message.android.ThirdNotification;
+import com.getui.push.v2.sdk.dto.req.message.android.Ups;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.project.system.domain.GetuiConfig;
+import com.ruoyi.project.system.domain.SysMenu;
+import com.ruoyi.project.system.domain.SysNotice;
+import com.ruoyi.project.system.domain.SysUserClient;
+import com.ruoyi.project.system.mapper.SysMenuMapper;
+import com.ruoyi.project.system.service.SysUserClientService;
+import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * APP娑堟伅鎺ㄩ�佹湇鍔�
+ *
+ * @author deslrey
+ * @version 1.4
+ * @since 2026/2/9
+ */
+@Slf4j
+@Component
+public class UnipushService {
+
+    @Autowired
+    private SysMenuMapper sysMenuMapper;
+
+    @Autowired
+    private GetuiConfig getuiConfig;
+
+    @Autowired
+    private SysUserClientService userClientService;
+
+    private PushApi pushApi;
+
+    private static final String DEFAULT_APP_PAGE = "pages/index";
+
+    @PostConstruct
+    public void init() {
+        GtApiConfiguration config = new GtApiConfiguration();
+        config.setAppId(getuiConfig.getAppId());
+        config.setAppKey(getuiConfig.getAppKey());
+        config.setMasterSecret(getuiConfig.getMasterSecret());
+        config.setDomain(getuiConfig.getDomain());
+        ApiHelper apiHelper = ApiHelper.build(config);
+        this.pushApi = apiHelper.creatApi(PushApi.class);
+    }
+
+    /**
+     * 鎵归噺鍙戦�侀�氱煡鍏憡鍒扮Щ鍔ㄧ
+     */
+    @Async
+    public void sendClientMessage(List<SysNotice> sysNoticeList) {
+        if (sysNoticeList == null || sysNoticeList.isEmpty()) {
+            return;
+        }
+
+        for (SysNotice sysNotice : sysNoticeList) {
+            SysUserClient client = userClientService.getById(sysNotice.getConsigneeId());
+            if (client == null || StringUtils.isEmpty(client.getCid())) {
+                log.warn("鐢ㄦ埛 {} 鏈粦瀹氱Щ鍔ㄧ CID,璺宠繃鎺ㄩ��", sysNotice.getConsigneeId());
+                continue;
+            }
+
+            // 杞崲璺緞
+//            String appPath = convertWebPathToAppPath(sysNotice.getJumpPath());
+
+            // 鎺ㄩ��
+            sendRoutingPush(
+                    sysNotice.getNoticeId(),
+                    client.getCid(),
+                    sysNotice.getNoticeTitle(),
+                    sysNotice.getRemark() != null ? sysNotice.getRemark() : sysNotice.getNoticeContent(),
+                    sysNotice.getAppJumpPath()
+            );
+        }
+    }
+
+    /**
+     * 灏� Web 绔垎灞傚叏璺緞杞崲涓� App 绔粍浠惰矾鐢�
+     */
+    public String convertWebPathToAppPath(String webPath) {
+        if (StringUtils.isEmpty(webPath)) {
+            return DEFAULT_APP_PAGE;
+        }
+
+        String pathOnly = webPath;
+        String queryString = "";
+        if (webPath.contains("?")) {
+            int index = webPath.indexOf("?");
+            pathOnly = webPath.substring(0, index);
+            queryString = webPath.substring(index);
+        }
+
+        String lastSegment;
+        int lastSlashIndex = pathOnly.lastIndexOf("/");
+        if (lastSlashIndex != -1) {
+            lastSegment = pathOnly.substring(lastSlashIndex + 1);
+        } else {
+            lastSegment = pathOnly;
+        }
+
+        if (StringUtils.isEmpty(lastSegment)) {
+            return DEFAULT_APP_PAGE;
+        }
+
+        SysMenu menu = sysMenuMapper.selectMenuByPath(lastSegment);
+
+        if (menu != null && StringUtils.isNotEmpty(menu.getAppComponent())) {
+            String appPath = menu.getAppComponent();
+
+            if (appPath.startsWith("/")) {
+                appPath = appPath.substring(1);
+            }
+
+            //  鎷兼帴 Web 绔師濮嬪弬鏁板苟杩斿洖
+            return appPath + queryString;
+        }
+
+        return DEFAULT_APP_PAGE;
+    }
+
+    /**
+     * 鍙戦�佸崟浜鸿矾鐢辨帹閫�
+     */
+    private void sendRoutingPush(Long noticeId, String cid, String title, String content, String targetPath) {
+        log.info("鍑嗗鎺ㄩ�佹秷鎭�:NoticeId={}, CID={}, Title={}, TargetPath={}", noticeId, cid, title, targetPath);
+
+        PushDTO<Audience> pushDTO = new PushDTO<>();
+        pushDTO.setRequestId("REQ_" + System.currentTimeMillis());
+
+        // 鍦ㄧ嚎閫忎紶鍐呭
+        PushMessage pushMessage = new PushMessage();
+        Map<String, Object> pushMessageMap = new HashMap<>();
+        Map<String, Object> payloadMap = new HashMap<>();
+        pushMessageMap.put("title", title);
+        pushMessageMap.put("content", content);
+        payloadMap.put("url", targetPath);
+        payloadMap.put("noticeId", noticeId);
+        pushMessageMap.put("payload", JSON.toJSONString(payloadMap));
+
+        String transmissionContent = JSON.toJSONString(pushMessageMap);
+        pushMessage.setTransmission(transmissionContent);
+        pushDTO.setPushMessage(pushMessage);
+
+        // 鎺ユ敹浜�
+        Audience audience = new Audience();
+        audience.addCid(cid);
+        pushDTO.setAudience(audience);
+
+        // 绂荤嚎鎺ㄩ�侀�氶亾
+//        pushDTO.setPushChannel(getPushChannel(noticeId, title, content, targetPath));
+
+        try {
+            ApiResult<Map<String, Map<String, String>>> result = pushApi.pushToSingleByCid(pushDTO);
+            if (result.isSuccess()) {
+                log.info("Unipush 鎺ㄩ�佹垚鍔�: CID={}", cid);
+            } else {
+                log.error("Unipush 鎺ㄩ�佸け璐�: CID={}, Code={}, Msg={}", cid, result.getCode(), result.getMsg());
+            }
+        } catch (Exception e) {
+            log.error("Unipush 鎺ㄩ�佸紓甯�: ", e);
+        }
+    }
+
+    @NotNull
+    private PushChannel getPushChannel(Long noticeId, String title, String content, String targetPath) {
+        PushChannel pushChannel = new PushChannel();
+        AndroidDTO androidDTO = new AndroidDTO();
+        Ups ups = new Ups();
+        ThirdNotification thirdNotification = new ThirdNotification();
+        thirdNotification.setTitle(title);
+        thirdNotification.setBody(content);
+        thirdNotification.setClickType("intent");
+
+        String intent = "intent:#Intent;launchFlags=0x04000000;"
+                + "component=" + getuiConfig.getIntentComponent() + ";"
+                + "S.UP-OL-P9=true;"
+                + "S.path=" + targetPath + ";"
+                + "S.payload=" + targetPath + ";"
+                + "end";
+        thirdNotification.setIntent(intent);
+
+        ups.setNotification(thirdNotification);
+        androidDTO.setUps(ups);
+        pushChannel.setAndroid(androidDTO);
+        return pushChannel;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/sales/controller/BusinessOpportunityController.java b/src/main/java/com/ruoyi/sales/controller/BusinessOpportunityController.java
index 49e311c..ff320d0 100644
--- a/src/main/java/com/ruoyi/sales/controller/BusinessOpportunityController.java
+++ b/src/main/java/com/ruoyi/sales/controller/BusinessOpportunityController.java
@@ -3,10 +3,13 @@
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.framework.aspectj.lang.annotation.Log;
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.controller.BaseController;
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.project.system.domain.SysNotice;
+import com.ruoyi.project.system.service.impl.UnipushService;
 import com.ruoyi.sales.mapper.BusinessDescriptionMapper;
 import com.ruoyi.sales.pojo.BusinessDescription;
 import com.ruoyi.sales.pojo.BusinessOpportunity;
@@ -20,6 +23,7 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -39,6 +43,9 @@
 
     @Autowired
     private CommonFileServiceImpl commonFileService;
+
+    @Autowired
+    private UnipushService unipushService;
 
     @ApiOperation("鑾峰彇鐪佺骇鍒楄〃")
     @GetMapping("/getProvinceList")
@@ -69,13 +76,24 @@
     @ApiOperation("娣诲姞鍟嗘満")
     @Log(title = "鍟嗘満绠$悊-娣诲姞鍟嗘満", businessType = BusinessType.INSERT)
     @Transactional(rollbackFor = Exception.class)
-    public AjaxResult add(@RequestBody BusinessOpportunity businessOpportunity) throws  Exception{
+    public AjaxResult add(@RequestBody BusinessOpportunity businessOpportunity) throws Exception{
         businessOpportunityService.save(businessOpportunity);
         BusinessDescription businessDescription = new BusinessDescription();
         BeanUtils.copyProperties(businessOpportunity, businessDescription);
         businessDescription.setBusinessOpportunityId(businessOpportunity.getId());
         // 杩佺Щ涓存椂鏂囦欢鍒版寮忔枃浠�
         commonFileService.migrateTempFilesToFormal(businessOpportunity.getId(), businessOpportunity.getTempFileIds());
+        // 鎺ㄩ�佹秷鎭�
+        List<SysNotice> sysNoticeList = new ArrayList<>();
+        SysNotice sysNotice = new SysNotice();
+        sysNotice.setNoticeTitle("涓氬姟鍛� "+ businessOpportunity.getEntryPerson());
+        sysNotice.setNoticeContent("鏂板瀹㈡埛 " + businessOpportunity.getCustomerName() + " 閲戦 "+ businessOpportunity.getContractAmount());
+        sysNotice.setNoticeType("1");
+        sysNotice.setStatus("0");
+        sysNotice.setSenderId(SecurityUtils.getUserId());
+        sysNotice.setConsigneeId(SecurityUtils.getUserId());
+        sysNotice.setAppJumpPath("pages/opportunityManagement/index");
+        unipushService.sendClientMessage(sysNoticeList);
         return businessDescriptionMapper.insert(businessDescription) > 0 ? success() : error();
     }
 
@@ -90,6 +108,17 @@
         if(byId != null){
             byId.setStatus(businessDescription.getStatus());
             businessOpportunityService.updateById(byId);
+            // 鎺ㄩ�佹秷鎭�
+            List<SysNotice> sysNoticeList = new ArrayList<>();
+            SysNotice sysNotice = new SysNotice();
+            sysNotice.setNoticeTitle("涓氬姟鍛� "+ businessDescription.getEntryPerson());
+            sysNotice.setNoticeContent("瀹㈡埛 " + byId.getCustomerName() + " 閲戦 "+ byId.getContractAmount() + " 鐘舵�� " + businessDescription.getStatus());
+            sysNotice.setNoticeType("1");
+            sysNotice.setStatus("0");
+            sysNotice.setSenderId(SecurityUtils.getUserId());
+            sysNotice.setConsigneeId(SecurityUtils.getUserId());
+            sysNotice.setAppJumpPath("pages/opportunityManagement/index");
+            unipushService.sendClientMessage(sysNoticeList);
         }
         return businessDescriptionMapper.insert(businessDescription) > 0 ? success() : error();
     }
diff --git a/src/main/java/com/ruoyi/sales/pojo/BusinessDescription.java b/src/main/java/com/ruoyi/sales/pojo/BusinessDescription.java
index 881dad1..763fc3e 100644
--- a/src/main/java/com/ruoyi/sales/pojo/BusinessDescription.java
+++ b/src/main/java/com/ruoyi/sales/pojo/BusinessDescription.java
@@ -7,6 +7,7 @@
 import lombok.Data;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.Date;
 import java.util.List;
diff --git a/src/main/java/com/ruoyi/sales/pojo/BusinessOpportunity.java b/src/main/java/com/ruoyi/sales/pojo/BusinessOpportunity.java
index 7e6e10d..7da6242 100644
--- a/src/main/java/com/ruoyi/sales/pojo/BusinessOpportunity.java
+++ b/src/main/java/com/ruoyi/sales/pojo/BusinessOpportunity.java
@@ -8,6 +8,7 @@
 import lombok.Data;
 import org.springframework.format.annotation.DateTimeFormat;
 
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.Date;
 import java.util.List;
@@ -71,6 +72,12 @@
     @TableField(exist = false)
     private String description;
 
+    @ApiModelProperty(value = "鍚堝悓閲戦")
+    private BigDecimal contractAmount;
+
+    @ApiModelProperty(value = "浠樻鎻忚堪")
+    private String paymentDescription;
+
     @ApiModelProperty(value = "鍟嗘満鏉ユ簮")
     private String businessSource;
 
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
index a0b7864..f0010a0 100644
--- a/src/main/resources/application-dev.yml
+++ b/src/main/resources/application-dev.yml
@@ -14,6 +14,15 @@
   # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
   captchaType: math
 
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
 # 寮�鍙戠幆澧冮厤缃�
 server:
   # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml
index 7c4b412..859e52e 100644
--- a/src/main/resources/application-prod.yml
+++ b/src/main/resources/application-prod.yml
@@ -14,6 +14,15 @@
   # 楠岃瘉鐮佺被鍨� math 鏁板瓧璁$畻 char 瀛楃楠岃瘉
   captchaType: math
 
+  # 涓帹 Unipush 閰嶇疆
+  getui:
+    appId: PfjyAAE0FK64FaO1w2CMb1
+    appKey: zTMb831OEL6J4GK1uE3Ob4
+    masterSecret: K1GFtsv42v61tXGnF7SGE5
+    domain: https://restapi.getui.cn/v2/
+    # 绂荤嚎鎺ㄩ�佷娇鐢ㄧ殑鍖呭悕/缁勪欢鍚�
+    intentComponent: uni.app.UNI099A590/io.dcloud.PandoraEntry
+
 # 寮�鍙戠幆澧冮厤缃�
 server:
   # 鏈嶅姟鍣ㄧ殑HTTP绔彛锛岄粯璁や负8080
diff --git a/src/main/resources/mapper/system/SysMenuMapper.xml b/src/main/resources/mapper/system/SysMenuMapper.xml
index a3b6426..b629639 100644
--- a/src/main/resources/mapper/system/SysMenuMapper.xml
+++ b/src/main/resources/mapper/system/SysMenuMapper.xml
@@ -12,6 +12,7 @@
 		<result property="orderNum"       column="order_num"      />
 		<result property="path"           column="path"           />
 		<result property="component"      column="component"      />
+		<result property="appComponent"      column="app_component"      />
 		<result property="query"          column="query"          />
 		<result property="routeName"      column="route_name"     />
 		<result property="isFrame"        column="is_frame"       />
@@ -132,8 +133,14 @@
 		<include refid="selectMenuVo"/>
 		where menu_name=#{menuName} and parent_id = #{parentId} limit 1
 	</select>
-	
-	<update id="updateMenu" parameterType="com.ruoyi.project.system.domain.SysMenu">
+	<select id="selectMenuByPath" resultType="com.ruoyi.project.system.domain.SysMenu" parameterType="java.lang.String">
+		SELECT menu_id, menu_name, parent_id, path, app_component, status
+		FROM sys_menu
+		WHERE path = #{path}
+		  AND status = '0' LIMIT 1
+	</select>
+
+    <update id="updateMenu" parameterType="com.ruoyi.project.system.domain.SysMenu">
 		update sys_menu
 		<set>
 			<if test="menuName != null and menuName != ''">menu_name = #{menuName},</if>
diff --git a/src/main/resources/mapper/system/SysUserMapper.xml b/src/main/resources/mapper/system/SysUserMapper.xml
index f77e62c..1b5cc71 100644
--- a/src/main/resources/mapper/system/SysUserMapper.xml
+++ b/src/main/resources/mapper/system/SysUserMapper.xml
@@ -56,19 +56,38 @@
     </sql>
     
     <select id="selectUserList" parameterType="com.ruoyi.project.system.domain.SysUser" resultMap="SysUserResult">
-		select u.user_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,T2.dept_names from sys_user u
+		select
+		u.user_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,
+		T2.dept_names,
+		GROUP_CONCAT(DISTINCT p.post_name SEPARATOR ', ') AS post_names
+		from sys_user u
 		left join
-		(	SELECT T1.user_id,GROUP_CONCAT(T2.dept_name SEPARATOR ', ') AS dept_names
-			FROM
-				sys_user_dept T1
-			LEFT JOIN sys_dept T2 ON T1.dept_id = T2.dept_id
+		(   SELECT T1.user_id,GROUP_CONCAT(T2.dept_name SEPARATOR ', ') AS dept_names
+		FROM
+		sys_user_dept T1
+		LEFT JOIN sys_dept T2 ON T1.dept_id = T2.dept_id
 		<where>
 			<if test="tenantId != null and tenantId != 0">
 				T1.dept_id = #{tenantId}
 			</if>
 		</where>
-			GROUP BY T1.user_id
+		GROUP BY T1.user_id
 		) T2 on T2.user_id = u.user_id
+		LEFT JOIN sys_user_post up ON u.user_id = up.user_id
+		LEFT JOIN sys_post p ON up.post_id = p.post_id
 		where u.del_flag = '0'
 		<if test="userId != null and userId != 0">
 			AND u.user_id = #{userId}
@@ -91,11 +110,22 @@
 		<if test="params.deptId != null">
 			AND u.user_id IN
 			(
-			SELECT user_id FROM sys_user_dept WHERE dept_id = #{deptId}
+			SELECT user_id FROM sys_user_dept WHERE dept_id = #{params.deptId}
+			)
+		</if>
+		<!-- 鏂板锛氭牴鎹矖浣嶇紪鐮佺瓫閫夌敤鎴� -->
+		<if test="postCode != null and postCode != ''">
+			AND u.user_id IN
+			(
+			SELECT DISTINCT up.user_id
+			FROM sys_user_post up
+			LEFT JOIN sys_post p ON up.post_id = p.post_id
+			WHERE p.post_code = #{postCode}
 			)
 		</if>
 		<!-- 鏁版嵁鑼冨洿杩囨护 -->
 		${params.dataScope}
+		GROUP BY u.user_id
 	</select>
 	
 	<select id="selectAllocatedList" parameterType="com.ruoyi.project.system.domain.SysUser" resultMap="SysUserResult">

--
Gitblit v1.9.3