diff --git a/login-app/pom.xml b/login-app/pom.xml
new file mode 100644
index 00000000..cbf81833
--- /dev/null
+++ b/login-app/pom.xml
@@ -0,0 +1,22 @@
+
+
+
+ wg-basic
+ ink.wgink
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ login-app
+
+
+
+ ink.wgink
+ login-base
+ 1.0-SNAPSHOT
+
+
+
+
\ No newline at end of file
diff --git a/login-app/src/main/java/ink/wgink/login/app/controller/api/appsign/AppSignController.java b/login-app/src/main/java/ink/wgink/login/app/controller/api/appsign/AppSignController.java
new file mode 100644
index 00000000..57940c68
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/controller/api/appsign/AppSignController.java
@@ -0,0 +1,66 @@
+package ink.wgink.login.app.controller.api.appsign;
+
+import ink.wgink.annotation.CheckRequestBodyAnnotation;
+import ink.wgink.exceptions.ParamsException;
+import ink.wgink.interfaces.consts.ISystemConstant;
+import ink.wgink.login.app.pojo.vos.appsign.AppLoginDefaultVO;
+import ink.wgink.login.app.pojo.vos.appsign.AppLoginPhoneVO;
+import ink.wgink.login.app.service.appsign.IAppSignService;
+import ink.wgink.pojo.result.ErrorResult;
+import ink.wgink.pojo.result.SuccessResultData;
+import ink.wgink.util.RegexUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AppSignController
+ * @Description: 登录
+ * @Author: wanggeng
+ * @Date: 2021/4/7 3:55 下午
+ * @Version: 1.0
+ */
+@Api(tags = ISystemConstant.API_TAGS_APP_PREFIX + "登录")
+@RestController
+@RequestMapping(ISystemConstant.APP_PREFIX + "/sign")
+public class AppSignController {
+
+ @Autowired
+ private IAppSignService appSignService;
+
+ @ApiOperation(value = "APP用户名密码登录", notes = "APP用户名密码登录接口")
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @PostMapping("default")
+ @CheckRequestBodyAnnotation
+ public synchronized SuccessResultData defaultSign(@RequestBody AppLoginDefaultVO appLoginDefaultVO) throws Exception {
+ return new SuccessResultData<>(appSignService.defaultSign(appLoginDefaultVO));
+ }
+
+ @ApiOperation(value = "APP手机验证码登录", notes = "APP手机验证码登录接口")
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @PostMapping("phone")
+ @CheckRequestBodyAnnotation
+ public synchronized SuccessResultData phone(@RequestBody AppLoginPhoneVO appLoginPhoneVO) throws Exception {
+ if (!RegexUtil.isPhone(appLoginPhoneVO.getUsername())) {
+ throw new ParamsException("用户名非手机格式");
+ }
+ // String verificationCode = VerificationCodeManager.getInstance().getVerificationCode(appLoginPhoneVO.getUsername());
+// if (StringUtils.isBlank(verificationCode)) {
+// throw new ParamsException("验证码为空");
+// }
+// if (!StringUtils.equalsIgnoreCase(verificationCode, appLoginPhoneVO.getVerificationCode())) {
+// throw new ParamsException("验证码错误");
+// }
+ return new SuccessResultData<>(appSignService.phoneSign(appLoginPhoneVO));
+ }
+
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/controller/api/appverion/AppVersionController.java b/login-app/src/main/java/ink/wgink/login/app/controller/api/appverion/AppVersionController.java
new file mode 100644
index 00000000..1788b5a8
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/controller/api/appverion/AppVersionController.java
@@ -0,0 +1,147 @@
+package ink.wgink.login.app.controller.api.appverion;
+
+import ink.wgink.annotation.CheckRequestBodyAnnotation;
+import ink.wgink.common.base.DefaultBaseController;
+import ink.wgink.exceptions.RemoveException;
+import ink.wgink.interfaces.consts.ISystemConstant;
+import ink.wgink.login.app.pojo.dtos.appversion.AppVersionDTO;
+import ink.wgink.login.app.pojo.vos.appversion.AppVersionSaveVO;
+import ink.wgink.login.app.pojo.vos.appversion.AppVersionVO;
+import ink.wgink.login.app.service.appversion.IAppVersionService;
+import ink.wgink.pojo.ListPage;
+import ink.wgink.pojo.result.ErrorResult;
+import ink.wgink.pojo.result.SuccessResult;
+import ink.wgink.pojo.result.SuccessResultList;
+import io.swagger.annotations.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName: AppVersionController
+ * @Description: app版本
+ * @Author: admin
+ * @Date: 2019-08-26 14:50:40
+ * @Version: 1.0
+ **/
+@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "app版本管理接口")
+@RestController
+@RequestMapping(ISystemConstant.API_PREFIX + "/appversion")
+public class AppVersionController extends DefaultBaseController {
+
+ @Autowired
+ private IAppVersionService appVersionService;
+
+ @ApiOperation(value = "app版本新增", notes = "app版本新增接口")
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @PostMapping("save")
+ @CheckRequestBodyAnnotation
+ public SuccessResult saveAppVersion(@RequestBody AppVersionSaveVO appVersionSaveVO) {
+ appVersionService.save(appVersionSaveVO);
+ return new SuccessResult();
+ }
+
+ @ApiOperation(value = "app版本删除", notes = "通过id列表批量删除app版本接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "ids", value = "app版本ID列表,用下划线分隔", paramType = "path", example = "1_2_3")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @DeleteMapping("remove/{ids}")
+ public SuccessResult remove(@PathVariable("ids") String ids) throws RemoveException {
+ appVersionService.remove(Arrays.asList(ids.split("\\_")));
+ return new SuccessResult();
+ }
+
+ @ApiOperation(value = "app版本修改", notes = "app版本修改接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "appVersionId", value = "app版本ID", paramType = "path")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @PutMapping("update/{appVersionId}")
+ @CheckRequestBodyAnnotation
+ public SuccessResult update(@PathVariable("appVersionId") String appVersionId, @RequestBody AppVersionVO appVersionVO) {
+ appVersionService.update(appVersionId, appVersionVO);
+ return new SuccessResult();
+ }
+
+ @ApiOperation(value = "更新APP接口锁定状态", notes = "更新APP接口锁定状态接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "appVersionId", value = "app版本ID", paramType = "path"),
+ @ApiImplicitParam(name = "appApiLock", value = "接口版本锁定", paramType = "path")
+ })
+ @PutMapping("update-api-lock/{appVersionId}/{appApiLock}")
+ public SuccessResult updateAppApiLock(@PathVariable("appVersionId") String appVersionId, @PathVariable("appApiLock") Integer appApiLock) {
+ appVersionService.updateApiLock(appVersionId, appApiLock);
+ return new SuccessResult();
+ }
+
+ @ApiOperation(value = "更新APP为发布状态", notes = "更新APP为发布状态接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "appVersionId", value = "app版本ID", paramType = "path"),
+ })
+ @PutMapping("update-release/{appVersionId}")
+ public SuccessResult updateRelease(@PathVariable("appVersionId") String appVersionId) {
+ appVersionService.updateRelease(appVersionId, 1);
+ return new SuccessResult();
+ }
+
+ @ApiOperation(value = "更新APP为未发布状态", notes = "更新APP为未发布状态接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "appVersionId", value = "app版本ID", paramType = "path"),
+ })
+ @PutMapping("update-unrelease/{appVersionId}")
+ public SuccessResult updateUnRelease(@PathVariable("appVersionId") String appVersionId) {
+ appVersionService.updateRelease(appVersionId, 0);
+ return new SuccessResult();
+ }
+
+ @ApiOperation(value = "app版本列表", notes = "app版本列表接口")
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @GetMapping("list")
+ public List listAppVersion() {
+ Map params = getParams();
+ return appVersionService.list(params);
+ }
+
+ @ApiOperation(value = "app版本详情", notes = "app版本详情接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "appVersionId", value = "app版本ID", paramType = "path")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @GetMapping("get/{appVersionId}")
+ public AppVersionDTO get(@PathVariable("appVersionId") String appVersionId) {
+ return appVersionService.get(appVersionId);
+ }
+
+ @ApiOperation(value = "分页app版本列表", notes = "分页app版本列表接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "page", value = "当前页码", paramType = "query", dataType = "int", defaultValue = "1"),
+ @ApiImplicitParam(name = "rows", value = "显示数量", paramType = "query", dataType = "int", defaultValue = "20"),
+ @ApiImplicitParam(name = "keywords", value = "关键字", paramType = "query", dataType = "String"),
+ @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "query", dataType = "String"),
+ @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "query", dataType = "String")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @GetMapping("listpage")
+ public SuccessResultList> listPageAppVersion(ListPage page) {
+ Map params = requestParams();
+ page.setParams(params);
+ return appVersionService.listPage(page);
+ }
+
+ @ApiOperation(value = "获取app二维码", notes = "获取app二维码接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "appVersionId", value = "app版本ID", paramType = "path")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @GetMapping("downloadqrcode/{appVersionId}")
+ public void downloadQrCode(@PathVariable("appVersionId") String appVersionId, HttpServletResponse response) throws IOException {
+ appVersionService.downloadQrCode(appVersionId, response);
+ }
+
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/controller/app/api/appversion/AppVersionAppController.java b/login-app/src/main/java/ink/wgink/login/app/controller/app/api/appversion/AppVersionAppController.java
new file mode 100644
index 00000000..36f182e5
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/controller/app/api/appversion/AppVersionAppController.java
@@ -0,0 +1,61 @@
+package ink.wgink.login.app.controller.app.api.appversion;
+
+import ink.wgink.common.base.DefaultBaseController;
+import ink.wgink.exceptions.FileException;
+import ink.wgink.exceptions.SearchException;
+import ink.wgink.exceptions.UpdateException;
+import ink.wgink.interfaces.consts.ISystemConstant;
+import ink.wgink.login.app.service.appversion.IAppVersionService;
+import ink.wgink.pojo.result.ErrorResult;
+import ink.wgink.pojo.result.SuccessResultData;
+import io.swagger.annotations.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.mvc.AbstractController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AppVersionAppController
+ * @Description: app版本
+ * @Author: WangGeng
+ * @Date: 2019/8/26 4:30 下午
+ * @Version: 1.0
+ **/
+@Api(tags = ISystemConstant.API_TAGS_APP_PREFIX + "app版本管理接口")
+@RestController
+@RequestMapping(ISystemConstant.APP_PREFIX + "/appversion")
+public class AppVersionAppController extends DefaultBaseController {
+
+ @Autowired
+ private IAppVersionService appVersionService;
+
+ @ApiOperation(value = "获取app当前版本", notes = "获取app当前版本接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "appVersionId", value = "app版本ID", paramType = "path")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @GetMapping("get-number/{appVersionId}")
+ public SuccessResultData getNumber(@PathVariable("appVersionId") String appVersionId) throws SearchException {
+ return new SuccessResultData<>(appVersionService.getNumber(appVersionId));
+ }
+
+ @ApiOperation(value = "下载app", notes = "下载app接口")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "appVersionId", value = "app版本ID", paramType = "path")
+ })
+ @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
+ @GetMapping("download/{appVersionId}")
+ public void download(@PathVariable("appVersionId") String appVersionId, HttpServletRequest request, HttpServletResponse response) throws SearchException, FileException, UpdateException {
+ appVersionService.download(appVersionId, request, response);
+ }
+
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/controller/route/appversion/AppVersionRouteController.java b/login-app/src/main/java/ink/wgink/login/app/controller/route/appversion/AppVersionRouteController.java
new file mode 100644
index 00000000..f0beffb9
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/controller/route/appversion/AppVersionRouteController.java
@@ -0,0 +1,40 @@
+package ink.wgink.login.app.controller.route.appversion;
+
+import ink.wgink.interfaces.consts.ISystemConstant;
+import io.swagger.annotations.Api;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.servlet.ModelAndView;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: LogRouteController
+ * @Description: 日志
+ * @Author: wanggeng
+ * @Date: 2021/3/1 10:41 上午
+ * @Version: 1.0
+ */
+@Api(tags = ISystemConstant.API_TAGS_APP_ROUTE_PREFIX + "版本控制")
+@Controller
+@RequestMapping(ISystemConstant.ROUTE_PREFIX + "/appversion")
+public class AppVersionRouteController {
+
+ @GetMapping("list")
+ public ModelAndView list() {
+ return new ModelAndView("appversion/list");
+ }
+
+ @GetMapping("save")
+ public ModelAndView save() {
+ return new ModelAndView("appversion/save");
+ }
+
+ @GetMapping("update")
+ public ModelAndView update() {
+ return new ModelAndView("appversion/update");
+ }
+
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/dao/appdeviceuser/IAppDeviceUserDao.java b/login-app/src/main/java/ink/wgink/login/app/dao/appdeviceuser/IAppDeviceUserDao.java
new file mode 100644
index 00000000..c312c632
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/dao/appdeviceuser/IAppDeviceUserDao.java
@@ -0,0 +1,68 @@
+package ink.wgink.login.app.dao.appdeviceuser;
+
+import ink.wgink.exceptions.RemoveException;
+import ink.wgink.exceptions.SaveException;
+import ink.wgink.exceptions.SearchException;
+import ink.wgink.exceptions.UpdateException;
+import ink.wgink.login.app.pojo.dtos.appdeviceuser.AppDeviceUserDTO;
+import ink.wgink.login.app.pojo.pos.appdeviceuser.AppDeviceUserPO;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: IAppDeviceUserDao
+ * @Description: app设备用户
+ * @Author: wanggeng
+ * @Date: 2021/4/7 4:23 下午
+ * @Version: 1.0
+ */
+@Repository
+public interface IAppDeviceUserDao {
+
+ /**
+ * 建表
+ *
+ * @throws UpdateException
+ */
+ void createTable() throws UpdateException;
+
+ /**
+ * 保存
+ *
+ * @param params
+ * @throws SaveException
+ */
+ void save(Map params) throws SaveException;
+
+ /**
+ * 删除(物理)
+ *
+ * @param params
+ * @throws RemoveException
+ */
+ void delete(Map params) throws RemoveException;
+
+ /**
+ * 列表
+ *
+ * @param params
+ * @return
+ * @throws SearchException
+ */
+ List list(Map params) throws SearchException;
+
+ /**
+ * 列表
+ *
+ * @param params
+ * @return
+ * @throws SearchException
+ */
+ List listPO(Map params) throws SearchException;
+
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/dao/appversion/IAppVersionDao.java b/login-app/src/main/java/ink/wgink/login/app/dao/appversion/IAppVersionDao.java
new file mode 100644
index 00000000..128bdd81
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/dao/appversion/IAppVersionDao.java
@@ -0,0 +1,118 @@
+package ink.wgink.login.app.dao.appversion;
+
+import ink.wgink.exceptions.RemoveException;
+import ink.wgink.exceptions.SaveException;
+import ink.wgink.exceptions.SearchException;
+import ink.wgink.exceptions.UpdateException;
+import ink.wgink.login.app.pojo.dtos.appversion.AppVersionDTO;
+import ink.wgink.login.app.pojo.pos.appversion.AppVersionPO;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: IAppDeviceDao
+ * @Description: app设备
+ * @Author: wanggeng
+ * @Date: 2021/4/7 4:22 下午
+ * @Version: 1.0
+ */
+@Repository
+public interface IAppVersionDao {
+
+ /**
+ * 建表
+ *
+ * @throws UpdateException
+ */
+ void createTable() throws UpdateException;
+
+ /**
+ * 新增app版本
+ *
+ * @param params
+ * @throws SaveException
+ */
+ void save(Map params) throws SaveException;
+
+ /**
+ * 删除app版本
+ *
+ * @param params
+ * @throws RemoveException
+ */
+ void remove(Map params) throws RemoveException;
+
+ /**
+ * 修改app版本
+ *
+ * @param params
+ * @throws UpdateException
+ */
+ void update(Map params) throws UpdateException;
+
+ /**
+ * 更新下载次数
+ *
+ * @param appVersionId
+ * @throws UpdateException
+ */
+ void updateDownloadCount(String appVersionId) throws UpdateException;
+
+ /**
+ * 更新APP接口锁定状态
+ *
+ * @param params
+ * @throws UpdateException
+ */
+ void updateApiLock(Map params) throws UpdateException;
+
+ /**
+ * 更新APP的发布状态
+ *
+ * @param params
+ * @throws UpdateException
+ */
+ void updateRelease(Map params) throws UpdateException;
+
+ /**
+ * app版本列表
+ *
+ * @param params
+ * @return
+ * @throws SearchException
+ */
+ List list(Map params) throws SearchException;
+
+ /**
+ * 详情
+ *
+ * @param params
+ * @return
+ * @throws SearchException
+ */
+ AppVersionDTO get(Map params) throws SearchException;
+
+ /**
+ * app版本列表
+ *
+ * @param params
+ * @return
+ * @throws SearchException
+ */
+ List listPO(Map params) throws SearchException;
+
+ /**
+ * 详情
+ *
+ * @param params
+ * @return
+ * @throws SearchException
+ */
+ AppVersionPO getPO(Map params) throws SearchException;
+
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/pojo/dtos/appdeviceuser/AppDeviceUserDTO.java b/login-app/src/main/java/ink/wgink/login/app/pojo/dtos/appdeviceuser/AppDeviceUserDTO.java
new file mode 100644
index 00000000..5c9e95e8
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/pojo/dtos/appdeviceuser/AppDeviceUserDTO.java
@@ -0,0 +1,42 @@
+package ink.wgink.login.app.pojo.dtos.appdeviceuser;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AppDeviceUserDTO
+ * @Description: app设备用户
+ * @Author: wanggeng
+ * @Date: 2021/4/7 4:34 下午
+ * @Version: 1.0
+ */
+@ApiModel
+public class AppDeviceUserDTO implements Serializable {
+
+ private static final long serialVersionUID = 7352338869750340418L;
+ @ApiModelProperty(name = "userId", value = "用户ID")
+ private String userId;
+ @ApiModelProperty(name = "deviceNo", value = "设备编号")
+ private String deviceNo;
+
+ public String getUserId() {
+ return userId == null ? "" : userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getDeviceNo() {
+ return deviceNo == null ? "" : deviceNo;
+ }
+
+ public void setDeviceNo(String deviceNo) {
+ this.deviceNo = deviceNo;
+ }
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/pojo/dtos/appversion/AppVersionDTO.java b/login-app/src/main/java/ink/wgink/login/app/pojo/dtos/appversion/AppVersionDTO.java
new file mode 100644
index 00000000..3086c33e
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/pojo/dtos/appversion/AppVersionDTO.java
@@ -0,0 +1,134 @@
+package ink.wgink.login.app.pojo.dtos.appversion;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AppDeviceDTO
+ * @Description: app设备
+ * @Author: wanggeng
+ * @Date: 2021/4/7 4:33 下午
+ * @Version: 1.0
+ */
+@ApiModel
+public class AppVersionDTO {
+
+ @ApiModelProperty(name = "appVersionId", value = "app版本ID")
+ private String appVersionId;
+ @ApiModelProperty(name = "appName", value = "APP名称")
+ private String appName;
+ @ApiModelProperty(name = "appSummary", value = "APP说明")
+ private String appSummary;
+ @ApiModelProperty(name = "appVersion", value = "APP版本号")
+ private Integer appVersion;
+ @ApiModelProperty(name = "appDownloadCount", value = "下载次数")
+ private Integer appDownloadCount;
+ @ApiModelProperty(name = "appFile", value = "APP文件")
+ private String appFile;
+ @ApiModelProperty(name = "appApiLock", value = "接口版本锁定")
+ private Integer appApiLock;
+ @ApiModelProperty(name = "isNecessary", value = "强制更新,0:否,1:是")
+ private Integer isNecessary;
+ @ApiModelProperty(name = "isRelease", value = "是否发布,0:否,1:是")
+ private Integer isRelease;
+
+ public String getAppVersionId() {
+ return appVersionId == null ? "" : appVersionId;
+ }
+
+ public void setAppVersionId(String appVersionId) {
+ this.appVersionId = appVersionId;
+ }
+
+ public String getAppName() {
+ return appName == null ? "" : appName;
+ }
+
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
+
+ public String getAppSummary() {
+ return appSummary == null ? "" : appSummary;
+ }
+
+ public void setAppSummary(String appSummary) {
+ this.appSummary = appSummary;
+ }
+
+ public Integer getAppVersion() {
+ return appVersion == null ? 0 : appVersion;
+ }
+
+ public void setAppVersion(Integer appVersion) {
+ this.appVersion = appVersion;
+ }
+
+ public Integer getAppDownloadCount() {
+ return appDownloadCount == null ? 0 : appDownloadCount;
+ }
+
+ public void setAppDownloadCount(Integer appDownloadCount) {
+ this.appDownloadCount = appDownloadCount;
+ }
+
+ public String getAppFile() {
+ return appFile == null ? "" : appFile;
+ }
+
+ public void setAppFile(String appFile) {
+ this.appFile = appFile;
+ }
+
+ public Integer getAppApiLock() {
+ return appApiLock == null ? 0 : appApiLock;
+ }
+
+ public void setAppApiLock(Integer appApiLock) {
+ this.appApiLock = appApiLock;
+ }
+
+ public Integer getIsNecessary() {
+ return isNecessary == null ? 0 : isNecessary;
+ }
+
+ public void setIsNecessary(Integer isNecessary) {
+ this.isNecessary = isNecessary;
+ }
+
+ public Integer getIsRelease() {
+ return isRelease == null ? 0 : isRelease;
+ }
+
+ public void setIsRelease(Integer isRelease) {
+ this.isRelease = isRelease;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"appVersionId\":\"")
+ .append(appVersionId).append('\"');
+ sb.append(",\"appName\":\"")
+ .append(appName).append('\"');
+ sb.append(",\"appSummary\":\"")
+ .append(appSummary).append('\"');
+ sb.append(",\"appVersion\":")
+ .append(appVersion);
+ sb.append(",\"appDownloadCount\":")
+ .append(appDownloadCount);
+ sb.append(",\"appFile\":\"")
+ .append(appFile).append('\"');
+ sb.append(",\"appApiLock\":")
+ .append(appApiLock);
+ sb.append(",\"isNecessary\":")
+ .append(isNecessary);
+ sb.append(",\"isRelease\":")
+ .append(isRelease);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/pojo/pos/appdeviceuser/AppDeviceUserPO.java b/login-app/src/main/java/ink/wgink/login/app/pojo/pos/appdeviceuser/AppDeviceUserPO.java
new file mode 100644
index 00000000..d20db3e0
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/pojo/pos/appdeviceuser/AppDeviceUserPO.java
@@ -0,0 +1,47 @@
+package ink.wgink.login.app.pojo.pos.appdeviceuser;
+
+import java.io.Serializable;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AppDeviceUserPO
+ * @Description: app设备用户
+ * @Author: wanggeng
+ * @Date: 2021/4/7 4:34 下午
+ * @Version: 1.0
+ */
+public class AppDeviceUserPO implements Serializable {
+
+ private static final long serialVersionUID = -3532724359534273591L;
+ private String userId;
+ private String deviceNo;
+
+ public String getUserId() {
+ return userId == null ? "" : userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getDeviceNo() {
+ return deviceNo == null ? "" : deviceNo;
+ }
+
+ public void setDeviceNo(String deviceNo) {
+ this.deviceNo = deviceNo;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"userId\":\"")
+ .append(userId).append('\"');
+ sb.append(",\"deviceNo\":\"")
+ .append(deviceNo).append('\"');
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/pojo/pos/appversion/AppVersionPO.java b/login-app/src/main/java/ink/wgink/login/app/pojo/pos/appversion/AppVersionPO.java
new file mode 100644
index 00000000..eba230bd
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/pojo/pos/appversion/AppVersionPO.java
@@ -0,0 +1,126 @@
+package ink.wgink.login.app.pojo.pos.appversion;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AppDevicePO
+ * @Description: app设备
+ * @Author: wanggeng
+ * @Date: 2021/4/7 4:33 下午
+ * @Version: 1.0
+ */
+public class AppVersionPO implements Serializable {
+
+ private static final long serialVersionUID = 6906701658888507376L;
+ private String appVersionId;
+ private String appName;
+ private String appSummary;
+ private Integer appVersion;
+ private Integer appDownloadCount;
+ private String appFile;
+ private Integer appApiLock;
+ private Integer isNecessary;
+ private Integer isRelease;
+
+ public String getAppVersionId() {
+ return appVersionId == null ? "" : appVersionId;
+ }
+
+ public void setAppVersionId(String appVersionId) {
+ this.appVersionId = appVersionId;
+ }
+
+ public String getAppName() {
+ return appName == null ? "" : appName;
+ }
+
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
+
+ public String getAppSummary() {
+ return appSummary == null ? "" : appSummary;
+ }
+
+ public void setAppSummary(String appSummary) {
+ this.appSummary = appSummary;
+ }
+
+ public Integer getAppVersion() {
+ return appVersion == null ? 0 : appVersion;
+ }
+
+ public void setAppVersion(Integer appVersion) {
+ this.appVersion = appVersion;
+ }
+
+ public Integer getAppDownloadCount() {
+ return appDownloadCount == null ? 0 : appDownloadCount;
+ }
+
+ public void setAppDownloadCount(Integer appDownloadCount) {
+ this.appDownloadCount = appDownloadCount;
+ }
+
+ public String getAppFile() {
+ return appFile == null ? "" : appFile;
+ }
+
+ public void setAppFile(String appFile) {
+ this.appFile = appFile;
+ }
+
+ public Integer getAppApiLock() {
+ return appApiLock == null ? 0 : appApiLock;
+ }
+
+ public void setAppApiLock(Integer appApiLock) {
+ this.appApiLock = appApiLock;
+ }
+
+ public Integer getIsNecessary() {
+ return isNecessary == null ? 0 : isNecessary;
+ }
+
+ public void setIsNecessary(Integer isNecessary) {
+ this.isNecessary = isNecessary;
+ }
+
+ public Integer getIsRelease() {
+ return isRelease == null ? 0 : isRelease;
+ }
+
+ public void setIsRelease(Integer isRelease) {
+ this.isRelease = isRelease;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"appVersionId\":\"")
+ .append(appVersionId).append('\"');
+ sb.append(",\"appName\":\"")
+ .append(appName).append('\"');
+ sb.append(",\"appSummary\":\"")
+ .append(appSummary).append('\"');
+ sb.append(",\"appVersion\":")
+ .append(appVersion);
+ sb.append(",\"appDownloadCount\":")
+ .append(appDownloadCount);
+ sb.append(",\"appFile\":\"")
+ .append(appFile).append('\"');
+ sb.append(",\"appApiLock\":")
+ .append(appApiLock);
+ sb.append(",\"isNecessary\":")
+ .append(isNecessary);
+ sb.append(",\"isRelease\":")
+ .append(isRelease);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appsign/AppLoginDefaultVO.java b/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appsign/AppLoginDefaultVO.java
new file mode 100644
index 00000000..b65b6cb5
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appsign/AppLoginDefaultVO.java
@@ -0,0 +1,40 @@
+package ink.wgink.login.app.pojo.vos.appsign;
+
+import ink.wgink.annotation.CheckEmptyAnnotation;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: LoginDefault
+ * @Description: 默认登录
+ * @Author: WangGeng
+ * @Date: 2020/6/3 9:11
+ * @Version: 1.0
+ **/
+@ApiModel
+public class AppLoginDefaultVO extends AppLoginVO {
+
+ @ApiModelProperty(name = "password", value = "密码")
+ @CheckEmptyAnnotation(name = "密码")
+ private String password;
+
+ public String getPassword() {
+ return password == null ? "" : password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"password\":\"")
+ .append(password).append('\"');
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appsign/AppLoginPhoneVO.java b/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appsign/AppLoginPhoneVO.java
new file mode 100644
index 00000000..30daf4df
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appsign/AppLoginPhoneVO.java
@@ -0,0 +1,40 @@
+package ink.wgink.login.app.pojo.vos.appsign;
+
+import ink.wgink.annotation.CheckEmptyAnnotation;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: LoginVO
+ * @Description: 登录
+ * @Author: WangGeng
+ * @Date: 2019-08-01 14:33
+ * @Version: 1.0
+ **/
+@ApiModel
+public class AppLoginPhoneVO extends AppLoginVO {
+
+ @ApiModelProperty(name = "verificationCode", value = "验证码")
+ @CheckEmptyAnnotation(name = "验证码")
+ private String verificationCode;
+
+ public String getVerificationCode() {
+ return verificationCode == null ? "" : verificationCode;
+ }
+
+ public void setVerificationCode(String verificationCode) {
+ this.verificationCode = verificationCode;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"verificationCode\":\"")
+ .append(verificationCode).append('\"');
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appsign/AppLoginVO.java b/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appsign/AppLoginVO.java
new file mode 100644
index 00000000..8e072651
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appsign/AppLoginVO.java
@@ -0,0 +1,100 @@
+package ink.wgink.login.app.pojo.vos.appsign;
+
+import ink.wgink.annotation.CheckEmptyAnnotation;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: LoginVO
+ * @Description: 登录
+ * @Author: WangGeng
+ * @Date: 2019-08-01 14:33
+ * @Version: 1.0
+ **/
+@ApiModel
+public class AppLoginVO {
+
+ @ApiModelProperty(name = "username", value = "用户名")
+ @CheckEmptyAnnotation(name = "用户名")
+ private String username;
+ @ApiModelProperty(name = "deviceNo", value = "设备编号")
+ private String deviceNo;
+ @ApiModelProperty(name = "longitude", value = "经度")
+ private String longitude;
+ @ApiModelProperty(name = "latitude", value = "纬度")
+ private String latitude;
+ @ApiModelProperty(name = "appId", value = "appId")
+ private String appId;
+ @ApiModelProperty(name = "appVersion", value = "app版本")
+ private Integer appVersion;
+
+ public String getUsername() {
+ return username == null ? "" : username.trim();
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getDeviceNo() {
+ return deviceNo == null ? "" : deviceNo.trim();
+ }
+
+ public void setDeviceNo(String deviceNo) {
+ this.deviceNo = deviceNo;
+ }
+
+ public String getLongitude() {
+ return longitude == null ? "" : longitude.trim();
+ }
+
+ public void setLongitude(String longitude) {
+ this.longitude = longitude;
+ }
+
+ public String getLatitude() {
+ return latitude == null ? "" : latitude.trim();
+ }
+
+ public void setLatitude(String latitude) {
+ this.latitude = latitude;
+ }
+
+ public String getAppId() {
+ return appId == null ? "" : appId.trim();
+ }
+
+ public void setAppId(String appId) {
+ this.appId = appId;
+ }
+
+ public Integer getAppVersion() {
+ return appVersion;
+ }
+
+ public void setAppVersion(Integer appVersion) {
+ this.appVersion = appVersion;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"username\":")
+ .append("\"").append(username).append("\"");
+ sb.append(",\"deviceNo\":")
+ .append("\"").append(deviceNo).append("\"");
+ sb.append(",\"longitude\":")
+ .append("\"").append(longitude).append("\"");
+ sb.append(",\"latitude\":")
+ .append("\"").append(latitude).append("\"");
+ sb.append(",\"appId\":")
+ .append("\"").append(appId).append("\"");
+ sb.append(",\"appVersion\":")
+ .append(appVersion);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appversion/AppVersionSaveVO.java b/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appversion/AppVersionSaveVO.java
new file mode 100644
index 00000000..204316c9
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appversion/AppVersionSaveVO.java
@@ -0,0 +1,35 @@
+package ink.wgink.login.app.pojo.vos.appversion;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @ClassName: AppVersionVO
+ * @Description: app版本
+ * @Author: admin
+ * @Date: 2019-08-26 14:50:40
+ * @Version: 1.0
+ **/
+@ApiModel
+public class AppVersionSaveVO extends AppVersionVO {
+
+ @ApiModelProperty(name = "appName", value = "APP名称")
+ private String appName;
+
+ public String getAppName() {
+ return appName;
+ }
+
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"appName\":\"")
+ .append(appName).append('\"');
+ sb.append('}');
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appversion/AppVersionVO.java b/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appversion/AppVersionVO.java
new file mode 100644
index 00000000..caac654f
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/pojo/vos/appversion/AppVersionVO.java
@@ -0,0 +1,77 @@
+package ink.wgink.login.app.pojo.vos.appversion;
+
+import ink.wgink.annotation.CheckEmptyAnnotation;
+import ink.wgink.annotation.CheckNumberAnnotation;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @ClassName: AppVersionVO
+ * @Description: app版本
+ * @Author: admin
+ * @Date: 2019-08-26 14:50:40
+ * @Version: 1.0
+ **/
+@ApiModel
+public class AppVersionVO {
+
+ @ApiModelProperty(name = "appSummary", value = "APP说明")
+ @CheckEmptyAnnotation(name = "APP说明")
+ private String appSummary;
+ @ApiModelProperty(name = "isNecessary", value = "强制更新")
+ @CheckNumberAnnotation(name = "强制更新")
+ private Integer isNecessary;
+ @ApiModelProperty(name = "isRelease", value = "是否发布")
+ @CheckNumberAnnotation(name = "是否发布")
+ private Integer isRelease;
+ @ApiModelProperty(name = "appFile", value = "APP文件")
+ @CheckEmptyAnnotation(name = "APP文件")
+ private String appFile;
+
+ public String getAppSummary() {
+ return appSummary;
+ }
+
+ public void setAppSummary(String appSummary) {
+ this.appSummary = appSummary;
+ }
+
+ public Integer getIsNecessary() {
+ return isNecessary;
+ }
+
+ public void setIsNecessary(Integer isNecessary) {
+ this.isNecessary = isNecessary;
+ }
+
+ public Integer getIsRelease() {
+ return isRelease;
+ }
+
+ public void setIsRelease(Integer isRelease) {
+ this.isRelease = isRelease;
+ }
+
+ public String getAppFile() {
+ return appFile;
+ }
+
+ public void setAppFile(String appFile) {
+ this.appFile = appFile;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("{");
+ sb.append("\"appSummary\":\"")
+ .append(appSummary).append('\"');
+ sb.append(",\"isNecessary\":")
+ .append(isNecessary);
+ sb.append(",\"isRelease\":")
+ .append(isRelease);
+ sb.append(",\"appFile\":\"")
+ .append(appFile).append('\"');
+ sb.append('}');
+ return sb.toString();
+ }
+}
\ No newline at end of file
diff --git a/login-app/src/main/java/ink/wgink/login/app/service/appdeviceuser/IAppDeviceUserService.java b/login-app/src/main/java/ink/wgink/login/app/service/appdeviceuser/IAppDeviceUserService.java
new file mode 100644
index 00000000..885df627
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/service/appdeviceuser/IAppDeviceUserService.java
@@ -0,0 +1,72 @@
+package ink.wgink.login.app.service.appdeviceuser;
+
+import ink.wgink.login.app.pojo.dtos.appdeviceuser.AppDeviceUserDTO;
+import ink.wgink.login.app.pojo.pos.appdeviceuser.AppDeviceUserPO;
+import ink.wgink.util.date.DateUtil;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: IAppDeviceUserService
+ * @Description: 设备用户
+ * @Author: wanggeng
+ * @Date: 2021/4/7 4:21 下午
+ * @Version: 1.0
+ */
+public interface IAppDeviceUserService {
+
+ /**
+ * 保存
+ *
+ * @param deviceNo 设备号
+ * @param userId 用户ID
+ */
+ void save(String deviceNo, String userId);
+
+ /**
+ * 列表
+ *
+ * @param params
+ * @return
+ */
+ List list(Map params);
+
+ /**
+ * 列表
+ *
+ * @param userId 用户ID
+ * @return
+ */
+ List listByUserId(String userId);
+
+ /**
+ * 列表
+ *
+ * @param params
+ * @return
+ */
+ List listPO(Map params);
+
+ /**
+ * 列表
+ *
+ * @param userId 用户ID
+ * @return
+ */
+ List listPOByUserId(String userId);
+
+ /**
+ * 判断APP是否能登录
+ *
+ * @param userId
+ * @param deviceNo
+ * @return
+ */
+ boolean canSign(String userId, String deviceNo);
+
+}
+
diff --git a/login-app/src/main/java/ink/wgink/login/app/service/appdeviceuser/impl/AppDeviceUserServiceImpl.java b/login-app/src/main/java/ink/wgink/login/app/service/appdeviceuser/impl/AppDeviceUserServiceImpl.java
new file mode 100644
index 00000000..0e9ddce0
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/service/appdeviceuser/impl/AppDeviceUserServiceImpl.java
@@ -0,0 +1,95 @@
+package ink.wgink.login.app.service.appdeviceuser.impl;
+
+import ink.wgink.common.base.DefaultBaseService;
+import ink.wgink.login.app.dao.appdeviceuser.IAppDeviceUserDao;
+import ink.wgink.login.app.pojo.dtos.appdeviceuser.AppDeviceUserDTO;
+import ink.wgink.login.app.pojo.pos.appdeviceuser.AppDeviceUserPO;
+import ink.wgink.login.app.service.appdeviceuser.IAppDeviceUserService;
+import ink.wgink.login.base.manager.ConfigManager;
+import ink.wgink.util.date.DateUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AppDeviceUserServiceImpl
+ * @Description: 设备用户
+ * @Author: wanggeng
+ * @Date: 2021/4/7 4:21 下午
+ * @Version: 1.0
+ */
+@Service
+public class AppDeviceUserServiceImpl extends DefaultBaseService implements IAppDeviceUserService {
+
+ @Autowired
+ private IAppDeviceUserDao appDeviceUserDao;
+
+ @Override
+ public void save(String deviceNo, String userId) {
+ Map params = getHashMap(2);
+ params.put("deviceNo", deviceNo);
+ params.put("userId", userId);
+ params.put("gmtCreate", DateUtil.getTime());
+ appDeviceUserDao.save(params);
+ }
+
+ @Override
+ public List list(Map params) {
+ return appDeviceUserDao.list(params);
+ }
+
+ @Override
+ public List listByUserId(String userId) {
+ Map params = getHashMap(2);
+ params.put("userId", userId);
+ return list(params);
+ }
+
+ @Override
+ public List listPO(Map params) {
+ return appDeviceUserDao.listPO(params);
+ }
+
+ @Override
+ public List listPOByUserId(String userId) {
+ Map params = getHashMap(2);
+ params.put("userId", userId);
+ return listPO(params);
+ }
+
+ @Override
+ public boolean canSign(String userId, String deviceNo) {
+ Object appDeviceCountObject = ConfigManager.getInstance().getConfig().get("appDeviceCount");
+ if (Objects.isNull(appDeviceCountObject)) {
+ return true;
+ }
+ Integer appDeviceCount = Integer.parseInt(appDeviceCountObject.toString());
+ if (appDeviceCount == 0) {
+ return true;
+ }
+ List appDeviceUserPOs = listPOByUserId(userId);
+ boolean canLogin = false;
+ if (!appDeviceUserPOs.isEmpty()) {
+ for (AppDeviceUserPO appDeviceUserPO : appDeviceUserPOs) {
+ if (StringUtils.equals(deviceNo, appDeviceUserPO.getDeviceNo())) {
+ canLogin = true;
+ break;
+ }
+ }
+ }
+ if (!canLogin && appDeviceUserPOs.size() < appDeviceCount) {
+ LOG.debug("绑定设备");
+ save(deviceNo, userId);
+ canLogin = true;
+ }
+ return canLogin;
+ }
+
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/service/appsign/IAppSignService.java b/login-app/src/main/java/ink/wgink/login/app/service/appsign/IAppSignService.java
new file mode 100644
index 00000000..a8e70d0b
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/service/appsign/IAppSignService.java
@@ -0,0 +1,36 @@
+package ink.wgink.login.app.service.appsign;
+
+import ink.wgink.interfaces.app.IAppSignBaseService;
+import ink.wgink.login.app.pojo.vos.appsign.AppLoginDefaultVO;
+import ink.wgink.login.app.pojo.vos.appsign.AppLoginPhoneVO;
+
+import java.io.UnsupportedEncodingException;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: IAppSignService
+ * @Description: 登录
+ * @Author: wanggeng
+ * @Date: 2021/4/7 3:58 下午
+ * @Version: 1.0
+ */
+public interface IAppSignService extends IAppSignBaseService {
+
+ /**
+ * APP用户名密码登录
+ *
+ * @param appLoginDefaultVO
+ * @return token
+ */
+ String defaultSign(AppLoginDefaultVO appLoginDefaultVO) throws UnsupportedEncodingException;
+
+ /**
+ * APP手机验证码登录
+ *
+ * @param appLoginPhoneVO
+ * @return token
+ */
+ String phoneSign(AppLoginPhoneVO appLoginPhoneVO) throws UnsupportedEncodingException;
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/service/appsign/impl/AppSignServiceImpl.java b/login-app/src/main/java/ink/wgink/login/app/service/appsign/impl/AppSignServiceImpl.java
new file mode 100644
index 00000000..9fdfa93b
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/service/appsign/impl/AppSignServiceImpl.java
@@ -0,0 +1,126 @@
+package ink.wgink.login.app.service.appsign.impl;
+
+import ink.wgink.exceptions.AppDeviceException;
+import ink.wgink.exceptions.AppVersionException;
+import ink.wgink.exceptions.SearchException;
+import ink.wgink.exceptions.UpdateException;
+import ink.wgink.login.app.pojo.vos.appsign.AppLoginDefaultVO;
+import ink.wgink.login.app.pojo.vos.appsign.AppLoginPhoneVO;
+import ink.wgink.login.app.pojo.vos.appsign.AppLoginVO;
+import ink.wgink.login.app.service.appdeviceuser.IAppDeviceUserService;
+import ink.wgink.login.app.service.appsign.IAppSignService;
+import ink.wgink.login.app.service.appversion.IAppVersionService;
+import ink.wgink.login.base.service.BaseAppSignService;
+import ink.wgink.service.user.pojo.pos.UserPO;
+import ink.wgink.service.user.service.IUserService;
+import ink.wgink.util.date.DateUtil;
+import ink.wgink.util.request.RequestUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AppSignServiceImpl
+ * @Description: 登录
+ * @Author: wanggeng
+ * @Date: 2021/4/7 3:59 下午
+ * @Version: 1.0
+ */
+@Service
+public class AppSignServiceImpl extends BaseAppSignService implements IAppSignService {
+
+ @Autowired
+ private IAppDeviceUserService appDeviceUserService;
+ @Autowired
+ private IAppVersionService appVersionService;
+ @Autowired
+ private PasswordEncoder passwordEncoder;
+ @Autowired
+ private IUserService userService;
+
+ @Override
+ public String defaultSign(AppLoginDefaultVO appLoginDefaultVO) throws UnsupportedEncodingException {
+ String userPassword = appLoginDefaultVO.getPassword();
+ checkApiLock(appLoginDefaultVO);
+ UserPO userPO = userService.getPOByUsername(appLoginDefaultVO.getUsername());
+ if (userPO == null) {
+ throw new SearchException("用户不存在");
+ }
+ if (!passwordEncoder.matches(userPassword, userPO.getUserPassword())) {
+ throw new SearchException("用户名或密码错误");
+ }
+ userLogin(appLoginDefaultVO, userPO);
+ return getToken(userPO);
+ }
+
+ @Override
+ public String phoneSign(AppLoginPhoneVO appLoginPhoneVO) throws UnsupportedEncodingException {
+ UserPO userPO = userService.getPOByUsername(appLoginPhoneVO.getUsername());
+ if (userPO == null) {
+ throw new SearchException("用户不存在");
+ }
+ userLogin(appLoginPhoneVO, userPO);
+ return getToken(userPO);
+ }
+
+ /**
+ * 用户登陆,如果设备编号存在,则通过设备编号判断是否可以登录
+ *
+ * @param appLoginVO
+ * @param userPO
+ */
+ private void userLogin(AppLoginVO appLoginVO, UserPO userPO) {
+ if (userPO.getUserState() == 1) {
+ throw new SearchException("账号已冻结");
+ }
+ if (userPO.getUserState() == 2) {
+ throw new SearchException("账号已锁定");
+ }
+ LOG.debug("校验设备");
+ if (!StringUtils.isBlank(appLoginVO.getDeviceNo()) && !appDeviceUserService.canSign(userPO.getUserId(), appLoginVO.getDeviceNo())) {
+ throw new AppDeviceException("非法登录设备");
+ }
+ LOG.debug("更新登录信息");
+ updateLoginInfo(userPO, appLoginVO.getLongitude(), appLoginVO.getLatitude());
+ }
+
+ /**
+ * 更新登录信息
+ *
+ * @param userPO
+ * @param userLongitude
+ * @param userLatitude
+ * @throws UpdateException
+ */
+ private void updateLoginInfo(UserPO userPO, Object userLongitude, Object userLatitude) throws UpdateException {
+ String currentTime = DateUtil.getTime();
+ Map params = new HashMap<>(0);
+ params.put("userId", userPO.getUserId());
+ params.put("lastLoginAddress", RequestUtil.getRequestIp());
+ params.put("lastLoginTime", currentTime);
+ params.put("userLongitude", userLongitude);
+ params.put("userLatitude", userLatitude);
+ params.put("gmtModified", currentTime);
+ params.put("modifier", userPO.getUserId());
+ userService.updateLoginInfo(params);
+ }
+
+ /**
+ * 校验是否版本锁定,锁定后,如果有升级,提示下载
+ */
+ private void checkApiLock(AppLoginVO appLoginVO) {
+ if (!StringUtils.isBlank(appLoginVO.getAppId()) &&
+ appVersionService.canApiLock(appLoginVO.getAppId(), appLoginVO.getAppVersion() == null ? null : appLoginVO.getAppVersion().toString())) {
+ throw new AppVersionException("app版本过低,请重新下载");
+ }
+ }
+
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/service/appversion/IAppVersionService.java b/login-app/src/main/java/ink/wgink/login/app/service/appversion/IAppVersionService.java
new file mode 100644
index 00000000..28326488
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/service/appversion/IAppVersionService.java
@@ -0,0 +1,162 @@
+package ink.wgink.login.app.service.appversion;
+
+import ink.wgink.exceptions.FileException;
+import ink.wgink.exceptions.SearchException;
+import ink.wgink.exceptions.UpdateException;
+import ink.wgink.login.app.pojo.dtos.appversion.AppVersionDTO;
+import ink.wgink.login.app.pojo.pos.appversion.AppVersionPO;
+import ink.wgink.login.app.pojo.vos.appversion.AppVersionSaveVO;
+import ink.wgink.login.app.pojo.vos.appversion.AppVersionVO;
+import ink.wgink.pojo.ListPage;
+import ink.wgink.pojo.result.SuccessResultData;
+import ink.wgink.pojo.result.SuccessResultList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: IAppDeviceService
+ * @Description: app设备
+ * @Author: wanggeng
+ * @Date: 2021/4/7 4:19 下午
+ * @Version: 1.0
+ */
+public interface IAppVersionService {
+
+ /**
+ * 新增app版本
+ *
+ * @param appVersionSaveVO
+ * @return
+ */
+ void save(AppVersionSaveVO appVersionSaveVO);
+
+ /**
+ * 删除
+ *
+ * @param ids
+ */
+ void remove(List ids);
+
+ /**
+ * 修改
+ *
+ * @param appVersionId
+ * @param appVersionVO
+ */
+ void update(String appVersionId, AppVersionVO appVersionVO);
+
+ /**
+ * 更新APP接口锁定状态
+ *
+ * @param appVersionId
+ * @param appApiLock
+ */
+ void updateApiLock(String appVersionId, Integer appApiLock);
+
+ /**
+ * 更新APP为发布状态
+ *
+ * @param appVersionId
+ * @param isRelease
+ */
+ void updateRelease(String appVersionId, int isRelease);
+
+ /**
+ * APP接口是否锁定,如果锁定,必须升级APP
+ *
+ * @param appVersionId
+ * @param appVersion
+ * @return
+ */
+ boolean canApiLock(String appVersionId, String appVersion);
+
+ /**
+ * 详情
+ *
+ * @param params
+ * @return
+ */
+ AppVersionDTO get(Map params);
+
+ /**
+ * 详情
+ *
+ * @param appVersionId
+ * @return
+ */
+ AppVersionDTO get(String appVersionId);
+
+ /**
+ * 详情
+ *
+ * @param params
+ * @return
+ */
+ AppVersionPO getPO(Map params);
+
+ /**
+ * 详情
+ *
+ * @param appVersionId
+ * @return
+ */
+ AppVersionPO getPO(String appVersionId);
+
+ /**
+ * 详情
+ *
+ * @param appVersionId
+ * @param isRelease
+ * @return
+ */
+ AppVersionPO getPO(String appVersionId, int isRelease);
+
+ /**
+ * 列表
+ *
+ * @param params
+ * @return
+ */
+ List list(Map params);
+
+ /**
+ * 列表(分页)
+ *
+ * @param page
+ * @return
+ */
+ SuccessResultList> listPage(ListPage page);
+
+ /**
+ * 获取app二维码
+ *
+ * @param appVersionId
+ * @param response
+ */
+ void downloadQrCode(String appVersionId, HttpServletResponse response) throws IOException;
+
+ /**
+ * 获取APP当前版本号
+ *
+ * @param appVersionId
+ * @return
+ * @throws SearchException
+ */
+ Integer getNumber(String appVersionId) throws SearchException;
+
+ /**
+ * 下载APP
+ *
+ * @param appVersionId
+ * @param request
+ * @param response
+ */
+ void download(String appVersionId, HttpServletRequest request, HttpServletResponse response);
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/service/appversion/impl/AppVersionServiceImpl.java b/login-app/src/main/java/ink/wgink/login/app/service/appversion/impl/AppVersionServiceImpl.java
new file mode 100644
index 00000000..2f08e5c6
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/service/appversion/impl/AppVersionServiceImpl.java
@@ -0,0 +1,192 @@
+package ink.wgink.login.app.service.appversion.impl;
+
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import ink.wgink.common.base.DefaultBaseService;
+import ink.wgink.exceptions.SearchException;
+import ink.wgink.login.app.dao.appversion.IAppVersionDao;
+import ink.wgink.login.app.pojo.dtos.appversion.AppVersionDTO;
+import ink.wgink.login.app.pojo.pos.appversion.AppVersionPO;
+import ink.wgink.login.app.pojo.vos.appversion.AppVersionSaveVO;
+import ink.wgink.login.app.pojo.vos.appversion.AppVersionVO;
+import ink.wgink.login.app.service.appversion.IAppVersionService;
+import ink.wgink.module.file.service.IFileService;
+import ink.wgink.pojo.ListPage;
+import ink.wgink.pojo.result.SuccessResultList;
+import ink.wgink.util.QRCodeUtil;
+import ink.wgink.util.UUIDUtil;
+import ink.wgink.util.map.HashMapUtil;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: AppDeviceServiceImpl
+ * @Description: app设备
+ * @Author: wanggeng
+ * @Date: 2021/4/7 4:20 下午
+ * @Version: 1.0
+ */
+@Service
+public class AppVersionServiceImpl extends DefaultBaseService implements IAppVersionService {
+
+ @Autowired
+ private IAppVersionDao appVersionDao;
+ @Autowired
+ private IFileService fileService;
+ @Value("${server.url}")
+ private String serverUrl;
+
+ @Override
+ public void save(AppVersionSaveVO appVersionSaveVO) {
+ Map params = HashMapUtil.beanToMap(appVersionSaveVO);
+ params.put("appVersion", "1");
+ params.put("appDownloadCount", "0");
+ params.put("appVersionId", UUIDUtil.getUUID());
+ setSaveInfo(params);
+ appVersionDao.save(params);
+ }
+
+ @Override
+ public void remove(List ids) {
+ Map params = getHashMap(2);
+ params.put("appVersionIds", ids);
+ setUpdateInfo(params);
+ appVersionDao.remove(params);
+ }
+
+ @Override
+ public void update(String appVersionId, AppVersionVO appVersionVO) {
+ Map params = HashMapUtil.beanToMap(appVersionVO);
+ setUpdateInfo(params);
+ appVersionDao.update(params);
+ }
+
+ @Override
+ public void updateApiLock(String appVersionId, Integer appApiLock) {
+ Map params = getHashMap(8);
+ params.put("appApiLock", appApiLock);
+ params.put("appVersionId", appVersionId);
+ setUpdateInfo(params);
+ appVersionDao.updateApiLock(params);
+ }
+
+ @Override
+ public void updateRelease(String appVersionId, int isRelease) {
+ Map params = getHashMap(8);
+ params.put("isRelease", isRelease);
+ params.put("appVersionId", appVersionId);
+ setUpdateInfo(params);
+ appVersionDao.updateRelease(params);
+ }
+
+ @Override
+ public AppVersionDTO get(Map params) {
+ return appVersionDao.get(params);
+ }
+
+ @Override
+ public AppVersionDTO get(String appVersionId) {
+ Map params = getHashMap(2);
+ params.put("appVersionId", appVersionId);
+ return get(params);
+ }
+
+ @Override
+ public AppVersionPO getPO(Map params) {
+ return appVersionDao.getPO(params);
+ }
+
+ @Override
+ public AppVersionPO getPO(String appVersionId) {
+ Map params = getHashMap(2);
+ params.put("appVersionId", appVersionId);
+ return getPO(params);
+ }
+
+ @Override
+ public AppVersionPO getPO(String appVersionId, int isRelease) {
+ Map params = getHashMap(2);
+ params.put("appVersionId", appVersionId);
+ params.put("isRelease", isRelease);
+ return getPO(params);
+ }
+
+ @Override
+ public List list(Map params) {
+ return appVersionDao.list(params);
+ }
+
+ @Override
+ public SuccessResultList> listPage(ListPage page) {
+ PageHelper.startPage(page.getPage(), page.getRows());
+ List appVersionDTOs = list(page.getParams());
+ PageInfo pageInfo = new PageInfo<>(appVersionDTOs);
+ return new SuccessResultList<>(appVersionDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
+ }
+
+ @Override
+ public void downloadQrCode(String appVersionId, HttpServletResponse response) throws IOException {
+ String qrContent = String.format("%s/app/appversion/download/%s", serverUrl, appVersionId);
+ response.setContentType("image/png");
+ BufferedImage bufferedImage = QRCodeUtil.createQrCode(300, 300, qrContent, null);
+ ImageIO.write(bufferedImage, "png", response.getOutputStream());
+ }
+
+ @Override
+ public Integer getNumber(String appVersionId) throws SearchException {
+ AppVersionPO appVersionPO = getPO(appVersionId, 1);
+ if (appVersionPO == null) {
+ throw new SearchException("app不存在或未发布");
+ }
+ return appVersionPO.getAppVersion();
+ }
+
+ @Override
+ public void download(String appVersionId, HttpServletRequest request, HttpServletResponse response) {
+ LOG.debug("获取当前APP");
+ AppVersionPO appVersionPO = getPO(appVersionId, 1);
+ if (appVersionPO == null) {
+ throw new SearchException("app不存在或未发布");
+ }
+ LOG.debug("下载APP");
+ Map params = getHashMap(4);
+ params.put("fileId", appVersionPO.getAppFile());
+ params.put("isOpen", false);
+ fileService.downLoadFile(request, response, params, false);
+ LOG.debug("更新下载次数");
+ appVersionDao.updateDownloadCount(appVersionPO.getAppVersionId());
+ }
+
+ @Override
+ public boolean canApiLock(String appVersionId, String appVersion) {
+ AppVersionPO appVersionPO = getPO(appVersionId);
+ if (Objects.isNull(appVersionPO)) {
+ throw new SearchException("app不存在");
+ }
+ if (appVersionPO.getAppApiLock() == 0) {
+ return false;
+ }
+ if (StringUtils.isBlank(appVersion)) {
+ throw new SearchException("app版本号不能为空");
+ }
+ if (Integer.parseInt(appVersion) < appVersionPO.getAppVersion()) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/login-app/src/main/java/ink/wgink/login/app/startup/LoginAppStartUp.java b/login-app/src/main/java/ink/wgink/login/app/startup/LoginAppStartUp.java
new file mode 100644
index 00000000..bd74b5c1
--- /dev/null
+++ b/login-app/src/main/java/ink/wgink/login/app/startup/LoginAppStartUp.java
@@ -0,0 +1,47 @@
+package ink.wgink.login.app.startup;
+
+import ink.wgink.login.app.dao.appdeviceuser.IAppDeviceUserDao;
+import ink.wgink.login.app.dao.appversion.IAppVersionDao;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+/**
+ * When you feel like quitting. Think about why you started
+ * 当你想要放弃的时候,想想当初你为何开始
+ *
+ * @ClassName: LoginAppStartUp
+ * @Description: app登录
+ * @Author: wanggeng
+ * @Date: 2021/4/7 7:00 下午
+ * @Version: 1.0
+ */
+@Component
+public class LoginAppStartUp implements ApplicationRunner {
+
+ private static final Logger LOG = LoggerFactory.getLogger(LoginAppStartUp.class);
+ @Autowired
+ private IAppVersionDao appVersionDao;
+ @Autowired
+ private IAppDeviceUserDao appDeviceUserDao;
+
+ @Override
+ public void run(ApplicationArguments args) throws Exception {
+ initTable();
+ }
+
+ /**
+ * 建表
+ */
+ private void initTable() {
+ LOG.debug("创建 app_version 表");
+ appVersionDao.createTable();
+
+ LOG.debug("创建 app_device_user 表");
+ appDeviceUserDao.createTable();
+ }
+
+}
diff --git a/login-app/src/main/resources/mybatis/mapper/appdeviceuser/app-device-user-mapper.xml b/login-app/src/main/resources/mybatis/mapper/appdeviceuser/app-device-user-mapper.xml
new file mode 100644
index 00000000..ec750647
--- /dev/null
+++ b/login-app/src/main/resources/mybatis/mapper/appdeviceuser/app-device-user-mapper.xml
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CREATE TABLE IF NOT EXISTS `app_device_user` (
+ `device_no` varchar(255) DEFAULT NULL,
+ `user_id` char(36) DEFAULT NULL,
+ KEY `device_no` (`device_no`),
+ KEY `user_id` (`user_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+
+
+ INSERT INTO app_device_user(
+ device_no,
+ user_id,
+ gmt_create
+ ) VALUES(
+ #{deviceNo},
+ #{userId},
+ #{gmtCreate}
+ )
+
+
+
+
+ DELETE FROM
+ app_device_user
+ WHERE
+ device_no = #{deviceNo}
+ AND
+ user_id = #{userId}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/login-app/src/main/resources/mybatis/mapper/appversion/app-version-mapper.xml b/login-app/src/main/resources/mybatis/mapper/appversion/app-version-mapper.xml
new file mode 100644
index 00000000..0cca4810
--- /dev/null
+++ b/login-app/src/main/resources/mybatis/mapper/appversion/app-version-mapper.xml
@@ -0,0 +1,252 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CREATE TABLE IF NOT EXISTS `app_version` (
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `app_version_id` char(36) NOT NULL COMMENT '主键',
+ `app_name` varchar(255) NOT NULL COMMENT 'APP名称',
+ `app_summary` varchar(255) NOT NULL COMMENT 'APP说明',
+ `app_version` int(11) DEFAULT '0' COMMENT 'APP版本号',
+ `app_download_count` int(11) DEFAULT '0' COMMENT '下载次数',
+ `app_file` char(36) NOT NULL COMMENT 'APP文件',
+ `app_api_lock` int(1) DEFAULT '0' COMMENT '接口版本锁定',
+ `is_necessary` int(1) DEFAULT '0' COMMENT '强制更新',
+ `is_release` int(1) DEFAULT '0' COMMENT '是否发布',
+ `creator` char(36) DEFAULT NULL,
+ `gmt_create` datetime DEFAULT NULL,
+ `modifier` char(36) DEFAULT NULL,
+ `gmt_modified` datetime DEFAULT NULL,
+ `is_delete` int(1) DEFAULT '0',
+ PRIMARY KEY (`id`,`app_version_id`)
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+
+
+
+ INSERT INTO app_version(
+ app_version_id,
+ app_name,
+ app_summary,
+ app_version,
+ app_download_count,
+ app_file,
+ is_necessary,
+ is_release,
+ creator,
+ gmt_create,
+ modifier,
+ gmt_modified,
+ is_delete
+ ) VALUES(
+ #{appVersionId},
+ #{appName},
+ #{appSummary},
+ #{appVersion},
+ #{appDownloadCount},
+ #{appFile},
+ #{isNecessary},
+ #{isRelease},
+ #{creator},
+ #{gmtCreate},
+ #{modifier},
+ #{gmtModified},
+ #{isDelete}
+ )
+
+
+
+
+ UPDATE
+ app_version
+ SET
+ is_delete = 1,
+ modifier = #{modifier},
+ gmt_modified = #{gmtModified}
+ WHERE
+ app_version_id IN
+
+ #{appVersionIds[${index}]}
+
+
+
+
+
+ UPDATE
+ app_version
+ SET
+
+ app_summary = #{appSummary},
+
+ app_file = #{appFile},
+ is_necessary = #{isNecessary},
+ is_release = #{isRelease},
+ app_version = app_version + 1,
+ modifier = #{modifier},
+ gmt_modified = #{gmtModified}
+ WHERE
+ app_version_id = #{appVersionId}
+
+
+
+
+ UPDATE
+ app_version
+ SET
+ app_download_count = app_download_count + 1
+ WHERE
+ app_version_id = #{_parameter}
+
+
+
+
+ UPDATE
+ app_version
+ SET
+ app_api_lock = #{appApiLock},
+ modifier = #{modifier},
+ gmt_modified = #{gmtModified}
+ WHERE
+ is_delete = 0
+ AND
+ app_version_id = #{appVersionId}
+
+
+
+
+ UPDATE
+ app_version
+ SET
+ is_release = #{isRelease},
+ modifier = #{modifier},
+ gmt_modified = #{gmtModified}
+ WHERE
+ is_delete = 0
+ AND
+ app_version_id = #{appVersionId}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/login-app/src/main/resources/templates/appversion/list.html b/login-app/src/main/resources/templates/appversion/list.html
new file mode 100644
index 00000000..92ff8096
--- /dev/null
+++ b/login-app/src/main/resources/templates/appversion/list.html
@@ -0,0 +1,308 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/login-app/src/main/resources/templates/appversion/save.html b/login-app/src/main/resources/templates/appversion/save.html
new file mode 100644
index 00000000..b0cfcaa8
--- /dev/null
+++ b/login-app/src/main/resources/templates/appversion/save.html
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/login-app/src/main/resources/templates/appversion/update.html b/login-app/src/main/resources/templates/appversion/update.html
new file mode 100644
index 00000000..9acbe01f
--- /dev/null
+++ b/login-app/src/main/resources/templates/appversion/update.html
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1e08f908..eea0ffde 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,6 +26,7 @@
service-group
service-position
login-base
+ login-app
pom