maven
7 小时以前 7b4211d813e06b810c99bed7552d732dd31b4041
yys  商机管理优化
已添加7个文件
已修改12个文件
671 ■■■■ 文件已修改
pom.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/controller/SysUserClientController.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/domain/GetuiConfig.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/domain/SysMenu.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/domain/SysNotice.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/domain/SysUser.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/domain/SysUserClient.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/mapper/SysMenuMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/mapper/SysUserClientMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/SysUserClientService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/impl/SysUserClientServiceImpl.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/controller/BusinessOpportunityController.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/BusinessDescription.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/BusinessOpportunity.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-prod.yml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysMenuMapper.xml 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/system/SysUserMapper.xml 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>
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("设备绑定失败");
    }
}
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;
}
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;
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正常 1关闭) */
    private String status;
    public Long getNoticeId()
    {
        return noticeId;
    }
    /** å‘送人id */
    private Long senderId;
    public void setNoticeId(Long noticeId)
    {
        this.noticeId = noticeId;
    }
    /** æ”¶ä»¶äººid */
    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();
    }
}
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;
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;
}
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);
}
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> {
}
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);
}
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);
    }
}
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;
    }
}
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();
    }
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;
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;
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
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
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>
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">