Commit cb162782 authored by 赵啸非's avatar 赵啸非

添加应用发布

parent fc40e759
<template>
<!-- 弹出框表单 -->
<el-dialog :title="title" :visible.sync="open" width="90%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-row>
<Field label="应用编码" prop="appCode" v-model="form.appCode" type="textarea" placeholder="请输入应用编码"/>
<Field label="应用名称" prop="appName" v-model="form.appName" type="textarea" placeholder="请输入应用名称"/>
<Field label="文件路径地址"><fileUpload v-model="form.filePath" prePath="/file/uploadfile"/></Field>
<Field label="文件部署路径地址"><fileUpload v-model="form.distributeFilePath" prePath="/file/uploadfile"/></Field>
<Field label="应用类型" prop="appType" v-model="form.appType" type="select" :enumData="dict.appType" placeholder="请选择应用类型"/>
<Field label="是否部署" prop="distribute" v-model="form.distribute" type="select" :enumData="dict.distribute" placeholder="请选择是否部署"/>
<Field label="版本" prop="version" v-model="form.version" type="textarea" placeholder="请输入版本"/>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" v-if="pageInfo.type !== 'view'" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</template>
<script>
import form from "@/assets/mixins/formdialog";
import dialogShow from "./dialogshow";
import FileUpload from '@/components/FileUpload';
export default {
mixins: [form],
components: {
dialogShow ,
FileUpload,
},
data() {
return {
// 遮罩层
loading: true,
// 弹出层标题
title: "应用发布部署",
// 是否显示弹出层
open: false,
toString:[
"appType",
"distribute",
],
// 表单校验
rules: {
appType: [
{required: true,message: "请输入应用类型", trigger: "blur" },
],
distribute: [
{required: true,message: "请输入是否部署", trigger: "blur" },
],
}
};
},
methods: {
/** 编辑 */
edit(row) {
this.reset()
this.query = { id: row.id };
this.urls.currUrl ="app/publish/edit";
this.getData();
this.pageInfo.type="edit"
this.title = "修改应用发布部署";
},
/** 新增 */
add(row) {
this.reset()
this.urls.currUrl = "app/publish/add";
this.getData();
this.pageInfo.type="add"
this.title = "新增应用发布部署";
},
/** 查看*/
view(row) {
this.reset()
this.query = { id: row.id };
this.urls.currUrl ="app/publish/view";
this.getData();
this.pageInfo.type="view"
this.title = "应用发布部署详细";
},
/**取消按钮 */
cancel() {
this.open = false;
},
/**获取数据后弹框 */
afterRender(data) {
this.open = true;
},
afterSubmit(data) {
this.open = false;
this.$emit("ok");
},
// 表单重置
reset() {
this.form = {
appCode : null,
appName : null,
filePath : null,
distributeFilePath : null,
appType : null,
distribute : null,
version : null,
};
this.resetForm("form");
},
resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
}
},
},
};
</script>
<template>
<div class="page">
<LayoutTable :data="tableData" :config="tableConfig">
</LayoutTable>
<dialog-show ref="dialogform" @ok="getData" />
</div>
</template>
<script>
/** 表单弹出框模式需引入 */
import dialogShow from "./dialogshow";
import table from "@/assets/mixins/table";
export default {
name: "AppPublishList",
components: {
dialogShow
},
mixins: [table],
created() {
},
methods: {
/** 重写新增方法 */
toAdd(row) {
this.$refs.dialogform.add(row);
},
/** 重写编辑方法 */
toEdit(row) {
this.$refs.dialogform.edit(row);
},
/** 重写查看方法 */
toView(row) {
this.$refs.dialogform.view(row);
},
},
data() {
return {
config: {
search: [
],
columns: [
{type: "selection", width: 60},
{type: "index",label: "序号",width: 50},
{label: "应用编码", prop: "appCode"},
{label: "应用名称", prop: "appName"},
{label: "文件路径地址", prop: "filePath"},
{label: "文件部署路径地址", prop: "distributeFilePath"},
{label: "应用类型", prop: "appType",formatter: this.formatter},
{label: "是否部署", prop: "distribute",formatter: this.formatter},
{label: "版本", prop: "version"},
{
label: "操作",
width: 240,
formatter: row => {
return (
<table-buttons noAdd row={row} onEdit={this.toEdit} onView={this.toView} onDel={this.toDel} />
);
}
}
]
}
};
}
};
</script>
\ No newline at end of file
<template>
<layout-view>
<el-descriptions :title="title" :column="column" :size="size" :colon="false" border>
<template slot="title">
<i class="el-icon-tickets"></i>
基本详细信息
</template>
<template slot="extra">
<el-button type="primary" @click="$router.go(-1)" size="small">返回</el-button>
</template>
<el-descriptions-item label="应用编码" label-class-name="labelClass" content-class-name="contentClass">
{{form.appCode}}
</el-descriptions-item>
<el-descriptions-item label="应用名称" label-class-name="labelClass" content-class-name="contentClass">
{{form.appName}}
</el-descriptions-item>
<el-descriptions-item label="文件路径地址" label-class-name="labelClass" content-class-name="contentClass">
<fileUpload v-model="form.filePath" prePath="/file/uploadfile"/>
</el-descriptions-item>
<el-descriptions-item label="文件部署路径地址" label-class-name="labelClass" content-class-name="contentClass">
<fileUpload v-model="form.distributeFilePath" prePath="/file/uploadfile"/>
</el-descriptions-item>
<el-descriptions-item label="应用类型" label-class-name="labelClass" content-class-name="contentClass">
{{ util_formatters("appType", form.appType) }}
</el-descriptions-item>
<el-descriptions-item label="是否部署" label-class-name="labelClass" content-class-name="contentClass">
{{ util_formatters("distribute", form.distribute) }}
</el-descriptions-item>
<el-descriptions-item label="版本" label-class-name="labelClass" content-class-name="contentClass">
{{form.version}}
</el-descriptions-item>
</el-descriptions>
</layout-view>
</template>
<script>
import view from "@/assets/mixins/view";
import FileUpload from '@/components/FileUpload';
export default {
mixins: [view],
components: {
FileUpload,
},
methods: {
},
data() {
return {
size:"small",
column:2,
toString:[
"appType",
"distribute",
],
toArrays: [
],
toDate: [
]
}
}
}
</script>
<style lang="less">
.labelClass{
width: 200px;
}
.el-descriptions__body{
margin-left: 5px;
margin-right: 5px;
color: #606266;
background-color: #FFF;
}
.contentClass{
width: 600px;
}
</style>
\ No newline at end of file
......@@ -339,5 +339,23 @@ CREATE TABLE mortals_xhx_product_version
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='产品客户端版本';
-- ----------------------------
-- 应用发布部署表
-- ----------------------------
DROP TABLE IF EXISTS `mortals_xhx_app_publish`;
CREATE TABLE mortals_xhx_app_publish(
`id` bigint(20) AUTO_INCREMENT COMMENT '主键ID,主键,自增长',
`appCode` varchar(256) COMMENT '应用编码',
`appName` varchar(256) COMMENT '应用名称',
`filePath` varchar(256) COMMENT '文件路径地址',
`distributeFilePath` varchar(256) COMMENT '文件部署路径地址',
`appType` tinyint(2) NOT NULL COMMENT '应用类型(0.前端,1.后端)',
`distribute` tinyint(2) NOT NULL COMMENT '是否部署(0.否,1.是)',
`version` varchar(256) COMMENT '版本',
`createTime` datetime COMMENT '创建时间',
`updateUserId` bigint(20) COMMENT '更新用户',
`updateTime` datetime COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='应用发布部署';
......@@ -69,3 +69,9 @@ INSERT INTO `mortals_xhx_task` VALUES (5, '设备统计任务', 'deviceTotalStat
INSERT INTO `mortals_xhx_task`VALUES (6, '短信发送任务', 'smsSendTask', 0, 'SmsSendTask', NULL, NULL, 4, 10, '00', NULL, '127.0.1.1', '2023-01-13 14:42:18', 0, '2022-07-05 16:34:25', 1, '系统管理员');
INSERT INTO `mortals_xhx_task`VALUES (7, '用户同步', 'syncUserTask', 0, 'SyncUserTask', NULL, NULL, 4, 120, '00', NULL, '127.0.1.1', '2023-01-13 14:41:35', 0, '2022-07-06 10:49:48', 1, '系统管理员');
INSERT INTO `mortals_xhx_task` VALUES (9, '设备状态修正任务', 'deviceStatTask', 0, 'DeviceStatTask', NULL, NULL, 4, 120, '00', NULL, '127.0.1.1', '2023-01-13 14:41:35', 0, '2022-07-20 16:50:42', 1, '系统管理员');
INSERT INTO `mortals_xhx_param` VALUES (null, '设备资源部署细致', NULL, NULL, 'distribute_path', '/home/publish/device-manager-ui/homeDeviceUrl', 1, 4, 0, NULL, '2022-11-14 10:02:41', 1, '系统管理员');
INSERT INTO `mortals_xhx_param` VALUES (null, '应用发布编码', 'appPublish', NULL, '信息发布屏', 'information-publish', 1, 4, 0, 'appPublish', NULL, NULL, NULL);
package com.mortals.xhx.common.code;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 应用类型(0.前端,1.后端)枚举类
*
* @author zxfei
*/
public enum AppTypeEnum {
前端(0, "前端"),
后端(1, "后端");
private Integer value;
private String desc;
AppTypeEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
public Integer getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
public static AppTypeEnum getByValue(Integer value) {
for (AppTypeEnum appTypeEnum : AppTypeEnum.values()) {
if (appTypeEnum.getValue() == value) {
return appTypeEnum;
}
}
return null;
}
/**
* 获取Map集合
*
* @param eItem 不包含项
* @return
*/
public static Map<String, String> getEnumMap(Integer... eItem) {
Map<String, String> resultMap = new LinkedHashMap<>();
for (AppTypeEnum item : AppTypeEnum.values()) {
try {
boolean hasE = false;
for (Integer e : eItem) {
if (item.getValue() == e) {
hasE = true;
break;
}
}
if (!hasE) {
resultMap.put(item.getValue() + "", item.getDesc());
}
} catch (Exception ex) {
}
}
return resultMap;
}
}
\ No newline at end of file
package com.mortals.xhx.module.app.dao;
import com.mortals.framework.dao.ICRUDDao;
import com.mortals.xhx.module.app.model.AppPublishEntity;
import java.util.List;
/**
* 应用发布部署Dao
* 应用发布部署 DAO接口
*
* @author zxfei
* @date 2023-02-01
*/
public interface AppPublishDao extends ICRUDDao<AppPublishEntity,Long>{
}
package com.mortals.xhx.module.app.dao.ibatis;
import org.springframework.stereotype.Repository;
import com.mortals.xhx.module.app.dao.AppPublishDao;
import com.mortals.xhx.module.app.model.AppPublishEntity;
import java.util.Date;
import com.mortals.framework.dao.ibatis.BaseCRUDDaoMybatis;
import java.util.List;
/**
* 应用发布部署DaoImpl DAO接口
*
* @author zxfei
* @date 2023-02-01
*/
@Repository("appPublishDao")
public class AppPublishDaoImpl extends BaseCRUDDaoMybatis<AppPublishEntity,Long> implements AppPublishDao {
}
package com.mortals.xhx.module.app.model;
import java.util.List;
import java.util.ArrayList;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.mortals.framework.annotation.Excel;
import com.mortals.framework.model.BaseEntityLong;
import com.mortals.xhx.module.app.model.vo.AppPublishVo;
/**
* 应用发布部署实体对象
*
* @author zxfei
* @date 2023-02-01
*/
public class AppPublishEntity extends AppPublishVo {
private static final long serialVersionUID = 1L;
/**
* 应用编码
*/
private String appCode;
/**
* 应用名称
*/
private String appName;
/**
* 文件路径地址
*/
private String filePath;
/**
* 文件部署路径地址
*/
private String distributeFilePath;
/**
* 应用类型(0.前端,1.后端)
*/
private Integer appType;
/**
* 是否部署(0.否,1.是)
*/
private Integer distribute;
/**
* 版本
*/
private String version;
public AppPublishEntity(){}
/**
* 获取 应用编码
* @return String
*/
public String getAppCode(){
return appCode;
}
/**
* 设置 应用编码
* @param appCode
*/
public void setAppCode(String appCode){
this.appCode = appCode;
}
/**
* 获取 应用名称
* @return String
*/
public String getAppName(){
return appName;
}
/**
* 设置 应用名称
* @param appName
*/
public void setAppName(String appName){
this.appName = appName;
}
/**
* 获取 文件路径地址
* @return String
*/
public String getFilePath(){
return filePath;
}
/**
* 设置 文件路径地址
* @param filePath
*/
public void setFilePath(String filePath){
this.filePath = filePath;
}
/**
* 获取 文件部署路径地址
* @return String
*/
public String getDistributeFilePath(){
return distributeFilePath;
}
/**
* 设置 文件部署路径地址
* @param distributeFilePath
*/
public void setDistributeFilePath(String distributeFilePath){
this.distributeFilePath = distributeFilePath;
}
/**
* 获取 应用类型(0.前端,1.后端)
* @return Integer
*/
public Integer getAppType(){
return appType;
}
/**
* 设置 应用类型(0.前端,1.后端)
* @param appType
*/
public void setAppType(Integer appType){
this.appType = appType;
}
/**
* 获取 是否部署(0.否,1.是)
* @return Integer
*/
public Integer getDistribute(){
return distribute;
}
/**
* 设置 是否部署(0.否,1.是)
* @param distribute
*/
public void setDistribute(Integer distribute){
this.distribute = distribute;
}
/**
* 获取 版本
* @return String
*/
public String getVersion(){
return version;
}
/**
* 设置 版本
* @param version
*/
public void setVersion(String version){
this.version = version;
}
@Override
public int hashCode() {
return this.getId().hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (obj instanceof AppPublishEntity) {
AppPublishEntity tmp = (AppPublishEntity) obj;
if (this.getId() == tmp.getId()) {
return true;
}
}
return false;
}
public String toString(){
StringBuilder sb = new StringBuilder("");
sb.append(",appCode:").append(getAppCode());
sb.append(",appName:").append(getAppName());
sb.append(",filePath:").append(getFilePath());
sb.append(",distributeFilePath:").append(getDistributeFilePath());
sb.append(",appType:").append(getAppType());
sb.append(",distribute:").append(getDistribute());
sb.append(",version:").append(getVersion());
return sb.toString();
}
public void initAttrValue(){
this.appCode = null;
this.appName = null;
this.filePath = null;
this.distributeFilePath = null;
this.appType = null;
this.distribute = null;
this.version = null;
}
}
\ No newline at end of file
package com.mortals.xhx.module.app.model.vo;
import com.mortals.framework.model.BaseEntityLong;
import com.mortals.xhx.module.app.model.AppPublishEntity;
import java.util.ArrayList;
import java.util.List;
/**
* 应用发布部署视图对象
*
* @author zxfei
* @date 2023-02-01
*/
public class AppPublishVo extends BaseEntityLong {
}
\ No newline at end of file
package com.mortals.xhx.module.app.service;
import com.mortals.framework.service.ICRUDService;
import com.mortals.xhx.module.app.model.AppPublishEntity;
/**
* AppPublishService
*
* 应用发布部署 service接口
*
* @author zxfei
* @date 2023-02-01
*/
public interface AppPublishService extends ICRUDService<AppPublishEntity,Long>{
}
\ No newline at end of file
package com.mortals.xhx.module.app.service.impl;
import cn.hutool.core.io.FileUtil;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
import com.mortals.xhx.base.system.upload.service.UploadService;
import com.mortals.xhx.module.app.dao.AppPublishDao;
import com.mortals.xhx.module.app.model.AppPublishEntity;
import com.mortals.xhx.module.app.service.AppPublishService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
/**
* AppPublishService
* 应用发布部署 service实现
*
* @author zxfei
* @date 2023-02-01
*/
@Service("appPublishService")
public class AppPublishServiceImpl extends AbstractCRUDServiceImpl<AppPublishDao, AppPublishEntity, Long> implements AppPublishService {
@Autowired
private UploadService uploadService;
@Override
protected void saveBefore(AppPublishEntity entity, Context context) throws AppException {
String targetPath="/home/mortals/apps/";
String fileNewName=entity.getAppCode()+"-"+entity.getVersion();
//将zip包移动到指定目录 并更改名称
String realFilePath = uploadService.getFilePath(entity.getFilePath());
if (FileUtil.isEmpty(new File(realFilePath))) {
throw new AppException("部署文件不存在!");
}
if (!FileUtil.getSuffix(entity.getFilePath()).equals("zip")) {
throw new AppException("部署只支持zip文件!");
}
//移动文件并重命名
FileUtil.move(new File(realFilePath),new File(targetPath+fileNewName),true);
super.saveBefore(entity, context);
}
}
\ No newline at end of file
package com.mortals.xhx.module.app.web;
import com.mortals.framework.model.Context;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.param.service.ParamService;
import com.mortals.xhx.common.code.AppTypeEnum;
import com.mortals.xhx.common.code.DistributeEnum;
import com.mortals.xhx.module.app.model.AppPublishEntity;
import com.mortals.xhx.module.app.service.AppPublishService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* 应用发布部署
*
* @author zxfei
* @date 2023-02-01
*/
@RestController
@RequestMapping("app/publish")
public class AppPublishController extends BaseCRUDJsonBodyMappingController<AppPublishService, AppPublishEntity, Long> {
@Autowired
private ParamService paramService;
public AppPublishController() {
super.setModuleDesc("应用发布部署");
}
@Override
protected void init(Map<String, Object> model, Context context) {
this.addDict(model, "appType", AppTypeEnum.getEnumMap());
this.addDict(model, "distribute", DistributeEnum.getEnumMap());
this.addDict(model, "appPublish", paramService.getParamByFirstOrganize("appPublish"));
super.init(model, context);
}
}
\ No newline at end of file
......@@ -63,7 +63,6 @@ public class DeviceModuleDistributeServiceImpl extends AbstractCRUDServiceImpl<D
@Override
public void active(DeviceModuleDistributeEntity distributeEntity, Context context) {
//判断文件是否存在
String targetFilePath = uploadService.getFilePath(distributeEntity.getFilePath());
if (FileUtil.isEmpty(new File(targetFilePath))) {
throw new AppException("部署文件不存在!");
......@@ -73,6 +72,7 @@ public class DeviceModuleDistributeServiceImpl extends AbstractCRUDServiceImpl<D
throw new AppException("部署只支持zip文件!");
}
//RuntimeUtil
//部署路径是否存在 如果不存在 创建目录,
String path = GlobalSysInfo.getParamValue(Constant.DISTRIBUTE_PATH, "/home/publish/device-manager-ui/homeDeviceUrl");
String code = distributeEntity.getProductCode();
......
package com.mortals.xhx.module.product.service.impl;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.impl.AbstractCRUDServiceImpl;
......@@ -94,7 +92,7 @@ public class ProductVersionServiceImpl extends AbstractCRUDServiceImpl<ProductVe
header.put(MessageHeader.MESSAGETYPE, MESSAGETYPE_UPGREAD);
header.put(MessageHeader.DEVICECODE, deviceEntity.getDeviceCode());
header.put(MessageHeader.TIMESTAMP, DateUtils.getCurrStrDateTime());
TbQueueMsg queueMsg = new DefaultTbQueueMsg(IdUtil.fastUUID(), Base64.encode( new JSONObject().toJSONString()), header);
TbQueueMsg queueMsg = new DefaultTbQueueMsg(IdUtil.fastUUID(), "W10=", header);
messageProducer.sendMsg(QueueKey.DEFAULT_EXCHANGE, Constant.DOWN_TOPIC + deviceEntity.getDeviceCode(), JSON.toJSONString(queueMsg));
DeviceLogEntity deviceLogEntity = new DeviceLogEntity();
......@@ -105,7 +103,7 @@ public class ProductVersionServiceImpl extends AbstractCRUDServiceImpl<ProductVe
deviceLogEntity.setDeviceName(deviceEntity.getDeviceName());
deviceLogEntity.setDeviceCode(deviceEntity.getDeviceCode());
deviceLogEntity.setMessageHead(MESSAGETYPE_UPGREAD);
deviceLogEntity.setContent("==");
deviceLogEntity.setContent("W10=");
deviceLogEntity.setLogType(LogTypeEnum.下发服务.getValue());
deviceLogEntity.setCreateUserId(1L);
deviceLogEntity.setCreateTime(new Date());
......
###登录
POST {{baseUrl}}/login/login
Content-Type: application/json
{
"loginName":"admin",
"password":"admin",
"securityCode":"8888"
}
> {%
client.global.set("SmsSet_id", JSON.parse(response.body).data.id);
client.global.set("authToken", JSON.parse(response.body).data.token);
%}
###应用发布部署列表
POST {{baseUrl}}/app/publish/list
Authorization: {{authToken}}
Content-Type: application/json
{
"appCode":"fvvux8",
"appName":"ky08yt",
"filePath":"zarhfo",
"distributeFilePath":"g3uxc3",
"appType":603,
"distribute":205,
"version":"4ziigy",
"page":1,
"size":10
}
###应用发布部署更新与保存
POST {{baseUrl}}/app/publish/save
Authorization: {{authToken}}
Content-Type: application/json
{
"appCode":"fz9bky",
"appName":"8hrivq",
"filePath":"szqb1k",
"distributeFilePath":"40rn79",
"appType":297,
"distribute":171,
"version":"20jc15",
}
> {%
client.global.set("AppPublish_id", JSON.parse(response.body).data.id);
%}
###应用发布部署查看
GET {{baseUrl}}/app/publish/info?id={{AppPublish_id}}
Authorization: {{authToken}}
Accept: application/json
###应用发布部署编辑
GET {{baseUrl}}/app/publish/edit?id={{AppPublish_id}}
Authorization: {{authToken}}
Accept: application/json
###应用发布部署删除
GET {{baseUrl}}/app/publish/delete?id={{AppPublish_id}}
Authorization: {{authToken}}
Accept: application/json
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment