422 Commits 6c6999f657 ... 90a64d2bf8

Author SHA1 Message Date
  guozhaoshun 90a64d2bf8 已采集设备型号列表(已去重) 6 years ago
  guozhaoshun 1a27c3e4a5 已采集设备型号列表(已去重) 6 years ago
  guozhaoshun c291aa219b 已采集设备型号列表(已去重) 6 years ago
  guozhaoshun 878c4f238d 渠道指定登录设备型号 6 years ago
  guozhaoshun e0cf09b9db 报表 6 years ago
  guozhaoshun f4cc2771ad 报表下载 6 years ago
  guozhaoshun 0738b8486c 报表 6 years ago
  guozhaoshun 1340b87ab7 用户标签报表 6 years ago
  guozhaoshun b9d116a40d 用户标签报表 6 years ago
  guozhaoshun d3345e847a 用户标签报表 6 years ago
  guozhaoshun cb69364155 用户标签报表 6 years ago
  guozhaoshun a289b60a02 fix 6 years ago
  guozhaoshun 5cd503d862 用户标签报表 6 years ago
  guozhaoshun fa5d2f2cce 用户标签报表 6 years ago
  guozhaoshun e3f939a710 fix 6 years ago
  guozhaoshun c1bea5e9ff log 6 years ago
  guozhaoshun 77554a0452 log 6 years ago
  guozhaoshun eb61f6bdde fix 6 years ago
  guozhaoshun 557cf56fd7 fix 6 years ago
  guozhaoshun 377e27b570 fix 6 years ago
  guozhaoshun a771451aae fix 6 years ago
  guozhaoshun f5249ac355 add zxing pom 6 years ago
  guozhaoshun 1a491722cc fix 6 years ago
  guozhaoshun e9b87ff922 fix 6 years ago
  guozhaoshun 2da188ad61 log 6 years ago
  guozhaoshun 309977d6d9 Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 years ago
  guozhaoshun e77b72262c 增加扫码回调接口 6 years ago
  guozhaoshun 85a47628ba test 6 years ago
  guozhaoshun d1f966a50d fix 6 years ago
  guozhaoshun 2c67d7b720 fix 6 years ago
  guozhaoshun 2d3ab8ee88 扫码接口 6 years ago
  guozhaoshun bd8a33a4f2 add qrcode 6 years ago
  guozhaoshun 05a3916048 fix 6 years ago
  zhouxianguang e45857018f 优化导出功能 6 years ago
  zhouxianguang 1e0c240180 优化excel导出 6 years ago
  zhouxianguang 71cca48729 优化导出功能 6 years ago
  zhouxianguang 3cc5b9ba86 修改导出excel格式 6 years ago
  zhouxianguang 23a79093d6 修改excel字段位置 6 years ago
  zhouxianguang 4491b02b78 修改统计终端用户总数 6 years ago
  zhouxianguang 21d7b9a43c 优化接口 6 years ago
  zhouxianguang aed041c1f4 添加parseDateStr方法 6 years ago
  zhouxianguang 34e7ff6796 导出功能调整 6 years ago
  zhouxianguang 750e521b93 导出内容调整 6 years ago
  zhouxianguang e96996f3c6 导出内容调整 6 years ago
  zhouxianguang e1f1eb5266 导出内容调整 6 years ago
  zhouxianguang 1bf0d54c9c 导出内容调整 6 years ago
  zhouxianguang aecf572fb7 支持查询导出excel 6 years ago
  zhouxianguang 74e319ba4f 修改导出功能 6 years ago
  zhouxianguang 0b989f819f 优化代码 6 years ago
  zhouxianguang d1a057fcf8 提交总统计表 6 years ago
  zhouxianguang 0a906a8911 设置fastExpired 6 years ago
  zhouxianguang 7f27b6168a 添加fastExpired 6 years ago
  zhouxianguang 9011b99861 调试打印日志 6 years ago
  zhouxianguang 3ba35cd0bf 开始时间、结束时间等时间搓转换日期格式 6 years ago
  zhouxianguang dd645ab1a3 添加开始时间、结束时间字段 6 years ago
  zhouxianguang 61c05d54fe 添加fastExpired,用来标记终端号是否过期 6 years ago
  zhouxianguang ca1ce57d77 补充校区信息 6 years ago
  zhouxianguang c3dc89e6f3 添加campusId赋值 6 years ago
  zhouxianguang 0332bb8740 submit code 6 years ago
  zhouxianguang 52b97b4f4d 已开通账户报表导出 6 years ago
  zhouxianguang 597dd80a8e 添加校区编号、校区名称、校区联系方式 6 years ago
  zhouxianguang 192b2d64f4 修改用户设备信息 6 years ago
  zhouxianguang 7a104a48b9 修改用户设备信息 6 years ago
  zhouxianguang 47d80fffc4 修改用户设备信息 6 years ago
  zhouxianguang d43c66cb17 终端用户报表 6 years ago
  zhouxianguang dadc6582e6 优化导出excel格式 6 years ago
  zhouxianguang d9cd50ea85 excel导出 6 years ago
  zhouxianguang 80239d3972 添加excel导出 6 years ago
  zhouxianguang 5061d5c486 添加excel导出功能 6 years ago
  zhouxianguang af108e3e2f submit code 6 years ago
  zhouxianguang c7f386fda7 补充省份字段 6 years ago
  zhouxianguang 57da462c9d 添加省份字段 6 years ago
  zhouxianguang 2331fb00eb Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 years ago
  zhouxianguang 6f79d3bf50 添加已开通校区报表接口 6 years ago
  zhouxianguang 0c5b4d6c2d 添加已开通校区报表接口 6 years ago
  zhouxianguang edd9bff632 修改用户设备信息 6 years ago
  zhouxianguang 5ee11d4259 修改用户设备信息 6 years ago
  zhouxianguang d2175fe6b2 修改获取用户登录设备信息 6 years ago
  zhouxianguang 5bd719c607 Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 years ago
  zhouxianguang ae2088719f 刷新token绑定设备信息 6 years ago
  zhouxianguang eaeaec3258 添加排序功能 6 years ago
  zhouxianguang 7330812d52 Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 years ago
  zhouxianguang 17d6ae0247 去掉获取mac代码 6 years ago
  zhouxianguang f737c69532 修改用户设备信息 6 years ago
  zhouxianguang 31f64a8a4f 修改用户设备信息 6 years ago
  zhouxianguang 203add6b80 修改用户设备信息 6 years ago
  zhouxianguang 712e3ed64b 修改用户设备信息 6 years ago
  zhouxianguang e28b8fcba6 修改用户设备信息 6 years ago
  zhouxianguang fd0f44df46 Merge remote-tracking branch 'origin/master' 6 years ago
  zhouxianguang 420515f38b 添加mac地址 6 years ago
  zhouxianguang dfe191235b 修改用户设备信息 6 years ago
  zhouxianguang 600bfdecd8 修改用户设备信息 6 years ago
  zhouxianguang 9374cb11d6 修改用户设备信息 6 years ago
  zhouxianguang 64e63733ae 修改用户设备信息 6 years ago
  zhouxianguang 7d276b09a6 修改用户设备信息 6 years ago
  zhouxianguang 1fe860f183 修改用户设备信息 6 years ago
  zhouxianguang 5ae26a397c Merge remote-tracking branch 'origin/master' 6 years ago
  zhouxianguang 967f900ace 修改用户设备信息 6 years ago
  zhouxianguang 68445201e2 修改用户设备信息 6 years ago
  zhouxianguang 6edc5305a5 修改用户设备信息 6 years ago
  zhouxianguang 087ca0c409 修改用户设备信息 6 years ago
  guozhaoshun 43068fe554 修改下载相关接口 6 years ago
  guozhaoshun 36769ca6f0 修改下载相关接口 6 years ago
  guozhaoshun 31816f4688 Merge remote-tracking branch 'origin/master' 6 years ago
  guozhaoshun 38d5be19b2 修改下载相关接口 6 years ago
  zhouxianguang e83f1e6c2d Merge remote-tracking branch 'origin/master' 6 years ago
  zhouxianguang 69310eb086 修改用户设备信息 6 years ago
  zhouxianguang bff01f767b submit code 6 years ago
  zhouxianguang 9526ac2a60 Merge remote-tracking branch 'origin/master' 6 years ago
  zhouxianguang 963f8dae84 submit code 6 years ago
  zhouxianguang 62f5567f29 add header user agent 6 years ago
  guozhaoshun 14c9b15c00 lesson add downloadStatus 6 years ago
  guozhaoshun 174095ff6e 修改下载相关接口 6 years ago
  guozhaoshun 49ed340d1b 修改下载相关接口 6 years ago
  guozhaoshun 6145922098 lesson add downloadStatus 6 years ago
  guozhaoshun f87419534d add mac 6 years ago
  guozhaoshun f7fe0a5842 修改下载相关接口 6 years ago
  guozhaoshun 68dabaf6c2 修改下载相关接口 6 years ago
  guozhaoshun a5241ad27e 修改下载相关接口 6 years ago
  guozhaoshun e97597233d 修改下载相关接口 6 years ago
  guozhaoshun 29a4107c94 add downloadStatus 6 years ago
  guozhaoshun c5400a7aad recover file 6 years ago
  guozhaoshun fefc190773 定义 下载状态 6 years ago
  guozhaoshun 9e95928d59 下载信息增加字段,课程返回下载状态 6 years ago
  guozhaoshun 560db20d23 fix bug 6 years ago
  guozhaoshun d384538f05 recover file 6 years ago
  guozhaoshun 94821f656b log 6 years ago
  guozhaoshun 56103c9aad log 6 years ago
  guozhaoshun a2b35c8285 设备信息 6 years ago
  guozhaoshun 307cdeebad 新增下载信息相关接口 6 years ago
  guozhaoshun 2bac5e7c74 收藏夹支持用户标签 6 years ago
  guozhaoshun ebc092b6bc fix bug 6 years ago
  guozhaoshun 73d7d4d1a1 fix bug 6 years ago
  guozhaoshun 8362a8b506 解决课程修改关联课操作后,TV前端不能正常展示bug 6 years ago
  guozhaoshun 36362b1411 解决课程修改关联课操作后,TV前端不能正常展示bug 6 years ago
  guozhaoshun 9ea777c9ad recover file 6 years ago
  guozhaoshun e3ec7e2ecd 创建标签 去除标签组 6 years ago
  guozhaoshun 59240036b4 API优化 标签逻辑 6 years ago
  guozhaoshun 0c9f0f3d6d API优化 标签逻辑 6 years ago
  guozhaoshun 986a184e5c 用户标签,没有数据直接返回空集合 6 years ago
  guozhaoshun e0a0edc1da 修复创建用户标签无法直接绑定产品 6 years ago
  guozhaoshun 2ef6ad74ac cms用户资源权限支持指定时长 6 years ago
  guozhaoshun d094d71d27 AuthDTO 支持指定时长,增加字段 {id,startTime,endTime} 6 years ago
  guozhaoshun 554da3762f fix /token PUT 6 years ago
  guozhaoshun 5c06255df2 fix /token PUT 6 years ago
  guozhaoshun c153078234 add log 6 years ago
  guozhaoshun 5ee6353606 add log 6 years ago
  guozhaoshun dafb1e4013 fix page info 6 years ago
  guozhaoshun dfef0dee43 terminalUserAuthVo | add terminalUser name 6 years ago
  guozhaoshun 4a3ba4d736 recover file 6 years ago
  guozhaoshun 16d57100e9 recover file 6 years ago
  guozhaoshun 2d9c8cdf01 recover file 6 years ago
  guozhaoshun de9fd93e84 cms support show terminalUser | auth info 6 years ago
  guozhaoshun 191f3e890e cms support show terminalUser auth info 6 years ago
  guozhaoshun 34d1b55563 Product add getProductList method 6 years ago
  guozhaoshun eb53b3f84a AuthQueryDTO add pageNo pageSize 6 years ago
  guozhaoshun 459a2e93c2 fix video resource update 6 years ago
  guozhaoshun 57418cbd98 fix terminalUser change passwd 6 years ago
  guozhaoshun 4ded2469bb fix terminalUser change passwd 6 years ago
  guozhaoshun 1a0aa5aa28 Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 years ago
  guozhaoshun c6f6585d42 fix login by token 6 years ago
  guozhaoshun b3f895ed91 fix 6 years ago
  guozhaoshun f0cad80e7e fix 6 years ago
  guozhaoshun f271fb26f7 fix getClientIp 6 years ago
  guozhaoshun 3429c5cf68 fix 6 years ago
  guozhaoshun 85f4e647dc change merchant from body to header 6 years ago
  guozhaoshun a5aae338a2 data api entity add merchant 6 years ago
  guozhaoshun a5483beb57 api login/authentication add merchant 6 years ago
  guozhaoshun 49d03ed008 optimize userTag copy 6 years ago
  guozhaoshun 0dadbb2e36 fix recommend num 6 years ago
  guozhaoshun 664b5a5ccc recover file 6 years ago
  guozhaoshun 03a368021a angelBell HN provinceCode = 90 6 years ago
  guozhaoshun ea9b83742d angelBell HN provinceCode = 90 6 years ago
  guozhaoshun 9efc79ba32 angelBell HN provinceCode = 90 6 years ago
  guozhaoshun 714dc6003e ProvinceUtil get 43 -> 90 6 years ago
  guozhaoshun 6a73cabad1 fix video update 6 years ago
  guozhaoshun 3256f1321c ProvinceUtil get HN 43|90 6 years ago
  guozhaoshun 250b07a14b update ProvinceUtil change provinceCode HN = "90" 6 years ago
  guozhaoshun 1c4c12f106 fix 6 years ago
  guozhaoshun 925d3e0715 fix resource/list find by type 6 years ago
  guozhaoshun a3c1fea9d7 API support audioImg resource 6 years ago
  xuchaolang ce6c7b8208 Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 years ago
  xuchaolang 4e69f04b87 Merge branch 'release/1.0.0' 6 years ago
  guozhaoshun 0eea46bf57 courseware support audioImg resource 6 years ago
  guozhaoshun 81538f7bf4 courseware support audioImg resource 6 years ago
  guozhaoshun 21518e8d80 fix url AudioImg 6 years ago
  guozhaoshun bdc6143ab5 Merge branch 'dev20180611' 6 years ago
  guozhaoshun 78120e41c4 support AudioImg 6 years ago
  guozhaoshun af8fd89f3b UserTag support copy from tag 6 years ago
  guozhaoshun 2e09eec0bf support AudioImg 6 years ago
  guozhaoshun c18b9479e5 CMS add AudioImg module 6 years ago
  guozhaoshun 4ffe74f10f support AudioImg 6 years ago
  guozhaoshun 2bce02f682 fix change video resource url | https:// 6 years ago
  guozhaoshun 1e5447c99c fix change video resource url | https:// 6 years ago
  guozhaoshun 8c6c5e2f6f fix 6 years ago
  guozhaoshun 84fcec2c52 fix 6 years ago
  guozhaoshun addf733cef optimize change video resource url | https:// 6 years ago
  guozhaoshun e25a1087b2 API support UserTag UserRecommend module 6 years ago
  guozhaoshun c1cafa0dde CMS support UserTag UserRecommend module 6 years ago
  guozhaoshun b7f7ae4fbd CMS support UserTag UserRecommend module 6 years ago
  guozhaoshun 68e668299a change ItemController package 6 years ago
  guozhaoshun 179ebf9818 support UserTag UserRecommend module 6 years ago
  guozhaoshun 53870c5081 add UserTag UserRecommend module 6 years ago
  guozhaoshun 9a91434191 add UserTag module 6 years ago
  guozhaoshun 3f669d5d8d add UserRecommend module 6 years ago
  guozhaoshun f342259060 UserTag UserRecommend UserTagProductRelation 6 years ago
  guozhaoshun bcf2a31407 img resource replace the blank space 6 years ago
  guozhaoshun f222501fd2 optimize poster 6 years ago
  guozhaoshun 13173f2b4d optimize poster 6 years ago
  guozhaoshun e9a0dde366 optimize 6 years ago
  guozhaoshun bac3f345a1 video list sort by createTime DESC 6 years ago
  guozhaoshun 7553ae7a1e video list sort by updateTime DESC 6 years ago
  guozhaoshun 394cf45ea7 video list sort by createTime DESC 6 years ago
  guozhaoshun 4e742c737a restore file 6 years ago
  guozhaoshun 1549a46a4d fix tag support update typeCode,merchant; 6 years ago
  guozhaoshun 33b5c15d60 change video resource url | https:// 6 years ago
  guozhaoshun 506effdb57 change video resource url | https:// 6 years ago
  guozhaoshun 9e8234ef28 terminalUser add deviceStatus 6 years ago
  guozhaoshun 816b823469 change video resource url | https:// 6 years ago
  guozhaoshun 6272cefc73 fix optimize the recommended course 6 years ago
  guozhaoshun b9de4f6722 optimize the recommended course 6 years ago
  guozhaoshun 3ffe8c3f5e fix updateResource 6 years ago
  guozhaoshun f3fb2065fc fix updateResource 6 years ago
  guozhaoshun a387a6d808 fix updateResource 6 years ago
  guozhaoshun f477dadf3d fix updateResource 6 years ago
  guozhaoshun 9311a32594 fix updateResource 6 years ago
  guozhaoshun f9b5490ab0 fix updateResource 6 years ago
  guozhaoshun 9d1b06ca5e fix poster 6 years ago
  guozhaoshun b1444f5476 fix poster 6 years ago
  guozhaoshun 6bdbf70ab7 fix picture list sort by gmtModified DESC 6 years ago
  guozhaoshun f7dd51ab62 from the update resource document; 1 video | 0 audio 6 years ago
  xuchaolang 9933ecdbfe Merge branch 'fix_bug.0525' 6 years ago
  xuchaolang 28d6e829ce Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 years ago
  xuchaolang 56ef2ae8da Fix bug, check idList if empty while find in repo 6 years ago
  guozhaoshun 1a88c54723 fix tag support update typeCode,merchant; 6 years ago
  guozhaoshun 7d2928ebf6 fix poster 6 years ago
  guozhaoshun c8a3defbf6 fix poster 6 years ago
  guozhaoshun fef1be4ad4 fix saveRemoteResource 6 years ago
  guozhaoshun 2232e69783 fix poster 6 years ago
  guozhaoshun d64df3cd1d fix poster 6 years ago
  guozhaoshun c6323af106 Merge branch 'dev001' 6 years ago
  xuchaolang 33f4ed14cc cms-web-api, /resource PUT, id pass in body 6 years ago
  xuchaolang 42d7a7fde9 web-api, /package/<pid>, return goods 6 years ago
  xuchaolang 80337f7aee Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 years ago
  xuchaolang e0359d50e8 Accomplish /user/messages/productExpiredAlert, /package/<pid> 6 years ago
  xuchaolang 4f2db3edf5 Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 6 years ago
  xuchaolang a6153d0f3e ProductService.getRelatedPackages, filter offline pkgs by status 6 years ago
  xuchaolang 5b06485ee2 return code in /product/<pid>/relatedPkg, move shopQR into Goods 6 years ago
  xuchaolang a6a6614946 ProductService.getRelatedPkgs, set goods 6 years ago
  xuchaolang 4c631931cd ProductService.getRelatedPackges, check pkgId but not productId while scaning relatedPkgs 6 years ago
  xuchaolang 6991a10393 ProductService, move ProductController from controller.cms package to controller package 6 years ago
  xuchaolang c6b6a14078 Accomplish Api /product/<pid>/relatedPkg 6 years ago
  xuchaolang e06c345575 Add /merchant prefix to Api /merchant/<merchantId>/posters 6 years ago
  xuchaolang cdc99ef674 service /user/<uid>/product/valid Resturn [] while user have no valid products 6 years ago
  xuchaolang 9e62064f53 Print product Log while get valid product from service 6 years ago
  xuchaolang 9ca21fe5ad Print User 6 years ago
  xuchaolang 6d90ff45c9 Temporarily add /user/product/valid in product service 6 years ago
  xuchaolang 027257e268 Merge branch 'dev.3.0' 6 years ago
  guozhaoshun 279f88c027 change TagTypeController /controller/app to /controller/ 6 years ago
  guozhaoshun f3ca8a50f5 add support video upload 6 years ago
  guozhaoshun d8011a4be3 tag create/update support tagType 6 years ago
  guozhaoshun 2f51c018ab tagType 6 years ago
  guozhaoshun 3d0665565c Tag create/update support typeCode 6 years ago
  guozhaoshun 671925bb7c merchant product name change source 6 years ago
  guozhaoshun 4f4b2067cd add /tagType/{code} 6 years ago
  guozhaoshun 150ce1a65d add 6 years ago
  guozhaoshun ebb60529f4 add 6 years ago
  xuchaolang fdcb5a30ea Fix getTagType request mapping value 6 years ago
  xuchaolang bb4f968336 restore pom.xml 6 years ago
  xuchaolang c3df828bef check if sign is empty while get it from header 6 years ago
  xuchaolang 00103a8f10 use Authentication while sign not Exist, For compatition with 2.x app verions 6 years ago
  guozhaoshun e35f33f816 recover yml 6 years ago
  guozhaoshun 967949bded test commit 6 years ago
  guozhaoshun eec791684a Merge remote-tracking branch 'origin/master' into dev 6 years ago
  guozhaoshun 75b5a94017 repair bug 6 years ago
  xuchaolang e554490545 skip shelf in relatedSupport 6 years ago
  xuchaolang 0ee63c8bde set dateDesc,openTime,closeTime 6 years ago
  xuchaolang 1cf7041a5d fix /training/{id} request map bug 6 years ago
  xuchaolang a5feaf286d change service api /app/training/{id} to /training/{id} 6 years ago
  xuchaolang d55840f63b TrainingController add log 6 years ago
  xuchaolang 150e531e17 check productid is null in findByIds 6 years ago
  xuchaolang c01366a887 fix training update 6 years ago
  xuchaolang 926e20469b return Training type in ProductService 6 years ago
  xuchaolang c35e78559c training.get only return training entity 6 years ago
  xuchaolang ba6772a241 add traing cms api 6 years ago
  xuchaolang 2a2b0f02ff add traing cms api 6 years ago
  xuchaolang 0839854e30 加入/training/<id>接口 6 years ago
  xuchaolang 1c593901be add course title to course/lesson 6 years ago
  huodongdong 8fb41e9d7e fix 6 years ago
  huodongdong 33dfe9086d fix white user search 6 years ago
  huodongdong 12ee9bd962 fix white user search request body 6 years ago
  huodongdong 46bb611eac fix 6 years ago
  huodongdong a7c33c52fe fix feign pathvariable error 6 years ago
  huodongdong 7450e47d4f fix 6 years ago
  huodongdong c9ecf201a9 add merchantId of white user 6 years ago
  huodongdong 8bb7d1122a add merchant name of white user 6 years ago
  huodongdong 50a2dd42d0 add api binder cms white user 6 years ago
  huodongdong ac39c034af add white user model 6 years ago
  huodongdong 2798495bf0 add white user table 6 years ago
  huodongdong e03a581e5a fix 6 years ago
  huodongdong de4cb52101 cms log level 6 years ago
  huodongdong 445c3c5ae5 cms delete redis app login data 6 years ago
  huodongdong 83fe73e0b3 add cms unbind device 6 years ago
  huodongdong db8ea62107 fix tag product sort bug 6 years ago
  huodongdong aeee85f461 add timeout session 6 years ago
  huodongdong 973392ebf0 fix 6 years ago
  huodongdong 6757e24f70 remove session 6 years ago
  huodongdong 938ebbaf0c fix lesson search 6 years ago
  huodongdong f37e9b6eb4 fix lesson empty exception 6 years ago
  huodongdong c635cbc670 add log 6 years ago
  huodongdong 9edd40418a fix 6 years ago
  huodongdong 9637fee49d fix group code 6 years ago
  huodongdong 27c762f9a1 add field of merchant simple 6 years ago
  huodongdong 473394bd12 fix 6 years ago
  huodongdong 9e1fe10b8f fix video url error 6 years ago
  huodongdong 190f0e601b fix bing terminal field null and log error 6 years ago
  huodongdong c27e8c256a add web login force 6 years ago
  huodongdong 73c7c88a25 fix terminal name 6 years ago
  huodongdong 19d3c3e4f7 modifiy terminal name to campusName + terminalName 6 years ago
  huodongdong fb221ea346 fix campus name remove - 6 years ago
  huodongdong c561799f73 fix 6 years ago
  huodongdong e9f308a413 fix 6 years ago
  huodongdong 5bc08795d5 fix 6 years ago
  huodongdong 69fe592df2 fix 6 years ago
  huodongdong 74f882a885 完成pushmsg push 6 years ago
  huodongdong 9585210305 complete app api 6 years ago
  huodongdong ed9f6583d9 fix device_code null 6 years ago
  huodongdong 8b7fc151e6 refresh token not signature 6 years ago
  huodongdong 53d28c7191 fix api recommend 6 years ago
  huodongdong 1c36c05943 fix recommend 6 years ago
  huodongdong 9bca91cc2a add refresh token 6 years ago
  huodongdong 05927ed824 remove test intercepter, same the terminal user id 6 years ago
  huodongdong b96f1f4298 fix 6 years ago
  huodongdong 5913d3072d valid login 6 years ago
  huodongdong 9c3aaf41f5 fix 6 years ago
  huodongdong b300458a22 fix 6 years ago
  huodongdong 5a764d1100 fix 6 years ago
  huodongdong c817e33b16 add status terminal user filter search 6 years ago
  huodongdong 4c5881db37 add product merchantId when search 6 years ago
  huodongdong ca84c38189 add tag sort 6 years ago
  huodongdong f813b6b318 deploy 6 years ago
  huodongdong cfbbf4c3c8 fix header and option request bug 6 years ago
  huodongdong 61522ff50e fix 6 years ago
  huodongdong 1f54a29d64 fix receive 6 years ago
  huodongdong 0a7d232e36 web api stash and fix charge 6 years ago
  huodongdong 8dfc0d3ea3 fix 6 years ago
  huodongdong b1908c474c add code and name order goods 6 years ago
  huodongdong 4f2560e16a order detail api 6 years ago
  huodongdong 1cd5f51282 fix transactional 6 years ago
  huodongdong 74b94275b4 add charge 6 years ago
  huodongdong a71b1653d0 add charge api 6 years ago
  huodongdong 9f8ce28658 fix MySQL5DialectUTF8 6 years ago
  huodongdong 29fbd94fa5 fix create table utf8 6 years ago
  huodongdong 23569b09dd fix 6 years ago
  huodongdong 2e49f4d8bd fix 6 years ago
  huodongdong 42bb7557bd modified yml config 6 years ago
  huodongdong 54ebcd3e0c fix 6 years ago
  huodongdong 43b3b23379 add merchantPrice of pakcageProductVo 6 years ago
  huodongdong af3de4ab65 add merchant price of product in package 6 years ago
  huodongdong c73ae0883f add category of courseware 6 years ago
  huodongdong e3bc647fdb fix 6 years ago
  huodongdong 504b10c476 config test 6 years ago
  huodongdong 4ddca8254e profile act 6 years ago
  huodongdong cc65c80444 test 6 years ago
  huodongdong 7ed2337ea0 add sub title 6 years ago
  huodongdong c36277375e modified cancel order api 6 years ago
  huodongdong 08bd31ccdf order search to post feign 7 years ago
  huodongdong c2cabfc0ac add goods type auto 7 years ago
  huodongdong 6b8d5122d3 same order status and order detail status 7 years ago
  huodongdong 75c5cd1338 fix 7 years ago
  huodongdong 4ef6d6bb47 add terminal user address 7 years ago
  huodongdong aa34b15a14 add merchant product list package info 7 years ago
  huodongdong 049d6eb4c8 add oderdetail and snapshot search api 7 years ago
  huodongdong d6aef08774 fix log 7 years ago
  huodongdong 30ccda2563 complete task 7 years ago
  huodongdong 4a50d6038c size 7 years ago
  huodongdong db4847d06a fix name 7 years ago
  huodongdong aa15ceede3 fix 7 years ago
  huodongdong b28be55f44 add status of goods package when put on sale 7 years ago
  huodongdong d20807fba1 fix 7 years ago
  huodongdong 072ea17be3 add sort when put on sale product 7 years ago
  huodongdong 21aa6d4df2 add cms merchantProduct 7 years ago
  huodongdong 466c98dfe4 add package update and on sale goods relation add and update 7 years ago
  huodongdong fc7f9598dd fix lesson api cms 7 years ago
  huodongdong bd88622c1f fix 7 years ago
  huodongdong 503a8f4481 fix lesson warelist 7 years ago
  huodongdong 3c50ba20cd add tag and group info 7 years ago
  huodongdong ea7d4da2c7 no 7 years ago
  huodongdong 72c1434dc3 @Modifying remove clearAutomatically=true 7 years ago
  huodongdong 72ae842ea9 add status product create 7 years ago
  huodongdong f99e29af74 fix 7 years ago
  huodongdong 47afdb4c32 product search string format error 7 years ago
  huodongdong 6b421cec99 fix support 7 years ago
  huodongdong 446296f16f fix ware data structure 7 years ago
  huodongdong 187f7f622b 订单分拆初版 7 years ago
  huodongdong ac7e27719b modified table name and createtime 7 years ago
  huodongdong 97e636322c api web test remove token check 7 years ago
  huodongdong 012209cc64 fix resource name 7 years ago
  huodongdong 723cceb4bb fix 7 years ago
  huodongdong 3214cf4a72 fix pom config 7 years ago
  huodongdong 76798122fa fix pom config 7 years ago
  huodongdong 7f082bf582 fix pom build config 7 years ago
  huodongdong 120f9de598 tmp 7 years ago
  huodongdong 1fe47abcc0 complete pay ok 7 years ago
  huodongdong 2bd43244b7 save 7 years ago
  huodongdong 857b5bb181 add package 7 years ago
  huodongdong 3b6e896596 complete product and goods recoding 7 years ago
  huodongdong 225693bfc7 product idea period 1 7 years ago
  huodongdong f15b6dbe00 stash 7 years ago
  huodongdong bbb144a1c9 campus and termianl user complete 7 years ago
  huodongdong 2ddd9d23e8 add cms web 7 years ago
  huodongdong 31ca7939f3 tag 7 years ago
  huodongdong 98f4431dcf version 1.0 dev 7 years ago
  huodongdong 1d57b2f9f0 shit commit and reset 7 years ago
  huodongdong 34a6cad675 nothing 7 years ago
  huodongdong d69395e6a7 version 1.1: id string and relation; hibernate relation 7 years ago
  huodongdong e428f275b5 resource service complete 7 years ago
  huodongdong 2f57ba34a8 first version 7 years ago
  huodongdong 05dfbac277 fix 7 years ago
  huodongdong bdc9fa3299 rename 7 years ago
  huodongdong 08fb34581d add ignore 7 years ago
  huodongdong dd01ec7ace first framework 7 years ago
63 changed files with 3501 additions and 127 deletions
  1. 106 13
      rankin-api-web/src/main/java/cn/rankin/apiweb/controller/LoginController.java
  2. 123 0
      rankin-api-web/src/main/java/cn/rankin/apiweb/controller/QRcodeController.java
  3. 1 0
      rankin-api-web/src/main/java/cn/rankin/apiweb/intercepter/RequestSignatureInterceptor.java
  4. 35 0
      rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserClient.java
  5. 122 25
      rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserService.java
  6. 6 0
      rankin-cms-web/pom.xml
  7. 172 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtCampusController.java
  8. 197 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtStatsController.java
  9. 249 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtTerminalUserController.java
  10. 152 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtUserTagController.java
  11. 51 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/user/MerchantPermitDeviceController.java
  12. 7 3
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/user/UserDeviceController.java
  13. 33 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/stmt/StmtCampusService.java
  14. 36 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/stmt/StmtTerminalUserService.java
  15. 23 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/stmt/StmtUserTagService.java
  16. 30 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/user/MerchantPermitDeviceService.java
  17. 4 4
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/user/UserDeviceService.java
  18. 10 0
      rankin-common-utils/pom.xml
  19. 21 4
      rankin-common-utils/src/main/java/cn/rankin/common/utils/util/DateUtil.java
  20. 122 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/util/FastJsonUtils.java
  21. 54 0
      rankin-common-utils/src/main/java/cn/rankin/common/utils/util/QRCodeUtil.java
  22. 12 0
      rankin-data-api/src/main/java/cn/rankin/data/api/app/dto/DeviceLoginDTO.java
  23. 4 0
      rankin-data-api/src/main/java/cn/rankin/data/api/auth/dto/AuthQueryDTO.java
  24. 27 0
      rankin-data-api/src/main/java/cn/rankin/data/api/cms/StmtSearchDTO.java
  25. 28 0
      rankin-data-api/src/main/java/cn/rankin/data/api/cms/vo/UserTagStmt.java
  26. 37 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/MerchantPermitDeviceDTO.java
  27. 33 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/QRCodeDTO.java
  28. 6 1
      rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/TerminalUserSearchDTO.java
  29. 27 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/UserDeviceSearchDTO.java
  30. 4 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/UserTagSearchDTO.java
  31. 88 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/LocationInfo.java
  32. 49 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/MerchantPermitDevice.java
  33. 50 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/QRCode.java
  34. 2 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/CampusVo.java
  35. 13 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/DeviceModelVo.java
  36. 31 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/MerchantPermitDeviceVo.java
  37. 33 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/QRCodeVo.java
  38. 12 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/TerminalUserAuthVo.java
  39. 0 1
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/CourseSubRelationRepository.java
  40. 1 0
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/service/ResourceService.java
  41. 78 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/MerchantPermitDeviceController.java
  42. 134 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/QRCodeController.java
  43. 266 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/StmtCampusController.java
  44. 429 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/StmtTerminalUserController.java
  45. 32 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/StmtUserTagController.java
  46. 159 68
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/TerminalUserController.java
  47. 8 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/UserDeviceController.java
  48. 1 1
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/DownloadInfoRepository.java
  49. 8 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/LocationInfoRepository.java
  50. 21 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/MerchantPermitDeviceRepository.java
  51. 16 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/QRCodeRepository.java
  52. 31 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/StmtRepository.java
  53. 2 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/TerminalDeviceRepository.java
  54. 8 1
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/UserDeviceRepository.java
  55. 3 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/UserTagRepository.java
  56. 17 0
      rankin-user-service/src/main/java/cn/rankin/userservice/service/LocationInfoService.java
  57. 88 0
      rankin-user-service/src/main/java/cn/rankin/userservice/service/MerchantPermitDeviceService.java
  58. 52 0
      rankin-user-service/src/main/java/cn/rankin/userservice/service/QRCodeService.java
  59. 81 0
      rankin-user-service/src/main/java/cn/rankin/userservice/service/StmtService.java
  60. 11 1
      rankin-user-service/src/main/java/cn/rankin/userservice/service/TerminalDeviceService.java
  61. 32 5
      rankin-user-service/src/main/java/cn/rankin/userservice/service/UserDeviceService.java
  62. 1 0
      rankin-user-service/src/main/java/cn/rankin/userservice/utils/Converter.java
  63. 12 0
      rankin-user-service/src/main/java/cn/rankin/userservice/utils/DTOConverter.java

+ 106 - 13
rankin-api-web/src/main/java/cn/rankin/apiweb/controller/LoginController.java

@@ -41,19 +41,16 @@ public class LoginController
         String merchant = request.getHeader("merchant");
         String userAgent = request.getHeader("User-Agent");
 
+
         String ip = HttpUtil.getClientIp(request);
         loginInfoDTO.setIp(ip);
         loginInfoDTO.setTerminal(terminal);
         loginInfoDTO.setMerchant(merchant);
 
-       String mac = MacAddressHelper.getMacInLinux(ip);
-
+        log.info("login request header : ip={},terminal={},merchant={},user-agent={}", ip, terminal, merchant,userAgent);
         //填充设备信息
         fillDeviceInfo(userAgent, loginInfoDTO);
 
-        log.info("login request header : ip={},terminal={},merchant={},mac={},user-agent={}", ip, terminal, merchant, mac,userAgent);
-
-
         return userService.login(loginInfoDTO);
     }
 
@@ -62,8 +59,13 @@ public class LoginController
     {
         String deviceCode = deviceLoginDTO.getDeviceCode();
         String merchant = request.getHeader("merchant");
-        log.info("refresh request header : deviceCode={}, merchant={}", deviceCode, merchant);
-        return userService.refresh(deviceCode, merchant, Boolean.TRUE);
+        String userAgent = request.getHeader("User-Agent");
+        log.info("refresh request header : deviceCode={}, merchant={},userAgent={}", deviceCode, merchant,userAgent);
+
+        //填充设备信息
+        fillDeviceInfo(userAgent, deviceLoginDTO);
+
+        return userService.refresh(deviceCode, merchant, Boolean.TRUE,deviceLoginDTO);
     }
 
     @RequestMapping(method = RequestMethod.DELETE)
@@ -78,6 +80,79 @@ public class LoginController
      * @param userAgentStr the string of user agent
      * @param loginInfoDTO the login info
      */
+    private void fillDeviceInfo(String userAgentStr, DeviceLoginDTO loginInfoDTO)
+    {
+        if (userAgentStr == "" || userAgentStr == null)
+        {
+            return;
+        }
+        if (loginInfoDTO == null)
+        {
+            return;
+        }
+
+        UserAgent userAgent = UserAgent.parseUserAgentString(userAgentStr);
+
+        //获取浏览器对象
+        Browser browser = userAgent.getBrowser();
+
+        //获取操作系统对象
+        OperatingSystem operatingSystem = userAgent.getOperatingSystem();
+
+        //操作系统名称
+        String osName = operatingSystem.getName();
+        loginInfoDTO.setDeviceName(osName);
+
+        //获取厂商
+        String osMfrs = operatingSystem.getManufacturer().toString();
+        loginInfoDTO.setDeviceMfrs(osMfrs);
+
+        //获取设备类型
+        String deviceType = operatingSystem.getDeviceType().toString();
+        loginInfoDTO.setDeviceType(deviceType);
+
+        //获取设备型号
+        //获取设备型号
+        if ("MOBILE".equals(deviceType))
+        {
+            String split[] = userAgentStr.split("Build/");
+
+            if(split!=null || split.length > 0)
+            {
+                String splitType[] =  split[0].split(";");
+                if(splitType!=null && splitType.length>0)
+                {
+                    loginInfoDTO.setDeviceModel(splitType[splitType.length-1]);
+                }
+
+            }
+
+        }
+        else if ("TABLET".equals(deviceType))
+        {
+            String split[] = userAgentStr.split("Build/");
+
+            if(split!=null || split.length > 0)
+            {
+                String splitType[] =  split[0].split(";");
+                if(splitType!=null && splitType.length>0)
+                {
+                    loginInfoDTO.setDeviceModel(splitType[splitType.length-1]);
+                }
+
+            }
+        }
+        else
+        {
+            loginInfoDTO.setDeviceModel(osName);
+        }
+    }
+
+    /**
+     * Fill device info
+     * @param userAgentStr the string of user agent
+     * @param loginInfoDTO the login info
+     */
     private void fillDeviceInfo(String userAgentStr, LoginInfoDTO loginInfoDTO)
     {
         if (userAgentStr == "" || userAgentStr == null)
@@ -112,13 +187,31 @@ public class LoginController
         //获取设备型号
         if ("MOBILE".equals(deviceType))
         {
-            Pattern pattern = Pattern.compile(";\\s?(\\S*?\\s?\\S*?)\\s?(Build)?/");
-            Matcher matcher = pattern.matcher(userAgentStr);
-            String model = null;
-            if (matcher.find())
+            String split[] = userAgentStr.split("Build/");
+
+            if(split!=null || split.length > 0)
             {
-                model = matcher.group(1).trim();
-                loginInfoDTO.setDeviceModel(model);
+                String splitType[] =  split[0].split(";");
+                if(splitType!=null && splitType.length>0)
+                {
+                    loginInfoDTO.setDeviceModel(splitType[splitType.length-1]);
+                }
+
+            }
+
+        }
+        else if ("TABLET".equals(deviceType))
+        {
+            String split[] = userAgentStr.split("Build/");
+
+            if(split!=null || split.length > 0)
+            {
+                String splitType[] =  split[0].split(";");
+                if(splitType!=null && splitType.length>0)
+                {
+                    loginInfoDTO.setDeviceModel(splitType[splitType.length-1]);
+                }
+
             }
         }
         else

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

@@ -0,0 +1,123 @@
+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.common.utils.util.FastJsonUtils;
+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.*;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+
+@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);
+    }
+
+    @RequestMapping(value = "/callback", method = RequestMethod.POST)
+    public APIResult callback(@RequestParam("data") String data)
+    {
+        log.info("qrcode/callback request json : json={},", data);
+        return userService.qrcodeCallback(data);
+    }
+
+
+    public static String getJson (){
+
+        //二维码信息
+        Map<String,Object> qrcode = new HashMap<>();
+        qrcode.put("user","100166661101001");
+        qrcode.put("time",new Date().getTime());
+
+        //扫码定位信息
+        Map<String,Object> position = new HashMap<>();
+        position.put("lat","27.10444444");
+        position.put("lng","101.5688746");
+        position.put("precise","位置精确度低");
+        position.put("address","湖南省长沙市五一大道壹号公馆");
+
+        //扫码人老师信息
+        Map<String,Object> teacher_info = new HashMap<>();
+        teacher_info.put("real_name","方老师");
+        teacher_info.put("mobile","17319266010");
+        teacher_info.put("position","校长");
+        teacher_info.put("en_code","10056");
+
+
+        //扫码人校区信息
+        Map<String,Object> campus_info = new HashMap<>();
+        campus_info.put("campus_name","芙蓉校区");
+        campus_info.put("en_code","10056");
+        campus_info.put("lat","27.10444444");
+        campus_info.put("lng","101.5688746");
+
+        //其他附加消息
+        Map<String,Object> attach = new HashMap<>();
+
+
+
+        Map<String,Object> data = new HashMap<>();
+        data.put("qrcode",qrcode);
+        data.put("position",position);
+        data.put("teacher_info",teacher_info);
+        data.put("campus_info",campus_info);
+        data.put("attach",attach);
+
+
+
+        Map<String,Object> result = new HashMap<>();
+        result.put("code","0");
+        result.put("status",true);
+        result.put("msg","扫码成功");
+        result.put("data",data);
+        result.put("user","100166661101001");
+
+
+        String json = FastJsonUtils.toJSONNoFeatures(result);
+        System.out.println(json);
+        return json;
+
+    }
+
+
+    public static void main(String[] args){
+        String json = getJson();
+
+        Map<Object, Object> objectMap = FastJsonUtils.stringToCollect(json);
+
+        Object code = objectMap.get("code");
+        Object status = objectMap.get("status");
+        Object msg = objectMap.get("msg");
+        Object data = objectMap.get("data");
+
+        System.out.println("=============");
+
+    }
+
+}
+

+ 1 - 0
rankin-api-web/src/main/java/cn/rankin/apiweb/intercepter/RequestSignatureInterceptor.java

@@ -44,6 +44,7 @@ public class RequestSignatureInterceptor implements HandlerInterceptor {
 
     static {
         ignorePaths.add("/token");
+        ignorePaths.add("/qrcode/callback");
     }
 
     @Autowired

+ 35 - 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,19 @@ 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);
+
+    @RequestMapping(value = "/qrcode/callback", method = RequestMethod.POST)
+    APIResult qrcodeCallback(@RequestParam("data")String data);
+
+    @RequestMapping(value = "/qrcode/status/fail", method = RequestMethod.PUT)
+    void updateQrcodesStatus(@RequestParam("eid") String eid);
+
+
     @Component
     class UserServiceHystrix implements UserClient
     {
@@ -162,6 +177,26 @@ public interface UserClient
             return null;
         }
 
+        @Override
+        public QRCodeVo qrcode(QRCodeDTO dto) {
+            return null;
+        }
+
+        @Override
+        public QRCodeVo queryLastQRCode(String eid) {
+            return null;
+        }
+
+        @Override
+        public APIResult qrcodeCallback(String data) {
+            return null;
+        }
+
+        @Override
+        public void updateQrcodesStatus(String eid) {
+
+        }
+
 
     }
 }

+ 122 - 25
rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserService.java

@@ -3,21 +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;
@@ -30,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
@@ -79,27 +82,7 @@ public class UserService
             return APIResult.error(ApiWebCode.LOGIN_ERROR);
         }
 
-        //操作用户登录设备信息
-        if (deviceName != null && !"".equals(deviceName.trim()))
-        {
-            String uid = userVo.getId();
-            UserDeviceDTO dto = new UserDeviceDTO();
-            dto.setDeviceCode(deviceCode);
-            dto.setDeviceModel(deviceModel);
-            dto.setDeviceType(deviceType);
-            dto.setDeviceMfrs(deviceMfrs);
-            dto.setDeviceName(deviceName);
 
-            int opRet = userClient.opUserDevice(uid,dto);
-            if (opRet == 0)
-            {
-                log.error("Failed to operated user device with[uid={},deviceCode={},deviceModel={},deviceName={}]", uid, deviceCode, deviceModel, deviceName);
-            }
-            else
-            {
-                log.info("Succeed to operating user device with[uid={},deviceCode={},deviceModel={},deviceName={}]", uid, deviceCode, deviceModel, deviceName);
-            }
-        }
 
         String storePassword = userVo.getPassword();
         if (!SecurityManager.validate(loginPassword, storePassword))
@@ -153,6 +136,32 @@ public class UserService
         UserInfoVo userInfoVo = toUserInfoVo(deviceUserVo, true);
         log.info("user={} login success, userInfo={}", eid, JSON.toJSONString(userInfoVo));
 
+
+        //操作用户登录设备信息
+        if (deviceName != null && !"".equals(deviceName.trim()))
+        {
+            UserDeviceDTO dto = new UserDeviceDTO();
+            dto.setDeviceCode(deviceCode);
+            dto.setDeviceModel(deviceModel);
+            dto.setDeviceType(deviceType);
+            dto.setDeviceMfrs(deviceMfrs);
+            dto.setDeviceName(deviceName);
+            if(deviceModel == "" || deviceModel == null)
+            {
+                dto.setDeviceModel("未知");
+            }
+
+            int opRet = userClient.opUserDevice(userId,dto);
+            if (opRet == 0)
+            {
+                log.error("Failed to operated user device with[uid={},deviceCode={},deviceModel={},deviceName={}]", userId, deviceCode, deviceModel, deviceName);
+            }
+            else
+            {
+                log.info("Succeed to operating user device with[uid={},deviceCode={},deviceModel={},deviceName={}]", userId, deviceCode, deviceModel, deviceName);
+            }
+        }
+
         return APIResult.ok(userInfoVo);
     }
 
@@ -230,7 +239,7 @@ public class UserService
         return toDeviceUserVo(userVo, deviceVo);
     }
 
-    public APIResult<UserInfoVo> refresh(String deviceCode, String merchant, Boolean force)
+    public APIResult<UserInfoVo> refresh(String deviceCode, String merchant, Boolean force, DeviceLoginDTO deviceLoginDTO)
     {
 
         List<TerminalDeviceVo> deviceVoList = userClient.findByDeviceCode(deviceCode);
@@ -301,6 +310,36 @@ public class UserService
         refreshToken(deviceUserVo);
         save(deviceUserVo);
 
+        //获取设备台账
+        String deviceModel = deviceLoginDTO.getDeviceModel();
+        String deviceMfrs = deviceLoginDTO.getDeviceMfrs();
+        String deviceName = deviceLoginDTO.getDeviceName();
+        String deviceType = deviceLoginDTO.getDeviceType();
+        //操作用户登录设备信息
+        if (deviceName != null && !"".equals(deviceName.trim()))
+        {
+            UserDeviceDTO dto = new UserDeviceDTO();
+            dto.setDeviceCode(deviceCode);
+            dto.setDeviceModel(deviceModel);
+            dto.setDeviceType(deviceType);
+            dto.setDeviceMfrs(deviceMfrs);
+            dto.setDeviceName(deviceName);
+            if(deviceModel == "" || deviceModel == null)
+            {
+                dto.setDeviceModel("未知");
+            }
+
+            int opRet = userClient.opUserDevice(uid,dto);
+            if (opRet == 0)
+            {
+                log.error("Failed to operated user device with[uid={},deviceCode={},deviceModel={},deviceName={}]", uid, deviceCode, deviceModel, deviceName);
+            }
+            else
+            {
+                log.info("Succeed to operating user device with[uid={},deviceCode={},deviceModel={},deviceName={}]", uid, deviceCode, deviceModel, deviceName);
+            }
+        }
+
         UserInfoVo userInfoVo = toUserInfoVo(deviceUserVo, true);
         return APIResult.ok(userInfoVo);
     }
@@ -436,4 +475,62 @@ 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();
+
+
+        //生成新二维码入库前,将所有的待验证的二维码状态置为失败
+        userClient.updateQrcodesStatus(eid);
+
+
+
+        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);
+    }
+
+    public APIResult qrcodeCallback(String data) {
+        return userClient.qrcodeCallback(data);
+    }
 }

+ 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;
+    }
+
+}

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

@@ -0,0 +1,197 @@
+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.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;
+
+
+@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 searchDTO the search Dto
+     * @return
+     */
+    @RequestMapping(value = {"/export", "/"}, method = RequestMethod.GET)
+    public APIResult<Page<TerminalUserVo>> campusListExport(HttpServletResponse res, @NeedUser UserDetails user, TerminalUserSearchDTO searchDTO) {
+        if (!user.isPlatForm()) {
+            String merchantId = user.getMerchantId();
+            searchDTO.setMerchantId(merchantId);
+        }
+
+        //
+        //下载所有
+        searchDTO.setPageNo(1);
+        searchDTO.setPageSize(10000);
+
+        APIResult<Page<TerminalUserVo>> pageAPIResult = terminalUserService.search(BeanUtil.convertToMap(searchDTO));
+
+        if (!pageAPIResult.getSuccess()) {
+            return null;
+        }
+
+        Page<TerminalUserVo> userTagStmtPage = pageAPIResult.getData();
+
+        if (null != userTagStmtPage) {
+            List<TerminalUserVo> list = userTagStmtPage.getList();
+
+            //创建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("终端状态");
+
+            //单元格日期格式
+            HSSFCellStyle cellStyle = wb.createCellStyle();
+            HSSFDataFormat format = wb.createDataFormat();
+            cellStyle.setDataFormat(format.getFormat("yyyy/mm/dd"));
+
+            //插入数据
+            if (!CollectionUtils.isEmpty(list)) {
+                for (int i = 0; i < list.size(); i++) {
+                    TerminalUserVo vo = list.get(i);
+
+                    HSSFRow row = sheet.createRow(i + 1);
+                    row.createCell(0).setCellValue(vo.getMerchantName());
+                    row.createCell(1).setCellValue(vo.getCampusName());
+                    row.createCell(2).setCellValue(vo.getCode());
+                    row.createCell(3).setCellValue(vo.getName());
+                    row.createCell(4).setCellValue(vo.getStatus().getName());
+                }
+            }
+
+            try {
+                long currentTime = new Date().getTime();
+                //输出Excel文件
+                OutputStream output = res.getOutputStream();
+                res.reset();
+                res.setHeader("Content-disposition", "attachment; filename=lingjiao_stats_" + currentTime + ".xls");
+                res.setContentType("application/msexcel");
+                wb.write(output);
+                output.close();
+            } catch (Exception ex) {
+
+            }
+
+            return null;
+        }
+        return null;
+    }
+
+
+    /**
+     * 获取校区总数
+     *
+     * @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());
+                }
+            }
+        }
+    }
+
+}

+ 152 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/stmt/StmtUserTagController.java

@@ -0,0 +1,152 @@
+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.StmtUserTagService;
+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.cms.StmtSearchDTO;
+import cn.rankin.data.api.cms.vo.UserTagStmt;
+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;
+
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/stmt/userTagStmt")
+public class StmtUserTagController
+{
+    @Autowired
+    private StmtUserTagService stmtService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<UserTagStmt>> search(@NeedUser UserDetails user, StmtSearchDTO searchDTO) {
+        if (!user.isPlatForm()) {
+            searchDTO.setMerchantId(user.getMerchantId());
+        }
+        return stmtService.UserTagStmtPage(BeanUtil.convertToMap(searchDTO));
+
+    }
+
+    /**
+     * 查询已开通校区报表
+     *
+     * @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, StmtSearchDTO searchDTO)
+    {
+        if (!user.isPlatForm())
+        {
+            searchDTO.setMerchantId(user.getMerchantId());
+        }
+
+        //下载所有
+        searchDTO.setPageNo(1);
+        searchDTO.setPageSize(10000);
+
+        APIResult<Page<UserTagStmt>> pageAPIResult = stmtService.UserTagStmtPage(BeanUtil.convertToMap(searchDTO));
+        if(!pageAPIResult.getSuccess()){
+            return null;
+        }
+
+        Page<UserTagStmt> userTagStmtPage = pageAPIResult.getData();
+        if(null != userTagStmtPage){
+            List<UserTagStmt> list = userTagStmtPage.getList();
+
+            //创建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("标签数量");
+
+            //单元格日期格式
+            HSSFCellStyle cellStyle = wb.createCellStyle();
+            HSSFDataFormat format = wb.createDataFormat();
+            cellStyle.setDataFormat(format.getFormat("yyyy/mm/dd"));
+
+            //插入数据
+            if (!CollectionUtils.isEmpty(list))
+            {
+                for (int i = 0; i < list.size(); i++)
+                {
+                    UserTagStmt stmt = list.get(i);
+
+                    HSSFRow row = sheet.createRow(i + 1);
+                    row.createCell(0).setCellValue(stmt.getUCode());
+                    row.createCell(1).setCellValue(stmt.getCName());
+                    row.createCell(2).setCellValue(stmt.getCName());
+                    row.createCell(3).setCellValue(stmt.getUserTags().toString());
+                    row.createCell(4).setCellValue(stmt.getUserTagNum());
+                }
+            }
+
+            try
+            {
+                long currentTime = new Date().getTime();
+                //输出Excel文件
+                OutputStream output = res.getOutputStream();
+                res.reset();
+                res.setHeader("Content-disposition", "attachment; filename=lingjiao_user_tag_" + currentTime + ".xls");
+                res.setContentType("application/msexcel");
+                wb.write(output);
+                output.close();
+            }
+            catch (Exception ex)
+            {
+
+            }
+
+
+
+
+
+
+
+
+
+
+
+
+
+        }else{
+            return null;
+        }
+
+
+
+
+        return null;
+    }
+
+
+}

+ 51 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/user/MerchantPermitDeviceController.java

@@ -0,0 +1,51 @@
+package cn.rankin.cmsweb.controller.user;
+
+import cn.rankin.cmsweb.service.user.MerchantPermitDeviceService;
+import cn.rankin.common.utils.api.model.APICode;
+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.MerchantPermitDeviceDTO;
+import cn.rankin.data.api.user.vo.MerchantPermitDeviceVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping(value = "/merchantPermitDevice")
+public class MerchantPermitDeviceController
+{
+
+    @Autowired
+    private MerchantPermitDeviceService merchantPermitDeviceService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<MerchantPermitDeviceVo>> search(MerchantPermitDeviceDTO searchDTO) {
+        return merchantPermitDeviceService.search(BeanUtil.convertToMap(searchDTO));
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<MerchantPermitDeviceVo> create(@RequestBody MerchantPermitDeviceDTO dto){
+        return merchantPermitDeviceService.create(dto);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<MerchantPermitDeviceVo> update(@Valid @RequestBody MerchantPermitDeviceDTO dto){
+        if (dto.getId() == null) {
+            return APIResult.error(APICode.PARAMETER_ERROR);
+        }
+        return merchantPermitDeviceService.update(dto);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable String id) {
+        return merchantPermitDeviceService.delete(id);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<MerchantPermitDeviceVo> getMerchantPermitDevice(@PathVariable String id) {
+        return merchantPermitDeviceService.getMerchantPermitDevice(id);
+    }
+
+}

+ 7 - 3
rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/user/UserDeviceController.java

@@ -3,16 +3,14 @@ package cn.rankin.cmsweb.controller.user;
 
 import cn.rankin.cmsweb.service.user.UserDeviceService;
 import cn.rankin.common.utils.api.model.APIResult;
-import cn.rankin.data.api.user.entity.DownloadInfo;
 import cn.rankin.data.api.user.entity.UserDevice;
-import com.alibaba.fastjson.JSON;
+import cn.rankin.data.api.user.vo.DeviceModelVo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
-
 /**
  * The controller of user device
  */
@@ -31,5 +29,11 @@ public class UserDeviceController
 
         return APIResult.ok(list);
     }
+
+    @RequestMapping(value = "/model/list", method = RequestMethod.GET)
+    public APIResult<List<DeviceModelVo>> searchDeviceModel(@RequestParam("deviceModel") String deviceModel) {
+        APIResult<List<DeviceModelVo>> apiResult = userDeviceService.searchDeviceModel(deviceModel);
+        return apiResult;
+    }
 }
 

+ 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);
+}

+ 23 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/stmt/StmtUserTagService.java

@@ -0,0 +1,23 @@
+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.cms.vo.UserTagStmt;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+@FeignClient(value = "${service.user.name}")
+public interface StmtUserTagService {
+
+    /**
+     * 条件查询
+     * 已配置用户标签   终端信息
+     * @param searchDTO
+     * @return
+     */
+    @RequestMapping(value = "/stmt/userTagStmt/list", method = RequestMethod.GET)
+    APIResult<Page<UserTagStmt>> UserTagStmtPage(@RequestParam Map<String,Object> searchDTO);
+
+}

+ 30 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/user/MerchantPermitDeviceService.java

@@ -0,0 +1,30 @@
+package cn.rankin.cmsweb.service.user;
+
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.data.api.user.dto.MerchantPermitDeviceDTO;
+import cn.rankin.data.api.user.vo.MerchantPermitDeviceVo;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+@FeignClient(name = "${service.user.name}")
+public interface MerchantPermitDeviceService {
+
+    @RequestMapping(value = "/merchantPermitDevice/list", method = RequestMethod.GET)
+    APIResult<Page<MerchantPermitDeviceVo>> search(@RequestParam Map<String, Object> searchDTO);
+
+    @RequestMapping(value = "/merchantPermitDevice", method = RequestMethod.POST)
+    APIResult<MerchantPermitDeviceVo> create(@RequestBody MerchantPermitDeviceDTO dto);
+
+    @RequestMapping(value = "/merchantPermitDevice", method = RequestMethod.PUT)
+    APIResult<MerchantPermitDeviceVo> update(@RequestBody MerchantPermitDeviceDTO dto);
+
+    @RequestMapping(value = "/merchantPermitDevice/{id}", method = RequestMethod.DELETE)
+    APIResult<Boolean> delete(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/merchantPermitDevice/{id}", method = RequestMethod.GET)
+    APIResult<MerchantPermitDeviceVo> getMerchantPermitDevice(@PathVariable("id") String id);
+
+}

+ 4 - 4
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/user/UserDeviceService.java

@@ -1,19 +1,19 @@
 package cn.rankin.cmsweb.service.user;
 
 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.entity.UserDevice;
-import cn.rankin.data.api.user.vo.CampusVo;
+import cn.rankin.data.api.user.vo.DeviceModelVo;
 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 UserDeviceService
 {
     @RequestMapping(value = "/userDevice/list/{uid}", method = RequestMethod.GET)
     List<UserDevice> findByCondition(@PathVariable("uid") String uid);
+
+    @RequestMapping(value = "/userDevice/model/list", method = RequestMethod.GET)
+    APIResult<List<DeviceModelVo>> searchDeviceModel(@RequestParam("deviceModel") String deviceModel);
 }

+ 10 - 0
rankin-common-utils/pom.xml

@@ -91,6 +91,16 @@
             <artifactId>commons-lang3</artifactId>
             <version>3.4</version>
         </dependency>
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+            <version>3.3.3</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>javase</artifactId>
+            <version>3.3.3</version>
+        </dependency>
 
     </dependencies>
 

+ 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);
+
+
+
+    }
+}
+

+ 12 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/app/dto/DeviceLoginDTO.java

@@ -12,4 +12,16 @@ public class DeviceLoginDTO implements Serializable{
     private String deviceCode;
 
     private String merchant;
+
+    //设备名称
+    private String deviceName;
+
+    //设备型号
+    private String deviceModel;
+
+    //设备厂商
+    private String deviceMfrs;
+
+    //设备类型
+    private String deviceType;
 }

+ 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;
 }

+ 27 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/cms/StmtSearchDTO.java

@@ -0,0 +1,27 @@
+package cn.rankin.data.api.cms;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+
+@Data
+@ToString
+public class StmtSearchDTO implements Serializable {
+
+    private String merchantId;
+
+    private String campusId;
+
+    private String name;
+
+    private String uid;
+
+    private String code;
+
+    private String sort;
+
+    private Integer pageNo = 1;
+
+    private Integer pageSize = 10;
+}

+ 28 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/cms/vo/UserTagStmt.java

@@ -0,0 +1,28 @@
+package cn.rankin.data.api.cms.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+import javax.persistence.Entity;
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+@ToString
+@Entity
+public class UserTagStmt implements Serializable {
+
+    private String cName;
+
+    private String uid;
+
+    private String uName;
+
+    private String uCode;
+
+    private List<String> userTags;
+
+    private int userTagNum;
+
+
+}

+ 37 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/MerchantPermitDeviceDTO.java

@@ -0,0 +1,37 @@
+package cn.rankin.data.api.user.dto;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import lombok.Data;
+import lombok.ToString;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@ToString
+public class MerchantPermitDeviceDTO implements Serializable {
+
+    private String id;
+
+    private String merchantId;
+
+    private String deviceModel;
+
+    @NotNull
+    private String provinceCode;
+
+    private BaseStatusEnum status;
+
+    private Date gmtCreated;
+
+    private Date gmtModified;
+
+    private Integer pageNo = 1;
+
+    private Integer pageSize = 10;
+
+}
+
+
+

+ 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;
+
+}
+
+
+

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

@@ -2,11 +2,14 @@ package cn.rankin.data.api.user.dto;
 
 import cn.rankin.common.utils.enums.BaseStatusEnum;
 import lombok.Data;
+import lombok.ToString;
 
 import java.io.Serializable;
 
 @Data
-public class TerminalUserSearchDTO implements Serializable {
+@ToString
+public class TerminalUserSearchDTO implements Serializable
+{
 
     private String code;
 
@@ -23,4 +26,6 @@ public class TerminalUserSearchDTO implements Serializable {
     private Integer pageNo = 1;
 
     private Integer pageSize = 10;
+
+    private Integer fastExpired = 0;
 }

+ 27 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/UserDeviceSearchDTO.java

@@ -0,0 +1,27 @@
+package cn.rankin.data.api.user.dto;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+@Data
+@ToString
+public class UserDeviceSearchDTO  implements Serializable
+{
+    private String userId;
+
+    private String deviceCode;
+
+    private String deviceModel;
+
+    private String deviceMfrs;
+
+    private String deviceName;
+
+    private String deviceType;
+
+    private Integer pageNo = 1;
+
+    private Integer pageSize = 10;
+
+}

+ 4 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/UserTagSearchDTO.java

@@ -9,6 +9,10 @@ import java.io.Serializable;
 @ToString
 public class UserTagSearchDTO implements Serializable {
 
+    private String merchantId;
+
+    private String campusId;
+
     private String name;
 
     private String uid;

+ 88 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/LocationInfo.java

@@ -0,0 +1,88 @@
+package cn.rankin.data.api.user.entity;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+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_location_info")
+@DynamicInsert
+@DynamicUpdate
+public class LocationInfo 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="lat")
+    private String lat;                 //经纬度
+
+    @Column(name="lng")
+    private String lng;                 //经纬度
+
+    @Column(name="precise")
+    private String precise;             //说明
+
+    @Column(name="address")
+    private String address;             //地址
+
+    //老师信息
+    @Column(name="t_real_name")
+    private String tRealName;
+
+    @Column(name="t_mobile")
+    private String tMobile;
+
+    @Column(name="t_position")
+    private String tPosition;
+
+    @Column(name="t_en_code")
+    private String tEnCode;
+
+    //校区信息
+    @Column(name="campus_name")
+    private String campusName;
+
+    @Column(name="c_en_code")
+    private String cEnCode;
+
+    @Column(name="c_lat")
+    private String cLat;
+
+    @Column(name="c_lng")
+    private String cLng;
+
+    @Enumerated(EnumType.ORDINAL)
+    @Column(name="status")
+    private BaseStatusEnum 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;
+
+}
+
+
+

+ 49 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/MerchantPermitDevice.java

@@ -0,0 +1,49 @@
+package cn.rankin.data.api.user.entity;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+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_merchant_permit_device")
+@DynamicInsert
+@DynamicUpdate
+public class MerchantPermitDevice implements Serializable {
+    @Id
+    @Column(name="id")
+    private String id;
+
+    @Column(name="merchant_id")
+    private String merchantId;
+
+    //设备型号
+    @Column(name="device_model")
+    private String deviceModel;
+
+    @Column(name = "province_code")
+    private String provinceCode;
+
+    @Enumerated(EnumType.ORDINAL)
+    private BaseStatusEnum 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;
+
+}
+
+
+

+ 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;

+ 13 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/DeviceModelVo.java

@@ -0,0 +1,13 @@
+package cn.rankin.data.api.user.vo;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+
+@Data
+@ToString
+public class DeviceModelVo  implements Serializable
+{
+    private String deviceModel;
+}

+ 31 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/MerchantPermitDeviceVo.java

@@ -0,0 +1,31 @@
+package cn.rankin.data.api.user.vo;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@ToString
+public class MerchantPermitDeviceVo implements Serializable {
+
+    private String id;
+
+    private String merchantId;
+
+    private String deviceModel;
+
+    private String provinceCode;
+
+    private BaseStatusEnum status;
+
+    private Date gmtCreated;
+
+    private Date gmtModified;
+
+}
+
+
+

+ 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;
 }

+ 0 - 1
rankin-product-service/src/main/java/cn/rankin/productservice/repository/CourseSubRelationRepository.java

@@ -13,7 +13,6 @@ public interface CourseSubRelationRepository extends BasicJpaRepository<CourseSu
 
     List<CourseSubRelation> findByCourseId(String courseId);
 
-
     @Query(value = "select r.* from p_course_sub_relation r where r.course_id = :courseId and r.status = 0 order by r.sort limit 1", nativeQuery = true)
     CourseSubRelation findFirstByCourseIdOrderBySort(@Param("courseId") String courseId);
 

+ 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());

+ 78 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/controller/MerchantPermitDeviceController.java

@@ -0,0 +1,78 @@
+package cn.rankin.userservice.controller;
+
+import cn.rankin.common.utils.api.model.APICode;
+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.data.api.user.dto.MerchantPermitDeviceDTO;
+import cn.rankin.data.api.user.dto.MerchantSearchDTO;
+import cn.rankin.data.api.user.dto.UserDeviceDTO;
+import cn.rankin.data.api.user.entity.Merchant;
+import cn.rankin.data.api.user.entity.MerchantPermitDevice;
+import cn.rankin.data.api.user.entity.UserDevice;
+import cn.rankin.data.api.user.vo.MerchantPermitDeviceVo;
+import cn.rankin.userservice.helper.RaStringHelper;
+import cn.rankin.userservice.service.MerchantPermitDeviceService;
+import cn.rankin.userservice.service.UserDeviceService;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+
+@RestController
+@RequestMapping(value = "/merchantPermitDevice")
+public class MerchantPermitDeviceController
+{
+
+    @Autowired
+    private MerchantPermitDeviceService merchantPermitDeviceService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<MerchantPermitDevice>> search(MerchantPermitDeviceDTO searchDTO) {
+        MerchantPermitDevice simple = new MerchantPermitDevice();
+        String merchantId = searchDTO.getMerchantId();
+        if (StringUtils.isNotBlank(merchantId)) {
+            simple.setMerchantId(merchantId);
+        }
+
+        String provinceCode = searchDTO.getProvinceCode();
+        if (StringUtils.isNotBlank(provinceCode)) {
+            simple.setProvinceCode(provinceCode);
+        }
+
+        // sort
+        LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap<>();
+        sort.put("gmtModified", BaseOrderEnum.DESC);
+
+        return merchantPermitDeviceService.search(simple, searchDTO.getPageNo(), searchDTO.getPageSize(), sort);
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<MerchantPermitDevice> create(@Valid @RequestBody MerchantPermitDeviceDTO dto){
+        return merchantPermitDeviceService.create(dto);
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<MerchantPermitDevice> update(@Valid @RequestBody MerchantPermitDeviceDTO dto){
+        if (dto.getId() == null) {
+            return APIResult.error(APICode.PARAMETER_ERROR);
+        }
+        return merchantPermitDeviceService.update(dto);
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult<Boolean> delete(@PathVariable String id) {
+        return merchantPermitDeviceService.delete(id);
+
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<MerchantPermitDevice> getMerchantPermitDevice(@PathVariable String id) {
+        return merchantPermitDeviceService.getMerchantPermitDevice(id);
+    }
+
+}

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

@@ -0,0 +1,134 @@
+package cn.rankin.userservice.controller;
+
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.util.FastJsonUtils;
+import cn.rankin.data.api.user.dto.QRCodeDTO;
+import cn.rankin.data.api.user.entity.LocationInfo;
+import cn.rankin.data.api.user.entity.QRCode;
+import cn.rankin.userservice.service.LocationInfoService;
+import cn.rankin.userservice.service.QRCodeService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Date;
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/qrcode")
+public class QRCodeController {
+
+    @Autowired
+    private QRCodeService qrcodeService;
+
+    @Autowired
+    private LocationInfoService locationInfoService;
+
+    @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);
+    }
+
+    @RequestMapping(value = "/status/fail", method = RequestMethod.PUT)
+    public void updateStatusFail(@RequestParam("eid") String eid ){
+        qrcodeService.updateStatusFail(eid);
+    }
+
+    @RequestMapping(value = "/callback", method = RequestMethod.POST)
+    public APIResult callback(@RequestParam("data") String data)
+    {
+
+        try{
+            Map<String, Object> requestMap = FastJsonUtils.stringToCollect(data);
+
+            boolean status = (boolean) requestMap.get("status");
+            Map<String, Object> dataMap = (Map<String, Object>) requestMap.get("data");
+
+
+            Map<String, Object> qrcodeMap = (Map<String, Object>) dataMap.get("qrcode");
+            String eid = (String) qrcodeMap.get("user");
+            long time = (long) qrcodeMap.get("time");
+
+            QRCode qrcode = new QRCode();
+            qrcode.setEid(eid);
+            //qrcode.setTime(new Date(time));
+
+            QRCode entity = qrcodeService.findFirst(qrcode);
+
+            if(null == entity){
+                log.error("qrcode/callback  error ,qrcode is null");
+                return APIResult.ok("扫码失败,未找到二维码信息");
+            }
+
+            if(status){
+                qrcodeCallback(eid, entity.getSimple(), dataMap);
+                entity.setStatus(2);
+                qrcodeService.update(entity);
+                return APIResult.ok("扫码成功");
+            }else{
+                entity.setStatus(1);
+                qrcodeService.update(entity);
+                return APIResult.ok("扫码失败");
+            }
+        }catch(Exception e){
+            return APIResult.ok("扫码失败");
+        }
+    }
+
+    /**
+     * 处理位置信息
+     * @param dataMap
+     */
+    private void qrcodeCallback(String eid,String simple ,Map<String,Object> dataMap) {
+
+        Map<String,Object> position = (Map<String, Object>) dataMap.get("position");
+        String lat = (String) position.get("lat");
+        String lng = (String) position.get("lng");
+        String precise = (String) position.get("precise");
+        String address = (String) position.get("address");
+
+        Map<String,Object> teacher_info = (Map<String, Object>) dataMap.get("teacher_info");
+        String tRealName = (String) teacher_info.get("real_name");
+        String tMobile = (String) teacher_info.get("mobile");
+        String tPosition = (String) teacher_info.get("position");
+        String tEnCode = (String) teacher_info.get("en_code");
+
+
+        Map<String,Object> campus_info = (Map<String, Object>) dataMap.get("campus_info");
+        String campusName = (String) campus_info.get("campus_name");
+        String cEnCode = (String) campus_info.get("en_code");
+        String cLat = (String) campus_info.get("lat");
+        String cLng = (String) campus_info.get("lng");
+        Map<String,Object> attach = (Map<String, Object>) dataMap.get("attach");
+
+
+        LocationInfo locationInfo = new LocationInfo();
+        locationInfo.setEid(eid);
+        locationInfo.setSimple(simple);
+        locationInfo.setAddress(address);
+        locationInfo.setLat(lat);
+        locationInfo.setLng(lng);
+        locationInfo.setPrecise(precise);
+
+
+        locationInfo.setTRealName(tRealName);
+        locationInfo.setTEnCode(tEnCode);
+        locationInfo.setTMobile(tMobile);
+        locationInfo.setTPosition(tPosition);
+
+        locationInfo.setCampusName(campusName);
+        locationInfo.setCEnCode(cEnCode);
+        locationInfo.setCLat(cLat);
+        locationInfo.setCLng(cLng);
+
+        locationInfoService.add(locationInfo);
+
+    }
+
+}

+ 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());
+        }
+    }
+
+}

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

@@ -0,0 +1,429 @@
+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) {
+        log.info("request param = {}",terminalUserSearchDTO.toString());
+        TerminalUser terminalUser = new TerminalUser();
+
+        String code = terminalUserSearchDTO.getCode();
+
+        if (!StringUtils.isEmpty(code)) {
+            terminalUser.setCode("%" + code + "%");
+        }
+        String campusId = terminalUserSearchDTO.getCampusId();
+        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);
+            }
+        });
+    }
+
+
+}

+ 32 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/controller/StmtUserTagController.java

@@ -0,0 +1,32 @@
+package cn.rankin.userservice.controller;
+
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.data.api.cms.StmtSearchDTO;
+import cn.rankin.data.api.cms.vo.UserTagStmt;
+import cn.rankin.userservice.service.StmtService;
+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/userTagStmt")
+public class StmtUserTagController
+{
+    @Autowired
+    private StmtService stmtService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<UserTagStmt>> UserTagStmtPage(StmtSearchDTO searchDTO) {
+        return stmtService.userTagStmtPage(searchDTO.getCode(),searchDTO.getMerchantId(),searchDTO.getCampusId(),searchDTO.getPageSize(),searchDTO.getPageNo());
+    }
+
+
+
+
+}

+ 159 - 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,109 @@ 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);
+        }
+
+        String campusId = terminalUserSearchDTO.getCampusId();
+        if (!StringUtils.isEmpty(campusId))
+        {
+            log.info("/user/auth/list | request campusId={}", campusId);
+            terminalUser.setCampusId(campusId);
+        }
+
         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 +276,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 +298,8 @@ public class TerminalUserController {
 
         // 存储数据库
         APIResult<TerminalUser> result = terminalUserService.create(terminalUserDTO);
-        if (!result.getSuccess()) {
+        if (!result.getSuccess())
+        {
             return result;
         }
 
@@ -252,30 +310,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 +348,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 +361,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 +374,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 +391,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 +413,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 +439,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 +448,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 +467,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 +481,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 +492,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);
             }
         });
     }
 
 
-
-
 }

+ 8 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/controller/UserDeviceController.java

@@ -1,7 +1,9 @@
 package cn.rankin.userservice.controller;
 
+import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.data.api.user.dto.UserDeviceDTO;
 import cn.rankin.data.api.user.entity.UserDevice;
+import cn.rankin.data.api.user.vo.DeviceModelVo;
 import cn.rankin.userservice.helper.RaStringHelper;
 import cn.rankin.userservice.service.UserDeviceService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -50,4 +52,10 @@ public class UserDeviceController
         return userDeviceService.findByUserId(uid);
     }
 
+    @RequestMapping(value = "/model/list", method = RequestMethod.GET)
+    public APIResult<List<DeviceModelVo>> searchDeviceModel(@RequestParam("deviceModel") String deviceModel) {
+        APIResult<List<DeviceModelVo>> apiResult = userDeviceService.searchDeviceModel(deviceModel);
+        return apiResult;
+    }
+
 }

+ 1 - 1
rankin-user-service/src/main/java/cn/rankin/userservice/repository/DownloadInfoRepository.java

@@ -11,7 +11,7 @@ import java.util.List;
 
 public interface DownloadInfoRepository extends BasicJpaRepository<DownloadInfo, String> {
 
-    @Query(value = "select info from DownloadInfo info where info.userId = ?1 AND info.mac = ?2 AND info.eventType= ?3 AND info.status = ?4 ORDER BY info.gmtCreated DESC ")
+    @Query(value = "select info from DownloadInfo info where info.userId = ?1 AND info.mac = ?2 AND info.eventType= ?3 AND info.status = ?4 ORDER BY info.gmtModified DESC ")
     List<DownloadInfo> findByUserId(String uid, String mac, EventTypeEnum eventType, BaseStatusEnum status);
 
     @Query(value = "select info from DownloadInfo info where info.userId = ?1 AND info.lessonId = ?2 AND info.mac = ?3 AND info.eventType = ?4  AND info.status = ?5 ORDER BY info.gmtCreated DESC ")

+ 8 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/repository/LocationInfoRepository.java

@@ -0,0 +1,8 @@
+package cn.rankin.userservice.repository;
+
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.data.api.user.entity.LocationInfo;
+
+public interface LocationInfoRepository extends BasicJpaRepository<LocationInfo, String> {
+
+}

+ 21 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/repository/MerchantPermitDeviceRepository.java

@@ -0,0 +1,21 @@
+package cn.rankin.userservice.repository;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.data.api.user.entity.MerchantPermitDevice;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+
+public interface MerchantPermitDeviceRepository extends BasicJpaRepository<MerchantPermitDevice, String> {
+
+    @Query(value = "select m from MerchantPermitDevice m where m.merchantId = :merchantId AND m.status = :status ")
+    List<MerchantPermitDevice> findByMerchantId(@Param("merchantId")String merchantId, @Param("status") BaseStatusEnum status);
+
+    @Modifying
+    @Query("update MerchantPermitDevice m set m.status = :status where m.id = :id ")
+    Integer updateStatusById(@Param("id") String id, @Param("status") BaseStatusEnum status);
+}

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

@@ -0,0 +1,16 @@
+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.Modifying;
+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);
+
+    @Modifying
+    @Query(value = "update QRCode qr set qr.status = 1 where qr.eid = ?1 and qr.status = 0 ")
+    void updateStatusFail(String eid);
+}

+ 31 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/repository/StmtRepository.java

@@ -0,0 +1,31 @@
+package cn.rankin.userservice.repository;
+
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.data.api.user.entity.UserTag;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+public interface StmtRepository extends BasicJpaRepository<UserTag, String> {
+
+    /**
+     * 配置用户标签的终端数量
+     * @param merchantId
+     * @param campusId
+     * @return
+     */
+    @Query(value = "SELECT COUNT(1) FROM u_terminal_user tu " +
+            " WHERE tu.id IN ( SELECT tag.uid FROM u_user_tag tag WHERE tag.status = 0 )" +
+            " AND if(?1 !='',tu.code LIKE CONCAT('%',?1,'%'),1=1) " +
+            " AND if(?2 !='',tu.merchant_id=?2,1=1) " +
+            " AND if(?3 !='',tu.campus_id=?3,1=1) ",nativeQuery = true)
+    int userCount(String code, String merchantId, String campusId);
+
+    @Query(value = "SELECT  tu.id  FROM u_terminal_user tu " +
+            " WHERE tu.id IN ( SELECT tag.uid FROM u_user_tag tag WHERE tag.status = 0 ) " +
+            " AND if(?1 !='',tu.code LIKE CONCAT('%',?1,'%'),1=1) " +
+            " AND if(?2 !='',tu.merchant_id=?2,1=1) " +
+            " AND if(?3 !='',tu.campus_id=?3,1=1)  " +
+            " ORDER BY tu.gmt_created DESC LIMIT ?4,?5  ",nativeQuery = true)
+    List<String> uidList(String code, String merchantId, String campusId, long start, Integer pageSize);
+}

+ 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

+ 8 - 1
rankin-user-service/src/main/java/cn/rankin/userservice/repository/UserDeviceRepository.java

@@ -27,6 +27,13 @@ public interface UserDeviceRepository extends BasicJpaRepository<UserDevice, Str
      * @param userId the id of user
      * @return
      */
-    @Query(value = "select u from  UserDevice  u where u.userId = ?1")
+    @Query(value = "select u from  UserDevice  u where u.userId = ?1 order by u.gmtModified desc")
     List<UserDevice> findByUserId(String userId);
+
+    /**
+     * 查询所有已采集到的设备类型(去除重复)
+     * @return
+     */
+    @Query(value = "select distinct(u.deviceModel) from  UserDevice  u where u.deviceModel LIKE CONCAT('%',?1,'%') order by u.gmtModified desc")
+    List<String> queryDeviceModel(String deviceModel);
 }

+ 3 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/repository/UserTagRepository.java

@@ -30,4 +30,7 @@ public interface UserTagRepository extends BasicJpaRepository<UserTag, String> {
 
     @Query(value = "select t from UserTag t where t.uid = ?1  order by t.sort")
     List<UserTag> findUserTagByUid(String uid);
+
+    @Query(value = "select t from UserTag t where t.uid = ?1 and t.status = ?2 order by t.sort")
+    List<UserTag> findUserTagByUidStatus(String uid,BaseStatusEnum status);
 }

+ 17 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/service/LocationInfoService.java

@@ -0,0 +1,17 @@
+package cn.rankin.userservice.service;
+
+import cn.rankin.data.api.user.entity.LocationInfo;
+import cn.rankin.userservice.repository.LocationInfoRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class LocationInfoService {
+
+    @Autowired
+    private LocationInfoRepository locationInfoRepository;
+
+    public void add(LocationInfo locationInfo) {
+        locationInfoRepository.save(locationInfo);
+    }
+}

+ 88 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/service/MerchantPermitDeviceService.java

@@ -0,0 +1,88 @@
+package cn.rankin.userservice.service;
+
+import cn.rankin.common.utils.api.model.APICode;
+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.JpaSortUtil;
+import cn.rankin.data.api.user.dto.MerchantPermitDeviceDTO;
+import cn.rankin.data.api.user.entity.MerchantPermitDevice;
+import cn.rankin.userservice.repository.MerchantPermitDeviceRepository;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import static cn.rankin.userservice.utils.DTOConverter.convert;
+
+@Service
+public class MerchantPermitDeviceService
+{
+    @Autowired
+    private MerchantPermitDeviceRepository merchantPermitDeviceRepository;
+
+    public APIResult<MerchantPermitDevice> findByMerchantId(String merchantId){
+        List<MerchantPermitDevice> merchantPermitDevices = merchantPermitDeviceRepository.findByMerchantId(merchantId, BaseStatusEnum.NORMAL);
+        return APIResult.ok(merchantPermitDevices);
+    }
+
+    @Transactional
+    public APIResult<MerchantPermitDevice> create(MerchantPermitDeviceDTO dto) {
+        MerchantPermitDevice entity = convert(dto);
+        MerchantPermitDevice result = merchantPermitDeviceRepository.save(entity);
+
+        if(null == result ){
+            return APIResult.error(APICode.OPERATE_ERROR);
+        }
+
+        return APIResult.ok(result);
+    }
+
+    public APIResult<Page<MerchantPermitDevice>> search(MerchantPermitDevice simple, Integer pageNo, Integer pageSize, LinkedHashMap<String,BaseOrderEnum> sort) {
+        Long count = merchantPermitDeviceRepository.count(simple);
+        Page<MerchantPermitDevice> page = new Page<>(count, pageNo, pageSize);
+
+        if (count == 0) {
+            return APIResult.ok(page);
+        }
+
+        List<MerchantPermitDevice> list = merchantPermitDeviceRepository.find(simple, page.getStart(), page.getPageSize(), JpaSortUtil.sort(sort));
+        page.setList(list);
+
+        return APIResult.ok(page);
+    }
+
+    @Transactional
+    public APIResult<MerchantPermitDevice> update(MerchantPermitDeviceDTO dto) {
+        MerchantPermitDevice entity = convert(dto);
+        MerchantPermitDevice result = merchantPermitDeviceRepository.update(entity);
+
+        if(null == result ){
+            return APIResult.error(APICode.OPERATE_ERROR);
+        }
+
+        return APIResult.ok(result);
+    }
+
+    @Transactional
+    public APIResult<Boolean> delete(String id) {
+        Integer count = merchantPermitDeviceRepository.updateStatusById(id, BaseStatusEnum.DEL);
+
+        if (count == 0) {
+            return APIResult.error(APICode.NOT_EXISTS);
+        }
+        return APIResult.ok(true);
+    }
+
+    public APIResult<MerchantPermitDevice> getMerchantPermitDevice(String id) {
+        if(StringUtils.isBlank(id)){
+            return APIResult.error(APICode.OPERATE_ERROR);
+        }
+        MerchantPermitDevice result = merchantPermitDeviceRepository.find(id);
+        return APIResult.ok(result);
+    }
+}

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

@@ -0,0 +1,52 @@
+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 javax.transaction.Transactional;
+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;
+    }
+
+    public QRCode findFirst(QRCode simple) {
+        return qrcodeRepository.findFirst(simple);
+    }
+
+    public void update(QRCode qrcode) {
+        qrcodeRepository.update(qrcode);
+    }
+
+    @Transactional
+    public void updateStatusFail(String eid) {
+        qrcodeRepository.updateStatusFail(eid);
+    }
+}

+ 81 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/service/StmtService.java

@@ -0,0 +1,81 @@
+package cn.rankin.userservice.service;
+
+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.JpaSortUtil;
+import cn.rankin.data.api.cms.vo.UserTagStmt;
+import cn.rankin.data.api.user.dto.UserTagDTO;
+import cn.rankin.data.api.user.entity.Campus;
+import cn.rankin.data.api.user.entity.TerminalUser;
+import cn.rankin.data.api.user.entity.UserTag;
+import cn.rankin.userservice.repository.CampusRepository;
+import cn.rankin.userservice.repository.StmtRepository;
+import cn.rankin.userservice.repository.TerminalUserRepository;
+import cn.rankin.userservice.repository.UserTagRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+
+import static cn.rankin.userservice.utils.DTOConverter.convert;
+
+@Slf4j
+@Service
+public class StmtService {
+
+    @Autowired
+    private StmtRepository stmtRepository;
+
+    @Autowired
+    private TerminalUserRepository terminalUserRepository;
+    @Autowired
+    private CampusRepository campusRepository;
+    @Autowired
+    private UserTagRepository userTagRepository;
+
+
+    public APIResult<Page<UserTagStmt>> userTagStmtPage(String code, String merchantId, String campusId, Integer pageSize, Integer pageNo) {
+
+        long count = (long)stmtRepository.userCount(code, merchantId, campusId);
+
+        Page<UserTagStmt> page = new Page(count, pageNo, pageSize);
+        if (count == 0) {
+            return APIResult.ok(page);
+        }
+
+        List<String> uids = stmtRepository.uidList(code, merchantId, campusId, page.getStart() , page.getPageSize());
+
+        List<UserTagStmt> data = new ArrayList<>();
+        uids.forEach(uid -> {
+            TerminalUser terminalUser = terminalUserRepository.find(uid);
+            if(null != terminalUser){
+                UserTagStmt stmt = new UserTagStmt();
+                stmt.setUCode(terminalUser.getCode());
+                stmt.setUid(uid);
+                stmt.setUName(terminalUser.getName());
+                Campus campus = campusRepository.find(terminalUser.getCampusId());
+                if(null != campus){
+                    stmt.setCName(campus.getName());
+                }
+                List<UserTag> userTags = userTagRepository.findUserTagByUidStatus(uid, BaseStatusEnum.NORMAL);
+                if(!CollectionUtils.isEmpty(userTags)){
+                    List<String> tags = new ArrayList<>();
+                    userTags.forEach(userTag -> {
+                        tags.add(userTag.getName());
+                    });
+                    stmt.setUserTags(tags);
+                    stmt.setUserTagNum(tags.size());
+                }
+                data.add(stmt);
+            }
+        });
+
+        page.setList(data);
+        return APIResult.ok(page);
+    }
+}

+ 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);

+ 32 - 5
rankin-user-service/src/main/java/cn/rankin/userservice/service/UserDeviceService.java

@@ -1,15 +1,17 @@
 package cn.rankin.userservice.service;
 
+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.JpaSortUtil;
 import cn.rankin.data.api.user.dto.UserDeviceDTO;
 import cn.rankin.data.api.user.entity.UserDevice;
-import cn.rankin.data.api.user.vo.UserDeviceVo;
-import cn.rankin.userservice.helper.RaStringHelper;
+import cn.rankin.data.api.user.vo.DeviceModelVo;
 import cn.rankin.userservice.repository.UserDeviceRepository;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 
 @Service
 public class UserDeviceService
@@ -20,7 +22,6 @@ public class UserDeviceService
     /**
      * Find
      *
-     * @param userDeviceVo
      * @return
      */
     public int opUserDevice(UserDeviceDTO uerDeviceDTO)
@@ -80,4 +81,30 @@ public class UserDeviceService
         return list;
     }
 
+    public APIResult<Page<UserDevice>> search(UserDevice simple, Integer pageNo, Integer pageSize, LinkedHashMap<String,BaseOrderEnum> sort) {
+        Long count = userDeviceRepository.count(simple);
+        Page<UserDevice> page = new Page<>(count, pageNo, pageSize);
+        if (count == 0) {
+            return APIResult.ok(page);
+        }
+
+
+        List<UserDevice> result = userDeviceRepository.find(simple, page.getStart(), page.getPageSize(), JpaSortUtil.sort(sort));
+        page.setList(result);
+
+        return APIResult.ok(page);
+
+    }
+
+    public APIResult<List<DeviceModelVo>> searchDeviceModel(String deviceModel) {
+        List<String> models = userDeviceRepository.queryDeviceModel(deviceModel);
+        List<DeviceModelVo> deviceModels = new ArrayList<>();
+        models.forEach(model -> {
+            DeviceModelVo vo = new DeviceModelVo();
+            vo.setDeviceModel(model);
+            deviceModels.add(vo);
+        });
+
+        return APIResult.ok(deviceModels);
+    }
 }

+ 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;

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

@@ -76,4 +76,16 @@ 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;
+    }
+
+    public static MerchantPermitDevice convert(MerchantPermitDeviceDTO dto) {
+        MerchantPermitDevice entity = new MerchantPermitDevice();
+        BeanUtils.copyProperties(dto, entity);
+        return entity;
+    }
 }