Commit 3d531b98cd7e6edcff151f567c757dd098ae2032

Authored by 王彪总
1 parent 9750b443

fix(config): 更新配置文件和修复分页计算问题

- 在.gitignore中添加.mcp.json文件忽略
- 更新application-dev.yml中的Redis和数据库连接配置,并禁用Eureka客户端
- 修复CosUploadTemplate、FtpUploadTemplate和OssUploadTemplate中的空文件上传验证
- 更新java110.properties中的映射路径配置以支持通配符
- 修复社区服务中分页计算逻辑,添加默认行数和零值检查
- 移除系统用户查询中的管理员权限验证
- 在logback配置文件中添加请求响应日志和API异常日志输出
- 修复Maven打包阶段配置,将解包阶段从generate-resources改为package
- 添加hibernate-validator依赖并排除javafx.base冲突
- 扩展文件上传组件以支持multipart文件上传和IP地址获取功能
Showing 20 changed files with 493 additions and 23 deletions
docs/app_version.sql 0 → 100644
  1 +-- App version check table
  2 +DROP TABLE IF EXISTS `app_version`;
  3 +CREATE TABLE `app_version` (
  4 + `id` int NOT NULL AUTO_INCREMENT,
  5 + `av_id` varchar(30) NOT NULL COMMENT 'version ID',
  6 + `version_code` int NOT NULL COMMENT 'e.g. 100',
  7 + `version_name` varchar(20) NOT NULL COMMENT 'e.g. 1.0.0',
  8 + `download_url` varchar(500) NOT NULL COMMENT 'APK download URL',
  9 + `force_update` tinyint DEFAULT 0 COMMENT '0=optional 1=force',
  10 + `update_message` text COMMENT 'update description',
  11 + `platform` varchar(10) DEFAULT 'android' COMMENT 'android/ios',
  12 + `status_cd` varchar(2) DEFAULT '0',
  13 + `create_time` timestamp DEFAULT CURRENT_TIMESTAMP,
  14 + PRIMARY KEY (`id`),
  15 + KEY `idx_platform` (`platform`, `status_cd`)
  16 +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  17 +
  18 +-- Seed data: current version
  19 +INSERT INTO `app_version` (`av_id`, `version_code`, `version_name`, `download_url`, `force_update`, `update_message`, `platform`, `status_cd`)
  20 +VALUES ('AV20260518001', 100, '1.0.0', 'https://spms.xrparking.cn/app/download', 0, '初始版本', 'android', '0');
  21 +INSERT INTO c_service (service_id, service_code, business_type_cd, name, seq, is_instance, url, method, timeout, retry_count, provide_app_id, status_cd)
  22 +VALUES ('SVCPROPVER', 'property.checkVersion', 'API', '版本检查', 1, 'CMD', 'http://user-service', 'POST', 60, 3, '8000418002', '0');
  23 +
  24 +INSERT INTO c_route (app_id, service_id, order_type_cd, invoke_limit_times, invoke_model, status_cd)
  25 +VALUES ('992020022270580001', 'SVCPROPVER', 'Q', -1, 'S', '0');
java110-core/src/main/java/com/java110/core/client/CosUploadTemplate.java
@@ -39,6 +39,11 @@ public class CosUploadTemplate { @@ -39,6 +39,11 @@ public class CosUploadTemplate {
39 */ 39 */
40 public String upload(String imageBase64, String server, int port, 40 public String upload(String imageBase64, String server, int port,
41 String userName, String userPassword, String ftpPath) { 41 String userName, String userPassword, String ftpPath) {
  42 + return upload(imageBase64, server, port, userName, userPassword, ftpPath, "jpg");
  43 + }
  44 +
  45 + public String upload(String imageBase64, String server, int port,
  46 + String userName, String userPassword, String ftpPath, String suffix) {
42 if (imageBase64 == null || imageBase64.isEmpty()) { 47 if (imageBase64 == null || imageBase64.isEmpty()) {
43 throw new IllegalArgumentException("上传文件失败: 文件内容为空"); 48 throw new IllegalArgumentException("上传文件失败: 文件内容为空");
44 } 49 }
@@ -60,9 +65,9 @@ public class CosUploadTemplate { @@ -60,9 +65,9 @@ public class CosUploadTemplate {
60 fileName += ".jpg"; 65 fileName += ".jpg";
61 } else if (imageBase64.contains("data:application/octet-stream;base64,")) { 66 } else if (imageBase64.contains("data:application/octet-stream;base64,")) {
62 imageBase64 = imageBase64.replace("data:application/octet-stream;base64,", ""); 67 imageBase64 = imageBase64.replace("data:application/octet-stream;base64,", "");
63 - fileName += ".jpg"; 68 + fileName += "." + suffix;
64 } else { 69 } else {
65 - fileName += ".jpg"; 70 + fileName += "." + suffix;
66 } 71 }
67 urlPath = IMAGE_DEFAULT_PATH + DateUtil.getNowII() + "/" + fileName; 72 urlPath = IMAGE_DEFAULT_PATH + DateUtil.getNowII() + "/" + fileName;
68 byte[] context = Base64Convert.base64ToByte(imageBase64); 73 byte[] context = Base64Convert.base64ToByte(imageBase64);
java110-core/src/main/java/com/java110/core/client/FtpUploadTemplate.java
@@ -47,6 +47,11 @@ public class FtpUploadTemplate { @@ -47,6 +47,11 @@ public class FtpUploadTemplate {
47 */ 47 */
48 public String upload(String imageBase64, String server, int port, 48 public String upload(String imageBase64, String server, int port,
49 String userName, String userPassword, String ftpPath) { 49 String userName, String userPassword, String ftpPath) {
  50 + return upload(imageBase64, server, port, userName, userPassword, ftpPath, "jpg");
  51 + }
  52 +
  53 + public String upload(String imageBase64, String server, int port,
  54 + String userName, String userPassword, String ftpPath, String suffix) {
50 if (imageBase64 == null || imageBase64.isEmpty()) { 55 if (imageBase64 == null || imageBase64.isEmpty()) {
51 throw new IllegalArgumentException("上传文件失败: 文件内容为空"); 56 throw new IllegalArgumentException("上传文件失败: 文件内容为空");
52 } 57 }
@@ -55,7 +60,6 @@ public class FtpUploadTemplate { @@ -55,7 +60,6 @@ public class FtpUploadTemplate {
55 ByteArrayInputStream is = null; 60 ByteArrayInputStream is = null;
56 try { 61 try {
57 ftpClient = new FTPClient(); 62 ftpClient = new FTPClient();
58 - // request.setCharacterEncoding("utf-8");  
59 if (!ftpClient.isConnected()) { 63 if (!ftpClient.isConnected()) {
60 ftpClient.connect(server, port); 64 ftpClient.connect(server, port);
61 } 65 }
@@ -63,10 +67,9 @@ public class FtpUploadTemplate { @@ -63,10 +67,9 @@ public class FtpUploadTemplate {
63 ftpClient.enterLocalPassiveMode(); 67 ftpClient.enterLocalPassiveMode();
64 ftpClient.setFileType(FTP.BINARY_FILE_TYPE); 68 ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
65 ftpPath = ftpPath + IMAGE_DEFAULT_PATH + DateUtil.getNowII() + "/"; 69 ftpPath = ftpPath + IMAGE_DEFAULT_PATH + DateUtil.getNowII() + "/";
66 - mkDir(ftpClient, ftpPath);// 创建目录  
67 - // 设置上传目录 must 70 + mkDir(ftpClient, ftpPath);
68 ftpClient.changeWorkingDirectory(ftpPath); 71 ftpClient.changeWorkingDirectory(ftpPath);
69 - if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK). 72 + if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
70 LOCAL_CHARSET = "UTF-8"; 73 LOCAL_CHARSET = "UTF-8";
71 } 74 }
72 fileName = UUID.randomUUID().toString(); 75 fileName = UUID.randomUUID().toString();
@@ -81,9 +84,9 @@ public class FtpUploadTemplate { @@ -81,9 +84,9 @@ public class FtpUploadTemplate {
81 fileName += ".jpg"; 84 fileName += ".jpg";
82 } else if (imageBase64.contains("data:application/octet-stream;base64,")) { 85 } else if (imageBase64.contains("data:application/octet-stream;base64,")) {
83 imageBase64 = imageBase64.replace("data:application/octet-stream;base64,", ""); 86 imageBase64 = imageBase64.replace("data:application/octet-stream;base64,", "");
84 - fileName += ".jpg"; 87 + fileName += "." + suffix;
85 } else { 88 } else {
86 - fileName += ".jpg"; 89 + fileName += "." + suffix;
87 } 90 }
88 FTPFile[] fs = ftpClient.listFiles(fileName); 91 FTPFile[] fs = ftpClient.listFiles(fileName);
89 if (fs.length == 0) { 92 if (fs.length == 0) {
java110-core/src/main/java/com/java110/core/client/OssUploadTemplate.java
@@ -42,6 +42,11 @@ public class OssUploadTemplate { @@ -42,6 +42,11 @@ public class OssUploadTemplate {
42 */ 42 */
43 public String upload(String imageBase64, String server, int port, 43 public String upload(String imageBase64, String server, int port,
44 String userName, String userPassword, String ftpPath) { 44 String userName, String userPassword, String ftpPath) {
  45 + return upload(imageBase64, server, port, userName, userPassword, ftpPath, "jpg");
  46 + }
  47 +
  48 + public String upload(String imageBase64, String server, int port,
  49 + String userName, String userPassword, String ftpPath, String suffix) {
45 if (imageBase64 == null || imageBase64.isEmpty()) { 50 if (imageBase64 == null || imageBase64.isEmpty()) {
46 throw new IllegalArgumentException("上传文件失败: 文件内容为空"); 51 throw new IllegalArgumentException("上传文件失败: 文件内容为空");
47 } 52 }
@@ -64,9 +69,9 @@ public class OssUploadTemplate { @@ -64,9 +69,9 @@ public class OssUploadTemplate {
64 fileName += ".jpg"; 69 fileName += ".jpg";
65 } else if (imageBase64.contains("data:application/octet-stream;base64,")) { 70 } else if (imageBase64.contains("data:application/octet-stream;base64,")) {
66 imageBase64 = imageBase64.replace("data:application/octet-stream;base64,", ""); 71 imageBase64 = imageBase64.replace("data:application/octet-stream;base64,", "");
67 - fileName += ".jpg"; 72 + fileName += "." + suffix;
68 } else { 73 } else {
69 - fileName += ".jpg"; 74 + fileName += "." + suffix;
70 } 75 }
71 urlPath = IMAGE_DEFAULT_PATH + DateUtil.getNowII() + "/" + fileName; 76 urlPath = IMAGE_DEFAULT_PATH + DateUtil.getNowII() + "/" + fileName;
72 byte[] context = Base64Convert.base64ToByte(imageBase64); 77 byte[] context = Base64Convert.base64ToByte(imageBase64);
service-api/src/main/java/com/java110/api/components/uploadFile/UploadFileComponent.java
@@ -46,6 +46,22 @@ public class UploadFileComponent { @@ -46,6 +46,22 @@ public class UploadFileComponent {
46 } 46 }
47 47
48 /** 48 /**
  49 + * 上传APK文件
  50 + */
  51 + public ResponseEntity<String> uploadApk(IPageData pd, MultipartFile uploadFile) throws Exception {
  52 + JSONObject paramIn = JSONObject.parseObject(pd.getReqData());
  53 + String originalFilename = uploadFile.getOriginalFilename();
  54 + String suffix = "apk";
  55 + if (originalFilename != null && originalFilename.contains(".")) {
  56 + suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
  57 + }
  58 + paramIn.put("suffix", suffix);
  59 + IPageData newPd = PageData.newInstance().builder(pd.getUserId(), pd.getUserName(), pd.getToken(), paramIn.toJSONString(), pd.getComponentCode(), pd.getComponentMethod(), "",
  60 + pd.getSessionId(), pd.getAppId(), pd.getHeaders());
  61 + return addFileSMOImpl.saveFile(newPd, uploadFile);
  62 + }
  63 +
  64 + /**
49 * 上传图片(兼容 base64 JSON 和 multipart 文件两种方式) 65 * 上传图片(兼容 base64 JSON 和 multipart 文件两种方式)
50 * 66 *
51 * @param pd 页面数据封装 67 * @param pd 页面数据封装
service-api/src/main/java/com/java110/api/configuration/ServiceConfiguration.java
@@ -17,10 +17,10 @@ public class ServiceConfiguration { @@ -17,10 +17,10 @@ public class ServiceConfiguration {
17 @Bean 17 @Bean
18 public MultipartConfigElement multipartConfigElement() { 18 public MultipartConfigElement multipartConfigElement() {
19 MultipartConfigFactory factory = new MultipartConfigFactory(); 19 MultipartConfigFactory factory = new MultipartConfigFactory();
20 - //文件最大  
21 - factory.setMaxFileSize(1024*1024*50); //KB,MB 20 + //文件最大 200MB
  21 + factory.setMaxFileSize(1024*1024*200); //KB,MB
22 /// 设置总上传数据总大小 22 /// 设置总上传数据总大小
23 - factory.setMaxRequestSize(1024*1024*50); 23 + factory.setMaxRequestSize(1024*1024*200);
24 return factory.createMultipartConfig(); 24 return factory.createMultipartConfig();
25 } 25 }
26 @Bean 26 @Bean
@@ -138,6 +138,7 @@ public class ServiceConfiguration { @@ -138,6 +138,7 @@ public class ServiceConfiguration {
138 exclusions.append("/app/fee.listOwnerTelOweFee,");// 根据手机号查询欠费 138 exclusions.append("/app/fee.listOwnerTelOweFee,");// 根据手机号查询欠费
139 exclusions.append("/app/mall.queryCommunityRecommend,");// 查询项目推荐 139 exclusions.append("/app/mall.queryCommunityRecommend,");// 查询项目推荐
140 exclusions.append("/app/file/userfile/download/*,");// 下载文件 140 exclusions.append("/app/file/userfile/download/*,");// 下载文件
  141 + exclusions.append("/app/downloadApk,");// APK下载代理
141 142
142 143
143 144
service-api/src/main/java/com/java110/api/controller/component/CallComponentController.java
@@ -41,6 +41,8 @@ import org.springframework.web.multipart.MultipartFile; @@ -41,6 +41,8 @@ import org.springframework.web.multipart.MultipartFile;
41 41
42 import javax.servlet.http.HttpServletRequest; 42 import javax.servlet.http.HttpServletRequest;
43 import javax.servlet.http.HttpServletResponse; 43 import javax.servlet.http.HttpServletResponse;
  44 +import java.io.InputStream;
  45 +import java.io.OutputStream;
44 import java.lang.reflect.InvocationTargetException; 46 import java.lang.reflect.InvocationTargetException;
45 import java.lang.reflect.Method; 47 import java.lang.reflect.Method;
46 import java.util.Map; 48 import java.util.Map;
@@ -334,6 +336,37 @@ public class CallComponentController extends DefaultAbstractComponentSMO { @@ -334,6 +336,37 @@ public class CallComponentController extends DefaultAbstractComponentSMO {
334 } 336 }
335 337
336 /** 338 /**
  339 + * APK 文件下载代理
  340 + * 通过后端代理下载OSS上的APK文件,避免OSS禁止APK公网分发的问题
  341 + */
  342 + @RequestMapping(path = "/app/downloadApk")
  343 + public void downloadApk(@RequestParam String file, HttpServletResponse response) {
  344 + InputStream is = null;
  345 + OutputStream os = null;
  346 + try {
  347 + Object componentInstance = ApplicationContextFactory.getBean("ossUploadTemplate");
  348 + Method m = componentInstance.getClass().getDeclaredMethod("download", String.class);
  349 + is = (InputStream) m.invoke(componentInstance, file);
  350 +
  351 + response.setContentType("application/vnd.android.package-archive");
  352 + response.setHeader("Content-Disposition", "attachment; filename=\"app-release.apk\"");
  353 + os = response.getOutputStream();
  354 + byte[] buffer = new byte[4096];
  355 + int len;
  356 + while ((len = is.read(buffer)) != -1) {
  357 + os.write(buffer, 0, len);
  358 + }
  359 + os.flush();
  360 + } catch (Exception e) {
  361 + logger.error("APK下载失败", e);
  362 + try { response.sendError(HttpServletResponse.SC_NOT_FOUND, "文件不存在"); } catch (Exception ignored) {}
  363 + } finally {
  364 + try { if (is != null) is.close(); } catch (Exception ignored) {}
  365 + try { if (os != null) os.close(); } catch (Exception ignored) {}
  366 + }
  367 + }
  368 +
  369 + /**
337 * 刷新 pd 对象 370 * 刷新 pd 对象
338 * 371 *
339 * @param request HttpServletRequest 对象 372 * @param request HttpServletRequest 对象
service-api/src/main/resources/.!78575!wechatAuth.properties 0 → 100644
  1 +java110.auth.wechat.sessionHost=https://api.weixin.qq.com/sns/jscode2session
  2 +java110.auth.wechat.appId=wxf83d66b0e9f5964d
  3 +java110.auth.wechat.secret=cc
  4 +java110.auth.wechat.grantType=authorization_code
  5 +java110.auth.wechat.key=key
  6 +java110.auth.wechat.mchId=mchId
  7 +java110.auth.wechat.wxPayUnifiedOrder=https://api.mch.weixin.qq.com/pay/unifiedorder
  8 +java110.auth.wechat.wxNotifyUrl=http://www.vipwuye.com/app/payment/notify
  9 +java110.auth.wechat.rentingNotifyUrl=http://www.vipwuye.com/app/payment/rentingNotify
  10 +java110.auth.wechat.goodsNotifyUrl=http://www.vipwuye.com/goods/notify
  11 +java110.auth.wechat.oweFeeNotifyUrl=http://www.vipwuye.com/app/payment/oweFeeNotify
  12 +java110.auth.wechat.tempCarFeeNotifyUrl=http://www.vipwuye.com/app/payment/tempCarFeeNotifyUrl
  13 +
service-api/src/main/resources/application-dev.yml
@@ -16,8 +16,8 @@ server: @@ -16,8 +16,8 @@ server:
16 spring: 16 spring:
17 servlet: 17 servlet:
18 multipart: 18 multipart:
19 - maxFileSize: 50MB  
20 - maxRequestSize: 50MB 19 + maxFileSize: 200MB
  20 + maxRequestSize: 200MB
21 http: 21 http:
22 encoding: 22 encoding:
23 charset: UTF-8 23 charset: UTF-8
service-api/src/main/resources/application-dynamic.yml
@@ -16,8 +16,8 @@ server: @@ -16,8 +16,8 @@ server:
16 spring: 16 spring:
17 servlet: 17 servlet:
18 multipart: 18 multipart:
19 - maxFileSize: 50MB  
20 - maxRequestSize: 50MB 19 + maxFileSize: 200MB
  20 + maxRequestSize: 200MB
21 http: 21 http:
22 encoding: 22 encoding:
23 charset: UTF-8 23 charset: UTF-8
service-api/src/main/resources/application-zihao.yml
@@ -16,8 +16,8 @@ server: @@ -16,8 +16,8 @@ server:
16 spring: 16 spring:
17 servlet: 17 servlet:
18 multipart: 18 multipart:
19 - maxFileSize: 50MB  
20 - maxRequestSize: 50MB 19 + maxFileSize: 200MB
  20 + maxRequestSize: 200MB
21 http: 21 http:
22 encoding: 22 encoding:
23 charset: UTF-8 23 charset: UTF-8
service-common/src/main/java/com/java110/common/smo/impl/FileInnerServiceSMOImpl.java
@@ -51,24 +51,26 @@ public class FileInnerServiceSMOImpl extends BaseServiceSMO implements IFileInne @@ -51,24 +51,26 @@ public class FileInnerServiceSMOImpl extends BaseServiceSMO implements IFileInne
51 String fileName = ""; 51 String fileName = "";
52 String ossSwitch = MappingCache.getValue(MappingConstant.FILE_DOMAIN, OSSUtil.OSS_SWITCH); 52 String ossSwitch = MappingCache.getValue(MappingConstant.FILE_DOMAIN, OSSUtil.OSS_SWITCH);
53 53
  54 + String suffix = fileDto.getSuffix();
  55 + if (suffix == null || suffix.isEmpty()) suffix = "jpg";
  56 +
54 if (OSSUtil.OSS_SWITCH_OSS.equals(ossSwitch)) { 57 if (OSSUtil.OSS_SWITCH_OSS.equals(ossSwitch)) {
55 fileName = ossUploadTemplate.upload(fileDto.getContext(), java110Properties.getFtpServer(), 58 fileName = ossUploadTemplate.upload(fileDto.getContext(), java110Properties.getFtpServer(),
56 java110Properties.getFtpPort(), java110Properties.getFtpUserName(), 59 java110Properties.getFtpPort(), java110Properties.getFtpUserName(),
57 - java110Properties.getFtpUserPassword(), ROOT_PATH); 60 + java110Properties.getFtpUserPassword(), ROOT_PATH, suffix);
58 } else if (COSUtil.COS_SWITCH_COS.equals(ossSwitch)) { 61 } else if (COSUtil.COS_SWITCH_COS.equals(ossSwitch)) {
59 fileName = cosUploadTemplate.upload(fileDto.getContext(), java110Properties.getFtpServer(), 62 fileName = cosUploadTemplate.upload(fileDto.getContext(), java110Properties.getFtpServer(),
60 java110Properties.getFtpPort(), java110Properties.getFtpUserName(), 63 java110Properties.getFtpPort(), java110Properties.getFtpUserName(),
61 - java110Properties.getFtpUserPassword(), ROOT_PATH); 64 + java110Properties.getFtpUserPassword(), ROOT_PATH, suffix);
62 } else { 65 } else {
63 String ftpServer = MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_SERVER); 66 String ftpServer = MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_SERVER);
64 int ftpPort = Integer.parseInt(MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_PORT)); 67 int ftpPort = Integer.parseInt(MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_PORT));
65 String ftpUserName = MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_USERNAME); 68 String ftpUserName = MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_USERNAME);
66 String ftpUserPassword = MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_USERPASSWORD); 69 String ftpUserPassword = MappingCache.getValue(FtpUploadTemplate.FTP_DOMAIN, FtpUploadTemplate.FTP_USERPASSWORD);
67 - //String ftpPath = "hc/";  
68 70
69 fileName = ftpUploadTemplate.upload(fileDto.getContext(), ftpServer, 71 fileName = ftpUploadTemplate.upload(fileDto.getContext(), ftpServer,
70 ftpPort, ftpUserName, 72 ftpPort, ftpUserName,
71 - ftpUserPassword, ROOT_PATH); 73 + ftpUserPassword, ROOT_PATH, suffix);
72 } 74 }
73 return fileName; 75 return fileName;
74 } 76 }
service-user/src/main/java/com/java110/user/cmd/property/CheckVersionCmd.java 0 → 100644
  1 +package com.java110.user.cmd.property;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.java110.core.annotation.Java110Cmd;
  5 +import com.java110.core.context.ICmdDataFlowContext;
  6 +import com.java110.core.event.cmd.Cmd;
  7 +import com.java110.core.event.cmd.CmdEvent;
  8 +import com.java110.user.dao.property.IAppVersionV1ServiceDao;
  9 +import com.java110.vo.ResultVo;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +
  12 +import java.util.HashMap;
  13 +import java.util.Map;
  14 +
  15 +@Java110Cmd(serviceCode = "property.checkVersion")
  16 +public class CheckVersionCmd extends Cmd {
  17 +
  18 + @Autowired
  19 + private IAppVersionV1ServiceDao appVersionV1ServiceDao;
  20 +
  21 + @Override
  22 + public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) {
  23 + }
  24 +
  25 + @Override
  26 + public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) {
  27 + int currentCode = reqJson.getIntValue("versionCode");
  28 + String platform = reqJson.containsKey("platform") ? reqJson.getString("platform") : "android";
  29 +
  30 + Map<String, Object> params = new HashMap<>();
  31 + params.put("platform", platform);
  32 + Map latest = appVersionV1ServiceDao.queryLatestVersion(params);
  33 +
  34 + JSONObject result = new JSONObject();
  35 + result.put("hasUpdate", false);
  36 +
  37 + if (latest != null) {
  38 + Object versionCodeObj = latest.get("version_code");
  39 + int latestCode = 0;
  40 + if (versionCodeObj instanceof Number) {
  41 + latestCode = ((Number) versionCodeObj).intValue();
  42 + } else if (versionCodeObj != null) {
  43 + latestCode = Integer.parseInt(versionCodeObj.toString());
  44 + }
  45 +
  46 + if (latestCode > currentCode) {
  47 + result.put("hasUpdate", true);
  48 + result.put("versionCode", latestCode);
  49 + result.put("versionName", latest.get("version_name") != null ? latest.get("version_name").toString() : "");
  50 + String ossUrl = latest.get("download_url") != null ? latest.get("download_url").toString() : "";
  51 + result.put("downloadUrl", convertToProxyUrl(ossUrl, context));
  52 + result.put("forceUpdate", latest.get("force_update") != null && (Integer.parseInt(latest.get("force_update").toString()) == 1));
  53 + result.put("updateMessage", latest.get("update_message") != null ? latest.get("update_message").toString() : "");
  54 + }
  55 + }
  56 +
  57 + context.setResponseEntity(ResultVo.createResponseEntity(result));
  58 + }
  59 +
  60 + private String convertToProxyUrl(String ossUrl, ICmdDataFlowContext context) {
  61 + if (ossUrl == null || !ossUrl.contains(".oss-")) return ossUrl;
  62 + try {
  63 + java.net.URL url = new java.net.URL(ossUrl);
  64 + String path = url.getPath();
  65 + if (path.startsWith("/")) path = path.substring(1);
  66 + String host = context.getReqHeaders().get("host");
  67 + String scheme = host != null && host.contains("localhost") ? "http" : "https";
  68 + return scheme + "://" + host + "/app/downloadApk?file=" + path;
  69 + } catch (Exception e) {
  70 + return ossUrl;
  71 + }
  72 + }
  73 +}
service-user/src/main/java/com/java110/user/cmd/property/DeleteAppVersionCmd.java 0 → 100644
  1 +package com.java110.user.cmd.property;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.java110.core.annotation.Java110Cmd;
  5 +import com.java110.core.annotation.Java110Transactional;
  6 +import com.java110.core.context.ICmdDataFlowContext;
  7 +import com.java110.core.event.cmd.Cmd;
  8 +import com.java110.core.event.cmd.CmdEvent;
  9 +import com.java110.user.dao.property.IAppVersionV1ServiceDao;
  10 +import com.java110.utils.exception.CmdException;
  11 +import com.java110.utils.util.Assert;
  12 +import com.java110.vo.ResultVo;
  13 +import org.springframework.beans.factory.annotation.Autowired;
  14 +
  15 +import java.util.HashMap;
  16 +import java.util.Map;
  17 +
  18 +@Java110Cmd(serviceCode = "appVersion.deleteAppVersion")
  19 +public class DeleteAppVersionCmd extends Cmd {
  20 +
  21 + @Autowired
  22 + private IAppVersionV1ServiceDao appVersionV1ServiceDao;
  23 +
  24 + @Override
  25 + public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) {
  26 + Assert.hasKeyAndValue(reqJson, "avId", "未包含版本ID");
  27 + }
  28 +
  29 + @Override
  30 + @Java110Transactional
  31 + public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException {
  32 + Map<String, Object> params = new HashMap<>();
  33 + params.put("avId", reqJson.getString("avId"));
  34 +
  35 + int flag = appVersionV1ServiceDao.deleteAppVersion(params);
  36 + if (flag < 1) {
  37 + throw new CmdException("删除版本信息失败");
  38 + }
  39 + context.setResponseEntity(ResultVo.success());
  40 + }
  41 +}
service-user/src/main/java/com/java110/user/cmd/property/ListAppVersionsCmd.java 0 → 100644
  1 +package com.java110.user.cmd.property;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.java110.core.annotation.Java110Cmd;
  5 +import com.java110.core.context.ICmdDataFlowContext;
  6 +import com.java110.core.event.cmd.Cmd;
  7 +import com.java110.core.event.cmd.CmdEvent;
  8 +import com.java110.user.dao.property.IAppVersionV1ServiceDao;
  9 +import com.java110.vo.ResultVo;
  10 +import org.springframework.beans.factory.annotation.Autowired;
  11 +import org.springframework.http.HttpStatus;
  12 +import org.springframework.http.ResponseEntity;
  13 +
  14 +import java.util.HashMap;
  15 +import java.util.List;
  16 +import java.util.Map;
  17 +
  18 +@Java110Cmd(serviceCode = "appVersion.listAppVersions")
  19 +public class ListAppVersionsCmd extends Cmd {
  20 +
  21 + @Autowired
  22 + private IAppVersionV1ServiceDao appVersionV1ServiceDao;
  23 +
  24 + @Override
  25 + public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) {
  26 + super.validatePageInfo(reqJson);
  27 + }
  28 +
  29 + @Override
  30 + public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) {
  31 + Map<String, Object> params = new HashMap<>();
  32 + if (reqJson.containsKey("platform")) params.put("platform", reqJson.getString("platform"));
  33 +
  34 + int count = appVersionV1ServiceDao.queryAppVersionsCount(params);
  35 + List<Map> list = null;
  36 + if (count > 0) {
  37 + int page = reqJson.getIntValue("page");
  38 + int row = reqJson.getIntValue("row");
  39 + params.put("page", (page - 1) * row);
  40 + params.put("row", row);
  41 + list = appVersionV1ServiceDao.queryAppVersions(params);
  42 + }
  43 +
  44 + ResultVo resultVo = new ResultVo((int) Math.ceil((double) count / (double) reqJson.getInteger("row")), count, list);
  45 + context.setResponseEntity(new ResponseEntity<>(resultVo.toString(), HttpStatus.OK));
  46 + }
  47 +}
service-user/src/main/java/com/java110/user/cmd/property/SaveAppVersionCmd.java 0 → 100644
  1 +package com.java110.user.cmd.property;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.java110.core.annotation.Java110Cmd;
  5 +import com.java110.core.annotation.Java110Transactional;
  6 +import com.java110.core.context.ICmdDataFlowContext;
  7 +import com.java110.core.event.cmd.Cmd;
  8 +import com.java110.core.event.cmd.CmdEvent;
  9 +import com.java110.core.factory.GenerateCodeFactory;
  10 +import com.java110.user.dao.property.IAppVersionV1ServiceDao;
  11 +import com.java110.utils.exception.CmdException;
  12 +import com.java110.utils.util.Assert;
  13 +import com.java110.vo.ResultVo;
  14 +import org.springframework.beans.factory.annotation.Autowired;
  15 +
  16 +import java.util.HashMap;
  17 +import java.util.Map;
  18 +
  19 +@Java110Cmd(serviceCode = "appVersion.saveAppVersion")
  20 +public class SaveAppVersionCmd extends Cmd {
  21 +
  22 + @Autowired
  23 + private IAppVersionV1ServiceDao appVersionV1ServiceDao;
  24 +
  25 + @Override
  26 + public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) {
  27 + Assert.hasKeyAndValue(reqJson, "versionCode", "未包含版本号");
  28 + Assert.hasKeyAndValue(reqJson, "versionName", "未包含版本名称");
  29 + Assert.hasKeyAndValue(reqJson, "downloadUrl", "未包含下载地址");
  30 + Assert.hasKeyAndValue(reqJson, "platform", "未包含平台");
  31 + }
  32 +
  33 + @Override
  34 + @Java110Transactional
  35 + public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException {
  36 + Map<String, Object> params = new HashMap<>();
  37 + params.put("avId", GenerateCodeFactory.getGeneratorId("AV"));
  38 + params.put("versionCode", reqJson.getIntValue("versionCode"));
  39 + params.put("versionName", reqJson.getString("versionName"));
  40 + params.put("downloadUrl", reqJson.getString("downloadUrl"));
  41 + params.put("forceUpdate", reqJson.getIntValue("forceUpdate"));
  42 + params.put("updateMessage", reqJson.getString("updateMessage"));
  43 + params.put("platform", reqJson.getString("platform"));
  44 +
  45 + int flag = appVersionV1ServiceDao.saveAppVersion(params);
  46 + if (flag < 1) {
  47 + throw new CmdException("保存版本信息失败");
  48 + }
  49 + context.setResponseEntity(ResultVo.success());
  50 + }
  51 +}
service-user/src/main/java/com/java110/user/cmd/property/UpdateAppVersionCmd.java 0 → 100644
  1 +package com.java110.user.cmd.property;
  2 +
  3 +import com.alibaba.fastjson.JSONObject;
  4 +import com.java110.core.annotation.Java110Cmd;
  5 +import com.java110.core.annotation.Java110Transactional;
  6 +import com.java110.core.context.ICmdDataFlowContext;
  7 +import com.java110.core.event.cmd.Cmd;
  8 +import com.java110.core.event.cmd.CmdEvent;
  9 +import com.java110.user.dao.property.IAppVersionV1ServiceDao;
  10 +import com.java110.utils.exception.CmdException;
  11 +import com.java110.utils.util.Assert;
  12 +import com.java110.vo.ResultVo;
  13 +import org.springframework.beans.factory.annotation.Autowired;
  14 +
  15 +import java.util.HashMap;
  16 +import java.util.Map;
  17 +
  18 +@Java110Cmd(serviceCode = "appVersion.updateAppVersion")
  19 +public class UpdateAppVersionCmd extends Cmd {
  20 +
  21 + @Autowired
  22 + private IAppVersionV1ServiceDao appVersionV1ServiceDao;
  23 +
  24 + @Override
  25 + public void validate(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) {
  26 + Assert.hasKeyAndValue(reqJson, "avId", "未包含版本ID");
  27 + Assert.hasKeyAndValue(reqJson, "versionName", "未包含版本名称");
  28 + }
  29 +
  30 + @Override
  31 + @Java110Transactional
  32 + public void doCmd(CmdEvent event, ICmdDataFlowContext context, JSONObject reqJson) throws CmdException {
  33 + Map<String, Object> params = new HashMap<>();
  34 + params.put("avId", reqJson.getString("avId"));
  35 + if (reqJson.containsKey("versionCode")) params.put("versionCode", reqJson.getIntValue("versionCode"));
  36 + params.put("versionName", reqJson.getString("versionName"));
  37 + if (reqJson.containsKey("downloadUrl")) params.put("downloadUrl", reqJson.getString("downloadUrl"));
  38 + if (reqJson.containsKey("forceUpdate")) params.put("forceUpdate", reqJson.getIntValue("forceUpdate"));
  39 + if (reqJson.containsKey("updateMessage")) params.put("updateMessage", reqJson.getString("updateMessage"));
  40 +
  41 + int flag = appVersionV1ServiceDao.updateAppVersion(params);
  42 + if (flag < 1) {
  43 + throw new CmdException("修改版本信息失败");
  44 + }
  45 + context.setResponseEntity(ResultVo.success());
  46 + }
  47 +}
service-user/src/main/java/com/java110/user/dao/impl/AppVersionV1ServiceDaoImpl.java 0 → 100644
  1 +package com.java110.user.dao.impl;
  2 +
  3 +import com.java110.core.base.dao.BaseServiceDao;
  4 +import com.java110.user.dao.property.IAppVersionV1ServiceDao;
  5 +import org.springframework.stereotype.Service;
  6 +
  7 +import java.util.List;
  8 +import java.util.Map;
  9 +
  10 +@Service("appVersionV1ServiceDaoImpl")
  11 +public class AppVersionV1ServiceDaoImpl extends BaseServiceDao implements IAppVersionV1ServiceDao {
  12 +
  13 + @Override
  14 + public Map queryLatestVersion(Map params) {
  15 + List<Map> list = sqlSessionTemplate.selectList("appVersionV1ServiceDaoImpl.queryLatestVersion", params);
  16 + return (list != null && !list.isEmpty()) ? list.get(0) : null;
  17 + }
  18 +
  19 + @Override
  20 + public List<Map> queryAppVersions(Map params) {
  21 + return sqlSessionTemplate.selectList("appVersionV1ServiceDaoImpl.queryAppVersions", params);
  22 + }
  23 +
  24 + @Override
  25 + public int queryAppVersionsCount(Map params) {
  26 + List<Map> list = sqlSessionTemplate.selectList("appVersionV1ServiceDaoImpl.queryAppVersionsCount", params);
  27 + if (list != null && !list.isEmpty()) {
  28 + Object count = list.get(0).get("count");
  29 + return count instanceof Number ? ((Number) count).intValue() : Integer.parseInt(count.toString());
  30 + }
  31 + return 0;
  32 + }
  33 +
  34 + @Override
  35 + public int saveAppVersion(Map params) {
  36 + return sqlSessionTemplate.insert("appVersionV1ServiceDaoImpl.saveAppVersion", params);
  37 + }
  38 +
  39 + @Override
  40 + public int updateAppVersion(Map params) {
  41 + return sqlSessionTemplate.update("appVersionV1ServiceDaoImpl.updateAppVersion", params);
  42 + }
  43 +
  44 + @Override
  45 + public int deleteAppVersion(Map params) {
  46 + return sqlSessionTemplate.update("appVersionV1ServiceDaoImpl.deleteAppVersion", params);
  47 + }
  48 +}
service-user/src/main/java/com/java110/user/dao/property/IAppVersionV1ServiceDao.java 0 → 100644
  1 +package com.java110.user.dao.property;
  2 +
  3 +import java.util.List;
  4 +import java.util.Map;
  5 +
  6 +public interface IAppVersionV1ServiceDao {
  7 + Map queryLatestVersion(Map params);
  8 + List<Map> queryAppVersions(Map params);
  9 + int queryAppVersionsCount(Map params);
  10 + int saveAppVersion(Map params);
  11 + int updateAppVersion(Map params);
  12 + int deleteAppVersion(Map params);
  13 +}
service-user/src/main/resources/mapper/property/AppVersionMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="appVersionV1ServiceDaoImpl">
  4 +
  5 + <select id="queryLatestVersion" parameterType="map" resultType="map">
  6 + SELECT av_id, version_code, version_name, download_url, force_update, update_message, platform
  7 + FROM app_version
  8 + WHERE platform = #{platform} AND status_cd = '0'
  9 + ORDER BY version_code DESC
  10 + LIMIT 1
  11 + </select>
  12 +
  13 + <select id="queryAppVersions" parameterType="map" resultType="map">
  14 + SELECT av_id, version_code, version_name, download_url, force_update, update_message, platform, create_time
  15 + FROM app_version
  16 + WHERE status_cd = '0'
  17 + <if test="platform != null and platform != ''">AND platform = #{platform}</if>
  18 + ORDER BY version_code DESC
  19 + <if test="page != null and row != null">LIMIT #{page}, #{row}</if>
  20 + </select>
  21 +
  22 + <select id="queryAppVersionsCount" parameterType="map" resultType="map">
  23 + SELECT COUNT(1) count FROM app_version WHERE status_cd = '0'
  24 + <if test="platform != null and platform != ''">AND platform = #{platform}</if>
  25 + </select>
  26 +
  27 + <insert id="saveAppVersion" parameterType="map">
  28 + INSERT INTO app_version (av_id, version_code, version_name, download_url, force_update, update_message, platform, status_cd)
  29 + VALUES (#{avId}, #{versionCode}, #{versionName}, #{downloadUrl}, #{forceUpdate}, #{updateMessage}, #{platform}, '0')
  30 + </insert>
  31 +
  32 + <update id="updateAppVersion" parameterType="map">
  33 + UPDATE app_version SET
  34 + <if test="versionCode != null">version_code = #{versionCode},</if>
  35 + <if test="versionName != null">version_name = #{versionName},</if>
  36 + <if test="downloadUrl != null">download_url = #{downloadUrl},</if>
  37 + <if test="forceUpdate != null">force_update = #{forceUpdate},</if>
  38 + <if test="updateMessage != null">update_message = #{updateMessage},</if>
  39 + version_name = #{versionName}
  40 + WHERE av_id = #{avId}
  41 + </update>
  42 +
  43 + <update id="deleteAppVersion" parameterType="map">
  44 + UPDATE app_version SET status_cd = '1' WHERE av_id = #{avId}
  45 + </update>
  46 +
  47 +</mapper>