3
0

48 Commity edd9bff632 ... df2f63efe4

Autor SHA1 Správa Dátum
  zhouxianguang df2f63efe4 去掉注释代码 6 rokov pred
  zhouxianguang 70a8b86181 添加打印日志调试 6 rokov pred
  zhouxianguang f97a200952 添加uids字段 6 rokov pred
  zhouxianguang 851d48b268 添加日志调试 6 rokov pred
  zhouxianguang 2befa7867d Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 rokov pred
  zhouxianguang d00424792f 添加渠道过滤 6 rokov pred
  zhouxianguang e45857018f 优化导出功能 6 rokov pred
  zhouxianguang 1e0c240180 优化excel导出 6 rokov pred
  zhouxianguang 71cca48729 优化导出功能 6 rokov pred
  zhouxianguang 3cc5b9ba86 修改导出excel格式 6 rokov pred
  zhouxianguang 23a79093d6 修改excel字段位置 6 rokov pred
  zhouxianguang 4491b02b78 修改统计终端用户总数 6 rokov pred
  zhouxianguang 21d7b9a43c 优化接口 6 rokov pred
  zhouxianguang aed041c1f4 添加parseDateStr方法 6 rokov pred
  zhouxianguang 34e7ff6796 导出功能调整 6 rokov pred
  zhouxianguang 750e521b93 导出内容调整 6 rokov pred
  zhouxianguang e96996f3c6 导出内容调整 6 rokov pred
  zhouxianguang e1f1eb5266 导出内容调整 6 rokov pred
  zhouxianguang 1bf0d54c9c 导出内容调整 6 rokov pred
  zhouxianguang aecf572fb7 支持查询导出excel 6 rokov pred
  zhouxianguang 74e319ba4f 修改导出功能 6 rokov pred
  zhouxianguang 0b989f819f 优化代码 6 rokov pred
  zhouxianguang d1a057fcf8 提交总统计表 6 rokov pred
  zhouxianguang 0a906a8911 设置fastExpired 6 rokov pred
  zhouxianguang 7f27b6168a 添加fastExpired 6 rokov pred
  zhouxianguang 9011b99861 调试打印日志 6 rokov pred
  zhouxianguang 3ba35cd0bf 开始时间、结束时间等时间搓转换日期格式 6 rokov pred
  zhouxianguang dd645ab1a3 添加开始时间、结束时间字段 6 rokov pred
  zhouxianguang 61c05d54fe 添加fastExpired,用来标记终端号是否过期 6 rokov pred
  zhouxianguang ca1ce57d77 补充校区信息 6 rokov pred
  zhouxianguang c3dc89e6f3 添加campusId赋值 6 rokov pred
  zhouxianguang 0332bb8740 submit code 6 rokov pred
  zhouxianguang 52b97b4f4d 已开通账户报表导出 6 rokov pred
  zhouxianguang 597dd80a8e 添加校区编号、校区名称、校区联系方式 6 rokov pred
  zhouxianguang 192b2d64f4 修改用户设备信息 6 rokov pred
  zhouxianguang 7a104a48b9 修改用户设备信息 6 rokov pred
  zhouxianguang 47d80fffc4 修改用户设备信息 6 rokov pred
  zhouxianguang d43c66cb17 终端用户报表 6 rokov pred
  zhouxianguang dadc6582e6 优化导出excel格式 6 rokov pred
  zhouxianguang d9cd50ea85 excel导出 6 rokov pred
  zhouxianguang 80239d3972 添加excel导出 6 rokov pred
  zhouxianguang 5061d5c486 添加excel导出功能 6 rokov pred
  zhouxianguang af108e3e2f submit code 6 rokov pred
  zhouxianguang c7f386fda7 补充省份字段 6 rokov pred
  zhouxianguang 57da462c9d 添加省份字段 6 rokov pred
  zhouxianguang 2331fb00eb Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 rokov pred
  zhouxianguang 6f79d3bf50 添加已开通校区报表接口 6 rokov pred
  zhouxianguang 0c5b4d6c2d 添加已开通校区报表接口 6 rokov pred
30 zmenil súbory, kde vykonal 1985 pridanie a 78 odobranie
  1. 41 0
      rankin-api-web/src/main/java/cn/rankin/apiweb/controller/QRcodeController.java
  2. 19 0
      rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserClient.java
  3. 54 4
      rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserService.java
  4. 6 0
      rankin-cms-web/pom.xml
  5. 172 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtCampusController.java
  6. 100 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtStatsController.java
  7. 249 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtTerminalUserController.java
  8. 33 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/stmt/StmtCampusService.java
  9. 36 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/stmt/StmtTerminalUserService.java
  10. 21 4
      rankin-common-utils/src/main/java/cn/rankin/common/utils/util/DateUtil.java
  11. 122 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/util/FastJsonUtils.java
  12. 54 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/util/QRCodeUtil.java
  13. 4 0
      rankin-data-api/src/main/java/cn/rankin/data/api/auth/dto/AuthQueryDTO.java
  14. 33 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/QRCodeDTO.java
  15. 4 1
      rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/TerminalUserSearchDTO.java
  16. 50 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/QRCode.java
  17. 2 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/CampusVo.java
  18. 33 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/QRCodeVo.java
  19. 12 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/TerminalUserAuthVo.java
  20. 1 0
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/service/ResourceService.java
  21. 26 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/QRCodeController.java
  22. 266 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/StmtCampusController.java
  23. 426 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/StmtTerminalUserController.java
  24. 152 68
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/TerminalUserController.java
  25. 11 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/QRCodeRepository.java
  26. 2 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/TerminalDeviceRepository.java
  27. 38 0
      rankin-user-service/src/main/java/cn/rankin/userservice/service/QRCodeService.java
  28. 11 1
      rankin-user-service/src/main/java/cn/rankin/userservice/service/TerminalDeviceService.java
  29. 1 0
      rankin-user-service/src/main/java/cn/rankin/userservice/utils/Converter.java
  30. 6 0
      rankin-user-service/src/main/java/cn/rankin/userservice/utils/DTOConverter.java

+ 41 - 0
rankin-api-web/src/main/java/cn/rankin/apiweb/controller/QRcodeController.java

@@ -0,0 +1,41 @@
+package cn.rankin.apiweb.controller;
+
+import cn.rankin.apiweb.assist.resolver.NeedUser;
+import cn.rankin.apiweb.service.user.UserService;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.data.api.app.vo.DeviceUserVo;
+import cn.rankin.data.api.user.vo.QRCodeVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/qrcode")
+public class QRcodeController {
+
+    @Autowired
+    private UserService userService;
+
+    @RequestMapping(method = RequestMethod.GET)
+    public APIResult<QRCodeVo> qrcode(@NeedUser DeviceUserVo user)
+    {
+
+        String eid = user.getEid();
+
+        log.info("qrcode request header : eid={},", eid);
+
+        return userService.qrcode(eid);
+    }
+
+    @RequestMapping(value = "/last", method = RequestMethod.GET)
+    public APIResult<QRCodeVo> queryLastQRCode(@NeedUser DeviceUserVo user)
+    {
+        String eid = user.getEid();
+        log.info("qrcode request header : eid={},", eid);
+        return userService.queryLastQRCode(eid);
+    }
+
+}
+

+ 19 - 0
rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserClient.java

@@ -3,11 +3,13 @@ package cn.rankin.apiweb.service.user;
 import cn.rankin.apiweb.code.ApiWebCode;
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.data.api.user.dto.QRCodeDTO;
 import cn.rankin.data.api.user.dto.TerminalDeviceDTO;
 import cn.rankin.data.api.user.dto.UserDeviceDTO;
 import cn.rankin.data.api.user.entity.UserRecommend;
 import cn.rankin.data.api.user.entity.UserTag;
 import cn.rankin.data.api.user.entity.UserTagProductRelation;
+import cn.rankin.data.api.user.vo.QRCodeVo;
 import cn.rankin.data.api.user.vo.TerminalDeviceVo;
 import cn.rankin.data.api.user.vo.TerminalUserVo;
 import cn.rankin.data.api.user.vo.WhiteUserVo;
@@ -71,6 +73,13 @@ public interface UserClient
                                                @RequestParam("pageNo") Integer pageNo,
                                                @RequestParam("pageSize") Integer pageSize);
 
+    @RequestMapping(value = "/qrcode", method = RequestMethod.POST)
+    QRCodeVo qrcode(@RequestBody QRCodeDTO dto);
+
+    @RequestMapping(value = "/qrcode/last", method = RequestMethod.GET)
+    QRCodeVo queryLastQRCode(@RequestParam("eid") String eid);
+
+
     @Component
     class UserServiceHystrix implements UserClient
     {
@@ -162,6 +171,16 @@ public interface UserClient
             return null;
         }
 
+        @Override
+        public QRCodeVo qrcode(QRCodeDTO dto) {
+            return null;
+        }
+
+        @Override
+        public QRCodeVo queryLastQRCode(String eid) {
+            return null;
+        }
+
 
     }
 }

+ 54 - 4
rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserService.java

@@ -3,22 +3,27 @@ package cn.rankin.apiweb.service.user;
 import cn.rankin.apiweb.code.ApiWebCode;
 import cn.rankin.apiweb.service.product.ProductClient;
 import cn.rankin.apiweb.utils.SecurityManager;
+import cn.rankin.common.utils.api.model.APICode;
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.common.utils.api.model.BaseCode;
 import cn.rankin.common.utils.api.page.Page;
 import cn.rankin.common.utils.constant.PlatForm;
 import cn.rankin.common.utils.constant.RedisKey;
 import cn.rankin.common.utils.service.RedisService;
+import cn.rankin.common.utils.util.FastJsonUtils;
+import cn.rankin.common.utils.util.QRCodeUtil;
 import cn.rankin.data.api.app.dto.DeviceLoginDTO;
 import cn.rankin.data.api.app.dto.LoginInfoDTO;
 import cn.rankin.data.api.app.vo.DeviceUserVo;
 import cn.rankin.data.api.app.vo.ItemVo;
 import cn.rankin.data.api.app.vo.UserInfoVo;
+import cn.rankin.data.api.user.dto.QRCodeDTO;
 import cn.rankin.data.api.user.dto.TerminalDeviceDTO;
 import cn.rankin.data.api.user.dto.UserDeviceDTO;
 import cn.rankin.data.api.user.entity.UserRecommend;
 import cn.rankin.data.api.user.entity.UserTag;
 import cn.rankin.data.api.user.entity.UserTagProductRelation;
+import cn.rankin.data.api.user.vo.QRCodeVo;
 import cn.rankin.data.api.user.vo.TerminalDeviceVo;
 import cn.rankin.data.api.user.vo.TerminalUserVo;
 import com.alibaba.fastjson.JSON;
@@ -31,10 +36,7 @@ import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 
 @Service
@@ -473,4 +475,52 @@ public class UserService
     {
         return userClient.findRelations(userTagId, productIdList, pageNo, pageSize);
     }
+
+    public APIResult<QRCodeVo> qrcode(String eid) {
+        APIResult<TerminalUserVo> apiResult = userClient.loadUserByEid(eid);
+        if(!apiResult.getSuccess()){
+            log.error("load user by eid is fail");
+            return APIResult.error(ApiWebCode.OPERATE_ERROR);
+        }
+        TerminalUserVo vo = apiResult.getData();
+        if(null == vo){
+            log.info("load terminalUser is null");
+            return APIResult.error(ApiWebCode.OPERATE_ERROR);
+        }
+
+        Date time = new Date();
+
+        Map qrcode = new HashMap();
+        qrcode.put("user",eid);
+        qrcode.put("time",time);
+        String json = FastJsonUtils.collectToString(qrcode);
+        String qrCode = null;
+
+        try{
+            qrCode = "data:image/png;base64," +  QRCodeUtil.generateQRCode(json);
+        }catch(Exception e){
+            log.error("generateQRCode exception,message={}",e.getMessage());
+            e.printStackTrace();
+            return APIResult.error(ApiWebCode.SERVER_ERROR);
+        }
+
+        String simple = vo.getMerchantSimple();
+
+        QRCodeDTO dto = new QRCodeDTO();
+        dto.setEid(eid);
+        dto.setSimple(simple);
+        dto.setTime(time);
+        dto.setQrcode(qrCode);
+        QRCodeVo qrcodeVo = userClient.qrcode(dto);
+
+        return APIResult.ok(qrcodeVo);
+    }
+
+    public APIResult<QRCodeVo> queryLastQRCode(String eid) {
+        QRCodeVo vo = userClient.queryLastQRCode(eid);
+        if(null == vo ){
+            return APIResult.error(APICode.OPERATE_ERROR);
+        }
+        return APIResult.ok(vo);
+    }
 }

+ 6 - 0
rankin-cms-web/pom.xml

@@ -93,6 +93,12 @@
             <artifactId>feign-httpclient</artifactId>
             <version>RELEASE</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>3.17</version>
+        </dependency>
     </dependencies>
 
 	<dependencyManagement>

+ 172 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtCampusController.java

@@ -0,0 +1,172 @@
+package cn.rankin.cmsweb.controller.stmt;
+
+import cn.rankin.cmsweb.assist.resolver.NeedUser;
+import cn.rankin.cmsweb.entity.UserDetails;
+import cn.rankin.cmsweb.service.stmt.StmtCampusService;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.util.BeanUtil;
+import cn.rankin.common.utils.util.ProvinceUtil;
+import cn.rankin.data.api.user.dto.CampusSearchDTO;
+import cn.rankin.data.api.user.vo.CampusVo;
+import org.apache.poi.hssf.usermodel.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/stmt/campus")
+public class StmtCampusController
+{
+    @Autowired
+    private StmtCampusService stmtService;
+
+    /**
+     * 查询已开通校区报表
+     *
+     * @param user            the user info
+     * @param campusSearchDTO the campus search
+     * @return
+     */
+    @RequestMapping(value = {"/list", "/"}, method = RequestMethod.GET)
+    public APIResult<Page<CampusVo>> campusList(@NeedUser UserDetails user, CampusSearchDTO campusSearchDTO)
+    {
+        if (!user.isPlatForm())
+        {
+            String merchantId = user.getMerchantId();
+            campusSearchDTO.setMerchantId(merchantId);
+        }
+        APIResult<Page<CampusVo>> pageData = stmtService.search(BeanUtil.convertToMap(campusSearchDTO));
+
+        //设置省份
+        if (pageData != null)
+        {
+            List<CampusVo> list = pageData.getData().getList();
+            if (list != null && list.size() > 0)
+            {
+                for (int i = 0; i < list.size(); i++)
+                {
+                    CampusVo vo = list.get(i);
+                    String provinceCode = vo.getProvinceCode();
+                    String provinceName = ProvinceUtil.get(provinceCode);
+                    vo.setProvinceName(provinceName);
+                }
+            }
+        }
+
+        return pageData;
+    }
+
+    /**
+     * 已开通校区报表导出
+     *
+     * @param user            the user info
+     * @param campusSearchDTO the campus search
+     * @return
+     */
+    @RequestMapping(value = {"/export", "/"}, method = RequestMethod.GET)
+    public String exportCampus(HttpServletResponse res, @NeedUser UserDetails user, CampusSearchDTO campusSearchDTO)
+    {
+        if (!user.isPlatForm())
+        {
+            String merchantId = user.getMerchantId();
+            campusSearchDTO.setMerchantId(merchantId);
+        }
+
+        //不是条件查询就全部下载
+        String code = campusSearchDTO.getCode();
+        String name = campusSearchDTO.getName();
+        if ((code != null && code != "") || (name != null && name != ""))
+        {
+
+        }
+        else
+        {
+            campusSearchDTO.setPageNo(1);
+            campusSearchDTO.setPageSize(100000);
+        }
+
+        APIResult<List<CampusVo>> apiResult = stmtService.query(BeanUtil.convertToMap(campusSearchDTO));
+
+        List<CampusVo> list = apiResult.getData();
+        //创建HSSFWorkbook对象(excel的文档对象)
+        HSSFWorkbook wb = new HSSFWorkbook();
+        //建立新的sheet对象(excel的表单)
+        HSSFSheet sheet = wb.createSheet("已开通校区报表");
+        //设置单元格宽度
+        sheet.setColumnWidth(0, 15 * 256);
+        sheet.setColumnWidth(1, 50 * 256);
+        sheet.setColumnWidth(2, 10 * 256);
+        sheet.setColumnWidth(3, 10 * 256);
+        sheet.setColumnWidth(4, 30 * 256);
+        sheet.setColumnWidth(5, 10 * 256);
+        sheet.setColumnWidth(6, 15 * 256);
+        sheet.setColumnWidth(7, 15 * 256);
+        //在sheet里创建第一行,参数为行索引(excel的行),可以是0~65535之间的任何一个
+        HSSFRow row1 = sheet.createRow(0);
+        //创建单元格并设置单元格内容
+        row1.createCell(0).setCellValue("校区编号");
+        row1.createCell(1).setCellValue("校区名称");
+        row1.createCell(2).setCellValue("客户类型");
+        row1.createCell(3).setCellValue("所属省");
+        row1.createCell(4).setCellValue("所属市");
+        row1.createCell(5).setCellValue("联系人");
+        row1.createCell(6).setCellValue("联系方式");
+        row1.createCell(7).setCellValue("更新时间");
+
+        //单元格日期格式
+        HSSFCellStyle cellStyle = wb.createCellStyle();
+        HSSFDataFormat format = wb.createDataFormat();
+        cellStyle.setDataFormat(format.getFormat("yyyy/mm/dd"));
+
+        //插入数据
+        if (list != null && list.size() > 0)
+        {
+            for (int i = 0; i < list.size(); i++)
+            {
+
+                CampusVo vo = list.get(i);
+                String provinceCode = vo.getProvinceCode();
+                String provinceName = ProvinceUtil.get(provinceCode);
+                vo.setProvinceName(provinceName);
+
+                HSSFRow row = sheet.createRow(i + 1);
+                row.createCell(0).setCellValue(vo.getCode());
+                row.createCell(1).setCellValue(vo.getName());
+                row.createCell(2).setCellValue(vo.getMerchantName());
+                row.createCell(3).setCellValue(vo.getProvinceName());
+                row.createCell(4).setCellValue(vo.getCityName());
+                row.createCell(5).setCellValue(vo.getContactName());
+                row.createCell(6).setCellValue(vo.getMobile());
+
+
+                HSSFCell cell = row.createCell(7);
+                cell.setCellValue(vo.getGmtModified());
+                cell.setCellStyle(cellStyle);
+            }
+        }
+
+        try
+        {
+            long currentTime = new Date().getTime();
+            //输出Excel文件
+            OutputStream output = res.getOutputStream();
+            res.reset();
+            res.setHeader("Content-disposition", "attachment; filename=lingjiao_campus_" + currentTime + ".xls");
+            res.setContentType("application/msexcel");
+            wb.write(output);
+            output.close();
+        }
+        catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+
+        return null;
+    }
+
+}

+ 100 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtStatsController.java

@@ -0,0 +1,100 @@
+package cn.rankin.cmsweb.controller.stmt;
+
+import cn.rankin.cmsweb.assist.resolver.NeedUser;
+import cn.rankin.cmsweb.entity.UserDetails;
+import cn.rankin.cmsweb.service.stmt.StmtCampusService;
+import cn.rankin.cmsweb.service.user.TerminalUserService;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.util.BeanUtil;
+import cn.rankin.data.api.user.dto.CampusSearchDTO;
+import cn.rankin.data.api.user.dto.TerminalUserSearchDTO;
+import cn.rankin.data.api.user.vo.CampusVo;
+import cn.rankin.data.api.user.vo.TerminalUserAuthVo;
+import cn.rankin.data.api.user.vo.TerminalUserVo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/stmt/stats")
+public class StmtStatsController
+{
+    @Autowired
+    private TerminalUserService terminalUserService;
+
+    @Autowired
+    private StmtCampusService stmtService;
+
+    /**
+     * 获取终端明细
+     *
+     * @param user      the user details
+     * @param searchDTO the search Dto
+     * @return
+     */
+    @RequestMapping(value = {"/page", "/"}, method = RequestMethod.GET)
+    public APIResult<Page<TerminalUserVo>> campusList(@NeedUser UserDetails user, TerminalUserSearchDTO searchDTO)
+    {
+        if (!user.isPlatForm())
+        {
+            String merchantId = user.getMerchantId();
+            searchDTO.setMerchantId(merchantId);
+        }
+        APIResult<Page<TerminalUserVo>> page = terminalUserService.search(BeanUtil.convertToMap(searchDTO));
+
+        return page;
+    }
+
+    /**
+     * 获取校区总数
+     *
+     * @param user            the user details
+     * @param campusSearchDTO the search Dto
+     * @return
+     */
+    @RequestMapping(value = {"/campus/totalsize", "/"}, method = RequestMethod.GET)
+    public APIResult<Page<CampusVo>> getCampusTotalSize(@NeedUser UserDetails user, CampusSearchDTO campusSearchDTO)
+    {
+        if (!user.isPlatForm())
+        {
+            String merchantId = user.getMerchantId();
+            campusSearchDTO.setMerchantId(merchantId);
+        }
+        APIResult<Page<CampusVo>> pageData = stmtService.search(BeanUtil.convertToMap(campusSearchDTO));
+
+        return APIResult.ok(pageData.getData().getTotalSize());
+    }
+
+    /**
+     * 获取终端用户数
+     *
+     * @param user the user details
+     * @param dto  the search Dto
+     * @return
+     */
+    @RequestMapping(value = {"/terminal/user/totalsize", "/"}, method = RequestMethod.GET)
+    public APIResult<Page<TerminalUserAuthVo>> getTerminalTotalSize(@NeedUser UserDetails user, TerminalUserSearchDTO dto)
+    {
+        if (!user.isPlatForm())
+        {
+            String merchantId = user.getMerchantId();
+            dto.setMerchantId(merchantId);
+        }
+
+        APIResult<Page<TerminalUserVo>> pageData =  terminalUserService.search(BeanUtil.convertToMap(dto));
+
+        if (pageData != null)
+        {
+            return APIResult.ok(pageData.getData().getTotalSize());
+        }
+        else
+        {
+            return APIResult.ok(0);
+        }
+    }
+}

+ 249 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtTerminalUserController.java

@@ -0,0 +1,249 @@
+package cn.rankin.cmsweb.controller.stmt;
+
+import cn.rankin.cmsweb.assist.resolver.NeedUser;
+import cn.rankin.cmsweb.entity.UserDetails;
+import cn.rankin.cmsweb.service.product.ProductService;
+import cn.rankin.cmsweb.service.stmt.StmtCampusService;
+import cn.rankin.cmsweb.service.user.CampusService;
+import cn.rankin.cmsweb.service.user.TerminalUserService;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.util.BeanUtil;
+import cn.rankin.common.utils.util.DateUtil;
+import cn.rankin.common.utils.util.ListUtil;
+import cn.rankin.data.api.product.vo.ProductVo;
+import cn.rankin.data.api.user.dto.CampusSearchDTO;
+import cn.rankin.data.api.user.dto.TerminalUserSearchDTO;
+import cn.rankin.data.api.user.vo.CampusVo;
+import cn.rankin.data.api.user.vo.TerminalUserAuthVo;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.hssf.usermodel.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/stmt/terminal/user")
+public class StmtTerminalUserController
+{
+    @Autowired
+    private StmtCampusService StmtService;
+
+    @Autowired
+    private TerminalUserService terminalUserService;
+
+    @Autowired
+    private ProductService productService;
+
+    @Autowired
+    private CampusService campusService;
+
+    /**
+     * 查询已开通校区报表
+     *
+     * @param user      the user info
+     * @param searchDTO the campus search
+     * @return
+     */
+    @RequestMapping(value = {"/page", "/"}, method = RequestMethod.GET)
+    public APIResult<Page<TerminalUserAuthVo>> campusList(@NeedUser UserDetails user, TerminalUserSearchDTO searchDTO)
+    {
+        if (!user.isPlatForm())
+        {
+            String merchantId = user.getMerchantId();
+            searchDTO.setMerchantId(merchantId);
+        }
+        Page<TerminalUserAuthVo> authVoPage = terminalUserService.findAuthList(BeanUtil.convertToMap(searchDTO));
+
+        List<TerminalUserAuthVo> terminalUserAuthVos = authVoPage.getList();
+        setProductInfo(terminalUserAuthVos);
+        setCampusInfo(terminalUserAuthVos);
+
+        return APIResult.ok(authVoPage);
+
+    }
+
+    /**
+     * 查询已开通校区报表
+     *
+     * @param user      the user info
+     * @param searchDTO the campus search
+     * @return
+     */
+    @RequestMapping(value = {"/export", "/"}, method = RequestMethod.GET)
+    public String exportCampus(HttpServletResponse res, @NeedUser UserDetails user, TerminalUserSearchDTO searchDTO)
+    {
+        log.info("fastExpired:"+searchDTO.getFastExpired()+"");
+        if (!user.isPlatForm())
+        {
+            String merchantId = user.getMerchantId();
+            searchDTO.setMerchantId(merchantId);
+        }
+
+        //不是条件查询就全部下载
+        String code = searchDTO.getCode();
+        if (code == null || code == "")
+        {
+            searchDTO.setPageNo(1);
+            searchDTO.setPageSize(100000);
+        }
+
+        Page<TerminalUserAuthVo> authVoPage = terminalUserService.findAuthList(BeanUtil.convertToMap(searchDTO));
+
+        List<TerminalUserAuthVo> list = authVoPage.getList();
+        setProductInfo(list);
+        setCampusInfo(list);
+
+        //创建HSSFWorkbook对象(excel的文档对象)
+        HSSFWorkbook wb = new HSSFWorkbook();
+        //建立新的sheet对象(excel的表单)
+        HSSFSheet sheet = wb.createSheet("已开通账户报表");
+        //设置单元格宽度
+        sheet.setColumnWidth(0, 20 * 256);
+        sheet.setColumnWidth(1, 10 * 256);
+        sheet.setColumnWidth(2, 30 * 256);
+        sheet.setColumnWidth(3, 30 * 256);
+        sheet.setColumnWidth(4, 10 * 256);
+        sheet.setColumnWidth(5, 30 * 256);
+        sheet.setColumnWidth(6, 15 * 256);
+        sheet.setColumnWidth(7, 15 * 256);
+        //在sheet里创建第一行,参数为行索引(excel的行),可以是0~65535之间的任何一个
+        HSSFRow row1 = sheet.createRow(0);
+        //创建单元格并设置单元格内容
+        row1.createCell(0).setCellValue("终端编号");
+        row1.createCell(1).setCellValue("课程包编号");
+        row1.createCell(2).setCellValue("课程包名称");
+        row1.createCell(3).setCellValue("权限有效期");
+        row1.createCell(4).setCellValue("权限有效时长");
+        row1.createCell(5).setCellValue("校区名称");
+        row1.createCell(6).setCellValue("联系人");
+        row1.createCell(7).setCellValue("联系方式");
+
+        //单元格日期格式
+        HSSFCellStyle cellStyle = wb.createCellStyle();
+        HSSFDataFormat format = wb.createDataFormat();
+        cellStyle.setDataFormat(format.getFormat("yyyy/mm/dd"));
+
+        //插入数据
+        if (list != null && list.size() > 0)
+        {
+            for (int i = 0; i < list.size(); i++)
+            {
+
+                TerminalUserAuthVo vo = list.get(i);
+
+                HSSFRow row = sheet.createRow(i + 1);
+                row.createCell(0).setCellValue(vo.getUCode());
+                row.createCell(1).setCellValue(vo.getPCode());
+                row.createCell(2).setCellValue(vo.getPName());
+                String dateStr = "起始时间: " + DateUtil.parseDateStr(vo.getStartTime()) + "\n";
+                dateStr += "到期时间:" + DateUtil.parseDateStr(vo.getEndTime());
+                row.createCell(3).setCellValue(dateStr);
+
+                //判断是否到期
+                Long curTime = new Date().getTime();
+                //获取到期天数
+                String expiredStr = "已到期";
+                long days = (vo.getEndTime() - curTime) / (1000 * 3600 * 24);
+                if (days > 0)
+                {
+                    expiredStr = days + "天到期";
+                }
+
+                row.createCell(4).setCellValue(new HSSFRichTextString(expiredStr));
+                row.createCell(5).setCellValue(vo.getCampusName());
+                row.createCell(6).setCellValue(vo.getCampusContactName());
+                row.createCell(7).setCellValue(vo.getCampusContactWay());
+            }
+        }
+
+        try
+        {
+            long currentTime = new Date().getTime();
+            //输出Excel文件
+            OutputStream output = res.getOutputStream();
+            res.reset();
+            res.setHeader("Content-disposition", "attachment; filename=lingjiao_terminal_user_" + currentTime + ".xls");
+            res.setContentType("application/msexcel");
+            wb.write(output);
+            output.close();
+        }
+        catch (Exception ex)
+        {
+
+        }
+
+        return null;
+    }
+
+    private void setProductInfo(List<TerminalUserAuthVo> terminalUserAuthVos)
+    {
+        if (CollectionUtils.isEmpty(terminalUserAuthVos))
+        {
+            return;
+        }
+
+        List<ProductVo> productVos = productService.productList();
+        if (CollectionUtils.isEmpty(productVos))
+        {
+            return;
+        }
+
+        Map<String, ProductVo> productVoMap = ListUtil.convert(productVos, "pid", ProductVo.class);
+
+        terminalUserAuthVos.forEach(vo ->
+        {
+            ProductVo productVo = productVoMap.get(vo.getPid());
+            if (null != productVo)
+            {
+                vo.setPCode(productVo.getCode());
+                vo.setPName(productVo.getName());
+            }
+            else
+            {
+                log.info("not found product by pid ,pid={}", vo.getPid());
+            }
+        });
+
+    }
+
+    private void setCampusInfo(List<TerminalUserAuthVo> terminalUserAuthVos)
+    {
+        if (CollectionUtils.isEmpty(terminalUserAuthVos))
+        {
+            return;
+        }
+
+        for (TerminalUserAuthVo vo : terminalUserAuthVos)
+        {
+            //时间转换
+            String startTime = DateUtil.parseDateStr(vo.getStartTime());
+            String endTime = DateUtil.parseDateStr(vo.getEndTime());
+            vo.setStartTimeStr(startTime);
+            vo.setEndTimeStr(endTime);
+            String campusId = vo.getCampusId();
+
+            if (campusId != null && campusId.trim() != "")
+            {
+                APIResult<CampusVo> apiResult = campusService.getCampus(campusId);
+                CampusVo campusVo = apiResult.getData();
+                if (campusVo != null)
+                {
+                    vo.setCampusName(campusVo.getName());
+                    vo.setCampusContactName(campusVo.getContactName());
+                    vo.setCampusContactWay(campusVo.getMobile());
+                }
+            }
+        }
+    }
+
+}

+ 33 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/stmt/StmtCampusService.java

@@ -0,0 +1,33 @@
+package cn.rankin.cmsweb.service.stmt;
+
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.data.api.user.dto.CampusDTO;
+import cn.rankin.data.api.user.vo.CampusVo;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@FeignClient(name = "${service.user.name}")
+public interface StmtCampusService
+{
+    /**
+     * 分页查询已开通校区
+     *
+     * @param searchDTO
+     * @return
+     */
+    @RequestMapping(value = "/stmt/campus/page", method = RequestMethod.GET)
+    APIResult<Page<CampusVo>> search(@RequestParam Map<String, Object> searchDTO);
+
+    /**
+     * 按照条件查询所有校区
+     *
+     * @param searchDTO
+     * @return
+     */
+    @RequestMapping(value = "/stmt/campus/list", method = RequestMethod.GET)
+    APIResult<List<CampusVo>> query(@RequestParam Map<String, Object> searchDTO);
+}

+ 36 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/stmt/StmtTerminalUserService.java

@@ -0,0 +1,36 @@
+package cn.rankin.cmsweb.service.stmt;
+
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.data.api.user.entity.TerminalUser;
+import cn.rankin.data.api.user.vo.CampusVo;
+import cn.rankin.data.api.user.vo.TerminalUserVo;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+import java.util.Map;
+
+@FeignClient(name = "${service.user.name}")
+public interface StmtTerminalUserService
+{
+    /**
+     * 分页查询终端用户
+     *
+     * @param searchDTO
+     * @return
+     */
+    @RequestMapping(value = "/stmt/terminal/user/page", method = RequestMethod.GET)
+    APIResult<Page<TerminalUserVo>> search(@RequestParam Map<String, Object> searchDTO);
+
+    /**
+     * 按照条件查询查询终端用户
+     *
+     * @param searchDTO
+     * @return
+     */
+    @RequestMapping(value = "/stmt/terminal/user/list", method = RequestMethod.GET)
+    APIResult<List<TerminalUserVo>> query(@RequestParam Map<String, Object> searchDTO);
+}

+ 21 - 4
rankin-common-utils/src/main/java/cn/rankin/common/utils/util/DateUtil.java

@@ -209,7 +209,8 @@ public class DateUtil {
 	 * @author xtwin <br/>
 	 * @version 2013-11-27 上午09:59:37 <br/>
 	 */
-	private static SimpleDateFormat getFormat(String pattern) {
+	private static SimpleDateFormat
+	getFormat(String pattern) {
 		SimpleDateFormat sdf = formats.get(pattern);
 		
 		if (null == sdf) {
@@ -247,9 +248,25 @@ public class DateUtil {
 		return strtodate;
 	}
 
+	public static String parseDateStr(Long times)
+	{
+		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+		ParsePosition pos = new ParsePosition(0);
+		return formatter.format(new Date(times));
+	}
+
+	/**
+	 * @param startDate
+	 * @param interval
+	 * @return 某日期加间隔分钟数后日期
+	 */
+	public static Date getAfterIntervalMInDate(Date startDate, int interval) {
+		Date calendar = new Date();
+		calendar.setTime((startDate.getTime() + interval * 60 * 1000));
+		return calendar;
+	}
+
 	public static void main(String[] args) {
-		for (int i = 0; i < 20; i++) {
-			System.out.println(DateUtil.getRandomCurrentTimeStamp());
-		}
+		System.out.print(parseDateStr(1543766400000l));
 	}
 }

+ 122 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/util/FastJsonUtils.java

@@ -0,0 +1,122 @@
+package cn.rankin.common.utils.util;
+
+import java.util.List;
+import java.util.Map;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.JSONLibDataFormatSerializer;
+import com.alibaba.fastjson.serializer.SerializeConfig;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+
+/**
+ * fastjson工具类
+ * @version:1.0.0
+ */
+public class FastJsonUtils {
+
+    private static final SerializeConfig config;
+
+    static {
+        config = new SerializeConfig();
+        config.put(java.util.Date.class, new JSONLibDataFormatSerializer()); // 使用和json-lib兼容的日期输出格式
+        config.put(java.sql.Date.class, new JSONLibDataFormatSerializer()); // 使用和json-lib兼容的日期输出格式
+    }
+
+    private static final SerializerFeature[] features = {SerializerFeature.WriteMapNullValue, // 输出空置字段
+            SerializerFeature.WriteNullListAsEmpty, // list字段如果为null,输出为[],而不是null
+            SerializerFeature.WriteNullNumberAsZero, // 数值字段如果为null,输出为0,而不是null
+            SerializerFeature.WriteNullBooleanAsFalse, // Boolean字段如果为null,输出为false,而不是null
+            SerializerFeature.WriteNullStringAsEmpty // 字符类型字段如果为null,输出为"",而不是null
+    };
+
+
+    public static String convertObjectToJSON(Object object) {
+        return JSON.toJSONString(object, config, features);
+    }
+
+    public static String toJSONNoFeatures(Object object) {
+        return JSON.toJSONString(object, config);
+    }
+
+
+
+    public static Object toBean(String text) {
+        return JSON.parse(text);
+    }
+
+    public static <T> T toBean(String text, Class<T> clazz) {
+        return JSON.parseObject(text, clazz);
+    }
+
+    // 转换为数组
+    public static <T> Object[] toArray(String text) {
+        return toArray(text, null);
+    }
+
+    // 转换为数组
+    public static <T> Object[] toArray(String text, Class<T> clazz) {
+        return JSON.parseArray(text, clazz).toArray();
+    }
+
+    // 转换为List
+    public static <T> List<T> toList(String text, Class<T> clazz) {
+        return JSON.parseArray(text, clazz);
+    }
+
+    /**
+     * 将javabean转化为序列化的json字符串
+     * @param keyvalue
+     * @return
+     */
+    /*public static Object beanToJson(KeyValue keyvalue) {
+        String textJson = JSON.toJSONString(keyvalue);
+        Object objectJson  = JSON.parse(textJson);
+        return objectJson;
+    }*/
+
+    /**
+     * 将string转化为序列化的json字符串
+     * @param keyvalue
+     * @return
+     */
+    public static Object textToJson(String text) {
+        Object objectJson  = JSON.parse(text);
+        return objectJson;
+    }
+
+    /**
+     * json字符串转化为map
+     * @param s
+     * @return
+     */
+    public static <K, V> Map<K, V>  stringToCollect(String s) {
+        Map<K, V> m = (Map<K, V>) JSONObject.parseObject(s);
+        return m;
+    }
+
+    /**
+     * 转换JSON字符串为对象
+     * @param jsonData
+     * @param clazz
+     * @return
+     */
+    public static Object convertJsonToObject(String jsonData, Class<?> clazz) {
+        return JSONObject.parseObject(jsonData, clazz);
+    }
+
+    public static Object convertJSONToObject(String content, Class<?> clazz) {
+        return JSONObject.parseObject(content, clazz);
+    }
+
+    /**
+     * 将map转化为string
+     * @param m
+     * @return
+     */
+    public static <K, V> String collectToString(Map<K, V> m) {
+        String s = JSONObject.toJSONString(m);
+        return s;
+    }
+
+}

+ 54 - 0
rankin-common-utils/src/main/java/cn/rankin/common/utils/util/QRCodeUtil.java

@@ -0,0 +1,54 @@
+package cn.rankin.common.utils.util;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
+import sun.misc.BASE64Encoder;
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+public class QRCodeUtil {
+
+    /**
+     * 根据内容,生成指定宽高、指定格式的二维码图片
+     *
+     * @param url   内容
+     * @return 生成的二维码图片路径
+     * @throws Exception
+     */
+    public static String generateQRCode(String url) throws IOException, WriterException {
+        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
+        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
+        hints.put(EncodeHintType.MARGIN, 0);
+        BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 360, 360, hints);
+        BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        ImageIO.write(image, "png", os);
+        byte b[] = os.toByteArray();
+        String QRCode = new BASE64Encoder().encode(b);
+        return QRCode;
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        Map qrcode = new HashMap();
+        qrcode.put("user","100166661101001");
+        qrcode.put("time",new Date());
+        String json = FastJsonUtils.collectToString(qrcode);
+        String qrCode = QRCodeUtil.generateQRCode(json);
+        System.out.println(qrCode);
+
+
+
+    }
+}
+

+ 4 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/auth/dto/AuthQueryDTO.java

@@ -21,4 +21,8 @@ public class AuthQueryDTO implements Serializable {
     private Integer pageNo = 1;
 
     private Integer pageSize = 10;
+
+    private Integer fastExpired = 0;
+
+    private String uids;
 }

+ 33 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/QRCodeDTO.java

@@ -0,0 +1,33 @@
+package cn.rankin.data.api.user.dto;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+@Data
+@ToString
+public class QRCodeDTO implements Serializable {
+
+    private String id;
+
+    private String eid;
+
+    private String simple;
+
+    private Date time;
+
+    private String qrcode;
+
+    private int status;
+
+    private Date gmtCreated;
+
+    private Date gmtModified;
+
+}
+
+
+

+ 4 - 1
rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/TerminalUserSearchDTO.java

@@ -6,7 +6,8 @@ import lombok.Data;
 import java.io.Serializable;
 
 @Data
-public class TerminalUserSearchDTO implements Serializable {
+public class TerminalUserSearchDTO implements Serializable
+{
 
     private String code;
 
@@ -23,4 +24,6 @@ public class TerminalUserSearchDTO implements Serializable {
     private Integer pageNo = 1;
 
     private Integer pageSize = 10;
+
+    private Integer fastExpired = 0;
 }

+ 50 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/QRCode.java

@@ -0,0 +1,50 @@
+package cn.rankin.data.api.user.entity;
+
+import lombok.Data;
+import lombok.ToString;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+
+@Data
+@ToString
+@Entity
+@Table(name = "u_qrcode")
+@DynamicInsert
+@DynamicUpdate
+public class QRCode implements Serializable {
+    @Id
+    @Column(name="id")
+    private String id;
+
+    @Column(name="eid")
+    private String eid;
+
+    @Column(name="simple")
+    private String simple;
+
+    @Column(name="time")
+    private Date time;
+
+    @Column(name="qrcode",columnDefinition="LONGTEXT")
+    private String qrcode;
+
+    @Column(name="status")
+    private int status;
+
+    @Column(name = "gmt_created", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtCreated;
+
+    @Column(name = "gmt_modified", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
+    @Temporal(TemporalType.TIMESTAMP)
+    private Date gmtModified;
+
+}
+
+
+

+ 2 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/CampusVo.java

@@ -17,6 +17,8 @@ public class CampusVo implements Serializable {
 
     private String provinceCode;
 
+    private String provinceName;
+
     private String cityName;
 
     private String zoneName;

+ 33 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/QRCodeVo.java

@@ -0,0 +1,33 @@
+package cn.rankin.data.api.user.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+@Data
+@ToString
+public class QRCodeVo implements Serializable {
+
+    private String id;
+
+    private String eid;
+
+    private String simple;
+
+    private Date time;
+
+    private String qrcode;
+
+    private int status;
+
+    private Date gmtCreated;
+
+    private Date gmtModified;
+
+}
+
+
+

+ 12 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/TerminalUserAuthVo.java

@@ -41,4 +41,16 @@ public class TerminalUserAuthVo implements Serializable {
     private Long createTime;
 
     private Long updateTime;
+
+    private String campusId;
+
+    private String campusName;
+
+    private String campusContactName;
+
+    private String campusContactWay;
+
+    private String startTimeStr;
+
+    private String endTimeStr;
 }

+ 1 - 0
rankin-resource-service/src/main/java/cn/rankin/resourceservice/service/ResourceService.java

@@ -126,6 +126,7 @@ public class ResourceService {
     public APIResult<Page<Resource>> findRemotePage(ResourceSearchDTO resourceSearchDTO) {
         APIResult<Page<ResourceRemote>> result = resourceProxy.findPage(new HashMap<String, Object>(){
             {
+                this.put("no", resourceSearchDTO.getCode());
                 this.put("title", resourceSearchDTO.getName());
                 this.put("pageNum", resourceSearchDTO.getPageNo());
                 this.put("pageSize", resourceSearchDTO.getPageSize());

+ 26 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/controller/QRCodeController.java

@@ -0,0 +1,26 @@
+package cn.rankin.userservice.controller;
+
+import cn.rankin.data.api.user.dto.QRCodeDTO;
+import cn.rankin.data.api.user.entity.QRCode;
+import cn.rankin.userservice.service.QRCodeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping(value = "/qrcode")
+public class QRCodeController {
+
+    @Autowired
+    private QRCodeService qrcodeService;
+
+    @RequestMapping(method = RequestMethod.POST)
+    public QRCode add(@RequestBody QRCodeDTO dto) {
+        return qrcodeService.add(dto);
+    }
+
+    @RequestMapping(value = "/last", method = RequestMethod.GET)
+    public QRCode findLastOne(@RequestParam("eid") String eid ){
+        return qrcodeService.findLastOne(eid);
+    }
+
+}

+ 266 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/controller/StmtCampusController.java

@@ -0,0 +1,266 @@
+package cn.rankin.userservice.controller;
+
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.enums.BaseOrderEnum;
+import cn.rankin.common.utils.util.ProvinceUtil;
+import cn.rankin.data.api.user.dto.CampusDTO;
+import cn.rankin.data.api.user.dto.CampusSearchDTO;
+import cn.rankin.data.api.user.dto.UserDeviceDTO;
+import cn.rankin.data.api.user.entity.Campus;
+import cn.rankin.data.api.user.entity.Merchant;
+import cn.rankin.data.api.user.entity.UserDevice;
+import cn.rankin.userservice.code.UserServiceAPICode;
+import cn.rankin.userservice.helper.RaStringHelper;
+import cn.rankin.userservice.service.CampusService;
+import cn.rankin.userservice.service.MerchantService;
+import cn.rankin.userservice.service.UserDeviceService;
+import cn.rankin.userservice.utils.StudentNo;
+import cn.rankin.userservice.utils.StudentNumberUtil;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.*;
+
+
+@RestController
+@RequestMapping(value = "/stmt/campus")
+public class StmtCampusController
+{
+    @Autowired
+    private MerchantService merchantService;
+
+    @Autowired
+    private CampusService campusService;
+
+    @RequestMapping(value = "/page", method = RequestMethod.GET)
+    public APIResult<Page<Campus>> page(CampusSearchDTO searchDTO)
+    {
+        Campus campus = new Campus();
+
+        String name = searchDTO.getName();
+        if (!StringUtils.isEmpty(name))
+        {
+            campus.setName("%" + name + "%");
+        }
+
+        String code = searchDTO.getCode();
+        if (!StringUtils.isEmpty(code))
+        {
+            campus.setCode("%" + code + "%");
+        }
+
+        String merchantId = searchDTO.getMerchantId();
+        if (!StringUtils.isEmpty(merchantId))
+        {
+            campus.setMerchantId(merchantId);
+        }
+
+        // sort
+        LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap<>();
+        sort.put("gmtModified", BaseOrderEnum.DESC);
+
+        APIResult<Page<Campus>> apiResult = campusService.search(campus, searchDTO.getPageNo(), searchDTO.getPageSize(), sort);
+        if (apiResult.getSuccess() && apiResult.getData() != null)
+        {
+            List<Campus> campusList = apiResult.getData().getList();
+            setMerchantName(campusList);
+
+        }
+
+        return apiResult;
+    }
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<List<Campus>> search(CampusSearchDTO searchDTO)
+    {
+        Campus campus = new Campus();
+
+        String name = searchDTO.getName();
+        if (!StringUtils.isEmpty(name))
+        {
+            campus.setName("%" + name + "%");
+        }
+
+        String code = searchDTO.getCode();
+        if (!StringUtils.isEmpty(code))
+        {
+            campus.setCode("%" + code + "%");
+        }
+
+        String merchantId = searchDTO.getMerchantId();
+        if (!StringUtils.isEmpty(merchantId))
+        {
+            campus.setMerchantId(merchantId);
+        }
+
+        // sort
+        LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap<>();
+        sort.put("gmtModified", BaseOrderEnum.DESC);
+
+        APIResult<List<Campus>> apiResult =  campusService.find(campus,sort);
+
+        setMerchantName(apiResult.getData());
+
+        return apiResult;
+    }
+
+    @RequestMapping(method = RequestMethod.GET)
+    public APIResult<List<Campus>> findByCondition(CampusSearchDTO searchDTO)
+    {
+        Campus campus = new Campus();
+
+        String name = searchDTO.getName();
+        if (!StringUtils.isEmpty(name))
+        {
+            campus.setName("%" + name + "%");
+        }
+
+        String code = searchDTO.getCode();
+        if (!StringUtils.isEmpty(code))
+        {
+            campus.setCode("%" + code + "%");
+        }
+
+        // sort
+        LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap<>();
+        sort.put("gmtModified", BaseOrderEnum.DESC);
+
+        return campusService.find(campus, sort);
+    }
+
+
+    @Transactional
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<Campus> create(@RequestBody @Valid CampusDTO campusDTO)
+    {
+        String merchantId = campusDTO.getMerchantId();
+        if (StringUtils.isEmpty(merchantId))
+        {
+            return APIResult.error(UserServiceAPICode.error("缺少渠道id"));
+        }
+
+        Merchant merchant = merchantService.findOne(merchantId);
+        if (merchant == null)
+        {
+            return APIResult.error(UserServiceAPICode.error("渠道不存在"));
+        }
+
+        String provinceCode = campusDTO.getProvinceCode();
+        if (StringUtils.isEmpty(provinceCode))
+        {
+            return APIResult.error(UserServiceAPICode.PARAMETER_ERROR);
+        }
+
+        provinceCode = converProvinceCode(merchant, provinceCode);
+
+        Integer serialNo = campusService.getSerialNo(merchantId, provinceCode);
+        StudentNo studentNo = StudentNumberUtil.getStudentNo(merchant.getCode(), provinceCode, serialNo);
+        if (studentNo == null)
+        {
+            return APIResult.error(UserServiceAPICode.CAMPUS_NO_ERROR);
+        }
+
+        campusDTO.setProvinceCode(provinceCode);
+        campusDTO.setSerialNo(serialNo);
+        campusDTO.setCode(studentNo.getCampusNo());
+
+        APIResult<Campus> result = campusService.create(campusDTO);
+        if (result.getSuccess())
+        {
+            Campus campus = result.getData();
+            setMerchantName(campus);
+        }
+
+        return result;
+    }
+
+    /**
+     * 判断是否贝尔安亲,湖南校区。
+     * 因湖南校区已达到最大限额,使用湖南新编号
+     *
+     * @param merchant
+     * @param provinceCode
+     * @return
+     */
+    private String converProvinceCode(Merchant merchant, String provinceCode)
+    {
+        if ("6666".equals(merchant.getCode()) && provinceCode.equals(ProvinceUtil.HN_ORIGINAL))
+        {
+            provinceCode = ProvinceUtil.HN;
+        }
+
+        return provinceCode;
+    }
+
+    @RequestMapping(value = "/ids", method = RequestMethod.GET)
+    public APIResult<Map<String, Campus>> findByIds(@RequestParam("id") List<String> campusIds)
+    {
+        Map<String, Campus> campusMap = campusService.getCampusMap(campusIds);
+        return APIResult.ok(campusMap);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<Campus> update(@RequestBody @Valid CampusDTO campusDTO)
+    {
+        String id = campusDTO.getId();
+        if (StringUtils.isEmpty(id))
+        {
+            return APIResult.error(UserServiceAPICode.PARAMETER_ERROR);
+        }
+
+        APIResult<Campus> result = campusService.update(campusDTO);
+        if (result.getSuccess())
+        {
+            Campus campus = result.getData();
+            setMerchantName(campus);
+        }
+
+        return result;
+    }
+
+    public void setMerchantName(List<Campus> campusList)
+    {
+        if (CollectionUtils.isEmpty(campusList))
+        {
+            return;
+        }
+
+        Set<String> merchantIdSet = new HashSet<>();
+        campusList.forEach(campus -> merchantIdSet.add(campus.getMerchantId()));
+
+        if (merchantIdSet.size() == 0)
+        {
+            return;
+        }
+        List<String> merchantIdList = new ArrayList<>();
+        merchantIdList.addAll(merchantIdSet);
+        Map<String, Merchant> merchantMap = merchantService.getMerchantMap(merchantIdList);
+
+        for (Campus campus : campusList)
+        {
+            String merchantId = campus.getMerchantId();
+            Merchant merchant = merchantMap.get(merchantId);
+            campus.setMerchantName(merchant.getName());
+        }
+    }
+
+    public void setMerchantName(Campus campus)
+    {
+        if (campus == null)
+        {
+            return;
+        }
+
+        Merchant merchant = merchantService.findOne(campus.getMerchantId());
+        if (merchant != null)
+        {
+            campus.setMerchantName(merchant.getName());
+        }
+    }
+
+}

+ 426 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/controller/StmtTerminalUserController.java

@@ -0,0 +1,426 @@
+package cn.rankin.userservice.controller;
+
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.enums.BaseOrderEnum;
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.util.HttpUtil;
+import cn.rankin.common.utils.util.ListUtil;
+import cn.rankin.common.utils.util.ProvinceUtil;
+import cn.rankin.data.api.auth.dto.AuthDTO;
+import cn.rankin.data.api.auth.dto.AuthQueryDTO;
+import cn.rankin.data.api.auth.vo.AuthVo;
+import cn.rankin.data.api.user.dto.CampusDTO;
+import cn.rankin.data.api.user.dto.CampusSearchDTO;
+import cn.rankin.data.api.user.dto.TerminalUserDTO;
+import cn.rankin.data.api.user.dto.TerminalUserSearchDTO;
+import cn.rankin.data.api.user.entity.Campus;
+import cn.rankin.data.api.user.entity.Merchant;
+import cn.rankin.data.api.user.entity.TerminalDevice;
+import cn.rankin.data.api.user.entity.TerminalUser;
+import cn.rankin.data.api.user.vo.TerminalUserAuthVo;
+import cn.rankin.userservice.code.UserServiceAPICode;
+import cn.rankin.userservice.dto.RemoteUser;
+import cn.rankin.userservice.proxy.RemoteAuthProxy;
+import cn.rankin.userservice.proxy.RemoteUserProxy;
+import cn.rankin.userservice.service.CampusService;
+import cn.rankin.userservice.service.MerchantService;
+import cn.rankin.userservice.service.TerminalDeviceService;
+import cn.rankin.userservice.service.TerminalUserService;
+import cn.rankin.userservice.utils.Converter;
+import cn.rankin.userservice.utils.StudentNo;
+import cn.rankin.userservice.utils.StudentNumberUtil;
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.transaction.Transactional;
+import javax.validation.Valid;
+import java.util.*;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/stmt/terminal/user")
+public class StmtTerminalUserController
+{
+    @Autowired
+    private TerminalUserService terminalUserService;
+
+    @Autowired
+    private CampusService campusService;
+
+    @Autowired
+    private MerchantService merchantService;
+
+    @Autowired
+    private RemoteUserProxy remoteUserProxy;
+
+    @Autowired
+    private RemoteAuthProxy remoteAuthProxy;
+
+    @Autowired
+    private TerminalDeviceService terminalDeviceService;
+
+    @RequestMapping(value = "/page", method = RequestMethod.GET)
+    public APIResult<Page<TerminalUser>> search(TerminalUserSearchDTO terminalUserSearchDTO) {
+        TerminalUser terminalUser = new TerminalUser();
+
+        String code = terminalUserSearchDTO.getCode();
+        String campusId = terminalUserSearchDTO.getCampusId();
+        if (!StringUtils.isEmpty(code)) {
+            terminalUser.setCode("%" + code + "%");
+        }else if (!StringUtils.isEmpty(campusId)) {
+            terminalUser.setCampusId(campusId);
+        }
+
+        String merchantId = terminalUserSearchDTO.getMerchantId();
+        if (!StringUtils.isEmpty(merchantId)) {
+            terminalUser.setMerchantId(merchantId);
+        }
+
+        BaseStatusEnum status = terminalUserSearchDTO.getStatus();
+        if (status != null) {
+            terminalUser.setStatus(status);
+        }
+
+        LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap<>();
+        sort.put("gmtModified", BaseOrderEnum.DESC);
+
+        APIResult<Page<TerminalUser>> result = terminalUserService.search(terminalUser, terminalUserSearchDTO.getPageNo(), terminalUserSearchDTO.getPageSize(), sort);
+        if (result.getSuccess()) {
+            List<TerminalUser> terminalUserList = result.getData().getList();
+            setUserInfo(terminalUserList);
+            setDeciceInfo(terminalUserList);
+        }
+
+        return result;
+    }
+
+
+    @RequestMapping(method = RequestMethod.GET)
+    public APIResult<List<TerminalUser>> findByCondition(TerminalUserSearchDTO terminalUserSearchDTO) {
+        TerminalUser terminalUser = new TerminalUser();
+
+        String code = terminalUserSearchDTO.getCode();
+        String campusId = terminalUserSearchDTO.getCampusId();
+        if (!StringUtils.isEmpty(code)) {
+            terminalUser.setCode("%" + code + "%");
+        } else if (!StringUtils.isEmpty(campusId)) {
+            terminalUser.setCampusId(campusId);
+        }
+
+        String merchantId = terminalUserSearchDTO.getMerchantId();
+        if (!StringUtils.isEmpty(merchantId)) {
+            terminalUser.setMerchantId(merchantId);
+        }
+
+        LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap<>();
+        sort.put("gmtModified", BaseOrderEnum.DESC);
+
+        List<TerminalUser> terminalUserList = terminalUserService.find(terminalUser, sort);
+        setUserInfo(terminalUserList);
+        return APIResult.ok(terminalUserList);
+    }
+
+    @RequestMapping(value = "/auth", method = RequestMethod.POST)
+    public APIResult updateAuth(@RequestBody AuthDTO dto) {
+        return remoteAuthProxy.saveOrUpdateAuth(dto);
+    }
+
+    @RequestMapping(value = "/auth/list", method = RequestMethod.GET)
+    public Page<TerminalUserAuthVo> findAuthListByCondition(TerminalUserSearchDTO terminalUserSearchDTO) {
+        Page<TerminalUserAuthVo> pageResult = new Page<>();
+        pageResult.setPageNo(terminalUserSearchDTO.getPageNo());
+        pageResult.setPageSize(terminalUserSearchDTO.getPageSize());
+
+        List<TerminalUserAuthVo> terminalUserAuthVos = new ArrayList<>();
+
+        //终端用户鉴权查询条件
+        AuthQueryDTO authQueryDTO = new AuthQueryDTO();
+        authQueryDTO.setPageNo(terminalUserSearchDTO.getPageNo());
+        authQueryDTO.setPageSize(terminalUserSearchDTO.getPageSize());
+
+
+        TerminalUser terminalUser = new TerminalUser();
+        String code = terminalUserSearchDTO.getCode();
+        if (!StringUtils.isEmpty(code)) {
+            log.info("/user/auth/list | request code={}",code);
+            terminalUser.setCode(code);
+        }
+        LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap<>();
+        sort.put("gmtModified", BaseOrderEnum.DESC);
+
+        List<TerminalUser> terminalUserList = terminalUserService.find(terminalUser, sort);
+
+        if(CollectionUtils.isEmpty(terminalUserList)){
+            log.info("terminalUserList is empty!");
+            return pageResult;
+        }else if(terminalUserList.size() == 1){
+            //查询到唯一用户时,设置资源库查询条件 | 其他情况默认查询全部
+            TerminalUser user = terminalUserList.get(0);
+            authQueryDTO.setUid(user.getId());
+        }
+
+        Page<AuthVo> authPage = remoteAuthProxy.findAuthList(authQueryDTO);
+
+        List<AuthVo> authList = authPage.getList();
+        if(CollectionUtils.isEmpty(authList)){
+            log.info("authList is empty!");
+            return pageResult;
+        }
+
+        Map<String, TerminalUser> terminalUserMap = ListUtil.convert(terminalUserList, "id", TerminalUser.class);
+
+        authList.forEach(authVo -> {
+            TerminalUser termianlUser = terminalUserMap.get(authVo.getUid());
+            TerminalUserAuthVo vo = Converter.getTerminalUserAuthVo(termianlUser,authVo);
+            terminalUserAuthVos.add(vo);
+        });
+
+        //设置分页数据
+        pageResult.setTotalSize((int)authPage.getTotalSize());
+        pageResult.setList(terminalUserAuthVos);
+
+        return pageResult;
+    }
+
+
+
+    @Transactional
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<TerminalUser> create(HttpServletRequest request, @RequestBody @Valid TerminalUserDTO terminalUserDTO) {
+        String campusId = terminalUserDTO.getCampusId();
+        if (StringUtils.isEmpty(campusId)) {
+            return APIResult.error(UserServiceAPICode.PARAMETER_ERROR);
+        }
+
+        Campus campus = campusService.findOne(campusId);
+        if (campus == null) {
+            return APIResult.error(UserServiceAPICode.NOT_EXISTS);
+        }
+
+        String merchantId = campus.getMerchantId();
+        Merchant merchant = merchantService.findOne(merchantId);
+
+        if (merchant == null) {
+            return APIResult.error(UserServiceAPICode.NOT_EXISTS);
+        }
+
+        // 开始生成学号
+        Integer serialNo = terminalUserService.getSerialNo(campusId);
+        String code = StudentNumberUtil.getStudentNo(campus.getCode(), serialNo);
+
+        // 设置学号
+        terminalUserDTO.setCode(code);
+        terminalUserDTO.setSerialNo(serialNo);
+        terminalUserDTO.setMerchantId(merchantId);
+
+        // 设置名字
+        String name = terminalUserDTO.getName();
+        if (StringUtils.isEmpty(name)) {
+            terminalUserDTO.setName(StudentNumberUtil.toChinese(serialNo, "教室"));
+        }
+
+        // 远程注册
+        String password = terminalUserDTO.getPassword();
+        APIResult<RemoteUser> remoteUserAPIResult = remoteUserProxy.register(code, password, HttpUtil.getClientIp(request), "0");
+        if (!remoteUserAPIResult.getSuccess()) {
+            log.error(JSON.toJSONString(remoteUserAPIResult));
+            return APIResult.error(UserServiceAPICode.REMOTE_USER_REGISTER_ERROR);
+        }else {
+            // 设置资源中心id为本地用户id
+            RemoteUser remoteUser = remoteUserAPIResult.getData();
+            terminalUserDTO.setId(remoteUser.getUid());
+        }
+
+        // 存储数据库
+        APIResult<TerminalUser> result = terminalUserService.create(terminalUserDTO);
+        if (!result.getSuccess()) {
+            return result;
+        }
+
+        TerminalUser terminalUser = result.getData();
+        setUserInfo(terminalUser, campus, merchant);
+
+        return result;
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<TerminalUser> update(HttpServletRequest request, @RequestBody TerminalUserDTO terminalUserDTO) {
+        String id = terminalUserDTO.getId();
+        if (StringUtils.isEmpty(id)) {
+            return APIResult.error(UserServiceAPICode.PARAMETER_ERROR);
+        }
+
+        TerminalUser terminalUser = terminalUserService.find(id);
+        if (terminalUser == null) {
+            return APIResult.error(UserServiceAPICode.NOT_EXISTS);
+        }
+
+        String newPassword = terminalUserDTO.getPassword();
+        if (!StringUtils.isEmpty(newPassword)) {
+            String prePassword = terminalUser.getPassword();
+            if (!prePassword.equals(newPassword)) {
+                APIResult result = remoteUserProxy.changePassword(terminalUser, newPassword, HttpUtil.getClientIp(request), "0");
+                if (!result.getSuccess()) {
+                    return result;
+                }
+            }
+        }
+
+        APIResult<TerminalUser> result = terminalUserService.update(terminalUserDTO);
+        if (result.getSuccess()) {
+            setUserInfo(result.getData());
+        }
+
+        return result;
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<TerminalUser> getUser(@PathVariable("id") String id) {
+        TerminalUser terminalUser = terminalUserService.find(id);
+        if (terminalUser == null) {
+            return APIResult.error(UserServiceAPICode.NOT_EXISTS);
+        }
+
+        setUserInfo(terminalUser);
+        return APIResult.ok(terminalUser);
+    }
+
+    @RequestMapping(value = "/code/{code}", method = RequestMethod.GET)
+    public APIResult<TerminalUser> loadUser(@PathVariable("code") String code) {
+        TerminalUser terminalUser = terminalUserService.loadUserByCode(code);
+        if (terminalUser == null) {
+            return APIResult.error(UserServiceAPICode.NOT_EXISTS);
+        }
+
+        setUserInfo(terminalUser);
+        return APIResult.ok(terminalUser);
+    }
+
+    @RequestMapping(value = "/campus/ids", method = RequestMethod.GET)
+    public APIResult<List<TerminalUser>> findByCampusIds(@RequestParam("id") List<String> campusIds) {
+        List<TerminalUser> terminalUserList = terminalUserService.findByCampusIds(campusIds);
+        setUserInfo(terminalUserList);
+        return APIResult.ok(terminalUserList);
+    }
+
+    @RequestMapping(value = "/ids", method = RequestMethod.GET)
+    public APIResult<List<TerminalUser>> findByIds(@RequestParam("id") List<String> ids) {
+        List<TerminalUser> terminalUserList = terminalUserService.findByIds(ids);
+        setUserInfo(terminalUserList);
+        return APIResult.ok(terminalUserList);
+    }
+
+    // 禁用终端用户
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable("id") String id) {
+        return terminalUserService.delete(id);
+    }
+
+
+    public static void setUserInfo(TerminalUser terminalUser, Campus campus, Merchant merchant) {
+        if (terminalUser == null) {
+            return;
+        }
+
+        if (campus != null) {
+            terminalUser.setContactName(campus.getContactName());
+            terminalUser.setMobile(campus.getMobile());
+            terminalUser.setCityName(campus.getCityName());
+            terminalUser.setZoneName(campus.getZoneName());
+            terminalUser.setProvinceName(ProvinceUtil.get(campus.getProvinceCode()));
+        }
+
+        if (merchant != null) {
+            terminalUser.setMerchantName(merchant.getName());
+            terminalUser.setMerchantContactMobile(merchant.getMobile());
+            terminalUser.setMerchantContactName(merchant.getContactName());
+        }
+    }
+
+    public void setUserInfo(TerminalUser terminalUser) {
+        if (terminalUser == null) {
+            return;
+        }
+
+        Campus campus = campusService.findOne(terminalUser.getCampusId());
+        if (campus != null) {
+            terminalUser.setContactName(campus.getContactName());
+            terminalUser.setMobile(campus.getMobile());
+            terminalUser.setCityName(campus.getCityName());
+            terminalUser.setZoneName(campus.getZoneName());
+            terminalUser.setProvinceName(ProvinceUtil.get(campus.getProvinceCode()));
+        }
+
+        Merchant merchant = merchantService.findOne(campus.getMerchantId());
+        if (merchant != null) {
+            terminalUser.setMerchantSimple(merchant.getSimple());
+            terminalUser.setMerchantName(merchant.getName());
+            terminalUser.setMerchantContactMobile(merchant.getMobile());
+            terminalUser.setMerchantContactName(merchant.getContactName());
+        }
+    }
+
+    public void setUserInfo(List<TerminalUser> terminalUserList) {
+        if (CollectionUtils.isEmpty(terminalUserList)) {
+            return;
+        }
+
+        List<String> campusIdList = new ArrayList<>();
+        List<String> merchantIdList = new ArrayList<>();
+
+        terminalUserList.forEach(terminalUser -> {
+            campusIdList.add(terminalUser.getCampusId());
+            merchantIdList.add(terminalUser.getMerchantId());
+        });
+
+        Map<String, Campus> campusMap = campusService.getCampusMap(campusIdList);
+        Map<String, Merchant> merchantMap = merchantService.getMerchantMap(merchantIdList);
+
+        for (TerminalUser terminalUser : terminalUserList) {
+            Campus campus = campusMap.get(terminalUser.getCampusId());
+            if (campus != null) {
+                terminalUser.setContactName(campus.getContactName());
+                terminalUser.setMobile(campus.getMobile());
+                terminalUser.setCityName(campus.getCityName());
+                terminalUser.setZoneName(campus.getZoneName());
+                terminalUser.setAddress(campus.getAddress());
+                terminalUser.setProvinceName(ProvinceUtil.get(campus.getProvinceCode()));
+            }
+
+            Merchant merchant = merchantMap.get(terminalUser.getMerchantId());
+            if (merchant != null) {
+                terminalUser.setMerchantName(merchant.getName());
+                terminalUser.setMerchantContactMobile(merchant.getMobile());
+                terminalUser.setMerchantContactName(merchant.getContactName());
+            }
+        }
+    }
+
+    /**
+     * 设置绑定设备信息
+     * @param terminalUserList
+     */
+    private void setDeciceInfo(List<TerminalUser> terminalUserList) {
+        if (CollectionUtils.isEmpty(terminalUserList)) {
+            return;
+        }
+
+        terminalUserList.forEach(terminalUser ->{
+            TerminalDevice terminalDevice = terminalDeviceService.findByUserId(terminalUser.getId());
+            if(null != terminalDevice){
+                //1  已绑定设备
+                terminalUser.setDeviceStatus(1);
+            }else{
+                terminalUser.setDeviceStatus(0);
+            }
+        });
+    }
+
+
+}

+ 152 - 68
rankin-user-service/src/main/java/cn/rankin/userservice/controller/TerminalUserController.java

@@ -45,7 +45,8 @@ import java.util.Map;
 @Slf4j
 @RestController
 @RequestMapping(value = "/user")
-public class TerminalUserController {
+public class TerminalUserController
+{
 
     @Autowired
     private TerminalUserService terminalUserService;
@@ -66,24 +67,31 @@ public class TerminalUserController {
     private TerminalDeviceService terminalDeviceService;
 
     @RequestMapping(value = "/list", method = RequestMethod.GET)
-    public APIResult<Page<TerminalUser>> search(TerminalUserSearchDTO terminalUserSearchDTO) {
+    public APIResult<Page<TerminalUser>> search(TerminalUserSearchDTO terminalUserSearchDTO)
+    {
         TerminalUser terminalUser = new TerminalUser();
 
         String code = terminalUserSearchDTO.getCode();
         String campusId = terminalUserSearchDTO.getCampusId();
-        if (!StringUtils.isEmpty(code)) {
+        if (!StringUtils.isEmpty(code))
+        {
             terminalUser.setCode("%" + code + "%");
-        }else if (!StringUtils.isEmpty(campusId)) {
+        }
+        else if (!StringUtils.isEmpty(campusId))
+        {
             terminalUser.setCampusId(campusId);
         }
 
         String merchantId = terminalUserSearchDTO.getMerchantId();
-        if (!StringUtils.isEmpty(merchantId)) {
+        log.info("merchantId:" + merchantId);
+        if (!StringUtils.isEmpty(merchantId))
+        {
             terminalUser.setMerchantId(merchantId);
         }
 
         BaseStatusEnum status = terminalUserSearchDTO.getStatus();
-        if (status != null) {
+        if (status != null)
+        {
             terminalUser.setStatus(status);
         }
 
@@ -91,7 +99,8 @@ public class TerminalUserController {
         sort.put("gmtModified", BaseOrderEnum.DESC);
 
         APIResult<Page<TerminalUser>> result = terminalUserService.search(terminalUser, terminalUserSearchDTO.getPageNo(), terminalUserSearchDTO.getPageSize(), sort);
-        if (result.getSuccess()) {
+        if (result.getSuccess())
+        {
             List<TerminalUser> terminalUserList = result.getData().getList();
             setUserInfo(terminalUserList);
             setDeciceInfo(terminalUserList);
@@ -102,19 +111,24 @@ public class TerminalUserController {
 
 
     @RequestMapping(method = RequestMethod.GET)
-    public APIResult<List<TerminalUser>> findByCondition(TerminalUserSearchDTO terminalUserSearchDTO) {
+    public APIResult<List<TerminalUser>> findByCondition(TerminalUserSearchDTO terminalUserSearchDTO)
+    {
         TerminalUser terminalUser = new TerminalUser();
 
         String code = terminalUserSearchDTO.getCode();
         String campusId = terminalUserSearchDTO.getCampusId();
-        if (!StringUtils.isEmpty(code)) {
+        if (!StringUtils.isEmpty(code))
+        {
             terminalUser.setCode("%" + code + "%");
-        } else if (!StringUtils.isEmpty(campusId)) {
+        }
+        else if (!StringUtils.isEmpty(campusId))
+        {
             terminalUser.setCampusId(campusId);
         }
 
         String merchantId = terminalUserSearchDTO.getMerchantId();
-        if (!StringUtils.isEmpty(merchantId)) {
+        if (!StringUtils.isEmpty(merchantId))
+        {
             terminalUser.setMerchantId(merchantId);
         }
 
@@ -127,12 +141,14 @@ public class TerminalUserController {
     }
 
     @RequestMapping(value = "/auth", method = RequestMethod.POST)
-    public APIResult updateAuth(@RequestBody AuthDTO dto) {
+    public APIResult updateAuth(@RequestBody AuthDTO dto)
+    {
         return remoteAuthProxy.saveOrUpdateAuth(dto);
     }
 
     @RequestMapping(value = "/auth/list", method = RequestMethod.GET)
-    public Page<TerminalUserAuthVo> findAuthListByCondition(TerminalUserSearchDTO terminalUserSearchDTO) {
+    public Page<TerminalUserAuthVo> findAuthListByCondition(TerminalUserSearchDTO terminalUserSearchDTO)
+    {
         Page<TerminalUserAuthVo> pageResult = new Page<>();
         pageResult.setPageNo(terminalUserSearchDTO.getPageNo());
         pageResult.setPageSize(terminalUserSearchDTO.getPageSize());
@@ -143,72 +159,102 @@ public class TerminalUserController {
         AuthQueryDTO authQueryDTO = new AuthQueryDTO();
         authQueryDTO.setPageNo(terminalUserSearchDTO.getPageNo());
         authQueryDTO.setPageSize(terminalUserSearchDTO.getPageSize());
+        authQueryDTO.setFastExpired(terminalUserSearchDTO.getFastExpired());
 
 
         TerminalUser terminalUser = new TerminalUser();
         String code = terminalUserSearchDTO.getCode();
-        if (!StringUtils.isEmpty(code)) {
-            log.info("/user/auth/list | request code={}",code);
+        if (!StringUtils.isEmpty(code))
+        {
+            log.info("/user/auth/list | request code={}", code);
             terminalUser.setCode(code);
         }
+
+        String merchantId = terminalUserSearchDTO.getMerchantId();
+        if (!StringUtils.isEmpty(merchantId))
+        {
+            log.info("/user/auth/list | request merchantId={}", merchantId);
+            terminalUser.setMerchantId(merchantId);
+        }
+
         LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap<>();
         sort.put("gmtModified", BaseOrderEnum.DESC);
 
         List<TerminalUser> terminalUserList = terminalUserService.find(terminalUser, sort);
 
-
-
-        if(CollectionUtils.isEmpty(terminalUserList)){
+        if (CollectionUtils.isEmpty(terminalUserList))
+        {
             log.info("terminalUserList is empty!");
             return pageResult;
-        }else if(terminalUserList.size() == 1){
+        }
+        else if (terminalUserList.size() == 1)
+        {
             //查询到唯一用户时,设置资源库查询条件 | 其他情况默认查询全部
             TerminalUser user = terminalUserList.get(0);
             authQueryDTO.setUid(user.getId());
         }
+        else
+        {
+            String uids = "";
+            for (TerminalUser obj : terminalUserList)
+            {
+                uids += obj.getId()+"#";
+            }
+            uids = uids.substring(0,uids.length()-1);
+            authQueryDTO.setUids(uids);
+        }
 
         Page<AuthVo> authPage = remoteAuthProxy.findAuthList(authQueryDTO);
 
         List<AuthVo> authList = authPage.getList();
-        if(CollectionUtils.isEmpty(authList)){
+        if (CollectionUtils.isEmpty(authList))
+        {
             log.info("authList is empty!");
             return pageResult;
         }
 
+
         Map<String, TerminalUser> terminalUserMap = ListUtil.convert(terminalUserList, "id", TerminalUser.class);
 
-        authList.forEach(authVo -> {
+        authList.forEach(authVo ->
+        {
             TerminalUser termianlUser = terminalUserMap.get(authVo.getUid());
-            TerminalUserAuthVo vo = Converter.getTerminalUserAuthVo(termianlUser,authVo);
-            terminalUserAuthVos.add(vo);
+            if (termianlUser != null)
+            {
+                TerminalUserAuthVo vo = Converter.getTerminalUserAuthVo(termianlUser, authVo);
+                terminalUserAuthVos.add(vo);
+            }
         });
 
         //设置分页数据
-        pageResult.setTotalSize((int)authPage.getTotalSize());
+        pageResult.setTotalSize((int) authPage.getTotalSize());
         pageResult.setList(terminalUserAuthVos);
 
         return pageResult;
     }
 
 
-
     @Transactional
     @RequestMapping(method = RequestMethod.POST)
-    public APIResult<TerminalUser> create(HttpServletRequest request, @RequestBody @Valid TerminalUserDTO terminalUserDTO) {
+    public APIResult<TerminalUser> create(HttpServletRequest request, @RequestBody @Valid TerminalUserDTO terminalUserDTO)
+    {
         String campusId = terminalUserDTO.getCampusId();
-        if (StringUtils.isEmpty(campusId)) {
+        if (StringUtils.isEmpty(campusId))
+        {
             return APIResult.error(UserServiceAPICode.PARAMETER_ERROR);
         }
 
         Campus campus = campusService.findOne(campusId);
-        if (campus == null) {
+        if (campus == null)
+        {
             return APIResult.error(UserServiceAPICode.NOT_EXISTS);
         }
 
         String merchantId = campus.getMerchantId();
         Merchant merchant = merchantService.findOne(merchantId);
 
-        if (merchant == null) {
+        if (merchant == null)
+        {
             return APIResult.error(UserServiceAPICode.NOT_EXISTS);
         }
 
@@ -223,17 +269,21 @@ public class TerminalUserController {
 
         // 设置名字
         String name = terminalUserDTO.getName();
-        if (StringUtils.isEmpty(name)) {
+        if (StringUtils.isEmpty(name))
+        {
             terminalUserDTO.setName(StudentNumberUtil.toChinese(serialNo, "教室"));
         }
 
         // 远程注册
         String password = terminalUserDTO.getPassword();
         APIResult<RemoteUser> remoteUserAPIResult = remoteUserProxy.register(code, password, HttpUtil.getClientIp(request), "0");
-        if (!remoteUserAPIResult.getSuccess()) {
+        if (!remoteUserAPIResult.getSuccess())
+        {
             log.error(JSON.toJSONString(remoteUserAPIResult));
             return APIResult.error(UserServiceAPICode.REMOTE_USER_REGISTER_ERROR);
-        }else {
+        }
+        else
+        {
             // 设置资源中心id为本地用户id
             RemoteUser remoteUser = remoteUserAPIResult.getData();
             terminalUserDTO.setId(remoteUser.getUid());
@@ -241,7 +291,8 @@ public class TerminalUserController {
 
         // 存储数据库
         APIResult<TerminalUser> result = terminalUserService.create(terminalUserDTO);
-        if (!result.getSuccess()) {
+        if (!result.getSuccess())
+        {
             return result;
         }
 
@@ -252,30 +303,37 @@ public class TerminalUserController {
     }
 
     @RequestMapping(method = RequestMethod.PUT)
-    public APIResult<TerminalUser> update(HttpServletRequest request, @RequestBody TerminalUserDTO terminalUserDTO) {
+    public APIResult<TerminalUser> update(HttpServletRequest request, @RequestBody TerminalUserDTO terminalUserDTO)
+    {
         String id = terminalUserDTO.getId();
-        if (StringUtils.isEmpty(id)) {
+        if (StringUtils.isEmpty(id))
+        {
             return APIResult.error(UserServiceAPICode.PARAMETER_ERROR);
         }
 
         TerminalUser terminalUser = terminalUserService.find(id);
-        if (terminalUser == null) {
+        if (terminalUser == null)
+        {
             return APIResult.error(UserServiceAPICode.NOT_EXISTS);
         }
 
         String newPassword = terminalUserDTO.getPassword();
-        if (!StringUtils.isEmpty(newPassword)) {
+        if (!StringUtils.isEmpty(newPassword))
+        {
             String prePassword = terminalUser.getPassword();
-            if (!prePassword.equals(newPassword)) {
+            if (!prePassword.equals(newPassword))
+            {
                 APIResult result = remoteUserProxy.changePassword(terminalUser, newPassword, HttpUtil.getClientIp(request), "0");
-                if (!result.getSuccess()) {
+                if (!result.getSuccess())
+                {
                     return result;
                 }
             }
         }
 
         APIResult<TerminalUser> result = terminalUserService.update(terminalUserDTO);
-        if (result.getSuccess()) {
+        if (result.getSuccess())
+        {
             setUserInfo(result.getData());
         }
 
@@ -283,9 +341,11 @@ public class TerminalUserController {
     }
 
     @RequestMapping(value = "/{id}", method = RequestMethod.GET)
-    public APIResult<TerminalUser> getUser(@PathVariable("id") String id) {
+    public APIResult<TerminalUser> getUser(@PathVariable("id") String id)
+    {
         TerminalUser terminalUser = terminalUserService.find(id);
-        if (terminalUser == null) {
+        if (terminalUser == null)
+        {
             return APIResult.error(UserServiceAPICode.NOT_EXISTS);
         }
 
@@ -294,9 +354,11 @@ public class TerminalUserController {
     }
 
     @RequestMapping(value = "/code/{code}", method = RequestMethod.GET)
-    public APIResult<TerminalUser> loadUser(@PathVariable("code") String code) {
+    public APIResult<TerminalUser> loadUser(@PathVariable("code") String code)
+    {
         TerminalUser terminalUser = terminalUserService.loadUserByCode(code);
-        if (terminalUser == null) {
+        if (terminalUser == null)
+        {
             return APIResult.error(UserServiceAPICode.NOT_EXISTS);
         }
 
@@ -305,14 +367,16 @@ public class TerminalUserController {
     }
 
     @RequestMapping(value = "/campus/ids", method = RequestMethod.GET)
-    public APIResult<List<TerminalUser>> findByCampusIds(@RequestParam("id") List<String> campusIds) {
+    public APIResult<List<TerminalUser>> findByCampusIds(@RequestParam("id") List<String> campusIds)
+    {
         List<TerminalUser> terminalUserList = terminalUserService.findByCampusIds(campusIds);
         setUserInfo(terminalUserList);
         return APIResult.ok(terminalUserList);
     }
 
     @RequestMapping(value = "/ids", method = RequestMethod.GET)
-    public APIResult<List<TerminalUser>> findByIds(@RequestParam("id") List<String> ids) {
+    public APIResult<List<TerminalUser>> findByIds(@RequestParam("id") List<String> ids)
+    {
         List<TerminalUser> terminalUserList = terminalUserService.findByIds(ids);
         setUserInfo(terminalUserList);
         return APIResult.ok(terminalUserList);
@@ -320,17 +384,21 @@ public class TerminalUserController {
 
     // 禁用终端用户
     @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
-    public APIResult<Boolean> delete(@PathVariable("id") String id) {
+    public APIResult<Boolean> delete(@PathVariable("id") String id)
+    {
         return terminalUserService.delete(id);
     }
 
 
-    public static void setUserInfo(TerminalUser terminalUser, Campus campus, Merchant merchant) {
-        if (terminalUser == null) {
+    public static void setUserInfo(TerminalUser terminalUser, Campus campus, Merchant merchant)
+    {
+        if (terminalUser == null)
+        {
             return;
         }
 
-        if (campus != null) {
+        if (campus != null)
+        {
             terminalUser.setContactName(campus.getContactName());
             terminalUser.setMobile(campus.getMobile());
             terminalUser.setCityName(campus.getCityName());
@@ -338,20 +406,24 @@ public class TerminalUserController {
             terminalUser.setProvinceName(ProvinceUtil.get(campus.getProvinceCode()));
         }
 
-        if (merchant != null) {
+        if (merchant != null)
+        {
             terminalUser.setMerchantName(merchant.getName());
             terminalUser.setMerchantContactMobile(merchant.getMobile());
             terminalUser.setMerchantContactName(merchant.getContactName());
         }
     }
 
-    public void setUserInfo(TerminalUser terminalUser) {
-        if (terminalUser == null) {
+    public void setUserInfo(TerminalUser terminalUser)
+    {
+        if (terminalUser == null)
+        {
             return;
         }
 
         Campus campus = campusService.findOne(terminalUser.getCampusId());
-        if (campus != null) {
+        if (campus != null)
+        {
             terminalUser.setContactName(campus.getContactName());
             terminalUser.setMobile(campus.getMobile());
             terminalUser.setCityName(campus.getCityName());
@@ -360,7 +432,8 @@ public class TerminalUserController {
         }
 
         Merchant merchant = merchantService.findOne(campus.getMerchantId());
-        if (merchant != null) {
+        if (merchant != null)
+        {
             terminalUser.setMerchantSimple(merchant.getSimple());
             terminalUser.setMerchantName(merchant.getName());
             terminalUser.setMerchantContactMobile(merchant.getMobile());
@@ -368,15 +441,18 @@ public class TerminalUserController {
         }
     }
 
-    public void setUserInfo(List<TerminalUser> terminalUserList) {
-        if (CollectionUtils.isEmpty(terminalUserList)) {
+    public void setUserInfo(List<TerminalUser> terminalUserList)
+    {
+        if (CollectionUtils.isEmpty(terminalUserList))
+        {
             return;
         }
 
         List<String> campusIdList = new ArrayList<>();
         List<String> merchantIdList = new ArrayList<>();
 
-        terminalUserList.forEach(terminalUser -> {
+        terminalUserList.forEach(terminalUser ->
+        {
             campusIdList.add(terminalUser.getCampusId());
             merchantIdList.add(terminalUser.getMerchantId());
         });
@@ -384,9 +460,11 @@ public class TerminalUserController {
         Map<String, Campus> campusMap = campusService.getCampusMap(campusIdList);
         Map<String, Merchant> merchantMap = merchantService.getMerchantMap(merchantIdList);
 
-        for (TerminalUser terminalUser : terminalUserList) {
+        for (TerminalUser terminalUser : terminalUserList)
+        {
             Campus campus = campusMap.get(terminalUser.getCampusId());
-            if (campus != null) {
+            if (campus != null)
+            {
                 terminalUser.setContactName(campus.getContactName());
                 terminalUser.setMobile(campus.getMobile());
                 terminalUser.setCityName(campus.getCityName());
@@ -396,7 +474,8 @@ public class TerminalUserController {
             }
 
             Merchant merchant = merchantMap.get(terminalUser.getMerchantId());
-            if (merchant != null) {
+            if (merchant != null)
+            {
                 terminalUser.setMerchantName(merchant.getName());
                 terminalUser.setMerchantContactMobile(merchant.getMobile());
                 terminalUser.setMerchantContactName(merchant.getContactName());
@@ -406,25 +485,30 @@ public class TerminalUserController {
 
     /**
      * 设置绑定设备信息
+     *
      * @param terminalUserList
      */
-    private void setDeciceInfo(List<TerminalUser> terminalUserList) {
-        if (CollectionUtils.isEmpty(terminalUserList)) {
+    private void setDeciceInfo(List<TerminalUser> terminalUserList)
+    {
+        if (CollectionUtils.isEmpty(terminalUserList))
+        {
             return;
         }
 
-        terminalUserList.forEach(terminalUser ->{
+        terminalUserList.forEach(terminalUser ->
+        {
             TerminalDevice terminalDevice = terminalDeviceService.findByUserId(terminalUser.getId());
-            if(null != terminalDevice){
+            if (null != terminalDevice)
+            {
                 //1  已绑定设备
                 terminalUser.setDeviceStatus(1);
-            }else{
+            }
+            else
+            {
                 terminalUser.setDeviceStatus(0);
             }
         });
     }
 
 
-
-
 }

+ 11 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/repository/QRCodeRepository.java

@@ -0,0 +1,11 @@
+package cn.rankin.userservice.repository;
+
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.data.api.user.entity.QRCode;
+import org.springframework.data.jpa.repository.Query;
+
+public interface QRCodeRepository extends BasicJpaRepository<QRCode, String> {
+
+    @Query(value = "select qr.* from u_qrcode qr where qr.eid = ?1 ORDER BY qr.gmt_created DESC limit 1",nativeQuery = true)
+    QRCode findLastOne(String eid);
+}

+ 2 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/repository/TerminalDeviceRepository.java

@@ -3,6 +3,7 @@ package cn.rankin.userservice.repository;
 import cn.rankin.common.utils.jpa.BasicJpaRepository;
 import cn.rankin.data.api.user.entity.TerminalDevice;
 import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 
 import java.util.List;
@@ -18,6 +19,7 @@ public interface TerminalDeviceRepository extends BasicJpaRepository<TerminalDev
     TerminalDevice findByDeviceCodeOrUserId(String code, String userId);
 
     @Modifying
+    @Query(value = "delete from TerminalDevice td where td.userId = ?1")
     Integer deleteByUserId(String userId);
 
     @Modifying

+ 38 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/service/QRCodeService.java

@@ -0,0 +1,38 @@
+package cn.rankin.userservice.service;
+
+import cn.rankin.common.utils.util.DateUtil;
+import cn.rankin.data.api.user.dto.QRCodeDTO;
+import cn.rankin.data.api.user.entity.QRCode;
+import cn.rankin.userservice.repository.QRCodeRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+
+import static cn.rankin.userservice.utils.DTOConverter.convert;
+
+@Service
+public class QRCodeService {
+
+    @Autowired
+    private QRCodeRepository qrcodeRepository;
+
+    public QRCode add(QRCodeDTO dto) {
+        QRCode qrcode = convert(dto);
+        return qrcodeRepository.save(qrcode);
+    }
+
+    public QRCode findLastOne(String eid) {
+        QRCode qrCode = qrcodeRepository.findLastOne(eid);
+        if(null != qrCode ){
+            Date now = new Date();
+            Date time = DateUtil.getAfterIntervalMInDate(qrCode.getTime(), 1);
+            if(now.getTime() > time.getTime()){
+                qrCode.setStatus(1); //已失效|过期
+                qrcodeRepository.update(qrCode);
+            }
+            return qrCode;
+        }
+        return qrCode;
+    }
+}

+ 11 - 1
rankin-user-service/src/main/java/cn/rankin/userservice/service/TerminalDeviceService.java

@@ -5,6 +5,7 @@ import cn.rankin.data.api.user.dto.TerminalDeviceDTO;
 import cn.rankin.data.api.user.entity.TerminalDevice;
 import cn.rankin.userservice.code.UserServiceAPICode;
 import cn.rankin.userservice.repository.TerminalDeviceRepository;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -12,6 +13,7 @@ import org.springframework.stereotype.Service;
 import javax.transaction.Transactional;
 import java.util.List;
 
+@Slf4j
 @Service
 public class TerminalDeviceService {
 
@@ -32,13 +34,17 @@ public class TerminalDeviceService {
         String terminal = terminalDeviceDTO.getTerminal();
 
         TerminalDevice terminalDevice = terminalDeviceRepository.findByUserId(userId);
+
         if (terminalDevice != null) {
             if(!deviceCode.equals(terminalDevice.getDeviceCode())){
                 //存在设备号不一致,账号被其他设备使用中
                 return APIResult.error(UserServiceAPICode.USER_IS_BOUND);
             }else{
                 //根据设备号,merchant,删除设备绑定记录,后面会重新添加绑定关系
-                deleteTerminalDeviceByDeviceCodeMerchant(deviceCode, merchant);
+                //deleteTerminalDeviceByDeviceCodeMerchant(deviceCode, merchant);
+                //根据设备号,merchant,删除设备绑定记录,后面会重新添加绑定关系
+                log.info("uid=,{}",userId);
+                deleteTerminalDeviceByUid(userId);
                 terminalDeviceBindLogService.insert(deviceCode, merchant, userId, brand, ip, modelNo, terminal+"_del");
             }
         }
@@ -58,6 +64,10 @@ public class TerminalDeviceService {
         return APIResult.ok(deviceBind);
     }
 
+    private void deleteTerminalDeviceByUid(String userId) {
+        terminalDeviceRepository.deleteByUserId(userId);
+    }
+
     private void deleteTerminalDeviceByDeviceCodeMerchant(String deviceCode, String merchant) {
         terminalDeviceRepository.deleteByDeviceCodeAndMerchant(deviceCode, merchant);
         terminalDeviceRepository.deleteByDeviceCodeAndMerchant(deviceCode, null);

+ 1 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/utils/Converter.java

@@ -26,6 +26,7 @@ public class Converter {
         if(null != termianlUser){
             vo.setUCode(termianlUser.getCode());
             vo.setUName(termianlUser.getName());
+            vo.setCampusId(termianlUser.getCampusId());
         }
 
         return vo;

+ 6 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/utils/DTOConverter.java

@@ -76,4 +76,10 @@ public class DTOConverter {
         BeanUtils.copyProperties(downloadInfoDTO, downloadInfo);
         return downloadInfo;
     }
+
+    public static QRCode convert(QRCodeDTO dto) {
+        QRCode qrcode = new QRCode();
+        BeanUtils.copyProperties(dto, qrcode);
+        return qrcode;
+    }
 }