瀏覽代碼

Merge remote-tracking branch 'origin/lih1010' into lih

# Conflicts:
#	yt-common/src/main/java/com/ytpm/app/model/YtDyzUser.java
#	yt-question/yt-question-service/src/main/java/com/ytpm/question/controller/UserController.java
hidewnd 4 周之前
父節點
當前提交
ac0bf46a53
共有 37 個文件被更改,包括 1147 次插入184 次删除
  1. 81 0
      yt-agent/agent-service/src/main/java/com/ytpm/controller/PromoterUserController.java
  2. 15 2
      yt-agent/agent-service/src/main/java/com/ytpm/controller/UserController.java
  3. 27 1
      yt-agent/agent-service/src/main/java/com/ytpm/dao/AgentUserMapper.java
  4. 35 0
      yt-agent/agent-service/src/main/java/com/ytpm/dao/PromoterUserMapper.java
  5. 45 0
      yt-agent/agent-service/src/main/java/com/ytpm/service/PromoterUserService.java
  6. 25 9
      yt-agent/agent-service/src/main/java/com/ytpm/service/impl/AgentAppServiceImpl.java
  7. 15 0
      yt-agent/agent-service/src/main/java/com/ytpm/service/impl/AgentDitchServiceImpl.java
  8. 179 0
      yt-agent/agent-service/src/main/java/com/ytpm/service/impl/PromoterUserServiceImpl.java
  9. 20 10
      yt-agent/agent-service/src/main/resources/mapper/AgentAppMapper.xml
  10. 6 1
      yt-agent/agent-service/src/main/resources/mapper/AgentDitchMapper.xml
  11. 111 1
      yt-agent/agent-service/src/main/resources/mapper/AgentUserMapper.xml
  12. 5 0
      yt-agent/agent-service/src/main/resources/mapper/AppMapper.xml
  13. 78 0
      yt-agent/agent-service/src/main/resources/mapper/PromoterUserMapper.xml
  14. 39 0
      yt-common/src/main/java/com/ytpm/agent/enums/UserTypeEnum.java
  15. 5 0
      yt-common/src/main/java/com/ytpm/agent/model/YtApp.java
  16. 48 0
      yt-common/src/main/java/com/ytpm/agent/model/YtPlatformUserPromoter.java
  17. 4 0
      yt-common/src/main/java/com/ytpm/agent/param/AppListParam.java
  18. 3 0
      yt-common/src/main/java/com/ytpm/agent/param/AppParam.java
  19. 3 0
      yt-common/src/main/java/com/ytpm/agent/param/DitchListParam.java
  20. 32 0
      yt-common/src/main/java/com/ytpm/agent/param/PromoterAssignParam.java
  21. 36 0
      yt-common/src/main/java/com/ytpm/agent/param/PromoterUserParam.java
  22. 9 0
      yt-common/src/main/java/com/ytpm/agent/view/AgentAppView.java
  23. 6 0
      yt-common/src/main/java/com/ytpm/agent/view/AgentUserInfo.java
  24. 3 0
      yt-common/src/main/java/com/ytpm/app/model/YtAppDefaultConfig.java
  25. 17 7
      yt-common/src/main/java/com/ytpm/app/model/YtDyzUser.java
  26. 3 0
      yt-common/src/main/java/com/ytpm/app/view/WxDefaultConfig.java
  27. 1 1
      yt-common/src/main/java/com/ytpm/general/ResultTable.java
  28. 23 0
      yt-common/src/main/java/com/ytpm/handle/BigDecimalSerialize.java
  29. 42 0
      yt-common/src/main/java/com/ytpm/middle/param/AgentUserListParam.java
  30. 1 0
      yt-common/src/main/java/com/ytpm/oauth/model/YtPlatformUser.java
  31. 39 0
      yt-common/src/main/java/com/ytpm/util/NumberUtils.java
  32. 2 7
      yt-middle/middle-platform/src/main/java/com/ytpm/middle/service/impl/UserServiceImpl.java
  33. 44 13
      yt-question/yt-question-service/src/main/java/com/ytpm/question/controller/UserController.java
  34. 7 0
      yt-question/yt-question-service/src/main/java/com/ytpm/question/dao/AdRecordMapper.java
  35. 7 4
      yt-question/yt-question-service/src/main/java/com/ytpm/question/dao/AppUserMapper.java
  36. 8 0
      yt-question/yt-question-service/src/main/resources/mapper/AdRecordMapper.xml
  37. 123 128
      yt-question/yt-question-service/src/main/resources/mapper/AppUserMapper.xml

+ 81 - 0
yt-agent/agent-service/src/main/java/com/ytpm/controller/PromoterUserController.java

@@ -0,0 +1,81 @@
+package com.ytpm.controller;
+
+
+import com.ytpm.agent.param.PromoterAssignParam;
+import com.ytpm.agent.param.PromoterUserParam;
+import com.ytpm.agent.view.AgentUserInfo;
+import com.ytpm.general.Result;
+import com.ytpm.general.ResultTable;
+import com.ytpm.middle.param.MiddleUserParam;
+import com.ytpm.oauth.model.YtPlatformUser;
+import com.ytpm.service.PromoterUserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.GetMapping;
+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.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.annotation.Resource;
+
+/**
+ * @author lih
+ * @date 2025-10-10 11:45
+ */
+@Api(tags = "渠道推广管理模块")
+@RestController
+@RequestMapping("/promoterUser")
+public class PromoterUserController {
+
+    @Resource
+    private PromoterUserService promoterUserService;
+
+    @ApiOperation("查询渠道所属推广人用户列表")
+    @PostMapping("/queryList")
+    public ResultTable<YtPlatformUser> queryList(@RequestBody PromoterUserParam userParam,
+                                                 @ApiIgnore @AuthenticationPrincipal AgentUserInfo userInfo) {
+        userParam.setParentUserId(userInfo.getUserId());
+        return promoterUserService.promoterUserList(userParam);
+    }
+
+    @ApiOperation("新增渠道所属用户")
+    @PostMapping("/addOne")
+    public Result<String> addOne(@RequestBody MiddleUserParam param, @ApiIgnore @AuthenticationPrincipal AgentUserInfo userInfo) {
+        param.setOperatorId(userInfo.getUserId());
+        return Result.resultObjOk(promoterUserService.addOne(param, userInfo));
+    }
+
+    @ApiOperation("修改渠道所属用户")
+    @PostMapping("/updateOne")
+    public Result<String> updateOne(@RequestBody MiddleUserParam param, @ApiIgnore @AuthenticationPrincipal AgentUserInfo userInfo) {
+        param.setOperatorId(userInfo.getUserId());
+        return Result.resultObjOk(promoterUserService.updateOne(param, userInfo));
+    }
+
+    @ApiOperation("删除渠道所属用户")
+    @ApiImplicitParam(name = "userId", value = "用户ID", required = true)
+    @GetMapping("/deleteOne")
+    public Result<String> deleteOne(@RequestParam(name = "userId") String userId) {
+        return Result.resultObjOk(promoterUserService.deleteOne(userId));
+    }
+
+    @ApiOperation("分配推广人")
+    @PostMapping("/assignment")
+    public Result<String> assignmentApp(@RequestBody PromoterAssignParam assignParam,
+                                        @ApiIgnore @AuthenticationPrincipal AgentUserInfo userInfo) {
+        return Result.resultObjOk(promoterUserService.assignmentApp(assignParam, userInfo));
+    }
+
+    @ApiOperation("取消分配推广人")
+    @PostMapping("/assignment/delete")
+    public Result<String> unAssignmentApp(@RequestBody PromoterAssignParam assignParam,
+                                          @ApiIgnore @AuthenticationPrincipal AgentUserInfo userInfo) {
+        return Result.resultObjOk(promoterUserService.unAssignmentApp(assignParam, userInfo));
+    }
+
+}

+ 15 - 2
yt-agent/agent-service/src/main/java/com/ytpm/controller/UserController.java

@@ -1,7 +1,9 @@
 package com.ytpm.controller;
 
 import com.ytpm.agent.view.AgentUserInfo;
+import com.ytpm.dao.AgentUserMapper;
 import com.ytpm.general.Result;
+import com.ytpm.oauth.model.YtPlatformUser;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
@@ -10,14 +12,25 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import springfox.documentation.annotations.ApiIgnore;
 
+import javax.annotation.Resource;
+
 @Api(tags = "用户管理模块")
 @RestController
 @RequestMapping("/ytUser")
-public class UserController{
+public class UserController {
+
+    @Resource
+    private AgentUserMapper agentUserMapper;
 
     @ApiOperation(value = "获取当前登录用户", notes = "无需传参")
     @GetMapping("/curUser")
-    public Result<AgentUserInfo> getCurrentUser(@ApiIgnore @AuthenticationPrincipal AgentUserInfo userInfo){
+    public Result<AgentUserInfo> getCurrentUser(@ApiIgnore @AuthenticationPrincipal AgentUserInfo userInfo) {
+        YtPlatformUser ytPlatformUser = userInfo == null ? null : agentUserMapper.selectPrimary(userInfo.getUserId());
+        if (userInfo != null && ytPlatformUser != null) {
+            userInfo.setUserType(ytPlatformUser.getUserType());
+        }
         return Result.resultObjOk(userInfo);
     }
+
+
 }

+ 27 - 1
yt-agent/agent-service/src/main/java/com/ytpm/dao/AgentUserMapper.java

@@ -1,14 +1,40 @@
 package com.ytpm.dao;
 
+import com.ytpm.agent.param.PromoterUserParam;
 import com.ytpm.agent.view.AgentUserInfo;
+import com.ytpm.oauth.model.YtPlatformUser;
 import org.apache.ibatis.annotations.Param;
 import org.mapstruct.Mapper;
 
+import java.util.List;
+
 @Mapper
 public interface AgentUserMapper {
     /**
      * 获取当前登录用户信息
+     *
      * @param loginName 用户名
      */
-    AgentUserInfo getCurrentUserInfo(@Param("loginName")String loginName);
+    AgentUserInfo getCurrentUserInfo(@Param("loginName") String loginName);
+
+    /**
+     * 分页查询渠道管理用户列表
+     */
+    List<YtPlatformUser> selectListByParent(@Param("param") PromoterUserParam userParam);
+
+    /**
+     * 主键查询
+     */
+    YtPlatformUser selectPrimary(@Param("userId") String userId);
+
+    /**
+     * 新增推广用户
+     */
+    void insertOne(@Param("user") YtPlatformUser user);
+
+    /**
+     * 修改用户
+     */
+    void updateById(YtPlatformUser user);
+
 }

+ 35 - 0
yt-agent/agent-service/src/main/java/com/ytpm/dao/PromoterUserMapper.java

@@ -0,0 +1,35 @@
+package com.ytpm.dao;
+
+
+import com.ytpm.agent.model.YtPlatformUserPromoter;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author lih
+ * @date 2025-10-10 12:01
+ */
+public interface PromoterUserMapper {
+
+    /**
+     * 新增推广应用关系
+     */
+    void insertPromoter(@Param("promoter") YtPlatformUserPromoter promoter);
+
+    /**
+     * 更新推广应用关系
+     */
+    void updatePromoter(@Param("promoter") YtPlatformUserPromoter promoter);
+
+    /**
+     * 查询应用推广配置信息
+     *
+     */
+    YtPlatformUserPromoter selectPromoterByAppId(@Param("appId") String appId);
+
+    /**
+     * 根据用户ID查询推广信息
+     */
+    List<YtPlatformUserPromoter> selectPromoterByUserId(@Param("userId") String userId);
+}

+ 45 - 0
yt-agent/agent-service/src/main/java/com/ytpm/service/PromoterUserService.java

@@ -0,0 +1,45 @@
+package com.ytpm.service;
+
+
+import com.ytpm.agent.param.PromoterAssignParam;
+import com.ytpm.agent.param.PromoterUserParam;
+import com.ytpm.agent.view.AgentUserInfo;
+import com.ytpm.general.ResultTable;
+import com.ytpm.middle.param.MiddleUserParam;
+import com.ytpm.oauth.model.YtPlatformUser;
+
+/**
+ * 渠道推广人服务
+ *
+ * @author lih
+ * @date 2025-10-10 11:33
+ */
+public interface PromoterUserService {
+
+    ResultTable<YtPlatformUser> promoterUserList(PromoterUserParam userParam);
+
+    /**
+     * 新增渠道推广人
+     */
+    String addOne(MiddleUserParam param, AgentUserInfo userInfo);
+
+    /**
+     * 修改渠道推广人
+     */
+    String updateOne(MiddleUserParam param, AgentUserInfo userInfo);
+
+    /**
+     * 删除渠道推广人
+     */
+    String deleteOne(String userId);
+
+    /**
+     * 为渠道子包应用分配推广人
+     */
+    String assignmentApp(PromoterAssignParam assignParam, AgentUserInfo userInfo);
+
+    /**
+     * 取消渠道子包应用推广人
+     */
+    String unAssignmentApp(PromoterAssignParam assignParam, AgentUserInfo userInfo);
+}

+ 25 - 9
yt-agent/agent-service/src/main/java/com/ytpm/service/impl/AgentAppServiceImpl.java

@@ -8,27 +8,28 @@ import cn.hutool.core.util.StrUtil;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
 import com.ytpm.advertise.enums.AppCategoryEnum;
-import com.ytpm.advertise.param.AddAppParam;
-import com.ytpm.advertise.param.ComprehensiveReportParam;
 import com.ytpm.advertise.param.RelativeChannelParam;
-import com.ytpm.advertise.view.AddAppResponse;
-import com.ytpm.advertise.view.ComprehensiveAppReport;
+import com.ytpm.agent.enums.UserTypeEnum;
 import com.ytpm.agent.model.YtApp;
 import com.ytpm.agent.model.YtAppChannelRelative;
 import com.ytpm.agent.model.YtPlatformUserApp;
+import com.ytpm.agent.model.YtPlatformUserPromoter;
 import com.ytpm.agent.param.AppListParam;
 import com.ytpm.agent.param.AppParam;
 import com.ytpm.agent.view.AgentAppView;
 import com.ytpm.agent.view.AgentEnableAppView;
 import com.ytpm.app.model.YtAppDefaultConfig;
 import com.ytpm.dao.AgentAppMapper;
+import com.ytpm.dao.AgentUserMapper;
 import com.ytpm.dao.AppChannelRelativeMapper;
 import com.ytpm.dao.AppMapper;
+import com.ytpm.dao.PromoterUserMapper;
 import com.ytpm.general.RepMessage;
 import com.ytpm.general.Result;
 import com.ytpm.general.ResultTable;
 import com.ytpm.handle.CustomerException;
 import com.ytpm.middle.view.AppListVO;
+import com.ytpm.oauth.model.YtPlatformUser;
 import com.ytpm.service.AgentAppService;
 import com.ytpm.utils.FeignClientInvoker;
 import lombok.extern.slf4j.Slf4j;
@@ -56,6 +57,10 @@ public class AgentAppServiceImpl implements AgentAppService {
     private AppMapper appMapper;
     @Resource
     private AppChannelRelativeMapper appChannelRelativeMapper;
+    @Resource
+    private AgentUserMapper agentUserMapper;
+    @Resource
+    private PromoterUserMapper promoterUserMapper;
 
     /**
      * 查询渠道启用的应用列表
@@ -72,18 +77,22 @@ public class AgentAppServiceImpl implements AgentAppService {
     @Override
     public ResultTable<AgentAppView> searchAppList(AppListParam appListParam) {
         PageHelper.startPage(appListParam.getPage(), appListParam.getLimit());
-        List<AgentAppView> views = agentAppMapper.searchAppList(appListParam);
+        YtPlatformUser platformUser = agentUserMapper.selectPrimary(appListParam.getUserId());
+        if (platformUser != null && UserTypeEnum.APP_PROMOTER.getCode().equals(platformUser.getUserType())) {
+            List<YtPlatformUserPromoter> list = promoterUserMapper.selectPromoterByUserId(platformUser.getUserId());
+            appListParam.setAppIds(list.stream().map(YtPlatformUserPromoter::getAppId).filter(StrUtil::isNotEmpty).collect(Collectors.toList()));
+        }
         //设置报表数据
-        if(CollUtil.isEmpty(views)){
-            return ResultTable.resultTableOk(new PageInfo<>(new ArrayList<>()));
+        List<AgentAppView> views = agentAppMapper.searchAppList(appListParam);
+        if (CollUtil.isEmpty(views)) {
+            views = new ArrayList<>();
         }
         return ResultTable.resultTableOk(new PageInfo<>(views));
     }
 
     @Override
     public List<AgentAppView> searchAppIdList(AppListParam appListParam) {
-        List<AgentAppView> agentAppViews = agentAppMapper.searchAppIdList(appListParam);
-        return agentAppViews;
+        return agentAppMapper.searchAppIdList(appListParam);
     }
 
     /**
@@ -111,6 +120,12 @@ public class AgentAppServiceImpl implements AgentAppService {
         BeanUtil.copyProperties(param, app);
         if(CharSequenceUtil.isNotBlank(param.getAppId())){
             appMapper.updateOne(app);
+            // 同步更新子服务相关配置
+            YtPlatformUserApp superior = agentAppMapper.selectByPrimaryKey(param.getSuperiorId());
+            YtAppDefaultConfig config = new YtAppDefaultConfig();
+            config.setAppId(app.getAppId());
+            config.setRevenueDisplayRate(app.getRevenueDisplayRate());
+            feignInvoker.invoke(superior.getServiceName(), "updateAppConfig", config);
         }else{
             //同一个应用同一个渠道只能出一个包
             YtApp exist = appMapper.getByDitchIdAndSuperiorId(param.getDitchId(),param.getSuperiorId());
@@ -160,6 +175,7 @@ public class AgentAppServiceImpl implements AgentAppService {
         //远程调用指定应用保存 应用的出包配置
         YtPlatformUserApp superior = agentAppMapper.selectByPrimaryKey(param.getSuperiorId());
         YtAppDefaultConfig config = new YtAppDefaultConfig(null, param.getAppName(), vo.getWxAppId(), vo.getWxSecret(), app.getAppId(), app.getAppId(), appType,ditchId);
+        config.setRevenueDisplayRate(app.getRevenueDisplayRate());
         feignInvoker.invoke(superior.getServiceName(), "saveAppConfig",config);
     }
 

+ 15 - 0
yt-agent/agent-service/src/main/java/com/ytpm/service/impl/AgentDitchServiceImpl.java

@@ -2,15 +2,20 @@ package com.ytpm.service.impl;
 
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import com.ytpm.agent.enums.UserTypeEnum;
 import com.ytpm.agent.model.YtApp;
 import com.ytpm.agent.model.YtDitch;
+import com.ytpm.agent.model.YtPlatformUserPromoter;
 import com.ytpm.agent.param.DitchListParam;
 import com.ytpm.agent.view.AgentDitchView;
 import com.ytpm.dao.AgentDitchMapper;
+import com.ytpm.dao.AgentUserMapper;
 import com.ytpm.dao.AppMapper;
+import com.ytpm.dao.PromoterUserMapper;
 import com.ytpm.general.RepMessage;
 import com.ytpm.general.Result;
 import com.ytpm.general.ResultTable;
+import com.ytpm.oauth.model.YtPlatformUser;
 import com.ytpm.service.AgentDitchService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -19,6 +24,7 @@ import javax.annotation.Resource;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
 
 @Service
 public class AgentDitchServiceImpl implements AgentDitchService {
@@ -28,11 +34,20 @@ public class AgentDitchServiceImpl implements AgentDitchService {
 
     @Resource
     private AppMapper appMapper;
+    @Resource
+    private AgentUserMapper agentUserMapper;
+    @Resource
+    private PromoterUserMapper promoterUserMapper;
 
 
     @Override
     public ResultTable<AgentDitchView> ditchList(DitchListParam param) {
         PageHelper.startPage(param.getPage(), param.getLimit());
+        YtPlatformUser platformUser = agentUserMapper.selectPrimary(param.getUserId());
+        if (platformUser != null && UserTypeEnum.APP_PROMOTER.getCode().equals(platformUser.getUserType())) {
+            List<YtPlatformUserPromoter> list = promoterUserMapper.selectPromoterByUserId(platformUser.getUserId());
+            param.setDitchIds(list.stream().map(YtPlatformUserPromoter::getDitchId).filter(Objects::nonNull).collect(Collectors.toList()));
+        }
         List<AgentDitchView> agentDitchViews = agentDitchMapper.ditchList(param);
         return ResultTable.resultTableOk(new PageInfo<>(agentDitchViews));
     }

+ 179 - 0
yt-agent/agent-service/src/main/java/com/ytpm/service/impl/PromoterUserServiceImpl.java

@@ -0,0 +1,179 @@
+package com.ytpm.service.impl;
+
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.StrUtil;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import com.ytpm.agent.enums.UserTypeEnum;
+import com.ytpm.agent.model.YtApp;
+import com.ytpm.agent.model.YtPlatformUserPromoter;
+import com.ytpm.agent.param.PromoterAssignParam;
+import com.ytpm.agent.param.PromoterUserParam;
+import com.ytpm.agent.view.AgentUserInfo;
+import com.ytpm.dao.AgentUserMapper;
+import com.ytpm.dao.AppMapper;
+import com.ytpm.dao.PromoterUserMapper;
+import com.ytpm.general.RepMessage;
+import com.ytpm.general.ResultTable;
+import com.ytpm.handle.CustomerException;
+import com.ytpm.middle.param.MiddleUserParam;
+import com.ytpm.oauth.model.YtPlatformUser;
+import com.ytpm.service.PromoterUserService;
+import com.ytpm.util.IDUtil;
+import com.ytpm.util.NumberUtils;
+import com.ytpm.util.RandomPasswordGenerator;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author lih
+ * @date 2025-10-10 11:45
+ */
+@Slf4j
+@Service
+public class PromoterUserServiceImpl implements PromoterUserService {
+
+    @Resource
+    private AgentUserMapper agentUserMapper;
+
+    @Resource
+    private PromoterUserMapper promoterUserMapper;
+
+    @Resource
+    private AppMapper appMapper;
+
+    @Override
+    public ResultTable<YtPlatformUser> promoterUserList(PromoterUserParam userParam) {
+        PageHelper.startPage(userParam.getPage(), userParam.getLimit());
+        List<YtPlatformUser> userList = agentUserMapper.selectListByParent(userParam);
+        return ResultTable.resultTableOk(new PageInfo<>(userList));
+    }
+
+    @Override
+    public String addOne(MiddleUserParam param, AgentUserInfo userInfo) {
+        //根据登录名生成登录账号
+        YtPlatformUser user = new YtPlatformUser();
+        user.setUserId(IDUtil.generateFlowID("yt_agent_"));
+        user.setAccountStatus(1);
+        user.setUserType(UserTypeEnum.APP_PROMOTER.getCode());
+        user.setNickName(param.getNickName());
+        user.setLoginName(param.getLoginName());
+        if (StrUtil.isEmpty(param.getPassword())) {
+            String generatedPassword = RandomPasswordGenerator.generatePassword(8);
+            log.info("创建推广用户成功,您本次的登录密码为:{}", generatedPassword);
+            param.setPassword(generatedPassword);
+        }
+        user.setEncryptPwd(new BCryptPasswordEncoder().encode(param.getPassword()));
+        user.setPhone(param.getPhone());
+        user.setLastLoginTime(new Date());
+        user.setRegistryTime(new Date());
+        user.setParentUserId(userInfo.getUserId());
+        agentUserMapper.insertOne(user);
+        return RepMessage.ADD_SUCCESS;
+    }
+
+    @Override
+    public String updateOne(MiddleUserParam param, AgentUserInfo userInfo) {
+        YtPlatformUser platformUser = agentUserMapper.selectPrimary(param.getUserId());
+        if (Objects.isNull(platformUser)) {
+            return RepMessage.OBJECT_NOT_EXIST;
+        }
+        //修改用户信息
+        YtPlatformUser user = new YtPlatformUser();
+        BeanUtils.copyProperties(param, user);
+        if (StrUtil.isNotBlank(param.getPassword())) {
+            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
+            user.setEncryptPwd(encoder.encode(param.getPassword()));
+        }
+
+        agentUserMapper.updateById(user);
+        return RepMessage.MODIFY_SUCCESS;
+    }
+
+    @Override
+    public String deleteOne(String userId) {
+        YtPlatformUser platformUser = agentUserMapper.selectPrimary(userId);
+        if (Objects.isNull(platformUser)) {
+            return RepMessage.OBJECT_NOT_EXIST;
+        }
+        platformUser = new YtPlatformUser();
+        platformUser.setUserId(userId);
+        platformUser.setAccountStatus(2);
+        agentUserMapper.updateById(platformUser);
+        return RepMessage.DELETE_SUCCESS;
+    }
+
+    @Override
+    public String assignmentApp(PromoterAssignParam assignParam, AgentUserInfo userInfo) {
+        YtApp ytApp = appMapper.selectPrimary(assignParam.getAppId());
+        if (ytApp == null) {
+            throw new CustomerException("应用不存在!");
+        }
+        // 校验 一个子包应用只允许一个推广人
+        YtPlatformUserPromoter promoter = promoterUserMapper.selectPromoterByAppId(ytApp.getAppId());
+        if (promoter != null) {
+            throw new CustomerException("该应用已绑定推广人!");
+        }
+        // 校验推广分成比例合法性,数据处理
+        if (StrUtil.isNotEmpty(assignParam.getShareRate())) {
+            BigDecimal shareRate = NumberUtils.rateToBigDecimal(assignParam.getShareRate());
+            if (BigDecimal.ZERO.compareTo(shareRate) > 0) {
+                throw new CustomerException("分成比例不得小于0");
+            }
+            if (BigDecimal.ONE.compareTo(shareRate) < 0) {
+                throw new CustomerException("分成比例不得大于100%");
+            }
+            assignParam.setShareRate(StrUtil.trim(assignParam.getShareRate().replace("%", "")));
+        }
+        // 开始时间为空则默认当前时间
+        if (assignParam.getStartTime() == null) {
+            assignParam.setStartTime(new Date());
+        }
+        promoter = new YtPlatformUserPromoter();
+        promoter.setRelationId(IdUtil.fastSimpleUUID());
+        promoter.setPlatformUserId(userInfo.getUserId());
+        promoter.setPromoterUserId(assignParam.getUserId());
+        promoter.setAppId(ytApp.getAppId());
+        promoter.setDitchId(ytApp.getDitchId());
+        promoter.setShareRate(assignParam.getShareRate());
+        promoter.setStartTime(assignParam.getStartTime());
+        promoter.setEndTime(assignParam.getEndTime());
+        promoter.setOperatorId(userInfo.getUserId());
+        promoter.setOperatorTime(new Date());
+        promoterUserMapper.insertPromoter(promoter);
+        log.info("[agent promoter]渠道商为应用{}指派推广人:{}", ytApp.getAppId(), assignParam.getUserId());
+        return RepMessage.SAVE_SUCCESS;
+    }
+
+    @Override
+    public String unAssignmentApp(PromoterAssignParam assignParam, AgentUserInfo userInfo) {
+        if (StrUtil.isEmpty(assignParam.getAppId())) {
+            throw new CustomerException("appId不能为空");
+        }
+        if (StrUtil.isEmpty(assignParam.getUserId())) {
+            throw new CustomerException("userId不能为空");
+        }
+        YtApp ytApp = appMapper.selectPrimary(assignParam.getAppId());
+        if (ytApp == null) {
+            throw new CustomerException("应用不存在!");
+        }
+        List<YtPlatformUserPromoter> list = promoterUserMapper.selectPromoterByUserId(assignParam.getUserId());
+        YtPlatformUserPromoter promoter = list.stream()
+                .filter(item -> StrUtil.equals(ytApp.getAppId(), item.getAppId()))
+                .findFirst().orElse(null);
+        if (promoter != null) {
+            promoter.setEndTime(new Date());
+            promoterUserMapper.updatePromoter(promoter);
+        }
+        return RepMessage.PROCESS_SUCCESS;
+    }
+}

+ 20 - 10
yt-agent/agent-service/src/main/resources/mapper/AgentAppMapper.xml

@@ -63,22 +63,32 @@
             GROUP_CONCAT( acr.channel_name ) channel_name,
             GROUP_CONCAT( acr.network_app_id ) network_app_id,
             GROUP_CONCAT( acr.network_app_name ) network_app_name,
-            u.nick_name
-        FROM
-            yt_app ya
-                JOIN yt_platform_user_app pua on ya.superior_id = pua.app_id
-                LEFT JOIN yt_app_channel_relative acr ON ya.app_id = acr.app_id
-                LEFT JOIN yt_platform_user u ON ya.user_id = u.user_id
-        WHERE
-            ya.enabled = 1 and ya.user_id = #{userId}
+            u.nick_name,
+            ya.revenue_display_rate,
+            upu.user_id as promoter_user_id,
+            upu.login_name as promoter_user_login_name,
+            upu.nick_name as promoter_user_nick_name,
+            up.share_rate as promoter_user_share_rate
+        FROM yt_app ya
+        JOIN yt_platform_user_app pua on ya.superior_id = pua.app_id
+        LEFT JOIN yt_app_channel_relative acr ON ya.app_id = acr.app_id
+        LEFT JOIN yt_platform_user u ON ya.user_id = u.user_id
+        LEFT JOIN yt_platform_user_promoter up on up.app_id = ya.app_id and (up.end_time is null or up.end_time <![CDATA[ <= ]]> current_date())
+        left join yt_platform_user upu on up.promoter_user_id = upu.user_id
+        WHERE ya.enabled = 1
+        <if test="appIds == null">
+            and ya.user_id = #{userId}
+        </if>
+        <if test="appIds != null and appIds.size() > 0">
+            and ya.app_id in <foreach collection="appIds" open="(" separator="," close=")" item="appId">#{appId}</foreach>
+        </if>
         <if test="appName !=null and appName != ''">
             and ya.app_name like concat('%', #{appName} ,'%')
         </if>
         <if test="appType !=null">
             and ya.app_type = #{appType}
         </if>
-        GROUP BY
-            ya.app_id
+        GROUP BY ya.app_id
     </select>
 
     <select id="searchAppIdList" resultType="com.ytpm.agent.view.AgentAppView">

+ 6 - 1
yt-agent/agent-service/src/main/resources/mapper/AgentDitchMapper.xml

@@ -45,7 +45,12 @@
             ditch_id, ditch_name, app_type, app_id, create_time
         from yt_ditch
         <where>
-            user_id = #{userId}
+            <if test="ditchIds == null">
+                user_id = #{userId}
+            </if>
+            <if test="ditchIds != null and ditchIds.size() > 0">
+                ditch_id in <foreach collection="ditchIds" item="ditchId" open="(" separator="," close=")">#{ditchId}</foreach>
+            </if>
             <if test="ditchName != null and ditchName != ''">
                 AND ditch_name LIKE CONCAT('%', #{ditchName}, '%')
             </if>

+ 111 - 1
yt-agent/agent-service/src/main/resources/mapper/AgentUserMapper.xml

@@ -4,9 +4,119 @@
 
     <select id="getCurrentUserInfo" resultType="com.ytpm.agent.view.AgentUserInfo">
         select
-            user_id, nick_name, head_image, login_name, encrypt_pwd, salt, phone, last_login_time, account_status,  user_type, registry_time
+            user_id, nick_name, head_image, login_name, encrypt_pwd, salt, phone,
+            last_login_time, account_status,  user_type, registry_time, parent_user_id
         from yt_platform_user
         where account_status = 1
         and login_name = #{loginName}
     </select>
+
+    <select id="selectPrimary" resultType="com.ytpm.oauth.model.YtPlatformUser">
+        select
+            user_id, nick_name, head_image, login_name, encrypt_pwd, salt, phone,
+            last_login_time,  account_status,  user_type,  registry_time, parent_user_id
+        from yt_platform_user
+        where user_id = #{userId}
+    </select>
+
+    <select id="selectListByParent" resultType="com.ytpm.oauth.model.YtPlatformUser">
+        select
+            user_id,
+            nick_name,
+            head_image,
+            login_name,
+            encrypt_pwd,
+            salt,
+            phone,
+            last_login_time,
+            account_status,
+            user_type,
+            registry_time,
+            dept_id,
+            super_admin,
+            parent_user_id
+        from yt_platform_user ypu
+        <where>
+            ypu.user_type = 11 and ypu.account_status = 1 and ypu.parent_user_id = #{param.parentUserId}
+            <if test="param.loginName != null and param.loginName != ''">
+                and ypu.login_name like concat('%', #{param.loginName} ,'%')
+            </if>
+            <if test="param.nickName != null and param.nickName != ''">
+                and ypu.nick_name like concat('%', #{param.nickName} ,'%')
+            </if>
+            <if test="param.phone != null and param.phone != ''">
+                and ypu.phone like concat('%', #{param.phone} ,'%')
+            </if>
+        </where>
+
+        order by ypu.registry_time
+    </select>
+
+    <insert id="insertOne">
+        insert into yt_platform_user(user_id,
+                                     nick_name,
+                                     head_image,
+                                     login_name,
+                                     encrypt_pwd,
+                                     phone,
+                                     last_login_time,
+                                     account_status,
+                                     user_type,
+                                     registry_time,
+                                     parent_user_id)
+        values (#{user.userId},
+                #{user.nickName},
+                #{user.headImage},
+                #{user.loginName},
+                #{user.encryptPwd},
+                #{user.phone},
+                #{user.lastLoginTime},
+                #{user.accountStatus},
+                #{user.userType},
+                #{user.registryTime},
+                #{user.parentUserId});
+    </insert>
+
+    <update id="updateById">
+        update yt_platform_user
+        <set>
+            <if test="nickName != null">
+                nick_name = #{nickName},
+            </if>
+            <if test="headImage != null">
+                head_image = #{headImage},
+            </if>
+            <if test="loginName != null">
+                login_name = #{loginName},
+            </if>
+            <if test="encryptPwd != null">
+                encrypt_pwd = #{encryptPwd},
+            </if>
+            <if test="salt != null">
+                salt = #{salt},
+            </if>
+            <if test="phone != null">
+                phone = #{phone},
+            </if>
+            <if test="lastLoginTime != null">
+                last_login_time = #{lastLoginTime},
+            </if>
+            <if test="accountStatus != null">
+                account_status = #{accountStatus},
+            </if>
+            <if test="userType != null">
+                user_type = #{userType},
+            </if>
+            <if test="registryTime != null">
+                registry_time = #{registryTime},
+            </if>
+            <if test="parentUserId != null">
+                parent_user_id = #{parentUserId},
+            </if>
+            <if test="deptId != null">
+                dept_id = #{deptId}
+            </if>
+        </set>
+        where user_id = #{userId}
+    </update>
 </mapper>

+ 5 - 0
yt-agent/agent-service/src/main/resources/mapper/AppMapper.xml

@@ -27,6 +27,7 @@
          ditch_id,
          ditch_name,
          superior_id,
+         revenue_display_rate,
          enabled
         )
         values
@@ -53,6 +54,7 @@
          #{ditchId},
          #{ditchName},
          #{superiorId},
+         #{revenueDisplayRate},
          #{enabled}
         )
     </insert>
@@ -119,6 +121,9 @@
             <if test="ditchName != null">
                 ditch_name = #{ditchName},
             </if>
+            <if test="revenueDisplayRate != null">
+                revenue_display_rate = #{revenueDisplayRate},
+            </if>
             <if test="superiorId != null">
                 superior_id = #{superiorId}
             </if>

+ 78 - 0
yt-agent/agent-service/src/main/resources/mapper/PromoterUserMapper.xml

@@ -0,0 +1,78 @@
+<?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.ytpm.dao.PromoterUserMapper">
+
+    <insert id="insertPromoter">
+        insert into yt_platform_user_promoter
+        (relation_id, platform_user_id, promoter_user_id, ditch_id, app_id, share_rate, start_time, end_time,
+         operator_id, operator_time)
+        values (#{promoter.relationId},
+                #{promoter.platformUserId},
+                #{promoter.promoterUserId},
+                #{promoter.ditchId},
+                #{promoter.appId},
+                #{promoter.shareRate},
+                #{promoter.startTime},
+                #{promoter.endTime},
+                #{promoter.operatorId},
+                #{promoter.operatorTime});
+
+    </insert>
+    <update id="updatePromoter">
+        update yt_platform_user_promoter set
+        <if test="promoter.platformUserId != null and promoter.platformUserId != ''">
+            platform_user_id = #{promoter.platformUserId},
+        </if>
+        <if test="promoter.promoterUserId != null and promoter.promoterUserId != ''">
+            promoter_user_id = #{promoter.promoterUserId},
+        </if>
+        <if test="promoter.ditchId != null">
+            ditch_id = #{promoter.ditchId},
+        </if>
+        <if test="promoter.appId != null">
+            app_id = #{promoter.appId},
+        </if>
+        <if test="promoter.shareRate != null and promoter.shareRate != ''">
+            share_rate = #{promoter.shareRate},
+        </if>
+        <if test="promoter.endTime != null">
+            end_time = #{promoter.endTime},
+        </if>
+        operator_time = #{promoter.operatorTime}
+        where relation_id = #{promoter.relationId}
+    </update>
+
+    <select id="selectPromoterByAppId" resultType="com.ytpm.agent.model.YtPlatformUserPromoter">
+        select relation_id,
+               platform_user_id,
+               promoter_user_id,
+               ditch_id,
+               app_id,
+               share_rate,
+               start_time,
+               end_time,
+               operator_id,
+               operator_time
+        from yt_platform_user_promoter
+        where app_id = #{appId}
+        and (end_time is null or end_time <![CDATA[ <= ]]> current_date())
+        limit 1
+    </select>
+    <select id="selectPromoterByUserId" resultType="com.ytpm.agent.model.YtPlatformUserPromoter">
+        select relation_id,
+               platform_user_id,
+               promoter_user_id,
+               ditch_id,
+               app_id,
+               share_rate,
+               start_time,
+               end_time,
+               operator_id,
+               operator_time
+        from yt_platform_user_promoter
+        where promoter_user_id = #{userId}
+            and (end_time is null or end_time <![CDATA[ <= ]]> current_date())
+        order by start_time
+    </select>
+
+</mapper>

+ 39 - 0
yt-common/src/main/java/com/ytpm/agent/enums/UserTypeEnum.java

@@ -0,0 +1,39 @@
+package com.ytpm.agent.enums;
+
+
+import lombok.Getter;
+
+/**
+ * 用户类型 {@link com.ytpm.oauth.model.YtPlatformUser YtPlatformUser} 属性 userType
+ * <p>
+ * 用户类型 1-一级代理商 2-二级代理商 99-平台用户
+ * </p>
+ * @author lih
+ * @date 2025/10/10
+ */
+@Getter
+public enum UserTypeEnum {
+    AGENT_LEVEL_1(1, "一级代理商"),
+    AGENT_LEVEL_2(2, "二级代理商"),
+    APP_PROMOTER(11, "渠道推广人"),
+    PLATFORM_USER(99, "平台用户"),
+    ;
+    private final Integer code;
+    private final String desc;
+
+    UserTypeEnum(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    /**
+     * 根据编码获取用户状态
+     */
+    public static String getByCode(Integer code){
+        for (UserStatusEnum value : UserStatusEnum.values()) {
+            if(!value.getCode().equals(code))continue;
+            return value.getDesc();
+        }
+        return "";
+    }
+}

+ 5 - 0
yt-common/src/main/java/com/ytpm/agent/model/YtApp.java

@@ -110,5 +110,10 @@ public class YtApp {
      */
     private String superiorId;
 
+    /**
+     * 收益 显示比例
+     */
+    private String revenueDisplayRate;
+
 
 }

+ 48 - 0
yt-common/src/main/java/com/ytpm/agent/model/YtPlatformUserPromoter.java

@@ -0,0 +1,48 @@
+package com.ytpm.agent.model;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author lih
+ * @date 2025-10-10 13:57
+ */
+@Data
+@ApiModel("渠道应用推广关系表")
+public class YtPlatformUserPromoter implements Serializable {
+
+    @ApiModelProperty("关系表ID")
+    private String relationId;
+
+    @ApiModelProperty("渠道商ID")
+    private String platformUserId;
+
+    @ApiModelProperty("推广人ID")
+    private String promoterUserId;
+
+    @ApiModelProperty("渠道ID")
+    private Long ditchId;
+
+    @ApiModelProperty("应用ID")
+    private String appId;
+
+    @ApiModelProperty("分成比例(%)")
+    private String shareRate;
+
+    @ApiModelProperty("开始时间")
+    private Date startTime;
+
+    @ApiModelProperty("结束时间")
+    private Date endTime;
+
+    @ApiModelProperty("操作人")
+    private String operatorId;
+
+    @ApiModelProperty("操作时间")
+    private Date operatorTime;
+}

+ 4 - 0
yt-common/src/main/java/com/ytpm/agent/param/AppListParam.java

@@ -8,12 +8,16 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 
+import java.util.List;
+
 @EqualsAndHashCode(callSuper = true)
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
 @ApiModel("应用列表入参")
 public class AppListParam extends PageMeta {
+    @ApiModelProperty("appID集合")
+    private List<String> appIds;
     @ApiModelProperty("app名称")
     private String appName;
     @ApiModelProperty("用户ID")

+ 3 - 0
yt-common/src/main/java/com/ytpm/agent/param/AppParam.java

@@ -88,4 +88,7 @@ public class AppParam {
 
     @ApiModelProperty("是否允许自动刷新")
     private Integer canAllowAutoRefresh;
+
+    @ApiModelProperty("收益 显示比例")
+    private String revenueDisplayRate;
 }

+ 3 - 0
yt-common/src/main/java/com/ytpm/agent/param/DitchListParam.java

@@ -7,6 +7,8 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 
+import java.util.List;
+
 @Data
 @EqualsAndHashCode(callSuper = false)
 @NoArgsConstructor
@@ -16,4 +18,5 @@ public class DitchListParam extends PageMeta {
     private String ditchName;
     private String userId;
     private String appId;
+    private List<Long> ditchIds;
 }

+ 32 - 0
yt-common/src/main/java/com/ytpm/agent/param/PromoterAssignParam.java

@@ -0,0 +1,32 @@
+package com.ytpm.agent.param;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author lih
+ * @date 2025-10-10 11:39
+ */
+@Data
+@ApiModel("渠道推广指派参数")
+public class PromoterAssignParam implements Serializable {
+
+    private String userId;
+
+    private Long ditchId;
+
+    private String appId;
+
+    private String shareRate;
+
+    @ApiModelProperty("开始时间")
+    private Date startTime;
+
+    @ApiModelProperty("结束时间")
+    private Date endTime;
+}

+ 36 - 0
yt-common/src/main/java/com/ytpm/agent/param/PromoterUserParam.java

@@ -0,0 +1,36 @@
+package com.ytpm.agent.param;
+
+
+import com.ytpm.general.PageMeta;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import springfox.documentation.annotations.ApiIgnore;
+
+/**
+ * @author lih
+ * @date 2025-10-10 14:17
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@NoArgsConstructor
+@AllArgsConstructor
+@ApiModel("渠道管理列表入参")
+public class PromoterUserParam extends PageMeta {
+
+    @ApiModelProperty(hidden = true)
+    private String parentUserId;
+
+    @ApiModelProperty("登陆用户名")
+    private String loginName;
+
+    @ApiModelProperty("用户昵称")
+    private String nickName;
+
+    @ApiModelProperty("手机号码")
+    private String phone;
+
+}

+ 9 - 0
yt-common/src/main/java/com/ytpm/agent/view/AgentAppView.java

@@ -41,6 +41,13 @@ public class AgentAppView {
     private String nickName;
     private boolean showKey;
 
+    @ApiModelProperty("应用推广人")
+    private String promoterUserId;
+    private String promoterUserLoginName;
+    private String promoterUserNickName;
+    @ApiModelProperty("应用推广人分成比例")
+    private String promoterUserShareRate;
+
     /**
      * 是否应用商店上架 1-否 2-是
      */
@@ -176,5 +183,7 @@ public class AgentAppView {
     @ApiModelProperty("是否允许自动刷新")
     private Integer canAllowAutoRefresh;
 
+    @ApiModelProperty("收益 显示比例")
+    private String revenueDisplayRate;
 
 }

+ 6 - 0
yt-common/src/main/java/com/ytpm/agent/view/AgentUserInfo.java

@@ -1,5 +1,7 @@
 package com.ytpm.agent.view;
 
+import com.ytpm.agent.model.YtPlatformUserPromoter;
+import com.ytpm.oauth.model.YtPlatformUser;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
@@ -10,6 +12,7 @@ import org.springframework.security.core.GrantedAuthority;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
+import java.util.List;
 
 @Data
 @NoArgsConstructor
@@ -31,6 +34,9 @@ public class AgentUserInfo {
     @ApiModelProperty("最新登录IP")
     private String lastLoginIp;
 
+    @ApiModelProperty("用户类型")
+    private Integer userType;
+
     public Collection<? extends GrantedAuthority> getAuthorities() {
         return Collections.emptyList();
     }

+ 3 - 0
yt-common/src/main/java/com/ytpm/app/model/YtAppDefaultConfig.java

@@ -80,6 +80,9 @@ public class YtAppDefaultConfig {
     @ApiModelProperty("是否允许自动刷新")
     private Integer canAllowAutoRefresh;
 
+    @ApiModelProperty("收益 显示比例")
+    private String revenueDisplayRate;
+
     public YtAppDefaultConfig(Object o, String appName, String wxAppId, String wxSecret, String appId, String appKey, int appType,String ditchId) {
         this.configId = Objects.isNull(o)?null: Integer.parseInt(o.toString());
         this.configName = appName;

+ 17 - 7
yt-common/src/main/java/com/ytpm/app/model/YtDyzUser.java

@@ -1,5 +1,6 @@
 package com.ytpm.app.model;
 
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.ytpm.app.enums.LoginType;
 import com.ytpm.custom.CustomField;
 import io.swagger.annotations.ApiModel;
@@ -58,12 +59,7 @@ public class YtDyzUser extends YtUser {
     @CustomField(node = 1)
     @ApiModelProperty("总观看视频数")
     private Integer totalVideo;
-    /** 总收益 */
-    @ApiModelProperty("总收益")
-    private BigDecimal totalIncome;
 
-    @ApiModelProperty("前三日总收益")
-    private BigDecimal nearlyIncome;
 
     /** 红包余额 */
     @CustomField(node = 1)
@@ -108,13 +104,28 @@ public class YtDyzUser extends YtUser {
     /** 体力 */
     @ApiModelProperty("体力")
     private Integer power;
+
+    @ApiModelProperty(value = "今日收益")
+    @JsonSerialize(using = BigDecimalSerialize.class)
+    private BigDecimal todayIncome;
+
+    @ApiModelProperty("前三日总收益")
+    @JsonSerialize(using = BigDecimalSerialize.class)
+    private BigDecimal nearlyIncome;
+
+    @ApiModelProperty("总收益")
+    @JsonSerialize(using = BigDecimalSerialize.class)
+    private BigDecimal totalIncome;
+
     /** 今日答题数 */
     @CustomField(node = 1)
     @ApiModelProperty("今日答题数")
     private Integer todayAnswerCount;
+
     /** 历史答题数 */
     @ApiModelProperty("历史答题数")
     private Integer historyAnswerCount;
+
     /** 答题历史记录 */
     @ApiModelProperty("答题历史记录")
     private List<YtDyzAnswerRecord> answerRecordList;
@@ -132,8 +143,7 @@ public class YtDyzUser extends YtUser {
     private Long ditchId;
     @ApiModelProperty(value = "渠道名称")
     private String ditchName;
-    @ApiModelProperty(value = "今日收益")
-    private BigDecimal todayIncome;
+
     @ApiModelProperty(value = "应用ID")
     private String appId;
     @ApiModelProperty(value = "手机号")

+ 3 - 0
yt-common/src/main/java/com/ytpm/app/view/WxDefaultConfig.java

@@ -75,4 +75,7 @@ public class WxDefaultConfig {
 
     @ApiModelProperty("是否允许自动刷新")
     private Integer canAllowAutoRefresh;
+
+    @ApiModelProperty("收益 显示比例")
+    private String revenueDisplayRate;
 }

+ 1 - 1
yt-common/src/main/java/com/ytpm/general/ResultTable.java

@@ -72,7 +72,7 @@ public class ResultTable<T> implements Serializable {
             list = new ArrayList<>();
         }
         PageMeta pageMeta =  new PageMeta(total, perPage, currentPage, lastPage);
-        return new ResultTable(StatusCode.OK, RepMessage.QUERY_SUCCESS, list, pageMeta);
+        return new ResultTable<>(StatusCode.OK, RepMessage.QUERY_SUCCESS, list, pageMeta);
     }
 
     /**

+ 23 - 0
yt-common/src/main/java/com/ytpm/handle/BigDecimalSerialize.java

@@ -0,0 +1,23 @@
+package com.ytpm.handle;
+
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+
+/**
+ * @author lih
+ * @date 2025-10-11 11:26
+ */
+public class BigDecimalSerialize extends JsonSerializer<BigDecimal> {
+
+    @Override
+    public void serialize(BigDecimal bigDecimal, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+        if (bigDecimal != null) {
+            jsonGenerator.writeString(bigDecimal.stripTrailingZeros().toPlainString());
+        }
+    }
+}

+ 42 - 0
yt-common/src/main/java/com/ytpm/middle/param/AgentUserListParam.java

@@ -0,0 +1,42 @@
+package com.ytpm.middle.param;
+
+
+import com.ytpm.general.BaseParam;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @author lih
+ * @date 2025-10-10 09:36
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class AgentUserListParam extends BaseParam {
+    @ApiModelProperty("手机号")
+    private String phone;
+
+    @ApiModelProperty("用户昵称")
+    private String nickName;
+
+    @ApiModelProperty("登录用户名")
+    private String loginName;
+
+    @ApiModelProperty("账户状态")
+    private Integer accountStatus;
+
+    @ApiModelProperty("渠道类型名称")
+    private String ditchName;
+
+    @ApiModelProperty("id")
+    private Long ditchId;
+
+    @ApiModelProperty("渠道类型")
+    private String ditchType;
+
+    @ApiModelProperty("应用类型")
+    private String appType;
+
+    @ApiModelProperty("应用ID")
+    private String appId;
+}

+ 1 - 0
yt-common/src/main/java/com/ytpm/oauth/model/YtPlatformUser.java

@@ -28,6 +28,7 @@ public class YtPlatformUser implements UserDetails {
     private Integer userType;
     private Integer superAdmin;
     private Date registryTime;
+    private String parentUserId;
 
     @Override
     public Collection<? extends GrantedAuthority> getAuthorities() {

+ 39 - 0
yt-common/src/main/java/com/ytpm/util/NumberUtils.java

@@ -0,0 +1,39 @@
+package com.ytpm.util;
+
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * @author lih
+ * @date 2025-10-09 18:11
+ */
+public class NumberUtils extends NumberUtil {
+
+    /**
+     * 百分比字符串转换为BigDecimal
+     *
+     * @param str “51.12%” | "51.00"
+     * @return BigDecimal 0.5112 | 0.51
+     */
+    public static BigDecimal rateToBigDecimal(String str) {
+        return rateToBigDecimal(str, 5, RoundingMode.HALF_UP);
+    }
+
+    public static BigDecimal rateToBigDecimal(String str, int scale, RoundingMode roundingMode) {
+        if (StrUtil.isBlank(str)) {
+            throw new IllegalArgumentException("输入字符串不能为空");
+        }
+        String numStr = StrUtil.trim(str);
+        // 处理带百分号的情况
+        if (str.contains("%")) {
+            // 去除百分号并 trim 空格
+            numStr = StrUtil.trim(str.replace("%", ""));
+        }
+        return toBigDecimal(numStr)
+                .divide(new BigDecimal("100"), scale, roundingMode);
+    }
+}

+ 2 - 7
yt-middle/middle-platform/src/main/java/com/ytpm/middle/service/impl/UserServiceImpl.java

@@ -4,19 +4,16 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
+import com.ytpm.agent.enums.UserTypeEnum;
 import com.ytpm.constant.StrConstant;
 import com.ytpm.general.RepMessage;
 import com.ytpm.general.Result;
 import com.ytpm.general.ResultTable;
 import com.ytpm.middle.dao.MiddleUserMapper;
-import com.ytpm.middle.model.YtMiddleRole;
-import com.ytpm.middle.model.YtMiddleUser;
-import com.ytpm.middle.model.YtMiddleUserRole;
 import com.ytpm.middle.param.MiddleUserListParam;
 import com.ytpm.middle.param.MiddleUserParam;
 import com.ytpm.middle.service.UserService;
 import com.ytpm.middle.util.RedisUtil;
-import com.ytpm.middle.view.MiddleRoleVO;
 import com.ytpm.middle.view.MiddleUserInfo;
 import com.ytpm.oauth.model.YtPlatformUser;
 import com.ytpm.util.IDUtil;
@@ -27,9 +24,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.util.Date;
-import java.util.List;
 import java.util.Objects;
-import java.util.stream.Collectors;
 
 @Service
 public class UserServiceImpl implements UserService {
@@ -62,7 +57,7 @@ public class UserServiceImpl implements UserService {
         YtPlatformUser user = new YtPlatformUser();
         BeanUtils.copyProperties(param, user);
         user.setUserId(IDUtil.generateFlowID("middle_"));
-        user.setUserType(99);
+        user.setUserType(UserTypeEnum.PLATFORM_USER.getCode());
         user.setRegistryTime(new Date());
         BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
         user.setEncryptPwd(encoder.encode(param.getPassword()));

+ 44 - 13
yt-question/yt-question-service/src/main/java/com/ytpm/question/controller/UserController.java

@@ -24,6 +24,7 @@ import com.ytpm.app.param.AppUserQueryParam;
 import com.ytpm.app.param.AppUserTodayBannedParam;
 import com.ytpm.app.param.YtAppUserListParam;
 import com.ytpm.app.view.HourCountView;
+import com.ytpm.app.view.WxDefaultConfig;
 import com.ytpm.app.view.YtAppUserListView;
 import com.ytpm.feign.RiskFeign;
 import com.ytpm.general.RepMessage;
@@ -38,7 +39,10 @@ import com.ytpm.question.redis.RedisService;
 import com.ytpm.risk.enums.BannedTypeEnum;
 import com.ytpm.risk.view.RiskConfigView;
 import com.ytpm.risk.view.RiskTemplateView;
+import com.ytpm.util.NumberUtils;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.apache.commons.codec.binary.Base64;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -53,6 +57,7 @@ import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -65,6 +70,7 @@ import java.util.Objects;
 import java.util.stream.Collectors;
 
 @Slf4j
+@RefreshScope
 @RestController
 @RequestMapping("/user")
 public class UserController {
@@ -84,6 +90,9 @@ public class UserController {
     @Resource
     private RiskFeign riskFeign;
 
+    @Value("${yt.revenue.scale:3}")
+    private Integer revenueScale;
+
     @Value("${spring.application.name:}")
     private String applicationName;
 
@@ -118,8 +127,8 @@ public class UserController {
     /**
      * 设置视频记录和登录信息
      */
-    private void setUserExtInfo(List<YtAppUserListView> result, Map<String, List<YtDyzAdRecord>> userAdMap, Map<String,
-            List<YtDyzLoginRecord>> loginMap) {
+    private void setUserExtInfo(List<YtAppUserListView> result, Map<String, List<YtDyzAdRecord>> userAdMap,
+                                Map<String, List<YtDyzLoginRecord>> loginMap) {
         for (YtAppUserListView user : result) {
             if (loginMap.containsKey(user.getUserId())) {
                 user.setLoginRecordList(loginMap.get(user.getUserId()));
@@ -164,18 +173,40 @@ public class UserController {
     @GetMapping("/getUserInfo")
     public Result<YtDyzUser> getUserInfo(@RequestParam("userId") String userId) {
         YtDyzUser user = appUserMapper.selectPrimaryKey(userId);
-        user.setLoginRecordList(loginRecordMapper.getLoginRecords(userId));
-        user.setTodayAnswerCount(questionMapper.getAnswerCount(userId, 1));
-        user.setHistoryAnswerCount(questionMapper.getAnswerCount(userId, 2));
-        user.setAnswerRecordList(questionMapper.getAnswerRecords(userId));
-        Result<?> result = riskFeign.checkAdRisk(user);
-        if (result != null) {
-            user.setIfPowerLimit(false);
-            if (result.getCode() != 200) {
-                if ("766".equals(result.getMessage()) || result.getCode() == StatusCode.ACCESS_RISK_ERROR && StrUtil.isNotEmpty(result.getMessage())) {
-                    user.setIfPowerLimit(true);
-                }
+        if (user != null) {
+            // 登陆记录
+            user.setLoginRecordList(loginRecordMapper.getLoginRecords(userId));
+            // 今日答题数
+            user.setTodayAnswerCount(questionMapper.getAnswerCount(userId, 1));
+            // 历史答题数
+            user.setHistoryAnswerCount(questionMapper.getAnswerCount(userId, 2));
+            // 答题记录列表
+            user.setAnswerRecordList(questionMapper.getAnswerRecords(userId));
+            WxDefaultConfig defaultConfig = appUserMapper.getDefaultConfigByAppId(user.getAppId());
+            // 分层系数
+            String revenueDisplayRate = defaultConfig == null ? "" : defaultConfig.getRevenueDisplayRate();
+            BigDecimal todayRevenue = adRecordMapper.getToTalRevenue(userId, 1);
+            BigDecimal totalRevenue = user.getTotalIncome() == null ? adRecordMapper.getToTalRevenue(userId, 2) : user.getTotalIncome();
+            if (StrUtil.isNotEmpty(revenueDisplayRate)) {
+                BigDecimal rate = NumberUtils.rateToBigDecimal(revenueDisplayRate);
+                todayRevenue = todayRevenue.multiply(rate).setScale(revenueScale, RoundingMode.HALF_UP);
+                totalRevenue = totalRevenue.multiply(rate).setScale(revenueScale, RoundingMode.HALF_UP);
+            }
+            // 今日收益
+            user.setTodayIncome(todayRevenue);
+            // 历史收益
+            user.setTotalIncome(totalRevenue);
+            if (user.getNearlyIncome() != null) {
+                user.setNearlyIncome(user.getNearlyIncome().setScale(revenueScale, RoundingMode.HALF_UP));
+            }
+            // 是否体力已达上限
+            boolean ifPowerLimit = false;
+            Result<?> result = riskFeign.checkAdRisk(user);
+            if (result != null && result.getCode() != 200) {
+                ifPowerLimit = "766".equals(result.getMessage())
+                        || result.getCode() == StatusCode.ACCESS_RISK_ERROR && StrUtil.isNotEmpty(result.getMessage());
             }
+            user.setIfPowerLimit(ifPowerLimit);
         }
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("serverName", applicationName);

+ 7 - 0
yt-question/yt-question-service/src/main/java/com/ytpm/question/dao/AdRecordMapper.java

@@ -82,4 +82,11 @@ public interface AdRecordMapper {
      * 本月按广告平台聚合
      */
     List<AgentNetworkAgg> getMonthAggByNetwork(@Param("appIds") String appIds);
+
+    /**
+     * 统计用户广告收益
+     * @param userId 用户ID
+     * @param type 统计方式|1统计今日|2统计所有
+     */
+    BigDecimal getToTalRevenue(@Param("userId") String userId, @Param("type") Integer type);
 }

+ 7 - 4
yt-question/yt-question-service/src/main/java/com/ytpm/question/dao/AppUserMapper.java

@@ -92,6 +92,12 @@ public interface AppUserMapper {
 
     WxDefaultConfig getDefaultConfigByAppId(@Param("appId") String appId);
 
+    /**
+     * 根据APP_ID获取配置
+     */
+    List<WxDefaultConfig> getConfigByIds(@Param("appIds") String appIds);
+
+
     /**
      * 根据微信openid查询用户
      */
@@ -112,10 +118,7 @@ public interface AppUserMapper {
     void updateAppConfig(YtAppDefaultConfig defaultConfig);
 
 
-    /**
-     * 根据APP_ID获取配置
-     */
-    List<WxDefaultConfig> getConfigByIds(@Param("appIds") String appIds);
+
 
     /**
      * 根据应用统计广告数

+ 8 - 0
yt-question/yt-question-service/src/main/resources/mapper/AdRecordMapper.xml

@@ -276,5 +276,13 @@
             and finish_time > #{startTime}
         </if>
     </select>
+    <select id="getToTalRevenue" resultType="java.math.BigDecimal">
+        select sum(revenue) as revenue
+        from yt_dyz_ad_record
+        where user_id = #{userId}
+        <if test="type != null and type = 1">
+            AND DATE(finish_time) = DATE(NOW())
+        </if>
+    </select>
 
 </mapper>

+ 123 - 128
yt-question/yt-question-service/src/main/resources/mapper/AppUserMapper.xml

@@ -66,112 +66,6 @@
                 #{recordId},#{userId},#{type},#{remark},#{addTime}
             )
     </insert>
-    <insert id="saveAppConfig">
-        insert into yt_app_default_config
-        (
-            config_name,
-            open_id,
-            secret,
-            app_id,
-            app_key,
-            app_type,
-            ditch_id
-        )
-        values
-            (
-                #{configName},
-                #{openId},
-                #{secret},
-                #{appId},
-                #{appKey},
-                #{appType},
-                #{ditchId}
-            )
-    </insert>
-    <update id="updateAppConfig">
-        update yt_app_default_config
-        <set>
-            <if test="canSimulator != null">
-                can_simulator = #{canSimulator},
-            </if>
-            <if test="configName != null">
-                config_name = #{configName},
-            </if>
-            <if test="openId != null">
-                open_id = #{openId},
-            </if>
-            <if test="secret != null">
-                secret = #{secret},
-            </if>
-            <if test="appKey != null">
-                app_key = #{appKey},
-            </if>
-            <if test="appType != null">
-                app_type = #{appType},
-            </if>
-            <if test="takuAppId != null">
-                taku_app_id = #{takuAppId},
-            </if>
-            <if test="takuKey != null">
-                taku_key = #{takuKey},
-            </if>
-            <if test="takuBannerPid != null">
-                taku_banner_pid = #{takuBannerPid},
-            </if>
-            <if test="takuNativePid != null">
-                taku_native_pid = #{takuNativePid},
-            </if>
-            <if test="takuRewardPid != null">
-                taku_reward_pid = #{takuRewardPid},
-            </if>
-            <if test="takuInterstitialPid != null">
-                taku_interstitial_pid = #{takuInterstitialPid},
-            </if>
-            <if test="canUseRoot != null">
-                can_use_root = #{canUseRoot},
-            </if>
-            <if test="canUseAdb != null">
-                can_use_adb = #{canUseAdb},
-            </if>
-            <if test="canUseFloat != null">
-                can_use_float = #{canUseFloat},
-            </if>
-            <if test="canAccumulation != null">
-                can_accumulation = #{canAccumulation},
-            </if>
-            <if test="ditchId != null">
-                ditch_id = #{ditchId},
-            </if>
-            <if test="powerWaitTime != null">
-                power_wait_time = #{powerWaitTime},
-            </if>
-            <if test="interstitialIntervalTime != null">
-                interstitial_interval_time = #{interstitialIntervalTime},
-            </if>
-            <if test="flowIntervalTime != null">
-                flow_interval_time = #{flowIntervalTime},
-            </if>
-            <if test="taskLimitTip != null">
-                task_limit_tip = #{taskLimitTip},
-            </if>
-            <if test="lowValueTip != null">
-                low_value_tip = #{lowValueTip},
-            </if>
-            <if test="brushTip != null">
-                brush_tip = #{brushTip},
-            </if>
-            <if test="startWaitTime != null">
-                start_wait_time = #{startWaitTime},
-            </if>
-            <if test="canCacheVideo != null">
-                can_cache_video = #{canCacheVideo},
-            </if>
-            <if test="canAllowAutoRefresh != null">
-                can_allow_auto_refresh = #{canAllowAutoRefresh}
-            </if>
-        </set>
-        where app_id = #{appId}
-    </update>
     <update id="addOnePower">
         update yt_dyz_user set power = power+1 where user_id = #{userId}
     </update>
@@ -250,9 +144,7 @@
         </set>
         where user_id = #{userId}
     </update>
-    <delete id="delByAppId">
-        delete from yt_app_default_config where app_id = #{appId}
-    </delete>
+
     <select id="getYtAppUser" resultType="com.ytpm.app.model.YtDyzUser">
         select
             user_id, app_id,phone,device_id, ditch_id, nick_name,head_img, power,
@@ -458,6 +350,118 @@
             #{item}
         </foreach>
     </select>
+    <insert id="saveAppConfig">
+        insert into yt_app_default_config
+        (
+            config_name,
+            open_id,
+            secret,
+            app_id,
+            app_key,
+            app_type,
+            ditch_id
+        )
+        values
+            (
+                #{configName},
+                #{openId},
+                #{secret},
+                #{appId},
+                #{appKey},
+                #{appType},
+                #{ditchId}
+            )
+    </insert>
+    <update id="updateAppConfig">
+        update yt_app_default_config
+        <set>
+            <if test="canSimulator != null">
+                can_simulator = #{canSimulator},
+            </if>
+            <if test="configName != null">
+                config_name = #{configName},
+            </if>
+            <if test="openId != null">
+                open_id = #{openId},
+            </if>
+            <if test="secret != null">
+                secret = #{secret},
+            </if>
+            <if test="appKey != null">
+                app_key = #{appKey},
+            </if>
+            <if test="appType != null">
+                app_type = #{appType},
+            </if>
+            <if test="takuAppId != null">
+                taku_app_id = #{takuAppId},
+            </if>
+            <if test="takuKey != null">
+                taku_key = #{takuKey},
+            </if>
+            <if test="takuBannerPid != null">
+                taku_banner_pid = #{takuBannerPid},
+            </if>
+            <if test="takuNativePid != null">
+                taku_native_pid = #{takuNativePid},
+            </if>
+            <if test="takuRewardPid != null">
+                taku_reward_pid = #{takuRewardPid},
+            </if>
+            <if test="takuInterstitialPid != null">
+                taku_interstitial_pid = #{takuInterstitialPid},
+            </if>
+            <if test="canUseRoot != null">
+                can_use_root = #{canUseRoot},
+            </if>
+            <if test="canUseAdb != null">
+                can_use_adb = #{canUseAdb},
+            </if>
+            <if test="canUseFloat != null">
+                can_use_float = #{canUseFloat},
+            </if>
+            <if test="canAccumulation != null">
+                can_accumulation = #{canAccumulation},
+            </if>
+            <if test="ditchId != null">
+                ditch_id = #{ditchId},
+            </if>
+            <if test="powerWaitTime != null">
+                power_wait_time = #{powerWaitTime},
+            </if>
+            <if test="interstitialIntervalTime != null">
+                interstitial_interval_time = #{interstitialIntervalTime},
+            </if>
+            <if test="flowIntervalTime != null">
+                flow_interval_time = #{flowIntervalTime},
+            </if>
+            <if test="taskLimitTip != null">
+                task_limit_tip = #{taskLimitTip},
+            </if>
+            <if test="lowValueTip != null">
+                low_value_tip = #{lowValueTip},
+            </if>
+            <if test="brushTip != null">
+                brush_tip = #{brushTip},
+            </if>
+            <if test="startWaitTime != null">
+                start_wait_time = #{startWaitTime},
+            </if>
+            <if test="canCacheVideo != null">
+                can_cache_video = #{canCacheVideo},
+            </if>
+            <if test="canAllowAutoRefresh != null">
+                can_allow_auto_refresh = #{canAllowAutoRefresh},
+            </if>
+            <if test="revenueDisplayRate != null">
+                revenue_display_rate = #{revenueDisplayRate}
+            </if>
+        </set>
+        where app_id = #{appId}
+    </update>
+    <delete id="delByAppId">
+        delete from yt_app_default_config where app_id = #{appId}
+    </delete>
     <select id="getDefaultConfig" resultType="com.ytpm.app.view.WxDefaultConfig">
         select
             config_id, config_name, open_id as app_id, secret, app_id as platformAppId, app_key as platformAppSecret,
@@ -466,7 +470,7 @@
             can_use_root, can_use_adb, can_use_float, can_accumulation,
             ditch_id, power_wait_time, interstitial_interval_time,
             low_value_tip, brush_tip,flow_interval_time,task_limit_tip,start_wait_time,
-            can_cache_video,can_allow_auto_refresh
+            can_cache_video,can_allow_auto_refresh, revenue_display_rate
         from yt_app_default_config
         where app_type = #{appType}
     </select>
@@ -477,20 +481,23 @@
             taku_reward_pid, taku_interstitial_pid, can_use_root, can_use_adb, can_use_float, can_accumulation,
             ditch_id, power_wait_time, interstitial_interval_time,
             low_value_tip, brush_tip,flow_interval_time,task_limit_tip,start_wait_time,
-            can_cache_video,can_allow_auto_refresh
+            can_cache_video,can_allow_auto_refresh, revenue_display_rate
         from yt_app_default_config
         where app_id = #{appId}
     </select>
-    <select id="getSecretByAppId" resultType="java.lang.String">
+    <select id="getConfigByIds" resultType="com.ytpm.app.view.WxDefaultConfig">
         select
             config_id, config_name, open_id, secret, app_id, app_key, app_type,user_path,login_path,ad_path,
             answer_path,power_path,can_simulator, taku_app_id, taku_key, taku_banner_pid, taku_native_pid,
             taku_reward_pid, taku_interstitial_pid, can_use_root, can_use_adb, can_use_float, can_accumulation,
             ditch_id, power_wait_time, interstitial_interval_time,
-            low_value_tip, brush_tip, flow_interval_time,task_limit_tip,start_wait_time,
-            can_cache_video,can_allow_auto_refresh
+            low_value_tip, brush_tip,flow_interval_time,task_limit_tip,start_wait_time,
+            can_cache_video,can_allow_auto_refresh, revenue_display_rate
         from yt_app_default_config
-        where app_id = #{appId}
+        where app_id in
+        <foreach collection="appIds.split(',')" item="item" separator="," open="(" close=")">
+            #{item}
+        </foreach>
     </select>
     <select id="queryByOpenid" resultType="com.ytpm.app.model.YtDyzUser">
         select
@@ -506,19 +513,7 @@
         where device_id = #{deviceId} and wx_open_id = #{openid}
         limit 1
     </select>
-    <select id="getConfigByIds" resultType="com.ytpm.app.view.WxDefaultConfig">
-        select
-        config_id, config_name, open_id, secret, app_id, app_key, app_type, user_path, login_path, ad_path,
-        answer_path, power_path,taku_app_id, taku_key, taku_banner_pid, taku_native_pid, taku_reward_pid,
-        taku_interstitial_pid, can_use_root, can_use_adb, can_use_float, can_accumulation,can_simulator,
-        ditch_id, power_wait_time, interstitial_interval_time,
-        low_value_tip, brush_tip, flow_interval_time,task_limit_tip,start_wait_time,can_cache_video,can_allow_auto_refresh
-        from yt_app_default_config
-        where app_id in
-        <foreach collection="appIds.split(',')" item="item" separator="," open="(" close=")">
-            #{item}
-        </foreach>
-    </select>
+
     <select id="getAdCount" resultType="java.lang.Integer">
         select sum(total_video)
         from yt_dyz_user