소스 검색

• feat: 新增通用客户端 JAR 包手动更新功能
- 新增通用客户端版本管理
- 支持上传和管理客户端 JAR 包
- 客户端设置中增加手动检查更新
- 支持下载、替换 JAR 并自动重启
- 保留原有安卓版本管理功能
- 放行客户端版本检查接口

wangxichen 1 일 전
부모
커밋
1058342aca

+ 15 - 0
src/main/java/com/jeesite/modules/mesclient/dao/MesClientVersionDao.java

@@ -0,0 +1,15 @@
+package com.jeesite.modules.mesclient.dao;
+
+import com.jeesite.common.dao.CrudDao;
+import com.jeesite.common.mybatis.annotation.MyBatisDao;
+import com.jeesite.modules.mesclient.entity.MesClientVersion;
+
+/**
+ * 瀹夊崜鐗堟湰DAO鎺ュ彛
+ * @author hzd
+ * @version 2023-08-11
+ */
+@MyBatisDao
+public interface MesClientVersionDao extends CrudDao<MesClientVersion> {
+    MesClientVersion findLatestVersion(MesClientVersion mesClientVersion);
+}

+ 39 - 0
src/main/java/com/jeesite/modules/mesclient/entity/MesClientVersion.java

@@ -0,0 +1,39 @@
+package com.jeesite.modules.mesclient.entity;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+import com.jeesite.common.entity.DataEntity;
+import com.jeesite.common.mybatis.annotation.Column;
+import com.jeesite.common.mybatis.annotation.Table;
+import com.jeesite.common.mybatis.mapper.query.QueryType;
+
+@Table(name="mes_client_version", alias="a", label="Client Version", columns={
+    @Column(name="id", attrName="id", label="id", isPK=true),
+    @Column(name="ver", attrName="ver", label="version", isUpdateForce=true),
+    @Column(name="content", attrName="content", label="content", queryType=QueryType.LIKE),
+    @Column(name="state", attrName="state", label="state"),
+    @Column(name="create_by", attrName="createBy", label="create_by", isUpdate=false, isQuery=false),
+    @Column(name="create_date", attrName="createDate", label="create_date", isUpdate=false, isQuery=false),
+    @Column(name="update_by", attrName="updateBy", label="update_by", isQuery=false),
+    @Column(name="update_date", attrName="updateDate", label="update_date", isQuery=false)
+}, orderBy="a.update_date DESC")
+public class MesClientVersion extends DataEntity<MesClientVersion> {
+    private static final long serialVersionUID = 1L;
+    private Long ver;
+    private String content;
+    private String state;
+    private String path;
+
+    public MesClientVersion() { this(null); }
+    public MesClientVersion(String id) { super(id); }
+    public Long getVer() { return ver; }
+    public void setVer(Long ver) { this.ver = ver; }
+    public String getContent() { return content; }
+    public void setContent(String content) { this.content = content; }
+    @NotBlank(message="state is required")
+    @Size(min=0, max=1, message="state length must not exceed 1")
+    public String getState() { return state; }
+    public void setState(String state) { this.state = state; }
+    public String getPath() { return path; }
+    public void setPath(String path) { this.path = path; }
+}

+ 99 - 0
src/main/java/com/jeesite/modules/mesclient/service/MesClientVersionService.java

@@ -0,0 +1,99 @@
+package com.jeesite.modules.mesclient.service;
+
+import java.util.List;
+
+import com.jeesite.modules.mesclient.dao.MesClientVersionDao;
+import com.jeesite.modules.mesclient.entity.MesClientVersion;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.service.CrudService;
+import com.jeesite.modules.file.utils.FileUploadUtils;
+
+/**
+ * 瀹夊崜鐗堟湰Service
+ * @author hzd
+ * @version 2023-08-11
+ */
+@Service
+public class MesClientVersionService extends CrudService<MesClientVersionDao, MesClientVersion> {
+
+	@Autowired
+	private MesClientVersionDao mesClientVersionDao;
+
+	/**
+	 * 鑾峰彇鍗曟潯鏁版嵁
+	 * @param mesClientVersion
+	 * @return
+	 */
+	@Override
+	public MesClientVersion get(MesClientVersion mesClientVersion) {
+		return super.get(mesClientVersion);
+	}
+	
+	/**
+	 * 鏌ヨ鍒嗛〉鏁版嵁
+	 * @param mesClientVersion 鏌ヨ鏉′欢
+	 * @param mesClientVersion.page 鍒嗛〉瀵硅薄
+	 * @return
+	 */
+	@Override
+	public Page<MesClientVersion> findPage(MesClientVersion mesClientVersion) {
+		return super.findPage(mesClientVersion);
+	}
+	
+	/**
+	 * 鏌ヨ鍒楄〃鏁版嵁
+	 * @param mesClientVersion
+	 * @return
+	 */
+	@Override
+	public List<MesClientVersion> findList(MesClientVersion mesClientVersion) {
+		return super.findList(mesClientVersion);
+	}
+	
+	/**
+	 * 淇濆瓨鏁版嵁锛堟彃鍏ユ垨鏇存柊锛?
+	 * @param mesClientVersion
+	 */
+	@Override
+	@Transactional
+	public void save(MesClientVersion mesClientVersion) {
+		super.save(mesClientVersion);
+		// 淇濆瓨涓婁紶闄勪欢
+		FileUploadUtils.saveFileUpload(mesClientVersion, mesClientVersion.getId(), "mesClientVersion_file");
+	}
+	
+	/**
+	 * 鏇存柊鐘舵€?
+	 * @param mesClientVersion
+	 */
+	@Override
+	@Transactional
+	public void updateStatus(MesClientVersion mesClientVersion) {
+		super.updateStatus(mesClientVersion);
+	}
+	
+	/**
+	 * 鍒犻櫎鏁版嵁
+	 * @param mesClientVersion
+	 */
+	@Override
+	@Transactional
+	public void delete(MesClientVersion mesClientVersion) {
+		super.delete(mesClientVersion);
+	}
+
+	/**
+	 * 鑾峰彇app鏈€鏂扮増鏈?
+	 * @return
+	 */
+	public MesClientVersion findLatestVersion(){
+		MesClientVersion mesClientVersion = new MesClientVersion();
+		mesClientVersion.setState("0");
+		return mesClientVersionDao.findLatestVersion(mesClientVersion);
+	}
+	
+}

+ 141 - 0
src/main/java/com/jeesite/modules/mesclient/web/MesClientVersionController.java

@@ -0,0 +1,141 @@
+package com.jeesite.modules.mesclient.web;
+
+import java.util.List;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.jeesite.common.collect.ListUtils;
+import com.jeesite.common.lang.ObjectUtils;
+import com.jeesite.common.shiro.authc.FormToken;
+import com.jeesite.common.shiro.filter.FormFilter;
+import com.jeesite.common.shiro.realm.AuthorizingRealm;
+import com.jeesite.modules.file.entity.FileUpload;
+import com.jeesite.modules.file.service.FileUploadService;
+import com.jeesite.modules.mesclient.entity.MesClientVersion;
+import com.jeesite.modules.mes.resp.CommonResp;
+import com.jeesite.modules.mesclient.service.MesClientVersionService;
+import com.jeesite.modules.sys.utils.UserUtils;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.jeesite.common.config.Global;
+import com.jeesite.common.entity.Page;
+import com.jeesite.common.web.BaseController;
+
+
+/**
+ * 瀹夊崜鐗堟湰Controller
+ * @author hzd
+ * @version 2023-08-11
+ */
+@Controller
+@RequestMapping(value = "${adminPath}/mes/clientVersion")
+public class MesClientVersionController extends BaseController {
+
+	@Autowired
+	private MesClientVersionService mesClientVersionService;
+
+	@Resource
+	private FileUploadService fileUploadService;
+	
+	/**
+	 * 鑾峰彇鏁版嵁
+	 */
+	@ModelAttribute
+	public MesClientVersion get(String id, boolean isNewRecord) {
+		return mesClientVersionService.get(id, isNewRecord);
+	}
+	
+	/**
+	 * 鏌ヨ鍒楄〃
+	 */
+	@RequiresPermissions("mes:clientVersion:view")
+	@RequestMapping(value = {"list", ""})
+	public String list(MesClientVersion mesClientVersion, Model model) {
+		model.addAttribute("mesClientVersion", mesClientVersion);
+		return "modules/mesclient/mesClientVersionList";
+	}
+	
+	/**
+	 * 鏌ヨ鍒楄〃鏁版嵁
+	 */
+	@RequiresPermissions("mes:clientVersion:view")
+	@RequestMapping(value = "listData")
+	@ResponseBody
+	public Page<MesClientVersion> listData(MesClientVersion mesClientVersion, HttpServletRequest request, HttpServletResponse response) {
+		mesClientVersion.setPage(new Page<>(request, response));
+		Page<MesClientVersion> page = mesClientVersionService.findPage(mesClientVersion);
+		return page;
+	}
+
+	/**
+	 * 鏌ョ湅缂栬緫琛ㄥ崟
+	 */
+	@RequiresPermissions("mes:clientVersion:view")
+	@RequestMapping(value = "form")
+	public String form(MesClientVersion mesClientVersion, Model model) {
+		model.addAttribute("mesClientVersion", mesClientVersion);
+		return "modules/mesclient/mesClientVersionForm";
+	}
+
+	/**
+	 * 淇濆瓨鏁版嵁
+	 */
+	@RequiresPermissions("mes:clientVersion:edit")
+	@PostMapping(value = "save")
+	@ResponseBody
+	public String save(@Validated MesClientVersion mesClientVersion) {
+		mesClientVersionService.save(mesClientVersion);
+		return renderResult(Global.TRUE, text("Operation succeeded"));
+	}
+	
+	/**
+	 * 鍒犻櫎鏁版嵁
+	 */
+	@RequiresPermissions("mes:clientVersion:edit")
+	@RequestMapping(value = "delete")
+	@ResponseBody
+	public String delete(MesClientVersion mesClientVersion) {
+		mesClientVersionService.delete(mesClientVersion);
+		return renderResult(Global.TRUE, text("Operation succeeded"));
+	}
+
+	@RequestMapping(value = "ver")
+	@ResponseBody
+	public CommonResp ver(HttpServletRequest req) {
+		String host = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/js";
+		CommonResp<MesClientVersion> resp = new CommonResp<>();
+		MesClientVersion mesClientVersion = mesClientVersionService.findLatestVersion();
+		if(ObjectUtils.isEmpty(mesClientVersion)){
+			resp.setResult(Global.FALSE);
+			resp.setMessage("No available client version");
+			return resp;
+		}
+
+		// 鑾峰彇鍥剧墖
+		FileUpload fu = new FileUpload();
+		fu.setBizKey(mesClientVersion.getId());
+		fu.setBizType("mesClientVersion_file");
+		List<FileUpload> finfo = fileUploadService.findList(fu);
+		if(ListUtils.isEmpty(finfo)){
+			resp.setResult(Global.FALSE);
+			resp.setMessage("No available client version");
+			return resp;
+		}
+		mesClientVersion.setPath(host + finfo.get(0).getFileUrl());
+		resp.setData(mesClientVersion);
+		resp.setResult(Global.TRUE);
+		return resp;
+	}
+
+	
+}

+ 3 - 2
src/main/resources/config/application.yml

@@ -54,8 +54,8 @@ jdbc:
   # Mysql 数据库配置
   type: mysql
   driver: com.mysql.cj.jdbc.Driver
-#  url: jdbc:mysql://127.0.0.1:3306/mes_cloud_t09?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
-  url: jdbc:mysql://192.168.114.99:3306/mes_cloud_t09?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
+  url: jdbc:mysql://127.0.0.1:3306/mes_cloud_t09?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
+#  url: jdbc:mysql://192.168.114.99:3306/mes_cloud_t09?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
 #  url: jdbc:mysql://192.168.110.99:3306/mes_cloud?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
 
   username: mes_cloud
@@ -616,6 +616,7 @@ shiro:
   # 提示:填写过滤规则,请注意先后顺序,从上到下,先匹配先受用规则,匹配成功后不再继续匹配。
   filterChainDefinitions: |
     ${adminPath}/mes/mesApp/ver = anon
+    ${adminPath}/mes/clientVersion/ver = anon
     ${adminPath}/mes/mesLogin/login = anon
     ${adminPath}/mes/pda/product/steelSn = anon
     ${adminPath}/mes/mesProductQm/add = anon

+ 23 - 0
src/main/resources/mappings/modules/mesclient/MesClientVersionDao.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.jeesite.modules.mesclient.dao.MesClientVersionDao">
+	
+	<!-- 鏌ヨ鏁版嵁
+	<select id="findList" resultType="MesClientVersion">
+		SELECT ${sqlMap.column.toSql()}
+		FROM ${sqlMap.table.toSql()}
+		<where>
+			${sqlMap.where.toSql()}
+		</where>
+		ORDER BY ${sqlMap.order.toSql()}
+	</select> -->
+	<select id="findLatestVersion" resultType="com.jeesite.modules.mesclient.entity.MesClientVersion">
+		SELECT ${sqlMap.column.toSql()}
+		FROM ${sqlMap.table.toSql()}
+		<where>
+			${sqlMap.where.toSql()}
+		</where>
+		ORDER BY create_date DESC
+		Limit 1
+	</select>
+</mapper>

+ 13 - 0
src/main/resources/views/modules/mesclient/mesClientVersionForm.html

@@ -0,0 +1,13 @@
+<% layout('/layouts/default.html', {title: '通用客户端版本', libs: ['validate','fileupload']}){ %>
+<div class="main-content"><div class="box box-main">
+<div class="box-header with-border"><div class="box-title"><i class="fa icon-note"></i> ${text(mesClientVersion.isNewRecord ? '新增通用客户端版本' : '编辑通用客户端版本')}</div></div>
+<#form:form id="inputForm" model="${mesClientVersion}" action="${ctx}/mes/clientVersion/save" method="post" class="form-horizontal">
+<div class="box-body">
+<#form:hidden path="id"/>
+<div class="form-group"><label class="control-label col-sm-2">版本号:</label><div class="col-sm-8"><#form:input path="ver" maxlength="9" class="form-control digits required"/></div></div>
+<div class="form-group"><label class="control-label col-sm-2">更新内容:</label><div class="col-sm-8"><#form:textarea path="content" rows="5" class="form-control"/></div></div>
+<div class="form-group"><label class="control-label col-sm-2">状态:</label><div class="col-sm-8"><#form:select path="state" dictType="mes_app_status" class="form-control required"/></div></div>
+<div class="form-group"><label class="control-label col-sm-2">JAR 文件:</label><div class="col-sm-8"><#form:fileupload id="uploadFile" bizKey="${mesClientVersion.id}" bizType="mesClientVersion_file" uploadType="all" allowSuffixes="jar" maxUploadNum="1" readonly="false" preview="true"/></div></div>
+</div><div class="box-footer"><button type="submit" class="btn btn-primary" id="btnSubmit">保存</button>&nbsp;<button type="button" class="btn btn-default" onclick="js.closeCurrentTabPage()">关闭</button></div>
+</#form:form></div></div><% } %>
+<script>$("#inputForm").validate({submitHandler:function(form){js.ajaxSubmitForm($(form),function(data){js.showMessage(data.message);if(data.result==Global.TRUE)js.closeCurrentTabPage();},"json");}});</script>

+ 75 - 0
src/main/resources/views/modules/mesclient/mesClientVersionList.html

@@ -0,0 +1,75 @@
+<% layout('/layouts/default.html', {title: '通用客户端版本管理', libs: ['dataGrid']}){ %>
+<div class="main-content">
+	<div class="box box-main">
+		<div class="box-header">
+			<div class="box-title">
+				<i class="fa icon-notebook"></i> ${text('通用客户端版本管理')}
+			</div>
+			<div class="box-tools pull-right">
+				<a href="#" class="btn btn-default" id="btnSearch" title="${text('查询')}"><i class="fa fa-filter"></i> ${text('查询')}</a>
+				<% if(hasPermi('mes:clientVersion:edit')){ %>
+					<a href="${ctx}/mes/clientVersion/form" class="btn btn-default btnTool" title="${text('新增通用客户端版本')}"><i class="fa fa-plus"></i> ${text('新增')}</a>
+				<% } %>
+				<a href="#" class="btn btn-default" id="btnSetting" title="${text('设置')}"><i class="fa fa-navicon"></i></a>
+			</div>
+		</div>
+		<div class="box-body">
+			<#form:form id="searchForm" model="${mesClientVersion}" action="${ctx}/mes/clientVersion/listData" method="post" class="form-inline hide"
+					data-page-no="${parameter.pageNo}" data-page-size="${parameter.pageSize}" data-order-by="${parameter.orderBy}">
+				<div class="form-group">
+					<label class="control-label">${text('版本号')}:</label>
+					<div class="control-inline">
+						<#form:input path="ver" maxlength="9" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('更新内容')}:</label>
+					<div class="control-inline">
+						<#form:input path="content" class="form-control width-120"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<label class="control-label">${text('状态')}:</label>
+					<div class="control-inline width-120">
+						<#form:select path="state" dictType="mes_app_status" blankOption="true" class="form-control"/>
+					</div>
+				</div>
+				<div class="form-group">
+					<button type="submit" class="btn btn-primary btn-sm">${text('查询')}</button>
+					<button type="reset" class="btn btn-default btn-sm">${text('重置')}</button>
+				</div>
+			</#form:form>
+			<table id="dataGrid"></table>
+			<div id="dataGridPage"></div>
+		</div>
+	</div>
+</div>
+<% } %>
+<script>
+// 初始化DataGrid对象
+$('#dataGrid').dataGrid({
+	searchForm: $("#searchForm"),
+	columnModel: [
+		{header:'${text("版本号")}', name:'ver', index:'a.ver', width:150, align:"center", frozen:true, formatter: function(val, obj, row, act){
+			return '<a href="${ctx}/mes/clientVersion/form?id='+row.id+'" class="btnList" data-title="${text("编辑通用客户端版本")}">'+(val||row.id)+'</a>';
+		}},
+		{header:'${text("更新内容")}', name:'content', index:'a.content', width:250, align:"center"},
+		{header:'${text("状态")}', name:'state', index:'a.state', width:150, align:"center", formatter: function(val, obj, row, act){
+			return js.getDictLabel(${@DictUtils.getDictListJson('mes_app_status')}, val, '${text("未知")}', true);
+		}},
+		{header:'${text("更新时间")}', name:'updateDate', index:'a.update_date', width:150, align:"center"},
+		{header:'${text("操作")}', name:'actions', width:120, formatter: function(val, obj, row, act){
+			var actions = [];
+			//<% if(hasPermi('mes:clientVersion:edit')){ %>
+				actions.push('<a href="${ctx}/mes/clientVersion/form?id='+row.id+'" class="btnList" title="${text("编辑通用客户端版本")}"><i class="fa fa-pencil"></i></a>&nbsp;');
+				actions.push('<a href="${ctx}/mes/clientVersion/delete?id='+row.id+'" class="btnList" title="${text("删除通用客户端版本")}" data-confirm="${text("确认要删除该通用客户端版本吗?")}"><i class="fa fa-trash-o"></i></a>&nbsp;');
+			//<% } %>
+			return actions.join('');
+		}}
+	],
+	// 加载成功后执行事件
+	ajaxSuccess: function(data){
+		
+	}
+});
+</script>