rk
4 天以前 214cda58c3786972c958da5c6d54a135490a3c11
功能开发
已添加6个文件
已删除1个文件
已修改27个文件
2033 ■■■■■ 文件已修改
server/admin/src/main/java/com/doumee/api/business/CategoryController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/admin/src/main/java/com/doumee/config/quartz/SnippetScannerConfig.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/admin/src/main/java/com/doumee/job/CommonTestJob.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/admin/src/main/java/com/doumee/job/DistributableTestJob.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/admin/src/main/java/com/doumee/job/DistributableTestJobDistributer.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/admin/src/main/java/com/doumee/job/InitializeCodeJob.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/api/system/SystemController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/biz/system/SystemUserBiz.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/biz/system/impl/SystemUserBizImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/config/jwt/JwtTokenUtil.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/config/shiro/ShiroConfig.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/config/shiro/ShiroToken.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/dingTalk/DingTalk.java 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/iPass/IPass.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/utils/Base64Util.java 1184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/core/utils/ZbomAESUtils.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/business/model/Category.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/system/dto/DingLoginDTO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/system/dto/DingTalkLoginDTO.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/system/dto/LoginDTO.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/system/model/SystemUser.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/vo/WebLoginUserVO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/dao/vo/ZhanQuVO.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/CategoryService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/MemberService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/ImportRecordServiceImpl.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/system/SystemLoginService.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/system/SystemUserService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/services/src/main/java/com/doumee/service/system/impl/SystemUserServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/web/src/main/java/com/doumee/api/web/LoginController.java 94 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/admin/src/main/java/com/doumee/api/business/CategoryController.java
@@ -20,6 +20,7 @@
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -105,4 +106,14 @@
    public ApiResponse findById(@PathVariable Integer id) {
        return ApiResponse.success(categoryService.findById(id));
    }
    @ApiOperation("战区信息同步")
    @GetMapping("/syncZhanQu")
    public ApiResponse syncZhanQu() throws IOException {
        categoryService.syncZhanQu();
        return ApiResponse.success("同步成功");
    }
}
server/admin/src/main/java/com/doumee/config/quartz/SnippetScannerConfig.java
@@ -20,13 +20,13 @@
                .build();
    }
    @Bean
    public Trigger getSnippetScannerTrigger() {
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?");
        return TriggerBuilder.newTrigger()
                .forJob(getSnippetScanner())
                .withIdentity("snippetScannerTrigger")
                .withSchedule(scheduleBuilder)
                .build();
    }
//    @Bean
//    public Trigger getSnippetScannerTrigger() {
//        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/1 * * * * ?");
//        return TriggerBuilder.newTrigger()
//                .forJob(getSnippetScanner())
//                .withIdentity("snippetScannerTrigger")
//                .withSchedule(scheduleBuilder)
//                .build();
//    }
}
server/admin/src/main/java/com/doumee/job/CommonTestJob.java
@@ -12,7 +12,7 @@
 * @since 2025/03/31 16:44
 */
@Slf4j
@Component("commonTestJob")
//@Component("commonTestJob")
public class CommonTestJob extends BaseJob {
    @Override
server/admin/src/main/java/com/doumee/job/DistributableTestJob.java
@@ -16,7 +16,7 @@
 * @since 2025/03/31 16:44
 */
@Slf4j
@Component("distributableTestJob")
//@Component("distributableTestJob")
public class DistributableTestJob extends BaseJob {
    @Override
server/admin/src/main/java/com/doumee/job/DistributableTestJobDistributer.java
@@ -14,7 +14,7 @@
 * @author  dm
 * @since 2025/03/31 16:44
 */
@Component("distributableTestJobDistributer")
//@Component("distributableTestJobDistributer")
public class DistributableTestJobDistributer extends BaseDistributer<SystemPermission> {
    @Autowired
server/admin/src/main/java/com/doumee/job/InitializeCodeJob.java
ÎļþÒÑɾ³ý
server/services/src/main/java/com/doumee/api/system/SystemController.java
@@ -8,9 +8,11 @@
import com.doumee.core.annotation.trace.Trace;
import com.doumee.core.model.ApiResponse;
import com.doumee.core.model.LoginUserInfo;
import com.doumee.dao.system.dto.DingLoginDTO;
import com.doumee.dao.system.dto.LoginDTO;
import com.doumee.dao.system.dto.UpdatePwdDto;
import com.doumee.service.system.SystemLoginService;
import com.taobao.api.ApiException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@@ -21,6 +23,7 @@
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
 * @author  dm
@@ -48,9 +51,23 @@
        return ApiResponse.success(systemLoginService.loginByPassword(dto, request));
    }
    @PreventRepeat(limit = 10, lockTime = 10000)
    @ApiOperation("钉钉授权登录")
//    @EncryptionReq
//    @EncryptionResp
    @PostMapping("/loginByDingTalk")
    public ApiResponse<Map<String,Object>> loginByDingTalk (@Validated @RequestBody DingLoginDTO dto, HttpServletRequest request) throws ApiException {
        return ApiResponse.success(systemLoginService.loginByDingTalk(dto, request));
    }
    @ApiOperation("退出登录")
    @PostMapping("/logout")
    public ApiResponse logout () {
        systemUserBiz.cleanUnionId(this.getLoginUser().getId());
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return ApiResponse.success(null);
server/services/src/main/java/com/doumee/biz/system/SystemUserBiz.java
@@ -48,7 +48,7 @@
     * @param systemUser è¯¦è§CreateSystemUserDTO
     */
    void create(CreateSystemUserDTO systemUser);
    void cleanUnionId(Integer userId);
    /**
     * ä¿®æ”¹ç”¨æˆ·ä¿¡æ¯
     *
server/services/src/main/java/com/doumee/biz/system/impl/SystemUserBizImpl.java
@@ -1,5 +1,7 @@
package com.doumee.biz.system.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.doumee.biz.system.SystemUserBiz;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.constants.ResponseStatus;
@@ -159,6 +161,15 @@
        systemUserService.updateById(systemUser);
    }
    @Override
    public void cleanUnionId(Integer userId){
        LambdaUpdateWrapper<SystemUser> w = new UpdateWrapper<SystemUser>().lambda().set(SystemUser::getUnionId,null)
                .eq(SystemUser::getId,userId);
        systemUserService.updateByWrapper(w);
    }
    @Override
    @Transactional
    public void createUserRole(CreateUserRoleDTO dto) {
server/services/src/main/java/com/doumee/config/jwt/JwtTokenUtil.java
@@ -7,6 +7,7 @@
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
server/services/src/main/java/com/doumee/config/shiro/ShiroConfig.java
@@ -87,6 +87,7 @@
        Map<String, String> map = new LinkedHashMap<>();
        // è·¯å¾„拦截配置
        map.put("/system/login", "anon");
        map.put("/system/loginByDingTalk", "anon");
        map.put("/system/logout", "anon");
        map.put("/common/captcha", "anon");
        // - æ”¾è¡Œswagger
server/services/src/main/java/com/doumee/config/shiro/ShiroCredentialsMatcher.java
@@ -25,17 +25,22 @@
    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        SystemUser queryUserDto = new SystemUser();
        queryUserDto.setUsername(usernamePasswordToken.getUsername());
        queryUserDto.setDeleted(Boolean.FALSE);
        SystemUser systemUser = systemUserService.findOne(queryUserDto);
        if (systemUser == null) {
            return Boolean.FALSE;
        ShiroToken shiroToken = (ShiroToken) token;
        if(!shiroToken.getDdLogin()){
            SystemUser queryUserDto = new SystemUser();
            queryUserDto.setUsername(shiroToken.getUsername());
            queryUserDto.setDeleted(Boolean.FALSE);
            SystemUser systemUser = systemUserService.findOne(queryUserDto);
            if (systemUser == null) {
                return Boolean.FALSE;
            }
            // åŠ å¯†å¯†ç 
            String pwd = Utils.Secure.encryptPassword(new String(shiroToken.getPassword()), systemUser.getSalt());
            // æ¯”较密码
            return this.equals(pwd, systemUser.getPassword());
        }else{
            return true;
        }
        // åŠ å¯†å¯†ç 
        String pwd = Utils.Secure.encryptPassword(new String(usernamePasswordToken.getPassword()), systemUser.getSalt());
        // æ¯”较密码
        return this.equals(pwd, systemUser.getPassword());
    }
}
server/services/src/main/java/com/doumee/config/shiro/ShiroToken.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.doumee.config.shiro;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.springframework.stereotype.Component;
/**
 * è‡ªå®šä¹‰Token ï¼Œå¤„理认证和权限
 * @author Eva.Caesar Liu
 * @date 2022/04/18 18:12
 */
@Component
public class ShiroToken extends UsernamePasswordToken {
    /**
     * å…¬å¸ID
     */
    String unionId;
    Boolean isDdLogin;
    public ShiroToken() {
    }
    public ShiroToken(String unionId, String username, String password, boolean isDdLogin) {
        super(username,  password, false, (String)null);
        this.unionId = unionId;
        this.isDdLogin = isDdLogin;
    }
    public Boolean getDdLogin() {
        return isDdLogin;
    }
    public void setDdLogin(Boolean ddLogin) {
        isDdLogin = ddLogin;
    }
    public String getUnionId() {
        return unionId;
    }
    public void setUnionId(String unionId) {
        this.unionId = unionId;
    }
}
server/services/src/main/java/com/doumee/core/dingTalk/DingTalk.java
@@ -82,32 +82,14 @@
        return accessToken;
    }
    private String getAccessToken(String corpId) {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        try {
            com.aliyun.dingtalkoauth2_1_0.Client client = new com.aliyun.dingtalkoauth2_1_0.Client(config);
            com.aliyun.dingtalkoauth2_1_0.models.GetTokenRequest getTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetTokenRequest()
                    .setClientId(clientId)
                    .setClientSecret(clientSecret)
                    .setGrantType("client_credentials");
            GetTokenResponse response = client.getToken(corpId, getTokenRequest);
            return response.getBody().accessToken;
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err ä¸­å«æœ‰ code å’Œ message å±žæ€§ï¼Œå¯å¸®åŠ©å¼€å‘å®šä½é—®é¢˜
                log.error("Error getting access token: {}", err.getMessage());
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err ä¸­å«æœ‰ code å’Œ message å±žæ€§ï¼Œå¯å¸®åŠ©å¼€å‘å®šä½é—®é¢˜
                log.error("Error getting access token: {}", err.getMessage());
            }
        }
        return null;
    private String getAccessToken() throws ApiException {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
        OapiGettokenRequest req = new OapiGettokenRequest();
        req.setAppkey(clientId);
        req.setAppsecret(clientSecret);
        req.setHttpMethod("GET");
        OapiGettokenResponse rsp = client.execute(req);
        return rsp.getAccessToken();
    }
@@ -115,7 +97,7 @@
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getuserinfo");
        OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
        req.setCode(dto.getCode());
        OapiV2UserGetuserinfoResponse rsp = client.execute(req, getAccessToken(dto.getCorpId()));
        OapiV2UserGetuserinfoResponse rsp = client.execute(req, getAccessToken());
        if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
           return  rsp.getResult();
        }else{
server/services/src/main/java/com/doumee/core/iPass/IPass.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,96 @@
package com.doumee.core.iPass;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.dao.vo.ZhanQuVO;
import okhttp3.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Rk
 * @create 2026/2/3 15:15
 */
public class IPass {
    private static  String userName = "djpt";
    private static  String password = "CwzOdj3G8Y05NRu9pWjcmmODj56/6iZjSD33couFE3XNrkNjEQUZwnkLEGN6ot1O7b9q/K+PsRNh7iRquL4ZYQdajIM3P+qxn8Q1eW2eICmwMY0L+vWpBK30xU+DX6yzkt5/meitCa5rZERUWUGAfAfimdvhfCazLseXdB3x/ieJ+/C+22LH0gIZoqiC0xqh+xR5NENu0lcC7PLJoCE0rzq+LLY7TNwmv6Ghxjbq5cCuxMd0H6uD3nKM/13+TNLuod5/9RzGBo966CUqLqS2L6XTqZkGCRwJL7pvD0+ZAnM36gXC1aTXT4Z6bYnwsGfpu7MjHODGSrzhrQEXS2Gbfg==";
    private static String tokenUrl = "https://ipaasuat.zhibang.com:4430/open-api/rest/core/auth/login";
    private static String zhanquUrl = "https://ipaasuat.zhibang.com:4430/open-api/mdm/cust-territories-trees/query";
    public String getIPassToken() throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        Map<String,String> requestBody = new HashMap<>();
        requestBody.put("userName",userName);
        requestBody.put("password",password);
        RequestBody body = RequestBody.create(mediaType, JSONObject.toJSON(requestBody).toString());
        Request request = new Request.Builder()
                .url(tokenUrl)
                .method("POST", body)
                .addHeader("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
                .addHeader("Content-Type", "application/json; charset=utf-8")
                .build();
        Response response = client.newCall(request).execute();
        if(Objects.isNull(response)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"获取IPASS授权权限失败,请联系管理员");
        }
        if(!Constants.equalsInteger(200,response.code())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"获取IPASS授权权限失败:"+response.message());
        }
        JSONObject jsonObject = JSONObject.parseObject(response.body().string());
        String token = jsonObject.getString("identitytoken");
        return  token;
    }
    public List<ZhanQuVO> getIPassZhanquList() throws IOException {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json");
        Map<String,Object> requestBody = new HashMap<>();
        requestBody.put("nodeLevel","1");
        requestBody.put("pageNo","1");
        requestBody.put("pageSize","1000");
        RequestBody body = RequestBody.create(mediaType, JSONObject.toJSON(requestBody).toString());
        Request request = new Request.Builder()
                .url(zhanquUrl)
                .method("POST", body)
                .addHeader("identitytoken", getIPassToken())
                .addHeader("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
                .addHeader("Content-Type", "application/json")
                .build();
        Response response = client.newCall(request).execute();
        if(Objects.isNull(response)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"获取IPASS战区信息失败,请联系管理员");
        }
        if(!Constants.equalsInteger(200,response.code())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"获取IPASS战区信息失败:"+response.message());
        }
        JSONObject json = JSONObject.parseObject(response.body().string());
        JSONArray jsonArray = json.getJSONArray("rows");
        List<ZhanQuVO> zhanQuVOS = jsonArray.toJavaList(ZhanQuVO.class);
        return zhanQuVOS;
    }
    public static void main(String[] args) throws IOException {
        IPass iPass = new IPass();
        iPass.getIPassZhanquList();
    }
}
server/services/src/main/java/com/doumee/core/utils/Base64Util.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,1184 @@
package com.doumee.core.utils;
/**
 * Base64文件字符串处理工具类
 *
 * @ClassName Base64Util
 * @Description TODO
 * @author jfli@woyitech.com
 * @date 2016å¹´5月27日 ä¸Šåˆ11:46:34
 */
public final class Base64Util {
    /**
     * NO_OPTIONS=0
     */
    public static final int NO_OPTIONS = 0;
    /**
     * ENCODE = 1
     */
    public static final int ENCODE = 1;
    /**
     * DECODE = 0
     */
    public static final int DECODE = 0;
    /**
     * GZIP = 2
     */
    public static final int GZIP = 2;
    /**
     * DONT_BREAK_LINES = 8
     */
    public static final int DONT_BREAK_LINES = 8;
    /**
     * MAX_LINE_LENGTH = 76
     */
    private static final int MAX_LINE_LENGTH = 76;
    /**
     * EQUALS_SIGN(=)
     */
    private static final byte EQUALS_SIGN = (byte) '=';
    /**
     * NEW_LINE(enter)
     */
    private static final byte NEW_LINE = (byte) '\n';
    /**
     * PREFERRED_ENCODING(UTF-8)
     */
    private static final String PREFERRED_ENCODING = "UTF-8";
    /**
     * ALPHABET
     */
    private static final byte[] ALPHABET;
    /**
     * _NATIVE_ALPHABET
     */
    private static final byte[] PRI_NATIVE_ALPHABET = new byte[] {
            (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D',
            (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I',
            (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M',
            (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R',
            (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V',
            (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a',
            (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
            (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
            (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
            (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's',
            (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w',
            (byte) 'x', (byte) 'y', (byte) 'z', (byte) '0', (byte) '1',
            (byte) '2', (byte) '3', (byte) '4', (byte) '5',
            (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) '+', (byte) '/' };
    static {
        byte[] priBytes = null;
        try {
            priBytes =
                    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
                    .getBytes(PREFERRED_ENCODING);
        } catch (java.io.UnsupportedEncodingException use) {
            priBytes = PRI_NATIVE_ALPHABET; // Fall back to native encoding
        } // end catch
        ALPHABET = priBytes;
    } // end static
    /**
     * DECODABET
     */
    private static final byte[] DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal// 0// -// 8
            -5, -5, // Whitespace: Tab and Linefeed
            -9, -9, // Decimal 11 - 12
            -5, // Whitespace: Carriage Return
            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - // 26
            -9, -9, -9, -9, -9, // Decimal 27 - 31
            -5, // Whitespace: Space
            -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
            62, // Plus sign at decimal 43
            -9, -9, -9, // Decimal 44 - 46
            63, // Slash at decimal 47
            52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
            -9, -9, -9, // Decimal 58 - 60
            -1, // Equals sign at decimal 61
            -9, -9, -9, // Decimal 62 - 64
            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through // 'N'
            14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O'// through 'Z'
            -9, -9, -9, -9, -9, -9, // Decimal 91 - 96
            26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a'// through 'm'
            39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n'// through 'z'
            -9, -9, -9, -9 // Decimal 123 - 126
    };
    // I think I end up not using the BAD_ENCODING indicator.
    // private final static byte BAD_ENCODING = -9; // Indicates error in
    // encoding
    /**
     * WHITE_SPACE_ENC = -5
     */
    private static final byte WHITE_SPACE_ENC = -5; // Indicates white space in
    // encoding
    /**
     *     EQUALS_SIGN_ENC = -1
     */
    private static final byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in // encoding
    /**
     * é»˜è®¤æž„造器
     * @Title Base64Util
     * @Description TODO
     */
    private Base64Util() {
    }
    /**
     * åР坆byte数组
     *
     * @param b4
     * @param threeBytes
     * @param numSigBytes
     * @return byte数组
     */
    private static byte[] encode3to4(byte[] b4, byte[] threeBytes, int numSigBytes) {
        encode3to4(threeBytes, 0, numSigBytes, b4, 0);
        return b4;
    } // end encode3to4
    /**
     * åР坆byte数组
     *
     * @param source
     * @param srcOffset
     * @param numSigBytes
     * @param destination
     * @param destOffset
     * @return byte数组
     */
    private static byte[] encode3to4(byte[] source, int srcOffset,
            int numSigBytes, byte[] destination,
            int destOffset) {
        // 1 2 3
        // 01234567890123456789012345678901 Bit position
        // --------000000001111111122222222 Array position from threeBytes
        // --------| || || || | Six bit groups to index ALPHABET
        // >>18 >>12 >> 6 >> 0 Right shift necessary
        // 0x3f 0x3f 0x3f Additional AND
        // Create buffer with zero-padding if there are only one or two
        // significant bytes passed in the array.
        // We have to shift left 24 in order to flush out the 1's that appear
        // when Java treats a value as negative that is cast from a byte to an
        // int.
        int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
                | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
                | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
        switch (numSigBytes) {
        case 3:
            destination[destOffset] = ALPHABET[(inBuff >>> 18)];
            destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
            destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
            destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f];
            return destination;
        case 2:
            destination[destOffset] = ALPHABET[(inBuff >>> 18)];
            destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
            destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f];
            destination[destOffset + 3] = EQUALS_SIGN;
            return destination;
        case 1:
            destination[destOffset] = ALPHABET[(inBuff >>> 18)];
            destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f];
            destination[destOffset + 2] = EQUALS_SIGN;
            destination[destOffset + 3] = EQUALS_SIGN;
            return destination;
        default:
            return destination;
        } // end switch
    } // end encode3to4
    /**
     * åºåˆ—化对象转化字符串
     *
     * @param serializableObject
     * @return å­—符串
     */
    public static String encodeObject(java.io.Serializable serializableObject) {
        return encodeObject(serializableObject, NO_OPTIONS);
    } // end encodeObject
    /**
     * åºåˆ—化对象转化字符串
     *
     * @param serializableObject
     * @param options
     * @return å­—符串
     */
    public static String encodeObject(java.io.Serializable serializableObject, int options) {
        // Streams
        java.io.ByteArrayOutputStream baos = null;
        java.io.OutputStream b64os = null;
        java.io.ObjectOutputStream oos = null;
        java.util.zip.GZIPOutputStream gzos = null;
        // Isolate options
        int gzip = (options & GZIP);
        int dontBreakLines = (options & DONT_BREAK_LINES);
        try {
            // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream
            baos = new java.io.ByteArrayOutputStream();
            b64os = new OutputStream(baos, ENCODE | dontBreakLines);
            // GZip?
            if (gzip == GZIP) {
                gzos = new java.util.zip.GZIPOutputStream(b64os);
                oos = new java.io.ObjectOutputStream(gzos);
                // end if: gzip
            } else {
                oos = new java.io.ObjectOutputStream(b64os);
            }
            oos.writeObject(serializableObject);
            // end try
        } catch (java.io.IOException e) {
            e.printStackTrace();
            return null;
            // end catch
        } finally {
            try {
                oos.close();
            } catch (Exception e) {
            }
            try {
                gzos.close();
            } catch (Exception e) {
            }
            try {
                b64os.close();
            } catch (Exception e) {
            }
            try {
                baos.close();
            } catch (Exception e) {
            }
        } // end finally
        // Return value according to relevant encoding.
        try {
            return new String(baos.toByteArray(), PREFERRED_ENCODING);
            // end try
        } catch (java.io.UnsupportedEncodingException uue) {
            return new String(baos.toByteArray());
        } // end catch
    } // end encode
    /**
     * byte数组转化字符串
     *
     * @param source
     * @return å­—符串
     */
    public static String encodeBytes(byte[] source) {
        return encodeBytes(source, 0, source.length, NO_OPTIONS);
    } // end encodeBytes
    /**
     * byte数组转化字符串
     *
     * @param source
     * @param options
     * @return å­—符串
     */
    public static String encodeBytes(byte[] source, int options) {
        return encodeBytes(source, 0, source.length, options);
    } // end encodeBytes
    /**
     * byte数组转化字符串
     *
     * @param source
     * @param off
     * @param len
     * @return å­—符串
     */
    public static String encodeBytes(byte[] source, int off, int len) {
        return encodeBytes(source, off, len, NO_OPTIONS);
    } // end encodeBytes
    /**
     * byte数组转化字符串
     *
     * @param source
     * @param off
     * @param len
     * @param options
     * @return å­—符串
     */
    public static String encodeBytes(byte[] source, int off, int len, int options) {
        // Isolate options
        int dontBreakLines = (options & DONT_BREAK_LINES);
        int gzip = (options & GZIP);
        // Compress?
        if (gzip == GZIP) {
            java.io.ByteArrayOutputStream baos = null;
            java.util.zip.GZIPOutputStream gzos = null;
            OutputStream b64os = null;
            try {
                // GZip -> Base64 -> ByteArray
                baos = new java.io.ByteArrayOutputStream();
                b64os = new OutputStream(baos, ENCODE | dontBreakLines);
                gzos = new java.util.zip.GZIPOutputStream(b64os);
                gzos.write(source, off, len);
                gzos.close();
                // end try
            } catch (java.io.IOException e) {
                e.printStackTrace();
                return null;
                // end catch
            } finally {
                try {
                    gzos.close();
                } catch (Exception e) {
                }
                try {
                    b64os.close();
                } catch (Exception e) {
                }
                try {
                    baos.close();
                } catch (Exception e) {
                }
            } // end finally
            // Return value according to relevant encoding.
            try {
                return new String(baos.toByteArray(), PREFERRED_ENCODING);
                // end try
            } catch (java.io.UnsupportedEncodingException uue) {
                return new String(baos.toByteArray());
            } // end catch
            // end if: compress
        } else {
        // Else, don't compress. Better not to use streams at all then.
            // Convert option to boolean in way that code likes it.
            boolean breakLines = dontBreakLines == 0;
            int len43 = len * 4 / 3;
            byte[] outBuff = new byte[(len43) // Main 4:3
                    + ((len % 3) > 0 ? 4 : 0) // Account for padding
                    + (breakLines ? (len43 / MAX_LINE_LENGTH) : 0)]; // New // lines
            int d = 0;
            int e = 0;
            int len2 = len - 2;
            int lineLength = 0;
            for (; d < len2; d += 3, e += 4) {
                encode3to4(source, d + off, 3, outBuff, e);
                lineLength += 4;
                if (breakLines && lineLength == MAX_LINE_LENGTH) {
                    outBuff[e + 4] = NEW_LINE;
                    e++;
                    lineLength = 0;
                } // end if: end of line
            } // en dfor: each piece of array
            if (d < len) {
                encode3to4(source, d + off, len - d, outBuff, e);
                e += 4;
            } // end if: some padding needed
            // Return value according to relevant encoding.
            try {
                return new String(outBuff, 0, e, PREFERRED_ENCODING);
                // end try
            } catch (java.io.UnsupportedEncodingException uue) {
                return new String(outBuff, 0, e);
            } // end catch
        } // end else: don't compress
    } // end encodeBytes
    /**
     * è¡¨ç¤ºçœ‹ä¸æ‡‚,求补充
     *
     * @param source
     * @param srcOffset
     * @param destination
     * @param destOffset
     * @return int
     */
    private static int decode4to3(byte[] source, int srcOffset,
            byte[] destination, int destOffset) {
        // Example: Dk==
        if (source[srcOffset + 2] == EQUALS_SIGN) {
            // Two ways to do the same thing. Don't know which way I like best.
            // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6
            // )
            // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 );
            int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
                    | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12);
            destination[destOffset] = (byte) (outBuff >>> 16);
            return 1;
        } else if (source[srcOffset + 3] == EQUALS_SIGN) {// Example: DkL=
            // Two ways to do the same thing. Don't know which way I like best.
            // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6
            // )
            // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
            // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 );
            int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
                    | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
                    | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6);
            destination[destOffset] = (byte) (outBuff >>> 16);
            destination[destOffset + 1] = (byte) (outBuff >>> 8);
            return 2;
        } else {// Example: DkLE
            try {
                // Two ways to do the same thing. Don't know which way I like
                // best.
                // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 )
                // >>> 6 )
                // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 )
                // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 )
                // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 );
                int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18)
                        | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12)
                        | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6)
                        | ((DECODABET[source[srcOffset + 3]] & 0xFF));
                destination[destOffset] = (byte) (outBuff >> 16);
                destination[destOffset + 1] = (byte) (outBuff >> 8);
                destination[destOffset + 2] = (byte) (outBuff);
                return 3;
            } catch (Exception e) {
                // System.out.println(""+source[srcOffset]+ ": " + ( DECODABET[
                // source[ srcOffset ] ] ) );
                // System.out.println(""+source[srcOffset+1]+ ": " + (
                // DECODABET[ source[ srcOffset + 1 ] ] ) );
                // System.out.println(""+source[srcOffset+2]+ ": " + (
                // DECODABET[ source[ srcOffset + 2 ] ] ) );
                // System.out.println(""+source[srcOffset+3]+ ": " + (
                // DECODABET[ source[ srcOffset + 3 ] ] ) );
                return -1;
            } // e nd catch
        }
    } // end decodeToBytes
    /**
     * åР坆byte数据
     *
     * @param source
     *            åŽŸbyte数组
     * @param off
     *            å¼€å§‹ä½ç½®
     * @param len
     *            é•¿åº¦
     * @return byte数组
     */
    public static byte[] decode(byte[] source, int off, int len) {
        int len34 = len * 3 / 4;
        byte[] outBuff = new byte[len34]; // Upper limit on size of output
        int outBuffPosn = 0;
        byte[] b4 = new byte[4];
        int b4Posn = 0;
        int i = 0;
        byte sbiCrop = 0;
        byte sbiDecode = 0;
        for (i = off; i < off + len; i++) {
            sbiCrop = (byte) (source[i] & 0x7f); // Only the low seven bits
            sbiDecode = DECODABET[sbiCrop];
            if (sbiDecode >= WHITE_SPACE_ENC){ // White space, Equals sign or
                                                // better
                if (sbiDecode >= EQUALS_SIGN_ENC) {
                    b4[b4Posn++] = sbiCrop;
                    if (b4Posn > 3) {
                        outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn);
                        b4Posn = 0;
                        // If that was the equals sign, break out of 'for' loop
                        if (sbiCrop == EQUALS_SIGN){
                            break;
                        }
                    } // end if: quartet built
                } // end if: equals sign or better
                // end if: white space, equals sign or better
            } else {
                System.err.println("Bad Base64 input character at "
                        + i + ": " + source[i] + "(decimal)");
                return null;
            } // end else:
        } // each input character
        byte[] out = new byte[outBuffPosn];
        System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
        return out;
    } // end decode
    /**
     * å°†å­—符串转化为byte数组
     *
     * @param s
     * @return byte数组
     */
    public static byte[] decode(String s) {
        byte[] bytes;
        try {
            bytes = s.getBytes(PREFERRED_ENCODING);
            // end try
        } catch (java.io.UnsupportedEncodingException uee) {
            bytes = s.getBytes();
        } // end catch
            // </change>
        // Decode
        bytes = decode(bytes, 0, bytes.length);
        // Check to see if it's gzip-compressed
        // GZIP Magic Two-Byte Number: 0x8b1f (35615)
        if (bytes != null && bytes.length >= 4) {
            int head = ((int) bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00);
            if (java.util.zip.GZIPInputStream.GZIP_MAGIC == head) {
                java.io.ByteArrayInputStream bais = null;
                java.util.zip.GZIPInputStream gzis = null;
                java.io.ByteArrayOutputStream baos = null;
                byte[] buffer = new byte[2048];
                int length = 0;
                try {
                    baos = new java.io.ByteArrayOutputStream();
                    bais = new java.io.ByteArrayInputStream(bytes);
                    gzis = new java.util.zip.GZIPInputStream(bais);
                    while ((length = gzis.read(buffer)) >= 0) {
                        baos.write(buffer, 0, length);
                    } // end while: reading input
                    // No error? Get new bytes.
                    bytes = baos.toByteArray();
                    // end try
                } catch (java.io.IOException e) {
                    // Just return originally-decoded bytes
                    // end catch
                } finally {
                    try {
                        baos.close();
                    } catch (Exception e) {
                    }
                    try {
                        gzis.close();
                    } catch (Exception e) {
                    }
                    try {
                        bais.close();
                    } catch (Exception e) {
                    }
                } // end finally
            } // end if: gzipped
        } // end if: bytes.length >= 2
        return bytes;
    } // end decode
    /**
     * å°†å­—符串转化为Object对象
     *
     * @param encodedObject
     * @return Object
     */
    public static Object decodeToObject(String encodedObject) {
        // Decode and gunzip if necessary
        byte[] objBytes = decode(encodedObject);
        java.io.ByteArrayInputStream bais = null;
        java.io.ObjectInputStream ois = null;
        Object obj = null;
        try {
            bais = new java.io.ByteArrayInputStream(objBytes);
            ois = new java.io.ObjectInputStream(bais);
            obj = ois.readObject();
             // end try
        } catch (java.io.IOException e) {
            e.printStackTrace();
            obj = null;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            obj = null;
        } finally {
            try {
                bais.close();
            } catch (Exception e) {
            }
            try {
                ois.close();
            } catch (Exception e) {
            }
        } // end finally
        return obj;
    } // end decodeObject
    /**
     * å°†byte数组转换成文件
     *
     * @param dataToEncode
     *            éœ€è¦è½¬æ¢çš„byte数组
     * @param filename
     *            æ–‡ä»¶å,带后缀
     * @return æ˜¯å¦è½¬æ¢æˆåŠŸ
     */
    public static boolean encodeToFile(byte[] dataToEncode, String filename) {
        boolean success = false;
        OutputStream bos = null;
        try {
            bos = new OutputStream(new java.io.FileOutputStream(filename),
                    Base64Util.ENCODE);
            bos.write(dataToEncode);
            success = true;
            // end try
        } catch (java.io.IOException e) {
            success = false;
            // end catch: IOException
        } finally {
            try {
                bos.close();
            } catch (Exception e) {
            }
        } // end finally
        return success;
    } // end encodeToFile
    /**
     * å°†åŠ å¯†å­—ç¬¦ä¸²è½¬æ¢æˆæ–‡ä»¶
     *
     * @param dataToDecode
     *            åŠ å¯†å­—ç¬¦ä¸²
     * @param filename
     *            æ–‡ä»¶åï¼Œå¸¦åŽç¼€
     * @return æ˜¯å¦è½¬æ¢æˆåŠŸ
     */
    public static boolean decodeToFile(String dataToDecode, String filename) {
        boolean success = false;
        OutputStream bos = null;
        try {
            bos = new OutputStream(new java.io.FileOutputStream(filename),
                    Base64Util.DECODE);
            bos.write(dataToDecode.getBytes(PREFERRED_ENCODING));
            success = true;
            // end try
        } catch (java.io.IOException e) {
            success = false;
            // end catch: IOException
        } finally {
            try {
                bos.close();
            } catch (Exception e) {
            }
        } // end finally
        return success;
    } // end decodeToFile
    /**
     * å°†æ–‡ä»¶åŠ å¯†æˆbyte数组
     *
     * @param filename
     *            æ–‡ä»¶åï¼Œå¸¦åŽç¼€
     * @return byte数组
     */
    public static byte[] decodeFromFile(String filename) {
        byte[] decodedData = null;
        InputStream bis = null;
        try {
            // Set up some useful variables
            java.io.File file = new java.io.File(filename);
            byte[] buffer = null;
            int length = 0;
            int numBytes = 0;
            // Check for size of file
            if (file.length() > Integer.MAX_VALUE) {
                System.err.println("File is too big for this convenience method ("
                        + file.length() + " bytes).");
                return null;
            } // end if: file too big for int index
            buffer = new byte[(int) file.length()];
            // Open a stream
            bis = new InputStream(
                    new java.io.BufferedInputStream(new java.io.FileInputStream(file)),
                    Base64Util.DECODE);
            // Read until done
            while ((numBytes = bis.read(buffer, length, 4096)) >= 0){
                length += numBytes;
            }
            // Save in a variable to return
            decodedData = new byte[length];
            System.arraycopy(buffer, 0, decodedData, 0, length);
            // end try
        } catch (java.io.IOException e) {
            System.err.println("Error decoding from file " + filename);
            // end catch: IOException
        } finally {
            try {
                bis.close();
            } catch (Exception e) {
            }
        } // end finally
        return decodedData;
    } // end decodeFromFile
    /**
     * å°†æ–‡ä»¶è½¬æ¢æˆå­—符串
     *
     * @param filename
     * @return æ–‡ä»¶è½¬æ¢åŽçš„字符串
     */
    public static String encodeFromFile(String filename) {
        String encodedData = null;
        InputStream bis = null;
        try {
            // Set up some useful variables
            java.io.File file = new java.io.File(filename);
            byte[] buffer = new byte[(int) (file.length() * 1.4)];
            int length = 0;
            int numBytes = 0;
            // Open a stream
            bis = new InputStream(new java.io.BufferedInputStream(
                    new java.io.FileInputStream(file)),
                    Base64Util.ENCODE);
            // Read until done
            while ((numBytes = bis.read(buffer, length, 4096)) >= 0){
                length += numBytes;
            }
            // Save in a variable to return
            encodedData = new String(buffer, 0, length, Base64Util.PREFERRED_ENCODING);
             // end try
        } catch (java.io.IOException e) {
            System.err.println("Error encoding from file " + filename);
            // end catch: IOException
        } finally {
            try {
                bis.close();
            } catch (Exception e) {
            }
        } // end finally
        return encodedData;
    } // end encodeFromFile
    /**
     * å†…部类InputStream
     * @ClassName  InputStream
     * @Description  TODO
     * @author  jfli@woyitech.com
     * @date  2016å¹´5月27日 ä¸‹åˆ12:27:42
     */
    public static class InputStream extends java.io.FilterInputStream {
        /**
         * Encoding or decoding
         */
        private boolean encode; // Encoding or decoding
        /**
         * Current position in the buffer
         */
        private int position; //
        /**
         * Small buffer holding converted data
         */
        private byte[] buffer; //
        /**
         * Length of buffer (3 or 4)
         */
        private int bufferLength; //
        /**
         *  Number of meaningful bytes in the buffer
         */
        private int numSigBytes; //
        /**
         * lineLength
         */
        private int lineLength;
        /**
         * Break lines at less than 80 characters
         */
        private boolean breakLines; //
        /**
         * æž„造函数
         * @Title InputStream
         * @Description TODO
         * @param in
         */
        public InputStream(java.io.InputStream in) {
            this(in, DECODE);
        } // end constructor
        /**
         * æž„造函数
         * @Title InputStream
         * @Description TODO
         * @param in
         * @param options
         */
        public InputStream(java.io.InputStream in, int options) {
            super(in);
            this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES;
            this.encode = (options & ENCODE) == ENCODE;
            this.bufferLength = encode ? 4 : 3;
            this.buffer = new byte[bufferLength];
            this.position = -1;
            this.lineLength = 0;
        } // end constructor
        /**
         * read
         * @return int
         */
        public int read() throws java.io.IOException {
            // Do we need to get data?
            if (position < 0) {
                if (encode) {
                    byte[] b3 = new byte[3];
                    int numBinaryBytes = 0;
                    for (int i = 0; i < 3; i++) {
                        try {
                            int b = in.read();
                            // If end of stream, b is -1.
                            if (b >= 0) {
                                b3[i] = (byte) b;
                                numBinaryBytes++;
                            } // end if: not end of stream
                            // end try: read
                        } catch (java.io.IOException e) {
                            // Only a problem if we got no data at all.
                            if (i == 0){
                                throw e;
                                }
                        } // end catch
                    } // end for: each needed input byte
                    if (numBinaryBytes > 0) {
                        encode3to4(b3, 0, numBinaryBytes, buffer, 0);
                        position = 0;
                        numSigBytes = 4;
                        // end if: got data
                    } else {
                        return -1;
                    } // end else
                     // end if: encoding
                }else {// Else decoding
                    byte[] b4 = new byte[4];
                    int i = 0;
                    for (i = 0; i < 4; i++) {
                        // Read four "meaningful" bytes:
                        int b = 0;
                        do {
                            b = in.read();
                        } while (b >= 0 && DECODABET[b & 0x7f] <= WHITE_SPACE_ENC);
                        if (b < 0){
                            break; // Reads a -1 if end of stream
                        }
                        b4[i] = (byte) b;
                    } // end for: each needed input byte
                    if (i == 4) {
                        numSigBytes = decode4to3(b4, 0, buffer, 0);
                        position = 0;
                        // end if: got four characters
                    } else if (i == 0) {
                        return -1;
                        // end else if: also padded correctly
                    } else {
                        // Must have broken out from above.
                        throw new java.io.IOException("Improperly padded Base64 input.");
                    } // end
                } // end else: decode
            } // end else: get data
            // Got data?
            if (position >= 0) {
                // End of relevant data?
                if (position >= numSigBytes){
                    return -1;
                }
                if (encode && breakLines && lineLength >= MAX_LINE_LENGTH) {
                    lineLength = 0;
                    return '\n';
                    // end if
                } else {
                    lineLength++; // This isn't important when decoding
                                    // but throwing an extra "if" seems
                                    // just as wasteful.
                    int b = buffer[position++];
                    if (position >= bufferLength){
                        position = -1;
                    }
                    return b & 0xFF; // This is how you "cast" a byte that's
                                        // intended to be unsigned.
                } // end else
                // end if: position >= 0
            } else {// Else error
                // When JDK1.4 is more accepted, use an assertion here.
                throw new java.io.IOException("Error in Base64 code reading stream.");
            } // end else
        } // end read
        /**
         * read
         * @return int
         */
        public int read(byte[] dest, int off, int len) throws java.io.IOException {
            int i;
            int b;
            for (i = 0; i < len; i++) {
                b = read();
                // if( b < 0 && i == 0 )
                // return -1;
                if (b >= 0){
                    dest[off + i] = (byte) b;
                }else if (i == 0){
                    return -1;
                }else{
                    break; // Out of 'for' loop
                }
            } // end for: each byte read
            return i;
        } // end read
    } // end inner class InputStream
    /**
     * å†…部类OutputStream
     * @ClassName  OutputStream
     * @Description  TODO
     * @author  jfli@woyitech.com
     * @date  2016å¹´5月27日 ä¸‹åˆ12:32:55
     */
    public static class OutputStream extends java.io.FilterOutputStream {
        /**
         * Encoding or decoding
         */
        private boolean encode;
        /**
         * Current position in the buffer
         */
        private int position;
        /**
         * Small buffer holding converted data
         */
        private byte[] buffer;
        /**
         * Length of buffer (3 or 4)
         */
        private int bufferLength;
        /**
         * lineLength
         */
        private int lineLength;
        /**
         *  Number of meaningful bytes in the buffer
         */
        private boolean breakLines;
        /**
         * Scratch used in a few places
         */
        private byte[] b4; //
        /**
         * suspendEncoding
         */
        private boolean suspendEncoding;
        /**
         * æž„造函数
         * @Title OutputStream
         * @Description TODO
         * @param out
         */
        public OutputStream(java.io.OutputStream out) {
            this(out, ENCODE);
        } // end constructor
        /**
         * æž„造函数
         * @Title OutputStream
         * @Description TODO
         * @param out
         */
        public OutputStream(java.io.OutputStream out, int options) {
            super(out);
            this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES;
            this.encode = (options & ENCODE) == ENCODE;
            this.bufferLength = encode ? 3 : 4;
            this.buffer = new byte[bufferLength];
            this.position = 0;
            this.lineLength = 0;
            this.suspendEncoding = false;
            this.b4 = new byte[4];
        } // end constructor
        /**
         * write
         */
        public void write(int theByte) throws java.io.IOException {
            // Encoding suspended?
            if (suspendEncoding) {
                super.out.write(theByte);
                return;
            } // end if: supsended
            // Encode?
            if (encode) {
                buffer[position++] = (byte) theByte;
                if (position >= bufferLength) {// Enough to encode.
                    out.write(encode3to4(b4, buffer, bufferLength));
                    lineLength += 4;
                    if (breakLines && lineLength >= MAX_LINE_LENGTH) {
                        out.write(NEW_LINE);
                        lineLength = 0;
                    } // end if: end of line
                    position = 0;
                } // end if: enough to output
                // end if: encoding
            } else {// Else, Decoding
                // Meaningful Base64 character?
                if (DECODABET[theByte & 0x7f] > WHITE_SPACE_ENC) {
                    buffer[position++] = (byte) theByte;
                    if (position >= bufferLength) {// Enough to output.
                        int len = Base64Util.decode4to3(buffer, 0, b4, 0);
                        out.write(b4, 0, len);
                        // out.write( Base64.decode4to3( buffer ) );
                        position = 0;
                    } // end if: enough to output
                     // end if: meaningful base64 character
                } else if (DECODABET[theByte & 0x7f] != WHITE_SPACE_ENC) {
                    throw new java.io.IOException("Invalid character in Base64 data.");
                } // end else: not white space either
            } // end else: decoding
        } // end write
        /**
         * write
         */
        public void write(byte[] theBytes, int off, int len) throws java.io.IOException {
            // Encoding suspended?
            if (suspendEncoding) {
                super.out.write(theBytes, off, len);
                return;
            } // end if: supsended
            for (int i = 0; i < len; i++) {
                write(theBytes[off + i]);
            } // end for: each byte written
        } // end write
        /**
         * flushBase64
         * @Title  flushBase64
         * @Description  TODO
         * @author  jfli@woyitech.com
         * @throws java.io.IOException
         * @return
         */
        public void flushBase64() throws java.io.IOException {
            if (position > 0) {
                if (encode) {
                    out.write(encode3to4(b4, buffer, position));
                    position = 0;
                } else {// end if: encoding
                    throw new java.io.IOException("Base64 input not properly padded.");
                } // end else: decoding
            } // end if: buffer partially full
        } // end flush
        /**
         * close
         */
        public void close() throws java.io.IOException {
            // 1. Ensure that pending characters are written
            flushBase64();
            // 2. Actually close the stream
            // Base class both flushes and closes.
            super.close();
            buffer = null;
            out = null;
        } // end close
        /**
         * suspendEncoding = true
         * @Title  suspendEncoding
         * @Description  TODO
         * @author  jfli@woyitech.com
         * @throws java.io.IOException
         * @return
         */
        public void suspendEncoding() throws java.io.IOException {
            flushBase64();
            this.suspendEncoding = true;
        } // end suspendEncoding
        /**
         * suspendEncoding = false
         * @Title  resumeEncoding
         * @Description  TODO
         * @author  jfli@woyitech.com
         * @return
         */
        public void resumeEncoding() {
            this.suspendEncoding = false;
        } // end resumeEncoding
    } // end inner class OutputStream
    // public static void main(String[] args) {
    //
    // String filePath = "F:\\test\\跨境电商事业部通讯录(合肥研发中心)-20140722.doc";
    //
    // String str = Base64Util.encodeFromFile(filePath);
    //
    // Base64Util.decodeToFile(str, "F:\\123.doc");
    // }
}
server/services/src/main/java/com/doumee/core/utils/ZbomAESUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,89 @@
package com.doumee.core.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
/**
 * å¯¹ç§°åР坆(AES)
 *
 * @author Joe
 */
public class ZbomAESUtils {
    public static final String INIT_VECTOR = "RandomInitVector";
    public static final String PRIVATE_KEY = "zbom20180922!@#$";
    /**
     * åР坆
     * @param key å¯†é’¥
     * @param value åŠ å¯†æ•°æ®
     * @return
     */
    public static String encrypt(String key, String value) {
        try {
            IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(value.getBytes());
            return Base64Util.encodeBytes(encrypted);
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
    /**
     * è§£å¯†
     * @param key å¯†é’¥
     * @param encrypted è§£å¯†æ•°æ®
     * @return
     */
    public static String decrypt(String key, String encrypted) {
        try {
            IvParameterSpec iv = new IvParameterSpec(INIT_VECTOR.getBytes("UTF-8"));
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] original = cipher.doFinal(Base64Util.decode(encrypted));
            return new String(original);
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
    public static void main(String[] args) {
        String str = "2[{\"broleName\":\"仓管员\",\"broleStatus\":\"Y\",\"operType\":\"0\",\"bonlyId\":842},{\"broleName\":\"网速测试\",\"broleStatus\":\"Y\",\"operType\":\"0\",\"bonlyId\":1282}]2019-01-11 11:59:07crmzbom20180922!@#$";
//        System.out.println(str);
//        System.out.println(MD5.string2MD5(str).toUpperCase());
        String var = "Xrz4%2Fe1h3pbiLGfVlWYIM3VOMLDjJHkQSLSSErQRiS5vWgG%2B0sGXCQLaIW4Uod1izlp6RKC0K74P%0A1%2BzmgNK7ow%3D%3D";
        //System.out.println(URLEncoder.encode("Xrz4%2Fe1h3pbiLGfVlWYIM12Vj0GtMaZ79IujEd4WNgM4d9QZcv%2BaqOzl%2FR2K%2Fs%2FVaAWS2OleN2uV%0A3lzglMli5g%3D%3D"));
        String key = "zbom20180922!@#$"; // 128 bit key
        Map resultMap = new HashMap();
        resultMap.put("ssouserid", 499);
        resultMap.put("appid", 2);
        resultMap.put("entranceid", 4);
//        System.out.println((URLDecoder.decode("PLFONVn89T%2FbNZKGRbMQaB9wYdaUNh1Wp88cfDBKykVXjdNH4CmfReijn6tl2i98CgyspshTTvg%2F%0AenRyPuIS4g%3D%3D")));
//        System.out.println(URLDecoder.decode("Yu9FRXlPGZ6m4HXRhOsAOrfjRM384t%2FcEwtCtKhoyH3ETT83r3g4CWOc38PdcYRig2xXZNHHhLWu%0At7FNn%2FRjKQ%3D%3D"));
        System.out.println(ZbomAESUtils.decrypt(ZbomAESUtils.PRIVATE_KEY, URLDecoder.decode(var)));
        //System.out.println("------------>"+AESUtils.decrypt(AESUtils.PRIVATE_KEY, URLDecoder.decode("Yu9FRXlPGZ6m4HXRhOsAOuaM5QFPc0%2BV7yrYkGE2GgAZOfxMV2hdIgjKFy%2Bg%2BO816e6d4oOI6Zeh%0AJxt4tJZswhoSTG%2FW7uUU4AEKoJhoRMU%3D")));
    }
}
server/services/src/main/java/com/doumee/dao/business/model/Category.java
@@ -42,7 +42,7 @@
    @ApiModelProperty(value = "创建时间")
    @ExcelColumn(name="创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @ApiModelProperty(value = "更新人编码", example = "1")
@@ -51,7 +51,7 @@
    @ApiModelProperty(value = "更新时间")
    @ExcelColumn(name="更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    @ApiModelProperty(value = "备注")
server/services/src/main/java/com/doumee/dao/system/dto/DingLoginDTO.java
@@ -12,7 +12,7 @@
 * @since 2025/03/31 16:44
 */
@Data
@ApiModel("登录参数")
@ApiModel("钉钉授权登录入参")
public class DingLoginDTO implements Serializable {
    @NotBlank(message = "code不能为空")
server/services/src/main/java/com/doumee/dao/system/dto/DingTalkLoginDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.doumee.dao.system.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
 * @author  dm
 * @since 2025/03/31 16:44
 */
@Data
@ApiModel("钉钉授权按登录参数")
public class DingTalkLoginDTO implements Serializable {
    @NotBlank(message = "code不能为空")
    @ApiModelProperty(value = "code")
    private String code;
}
server/services/src/main/java/com/doumee/dao/system/dto/LoginDTO.java
@@ -30,4 +30,10 @@
    @NotBlank(message = "验证码UUID不能为空")
    @ApiModelProperty(value = "验证码UUID")
    private String uuid;
    @ApiModelProperty(value = "unionId")
    private String unionId;
}
server/services/src/main/java/com/doumee/dao/system/model/SystemUser.java
@@ -85,4 +85,7 @@
    @ApiModelProperty(value = "是否已删除", hidden = true)
    private Boolean deleted;
    @ApiModelProperty(value = "钉钉 unionId", hidden = true)
    private String unionId;
}
server/services/src/main/java/com/doumee/dao/vo/WebLoginUserVO.java
@@ -19,8 +19,8 @@
    @ApiModelProperty(value = "用户主键")
    private String id;
    @ApiModelProperty(value = "用户角色:   (dUser:标记为钉钉用户)")
    private String roleType;
    @ApiModelProperty(value = "是否显示费用信息:0=不显示;1=显示")
    private Integer showFee;
    @ApiModelProperty(value = "战区编码")
    private String zhanqu;
server/services/src/main/java/com/doumee/dao/vo/ZhanQuVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.doumee.dao.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Rk
 * @create 2026/2/3 15:42
 */
@Data
public class ZhanQuVO {
    @ApiModelProperty(value = "战区编码")
    private String nodeCode;
    @ApiModelProperty(value = "战区名称")
    private String nodeName;
    @ApiModelProperty(value = "战区状态:")
    private String nodeStatus;
}
server/services/src/main/java/com/doumee/service/business/CategoryService.java
@@ -3,6 +3,8 @@
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.dao.business.model.Category;
import java.io.IOException;
import java.util.List;
/**
@@ -96,5 +98,11 @@
    long count(Category category);
    List<Category> getCategoryList(Integer type);
    List<Category> getCategoryList(Integer type,Integer rank);
    /**
     * æˆ˜åŒºä¿¡æ¯åŒæ­¥
     * @throws IOException
     */
    void syncZhanQu() throws IOException;
}
server/services/src/main/java/com/doumee/service/business/MemberService.java
@@ -97,6 +97,6 @@
     */
    long count(Member model);
    Member findDetailById(Integer id,String queryUserRole);
    Member findDetailById(Integer id);
}
server/services/src/main/java/com/doumee/service/business/impl/CategoryServiceImpl.java
@@ -6,6 +6,7 @@
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.iPass.IPass;
import com.doumee.core.model.LoginUserInfo;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
@@ -15,6 +16,7 @@
import com.doumee.dao.business.model.Category;
import com.doumee.dao.business.model.Multifile;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.dao.vo.ZhanQuVO;
import com.doumee.service.business.CategoryService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -23,6 +25,7 @@
import com.github.yulichang.base.MPJBaseMapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.math3.analysis.function.Log;
import org.apache.shiro.SecurityUtils;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
@@ -30,10 +33,12 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * åˆ†ç±»ä¿¡æ¯è¡¨Service实现
@@ -62,6 +67,17 @@
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        if(Constants.equalsInteger(category.getType(),Constants.ZERO)){
            if(categoryMapper.selectCount(new QueryWrapper<Category>().lambda()
                    .eq(Category::getType,Constants.ZERO)
                    .eq(Category::getDetail,category.getDetail())
                    .eq(Category::getDeleted,Constants.ZERO)
            )>Constants.ZERO){
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"该战区编码已存在");
            }
        }
        category.setDeleted(Constants.ZERO);
        category.setCreateTime(new Date());
        category.setCreateUser(loginUserInfo.getId());
@@ -127,12 +143,31 @@
        ){
            throw new BusinessException(ResponseStatus.BAD_REQUEST);
        }
        if(Constants.equalsInteger(category.getType(),Constants.ZERO)){
            if(categoryMapper.selectCount(new QueryWrapper<Category>().lambda()
                    .eq(Category::getType,Constants.ZERO)
                    .eq(Category::getDetail,category.getDetail())
                    .eq(Category::getDeleted,Constants.ZERO)
                    .ne(Category::getId,category.getId())
            )>Constants.ZERO){
                throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"该战区编码已存在");
            }
        }
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        category.setUpdateTime(new Date());
        category.setIsFixed(null);
        category.setUpdateUser(loginUserInfo.getId());
        categoryMapper.updateById(category);
        if(Objects.isNull(category.getSortnum())){
            categoryMapper.update(null,new UpdateWrapper<Category>().lambda()
                    .set(Category::getSortnum,null)
                    .eq(Category::getId,category.getId())
            );
        }
        dealBatchMultiFiles(category, category.getFileList(), loginUserInfo,true);
    }
    @Override
    public void updateStatus(Category category) {
@@ -234,6 +269,7 @@
            queryWrapper.eq(Category::getIsFixed, pageWrap.getModel().getIsFixed());
        }
        queryWrapper.orderByAsc(Category::getSortnum);
        queryWrapper.orderByAsc(Category::getId);
        PageData<Category> result =PageData.from(categoryMapper.selectJoinPage(page, Category.class,queryWrapper));
        if(result!=null && result.getRecords()!=null){
            String path  = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.RESOURCE_PATH).getCode()
@@ -277,20 +313,19 @@
    }
    @Override
    public List<Category> getCategoryList(Integer type){
    public List<Category> getCategoryList(Integer type,Integer rank){
        List<Category> categoryList = categoryMapper.selectList(new QueryWrapper<Category>().lambda().eq(Category::getDeleted,Constants.ZERO).eq(Category::getStatus,Constants.ZERO)
                .eq(Objects.nonNull(type),Category::getType,type)
                .apply(Objects.nonNull(rank)&&Constants.equalsInteger(rank,Constants.ONE)," id in ( " +
                        " select m.obj_id from multifile m where m.ISDELETED = 0 and m.OBJ_TYPE = 0  " +
                        " ) ")
                .orderByAsc(Category::getSortnum)
                .orderByAsc(Category::getId)
        );
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(categoryList)){
            String path  = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.RESOURCE_PATH).getCode()
                    +systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE,Constants.CATEGORY_FILES).getCode();
            for (Category category:categoryList) {
                if(StringUtils.isNotBlank(category.getIcon())){
                    category.setIconFull(path + category.getIcon());
                }
                if(Constants.equalsInteger(category.getType(),Constants.ONE) ){
                    initMultifileList(category);
            for(Category cate : categoryList){
                if(Constants.equalsInteger(cate.getType(),Constants.ONE) ){
                    initMultifileList(cate);
                }
            }
        }
@@ -298,4 +333,58 @@
    }
    @Override
    @Transactional(rollbackFor = {Exception.class,BusinessException.class})
    public void syncZhanQu() throws IOException {
        LoginUserInfo loginUserInfo = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        IPass iPass = new IPass();
        List<ZhanQuVO> l =  iPass.getIPassZhanquList();
        List<Category> categoryList = categoryMapper.selectList(new QueryWrapper<Category>().lambda()
                .eq(Category::getType,Constants.ZERO)
                .eq(Category::getDeleted,Constants.ZERO)
        );
        List<Category> updList = new ArrayList<>();
        List<Category> addList = new ArrayList<>();
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(l)){
            for (ZhanQuVO zhanQuVO:l) {
                Category category = this.vaildData(zhanQuVO,categoryList,loginUserInfo);
                if(Objects.isNull(category.getId())){
                    addList.add(category);
                }else{
                    updList.add(category);
                }
            }
        }
        if (com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(addList)) {
            categoryMapper.insertOrUpdate(addList);
        }
        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(updList)){
            categoryMapper.insertOrUpdate(updList);
        }
    }
    public Category vaildData(ZhanQuVO zhanQuVO , List<Category> categoryList, LoginUserInfo userInfo) {
        Category returnData = new Category();
        for (Category category:categoryList) {
            if(category.getDetail().equals(zhanQuVO.getNodeCode())){
                returnData = category   ;
                returnData.setName(zhanQuVO.getNodeName());
                returnData.setUpdateUser(userInfo.getId());
                returnData.setUpdateTime(new Date());
                return returnData;
            }
        }
        returnData.setDetail(zhanQuVO.getNodeCode());
        returnData.setCreateTime(new Date());
        returnData.setDeleted(Constants.ZERO);
        returnData.setStatus(zhanQuVO.getNodeStatus().equals("Y")?Constants.ZERO:Constants.ONE);
        returnData.setName(zhanQuVO.getNodeName());
        returnData.setCreateUser(userInfo.getId());
        returnData.setType(Constants.ZERO);
        returnData.setIsFixed(Constants.ZERO);
        return returnData;
    }
}
server/services/src/main/java/com/doumee/service/business/impl/ImportRecordServiceImpl.java
@@ -159,8 +159,8 @@
       queryWrapper.eq(pageWrap.getModel().getDoneNum() != null,ImportRecord::getDoneNum, pageWrap.getModel().getDoneNum());
       queryWrapper.eq(pageWrap.getModel().getErrorNum() != null,ImportRecord::getErrorNum, pageWrap.getModel().getErrorNum());
       queryWrapper.like(StringUtils.isNotBlank(pageWrap.getModel().getUpdateUserName()),SystemUser::getRealname, pageWrap.getModel().getUpdateUserName());
       queryWrapper.ge(pageWrap.getModel().getEndtime() != null,ImportRecord::getCreateTime, pageWrap.getModel().getEndtime());
       queryWrapper.ne(pageWrap.getModel().getStarttime() != null,ImportRecord::getCreateTime, pageWrap.getModel().getStarttime());
       queryWrapper.ge(pageWrap.getModel().getStarttime() != null,ImportRecord::getCreateTime, pageWrap.getModel().getStarttime());
       queryWrapper.le(pageWrap.getModel().getEndtime() != null,ImportRecord::getCreateTime, pageWrap.getModel().getEndtime());
       queryWrapper.orderByDesc(ImportRecord::getId);
        return PageData.from(importRecordMapper.selectPage(page, queryWrapper));
    }
@@ -180,7 +180,7 @@
        try {
            List<Category> categoryList = null;
            if(type == 0){
              categoryList = categoryMapper.selectList(new QueryWrapper<Category>().lambda().eq(Category::getDeleted,Constants.ZERO));
              categoryList = categoryMapper.selectList(new QueryWrapper<Category>().lambda().eq(Category::getDeleted,Constants.ZERO).eq(Category::getStatus,Constants.ZERO));
                if(categoryList == null || categoryList.size()==0){
                    throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起, è¯»å–老师基数数据配置出错,请先配置基础数据信息!");
                }
@@ -289,9 +289,13 @@
             if(StringUtils.isBlank(param.getTypeNames())){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, å•†ä¸šåŒ–类型信息不能为空");
             }
             if(StringUtils.isBlank(param.getFieldNames())){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, æ“…长领域信息不能为空");
             }
             if(StringUtils.isBlank(param.getFee())){
                 throw  new BusinessException(ResponseStatus.BAD_REQUEST.getCode(),"对不起,第"+index+"行数据, è´¹ç”¨æ ‡å‡†ä¿¡æ¯ä¸èƒ½ä¸ºç©º");
             }
          /*   if(pics!=null && StringUtils.isNotBlank(param.getImgurl())){
                log.info("===================="+param.getImgurl());
                int start = param.getImgurl().indexOf("(\"")+2;
@@ -340,7 +344,8 @@
                 member.setFee(new BigDecimal(param.getFee()));
             }catch (Exception e){
             }
             member.setSex(StringUtils.equals(param.getSex(),"男")?Constants.ZERO:(StringUtils.equals(param.getSex(),"女")?Constants.ZERO:null));
             member.setSex(StringUtils.equals(param.getSex(),"男")?Constants.ZERO:
                     (StringUtils.equals(param.getSex(),"女")?Constants.ONE:null));
             member.setZhanquIds(getIdStrListByList(list0));
             member.setBustypeIds(getIdStrListByList(list1));
             member.setFieldIds(getIdStrListByList(list2));
server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
@@ -214,22 +214,23 @@
        Utils.MP.blankToNull(pageWrap.getModel());
        Member model = pageWrap.getModel();
        queryWrapper.selectAll(Member.class)
                .selectAs(Category::getName, Member::getLevelName)
                .select("t2.`NAME`", Member::getLevelName)
                .selectAs(SystemUser::getRealname, Member::getUpdateUserName)
                .leftJoin(SystemUser.class,SystemUser::getId,Member::getUpdateUser)
                .leftJoin(Category.class,Category::getId,Member::getLevelId)
                .apply(Objects.nonNull(model.getBustypeIds())," find_in_set( '["+model.getBustypeIds()+"]', t.BUSTYPE_IDS ) ")
//                .leftJoin(Category.class,Category::getId,Member::getLevelId)
                .leftJoin(" ( select c.* from category c  where c.deleted = 0 and c.status = 0 and c.type = 3  )   t2  on t.level_id = t2.id   ")
//                .apply(Objects.nonNull(model.getBustypeIds())," find_in_set( '["+model.getBustypeIds()+"]', t.BUSTYPE_IDS ) ")
                .apply(Objects.nonNull(model.getZhanquIds())," find_in_set( '["+model.getZhanquIds()+"]', t.ZHANQU_IDS ) ")
                .like(StringUtils.isNotBlank(model.getName()),Member::getName, model.getName())
                .eq(Objects.nonNull(model.getImportId()),Member::getImportId, model.getImportId())
                .eq(Objects.nonNull(model.getStatus()),Member::getStatus, model.getStatus())
                .eq(model.getContainDeleted()!=1,Member::getDeleted, Constants.ZERO)
                .in(Objects.nonNull(model.getLevelId()),Category::getId, model.getLevelId())
                .in(Objects.nonNull(model.getLevelId()),"t1.id", model.getLevelId())
                .eq(Objects.nonNull(model.getCode()),Member::getCode, model.getCode())
                .orderByDesc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.ZERO),Member::getFee)
                .orderByAsc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.ONE),Member::getFee)
                .orderByDesc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.TWO),Category::getDetail)
                .orderByAsc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.THREE),Category::getDetail)
                .orderByDesc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.TWO),"t2.SORTNUM")
                .orderByAsc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.THREE),"t2.SORTNUM")
                .orderByDesc(Objects.nonNull(model.getOrderByType())&&Constants.equalsInteger(model.getOrderByType(), Constants.FOUR),Member::getServeNum)
                .orderByDesc(Member::getId)
        ;
@@ -244,6 +245,17 @@
            }
            queryWrapper.apply(sql);
        }
        if(CollectionUtils.isNotEmpty(model.getBustypeIdList())){
            String sql = "";
            for (Integer s:model.getBustypeIdList()
            ) {
                sql = sql + (StringUtils.isNotBlank(sql)?" or ":"") + " find_in_set( '["+s+"]' , t.BUSTYPE_IDS ) ";
            }
            queryWrapper.apply(sql);
        }
        if (StringUtils.isNotBlank(model.getQueryZQCode())) {
            Category zhanqu = categoryMapper.selectOne(new QueryWrapper<Category>().lambda()
                    .eq(Category::getDeleted,Constants.ZERO)
@@ -310,7 +322,7 @@
    @Override
    public Member findDetailById(Integer id,String userRole) {
    public Member findDetailById(Integer id) {
        Member member = memberMapper.selectJoinOne(Member.class, new MPJLambdaWrapper<Member>()
                .selectAll(Member.class)
                .select(" c1.NAME ", Member::getPromotionName)
@@ -334,17 +346,28 @@
           );
       }
        List<Category> categoryList = categoryMapper.selectList(new QueryWrapper<Category>().lambda()
                        .eq(Category::getDeleted, Constants.ZERO)
//                    .eq(Category::getType,Constants.TWO)
                        .orderByAsc(Category::getSortnum)
        );
        if(CollectionUtils.isNotEmpty(categoryList)){
            dealMemberField(member,categoryList);
            dealMemberCategoryList(member, categoryList,Constants.ONE);
        }
        String resourcePath = systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.RESOURCE_PATH).getCode();
        String path =  systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.MEMBER_FILES).getCode();
        String roleConfig = systemDictDataBiz.queryByCode(Constants.SYSTEM, Constants.ROLE_CONFIG).getCode();
        member.setFullImgurl(StringUtils.isNotBlank(member.getImgurl())?(resourcePath  + path + member.getImgurl()):"");
        List<Cases> casesList = casesMapper.selectList(new QueryWrapper<Cases>().lambda()
                .eq(Cases::getMemberId,member.getId())
                .eq(Cases::getDeleted,Constants.ZERO)
                .eq(Cases::getStatus,Constants.ZERO)
                .orderByDesc(Cases::getStartDate)
                .orderByDesc(Cases::getId)
        );
        if(CollectionUtils.isNotEmpty(casesList)){
            String casePath =  systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.CATEGORY_FILES).getCode();
            String casePath =  systemDictDataBiz.queryByCode(Constants.OBJCET_STORAGE, Constants.CASES_FILES).getCode();
            for (Cases cases:casesList) {
                List<Multifile> multifileList = multifileMapper.selectList(new QueryWrapper<Multifile>().lambda()
                        .eq(Multifile::getObjId,cases.getId())
@@ -358,10 +381,6 @@
                cases.setFileList(multifileList);
            }
            member.setCasesList(casesList);
        }
        if(StringUtils.isBlank(roleConfig)||StringUtils.isBlank(userRole)
                || !(roleConfig.contains(userRole)||userRole.equals(Constants.DD_USER_TYPE) )){
            member.setFee(null);
        }
        return member;
    }
server/services/src/main/java/com/doumee/service/system/SystemLoginService.java
@@ -1,8 +1,11 @@
package com.doumee.service.system;
import com.doumee.dao.system.dto.DingLoginDTO;
import com.doumee.dao.system.dto.LoginDTO;
import com.taobao.api.ApiException;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
 * ç³»ç»Ÿç™»å½•
@@ -19,4 +22,6 @@
     * @return String
     */
    String loginByPassword (LoginDTO dto, HttpServletRequest request);
    Map<String,Object> loginByDingTalk(DingLoginDTO dingLoginDTO, HttpServletRequest request) throws ApiException;
}
server/services/src/main/java/com/doumee/service/system/SystemUserService.java
@@ -1,10 +1,12 @@
package com.doumee.service.system;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.dao.system.dto.QuerySystemUserDTO;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.dao.system.vo.SystemUserListVO;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import java.util.List;
@@ -44,6 +46,8 @@
     */
    void updateById(SystemUser systemUser);
    void updateByWrapper(LambdaUpdateWrapper wrapper);
    /**
     * æ‰¹é‡ä¸»é”®æ›´æ–°
     *
server/services/src/main/java/com/doumee/service/system/impl/SystemLoginServiceImpl.java
@@ -1,14 +1,26 @@
package com.doumee.service.system.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dingtalk.api.response.OapiV2UserGetuserinfoResponse;
import com.doumee.config.shiro.ShiroToken;
import com.doumee.core.constants.Constants;
import com.doumee.core.dingTalk.DingTalk;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.model.LoginUserInfo;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.utils.Utils;
import com.doumee.dao.system.SystemUserMapper;
import com.doumee.dao.system.dto.DingLoginDTO;
import com.doumee.dao.system.dto.DingTalkLoginDTO;
import com.doumee.dao.system.dto.LoginDTO;
import com.doumee.dao.system.model.SystemLoginLog;
import com.doumee.dao.system.model.SystemUser;
import com.doumee.service.common.CaptchaService;
import com.doumee.service.system.SystemLoginLogService;
import com.doumee.service.system.SystemLoginService;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
@@ -21,6 +33,9 @@
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Service
@@ -40,8 +55,16 @@
    @Autowired
    private SystemLoginLogService systemLoginLogService;
    @Autowired
    private DingTalk dingTalk ;
    @Autowired
    private SystemUserMapper systemUserMapper;
    @Override
    public String loginByPassword(LoginDTO dto, HttpServletRequest request) {
        log.error("登录入参:"+ JSONObject.toJSONString(dto));
        SystemLoginLog loginLog = new SystemLoginLog();
        loginLog.setLoginUsername(dto.getUsername());
        loginLog.setLoginTime(new Date());
@@ -66,7 +89,81 @@
        }
        // æ ¡éªŒç”¨æˆ·åå’Œå¯†ç 
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(dto.getUsername(), dto.getPassword());
        ShiroToken token = new ShiroToken(null,dto.getUsername(), dto.getPassword(),false);
        try {
            subject.login(token);
            loginLog.setUserId(((LoginUserInfo)subject.getPrincipal()).getId());
            loginLog.setSuccess(Boolean.TRUE);
            systemLoginLogService.create(loginLog);
            if(StringUtils.isNotBlank(dto.getUnionId())){
                //更新用户的unionID
                this.dealDDUnionIdBiz(loginLog.getUserId(), dto.getUnionId());
            }
            return (String)subject.getSession().getId();
        } catch (AuthenticationException e) {
            log.error(ResponseStatus.ACCOUNT_INCORRECT.getMessage(), e);
            loginLog.setReason(e.getMessage().length() > 200 ? (e.getMessage().substring(0, 190) + "...") : e.getMessage());
            loginLog.setSuccess(Boolean.FALSE);
            systemLoginLogService.create(loginLog);
            throw new BusinessException(ResponseStatus.ACCOUNT_INCORRECT);
        }
    }
    private void dealDDUnionIdBiz(Integer userId, String ddUnionId) {
        if(StringUtils.isNotBlank(ddUnionId)){
            //如果openId不为空,绑定该用户openid
            systemUserMapper.update(null,new UpdateWrapper<SystemUser>().lambda()
                    .set(SystemUser::getUnionId,null)
                    .eq(SystemUser::getUnionId,ddUnionId)
            );
            systemUserMapper.update(null,new UpdateWrapper<SystemUser>().lambda()
                    .set(SystemUser::getUnionId,ddUnionId)
                    .eq(SystemUser::getId,userId));
        }
    }
    @Override
    public Map<String,Object> loginByDingTalk(DingLoginDTO dingLoginDTO, HttpServletRequest request) throws ApiException {
        log.error("授权钉钉登录入参:"+ JSONObject.toJSONString(dingLoginDTO));
        Map<String,Object> map = new HashMap<>();
        OapiV2UserGetuserinfoResponse.UserGetByCodeResponse response = dingTalk.getDDUserByCode(dingLoginDTO);
        if(Objects.nonNull(response)){
            String unionId = response.getUnionid();
            map.put("unionId",unionId);
            map.put("loginStatus",false);
            SystemUser systemUser = systemUserMapper.selectOne(new QueryWrapper<SystemUser>().lambda().eq(SystemUser::getUnionId,unionId)
                    .last("limit 1")
            );
            if(Objects.nonNull(systemUser)&&!systemUser.getDeleted()){
                loginByDingTalkCode(systemUser,unionId,request);
                map.put("loginStatus",true);
            }
        }
        log.error("授权钉钉登录出参:"+ JSONObject.toJSONString(map));
        return map;
    }
    public String loginByDingTalkCode(SystemUser systemUser,String unionId, HttpServletRequest request) {
        SystemLoginLog loginLog = new SystemLoginLog();
        loginLog.setLoginUsername(systemUser.getUsername());
        loginLog.setLoginTime(new Date());
        loginLog.setSystemVersion(systemVersion);
        loginLog.setIp(Utils.User_Client.getIP(request));
//        loginLog.setLocation(Utils.Location.getLocationString(loginLog.getIp()));
        loginLog.setPlatform(Utils.User_Client.getPlatform(request));
        loginLog.setClientInfo(Utils.User_Client.getBrowser(request));
        loginLog.setOsInfo(Utils.User_Client.getOS(request));
        loginLog.setServerIp(Utils.Server.getIP());
        // æ ¡éªŒç”¨æˆ·åå’Œå¯†ç 
        Subject subject = SecurityUtils.getSubject();
        ShiroToken token = new ShiroToken(unionId,systemUser.getUsername(), null,true);
        try {
            subject.login(token);
            loginLog.setUserId(((LoginUserInfo)subject.getPrincipal()).getId());
@@ -81,4 +178,6 @@
            throw new BusinessException(ResponseStatus.ACCOUNT_INCORRECT);
        }
    }
}
server/services/src/main/java/com/doumee/service/system/impl/SystemUserServiceImpl.java
@@ -1,5 +1,7 @@
package com.doumee.service.system.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.doumee.core.model.PageData;
@@ -62,6 +64,12 @@
    }
    @Override
    public void updateByWrapper(LambdaUpdateWrapper wrapper) {
        systemUserMapper.update(null,wrapper);
    }
    @Override
    @Transactional
    public void updateByIdInBatch(List<SystemUser> systemUsers) {
        if (CollectionUtils.isEmpty(systemUsers)) return;
server/web/src/main/java/com/doumee/api/web/LoginController.java
@@ -1,6 +1,8 @@
package com.doumee.api.web;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.api.response.OapiV2UserGetuserinfoResponse;
import com.doumee.api.BaseController;
@@ -11,13 +13,18 @@
import com.doumee.core.annotation.pr.PreventRepeat;
import com.doumee.core.annotation.trace.Trace;
import com.doumee.core.constants.Constants;
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.dingTalk.DingTalk;
import com.doumee.core.exception.BusinessException;
import com.doumee.core.model.ApiResponse;
import com.doumee.core.model.LoginUserInfo;
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.core.utils.AESUtils;
import com.doumee.core.utils.HttpsUtil;
import com.doumee.core.utils.ZbomAESUtils;
import com.doumee.dao.business.dto.LoginRequestNewParam;
import com.doumee.dao.business.dto.RoleRequestParam;
import com.doumee.dao.business.model.Category;
import com.doumee.dao.business.model.Member;
import com.doumee.dao.system.dto.DingLoginDTO;
@@ -82,19 +89,31 @@
        LoginRequestNewParam requestParam = new LoginRequestNewParam();
        // UK_ERROR_URL = "http://u.zhibang.com/sso/web/token/error";
        String errorUrl =systemDictDataBiz.queryByCode(Constants.ZBOM_PARAM,Constants.ZBOM_UK_ERROR_URL).getCode();
       /* try {
        String token = "";
        try {
            log.error("请求参数TICK最原始===========:" + tick);
            JSONObject urlParams = new JSONObject();
            log.info("请求参数:" + JSON.toJSONString(urlParams));
            //TICKET_LOGIN_TEST = "http://testsso.zhibang.com:8080/esc-idm/api/v1/getUserInfo";
            //TICKET_LOGIN = "https://sso.zbom.com/esc-idm/api/v1/getUserInfo";
            String url  = systemDictDataBiz.queryByCode(Constants.ZBOM_PARAM,Constants.ZBOM_TICKET_LOGIN_URL).getCode() + "?tick=" +  URLEncoder.encode(tick,Constants.UTF);
            String post =  HttpsUtil.get(url,true);
            String post =  HttpUtil.get(url);
            log.info("返回参数:" + post);
            JSONObject json = JSONObject.parseObject(post);
            if (StringUtils.equals(json.getString("code"), "0")) {
                JSONObject userInfo = json.getJSONObject("data");
                requestParam = JSONObject.toJavaObject(userInfo, LoginRequestNewParam.class);
            if (StringUtils.equals(json.getString("code"), "1")) {
                String dataE = json.getString("data");
                //反解析token
                String data =  ZbomAESUtils.decrypt( "zbom20180922!@#$",dataE);
                JSONObject userInfo = JSONObject.parseObject(data);
                log.error("U客登录返回参数:" + userInfo.toString());
                WebLoginUserVO loginUserVO = new WebLoginUserVO();
                loginUserVO.setId(userInfo.getString("buserPhone"));
                if(userInfo.getString("distrcode").isEmpty()){
                    loginUserVO.setShowFee(Constants.ONE);
                }else{
                    JSONArray jsonArray = userInfo.getJSONArray("ukRoles");
                    this.setLoginShowFee(loginUserVO,jsonArray);
                }
                log.error("web用户信息"+JSONObject.toJSONString(loginUserVO));
                token = jwtTokenUtil.generateToken(loginUserVO);
            } else {
                log.error("案例库系统单点登录失败 é”™è¯¯åŽŸå› èŽ·å–tick失败" + json.getString("message"));
                response.sendRedirect(errorUrl + "?title=" + enCode("登陆错误") + "&msg="+ enCode(json.getString("message")));
@@ -104,24 +123,46 @@
            log.error("ticket接口请求错误:" + e.getMessage());
            response.sendRedirect(errorUrl + "?title=" + enCode("登陆错误") + "&msg=" + enCode("系统繁忙,请稍后重试~"));
            return;
        }*/
        requestParam.setRediUrl("http://localhost:10087/#/login");
        WebLoginUserVO loginUserVO = new WebLoginUserVO();
        loginUserVO.setId("123");
        loginUserVO.setRoleType("admin");
        loginUserVO.setZhanqu("1");
        String token = jwtTokenUtil.generateToken(loginUserVO);
        }
        requestParam.setRediUrl("https://test.doumee.cn/h5/");
        log.error("跳转地址跳转信息:" + requestParam.getRediUrl()+"?token="+token);
        response.sendRedirect(requestParam.getRediUrl()+"?token="+token);
    }
    public void setLoginShowFee(WebLoginUserVO loginUserVO,JSONArray jsonArray){
        String roleConfig = systemDictDataBiz.queryByCode(Constants.SYSTEM, Constants.ROLE_CONFIG).getCode();
        loginUserVO.setShowFee(Constants.ZERO);
        if(StringUtils.isBlank(roleConfig)){
            return;
        }
        if(jsonArray.isEmpty()){
            return;
        }
        String [] configRole = roleConfig.split(",");
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject  j = jsonArray.getJSONObject(i);
            for (String s:configRole) {
                if(s.equals(j.getString("frontroleid"))){
                    loginUserVO.setShowFee(Constants.ONE);
                    return;
                }
            }
        }
    }
    @ApiOperation("钉钉登录")
    @PostMapping("/ddLogin")
    public ApiResponse<WebLoginUserVO> ddLogin(@Validated @RequestBody DingLoginDTO dingLoginDTO)  throws ApiException {
    public ApiResponse<WebLoginUserVO> ddLogin(@RequestBody DingLoginDTO dingLoginDTO)  throws ApiException {
        WebLoginUserVO loginUserVO = new WebLoginUserVO();
        log.error("钉钉授权登录入参:"+JSONObject.toJSONString(dingLoginDTO));
        System.out.println("钉钉授权登录入参:"+JSONObject.toJSONString(dingLoginDTO));
        OapiV2UserGetuserinfoResponse.UserGetByCodeResponse response = dingTalk.getDDUserByCode(dingLoginDTO);
        log.error("钉钉授权登录返参:"+JSONObject.toJSONString(response));
        System.out.println("钉钉授权登录返参:"+JSONObject.toJSONString(response));
        if(Objects.nonNull(response)){
            loginUserVO.setId(response.getUserid());
            loginUserVO.setRoleType(Constants.DD_USER_TYPE);
            loginUserVO.setShowFee(Constants.ONE);
        }
        loginUserVO.setToken(jwtTokenUtil.generateToken(loginUserVO));
        return ApiResponse.success(loginUserVO);
@@ -148,21 +189,22 @@
    })
    public ApiResponse<PageData<Member>> memberPage(@RequestBody PageWrap<Member> pageWrap) {
        WebLoginUserVO loginUserVO = this.getMemberResponse();
        pageWrap.getModel().setQueryUserRole(loginUserVO.getRoleType());
        log.error("分页查询用户信息"+JSONObject.toJSONString(loginUserVO));
        pageWrap.getModel().setQueryZQCode(loginUserVO.getZhanqu());
        PageData<Member> pageData = memberService.findPage(pageWrap);
        if(CollectionUtils.isNotEmpty(pageData.getRecords())){
            String roleConfig = systemDictDataBiz.queryByCode(Constants.SYSTEM, Constants.ROLE_CONFIG).getCode();
            if(StringUtils.isBlank(roleConfig)||StringUtils.isBlank(pageWrap.getModel().getQueryUserRole())
                    || ! (roleConfig.contains(pageWrap.getModel().getQueryUserRole()) || pageWrap.getModel().getQueryUserRole().equals(Constants.DD_USER_TYPE) )){
            log.error("分页数据信息"+JSONObject.toJSONString(pageData.getRecords()));
            if(Constants.equalsInteger(Constants.ZERO,loginUserVO.getShowFee())){
                log.error("分页数据信息清空金额");
                pageData.getRecords().forEach(i->{
                    i.setFee(null);
                });
            }
            log.error("分页数据信息清空后数据"+JSONObject.toJSONString(pageData.getRecords()));
        }
        return ApiResponse.success(pageData);
    }
    @LoginRequired
@@ -173,7 +215,11 @@
    })
    public ApiResponse<Member> memberPage(@RequestParam Integer id) {
        WebLoginUserVO loginUserVO = this.getMemberResponse();
        return ApiResponse.success(memberService.findDetailById(id,loginUserVO.getRoleType()));
        Member member = memberService.findDetailById(id);
        if(Objects.nonNull(member)&&Constants.equalsInteger(Constants.ZERO,loginUserVO.getShowFee())){
            member.setFee(null);
        }
        return ApiResponse.success(member);
    }
@@ -183,8 +229,8 @@
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "用户token值", required = true),
    })
    public ApiResponse<List<Category>> categoryList(@RequestParam Integer type) {
        return ApiResponse.success(categoryService.getCategoryList(type));
    public ApiResponse<List<Category>> categoryList(@RequestParam Integer type,Integer rank) {
        return ApiResponse.success(categoryService.getCategoryList(type,rank));
    }