网关服务代码合并

This commit is contained in:
yin fuxian 2024-04-22 17:46:24 +08:00
parent 040fa00415
commit 25eab4017c
60 changed files with 7712 additions and 1159 deletions

View File

@ -1,11 +1,12 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
VUE_APP_TITLE = SAC管理系统
# 开发环境配置
ENV = 'development'
# 若依管理系统/开发环境
# SAC管理系统/开发环境
VUE_APP_BASE_API = '/dev-api'
# SAC管理系统/开发环境上传
VUE_APP_BASE_API_ = '/'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true

View File

@ -1,8 +1,8 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
VUE_APP_TITLE = SAC管理系统
# 生产环境配置
ENV = 'production'
# 若依管理系统/生产环境
# SAC管理系统/生产环境
VUE_APP_BASE_API = '/prod-api'

View File

@ -1,10 +1,10 @@
# 页面标题
VUE_APP_TITLE = 若依管理系统
VUE_APP_TITLE = SAC管理系统
NODE_ENV = production
# 测试环境配置
ENV = 'staging'
# 若依管理系统/测试环境
# SAC管理系统/测试环境
VUE_APP_BASE_API = '/stage-api'

2
sf-ui/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/node_modules
/dist

View File

@ -1,8 +1,8 @@
{
"name": "ruoyi",
"version": "3.8.6",
"description": "若依管理系统",
"author": "若依",
"description": "SAC管理系统",
"author": "SAC",
"license": "MIT",
"scripts": {
"dev": "vue-cli-service serve",

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询安装包管理(新)列表
export function listINFO(query) {
return request({
url: '/deploy/INFO/list',
method: 'get',
params: query
})
}
// 查询安装包管理(新)详细
export function getINFO(id) {
return request({
url: '/deploy/INFO/' + id,
method: 'get'
})
}
// 新增安装包管理(新)
export function addINFO(data) {
return request({
url: '/deploy/INFO',
method: 'post',
data: data
})
}
// 修改安装包管理(新)
export function updateINFO(data) {
return request({
url: '/deploy/INFO',
method: 'put',
data: data
})
}
// 删除安装包管理(新)
export function delINFO(id) {
return request({
url: '/deploy/INFO/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,13 @@
import request from '@/utils/request'
export function Document11691998078000list(query) {
return request({
url: '/forms/api/router/get/Document11691998078000list',
method: 'get',
params: query
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询安装包管理(新)列表
export function listINFO(query) {
return request({
url: '/deploy/INFO/list',
method: 'get',
params: query
})
}
// 查询安装包管理(新)详细
export function getINFO(id) {
return request({
url: '/deploy/INFO/' + id,
method: 'get'
})
}
// 新增安装包管理(新)
export function addINFO(data) {
return request({
url: '/deploy/INFO',
method: 'post',
data: data
})
}
// 修改安装包管理(新)
export function updateINFO(data) {
return request({
url: '/deploy/INFO',
method: 'put',
data: data
})
}
// 删除安装包管理(新)
export function delINFO(id) {
return request({
url: '/deploy/INFO/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询接口管理列表
export function listInterface(query) {
return request({
url: '/gateway/interface/list',
method: 'get',
params: query
})
}
// 查询接口管理详细
export function getInterface(id) {
return request({
url: '/gateway/interface/' + id,
method: 'get'
})
}
// 新增接口管理
export function addInterface(data) {
return request({
url: '/gateway/interface',
method: 'post',
data: data
})
}
// 修改接口管理
export function updateInterface(data) {
return request({
url: '/gateway/interface',
method: 'put',
data: data
})
}
// 删除接口管理
export function delInterface(id) {
return request({
url: '/gateway/interface/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询路由管理列表
export function listRoute(query) {
return request({
url: '/gateway/route/list',
method: 'get',
params: query
})
}
// 查询路由管理详细
export function getRoute(id) {
return request({
url: '/gateway/route/' + id,
method: 'get'
})
}
// 新增路由管理
export function addRoute(data) {
return request({
url: '/gateway/route',
method: 'post',
data: data
})
}
// 修改路由管理
export function updateRoute(data) {
return request({
url: '/gateway/route',
method: 'put',
data: data
})
}
// 删除路由管理
export function delRoute(id) {
return request({
url: '/gateway/route/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询服务管理列表
export function listServer(query) {
return request({
url: '/gateway/server/list',
method: 'get',
params: query
})
}
// 查询服务管理详细
export function getServer(id) {
return request({
url: '/gateway/server/' + id,
method: 'get'
})
}
// 新增服务管理
export function addServer(data) {
return request({
url: '/gateway/server',
method: 'post',
data: data
})
}
// 修改服务管理
export function updateServer(data) {
return request({
url: '/gateway/server',
method: 'put',
data: data
})
}
// 删除服务管理
export function delServer(id) {
return request({
url: '/gateway/server/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询策略管理列表
export function listStrategy(query) {
return request({
url: '/gateway/strategy/list',
method: 'get',
params: query
})
}
// 查询策略管理详细
export function getStrategy(id) {
return request({
url: '/gateway/strategy/' + id,
method: 'get'
})
}
// 新增策略管理
export function addStrategy(data) {
return request({
url: '/gateway/strategy',
method: 'post',
data: data
})
}
// 修改策略管理
export function updateStrategy(data) {
return request({
url: '/gateway/strategy',
method: 'put',
data: data
})
}
// 删除策略管理
export function delStrategy(id) {
return request({
url: '/gateway/strategy/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询应用列列表
export function listList(query) {
return request({
url: '/index/list/list',
method: 'get',
params: query
})
}
// 查询应用列详细
export function getList(id) {
return request({
url: '/index/list/' + id,
method: 'get'
})
}
// 新增应用列
export function addList(data) {
return request({
url: '/index/list',
method: 'post',
data: data
})
}
// 修改应用列
export function updateList(data) {
return request({
url: '/index/list',
method: 'put',
data: data
})
}
// 删除应用列
export function delList(id) {
return request({
url: '/index/list/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询商品信息列表
export function listGoods(query) {
return request({
url: '/service/goods/list',
method: 'get',
params: query
})
}
// 查询商品信息详细
export function getGoods(id) {
return request({
url: '/service/goods/' + id,
method: 'get'
})
}
// 新增商品信息
export function addGoods(data) {
return request({
url: '/service/goods',
method: 'post',
data: data
})
}
// 修改商品信息
export function updateGoods(data) {
return request({
url: '/service/goods',
method: 'put',
data: data
})
}
// 删除商品信息
export function delGoods(id) {
return request({
url: '/service/goods/' + id,
method: 'delete'
})
}

View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询应用列列表
export function getListApi(query) {
return request({
url: '/index/list/list',
method: 'get',
params: query
})
}
// 查询应用列详细
export function getListDetail(id) {
return request({
url: '/index/list/' + id,
method: 'get'
})
}
// 新增应用列
export function addList(data) {
return request({
url: '/index/list',
method: 'post',
data: data
})
}
// 修改应用列
export function updateList(data) {
return request({
url: '/index/list',
method: 'put',
data: data
})
}
// 删除应用列
export function delList(id) {
return request({
url: '/index/list/' + id,
method: 'delete'
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

View File

@ -1,38 +1,38 @@
<template>
<div class="upload-file">
<el-upload
multiple
:action="uploadFileUrl"
ref="fileUpload"
:action="baseUrl+uploadFileUrl"
:before-upload="handleBeforeUpload"
:file-list="fileList"
:headers="headers"
:limit="limit"
:on-error="handleUploadError"
:on-exceed="handleExceed"
:on-success="handleUploadSuccess"
:show-file-list="false"
:headers="headers"
class="upload-file-uploader"
ref="fileUpload"
multiple
>
<!-- 上传按钮 -->
<el-button size="mini" type="primary">选取文件</el-button>
<!-- 上传提示 -->
<div class="el-upload__tip" slot="tip" v-if="showTip">
<div v-if="showTip" slot="tip" class="el-upload__tip">
请上传
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b></template>
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b></template>
的文件
</div>
</el-upload>
<!-- 文件列表 -->
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
<li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
<li v-for="(file, index) in fileList" :key="file.url" class="el-upload-list__item ele-upload-list__item-content">
<el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
</el-link>
<div class="ele-upload-list__item-content-action">
<el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
<el-link :underline="false" type="danger" @click="handleDelete(index)">删除</el-link>
</div>
</li>
</transition-group>
@ -40,32 +40,36 @@
</template>
<script>
import { getToken } from "@/utils/auth";
import { getToken } from '@/utils/auth'
export default {
name: "FileUpload",
name: 'FileUpload',
props: {
//
value: [String, Object, Array],
//
limit: {
type: Number,
default: 5,
default: 5
},
// (MB)
fileSize: {
type: Number,
default: 5,
default: 5
},
// , ['png', 'jpg', 'jpeg']
fileType: {
type: Array,
default: () => ["doc", "xls", "ppt", "txt", "pdf"],
default: () => ['doc', 'xls', 'ppt', 'txt', 'pdf', 'apk']
},
//
isShowTip: {
type: Boolean,
default: true
},
uploadFileUrl: {
type: String,
default: () => '/system/oss/zip/upload'
}
},
data() {
@ -73,31 +77,31 @@ export default {
number: 0,
uploadList: [],
baseUrl: process.env.VUE_APP_BASE_API,
uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", //
// uploadFileUrl: process.env.VUE_APP_BASE_API + '/common/upload', //
headers: {
Authorization: "Bearer " + getToken(),
Authorization: 'Bearer ' + getToken()
},
fileList: [],
};
fileList: []
}
},
watch: {
value: {
handler(val) {
if (val) {
let temp = 1;
let temp = 1
//
const list = Array.isArray(val) ? val : this.value.split(',');
const list = Array.isArray(val) ? val : this.value.split(',')
//
this.fileList = list.map(item => {
if (typeof item === "string") {
item = { name: item, url: item };
if (typeof item === 'string') {
item = { name: item, url: item }
}
item.uid = item.uid || new Date().getTime() + temp++;
return item;
});
item.uid = item.uid || new Date().getTime() + temp++
return item
})
} else {
this.fileList = [];
return [];
this.fileList = []
return []
}
},
deep: true,
@ -107,108 +111,113 @@ export default {
computed: {
//
showTip() {
return this.isShowTip && (this.fileType || this.fileSize);
},
return this.isShowTip && (this.fileType || this.fileSize)
}
},
methods: {
//
handleBeforeUpload(file) {
//
if (this.fileType) {
const fileName = file.name.split('.');
const fileExt = fileName[fileName.length - 1];
const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
const fileName = file.name.split('.')
const fileExt = fileName[fileName.length - 1]
const isTypeOk = this.fileType.indexOf(fileExt) >= 0
if (!isTypeOk) {
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
return false;
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join('/')}格式文件!`)
return false
}
}
//
if (this.fileSize) {
const isLt = file.size / 1024 / 1024 < this.fileSize;
const isLt = file.size / 1024 / 1024 < this.fileSize
if (!isLt) {
this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
return false;
this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`)
return false
}
}
this.$modal.loading("正在上传文件,请稍候...");
this.number++;
return true;
this.$modal.loading('正在上传文件,请稍候...')
this.number++
return true
},
//
handleExceed() {
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`)
},
//
handleUploadError(err) {
this.$modal.msgError("上传文件失败,请重试");
this.$modal.msgError('上传文件失败,请重试')
this.$modal.closeLoading()
},
//
handleUploadSuccess(res, file) {
if (res.code === 200) {
this.uploadList.push({ name: res.fileName, url: res.fileName });
this.uploadedSuccessfully();
this.uploadList.push({ name: res.data.url, url: res.data.url, size: res.data.size })
this.uploadedSuccessfully()
} else {
this.number--;
this.$modal.closeLoading();
this.$modal.msgError(res.msg);
this.$refs.fileUpload.handleRemove(file);
this.uploadedSuccessfully();
this.number--
this.$modal.closeLoading()
this.$modal.msgError(res.msg)
this.$refs.fileUpload.handleRemove(file)
this.uploadedSuccessfully()
}
},
//
handleDelete(index) {
this.fileList.splice(index, 1);
this.$emit("input", this.listToString(this.fileList));
this.fileList.splice(index, 1)
this.$emit('input', this.listToString(this.fileList))
},
//
uploadedSuccessfully() {
if (this.number > 0 && this.uploadList.length === this.number) {
this.fileList = this.fileList.concat(this.uploadList);
this.uploadList = [];
this.number = 0;
this.$emit("input", this.listToString(this.fileList));
this.$modal.closeLoading();
this.fileList = this.fileList.concat(this.uploadList)
this.uploadList = []
this.number = 0
this.$emit('input', this.listToString(this.fileList))
this.$emit('getSize', this.fileList)
this.$modal.closeLoading()
}
},
//
getFileName(name) {
if (name.lastIndexOf("/") > -1) {
return name.slice(name.lastIndexOf("/") + 1);
if (name.lastIndexOf('/') > -1) {
return name.slice(name.lastIndexOf('/') + 1)
} else {
return "";
return ''
}
},
//
listToString(list, separator) {
let strs = "";
separator = separator || ",";
let strs = ''
separator = separator || ','
for (let i in list) {
strs += list[i].url + separator;
strs += list[i].url
}
return strs != '' ? strs.substr(0, strs.length - 1) : '';
return strs != '' ? strs : ''
}
}
};
}
</script>
<style scoped lang="scss">
<style lang="scss" scoped>
.upload-file-uploader {
margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {
border: 1px solid #e4e7ed;
line-height: 2;
margin-bottom: 10px;
position: relative;
}
.upload-file-list .ele-upload-list__item-content {
display: flex;
justify-content: space-between;
align-items: center;
color: inherit;
}
.ele-upload-list__item-content-action .el-link {
margin-right: 10px;
}

View File

@ -1,38 +1,39 @@
<template>
<div class="component-upload-image">
<el-upload
multiple
:action="uploadImgUrl"
list-type="picture-card"
:on-success="handleUploadSuccess"
ref="imageUpload"
:action="baseUrl+uploadImgUrl"
:before-upload="handleBeforeUpload"
:class="{hide: this.fileList.length >= this.limit}"
:file-list="fileList"
:headers="headers"
:limit="limit"
:list-type="listType"
:on-error="handleUploadError"
:on-exceed="handleExceed"
ref="imageUpload"
:on-remove="handleDelete"
:show-file-list="true"
:headers="headers"
:file-list="fileList"
:on-preview="handlePictureCardPreview"
:class="{hide: this.fileList.length >= this.limit}"
:on-remove="handleDelete"
:on-success="handleUploadSuccess"
:show-file-list="true"
multiple
>
<i class="el-icon-plus"></i>
<i v-if="listType=='picture-card'" class="el-icon-plus"></i>
<el-button v-else icon="el-icon-upload" size="small" type="primary">上传文件</el-button>
</el-upload>
<!-- 上传提示 -->
<div class="el-upload__tip" slot="tip" v-if="showTip">
<div v-if="showTip" slot="tip" class="el-upload__tip">
请上传
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b></template>
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b></template>
的文件
</div>
<el-dialog
:visible.sync="dialogVisible"
append-to-body
title="预览"
width="800"
append-to-body
>
<img
:src="dialogImageUrl"
@ -43,7 +44,7 @@
</template>
<script>
import { getToken } from "@/utils/auth";
import { getToken } from '@/utils/auth'
export default {
props: {
@ -51,59 +52,67 @@ export default {
//
limit: {
type: Number,
default: 5,
default: 5
},
// (MB)
fileSize: {
type: Number,
default: 5,
type: Number,
default: 5
},
// , ['png', 'jpg', 'jpeg']
fileType: {
type: Array,
default: () => ["png", "jpg", "jpeg"],
default: () => ['png', 'jpg', 'jpeg']
},
listType: {
type: String,
default: 'picture-card'
},
//
isShowTip: {
type: Boolean,
default: true
},
uploadFileUrl: {
type: String,
default: () => '/system/oss/zip/upload'
}
},
data() {
return {
number: 0,
uploadList: [],
dialogImageUrl: "",
dialogImageUrl: '',
dialogVisible: false,
hideUpload: false,
baseUrl: process.env.VUE_APP_BASE_API,
uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", //
// uploadImgUrl: process.env.VUE_APP_BASE_API + '/common/upload', //
headers: {
Authorization: "Bearer " + getToken(),
Authorization: 'Bearer ' + getToken()
},
fileList: []
};
}
},
watch: {
value: {
handler(val) {
if (val) {
//
const list = Array.isArray(val) ? val : this.value.split(',');
const list = Array.isArray(val) ? val : this.value.split(',')
//
this.fileList = list.map(item => {
if (typeof item === "string") {
if (typeof item === 'string') {
if (item.indexOf(this.baseUrl) === -1) {
item = { name: this.baseUrl + item, url: this.baseUrl + item };
item = { name: this.baseUrl + item, url: this.baseUrl + item }
} else {
item = { name: item, url: item };
item = { name: item, url: item }
}
}
return item;
});
return item
})
} else {
this.fileList = [];
return [];
this.fileList = []
return []
}
},
deep: true,
@ -113,114 +122,116 @@ export default {
computed: {
//
showTip() {
return this.isShowTip && (this.fileType || this.fileSize);
},
return this.isShowTip && (this.fileType || this.fileSize)
}
},
methods: {
// loading
handleBeforeUpload(file) {
let isImg = false;
let isImg = false
if (this.fileType.length) {
let fileExtension = "";
if (file.name.lastIndexOf(".") > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
let fileExtension = ''
if (file.name.lastIndexOf('.') > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
}
isImg = this.fileType.some(type => {
if (file.type.indexOf(type) > -1) return true;
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
return false;
});
if (file.type.indexOf(type) > -1) return true
if (fileExtension && fileExtension.indexOf(type) > -1) return true
return false
})
} else {
isImg = file.type.indexOf("image") > -1;
isImg = file.type.indexOf('image') > -1
}
if (!isImg) {
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);
return false;
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join('/')}图片格式文件!`)
return false
}
if (this.fileSize) {
const isLt = file.size / 1024 / 1024 < this.fileSize;
const isLt = file.size / 1024 / 1024 < this.fileSize
if (!isLt) {
this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
return false;
this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`)
return false
}
}
this.$modal.loading("正在上传图片,请稍候...");
this.number++;
this.$modal.loading('正在上传图片,请稍候...')
this.number++
},
//
handleExceed() {
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`)
},
//
handleUploadSuccess(res, file) {
if (res.code === 200) {
this.uploadList.push({ name: res.fileName, url: res.fileName });
this.uploadedSuccessfully();
this.uploadList.push({ name: res.data.url, url: res.data.url, size: res.fileSize })
this.uploadedSuccessfully()
} else {
this.number--;
this.$modal.closeLoading();
this.$modal.msgError(res.msg);
this.$refs.imageUpload.handleRemove(file);
this.uploadedSuccessfully();
this.number--
this.$modal.closeLoading()
this.$modal.msgError(res.msg)
this.$refs.imageUpload.handleRemove(file)
this.uploadedSuccessfully()
}
},
//
handleDelete(file) {
const findex = this.fileList.map(f => f.name).indexOf(file.name);
if(findex > -1) {
this.fileList.splice(findex, 1);
this.$emit("input", this.listToString(this.fileList));
const findex = this.fileList.map(f => f.name).indexOf(file.name)
if (findex > -1) {
this.fileList.splice(findex, 1)
this.$emit('input', this.listToString(this.fileList))
}
},
//
handleUploadError() {
this.$modal.msgError("上传图片失败,请重试");
this.$modal.closeLoading();
this.$modal.msgError('上传图片失败,请重试')
this.$modal.closeLoading()
},
//
uploadedSuccessfully() {
if (this.number > 0 && this.uploadList.length === this.number) {
this.fileList = this.fileList.concat(this.uploadList);
this.uploadList = [];
this.number = 0;
this.$emit("input", this.listToString(this.fileList));
this.$modal.closeLoading();
this.fileList = this.fileList.concat(this.uploadList)
console.log(this.fileList)
this.uploadList = []
this.number = 0
this.$emit('input', this.listToString(this.fileList))
this.$modal.closeLoading()
}
},
//
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
this.dialogImageUrl = file.url
this.dialogVisible = true
},
//
listToString(list, separator) {
let strs = "";
separator = separator || ",";
let strs = ''
separator = separator || ','
for (let i in list) {
if (list[i].url) {
strs += list[i].url.replace(this.baseUrl, "") + separator;
strs += list[i].url.replace(this.baseUrl, '') + separator
}
}
return strs != '' ? strs.substr(0, strs.length - 1) : '';
return strs != '' ? strs : ''
}
}
};
}
</script>
<style scoped lang="scss">
<style lang="scss" scoped>
// .el-upload--picture-card
::v-deep.hide .el-upload--picture-card {
display: none;
display: none;
}
//
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {
transition: all 0s;
transition: all 0s;
}
::v-deep .el-list-enter, .el-list-leave-active {
opacity: 0;
transform: translateY(0);
opacity: 0;
transform: translateY(0);
}
</style>

View File

@ -111,7 +111,7 @@ export default {
value: val
})
if (!val) {
this.$store.dispatch('app/toggleSideBarHide', false);
// this.$store.dispatch('app/toggleSideBarHide', false);
this.$store.commit("SET_SIDEBAR_ROUTERS", this.$store.state.permission.defaultRoutes);
}
}

View File

@ -5,10 +5,12 @@ import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
import { isRelogin } from '@/utils/request'
import { getApplicationId } from './utils/application'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register']
const needApplicationList = ['/build/installationList', '/build/whiteListManagement', '/build/publish']
router.beforeEach((to, from, next) => {
NProgress.start()
@ -24,11 +26,17 @@ router.beforeEach((to, from, next) => {
// 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(() => {
isRelogin.show = false
store.dispatch('GenerateRoutes').then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
if (to.path === '/index') {
next();
} else if (checkApplication(to.path)) {
next({ path: '/' })
} else {
store.dispatch('GenerateRoutes').then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
}
}).catch(err => {
store.dispatch('LogOut').then(() => {
Message.error(err)
@ -36,7 +44,12 @@ router.beforeEach((to, from, next) => {
})
})
} else {
next()
if (checkApplication(to.path)) {
next({ path: '/' })
NProgress.done()
} else {
next()
}
}
}
} else {
@ -51,6 +64,10 @@ router.beforeEach((to, from, next) => {
}
})
function checkApplication(path) {
return needApplicationList.includes(path) && !getApplicationId();
}
router.afterEach(() => {
NProgress.done()
})

View File

@ -1,11 +1,10 @@
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
Vue.use(Router)
/**
* Note: 路由配置项
*
@ -68,7 +67,7 @@ export const constantRoutes = [
children: [
{
path: 'index',
component: () => import('@/views/index'),
component: () => import('@/views/indexNew'),
name: 'Index',
meta: { title: '首页', icon: 'dashboard', affix: true }
}
@ -87,7 +86,23 @@ export const constantRoutes = [
meta: { title: '个人中心', icon: 'user' }
}
]
}
},
// 本地测试-----------
{
path: '/gateway',
component: Layout,
hidden: true,
redirect: 'service-config',
children: [
{
path: 'service-config',
component: () => import('@/views/gateway/serviceManage/config'),
name: 'ServiceConfigAdd',
meta: { title: '新增服务配置', breadcrumb: false, }
}
]
},
// 本地测试-----------
]
// 动态路由,基于用户权限动态去加载
@ -161,12 +176,146 @@ export const dynamicRoutes = [
meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
}
]
},
{
path: '/build/install',
component: Layout,
hidden: true,
permissions: ['build:install:add'],
children: [
{
path: 'add',
component: () => import('@/views/FDS/installationList/add'),
name: 'InstallAdd',
meta: { title: '新增安装包', activeMenu: '/build/installationList' }
}
]
},
{
path: '/build/install',
component: Layout,
hidden: true,
permissions: ['build:install:edit'],
children: [
{
path: 'edit',
component: () => import('@/views/FDS/installationList/edit'),
name: 'InstallEdit',
meta: { title: '编辑安装包', activeMenu: '/build/installationList' }
}
]
},
{
path: '/build/install',
component: Layout,
hidden: true,
permissions: ['build:install:detail'],
children: [
{
path: 'detail',
component: () => import('@/views/FDS/installationList/detail'),
name: 'InstallDetail',
meta: { title: '安装包详情', activeMenu: '/build/installationList' }
}
]
},
{
path: '/build/publishList',
component: Layout,
hidden: true,
permissions: ['build:publishList:add'],
children: [
{
path: 'add',
component: () => import('@/views/FDS/publishList/add'),
name: 'PublishAdd',
meta: { title: '新增发布', activeMenu: '/build/publish' }
}
]
},
{
path: '/build/publishList',
component: Layout,
hidden: true,
permissions: ['build:publishList:detail'],
children: [
{
path: 'detail',
component: () => import('@/views/FDS/publishList/detail'),
name: 'PublishDetail',
meta: { title: '发布详情', activeMenu: '/build/publish' }
}
]
},
{
path: '/build/whiteList',
component: Layout,
hidden: true,
permissions: ['build:whiteListManagement:add'],
children: [
{
path: 'add',
component: () => import('@/views/FDS/whiteListManagement/add'),
name: 'WhiteListManagementAdd',
meta: { title: '新增白名单', activeMenu: '/build/whiteListManagement' }
}
]
},
{
path: '/build/whiteList',
component: Layout,
hidden: true,
permissions: ['build:whiteListManagement:detail'],
children: [
{
path: 'detail',
component: () => import('@/views/FDS/whiteListManagement/detail'),
name: 'WhiteListManagementDetail',
meta: { title: '白名单详情', activeMenu: '/build/whiteListManagement' }
}
]
},
{
path: '/build/whiteList',
component: Layout,
hidden: true,
permissions: ['build:whiteListManagement:equepDetail'],
children: [
{
path: 'equepDetail',
component: () => import('@/views/FDS/whiteListManagement/equepDetail'),
name: 'WhiteListManagementEquepDetail',
meta: { title: '白名单设备详情', activeMenu: '/build/whiteListManagement' }
}
]
},
{
path: '/build/whiteList',
component: Layout,
hidden: true,
permissions: ['build:whiteListManagement:addConfig'],
children: [
{
path: 'addConfig',
component: () => import('@/views/FDS/whiteListManagement/addConfig'),
name: 'WhiteListManagementConfigAdd',
meta: { title: '新增白名单配置', activeMenu: '/build/whiteListManagement' }
}
]
}
]
// 防止连续点击多次路由报错
let routerPush = Router.prototype.push;
let routerReplace = Router.prototype.replace;
let routerPush = Router.prototype.push
let routerReplace = Router.prototype.replace
// push
Router.prototype.push = function push(location) {
return routerPush.call(this, location).catch(err => err)

View File

@ -11,6 +11,7 @@ const getters = {
introduction: state => state.user.introduction,
roles: state => state.user.roles,
permissions: state => state.user.permissions,
applicationId: state => state.user.applicationId,
permission_routes: state => state.permission.routes,
topbarRouters:state => state.permission.topbarRouters,
defaultRoutes:state => state.permission.defaultRoutes,

View File

@ -126,7 +126,8 @@ export const loadView = (view) => {
return (resolve) => require([`@/views/${view}`], resolve)
} else {
// 使用 import 实现生产环境的路由懒加载
return () => import(`@/views/${view}`)
//return () => require([`@/views/${view}`], resolve)
return (resolve) => require([`@/views/${view}`], resolve)
}
}

View File

@ -1,5 +1,6 @@
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { getApplicationId, setApplicationId, removeApplicationId } from '@/utils/application'
const user = {
state: {
@ -7,7 +8,9 @@ const user = {
name: '',
avatar: '',
roles: [],
permissions: []
permissions: [],
applicationId: getApplicationId(),
applicationInfo: {}, // 用户选中的项目/应用
},
mutations: {
@ -25,7 +28,12 @@ const user = {
},
SET_PERMISSIONS: (state, permissions) => {
state.permissions = permissions
}
},
SET_APPLICATION: (state, applicationInfo) => {
const { id } = applicationInfo;
state.applicationId = id || '';
state.applicationInfo = applicationInfo;
},
},
actions: {
@ -74,6 +82,8 @@ const user = {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_PERMISSIONS', [])
commit('SET_APPLICATION', {})
removeApplicationId()
removeToken()
resolve()
}).catch(error => {
@ -86,9 +96,22 @@ const user = {
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
commit('SET_APPLICATION', {})
removeApplicationId()
removeToken()
resolve()
})
},
// 设置选中的项目应用信息
SetApplication({ commit }, applicationInfo) {
commit('SET_APPLICATION', applicationInfo)
const { appCode } = applicationInfo || {};
if (appCode) {
setApplicationId(applicationInfo.appCode);
} else {
removeApplicationId();
}
}
}
}

View File

@ -0,0 +1,30 @@
import Cookies from "js-cookie";
const ApplicationKey = "Admin-Application-Id";
/**
* 获取应用项目ID
* 该函数从Cookie中检索与应用项目相关的关键信息
* @returns {string} 返回从Cookie中获取的应用项目ID
*/
export function getApplicationId() {
return Cookies.get(ApplicationKey);
}
/**
* 设置应用项目ID到Cookie中
* @param {string} ApplicationId - 需要设置的应用项目ID
* @return {boolean|Object} 返回Cookie设置的结果成功则返回true失败则返回设置失败的对象
*/
export function setApplicationId(ApplicationId) {
return Cookies.set(ApplicationKey, ApplicationId);
}
/**
* 移除应用ID的Cookie
* 本函数用于删除与应用相关的ID Cookie
* @returns {boolean} 返回删除操作的结果如果删除成功则返回true如果删除失败则返回false
*/
export function removeApplicationId() {
return Cookies.remove(ApplicationKey);
}

View File

@ -2,6 +2,7 @@ import axios from 'axios'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import { getApplicationId } from '@/utils/application'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi";
import cache from '@/plugins/cache'
@ -29,6 +30,9 @@ service.interceptors.request.use(config => {
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
if (getApplicationId()) {
config.headers['appCode'] = getApplicationId()
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?' + tansParams(config.params);

View File

@ -0,0 +1,120 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>新增渠道</div>
<el-divider/>
</el-header>
<el-main>
<el-form ref="elForm" :model="formData" :rules="rules" label-width="100px" size="medium">
<el-form-item label="APP" prop="field101">
<el-input v-model="formData.field101" :style="{width: '100%'}" clearable placeholder="请输入APP">
</el-input>
</el-form-item>
<el-form-item label="版本号" prop="field102">
<el-select v-model="formData.field102" :style="{width: '100%'}" clearable placeholder="请选择版本号">
<el-option v-for="(item, index) in field102Options" :key="index" :disabled="item.disabled"
:label="item.label" :value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="下载市场" prop="field103">
<el-radio-group v-model="formData.field103" size="medium">
<el-radio v-for="(item, index) in field103Options" :key="index" :disabled="item.disabled"
:label="item.value"
>{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item size="large">
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</el-main>
</el-container>
</div>
</template>
<script>
export default {
components: {},
props: [],
data() {
return {
formData: {
field101: undefined,
field102: undefined,
field103: undefined
},
rules: {
field101: [{
required: true,
message: '请输入APP',
trigger: 'blur'
}],
field102: [{
required: true,
message: '请选择版本号',
trigger: 'change'
}],
field103: [{
required: true,
message: '下载市场不能为空',
trigger: 'change'
}]
},
field102Options: [{
'label': '选项一',
'value': 1
}, {
'label': '选项二',
'value': 2
}],
field103Options: [{
'label': '应用市场',
'value': 1
}, {
'label': '阿里云',
'value': 2
}]
}
},
computed: {},
watch: {},
created() {
},
mounted() {
},
methods: {
submitForm() {
this.$refs['elForm'].validate(valid => {
if (!valid) return
// TODO
})
},
resetForm() {
this.$refs['elForm'].resetFields()
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.el-upload__tip {
line-height: 1.2;
}
</style>

View File

@ -0,0 +1,207 @@
<template>
<div class="app-container">
<el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="90px" size="small">
<el-form-item label="选择APP" prop="sysApkName">
<el-input
v-model="queryParams.sysApkName"
clearable
placeholder="请输入APP"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="版本号" prop="version">
<el-input
v-model="queryParams.version"
clearable
placeholder="请输入版本号"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:add']"
icon="el-icon-plus"
plain
size="mini"
type="primary"
@click="handleAdd"
>新建
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:delete']"
:disabled="multiple"
icon="el-icon-plus"
plain
size="mini"
type="info"
@click="handleDelete"
>批量删除
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="INFOList" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"/>
<el-table-column align="center" label="APP" prop="APP"/>
<el-table-column align="center" label="最新版本号" prop="version"/>
<el-table-column align="center" label="文件类型" prop="sysApk"/>
<el-table-column align="center" label="公开时间" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="请求次数" prop="sysApk"/>
<el-table-column align="center" label="注册时间" prop="sysApk"/>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作" width="250">
<template slot-scope="scope">
<el-button
v-hasPermi="['system:config:dowmload']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleDown(scope.row)"
>下架
</el-button>
<el-button
v-hasPermi="['system:config:edit']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleEdit(scope.row)"
>编辑
</el-button>
<el-button
v-hasPermi="['system:config:delete']"
icon="el-icon-delete"
size="mini"
type="text"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:limit.sync="queryParams.pageSize"
:page.sync="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
</div>
</template>
<script>
// import { listINFO, getINFO, delINFO, addINFO, updateINFO } from "@/api/deploy/INFO";
export default {
name: 'ChannelManagement',
dicts: ['sys_yes_no'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
INFOList: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
sysApkName: null,
version: null
},
//
form: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询安装包管理(新)列表 */
getList() {
this.loading = false
// listINFO(this.queryParams).then(response => {
// this.INFOList = response.rows
// this.total = response.total
// this.loading = false
// })
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.create_time = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.$router.push({
path: 'install/add',
params: {
type: 'add',
activeTabs: this.activeTabs
}
})
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 删除按钮操作 */
handleDelete(row) {
const configIds = row.id || this.ids
this.$modal.confirm('是否确认删除编号为"' + configIds + '"的数据项?').then(function() {
return delConfig(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {
})
},
/** 修改按钮操作 */
handleEdit(row) {
this.reset()
const configId = row.id || this.ids
getConfig(configId).then(response => {
this.$router.push({
path: 'install/add',
params: {
type: 'edit',
activeTabs: this.activeTabs
}
})
})
},
/** 下架操作 **/
handleDown() {
}
}
}
</script>

View File

@ -0,0 +1,120 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>新增渠道</div>
<el-divider/>
</el-header>
<el-main>
<el-form ref="elForm" :model="formData" :rules="rules" label-width="100px" size="medium">
<el-form-item label="手机品牌" prop="field101">
<el-input v-model="formData.field101" :style="{width: '100%'}" clearable placeholder="请输入手机品牌">
</el-input>
</el-form-item>
<el-form-item label="版本号" prop="field102">
<el-select v-model="formData.field102" :style="{width: '100%'}" clearable placeholder="请选择版本号">
<el-option v-for="(item, index) in field102Options" :key="index" :disabled="item.disabled"
:label="item.label" :value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="下载市场" prop="field103">
<el-radio-group v-model="formData.field103" size="medium">
<el-radio v-for="(item, index) in field103Options" :key="index" :disabled="item.disabled"
:label="item.value"
>{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item size="large">
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</el-main>
</el-container>
</div>
</template>
<script>
export default {
components: {},
props: [],
data() {
return {
formData: {
field101: undefined,
field102: undefined,
field103: undefined
},
rules: {
field101: [{
required: true,
message: '请输入手机品牌',
trigger: 'blur'
}],
field102: [{
required: true,
message: '请选择版本号',
trigger: 'change'
}],
field103: [{
required: true,
message: '下载市场不能为空',
trigger: 'change'
}]
},
field102Options: [{
'label': '选项一',
'value': 1
}, {
'label': '选项二',
'value': 2
}],
field103Options: [{
'label': '应用市场',
'value': 1
}, {
'label': '阿里云',
'value': 2
}]
}
},
computed: {},
watch: {},
created() {
},
mounted() {
},
methods: {
submitForm() {
this.$refs['elForm'].validate(valid => {
if (!valid) return
// TODO
})
},
resetForm() {
this.$refs['elForm'].resetFields()
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.el-upload__tip {
line-height: 1.2;
}
</style>

View File

@ -0,0 +1,210 @@
<template>
<div class="app-container">
<el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="90px" size="small">
<el-form-item label="手机品牌" prop="sysApkName">
<el-input
v-model="queryParams.sysApkName"
clearable
placeholder="请输入手机品牌"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="版本号" prop="version">
<el-input
v-model="queryParams.version"
clearable
placeholder="请输入版本号"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:add']"
icon="el-icon-plus"
plain
size="mini"
type="primary"
@click="handleAdd"
>新建
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:delete']"
:disabled="multiple"
icon="el-icon-plus"
plain
size="mini"
type="info"
@click="handleDelete"
>批量删除
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="INFOList" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"/>
<el-table-column align="center" label="手机品牌" prop="sysApkName"/>
<el-table-column align="center" label="版本号" prop="version"/>
<el-table-column align="center" label="下载市场" prop="sysApk"/>
<el-table-column align="center" label="发布时间" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="状态" prop="uploading_status">
<template slot-scope="scopeA">
<dict-tag :options="dict.type.uploading_status" :value="scopeA.row.uploadingStatus"/>
</template>
</el-table-column>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作" width="250">
<template slot-scope="scope">
<el-button
v-hasPermi="['system:config:dowmload']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleDown(scope.row)"
>下架
</el-button>
<el-button
v-hasPermi="['system:config:edit']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleEdit(scope.row)"
>编辑
</el-button>
<el-button
v-hasPermi="['system:config:delete']"
icon="el-icon-delete"
size="mini"
type="text"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:limit.sync="queryParams.pageSize"
:page.sync="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
</div>
</template>
<script>
// import { listINFO, getINFO, delINFO, addINFO, updateINFO } from "@/api/deploy/INFO";
export default {
name: 'ChannelManagement',
dicts: ['sys_yes_no', 'uploading_status'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
INFOList: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
sysApkName: null,
version: null
},
//
form: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询安装包管理(新)列表 */
getList() {
this.loading = false
// listINFO(this.queryParams).then(response => {
// this.INFOList = response.rows
// this.total = response.total
// this.loading = false
// })
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.create_time = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.$router.push({
path: 'install/add',
params: {
type: 'add',
activeTabs: this.activeTabs
}
})
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 删除按钮操作 */
handleDelete(row) {
const configIds = row.id || this.ids
this.$modal.confirm('是否确认删除编号为"' + configIds + '"的数据项?').then(function() {
return delConfig(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {
})
},
/** 修改按钮操作 */
handleEdit(row) {
this.reset()
const configId = row.id || this.ids
getConfig(configId).then(response => {
this.$router.push({
path: 'install/add',
params: {
type: 'edit',
activeTabs: this.activeTabs
}
})
})
},
/** 下架操作 **/
handleDown() {
}
}
}
</script>

View File

@ -0,0 +1,439 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>安装包发布任务</div>
<el-divider/>
</el-header>
<el-main>
<div class="form-main">
<el-form ref="formAdd" v-loading="$store.state.app.isLoading" :label-width="'120px'" :model="list"
:rules="rules"
>
<el-form-item label="发布版本">
<span>{{ list.version }} ({{ list.platformName }})</span>
</el-form-item>
<el-form-item label="发布类型" prop="grayFlag">
<el-radio v-model="list.grayFlag" label="0">灰度</el-radio>
<el-radio v-model="list.grayFlag" label="1">正式</el-radio>
</el-form-item>
<el-form-item label="升级模式" prop="upgradeMode">
<el-radio v-model="list.upgradeMode" label="0">非强制升级</el-radio>
<el-radio v-model="list.upgradeMode" label="1">强制升级</el-radio>
</el-form-item>
<el-form-item label="升级描述" prop="upgradeDesp">
<el-input v-model="list.upgradeDesp" class="remark-input" maxlength="50" placeholder="请输入升级描述"
show-word-limit
type="textarea"
/>
</el-form-item>
<template v-if="list.grayFlag =='0'">
<el-form-item label="发布条件" prop="releaseDestType">
<el-radio v-model="list.releaseDestType" label="0">白名单</el-radio>
<el-radio v-model="list.releaseDestType" label="1">时间窗</el-radio>
</el-form-item>
<el-form-item v-if="list.releaseDestType =='0'" label="白名单" prop="whiteListId">
<template>
<el-cascader v-model="list.whiteListId" :options="whiteOptions" :show-all-levels="false" clearable/>
</template>
</el-form-item>
<el-form-item v-if="list.releaseDestType =='1'" label="结束日期" prop="expiryTime">
<template>
<div class="block">
<el-date-picker
v-model="list.expiryTime"
placeholder="选择日期时间"
type="datetime"
value-format="yyyy-MM-dd HH:mm:ss"
/>
</div>
</template>
</el-form-item>
<el-form-item v-if="list.releaseDestType =='1'" label="灰度人数">
<el-radio v-model="list.numType" label="0">无限制</el-radio>
<el-radio v-model="list.numType" label="1">限制</el-radio>
<el-input-number v-model="list.grayUserNum" :disabled="list.numType == '0'" :max="1000000000"
:min="1" controls-position="right" placeholder="请输入灰度人数"
/>
</el-form-item>
<el-form-item label="备注" prop="desp">
<el-input v-model="list.desp" class="remark-input" maxlength="50" placeholder="请输入备注"
show-word-limit
type="textarea"
/>
</el-form-item>
<el-form-item :prop="list.rule.regularRule? 'releaseRuleId': 'headerOperations'" label="高级规则">
<template>
<el-row>
<el-col :span="5">
<el-checkbox v-model="list.rule.regularRule">常用规则</el-checkbox>
</el-col>
<el-col :span="12">
<el-select v-model="list.releaseRuleId" :disabled="!list.rule.regularRule" filterable>
<el-option
v-for="item in releaseOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-col>
</el-row>
<el-row class="form-row">
<el-col :span="5">
<el-checkbox v-model="list.rule.customRule">自定义</el-checkbox>
</el-col>
</el-row>
<el-row v-if="list.rule.customRule" class="form-row">
<el-table
:data="list.headerOperations"
border
class="custom-table"
size="mini"
>
<el-table-column align="center" label="类型">
<template slot-scope="scope">
<el-select v-model="scope.row.type" :disabled="disabledCode" placeholder="请选择"
@change="value=>{dictionaryTypeChange(scope.$index,scope.row.type)}"
>
<el-option
v-for="item in typeList"
:key="item.code"
:label="item.name"
:value="item.code"
/>
</el-select>
</template>
</el-table-column>
<el-table-column align="center" label="条件">
<template slot-scope="scope">
<el-select v-model="scope.row.operType" :disabled="disabledCode" placeholder="请选择">
<el-option label="包含" value="1"/>
<el-option label="不包含" value="0"/>
</el-select>
</template>
</el-table-column>
<el-table-column align="center" label="发布条件">
<template slot-scope="scope">
<el-select v-model="scope.row.value" :disabled="disabledCode" placeholder="请选择">
<el-option v-for="item in scope.row.dictionaryList" :key="item.value" :label="item.value"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column align="center" border label="操作" width="80">
<template slot-scope="scope">
<el-button :disabled="disabledCode" round size="mini" type="danger"
@click="deleteHeaderOption(scope.$index)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<div v-if="!disabledCode" class="addRow" @click="addHeaderOption()">
<i class="el-icon-circle-plus-outline"/>
<a class="color-3B77FF">新增一行</a>
</div>
</el-row>
</template>
</el-form-item>
</template>
<template v-if="list.grayFlag =='1'">
<el-form-item label="备注" prop="desp">
<el-input v-model="list.desp" class="remark-input" maxlength="50" placeholder="请输入备注"
show-word-limit
type="textarea"
/>
</el-form-item>
</template>
<el-form-item>
<el-button type="primary" @click="addNew()">新增发布任务</el-button>
</el-form-item>
</el-form>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
// import { getDictionaryList, getInstallTaskAdd, getReleaseRuleList, getTypeList, getWhiteList } from '@/api/FDS'
export default {
name: 'InstallationPackTask',
components: {},
data() {
var checkHeader = (rule, value, callback) => {
if (this.list.rule.customRule) {
value.forEach(ele => {
for (const key in ele) {
if (Object.hasOwnProperty.call(ele, key)) {
const item = ele[key]
if (!item && key !== 'desp') {
return callback(new Error('请输入自定义规则必填项'))
}
}
}
})
}
callback()
}
var checkRadix = (rule, value, callback) => {
if (this.list.rule.regularRule && !value) {
return callback(new Error('请选择常用规则'))
}
callback()
}
return {
selectValue: 'code',
checkList: ['Android'],
disabledCode: false,
list: {
rule: {
regularRule: false,
customRule: false
},
// headerOperations: [],
packId: '', // ID
grayFlag: '0', // : 0 1
upgradeMode: '0', //
releaseDestType: '0', // 0 1
headerOperations: [//
// {
// 'scope': '', // region platform
// 'inclued': '', // 1 2
// 'condition': '', //
// 'desp': ''//
// }
],
grayUserNum: '', //
numType: '0',
expiryTime: '', //
desp: '',
releaseRuleId: '', //
// deviceListId: '', //
whiteListId: ''// id
},
whiteOptions: [],
releaseOptions: [],
fileList: [],
typeList: [],
rules: {
headerOperations: [
{ validator: checkHeader, trigger: 'blur' }
],
releaseRuleId: [
{ validator: checkRadix, trigger: 'blur' }
],
grayFlag: [
{ required: true }
],
upgradeMode: [
{ required: true }
],
upgradeDesp: [
{ required: true, message: '请输入升级描述', trigger: 'change' }
],
releaseDestType: [
{ required: true }
],
whiteListId: [
{ required: true, message: '请选择白名单', trigger: 'change' }
],
expiryTime: [
{ required: true, message: '请选择发布时间', trigger: 'blur' }
],
grayUserNum: [
{ required: true, message: '请输入灰度人数', trigger: 'blur' }
]
}
}
},
computed: {},
watch: {
'list.rule.regularRule'(newR, oldR) { //
if (this.list.rule.customRule && newR) {
this.list.rule.regularRule = true
this.list.rule.customRule = false
}
this.list.releaseRuleId = newR ? this.list.releaseRuleId : ''
},
'list.rule.customRule'(newC, oldC) {
if (this.list.rule.regularRule && newC) {
this.list.rule.customRule = true
this.list.rule.regularRule = false
}
if (newC && this.list.headerOperations.length < 1) {
this.addHeaderOption()
}
}
},
beforeMount() {
this.whiteOptions = [{
value: 'user',
label: '用户',
children: []
},
{
value: 'device',
label: '设备',
children: []
}]
getTypeList({
'beginPage': '1',
'pageSize': '999'
}).then(res => {
this.typeList = res.context.list
this.typeList.forEach(res => {
res.platform = this.list.platformName
})
console.log(275, this.typeList)
})
getWhiteList({ type: 0 }).then(res => {
if (res.code === '00') {
const list = res.context.list
list.forEach(i => {
this.whiteOptions[0].children.push({
value: i.id,
label: i.name
})
})
}
})
getWhiteList({ type: 1 }).then(res => {
if (res.code === '00') {
const list = res.context.list
list.forEach(i => {
this.whiteOptions[1].children.push({
value: i.id,
label: i.name
})
})
}
})
getReleaseRuleList({}).then(res => {
if (res.code === '00') {
const list = res.context.list
list.forEach(i => {
this.releaseOptions.push({
value: i.id,
label: i.name
})
console.log(this.releaseOptions)
})
}
})
},
mounted() {
if (this.$route.query.data) {
const params = JSON.parse(this.$route.query.data)
this.list.packId = params.id
this.list.version = params.version
this.list.platformName = params.platform === '0' ? 'Android' : 'IOS'
}
},
methods: {
addHeaderOption() {
this.list.headerOperations.push({
'type': '',
'operType': '',
'value': '',
'dictionaryList': []
// 'desp': ''
})
},
deleteHeaderOption(index) {
this.list.headerOperations.splice(index, 1)
},
dictionaryTypeChange(index, value) {
const params = { type: value }
if (value !== 'city') {
params.notPlatform = this.list.platformName === '0' ? 'IOS' : 'Android'
}
getDictionaryList(params).then(res => {
if (res.code === '00') {
this.list.headerOperations[index].dictionaryList = res.context.list
}
})
},
addNew() {
console.log(this.list)
const params = {}
params.grayFlag = this.list.grayFlag
params.pattern = this.list.upgradeMode
params.patternHint = this.list.upgradeDesp
params.desp = this.list.desp
params.packId = this.list.packId
if (this.list.grayFlag === '0') {
params.deployType = this.list.releaseDestType
params.desp = this.list.desp
if (this.list.rule.regularRule) {
params.releaseRuleId = this.list.releaseRuleId
}
if (this.list.rule.customRule) {
params.releaseRuleItemList = this.list.headerOperations
}
if (this.list.releaseDestType === '0') { //
params.whiteListId = this.list.whiteListId[this.list.whiteListId.length - 1]
}
if (this.list.releaseDestType === '1') { //
if (this.list.numType === '1') {
params.grayUserNum = this.list.grayUserNum
}
params.expiryTime = this.list.expiryTime
}
}
this.$refs.formAdd.validate((valid) => {
if (valid) {
getInstallTaskAdd(params).then(res => {
if (res.code === '00') {
this.$message({
message: '新增发布任务成功!',
type: 'success'
})
this.$router.go(-1)
}
})
} else {
return false
}
})
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
.form-row {
margin-top: 20px;
}
.el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.custom-table {
font-size: 12px;
}
.addRow {
width: 100px;
}
.remark-input {
width: 400px;
}
</style>

View File

@ -0,0 +1,152 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>新增安装包</div>
<el-divider/>
</el-header>
<el-main>
<div class="form-main">
<el-form ref="elForm" :model="formData" :rules="rules" label-width="100px" size="medium">
<el-form-item label="上传方式" prop="uploadingType">
<el-radio-group v-model="formData.uploadingType" size="medium">
<el-radio v-for="(item, index) in dict.type.sys_apk_uploading_type" :key="index"
:disabled="item.disabled"
:label="item.value"
>{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="activeTabs==='1'" label="安装包名称" prop="sysApkName">
<el-input v-model="formData.sysApkName" :style="{width: '100%'}" clearable placeholder="请输入安装包名称">
</el-input>
</el-form-item>
<!-- <el-form-item v-else label="模块包名称" prop="field107">-->
<!-- <el-input v-model="formData.field107" :style="{width: '100%'}" clearable placeholder="请输入模块包名称">-->
<!-- </el-input>-->
<!-- </el-form-item>-->
<el-form-item label="版本号" prop="version">
<el-input v-model="formData.version" :style="{width: '100%'}" clearable placeholder="请输入版本号">
</el-input>
</el-form-item>
<el-form-item label="安装包文件" prop="sysApk">
<file-upload v-model="formData.sysApk" :fileType="['apk','txt']" :limit="1"
@getSize="getSize"
/>
</el-form-item>
<el-form-item label="安装包大小" prop="sysApkSize">
<el-input v-model="formData.sysApkSize" :style="{width: '100%'}" placeholder="请输入安装包大小" readonly>
</el-input>
</el-form-item>
<el-form-item label="安装包类型" prop="sysType">
<el-radio-group v-model="formData.sysType" size="medium">
<el-radio v-for="(item, index) in dict.type.sys_apk_type" :key="index" :disabled="item.disabled"
:label="item.value"
>{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<!-- <el-form-item v-if="activeTabs!='1'" label="适用模块" prop="configName">-->
<!-- <el-select v-model="formData.field108" clearable placeholder="请选择对应的模块">-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.sys_yes_no"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item size="large">
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="cancel"> </el-button>
</el-form-item>
</el-form>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import { addINFO } from '@/api/FDS/installList'
export default {
name: 'InstallAdd',
dicts: ['sys_apk_uploading_type', 'uploading_status', 'sys_apk_type'],
data() {
return {
formData: {
uploadingType: 'OffLineUploading',
sysApkName: undefined,
version: undefined,
sysApk: null,
sysApkSize: undefined,
sysType: ''
},
rules: {
uploadingType: [
{ required: true, message: '上传类型不能为空', trigger: 'change' }
],
sysApkName: [
{ required: true, message: '安装包名称不能为空', trigger: 'blur' }
],
version: [
{ required: true, message: '版本号不能为空', trigger: 'blur' }
],
sysType: [
{ required: true, message: '安装包类型不能为空', trigger: 'change' }
],
sysApkSize: [
{ required: true, message: '安装包大小不能为空', trigger: 'blur' }
],
sysApk: [
{ required: true, message: '安装包不能为空', trigger: 'change' }
]
},
activeTabs: '1'
}
},
computed: {},
methods: {
/** 提交按钮 */
submitForm() {
this.$refs['elForm'].validate(valid => {
if (valid) {
addINFO(this.formData).then(response => {
this.$modal.msgSuccess('新增成功')
})
this.$router.push({ path: '/build/installationList' })
}
})
},
getSize(e) {
this.formData.sysApkSize = e[0].size + 'kb'
},
cancel() {
this.$router.push({ path: '/build/installationList' })
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.el-upload__tip {
line-height: 1.2;
}
</style>

View File

@ -0,0 +1,103 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>安装包详情</div>
<el-divider/>
</el-header>
<el-main>
<div class="form-main">
<el-form ref="form" :model="form" label-width="150px" size="mini">
<el-row>
<el-col :span="24">
<el-form-item label="上传方式:">
<dict-tag :options="dict.type.sys_apk_uploading_type" :value="form.uploadingType"/>
</el-form-item>
<el-form-item
label="安装包名称:"
>{{ form.sysApkName }}
</el-form-item>
<el-form-item label="安装包文件名称:">{{ form.sysApk }}</el-form-item>
<el-form-item label="安装包大小:">{{ form.sysApkSize }}</el-form-item>
<el-form-item label="适用系统:">
<dict-tag :options="dict.type.sys_apk_type" :value="form.sysType"/>
</el-form-item>
<el-form-item v-if="activeTabs!='1'" label="适用模块:">登录模块</el-form-item>
<el-form-item label="上传时间:">{{ form.createTime }}</el-form-item>
<el-form-item label="上传状态:">
<dict-tag :options="dict.type.uploading_status" :value="form.uploadingStatus"/>
</el-form-item>
<el-form-item label="上传人员:">{{ form.created }}</el-form-item>
<el-form-item label="上传日志:">日志日志</el-form-item>
<el-form-item size="large">
<el-button @click="cancel"> </el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import { getINFO } from '@/api/FDS/installList'
export default {
name: 'InstallDetail',
dicts: ['sys_apk_uploading_type', 'uploading_status', 'sys_apk_type'],
data() {
return {
form: {},
activeTabs: '1',
id: ''
}
},
created() {
this.getInfo()
},
methods: {
/** 查询安装包管理详情 */
getInfo() {
getINFO(this.$route.query.id).then(response => {
this.form = response.data
})
},
cancel() {
this.$router.push({ path: '/build/installationList' })
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.tag-group {
.el-tag {
cursor: pointer;
}
}
.el-tag + .el-tag {
margin-left: 10px
}
</style>

View File

@ -0,0 +1,173 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>编辑安装包</div>
<el-divider/>
</el-header>
<el-main>
<div class="form-main">
<el-form ref="elForm" :model="formData" :rules="rules" label-width="100px" size="medium">
<el-form-item label="上传方式" prop="uploadingType">
<el-radio-group v-model="formData.uploadingType" size="medium">
<el-radio v-for="(item, index) in dict.type.sys_apk_uploading_type" :key="index"
:disabled="item.disabled"
:label="item.value"
>{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="activeTabs==='1'" label="安装包名称" prop="sysApkName">
<el-input v-model="formData.sysApkName" :style="{width: '100%'}" clearable placeholder="请输入安装包名称">
</el-input>
</el-form-item>
<!-- <el-form-item v-else label="模块包名称" prop="field107">-->
<!-- <el-input v-model="formData.field107" :style="{width: '100%'}" clearable placeholder="请输入模块包名称">-->
<!-- </el-input>-->
<!-- </el-form-item>-->
<el-form-item label="版本号" prop="version">
<el-input v-model="formData.version" :style="{width: '100%'}" clearable placeholder="请输入版本号">
</el-input>
</el-form-item>
<el-form-item label="安装包文件" prop="sysApk">
<file-upload v-model="formData.sysApk" :fileType="['apk','txt']" :limit="1"
@getSize="getSize"
/>
</el-form-item>
<el-form-item label="安装包大小" prop="sysApkSize">
<el-input v-model="formData.sysApkSize" :style="{width: '100%'}" placeholder="请输入安装包大小" readonly>
</el-input>
</el-form-item>
<el-form-item label="安装包类型" prop="sysType">
<el-radio-group v-model="formData.sysType" size="medium">
<el-radio v-for="(item, index) in dict.type.sys_apk_type" :key="index" :disabled="item.disabled"
:label="item.value"
>{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<!-- <el-form-item v-if="activeTabs!='1'" label="适用模块" prop="configName">-->
<!-- <el-select v-model="formData.field108" clearable placeholder="请选择对应的模块">-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.sys_yes_no"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item size="large">
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="cancel"> </el-button>
</el-form-item>
</el-form>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import { getINFO, updateINFO } from '@/api/FDS/installList'
export default {
name: 'InstallAdd',
dicts: ['sys_apk_uploading_type', 'uploading_status', 'sys_apk_type'],
data() {
return {
formData: {
uploadingType: undefined,
sysApkName: undefined,
version: undefined,
sysApk: null,
sysApkSize: undefined,
sysType: ''
},
rules: {
uploadingType: [
{ required: true, message: '上传类型不能为空', trigger: 'change' }
],
sysApkName: [
{ required: true, message: '安装包名称不能为空', trigger: 'blur' }
],
version: [
{ required: true, message: '版本号不能为空', trigger: 'blur' }
],
sysType: [
{ required: true, message: '安装包类型不能为空', trigger: 'change' }
],
sysApkSize: [
{ required: true, message: '安装包大小不能为空', trigger: 'blur' }
],
sysApk: [
{ required: true, message: '安装包不能为空', trigger: 'change' }
]
}
}
},
computed: {},
watch: {
$route(to, from) {
if (to) {
this.getInfo()
console.log(to)
}
}
},
created() {
this.activeTabs = this.$route.query.activeTabs
this.getInfo()
},
mounted() {
},
methods: {
/** 提交按钮 */
submitForm() {
this.$refs['elForm'].validate(valid => {
if (valid) {
updateINFO(this.formData).then(response => {
this.$modal.msgSuccess('修改成功')
})
this.$router.push({ path: '/build/installationList' })
}
})
},
/** 查询安装包管理详情 */
getInfo() {
getINFO(this.$route.query.id).then(response => {
this.formData = response.data
})
},
getSize(e) {
this.formData.sysApkSize = e[0].size + 'kb'
},
cancel() {
this.$router.push({ path: '/build/installationList' })
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.el-upload__tip {
line-height: 1.2;
}
</style>

View File

@ -0,0 +1,328 @@
<template>
<div class="app-container">
<el-tabs v-model="activeTabs" type="card" @tab-click="handleClickTabs">
<el-tab-pane
v-for="item in packTabs"
:key="item.name"
:label="item.title"
:name="item.name"
>
</el-tab-pane>
</el-tabs>
<el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="90px" size="small">
<el-form-item label="上传类型" prop="uploadingType">
<el-select v-model="queryParams.uploadingType" clearable placeholder="请选择上传类型">
<el-option
v-for="dict in dict.type.sys_apk_uploading_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="安装包名称" prop="sysApkName">
<el-input
v-model="queryParams.sysApkName"
clearable
placeholder="请输入安装包名称"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="版本号" prop="version">
<el-input
v-model="queryParams.version"
clearable
placeholder="请输入版本号"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="安装包类型" prop="sysType">
<el-select v-model="queryParams.sysType" clearable placeholder="请选择安装包类型">
<el-option
v-for="dict in dict.type.sys_apk_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="上传状态" prop="uploadingStatus">
<el-select v-model="queryParams.uploadingStatus" clearable placeholder="请选择上传状态">
<el-option
v-for="dict in dict.type.uploading_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建人" prop="created">
<el-input
v-model="queryParams.created"
clearable
placeholder="请输入创建人"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:add']"
icon="el-icon-plus"
plain
size="mini"
type="primary"
@click="handleAdd"
>新建
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:delete']"
:disabled="multiple"
icon="el-icon-plus"
plain
size="mini"
type="info"
@click="handleDelete"
>批量删除
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="INFOList" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"/>
<template v-if="activeTabs=='1'">
<el-table-column align="center" label="上传类型" prop="uploadingType">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_apk_uploading_type" :value="scope.row.uploadingType"/>
</template>
</el-table-column>
<el-table-column align="center" label="安装包名称" prop="sysApkName"/>
<el-table-column align="center" label="版本号" prop="version"/>
<el-table-column align="center" label="安装包" prop="sysApk"/>
<el-table-column align="center" label="安装包大小" prop="sysApkSize"/>
<el-table-column align="center" label="安装包类型" prop="sysType">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_apk_type" :value="scope.row.sysType"/>
</template>
</el-table-column>
<el-table-column align="center" label="创建人" prop="created"/>
</template>
<template v-if="activeTabs=='2'">
<el-table-column align="center" label="安装包名称" prop="configId"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="版本号" prop="version"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="安装包大小" prop="sys_apk_size"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="上传方式" prop="uploading_type"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="创建人" prop="created"/>
<el-table-column align="center" label="创建时间" prop="create_time" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
</template>
<el-table-column align="center" label="状态" prop="uploading_status">
<template slot-scope="scopeA">
<dict-tag :options="dict.type.uploading_status" :value="scopeA.row.uploadingStatus"/>
</template>
</el-table-column>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作" width="250">
<template slot-scope="scope">
<el-button
v-hasPermi="['system:config:dowmload']"
icon="el-icon-download"
size="mini"
type="text"
@click="handleDownload(scope.row)"
>下载安装包
</el-button>
<el-button
v-hasPermi="['system:config:edit']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleEdit(scope.row)"
>编辑
</el-button>
<el-button
v-hasPermi="['system:config:detail']"
icon="el-icon-view"
size="mini"
type="text"
@click="handleDetail(scope.row)"
>详情
</el-button>
<el-button
v-hasPermi="['system:config:delete']"
icon="el-icon-delete"
size="mini"
type="text"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:limit.sync="queryParams.pageSize"
:page.sync="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
</div>
</template>
<script>
import { delINFO, listINFO } from '@/api/FDS/installList'
export default {
name: 'InstallationList',
dicts: ['sys_apk_uploading_type', 'uploading_status', 'sys_apk_type'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
INFOList: [],
packTabs: [{
name: '1',
title: 'APP安装包'
}, {
name: '2',
title: 'H5模块包'
}],
//
create_time: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
uploadingType: null,
sysApkName: null,
version: null,
sysType: null,
uploadingStatus: null,
created: null
},
//
form: {},
activeTabs: '1'
//
}
},
watch: {
$route(to, from) {
if (to) this.getList()
}
},
created() {
this.getList()
},
methods: {
/** 查询安装包管理(新)列表 */
getList() {
this.loading = false
listINFO(this.queryParams).then(response => {
this.INFOList = response.rows
this.total = response.total
this.loading = false
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.create_time = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
const query = {
activeTabs: this.activeTabs
}
this.$router.push({
path: '/build/install/add/',
query: query
})
// this.$tab.openPage('', '/build/install/add/', params)
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 删除按钮操作 */
handleDelete(row) {
const configIds = row.id || this.ids
this.$modal.confirm('是否确认删除编号为"' + configIds + '"的数据项?').then(function() {
return delINFO(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {
})
},
/** 修改按钮操作 */
handleEdit(row) {
const query = {
activeTabs: this.activeTabs,
id: row.id
}
this.$router.push({
path: '/build/install/edit/',
query: query
})
// this.$tab.openPage('', '/build/install/add/', params)
},
/** 查看详情弹窗 **/
handleDetail(row) {
const params = {
id: row.id
}
this.$tab.openPage('安装包详情', '/build/install/detail/', params)
},
/** 切换TAB触发的事件 */
handleClickTabs() {
this.getList()
},
/** 下载按钮 */
handleDownload(row) {
const configIds = row.id || this.ids
this.$modal.confirm('是否确认下载编号为"' + configIds + '"的数据项?').then(function() {
return delConfig(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('下载成功')
}).catch(() => {
})
}
}
}
</script>

View File

@ -0,0 +1,301 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>新增文件</div>
<el-divider/>
</el-header>
<el-main>
<div class="form-main">
<el-form ref="formAdd" v-loading="$store.state.app.isLoading" :label-width="'120px'" :model="list"
:rules="rules"
>
<el-form-item label="APP名称" prop="AppName">
<el-input v-model="list.AppName" placeholder="输入APP名称"/>
</el-form-item>
<el-form-item label="上传类型" prop="">
<el-input v-model="list.AppName" placeholder="请选择上传类型"/>
</el-form-item>
<el-form-item label="选择系统" prop="grayFlag">
<div class="tag-group">
<el-tag :type="list.platform=='android'?'':'info'" @click="list.platform='android'">安卓</el-tag>
<el-tag :type="list.platform=='IOS'?'':'info'" @click="list.platform='IOS'">IOS</el-tag>
<el-tag :type="list.platform=='HarmonyOS'?'':'info'" @click="list.platform='HarmonyOS'">鸿蒙</el-tag>
</div>
</el-form-item>
<el-form-item v-if="list.platform!=='IOS'" label="安装包" prop="upgradeMode">
<el-input v-model="list.packName" class="input-with-select" placeholder="请选择包" readonly>
<el-button slot="append" icon="el-icon-search" @click="handlePackOpen"></el-button>
</el-input>
</el-form-item>
<el-form-item v-else label="APP Store地址" prop="AppLink">
<el-input v-model="list.AppLink" placeholder="请输入APPStore地址"/>
</el-form-item>
<el-form-item label="版本号" prop="versionNumber">
<el-input v-model="list.versionNumber" class="remark-input" maxlength="500" placeholder="输入版本号"
show-word-limit
/>
</el-form-item>
<el-form-item label="版本说明">
<el-input v-model="list.imprint" class="remark-input" maxlength="500" placeholder="输入版本描述"
show-word-limit
type="textarea"
/>
</el-form-item>
<!-- 根据需求确认是否需要这些条件-->
<!-- <el-form-item label="发布环境" prop="releaseDestType">-->
<!-- <el-radio v-model="list.releaseDestType" label="0">开发环境</el-radio>-->
<!-- <el-radio v-model="list.releaseDestType" label="1">测试发布</el-radio>-->
<!-- <el-radio v-model="list.releaseDestType" label="2">生产发布</el-radio>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="发布策略" prop="releaseDestType">-->
<!-- <el-radio v-model="list.releaseDestType" label="0">灰度发布</el-radio>-->
<!-- <el-radio v-model="list.releaseDestType" label="1">全量发布</el-radio>-->
<!-- <el-radio v-model="list.releaseDestType" label="2">回滚发布</el-radio>-->
<!-- </el-form-item>-->
<el-form-item label="结果通知">
<el-switch
v-model="list.enableVerify"
/>
</el-form-item>
<el-form-item label="强制更新">
<el-switch
v-model="list.enableVerify"
/>
</el-form-item>
<el-form-item label="公开版">
<el-switch
v-model="list.enableVerify"
/>
</el-form-item>
<el-form-item label="下载验证">
<span slot="label">
下载验证
<el-tooltip class="item-tooltip"
content="当验证开关开启时为发布包生成下载二维码的同时也会生成一个6位验证码扫描二维码后需经过验证码才可下载发布."
effect="dark"
placement="right"
>
<i class="el-icon-question"/>
</el-tooltip>
</span>
<el-switch
v-model="list.downVerifi"
/>
</el-form-item>
<el-form-item label="更新客群">
<el-radio v-model="list.numType" label="0">白名单客户</el-radio>
<el-radio v-model="list.numType" label="1">普通客户</el-radio>
</el-form-item>
<el-form-item label="有效期">
<template>
<div class="block">
<el-date-picker
v-model="list.expiryTime"
end-placeholder="结束日期"
range-separator="-"
start-placeholder="开始日期"
style="width: 240px"
type="daterange"
value-format="yyyy-MM-dd"
></el-date-picker>
</div>
</template>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="list.desp" class="remark-input" maxlength="50" placeholder="请输入备注" show-word-limit
type="textarea"
/>
</el-form-item>
</el-form>
</div>
</el-main>
<!--安装包弹窗-->
<AddPack :visible.sync="packOpen" @close="closeAddPack"></AddPack>
</el-container>
</div>
</template>
<script>
import AddPack from '@/views/FDS/publishList/components/addPack.vue'
export default {
name: 'PublishAdd',
dicts: ['sys_yes_no'],
components: {
AddPack
},
data() {
// var checkHeader = (rule, value, callback) => {
// if (this.list.rule.customRule) {
// value.forEach(ele => {
// for (const key in ele) {
// if (Object.hasOwnProperty.call(ele, key)) {
// const item = ele[key]
// if (!item && key !== 'desp') {
// return callback(new Error(''))
// }
// }
// }
// })
// }
// callback()
// }
// var checkRadix = (rule, value, callback) => {
// if (this.list.rule.regularRule && !value) {
// return callback(new Error(''))
// }
// callback()
// }
return {
selectValue: 'code',
list: {
rule: {
regularRule: false,
customRule: false
},
// headerOperations: [],
packId: '', // ID
grayFlag: '0', // : 0 1
upgradeMode: '0', //
releaseDestType: '0', // 0 1
headerOperations: [//
// {
// 'scope': '', // region platform
// 'inclued': '', // 1 2
// 'condition': '', //
// 'desp': ''//
// }
],
grayUserNum: '', //
numType: '0',
expiryTime: '', //
desp: '',
releaseRuleId: '', //
// deviceListId: '', //
whiteListId: '',// id
enableVerify: false, //
imprint: '', //
versionNumber: '',
AppName: '', //APP
platform: 'android' //
},
//
showSearch: true,
//
total: 0,
packOpen: false,
//
loading: true,
dataList: [],
rules: {
grayFlag: [
{ required: true }
],
upgradeMode: [
{ required: true }
],
upgradeDesp: [
{ required: true, message: '请输入升级描述', trigger: 'change' }
],
releaseDestType: [
{ required: true }
],
whiteListId: [
{ required: true, message: '请选择白名单', trigger: 'change' }
],
expiryTime: [
{ required: true, message: '请选择发布时间', trigger: 'blur' }
],
grayUserNum: [
{ required: true, message: '请输入灰度人数', trigger: 'blur' }
]
}
}
},
computed: {},
// mounted() {
// if (this.$route.query.data) {
// const params = JSON.parse(this.$route.query.data)
// this.list.packId = params.id
// this.list.version = params.version
// this.list.platformName = params.platform === '0' ? 'Android' : 'IOS'
// }
// },
methods: {
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 在上传之前进行校验 */
beforeAvatarUpload(file) {
const formatList = file.name.split('.')
const isFormat = file.type === 'text/plain' || formatList[formatList.length - 1] === 'txt'
if (!isFormat) {
this.$message.error(`上传格式只能是名称后缀为.txt的文本文件!`)
}
const isLt2M = file.size / 1024 / 1024 < 5
if (!isLt2M) {
this.$message.error(`上传文件大小不能超过5M!`)
}
return isLt2M && isFormat
},
/** 上传文件 */
handleSuccess(file) {
this.fileList = []
const nameList = file.context.path.split('/')
this.fileList.push({
name: file.context.name || nameList[nameList.length - 1],
url: file.context.path
})
this.addFormData.path = file.context.path
},
beforeRemove(files, filesList) {
return this.$confirm(`确定要移除${files.name}`)
},
/** 弹出包选择框*/
handlePackOpen() {
this.packOpen = true
},
/** 关闭包选择框*/
closeAddPack() {
this.packOpen = false
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.tag-group {
.el-tag {
cursor: pointer;
}
}
.el-tag + .el-tag {
margin-left: 10px
}
</style>

View File

@ -0,0 +1,121 @@
<template>
<el-dialog :modal-append-to-body="false" :title="title" v-bind="$attrs" width="700px"
@close="onClose"
@open="onOpen"
v-on="$listeners"
>
<el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="90px"
size="small"
>
<el-form-item label="安装包名称" prop="installpackName">
<el-input
v-model="queryParams.installpackName"
clearable
placeholder="请输入安装包名称"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="dataList">
<el-table-column align="center" label="安装包名称" prop="configId"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="版本号" prop="configName"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="安装包大小" prop="configName"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="适用系统" prop="configValue"/>
<el-table-column align="center" label="状态" prop="configType">
<template slot-scope="scopeA">
<dict-tag :options="dict.type.sys_yes_no" :value="scopeA.row.type"/>
</template>
</el-table-column>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作" width="50">
<template slot-scope="scope">
<el-button circle icon="el-icon-plus" size="20" type="primary" @click="addPack"
></el-button>
</template>
</el-table-column>
</el-table>
<!-- <div slot="footer" class="dialog-footer">-->
<!-- <el-button type="primary" @click="submitAddForm()"> </el-button>-->
<!-- </div>-->
</el-dialog>
</template>
<script>
import { listConfig } from '@/api/system/config'
export default {
name: 'AddPack',
dicts: ['sys_yes_no'],
data() {
return {
//
title: '添加安装包',
loading: true,
configName: undefined,
form: {},
dataList: [],
//
showSearch: true,
total: 0,
//
queryParams: {
pageNum: 1,
pageSize: 10,
installpackName: undefined
}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listConfig(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.dataList = response.rows
this.total = response.total
this.loading = false
}
)
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
//
submitAddForm() {
},
/** 新增当前包的按钮 */
addPack() {
},
closeModal() {
this.$emit('close')
},
onOpen() {
this.active = this.current
this.key = ''
},
onClose() {
}
}
}
</script>

View File

@ -0,0 +1,144 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>发布详情</div>
<el-divider/>
</el-header>
<el-main>
<div class="form-main">
<el-form ref="form" :model="form" label-width="100px" size="mini">
<el-row>
<el-col :span="12">
<el-form-item label="APP名称"></el-form-item>
<el-form-item label="上传类型:">安装包11111</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所选系统:">安装包1111.excel</el-form-item>
<el-form-item label="安装包名称:">58.1kb</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="版本号:">安卓</el-form-item>
<el-form-item label="子版本号:">登录模块</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="版本说明:">说明说明</el-form-item>
<el-form-item label="发布环境:">发布环境</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="发布策略:">说明说明</el-form-item>
<el-form-item label="结果通知:">说明说明</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="强制更新:">说明说明</el-form-item>
<el-form-item label="公开版:">说明说明</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下载验证:">说明说明</el-form-item>
<el-form-item label="更新客群:">说明说明</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下载地址:">说明说明</el-form-item>
<el-form-item label="下载量:">说明说明</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="注册数:">说明说明</el-form-item>
<el-form-item label="最后刷新:">说明说明</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="发布时间:">说明说明</el-form-item>
<el-form-item label="创建人:">说明说明</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="发布状态:">说明说明</el-form-item>
<el-form-item label="发布日志:">说明说明</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="有效期:">说明说明</el-form-item>
<el-form-item label="备注:">说明说明</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
export default {
name: 'PublishDetail',
dicts: ['sys_yes_no'],
components: {},
data() {
return {
list: {
rule: {
regularRule: false,
customRule: false
},
// headerOperations: [],
packId: '', // ID
grayFlag: '0', // : 0 1
upgradeMode: '0', //
releaseDestType: '0', // 0 1
headerOperations: [//
// {
// 'scope': '', // region platform
// 'inclued': '', // 1 2
// 'condition': '', //
// 'desp': ''//
// }
],
grayUserNum: '', //
numType: '0',
expiryTime: '', //
desp: '',
releaseRuleId: '', //
// deviceListId: '', //
whiteListId: '',// id
enableVerify: false, //
imprint: '', //
versionNumber: '',
AppName: '', //APP
platform: 'android' //
},
//
//
packOpen: false,
//
loading: true,
dataList: [],
form: {}
}
},
methods: {}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 900px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.tag-group {
.el-tag {
cursor: pointer;
}
}
.el-tag + .el-tag {
margin-left: 10px
}
</style>

View File

@ -0,0 +1,366 @@
<template>
<div class="app-container">
<el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="90px" size="small">
<el-form-item label="选择APP" prop="configName">
<el-select v-model="queryParams.configType" clearable placeholder="请选择APP">
<el-option
v-for="dict in dict.type.sys_yes_no"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="版本号" prop="version">
<el-input
v-model="queryParams.version"
clearable
placeholder="请输入版本号"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="公开时间">
<el-date-picker
v-model="dateRange"
end-placeholder="结束日期"
range-separator="-"
start-placeholder="开始日期"
style="width: 240px"
type="daterange"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<el-form-item label="状态" prop="configType">
<el-select v-model="queryParams.configType" clearable placeholder="请选择状态">
<el-option
v-for="dict in dict.type.sys_yes_no"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:add']"
icon="el-icon-plus"
plain
size="mini"
type="primary"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
:disabled="multiple"
icon="el-icon-plus"
plain
size="mini"
type="info"
@click="handlePublish"
>批量发布
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:add']"
:disabled="multiple"
icon="el-icon-plus"
plain
size="mini"
type="info"
@click="handleDelete"
>批量删除
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"/>
<el-table-column align="center" label="APP" prop="configId"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="文件类型" prop="configName"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="版本号" prop="version"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="子版本号" prop="configValue"/>
<el-table-column
label="系统"
min-width="80"
prop="platform"
>
<template scope="scope">
<div>{{ scope.row.platform === '0' ? '安卓' : 'IOS' }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="公开版" prop="createTime" width="180">
<template slot-scope="scope">
<el-switch v-model="scope.row.tagsView" class="drawer-switch" disabled/>
</template>
</el-table-column>
<el-table-column align="center" label="强制更新" prop="createTime" width="180">
<template slot-scope="scope">
<el-switch v-model="scope.row.tagsView" class="drawer-switch" disabled/>
</template>
</el-table-column>
<el-table-column align="center" label="上传时间" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" align="center" label="发布环境" prop="configValue"/>
<el-table-column align="center" label="发布状态" prop="configType">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_yes_no" :value="scope.row.configType"/>
</template>
</el-table-column>
<el-table-column align="center" label="公开时间" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" align="center" label="更新说明" prop="remark"/>
<el-table-column
align="center"
label="二维码"
min-width="80"
>
<template slot-scope="scope">
<el-image
:preview-src-list="srcList"
:src="url"
style="width: 80px; height: 80px"
>
</el-image>
<!-- <el-popover-->
<!-- v-if="scope.row.qrCode && scopeC.row.status !== '20'"-->
<!-- ref="popver"-->
<!-- trigger="click"-->
<!-- width="200"-->
<!-- >-->
<!-- <div class="table-img">-->
<!-- <img :src="'data:image/jpg;base64,'+ scope.row.qrCode">-->
<!-- <p v-if="scopeC.row.verifyCode">密码:{{ scope.row.verifyCode }}</p>-->
<!-- </div>-->
<!-- </el-popover>-->
<!-- <div v-else>-</div>-->
</template>
</el-table-column>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作" width="150">
<template slot-scope="scope">
<el-button
v-hasPermi="['system:config:edit']"
icon="el-icon-bottom"
size="mini"
type="text"
@click="handleDown(scope.row)"
>下架
</el-button>
<el-button
v-hasPermi="['system:config:edit']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleEdit(scope.row)"
>修改
</el-button>
<el-dropdown size="mini"
@command="(command) => handleCommand(command, scope.row)"
>
<el-button icon="el-icon-d-arrow-right" size="mini" type="text">更多</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item v-hasPermi="['system:user:resetPwd']" command="handleDetail"
icon="el-icon-view"
>详情
</el-dropdown-item>
<el-dropdown-item v-hasPermi="['system:user:edit']" command="handleDownload"
icon="el-icon-download"
>下载安装包
</el-dropdown-item>
<el-dropdown-item v-hasPermi="['system:user:edit']" command="handleDelete"
icon="el-icon-delete"
>删除
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:limit.sync="queryParams.pageSize"
:page.sync="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
</div>
</template>
<script>
import { delConfig, listConfig } from '@/api/system/config'
export default {
name: 'PublishList',
dicts: ['sys_yes_no'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
configList: [],
//
title: '',
//
addOpen: false,
//
configOpen: false,
packOpen: false,
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
configName: undefined,
configKey: undefined,
configType: undefined
},
//
form: {},
url: require('@/assets/images/code.png'),
srcList: [
require('@/assets/images/code.png')
]
}
},
computed: {
applicationInfo: function() {
return this.$store.state.applicationInfo
}
},
created() {
this.getList()
},
mounted() {
console.log(this.$store.getters.applicationId)
console.log(this.applicationInfo)
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listConfig(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.configList = response.rows
this.total = response.total
this.loading = false
}
)
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
const params = {
type: 'add'
}
this.$tab.openPage('新增发布', '/build/publishList/add/', params)
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.configId)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 删除按钮操作 */
async handleDelete(row) {
const configIds = row.configId || this.ids
try {
await this.$modal.confirm('是否确认删除参数编号为"' + configIds + '"的数据项?')
await delConfig(configIds)
this.getList()
this.$modal.msgSuccess('删除成功')
} catch (error) {
console.error('删除失败', error)
//
}
},
/**查看详情*/
handleDetail() {
this.$tab.openPage('发布详情', '/build/publishList/detail/', '')
},
/**下载安装包*/
handleDownload() {
},
/**********编辑*******/
handleEdit() {
const params = {
type: 'edit'
}
this.$tab.openPage('编辑发布', '/build/publishList/add/', params)
},
/** 发布操作*/
handlePublish() {
},
//
handleCommand(command, row) {
switch (command) {
case 'handleDetail':
this.handleDetail(row)
break
case 'handleDownload':
this.handleDownload(row)
break
case 'handleDelete':
this.handleDelete(row)
break
default:
break
}
}
}
}
</script>

View File

@ -0,0 +1,142 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>新增白名单</div>
<el-divider/>
</el-header>
<el-main>
<div class="form-main">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-form-item label="白名单名称" prop="whiteListName">
<el-input v-model="form.whiteListName" placeholder="请输入白名单名称"/>
</el-form-item>
<el-form-item label="白名单类型" prop="whiteListType">
<el-select v-model="form.whiteListType" clearable placeholder="请选择白名单类型">
<el-option label="白名单人员" value="0"/>
<el-option label="白名单设备" value="1"/>
</el-select>
</el-form-item>
<el-form-item label="白名单模式" prop="whitePattern">
<el-select v-model="form.whitePattern" clearable placeholder="请选择白名单模式">
<el-option label="正则模式" value="0"/>
<el-option label="普通模式" value="1"/>
</el-select>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.remark" placeholder="请输入内容" type="textarea"/>
</el-form-item>
</el-form>
</div>
<div class="page-footer">
<el-button type="primary" @click="submitAddForm()"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import { addConfig } from '@/api/system/config'
export default {
name: 'WhiteAdd',
dicts: ['sys_yes_no'],
data() {
return {
form: {},
tokenId: '',
//
fileList: [],
rules: {
whiteListName: [
{ required: true, message: '白名单名称不能为空', trigger: 'blur' }
],
whiteListType: [
{ required: true, message: '白名单类型不能为空', trigger: 'change' }
],
whitePattern: [
{ required: true, message: '白名单模式不能为空', trigger: 'change' }
]
}
}
},
computed: {},
mounted() {
this.reset()
},
methods: {
reset() {
this.form = {
whiteListType: undefined,
whiteListName: undefined,
whitePattern: undefined,
remark: undefined
}
this.resetForm('form')
},
/** 新增按钮 */
submitAddForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
addConfig(this.form).then(response => {
this.$modal.msgSuccess('新增成功')
})
this.$router.push({ path: '/build/whiteListManagement' })
// if (this.form.configId != undefined) {
// updateConfig(this.form).then(response => {
// this.$modal.msgSuccess('')
// })
// } else {
// addConfig(this.form).then(response => {
// this.$modal.msgSuccess('')
// })
// }
}
})
},
cancel() {
this.$router.push({ path: '/build/whiteListManagement' })
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.tag-group {
.el-tag {
cursor: pointer;
}
}
.el-tag + .el-tag {
margin-left: 10px
}
.page-footer {
margin: 0 auto;
width: 700px;
justify-content: center;
display: flex;
}
</style>

View File

@ -0,0 +1,168 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>白名单配置</div>
<el-divider/>
</el-header>
<el-main>
<div class="form-main">
<el-form ref="configForm" :model="configForm" :rules="configRules" label-width="120px">
<el-form-item label="添加方式" prop="configName">
<el-radio-group v-model="configForm.addMode">
<el-radio
:label="1"
>手动添加
</el-radio>
<el-radio
:label="2"
>批量添加
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="白名单类型" prop="whiteListType">
<el-select v-model="configForm.whiteListType" clearable placeholder="请选择白名单类型">
<el-option label="白名单人员" value="0"/>
<el-option label="白名单设备" value="1"/>
</el-select>
</el-form-item>
<template v-if="configForm.addMode==1">
<el-form-item v-if="configForm.whiteListType==0" label="用户ID" prop="userId">
<el-input v-model="configForm.userId" placeholder="请输入用户ID" type="textarea"/>
</el-form-item>
<el-form-item v-if="configForm.whiteListType==1" label="白名单设备" prop="equepid">
<el-input v-model="configForm.equepid" placeholder="请输入设备信息" type="textarea"/>
</el-form-item>
</template>
<el-form-item v-else-if="configForm.addMode==2" label="白名单文件" prop="file">
<image-upload v-model="configForm.file" :fileType="['txt']" :limit="1"
:listType="'text'"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="configForm.remark" placeholder="请输入备注" type="textarea"/>
</el-form-item>
</el-form>
</div>
<div class="page-footer">
<el-button type="primary" @click="submitAddForm()"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import { addConfig, updateConfig } from '@/api/system/config'
export default {
name: 'WhiteAddConfig',
data() {
return {
form: {},
tokenId: '',
//
fileList: [],
configForm: {
addMode: 1,
whiteListType: '',
whitelistIds: '',
remark: '',
equepid: '',
file: []
},
configRules: {
addMode: [
{ required: true, message: '添加方式不能为空', trigger: 'change' }
],
whiteListType: [
{ required: true, message: '白名单类型不能为空', trigger: 'change' }
],
userId: [
{ required: true, message: '用户Id不能为空', trigger: 'blur' }
],
equepid: [
{ required: true, message: '设备信息不能为空', trigger: 'blur' }
],
file: [
{ required: true, message: '白名单文件不能为空', trigger: 'change' }
]
}
}
},
computed: {},
methods: {
reset() {
this.form = {
addMode: undefined,
whiteListType: undefined,
userId: undefined,
equepid: undefined,
file: undefined
}
this.resetForm('form')
},
/** 提交按钮 */
submitAddForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.configId != undefined) {
updateConfig(this.form).then(response => {
this.$modal.msgSuccess('修改成功')
})
} else {
addConfig(this.form).then(response => {
this.$modal.msgSuccess('新增成功')
})
}
this.$router.push({ path: '/build/whiteListManagement' })
}
})
},
cancel() {
this.$router.push({ path: '/build/whiteListManagement' })
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.tag-group {
.el-tag {
cursor: pointer;
}
}
.el-tag + .el-tag {
margin-left: 10px
}
.page-footer {
margin: 0 auto;
width: 700px;
justify-content: center;
display: flex;
}
</style>

View File

@ -0,0 +1,80 @@
<template>
<el-dialog :modal-append-to-body="false" :title="title" v-bind="$attrs" width="500px"
v-on="$listeners"
>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-form-item v-if="type==1" label="用户Id" prop="userId">
<el-input v-model="form.userId" placeholder="请输入用户Id"/>
</el-form-item>
<el-form-item v-else label="设备号" prop="equepid">
<el-input v-model="form.equepid" placeholder="请输入设备号"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitAddForm()"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</template>
<script>
import { updateConfig } from '@/api/system/config'
export default {
name: 'EditWhiteList',
props: {
//
type: {
type: Number,
default: 1
}
},
data() {
return {
configName: undefined,
form: {},
title: '编辑',
//
rules: {
userId: [
{ required: true, message: '用户Id不能为空', trigger: 'blur' }
],
equepid: [
{ required: true, message: '设备号不能为空', trigger: 'blur' }
]
}
}
},
methods: {
/** 提交按钮 */
submitAddForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
updateConfig(this.form).then(response => {
this.$modal.msgSuccess('修改成功')
this.closeModal()
})
}
})
},
reset() {
this.form = {
userId: undefined,
equepid: undefined
}
this.resetForm('form')
},
//
cancel() {
this.reset()
this.closeModal()
},
closeModal() {
this.$emit('close')
}
}
}
</script>

View File

@ -0,0 +1,177 @@
<template>
<div class="app-container">
<el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="90px" size="small">
<el-form-item label="白名单信息" prop="phoneNumber">
<el-input
v-model="queryParams.phoneNumber"
clearable
placeholder="请输入用户Id"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:delete']"
:disabled="multiple"
icon="el-icon-plus"
plain
size="mini"
type="info"
@click="handleDelete"
>批量删除
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="用户Id" prop="configName"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="添加时间" prop="configKey"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="备注" prop="configValue"/>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作" width="250">
<template slot-scope="scope">
<el-button
v-hasPermi="['system:config:edit']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleEdit(scope.row)"
>编辑
</el-button>
<el-button
v-hasPermi="['system:config:delete']"
icon="el-icon-delete"
size="mini"
type="text"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:limit.sync="queryParams.pageSize"
:page.sync="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
<EditWhiteList :visible.sync="editWhiteListOpen" @close="closeEditWhiteList"/>
</div>
</template>
<script>
import { delConfig, listConfig } from '@/api/system/config'
import EditWhiteList from '@/views/FDS/whiteListManagement/components/editWhiteList.vue'
export default {
name: 'WhiteListDetail',
components: { EditWhiteList },
dicts: ['sys_yes_no'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
dataList: [],
//
title: '',
editWhiteListOpen: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
phoneNumber: undefined
},
//
form: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listConfig(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.dataList = response.rows
this.total = response.total
this.loading = false
}
)
},
//
reset() {
this.form = {
phoneNumber: undefined
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.configId)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 删除按钮操作 */
handleDelete(row) {
const configIds = row.configId || this.ids
this.$modal.confirm('是否确认删除编号为"' + configIds + '"的数据项?').then(function() {
return delConfig(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {
})
},
/** 修改按钮操作 */
handleEdit(row) {
this.reset()
const configId = row.configId || this.ids
this.editWhiteListOpen = true
// getConfig(configId).then(response => {
// this.form = response.data
// this.addOpen = true
// this.title = ''
// })
},
/** 关闭新增弹出框*/
closeEditWhiteList() {
this.editWhiteListOpen = false
this.getList()
}
}
}
</script>

View File

@ -0,0 +1,140 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>编辑白名单</div>
<el-divider/>
</el-header>
<el-main>
<div class="form-main">
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<el-form-item label="白名单名称" prop="whiteListName">
<el-input v-model="form.whiteListName" placeholder="请输入白名单名称"/>
</el-form-item>
<el-form-item label="白名单类型" prop="whiteListType">
<el-select v-model="form.whiteListType" clearable placeholder="请选择白名单类型">
<el-option label="白名单人员" value="0"/>
<el-option label="白名单设备" value="1"/>
</el-select>
</el-form-item>
<el-form-item label="白名单模式" prop="whitePattern">
<el-select v-model="form.whitePattern" clearable placeholder="请选择白名单模式">
<el-option label="正则模式" value="0"/>
<el-option label="普通模式" value="1"/>
</el-select>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.remark" placeholder="请输入内容" type="textarea"/>
</el-form-item>
</el-form>
</div>
<div class="page-footer">
<el-button type="primary" @click="submitAddForm()"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import { updateConfig } from '@/api/system/config'
export default {
name: 'WhiteAdd',
dicts: ['sys_yes_no'],
data() {
return {
form: {},
tokenId: '',
//
fileList: [],
rules: {
whiteListName: [
{ required: true, message: '白名单名称不能为空', trigger: 'blur' }
],
whiteListType: [
{ required: true, message: '白名单类型不能为空', trigger: 'change' }
],
whitePattern: [
{ required: true, message: '白名单模式不能为空', trigger: 'change' }
]
}
}
},
computed: {},
methods: {
// reset() {
// this.form = {
// whiteListType: undefined,
// whiteListName: undefined,
// whitePattern: undefined,
// remark: undefined
// }
// this.resetForm('form')
// },
/** 提交按钮 */
submitAddForm: function() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.configId != undefined) {
updateConfig(this.form).then(response => {
this.$modal.msgSuccess('修改成功')
})
}
this.$router.push({ path: '/build/whiteListManagement' })
// else {
// addConfig(this.form).then(response => {
// this.$modal.msgSuccess('')
// })
// }
}
})
},
cancel() {
this.$router.push({ path: '/build/whiteListManagement' })
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.tag-group {
.el-tag {
cursor: pointer;
}
}
.el-tag + .el-tag {
margin-left: 10px
}
.page-footer {
margin: 0 auto;
width: 700px;
justify-content: center;
display: flex;
}
</style>

View File

@ -0,0 +1,184 @@
<template>
<div class="app-container">
<el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="90px" size="small">
<el-form-item label="白名单信息" prop="phoneNumber">
<el-input
v-model="queryParams.equepId"
clearable
placeholder="请输入设备号"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:delete']"
:disabled="multiple"
icon="el-icon-plus"
plain
size="mini"
type="info"
@click="handleDelete"
>批量删除
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"/>
<el-table-column align="center" label="设备号" prop="configId"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="添加时间" prop="configName"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="备注" prop="configValue"/>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作" width="250">
<template slot-scope="scope">
<el-button
v-hasPermi="['system:config:edit']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleEdit(scope.row)"
>编辑
</el-button>
<el-button
v-hasPermi="['system:config:delete']"
icon="el-icon-delete"
size="mini"
type="text"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:limit.sync="queryParams.pageSize"
:page.sync="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
<EditWhiteList :visible.sync="editWhiteListOpen" @close="closeEditWhiteList"/>
</div>
</template>
<script>
import { delConfig, listConfig } from '@/api/system/config'
import EditWhiteList from './components/editWhiteList.vue'
export default {
name: 'WhiteListEquepDetail',
dicts: ['sys_yes_no'],
components: {
EditWhiteList
},
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
dataList: [],
configList: [],
//
title: '',
//
editWhiteListOpen: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
equepId: undefined
},
//
form: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listConfig(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.dataList = response.rows
this.total = response.total
this.loading = false
}
)
},
//
reset() {
this.form = {
equepId: undefined
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.configId)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 删除按钮操作 */
handleDelete(row) {
const configIds = row.configId || this.ids
this.$modal.confirm('是否确认删除编号为"' + configIds + '"的数据项?').then(function() {
return delConfig(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {
})
},
/** 修改按钮操作 */
handleEdit(row) {
this.reset()
const configId = row.configId || this.ids
this.editWhiteListOpen = true
// getConfig(configId).then(response => {
// this.form = response.data
// this.editWhiteListOpen = true
// })
},
/** 关闭新增弹出框*/
closeEditWhiteList() {
this.editWhiteListOpen = false
this.getList()
}
}
}
</script>

View File

@ -0,0 +1,340 @@
<template>
<div class="app-container">
<el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="90px" size="small">
<el-form-item label="名单类型" prop="whiteListType">
<el-input
v-model="queryParams.whiteListType"
clearable
placeholder="请输入名单类型"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="名称" prop="whiteListName">
<el-input
v-model="queryParams.whiteListName"
clearable
placeholder="请输入名称"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="dateRange"
end-placeholder="结束日期"
range-separator="-"
start-placeholder="开始日期"
style="width: 240px"
type="daterange"
value-format="yyyy-MM-dd"
></el-date-picker>
</el-form-item>
<el-form-item label="状态" prop="configType">
<el-select v-model="queryParams.status" clearable placeholder="请选择状态">
<el-option
v-for="dict in dict.type.sys_yes_no"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:add']"
icon="el-icon-plus"
plain
size="mini"
type="primary"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
:disabled="multiple"
icon="el-icon-plus"
plain
size="mini"
type="info"
@click="handlePublish"
>批量发布
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
:disabled="multiple"
icon="el-icon-plus"
plain
size="mini"
type="info"
@click="handleDelete"
>批量删除
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"/>
<el-table-column align="center" label="白名单名称" prop="configId"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="说明" prop="configName"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="白名单类型" prop="configKey"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="数量" prop="configValue"/>
<el-table-column align="center" label="创建时间" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="状态" prop="configType">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_yes_no" :value="scope.row.configType"/>
</template>
</el-table-column>
<el-table-column :show-overflow-tooltip="true" align="center" label="备注" prop="remark"/>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作">
<template slot-scope="scope">
<el-button
icon="el-icon-edit"
size="mini"
type="text"
@click="handleDown(scope.row)"
>下架
</el-button>
<el-button
icon="el-icon-edit"
size="mini"
type="text"
@click="handlePublish(scope.row)"
>发布
</el-button>
<el-button
icon="el-icon-edit"
size="mini"
type="text"
@click="handleConfig(scope.row)"
>名单配置
</el-button>
<el-button
v-hasPermi="['system:config:edit']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleEdit(scope.row)"
>修改
</el-button>
<el-button
v-hasPermi="['system:config:edit']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleDetail(scope.row)"
>详情
</el-button>
<el-button
v-hasPermi="['system:config:remove']"
icon="el-icon-delete"
size="mini"
type="text"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:limit.sync="queryParams.pageSize"
:page.sync="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
</div>
</template>
<script>
import { delConfig, getConfig, listConfig } from '@/api/system/config'
export default {
name: 'WhiteList',
dicts: ['sys_yes_no'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
configList: [],
//
title: '',
//
addOpen: false,
//
configOpen: false,
//
dateRange: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
whiteListName: undefined,
whiteListType: undefined,
status: undefined
},
//
form: {},
//
configForm: {
addMode: 1,
whiteListType: undefined,
whitelistIds: undefined,
remark: undefined
}
}
},
created() {
this.getList()
},
methods: {
/** 查询参数列表 */
getList() {
this.loading = true
listConfig(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.configList = response.rows
this.total = response.total
this.loading = false
}
)
},
//
reset() {
this.form = {
configId: undefined,
configName: undefined,
configKey: undefined,
configValue: undefined,
configType: 'Y',
remark: undefined
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
const params = {
type: 'add'
}
this.$tab.openPage('新增白名单', '/build/WhiteList/add/', params)
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.configId)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 修改按钮操作 */
handleEdit(row) {
const params = {
type: 'edit'
}
this.$tab.openPage('编辑白名单', '/build/WhiteList/add/', params)
},
/** 白名单配置弹窗 **/
handleConfig(row) {
this.reset()
const configId = row.configId || this.ids
getConfig(configId).then(response => {
this.$router.push({
path: 'whiteList/addConfig'
})
})
},
/** 删除按钮操作 */
handleDelete(row) {
const configIds = row.configId || this.ids
this.$modal.confirm('是否确认删除编号为"' + configIds + '"的数据项?').then(function() {
return delConfig(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {
})
},
/** 发布按钮操作 */
handlePublish() {
const configIds = row.configId || this.ids
this.$modal.confirm('是否确认发布编号为"' + configIds + '"的数据项?').then(function() {
//
return delConfig(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('发布成功')
}).catch(() => {
})
},
/** 下架按钮操作 */
handleDown() {
const configIds = row.configId || this.ids
this.$modal.confirm('是否确认下架编号为"' + configIds + '"的数据项?').then(function() {
//
return delConfig(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('下架成功')
}).catch(() => {
})
},
/** 查看详情按钮操作 */
handleDetail(row) {
if (row.type == 1) {
this.$router.push({
path: '/build/WhiteList/detail'
})
} else {
this.$router.push({
path: '/build/WhiteList/equepDetail'
})
}
}
}
}
</script>

View File

@ -0,0 +1,116 @@
<template>
<el-row v-loading="loading" :gutter="20">
<el-col v-for="item in list" :key="item.id" :span="8" class="card-col">
<el-card :body-style="{ padding: '15px 0 0 0' }" shadow="hover">
<div class="card-conainer">
<div class="card-head">
<el-link :underline="false" @click="$emit('del', item)">删除</el-link>
</div>
<div class="card-center">
<image-preview :src="item.picture" :width="60" :height="60"/>
<!-- <el-avatar
class="icon"
:src="'/dev-api/'+item.picture"
fit="cover"
:size="100"
/> -->
<div class="content ml20">
<div class="card-title">{{item.appName}}</div>
<div class="time">{{item.createTime}}</div>
</div>
</div>
<p class="desc">{{item.appDesc}}</p>
</div>
<div class="card-foot">
<el-button class="card-btn" @click="$emit('update', item)">编辑</el-button>
<el-divider class="card-divider" direction="vertical"></el-divider>
<el-button class="card-btn" @click="$emit('enter', item)">进入</el-button>
</div>
</el-card>
</el-col>
</el-row>
</template>
<script>
export default {
props: {
list: {
type: Array,
default: () => []
},
loading: {
type: Boolean,
default: false
}
},
data() {
return {
defImg: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.card-col {
margin-bottom: 20px;
}
.card-conainer {
padding: 0 20px;
.card-head {
display: flex;
justify-content: flex-end;
}
.card-center {
display: flex;
.el-image {
width: 60px;
border-radius: 50%;
}
.content {
flex: 1;
display: flex;
flex-flow: column;
justify-content: space-evenly;
}
.card-title {
font-size: 16px;
font-weight: bold;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #707070;
}
.time {
font-size: 14px;
color: #666;
}
}
.desc {
font-size: 14px;
color: #999;
height: 38px;
display: -webkit-box; /* 兼容webkit内核浏览器 */
-webkit-line-clamp: 2; /* 最多显示两行 */
-webkit-box-orient: vertical; /* 设置或限制在一个块状元素显示的内容的排列方式 */
overflow: hidden; /* 隐藏超出部分 */
text-overflow: ellipsis; /* 显示省略号 */
}
}
.card-foot {
display: flex;
border-top: 1px solid #DCDFE6;
.card-btn {
flex: 1;
border: none;
border-radius: 0;
height: 50px;
}
.card-divider {
height: 50px;
margin: 0;
}
}
</style>

View File

@ -0,0 +1,60 @@
<template>
<el-table v-loading="loading" :data="list">
<el-table-column type="index" width="55" align="center" />
<el-table-column label="项目名" width="300" prop="appName" :show-overflow-tooltip="true" />
<el-table-column label="项目图片" width="100" prop="picture">
<template slot-scope="scope">
<image-preview :src="scope.row.picture" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="项目描述" prop="appDesc" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" width="200" prop="createTime" :show-overflow-tooltip="true" />
<el-table-column label="操作" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="$emit('enter', scope.row)"
>进入</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="$emit('update', scope.row)"
>编辑</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="$emit('del', scope.row)"
>删除</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
props: {
list: {
type: Array,
default: () => []
},
loading: {
type: Boolean,
default: false
},
},
data() {
return {
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,195 @@
<template>
<div class="app-container">
<el-container>
<el-header>
<div>新增安装包</div>
<el-divider/>
</el-header>
<el-main>
<div class="form-main">
<el-form ref="elForm" :model="formData" :rules="rules" label-width="100px" size="medium">
<el-form-item label="上传方式" prop="field102">
<el-radio-group v-model="formData.field102" size="medium">
<el-radio v-for="(item, index) in field102Options" :key="index" :disabled="item.disabled"
:label="item.value"
>{{ item.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="activeTabs===1" label="安装包名称" prop="sysApkName">
<el-input v-model="formData.sysApkName" :style="{width: '100%'}" clearable placeholder="请输入安装包名称">
</el-input>
</el-form-item>
<el-form-item v-else label="模块包名称" prop="field107">
<el-input v-model="formData.field107" :style="{width: '100%'}" clearable placeholder="请输入模块包名称">
</el-input>
</el-form-item>
<el-form-item label="版本号" prop="version">
<el-input v-model="formData.version" :style="{width: '100%'}" clearable placeholder="请输入版本号">
</el-input>
</el-form-item>
<el-form-item label="安装包文件" prop="sysApk">
<el-upload ref="sysApk" :action="field101Action" :before-upload="field101BeforeUpload"
:file-list="field101fileList"
>
<el-button icon="el-icon-upload" size="small" type="primary">上传文件</el-button>
</el-upload>
</el-form-item>
<el-form-item label="安装包大小" prop="sysApkSize">
<el-input v-model="formData.sysApkSize" :style="{width: '100%'}" clearable placeholder="请输入安装包大小">
</el-input>
</el-form-item>
<el-form-item label="安装包类型" prop="sysType">
<el-select v-model="form.sysType" placeholder="请选择安装包类型">
<el-option
v-for="dict in dict.type.sys_apk_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<!-- <el-form-item v-if="activeTabs!='1'" label="适用模块" prop="configName">-->
<!-- <el-select v-model="formData.field108" clearable placeholder="请选择对应的模块">-->
<!-- <el-option-->
<!-- v-for="dict in dict.type.sys_yes_no"-->
<!-- :key="dict.value"-->
<!-- :label="dict.label"-->
<!-- :value="dict.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item size="large">
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button @click="resetForm">重置</el-button>
</el-form-item>
</el-form>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import { addINFO, updateINFO } from '@/api/deploy/INFO'
export default {
name: 'InstallAdd',
dicts: ['sys_apk_uploading_type', 'uploading_status', 'sys_apk_type'],
data() {
return {
formData: {
field102: 1,
field103: undefined,
field104: undefined,
field101: null,
field105: undefined,
field106: 'Android',
field107: undefined,
field108: undefined
},
rules: {
field102: [{
required: true,
message: '上传方式不能为空',
trigger: 'change'
}],
field103: [{
required: true,
message: '请输入安装包名称',
trigger: 'blur'
}],
field107: [{
required: true,
message: '请输入模块包名称',
trigger: 'blur'
}],
field105: [],
field106: []
},
field101Action: 'https://jsonplaceholder.typicode.com/posts/',
field101fileList: [],
field102Options: [{
'label': '在线上传',
'value': 1
}, {
'label': '离线上传',
'value': 2
}],
field106Options: [{
'label': 'Android',
'value': 'Android'
}, {
'label': 'IOS',
'value': 'IOS'
}, {
'label': '鸿蒙',
'value': 'HarmonyOS'
}],
activeTabs: '1'
}
},
computed: {},
mounted() {
console.log(this.$route)
this.activeTabs = this.$route.params.activeTabs
},
methods: {
/** 提交按钮 */
submitForm() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id != null) {
let data = Object.assign({}, this.form)
delete data.explain
updateINFO(data).then(response => {
this.$modal.msgSuccess('修改成功')
this.open = false
this.getList()
})
} else {
addINFO(this.form).then(response => {
this.$modal.msgSuccess('新增成功')
this.open = false
this.getList()
})
}
}
})
},
//
resetForm() {
this.$refs['elForm'].resetFields()
},
field101BeforeUpload(file) {
let isRightSize = file.size / 1024 / 1024 < 2
if (!isRightSize) {
this.$message.error('文件大小超过 2MB')
}
return isRightSize
},
cancel() {
this.history.back()
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
background: #ffffff;
margin: 24px;
}
.form-main {
width: 700px;
margin: 0 auto;
}
::v-deep .el-input.is-disabled .el-input__inner, .el-textarea.is-disabled .el-textarea__inner {
border: 1px solid #E4E7ED !important;
}
.el-upload__tip {
line-height: 1.2;
}
</style>

View File

@ -0,0 +1,337 @@
<template>
<div class="app-container">
<el-tabs v-model="activeTabs" type="card" @tab-click="handleClickTabs">
<el-tab-pane
v-for="item in packTabs"
:key="item.name"
:label="item.title"
:name="item.name"
>
</el-tab-pane>
</el-tabs>
<el-form v-show="showSearch" ref="queryForm" :inline="true" :model="queryParams" label-width="90px" size="small">
<el-form-item label="上传类型" prop="uploadingType">
<el-select v-model="queryParams.uploadingType" clearable placeholder="请选择上传类型">
<el-option
v-for="dict in dict.type.sys_apk_uploading_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="安装包名称" prop="sysApkName">
<el-input
v-model="queryParams.sysApkName"
clearable
placeholder="请输入安装包名称"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="版本号" prop="version">
<el-input
v-model="queryParams.version"
clearable
placeholder="请输入版本号"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="安装包类型" prop="sysType">
<el-select v-model="queryParams.sysType" clearable placeholder="请选择安装包类型">
<el-option
v-for="dict in dict.type.sys_apk_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="上传状态" prop="uploadingStatus">
<el-select v-model="queryParams.uploadingStatus" clearable placeholder="请选择上传状态">
<el-option
v-for="dict in dict.type.uploading_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建人" prop="created">
<el-input
v-model="queryParams.created"
clearable
placeholder="请输入创建人"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:add']"
icon="el-icon-plus"
plain
size="mini"
type="primary"
@click="handleAdd"
>新建
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['system:config:delete']"
:disabled="multiple"
icon="el-icon-plus"
plain
size="mini"
type="info"
@click="handleDelete"
>批量删除
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="INFOList" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"/>
<template v-if="activeTabs=='1'">
<el-table-column align="center" label="上传类型" prop="uploadingType">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_apk_uploading_type" :value="scope.row.uploadingType"/>
</template>
</el-table-column>
<el-table-column align="center" label="安装包名称" prop="sysApkName"/>
<el-table-column align="center" label="版本号" prop="version"/>
<el-table-column align="center" label="安装包" prop="sysApk"/>
<el-table-column align="center" label="安装包大小" prop="sysApkSize"/>
<el-table-column align="center" label="安装包类型" prop="sysType">
<template slot-scope="scope">
<dict-tag :options="dict.type.sys_apk_type" :value="scope.row.sysType"/>
</template>
</el-table-column>
<el-table-column align="center" label="创建人" prop="created"/>
</template>
<template v-if="activeTabs=='2'">
<el-table-column align="center" label="安装包名称" prop="configId"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="版本号" prop="version"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="安装包大小" prop="sys_apk_size"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="上传方式" prop="uploading_type"/>
<el-table-column :show-overflow-tooltip="true" align="center" label="创建人" prop="created"/>
<el-table-column align="center" label="创建时间" prop="create_time" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
</template>
<el-table-column align="center" label="状态" prop="uploading_status">
<template slot-scope="scopeA">
<dict-tag :options="dict.type.sys_yes_no" :value="scopeA.row.type"/>
</template>
</el-table-column>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作" width="250">
<template slot-scope="scope">
<el-button
v-hasPermi="['system:config:dowmload']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleDownload(scope.row)"
>下载安装包
</el-button>
<el-button
v-hasPermi="['system:config:edit']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleEdit(scope.row)"
>编辑
</el-button>
<el-button
v-hasPermi="['system:config:detail']"
icon="el-icon-edit"
size="mini"
type="text"
@click="handleDetail(scope.row)"
>详情
</el-button>
<el-button
v-hasPermi="['system:config:delete']"
icon="el-icon-delete"
size="mini"
type="text"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:limit.sync="queryParams.pageSize"
:page.sync="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
</div>
</template>
<script>
// import { listINFO, getINFO, delINFO, addINFO, updateINFO } from "@/api/deploy/INFO";
export default {
name: 'InstallationList',
dicts: ['sys_yes_no'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
INFOList: [],
packTabs: [{
name: '1',
title: 'APP安装包'
}, {
name: '2',
title: 'H5模块包'
}],
//
create_time: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
uploadingType: null,
sysApkName: null,
version: null,
sysType: null,
uploadingStatus: null,
created: null
},
//
form: {},
activeTabs: '1'
//
}
},
created() {
this.getList()
},
methods: {
/** 查询安装包管理(新)列表 */
getList() {
this.loading = false
// listINFO(this.queryParams).then(response => {
// this.INFOList = response.rows
// this.total = response.total
// this.loading = false
// })
listINFO(this.queryParams).then(response => {
this.INFOList = response.rows
this.total = response.total
this.loading = false
})
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.create_time = []
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.$router.push({
path: 'install/add',
params: {
type: 'add',
activeTabs: this.activeTabs
}
})
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length != 1
this.multiple = !selection.length
},
/** 删除按钮操作 */
handleDelete(row) {
const configIds = row.id || this.ids
this.$modal.confirm('是否确认删除编号为"' + configIds + '"的数据项?').then(function() {
return delConfig(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
}).catch(() => {
})
},
/** 修改按钮操作 */
handleEdit(row) {
this.reset()
const configId = row.id || this.ids
getConfig(configId).then(response => {
this.form = response.data
this.$router.push({
path: 'install/add',
params: {
type: 'edit',
activeTabs: this.activeTabs
}
})
})
},
/** 查看详情弹窗 **/
handleDetail() {
this.$router.push({
path: 'install/detail',
params: {
activeTabs: this.activeTabs
}
})
},
/** 切换TAB触发的事件 */
handleClickTabs() {
this.getList()
},
/** 下载按钮 */
handleDownload(row) {
const configIds = row.id || this.ids
this.$modal.confirm('是否确认下载编号为"' + configIds + '"的数据项?').then(function() {
return delConfig(configIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess('下载成功')
}).catch(() => {
})
},
/** 关闭新增弹出框*/
closeAdd() {
this.addOpen = false
this.getList()
},
closeAddConfig() {
this.detailOpen = false
}
}
}
</script>

View File

@ -0,0 +1,336 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="接口名称" prop="interfaceName">
<el-input
v-model="queryParams.interfaceName"
placeholder="请输入接口名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="接口状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择接口状态" clearable>
<el-option
v-for="dict in dict.type.gateway_data_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="daterangeCreateTime"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['gateway:interface:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['gateway:interface:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['gateway:interface:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['gateway:interface:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="interfaceList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" />
<el-table-column label="接口名称" align="center" prop="interfaceName" />
<el-table-column label="接口路径" align="center" prop="interfacePath" />
<el-table-column label="请求方式" align="center" prop="requestMethod">
<template slot-scope="scope">
<dict-tag :options="dict.type.http_request_method" :value="scope.row.requestMethod"/>
</template>
</el-table-column>
<el-table-column label="接口描述" align="center" prop="description" />
<el-table-column label="接口版本" align="center" prop="version" />
<el-table-column label="接口状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.gateway_data_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="接口文档" align="center" prop="document" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['gateway:interface:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['gateway:interface:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改接口管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="接口名称" prop="interfaceName">
<el-input v-model="form.interfaceName" placeholder="请输入接口名称" />
</el-form-item>
<el-form-item label="接口路径" prop="interfacePath">
<el-input v-model="form.interfacePath" placeholder="请输入接口路径" />
</el-form-item>
<el-form-item label="请求方式" prop="requestMethod">
<el-radio-group v-model="form.requestMethod">
<el-radio
v-for="dict in dict.type.http_request_method"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="接口描述" prop="description">
<el-input v-model="form.description" placeholder="请输入接口描述" />
</el-form-item>
<el-form-item label="接口版本" prop="version">
<el-input v-model="form.version" placeholder="请输入接口版本" />
</el-form-item>
<el-form-item label="接口文档" prop="document">
<file-upload v-model="form.document"/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listInterface, getInterface, delInterface, addInterface, updateInterface } from "@/api/gateway/interface";
export default {
name: "Interface",
dicts: ['gateway_data_status', 'http_request_method'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
interfaceList: [],
//
title: "",
//
open: false,
//
daterangeCreateTime: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
interfaceName: null,
status: null,
createTime: null,
},
//
form: {},
//
rules: {
interfaceName: [
{ required: true, message: "接口名称不能为空", trigger: "blur" }
],
interfacePath: [
{ required: true, message: "接口路径不能为空", trigger: "blur" }
],
requestMethod: [
{ required: true, message: "请求方式不能为空", trigger: "change" }
],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询接口管理列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
// apijson
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
this.queryParams.createTime = this.daterangeCreateTime[0]+","+this.daterangeCreateTime[1];
}
listInterface(this.queryParams).then(response => {
this.interfaceList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
interfaceName: null,
interfacePath: null,
requestMethod: null,
description: null,
version: null,
status: null,
document: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.queryParams.createTime = null;
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加接口管理";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getInterface(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改接口管理";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
let data = Object.assign({},this.form)
delete data.explain
updateInterface(data).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addInterface(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除接口管理编号为"' + ids + '"的数据项?').then(function() {
return delInterface(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('gateway/interface/export', {
...this.queryParams
}, `interface_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -0,0 +1,336 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="路由名称" prop="routerName">
<el-input
v-model="queryParams.routerName"
placeholder="请输入路由名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="请求方式" prop="requestMethod">
<el-input
v-model="queryParams.requestMethod"
placeholder="请输入请求方式"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建人" prop="createBy">
<el-input
v-model="queryParams.createBy"
placeholder="请输入创建人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="daterangeCreateTime"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['gateway:route:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['gateway:route:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['gateway:route:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['gateway:route:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="routeList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" />
<el-table-column label="路由名称" align="center" prop="routerName" />
<el-table-column label="请求路径" align="center" prop="requestPath" />
<el-table-column label="请求方式" align="center" prop="requestMethod">
<template slot-scope="scope">
<dict-tag :options="dict.type.http_request_method" :value="scope.row.requestMethod"/>
</template>
</el-table-column>
<el-table-column label="请求参数json格式" align="center" prop="requestParameter" />
<el-table-column label="服务地址" align="center" prop="serverAddress" />
<el-table-column label="服务器端口" align="center" prop="serverPort" />
<el-table-column label="创建人" align="center" prop="createBy" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['gateway:route:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['gateway:route:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改路由管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="路由名称" prop="routerName">
<el-input v-model="form.routerName" placeholder="请输入路由名称" />
</el-form-item>
<el-form-item label="请求路径" prop="requestPath">
<el-input v-model="form.requestPath" placeholder="请输入请求路径" />
</el-form-item>
<el-form-item label="请求方式" prop="requestMethod">
<el-input v-model="form.requestMethod" placeholder="请输入请求方式" />
</el-form-item>
<el-form-item label="请求参数json格式" prop="requestParameter">
<el-input v-model="form.requestParameter" placeholder="请输入请求参数json格式" />
</el-form-item>
<el-form-item label="服务地址" prop="serverAddress">
<el-input v-model="form.serverAddress" placeholder="请输入服务地址" />
</el-form-item>
<el-form-item label="服务器端口" prop="serverPort">
<el-input v-model="form.serverPort" placeholder="请输入服务器端口" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listRoute, getRoute, delRoute, addRoute, updateRoute } from "@/api/gateway/route";
export default {
name: "Route",
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
routeList: [],
//
title: "",
//
open: false,
//
daterangeCreateTime: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
routerName: null,
requestMethod: null,
createBy: null,
createTime: null,
},
//
form: {},
//
rules: {
routerName: [
{ required: true, message: "路由名称不能为空", trigger: "blur" }
],
requestPath: [
{ required: true, message: "请求路径不能为空", trigger: "blur" }
],
requestMethod: [
{ required: true, message: "请求方式不能为空", trigger: "blur" }
],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询路由管理列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
// apijson
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
this.queryParams.createTime = this.daterangeCreateTime[0]+","+this.daterangeCreateTime[1];
}
listRoute(this.queryParams).then(response => {
this.routeList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
routerName: null,
requestPath: null,
requestMethod: null,
requestParameter: null,
serverAddress: null,
serverPort: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.queryParams.createTime = null;
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加路由管理";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getRoute(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改路由管理";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
let data = Object.assign({},this.form)
delete data.explain
updateRoute(data).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addRoute(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除路由管理编号为"' + ids + '"的数据项?').then(function() {
return delRoute(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('gateway/route/export', {
...this.queryParams
}, `route_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -0,0 +1,342 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="服务名称" prop="serverName">
<el-input
v-model="queryParams.serverName"
placeholder="请输入服务名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="服务地址" prop="serverAddress">
<el-input
v-model="queryParams.serverAddress"
placeholder="请输入服务地址"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="服务状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择服务状态" clearable>
<el-option
v-for="dict in dict.type.gateway_data_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="daterangeCreateTime"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['gateway:server:add']"
>新增</el-button>
</el-col>
<!-- <el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['gateway:server:edit']"
>修改</el-button>
</el-col> -->
<!-- <el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-position"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['gateway:server:remove']"
>批量发布</el-button>
</el-col> -->
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['gateway:server:remove']"
>批量删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['gateway:server:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="serverList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" />
<el-table-column label="服务名称" align="center" prop="serverName" />
<el-table-column label="服务地址" align="center" prop="serverAddress" />
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="接口版本" align="center" prop="version" />
<el-table-column label="服务状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.gateway_data_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="创建者" align="center" prop="createBy" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="更新时间" align="center" prop="updateTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['gateway:server:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['gateway:server:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改服务管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="服务名称" prop="serverName">
<el-input v-model="form.serverName" placeholder="请输入服务名称" />
</el-form-item>
<el-form-item label="服务地址" prop="serverAddress">
<el-input v-model="form.serverAddress" placeholder="请输入服务地址" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listServer, getServer, delServer, addServer, updateServer } from "@/api/gateway/server";
export default {
name: "Server",
dicts: ['gateway_data_status'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
serverList: [],
//
title: "",
//
open: false,
//
daterangeCreateTime: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
serverName: null,
serverAddress: null,
status: null,
createBy: null,
createTime: null,
},
//
form: {},
//
rules: {
serverName: [
{ required: true, message: "服务名称不能为空", trigger: "blur" }
],
serverAddress: [
{ required: true, message: "服务地址不能为空", trigger: "blur" }
],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询服务管理列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
// apijson
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
this.queryParams.createTime = this.daterangeCreateTime[0]+","+this.daterangeCreateTime[1];
}
listServer(this.queryParams).then(response => {
this.serverList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
serverName: null,
serverAddress: null,
remark: null,
version: null,
status: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.queryParams.createTime = null;
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加服务管理";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getServer(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改服务管理";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
let data = Object.assign({},this.form)
delete data.explain
updateServer(data).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addServer(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除服务管理编号为"' + ids + '"的数据项?').then(function() {
return delServer(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('gateway/server/export', {
...this.queryParams
}, `server_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -0,0 +1,394 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="策略名称" prop="strategyName">
<el-input
v-model="queryParams.strategyName"
placeholder="请输入策略名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="策略类型" prop="strategyType">
<el-select v-model="queryParams.strategyType" placeholder="请选择策略类型" clearable>
<el-option
v-for="dict in dict.type.gateway_strategy_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="请求方式" prop="requestMethod">
<el-input
v-model="queryParams.requestMethod"
placeholder="请输入请求方式"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="策略状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择策略状态" clearable>
<el-option
v-for="dict in dict.type.gateway_data_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker
v-model="daterangeCreateTime"
style="width: 240px"
value-format="yyyy-MM-dd"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['gateway:strategy:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['gateway:strategy:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['gateway:strategy:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['gateway:strategy:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="strategyList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="ID" align="center" prop="id" />
<el-table-column label="策略名称" align="center" prop="strategyName" />
<el-table-column label="策略类型" align="center" prop="strategyType">
<template slot-scope="scope">
<dict-tag :options="dict.type.gateway_strategy_type" :value="scope.row.strategyType"/>
</template>
</el-table-column>
<el-table-column label="策略描述" align="center" prop="description" />
<el-table-column label="请求方式" align="center" prop="requestMethod" />
<el-table-column label="策略状态" align="center" prop="status">
<template slot-scope="scope">
<dict-tag :options="dict.type.gateway_data_status" :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="更新时间" align="center" prop="updateTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['gateway:strategy:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['gateway:strategy:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改策略管理对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="策略名称" prop="strategyName">
<el-input v-model="form.strategyName" placeholder="请输入策略名称" />
</el-form-item>
<el-form-item label="策略类型" prop="strategyType">
<el-select v-model="form.strategyType" placeholder="请选择策略类型">
<el-option
v-for="dict in dict.type.gateway_strategy_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="策略描述" prop="description">
<el-input v-model="form.description" placeholder="请输入策略描述" />
</el-form-item>
<el-form-item label="请求方式" prop="requestMethod">
<el-input v-model="form.requestMethod" placeholder="请输入请求方式" />
</el-form-item>
<el-form-item label="加密算法" prop="encryptionAlgorithm">
<el-input v-model="form.encryptionAlgorithm" placeholder="请输入加密算法" />
</el-form-item>
<el-form-item label="策略状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.gateway_data_status"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="私钥" prop="privateKey">
<el-input v-model="form.privateKey" placeholder="请输入私钥" />
</el-form-item>
<el-form-item label="公钥" prop="publicKey">
<el-input v-model="form.publicKey" placeholder="请输入公钥" />
</el-form-item>
<el-form-item label="限流算法" prop="currentLimitingAlgorithm">
<el-input v-model="form.currentLimitingAlgorithm" placeholder="请输入限流算法" />
</el-form-item>
<el-form-item label="限流阈值" prop="currentLimitingThreshold">
<el-input v-model="form.currentLimitingThreshold" placeholder="请输入限流阈值" />
</el-form-item>
<el-form-item label="限流周期" prop="currentLimitingPeriod">
<el-input v-model="form.currentLimitingPeriod" placeholder="请输入限流周期" />
</el-form-item>
<el-form-item label="限流处理方式" prop="currentLimitingProcessingMethod">
<el-input v-model="form.currentLimitingProcessingMethod" placeholder="请输入限流处理方式" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listStrategy, getStrategy, delStrategy, addStrategy, updateStrategy } from "@/api/gateway/strategy";
export default {
name: "Strategy",
dicts: ['gateway_data_status', 'gateway_strategy_type'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
strategyList: [],
//
title: "",
//
open: false,
//
daterangeCreateTime: [],
//
queryParams: {
pageNum: 1,
pageSize: 10,
strategyName: null,
strategyType: null,
requestMethod: null,
status: null,
createTime: null,
},
//
form: {},
//
rules: {
strategyName: [
{ required: true, message: "策略名称不能为空", trigger: "blur" }
],
strategyType: [
{ required: true, message: "策略类型不能为空", trigger: "change" }
],
requestMethod: [
{ required: true, message: "请求方式不能为空", trigger: "blur" }
],
}
};
},
created() {
this.getList();
},
methods: {
/** 查询策略管理列表 */
getList() {
this.loading = true;
this.queryParams.params = {};
if (null != this.daterangeCreateTime && '' != this.daterangeCreateTime) {
// apijson
this.queryParams.params["beginCreateTime"] = this.daterangeCreateTime[0];
this.queryParams.params["endCreateTime"] = this.daterangeCreateTime[1];
this.queryParams.createTime = this.daterangeCreateTime[0]+","+this.daterangeCreateTime[1];
}
listStrategy(this.queryParams).then(response => {
this.strategyList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
strategyName: null,
strategyType: null,
description: null,
requestMethod: null,
encryptionAlgorithm: null,
status: null,
privateKey: null,
publicKey: null,
currentLimitingAlgorithm: null,
currentLimitingThreshold: null,
currentLimitingPeriod: null,
currentLimitingProcessingMethod: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.daterangeCreateTime = [];
this.queryParams.createTime = null;
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加策略管理";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getStrategy(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改策略管理";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
let data = Object.assign({},this.form)
delete data.explain
updateStrategy(data).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addStrategy(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除策略管理编号为"' + ids + '"的数据项?').then(function() {
return delStrategy(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('gateway/strategy/export', {
...this.queryParams
}, `strategy_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -1,963 +1,26 @@
<template>
<div class="app-container home">
<el-row :gutter="20">
<el-col :sm="24" :lg="24">
<blockquote class="text-warning" style="font-size: 14px">
领取阿里云通用云产品1888优惠券
<br />
<el-link
href="https://www.aliyun.com/minisite/goods?userCode=brki8iof"
type="primary"
target="_blank"
>https://www.aliyun.com/minisite/goods?userCode=brki8iof</el-link
>
<br />
领取腾讯云通用云产品2860优惠券
<br />
<el-link
href="https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console"
type="primary"
target="_blank"
>https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console</el-link
>
<br />
阿里云服务器折扣区
<el-link href="http://aly.ruoyi.vip" type="primary" target="_blank"
>>点我进入</el-link
>
&nbsp;&nbsp;&nbsp; 腾讯云服务器秒杀区
<el-link href="http://txy.ruoyi.vip" type="primary" target="_blank"
>>点我进入</el-link
><br />
<h4 class="text-danger">
云产品通用红包可叠加官网常规优惠使用(仅限新用户)
</h4>
</blockquote>
<hr />
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :sm="24" :lg="12" style="padding-left: 20px">
<h2>若依后台管理框架</h2>
<p>
一直想做一款后台管理系统看了很多优秀的开源项目但是发现没有合适自己的于是利用空闲休息时间开始自己写一套后台系统如此有了若依管理系统她可以用于所有的Web应用程序如网站管理后台网站会员中心CMSCRMOA等等当然您也可以对她进行深度定制以做出更强系统所有前端后台代码封装过后十分精简易上手出错概率低同时支持移动客户端访问系统会陆续更新一些实用功能
</p>
<p>
<b>当前版本:</b> <span>v{{ version }}</span>
</p>
<p>
<el-tag type="danger">&yen;免费开源</el-tag>
</p>
<p>
<el-button
type="primary"
size="mini"
icon="el-icon-cloudy"
plain
@click="goTarget('https://gitee.com/y_project/RuoYi-Vue')"
>访问码云</el-button
>
<el-button
size="mini"
icon="el-icon-s-home"
plain
@click="goTarget('http://ruoyi.vip')"
>访问主页</el-button
>
</p>
</el-col>
<el-col :sm="24" :lg="12" style="padding-left: 50px">
<el-row>
<el-col :span="12">
<h2>技术选型</h2>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<h4>后端技术</h4>
<ul>
<li>SpringBoot</li>
<li>Spring Security</li>
<li>JWT</li>
<li>MyBatis</li>
<li>Druid</li>
<li>Fastjson</li>
<li>...</li>
</ul>
</el-col>
<el-col :span="6">
<h4>前端技术</h4>
<ul>
<li>Vue</li>
<li>Vuex</li>
<li>Element-ui</li>
<li>Axios</li>
<li>Sass</li>
<li>Quill</li>
<li>...</li>
</ul>
</el-col>
</el-row>
</el-col>
</el-row>
<el-divider />
<el-row :gutter="20">
<el-col :xs="24" :sm="24" :md="12" :lg="8">
<el-card class="update-log">
<div slot="header" class="clearfix">
<span>联系信息</span>
</div>
<div class="body">
<p>
<i class="el-icon-s-promotion"></i> 官网<el-link
href="http://www.ruoyi.vip"
target="_blank"
>http://www.ruoyi.vip</el-link
>
</p>
<p>
<i class="el-icon-user-solid"></i> QQ群<s> 满937441 </s> <s> 满887144332 </s>
<s> 满180251782 </s> <s> 满104180207 </s> <s> 满186866453 </s> <s> 满201396349 </s>
<s> 满101456076 </s> <s> 满101539465 </s> <s> 满264312783 </s> <s> 满167385320 </s>
<s> 满104748341 </s> <s> 满160110482 </s> <s> 满170801498 </s> <s> 满108482800 </s>
<s> 满101046199 </s> <s> 满136919097 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921" target="_blank">143961921</a>
</p>
<p>
<i class="el-icon-chat-dot-round"></i> 微信<a
href="javascript:;"
>/ *</a
>
</p>
<p>
<i class="el-icon-money"></i> 支付宝<a
href="javascript:;"
class="支付宝信息"
>/ *</a
>
</p>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="24" :md="12" :lg="8">
<el-card class="update-log">
<div slot="header" class="clearfix">
<span>更新日志</span>
</div>
<el-collapse accordion>
<el-collapse-item title="v3.8.6 - 2023-06-30">
<ol>
<li>支持登录IP黑名单限制</li>
<li>新增监控页面图标显示</li>
<li>操作日志新增消耗时间属性</li>
<li>屏蔽定时任务bean违规的字符</li>
<li>日志管理使用索引提升查询性能</li>
<li>日志注解支持排除指定的请求参数</li>
<li>支持自定义隐藏属性列过滤子对象</li>
<li>升级oshi到最新版本6.4.3</li>
<li>升级druid到最新版本1.2.16</li>
<li>升级fastjson到最新版2.0.34</li>
<li>升级spring-boot到最新版本2.5.15</li>
<li>升级element-ui到最新版本2.15.13</li>
<li>移除apache/commons-fileupload依赖</li>
<li>修复页面切换时布局错乱的问题</li>
<li>修复匿名注解Anonymous空指针问题</li>
<li>修复路由跳转被阻止时内部产生报错信息问题</li>
<li>修复isMatchedIp的参数判断产生空指针的问题</li>
<li>修复用户多角色数据权限可能出现权限抬升的情况</li>
<li>修复开启TopNav后一级菜单路由参数设置无效问题</li>
<li>修复DictTag组件value没有匹配的值时则展示value</li>
<li>优化文件下载出现的异常</li>
<li>优化选择图标组件高亮回显</li>
<li>优化弹窗后导航栏偏移的问题</li>
<li>优化修改密码日志存储明文问题</li>
<li>优化页签栏关闭其他出现的异常问题</li>
<li>优化页签关闭左侧选项排除首页选项</li>
<li>优化关闭当前tab页跳转最右侧tab页</li>
<li>优化缓存列表清除操作提示不变的问题</li>
<li>优化字符未使用下划线不进行驼峰式处理</li>
<li>优化用户导入更新时需获取用户编号问题</li>
<li>优化侧边栏的平台标题与VUE_APP_TITLE保持同步</li>
<li>优化导出Excel时设置dictType属性重复查缓存问题</li>
<li>连接池Druid支持新的配置connectTimeout和socketTimeout</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.8.5 - 2023-01-01">
<ol>
<li>定时任务违规的字符</li>
<li>重置时取消部门选中</li>
<li>新增返回警告消息提示</li>
<li>忽略不必要的属性数据返回</li>
<li>修改参数键名时移除前缓存配置</li>
<li>导入更新用户数据前校验数据权限</li>
<li>兼容Excel下拉框内容过多无法显示的问题</li>
<li>升级echarts到最新版本5.4.0</li>
<li>升级core-js到最新版本3.25.3</li>
<li>升级oshi到最新版本6.4.0</li>
<li>升级kaptcha到最新版2.3.3</li>
<li>升级druid到最新版本1.2.15</li>
<li>升级fastjson到最新版2.0.20</li>
<li>升级pagehelper到最新版1.4.6</li>
<li>优化弹窗内容过多展示不全问题</li>
<li>优化swagger-ui静态资源使用缓存</li>
<li>开启TopNav没有子菜单隐藏侧边栏</li>
<li>删除fuse无效选项maxPatternLength</li>
<li>优化导出对象的子列表为空会出现[]问题</li>
<li>优化编辑头像时透明部分会变成黑色问题</li>
<li>优化小屏幕上修改头像界面布局错位的问题</li>
<li>修复代码生成勾选属性无效问题</li>
<li>修复文件上传组件格式验证问题</li>
<li>修复回显数据字典数组异常问题</li>
<li>修复sheet超出最大行数异常问题</li>
<li>修复Log注解GET请求记录不到参数问题</li>
<li>修复调度日志点击多次数据不变化的问题</li>
<li>修复主题颜色在Drawer组件不会加载问题</li>
<li>修复文件名包含特殊字符的文件无法下载问题</li>
<li>修复table中更多按钮切换主题色未生效修复问题</li>
<li>修复某些特性的环境生成代码变乱码TXT文件问题</li>
<li>修复代码生成图片/文件/单选时选择必填无法校验问题</li>
<li>修复某些特性的情况用户编辑对话框中角色和部门无法修改问题</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.8.4 - 2022-09-26">
<ol>
<li>数据逻辑删除不进行唯一验证</li>
<li>Excel注解支持导出对象的子列表方法</li>
<li>Excel注解支持自定义隐藏属性列</li>
<li>Excel注解支持backgroundColor属性设置背景色</li>
<li>支持配置密码最大错误次数/锁定时间</li>
<li>登录日志新增解锁账户功能</li>
<li>通用下载方法新增config配置选项</li>
<li>支持多权限字符匹配角色数据权限</li>
<li>页面内嵌iframe切换tab不刷新数据</li>
<li>操作日志记录支持排除敏感属性字段</li>
<li>修复多文件上传报错出现的异常问题</li>
<li>修复图片预览组件src属性为null值控制台报错问题</li>
<li>升级oshi到最新版本6.2.2</li>
<li>升级fastjson到最新版2.0.14</li>
<li>升级pagehelper到最新版1.4.3</li>
<li>升级core-js到最新版本3.25.2</li>
<li>升级element-ui到最新版本2.15.10</li>
<li>优化任务过期不执行调度</li>
<li>优化字典数据使用store存取</li>
<li>优化修改资料头像被覆盖的问题</li>
<li>优化修改用户登录账号重复验证</li>
<li>优化代码生成同步后值NULL问题</li>
<li>优化定时任务支持执行父类方法</li>
<li>优化用户个人信息接口防止修改部门</li>
<li>优化布局设置使用el-drawer抽屉显示</li>
<li>优化没有权限的用户编辑部门缺少数据</li>
<li>优化日志注解记录限制请求地址的长度</li>
<li>优化excel/scale属性导出单元格数值类型</li>
<li>优化日志操作中重置按钮时重复查询的问题</li>
<li>优化多个相同角色数据导致权限SQL重复问题</li>
<li>优化表格上右侧工具条搜索按钮显隐&右侧样式凸出</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.8.3 - 2022-06-27">
<ol>
<li>新增缓存列表菜单功能</li>
<li>代码生成树表新增(展开/折叠)</li>
<li>Excel注解支持color字体颜色</li>
<li>新增Anonymous匿名访问不鉴权注解</li>
<li>用户头像上传限制只能为图片格式</li>
<li>接口使用泛型使其看到响应属性字段</li>
<li>检查定时任务bean所在包名是否为白名单配置</li>
<li>添加页签openPage支持传递参数</li>
<li>用户缓存信息添加部门ancestors祖级列表</li>
<li>升级element-ui到最新版本2.15.8</li>
<li>升级oshi到最新版本6.1.6</li>
<li>升级druid到最新版本1.2.11</li>
<li>升级fastjson到最新版2.0.8</li>
<li>升级spring-boot到最新版本2.5.14</li>
<li>降级jsencrypt版本兼容IE浏览器</li>
<li>删除多余的salt字段</li>
<li>新增获取不带后缀文件名称方法</li>
<li>新增获取配置文件中的属性值方法</li>
<li>新增内容编码/解码方便插件集成使用</li>
<li>字典类型必须以字母开头且只能为小写字母数字下滑线</li>
<li>优化设置分页参数默认值</li>
<li>优化对空字符串参数处理的过滤</li>
<li>优化显示顺序orderNum类型为整型</li>
<li>优化表单构建按钮不显示正则校验</li>
<li>优化字典数据回显样式下拉框显示值</li>
<li>优化R响应成功状态码与全局保持一致</li>
<li>优化druid开启wall过滤器出现的异常问题</li>
<li>优化用户管理左侧树型组件增加选中高亮保持</li>
<li>优化新增用户与角色信息&用户与岗位信息逻辑</li>
<li>优化默认不启用压缩文件缓存防止node_modules过大</li>
<li>修复字典数据显示不全问题</li>
<li>修复操作日志查询类型条件为0时会查到所有数据</li>
<li>修复Excel注解prompt/combo同时使用不生效问题</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.8.2 - 2022-04-01">
<ol>
<li>前端支持设置是否需要防止数据重复提交</li>
<li>开启TopNav没有子菜单情况隐藏侧边栏</li>
<li>侧边栏菜单名称过长悬停显示标题</li>
<li>用户访问控制时校验数据权限防止越权</li>
<li>导出Excel时屏蔽公式防止CSV注入风险</li>
<li>组件ImagePreview支持多图预览显示</li>
<li>组件ImageUpload支持多图同时选择上传</li>
<li>组件FileUpload支持多文件同时选择上传</li>
<li>服务监控新增运行参数信息显示</li>
<li>定时任务目标字符串过滤特殊字符</li>
<li>定时任务目标字符串验证包名白名单</li>
<li>代码生成列表图片支持预览</li>
<li>代码生成编辑修改打开新页签</li>
<li>代码生成新增Java类型Boolean</li>
<li>代码生成子表支持日期/字典配置</li>
<li>代码生成同步保留必填/类型选项</li>
<li>升级oshi到最新版本6.1.2</li>
<li>升级fastjson到最新版1.2.80</li>
<li>升级pagehelper到最新版1.4.1</li>
<li>升级spring-boot到最新版本2.5.11</li>
<li>升级spring-boot-mybatis到最新版2.2.2</li>
<li>添加遗漏的分页参数合理化属性</li>
<li>修改npm即将过期的注册源地址</li>
<li>修复分页组件请求两次问题</li>
<li>修复通用文件下载接口跨域问题</li>
<li>修复Xss注解字段值为空时的异常问题</li>
<li>修复选项卡点击右键刷新丢失参数问题</li>
<li>修复表单清除元素位置未垂直居中问题</li>
<li>修复服务监控中运行参数显示条件错误</li>
<li>修复导入Excel时字典字段类型为Long转义为空问题</li>
<li>修复登录超时刷新页面跳转登录页面还提示重新登录问题</li>
<li>优化加载字典缓存数据</li>
<li>优化IP地址获取到多个的问题</li>
<li>优化任务队列满时任务拒绝策略</li>
<li>优化文件上传兼容Weblogic环境</li>
<li>优化定时任务默认保存到内存中执行</li>
<li>优化部门修改缩放后出现的错位问题</li>
<li>优化Excel格式化不同类型的日期对象</li>
<li>优化菜单表关键字导致的插件报错问题</li>
<li>优化Oracle用户头像列为空时不显示问题</li>
<li>优化页面若未匹配到字典标签则返回原字典值</li>
<li>优化修复登录失效后多次请求提示多次弹窗问题</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.8.1 - 2022-01-01">
<ol>
<li>新增Vue3前端代码生成模板</li>
<li>新增图片预览组件</li>
<li>新增压缩插件实现打包Gzip</li>
<li>自定义xss校验注解实现</li>
<li>自定义文字复制剪贴指令</li>
<li>代码生成预览支持复制内容</li>
<li>路由支持单独配置菜单或角色权限</li>
<li>用户管理部门查询选择节点后分页参数初始</li>
<li>修复用户分配角色属性错误</li>
<li>修复打包后字体图标偶现的乱码问题</li>
<li>修复菜单管理重置表单出现的错误</li>
<li>修复版本差异导致的懒加载报错问题</li>
<li>修复Cron组件中周回显问题</li>
<li>修复定时任务多参数逗号分隔的问题</li>
<li>修复根据ID查询列表可能出现的主键溢出问题</li>
<li>修复tomcat配置参数已过期问题</li>
<li>升级clipboard到最新版本2.0.8</li>
<li>升级oshi到最新版本v5.8.6</li>
<li>升级fastjson到最新版1.2.79</li>
<li>升级spring-boot到最新版本2.5.8</li>
<li>升级log4j2到2.17.1防止漏洞风险</li>
<li>优化下载解析blob异常提示</li>
<li>优化代码生成字典组重复问题</li>
<li>优化查询用户的角色组&岗位组代码</li>
<li>优化定时任务cron表达式小时设置24</li>
<li>优化用户导入提示溢出则显示滚动条</li>
<li>优化防重复提交标识组合为(key+url+header)</li>
<li>优化分页方法设置成通用方便灵活调用</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.8.0 - 2021-12-01">
<ol>
<li>新增配套并同步的Vue3前端版本</li>
<li>新增通用方法简化模态/缓存/下载/权限/页签使用</li>
<li>优化导出数据/使用通用下载方法</li>
<li>Excel注解支持自定义数据处理器</li>
<li>Excel注解支持导入导出标题信息</li>
<li>Excel导入支持@Excels注解</li>
<li>新增组件data-dict简化数据字典使用</li>
<li>新增Jaxb依赖防止jdk8以上出现的兼容错误</li>
<li>生产环境使用路由懒加载提升页面响应速度</li>
<li>修复五级以上菜单出现的404问题</li>
<li>防重提交注解支持配置间隔时间/提示消息</li>
<li>日志注解新增是否保存响应参数</li>
<li>任务屏蔽违规字符&参数忽略双引号中的逗号</li>
<li>升级SpringBoot到最新版本2.5.6</li>
<li>升级pagehelper到最新版1.4.0</li>
<li>升级spring-boot-mybatis到最新版2.2.0</li>
<li>升级oshi到最新版本v5.8.2</li>
<li>升级druid到最新版1.2.8</li>
<li>升级velocity到最新版本2.3</li>
<li>升级fastjson到最新版1.2.78</li>
<li>升级axios到最新版本0.24.0</li>
<li>升级dart-sass到版本1.32.13</li>
<li>升级core-js到最新版本3.19.1</li>
<li>升级jsencrypt到最新版本3.2.1</li>
<li>升级js-cookie到最新版本3.0.1</li>
<li>升级file-saver到最新版本2.0.5</li>
<li>升级sass-loader到最新版本10.1.1</li>
<li>升级element-ui到最新版本2.15.6</li>
<li>新增sendGet无参请求方法</li>
<li>禁用el-tag组件的渐变动画</li>
<li>代码生成点击预览重置激活tab</li>
<li>AjaxResult重写put方法以方便链式调用</li>
<li>优化登录/验证码请求headers不设置token</li>
<li>优化用户个人信息接口防止修改用户名</li>
<li>优化Cron表达式生成器关闭时销毁避免缓存</li>
<li>优化注册成功提示消息类型success</li>
<li>优化aop语法使用spring自动注入注解</li>
<li>优化记录登录信息移除不必要的修改</li>
<li>优化mybatis全局默认的执行器</li>
<li>优化Excel导入图片可能出现的异常</li>
<li>修复代码生成模板主子表删除缺少事务</li>
<li>修复日志记录可能出现的转换异常</li>
<li>修复代码生成复选框字典遗漏问题</li>
<li>修复关闭xss功能导致可重复读RepeatableFilter失效</li>
<li>修复字符串无法被反转义问题</li>
<li>修复后端主子表代码模板方法名生成错误问题</li>
<li>修复xss过滤后格式出现的异常</li>
<li>修复swagger没有指定dataTypeClass导致启动出现warn日志</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.7.0 - 2021-09-13">
<ol>
<li>参数管理支持配置验证码开关</li>
<li>新增是否开启用户注册功能</li>
<li>定时任务支持在线生成cron表达式</li>
<li>菜单管理支持配置路由参数</li>
<li>支持自定义注解实现接口限流</li>
<li>Excel注解支持Image图片导入</li>
<li>自定义弹层溢出滚动样式</li>
<li>自定义可拖动弹窗宽度指令</li>
<li>自定义可拖动弹窗高度指令</li>
<li>修复任意账户越权问题</li>
<li>修改时检查用户数据权限范围</li>
<li>修复保存配置主题颜色失效问题</li>
<li>新增暗色菜单风格主题</li>
<li>菜单&部门新增展开/折叠功能</li>
<li>页签新增关闭左侧&添加图标</li>
<li>顶部菜单排除隐藏的默认路由</li>
<li>顶部菜单同步系统主题样式</li>
<li>跳转路由高亮相对应的菜单栏</li>
<li>代码生成主子表多选行数据</li>
<li>日期范围支持添加多组</li>
<li>升级element-ui到最新版本2.15.5</li>
<li>升级oshi到最新版本v5.8.0</li>
<li>升级commons.io到最新版本v2.11.0</li>
<li>定时任务屏蔽ldap远程调用</li>
<li>定时任务屏蔽http(s)远程调用</li>
<li>补充定时任务表字段注释</li>
<li>定时任务对检查异常进行事务回滚</li>
<li>启用父部门状态排除顶级节点</li>
<li>富文本新增上传文件大小限制</li>
<li>默认首页使用keep-alive缓存</li>
<li>修改代码生成字典回显样式</li>
<li>自定义分页合理化传入参数</li>
<li>修复字典组件值为整形不显示问题</li>
<li>修复定时任务日志执行状态显示</li>
<li>角色&菜单新增字段属性提示信息</li>
<li>修复角色分配用户页面参数类型错误提醒</li>
<li>优化布局设置动画特效</li>
<li>优化异常处理信息</li>
<li>优化错误token导致的解析异常</li>
<li>密码框新增显示切换密码图标</li>
<li>定时任务新增更多操作</li>
<li>更多操作按钮添加权限控制</li>
<li>导入用户样式优化</li>
<li>提取通用方法到基类控制器</li>
<li>优化使用权限工具获取用户信息</li>
<li>优化用户不能删除自己</li>
<li>优化XSS跨站脚本过滤</li>
<li>优化代码生成模板</li>
<li>验证码默认20s超时</li>
<li>BLOB下载时清除URL对象引用</li>
<li>代码生成导入表按创建时间排序</li>
<li>修复代码生成页面数据编辑保存之后总是跳转第一页的问题</li>
<li>修复带safari浏览器无法格式化utc日期格式yyyy-MM-dd'T'HH:mm:ss.SSS问题</li>
<li>多图上传组件移除多余的api地址&验证失败导致图片删除问题&无法删除相应图片修复</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.6.0 - 2021-07-12">
<ol>
<li>角色管理新增分配用户功能</li>
<li>用户管理新增分配角色功能</li>
<li>日志列表支持排序操作</li>
<li>优化参数&字典缓存操作</li>
<li>系统布局配置支持动态标题开关</li>
<li>菜单路由配置支持内链访问</li>
<li>默认访问后端首页新增提示语</li>
<li>富文本默认上传返回url类型</li>
<li>新增自定义弹窗拖拽指令</li>
<li>全局注册常用通用组件</li>
<li>全局挂载字典标签组件</li>
<li>ImageUpload组件支持多图片上传</li>
<li>FileUpload组件支持多文件上传</li>
<li>文件上传组件添加数量限制属性</li>
<li>富文本编辑组件添加类型属性</li>
<li>富文本组件工具栏配置视频</li>
<li>封装通用iframe组件</li>
<li>限制超级管理员不允许操作</li>
<li>用户信息长度校验限制</li>
<li>分页组件新增pagerCount属性</li>
<li>添加bat脚本执行应用</li>
<li>升级oshi到最新版本v5.7.4</li>
<li>升级element-ui到最新版本2.15.2</li>
<li>升级pagehelper到最新版1.3.1</li>
<li>升级commons.io到最新版本v2.10.0</li>
<li>升级commons.fileupload到最新版本v1.4</li>
<li>升级swagger到最新版本v3.0.0</li>
<li>修复关闭confirm提示框控制台报错问题</li>
<li>修复存在的SQL注入漏洞问题</li>
<li>定时任务屏蔽rmi远程调用</li>
<li>修复用户搜索分页变量错误</li>
<li>修复导出角色数据范围翻译缺少仅本人</li>
<li>修复表单构建选择下拉选择控制台报错问题</li>
<li>优化图片工具类读取文件</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.5.0 - 2021-05-25">
<ol>
<li>新增菜单导航显示风格TopNavfalse为左侧导航菜单true为顶部导航菜单</li>
<li>布局设置支持保存&重置配置</li>
<li>修复树表数据显示不全&加载慢问题</li>
<li>新增IE浏览器版本过低提示页面</li>
<li>用户登录后记录最后登录IP&时间</li>
<li>页面导出按钮点击之后添加遮罩</li>
<li>富文本编辑器支持自定义上传地址</li>
<li>富文本编辑组件新增readOnly属性</li>
<li>页签TagsView新增关闭右侧功能</li>
<li>显隐列组件加载初始默认隐藏列</li>
<li>关闭头像上传窗口还原默认图片</li>
<li>个人信息添加手机&邮箱重复验证</li>
<li>代码生成模板导出按钮点击后添加遮罩</li>
<li>代码生成模板树表操作列添加新增按钮</li>
<li>代码生成模板修复主子表字段重名问题</li>
<li>升级fastjson到最新版1.2.76</li>
<li>升级druid到最新版本v1.2.6</li>
<li>升级mybatis到最新版3.5.6 阻止远程代码执行漏洞</li>
<li>升级oshi到最新版本v5.6.0</li>
<li>velocity剔除commons-collections版本防止3.2.1版本的反序列化漏洞</li>
<li>数据监控页默认账户密码防止越权访问</li>
<li>修复firefox下表单构建拖拽会新打卡一个选项卡</li>
<li>修正后端导入表权限标识</li>
<li>修正前端操作日志&登录日志权限标识</li>
<li>设置Redis配置HashKey序列化</li>
<li>删除操作日志记录信息</li>
<li>上传媒体类型添加视频格式</li>
<li>修复请求形参未传值记录日志异常问题</li>
<li>优化xss校验json请求条件</li>
<li>树级结构更新子节点使用replaceFirst</li>
<li>优化ExcelUtil空值处理</li>
<li>日志记录过滤BindingResult对象防止异常</li>
<li>修改主题后mini类型按钮无效问题</li>
<li>优化通用下载完成后删除节点</li>
<li>通用Controller添加响应返回消息</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.4.0 - 2021-02-22">
<ol>
<li>代码生成模板支持主子表</li>
<li>表格右侧工具栏组件支持显隐列</li>
<li>图片组件添加预览&移除功能</li>
<li>Excel注解支持Image图片导出</li>
<li>操作按钮组调整为朴素按钮样式</li>
<li>代码生成支持文件上传组件</li>
<li>代码生成日期控件区分范围</li>
<li>代码生成数据库文本类型生成表单文本域</li>
<li>用户手机邮箱&菜单组件修改允许空字符串</li>
<li>升级SpringBoot到最新版本2.2.13 提升启动速度</li>
<li>升级druid到最新版本v1.2.4</li>
<li>升级fastjson到最新版1.2.75</li>
<li>升级element-ui到最新版本2.15.0</li>
<li>修复IE11浏览器报错问题</li>
<li>优化多级菜单之间切换无法缓存的问题</li>
<li>修复四级菜单无法显示问题</li>
<li>修正侧边栏静态路由丢失问题</li>
<li>修复角色管理-编辑角色-功能权限显示异常</li>
<li>配置文件新增redis数据库索引属性</li>
<li>权限工具类增加admin判断</li>
<li>角色非自定义权限范围清空选择值</li>
<li>修复导入数据为负浮点数时丢失精度问题</li>
<li>移除path-to-regexp正则匹配插件</li>
<li>修复生成树表代码异常</li>
<li>修改ip字段长度防止ipv6地址长度不够</li>
<li>防止get请求参数值为false或0等特殊值会导致无法正确的传参</li>
<li>登录后push添加catch防止出现检查错误</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.3.0 - 2020-12-14">
<ol>
<li>新增缓存监控功能</li>
<li>支持主题风格配置</li>
<li>修复多级菜单之间切换无法缓存的问题</li>
<li>多级菜单自动配置组件</li>
<li>代码生成预览支持高亮显示</li>
<li>支持Get请求映射Params参数</li>
<li>删除用户和角色解绑关联</li>
<li>去除用户手机邮箱部门必填验证</li>
<li>Excel支持注解align对齐方式</li>
<li>Excel支持导入Boolean型数据</li>
<li>优化头像样式鼠标移入悬停遮罩</li>
<li>代码生成预览提供滚动机制</li>
<li>代码生成删除多余的数字float类型</li>
<li>修正转换字符串的目标字符集属性</li>
<li>回显数据字典防止空值报错</li>
<li>日志记录增加过滤多文件场景</li>
<li>修改缓存Set方法可能导致嵌套的问题</li>
<li>移除前端一些多余的依赖</li>
<li>防止安全扫描YUI出现的风险提示</li>
<li>修改node-sass为dart-sass</li>
<li>升级SpringBoot到最新版本2.1.18</li>
<li>升级poi到最新版本4.1.2</li>
<li>升级oshi到最新版本v5.3.6</li>
<li>升级bitwalker到最新版本1.21</li>
<li>升级axios到最新版本0.21.0</li>
<li>升级element-ui到最新版本2.14.1</li>
<li>升级vue到最新版本2.6.12</li>
<li>升级vuex到最新版本3.6.0</li>
<li>升级vue-cli到版本4.5.9</li>
<li>升级vue-router到最新版本3.4.9</li>
<li>升级vue-cli到最新版本4.4.6</li>
<li>升级vue-cropper到最新版本0.5.5</li>
<li>升级clipboard到最新版本2.0.6</li>
<li>升级core-js到最新版本3.8.1</li>
<li>升级echarts到最新版本4.9.0</li>
<li>升级file-saver到最新版本2.0.4</li>
<li>升级fuse.js到最新版本6.4.3</li>
<li>升级js-beautify到最新版本1.13.0</li>
<li>升级js-cookie到最新版本2.2.1</li>
<li>升级path-to-regexp到最新版本6.2.0</li>
<li>升级quill到最新版本1.3.7</li>
<li>升级screenfull到最新版本5.0.2</li>
<li>升级sortablejs到最新版本1.10.2</li>
<li>升级vuedraggable到最新版本2.24.3</li>
<li>升级chalk到最新版本4.1.0</li>
<li>升级eslint到最新版本7.15.0</li>
<li>升级eslint-plugin-vue到最新版本7.2.0</li>
<li>升级lint-staged到最新版本10.5.3</li>
<li>升级runjs到最新版本4.4.2</li>
<li>升级sass-loader到最新版本10.1.0</li>
<li>升级script-ext-html-webpack-plugin到最新版本2.1.5</li>
<li>升级svg-sprite-loader到最新版本5.1.1</li>
<li>升级vue-template-compiler到最新版本2.6.12</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.2.1 - 2020-11-18">
<ol>
<li>阻止任意文件下载漏洞</li>
<li>代码生成支持上传控件</li>
<li>新增图片上传组件</li>
<li>调整默认首页</li>
<li>升级druid到最新版本v1.2.2</li>
<li>mapperLocations配置支持分隔符</li>
<li>权限信息调整</li>
<li>调整sql默认时间</li>
<li>解决代码生成没有bit类型的问题</li>
<li>升级pagehelper到最新版1.3.0</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.2.0 - 2020-10-10">
<ol>
<li>升级springboot版本到2.1.17 提升安全性</li>
<li>升级oshi到最新版本v5.2.5</li>
<li>升级druid到最新版本v1.2.1</li>
<li>升级jjwt到版本0.9.1</li>
<li>升级fastjson到最新版1.2.74</li>
<li>修改sass为node-sass避免el-icon图标乱码</li>
<li>代码生成支持同步数据库</li>
<li>代码生成支持富文本控件</li>
<li>代码生成页面时不忽略remark属性</li>
<li>代码生成添加select必填选项</li>
<li>Excel导出类型NUMERIC支持精度浮点类型</li>
<li>Excel导出targetAttr优化获取值防止get方法不规范</li>
<li>Excel注解支持自动统计数据总和</li>
<li>Excel注解支持设置BigDecimal精度&舍入规则</li>
<li>菜单&数据权限新增展开/折叠 全选/全不选 父子联动</li>
<li>允许用户分配到部门父节点</li>
<li>菜单新增是否缓存keep-alive</li>
<li>表格操作列间距调整</li>
<li>限制系统内置参数不允许删除</li>
<li>富文本组件优化支持自定义高度&图片冲突问题</li>
<li>富文本工具栏样式对齐</li>
<li>导入excel整形值校验优化</li>
<li>修复页签关闭所有时固定标签路由不刷新问题</li>
<li>表单构建布局型组件新增按钮</li>
<li>左侧菜单文字过长显示省略号</li>
<li>修正根节点为子部门时树状结构显示问题</li>
<li>修正调用目标字符串最大长度</li>
<li>修正菜单提示信息错误</li>
<li>修正定时任务执行一次权限标识</li>
<li>修正数据库字符串类型nvarchar</li>
<li>优化递归子节点</li>
<li>优化数据权限判断</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.1.0 - 2020-08-13">
<ol>
<li>表格工具栏右侧添加刷新&显隐查询组件</li>
<li>后端支持CORS跨域请求</li>
<li>代码生成支持选择上级菜单</li>
<li>代码生成支持自定义路径</li>
<li>代码生成支持复选框</li>
<li>Excel导出导入支持dictType字典类型</li>
<li>Excel支持分割字符串组内容</li>
<li>验证码类型支持数组计算字符验证</li>
<li>升级vue-cli版本到4.4.4</li>
<li>修改 node-sass dart-sass</li>
<li>表单类型为Integer/Long设置整形默认值</li>
<li>代码生成器默认mapper路径与默认mapperScan路径不一致</li>
<li>优化防重复提交拦截器</li>
<li>优化上级菜单不能选择自己</li>
<li>修复角色的权限分配后未实时生效问题</li>
<li>修复在线用户日志记录类型</li>
<li>修复富文本空格和缩进保存后不生效问题</li>
<li>修复在线用户判断逻辑</li>
<li>唯一限制条件只返回单条数据</li>
<li>添加获取当前的环境配置方法</li>
<li>超时登录后页面跳转到首页</li>
<li>全局异常状态汉化拦截处理</li>
<li>HTML过滤器改为将html转义</li>
<li>检查字符支持小数点&降级改成异常提醒</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.0.0 - 2020-07-20">
<ol>
<li>单应用调整为多模块项目</li>
<li>升级element-ui版本到2.13.2</li>
<li>删除babel提高编译速度</li>
<li>新增菜单默认主类目</li>
<li>编码文件名修改为uuid方式</li>
<li>定时任务cron表达式验证</li>
<li>角色权限修改时已有权限未自动勾选异常修复</li>
<li>防止切换权限用户后登录出现404</li>
<li>Excel支持sort导出排序</li>
<li>创建用户不允许选择超级管理员角色</li>
<li>修复代码生成导入表结构出现异常页面不提醒问题</li>
<li>修复代码生成点击多次表修改数据不变化的问题</li>
<li>修复头像上传成功二次打开无法改变裁剪框大小和位置问题</li>
<li>修复布局为small者mini用户表单显示错位问题</li>
<li>修复热部署导致的强换异常问题</li>
<li>修改用户管理复选框宽度防止部分浏览器出现省略号</li>
<li>IpUtils工具清除Xss特殊字符防止Xff注入攻击</li>
<li>生成domain 如果是浮点型 统一用BigDecimal</li>
<li>定时任务调整label-width防止部署出现错位</li>
<li>调整表头固定列默认样式</li>
<li>代码生成模板调整字段为String并且必填则加空串条件</li>
<li>代码生成字典Integer/Long使用parseInt</li>
<li>
修复dict_sort不可update为0的问题&查询返回增加dict_sort升序排序
</li>
<li>修正岗位导出权限注解</li>
<li>禁止加密密文返回前端</li>
<li>修复代码生成页面中的查询条件创建时间未生效的问题</li>
<li>修复首页搜索菜单外链无法点击跳转问题</li>
<li>修复菜单管理选择图标backspace删除时不过滤数据</li>
<li>用户管理部门分支节点不可检查&显示计数</li>
<li>数据范围过滤属性调整</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v2.3.0 - 2020-06-01">
<ol>
<li>升级fastjson到最新版1.2.70 修复高危安全漏洞</li>
<li>dev启动默认打开浏览器</li>
<li>vue-cli使用默认source-map</li>
<li>slidebar eslint报错优化</li>
<li>当tags-view滚动关闭右键菜单</li>
<li>字典管理添加缓存读取</li>
<li>参数管理支持缓存操作</li>
<li>支持一级菜单和主页同级在main区域显示</li>
<li>限制外链地址必须以http(s)开头</li>
<li>tagview & sidebar 主题颜色与element ui(全局)同步</li>
<li>修改数据源类型优先级先根据方法再根据类</li>
<li>支持是否需要设置token属性自定义返回码消息</li>
<li>swagger请求前缀加入配置</li>
<li>登录地点设置内容过长则隐藏显示</li>
<li>修复定时任务执行一次按钮后不提示消息问题</li>
<li>修改上级部门选择项排除本身和下级</li>
<li>通用http发送方法增加参数 contentType 编码类型</li>
<li>更换IP地址查询接口</li>
<li>修复页签变量undefined</li>
<li>添加校验部门包含未停用的子部门</li>
<li>修改定时任务详情下次执行时间日期显示错误</li>
<li>角色管理查询设置默认排序字段</li>
<li>swagger添加enable参数控制是否启用</li>
<li>只对json类型请求构建可重复读取inputStream的request</li>
<li>修改代码生成字典字段int类型没有自动选中问题</li>
<li>vuex用户名取值修正</li>
<li>表格树模板去掉多余的)</li>
<li>代码生成序号修正</li>
<li>全屏情况下不调整上外边距</li>
<li>代码生成Date字段添加默认格式</li>
<li>用户管理角色选择权限控制</li>
<li>修复路由懒加载报错问题</li>
<li>模板sql.vm添加菜单状态</li>
<li>设置用户名称不能修改</li>
<li>dialog添加append-to-body属性防止ie遮罩</li>
<li>菜单区分状态和显示隐藏功能</li>
<li>升级fastjson到最新版1.2.68 修复安全加固</li>
<li>修复代码生成如果选择字典类型缺失逗号问题</li>
<li>登录请求params更换为data防止暴露url</li>
<li>日志返回时间格式处理</li>
<li>添加handle控制允许拖动的元素</li>
<li>布局设置点击扩大范围</li>
<li>代码生成列属性排序查询</li>
<li>代码生成列支持拖动排序</li>
<li>修复时间格式不支持ios问题</li>
<li>表单构建添加父级class防止冲突</li>
<li>定时任务并发属性修正</li>
<li>角色禁用&菜单隐藏不查询权限</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v2.2.0 - 2020-03-18">
<ol>
<li>系统监控新增定时任务功能</li>
<li>添加一个打包Web工程bat</li>
<li>修复页签鼠标滚轮按下的时候可以关闭不可关闭的tag</li>
<li>修复点击退出登录有时会无提示问题</li>
<li>修复防重复提交注解无效问题</li>
<li>修复通知公告批量删除异常问题</li>
<li>添加菜单时路由地址必填限制</li>
<li>代码生成字段描述可编辑</li>
<li>修复用户修改个人信息导致缓存不过期问题</li>
<li>个人信息创建时间获取正确属性值</li>
<li>操作日志详细显示正确类型</li>
<li>导入表单击行数据时选中对应的复选框</li>
<li>批量替换表前缀逻辑调整</li>
<li>固定重定向路径表达式</li>
<li>升级element-ui版本到2.13.0</li>
<li>操作日志排序调整</li>
<li>修复charts切换侧边栏或者缩放窗口显示bug</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v2.1.0 - 2020-02-24">
<ol>
<li>新增表单构建</li>
<li>代码生成支持树表结构</li>
<li>新增用户导入</li>
<li>修复动态加载路由页面刷新问题</li>
<li>修复地址开关无效问题</li>
<li>汉化错误提示页面</li>
<li>代码生成已知问题修改</li>
<li>修复多数据源下配置关闭出现异常处理</li>
<li>添加HTML过滤器用于去除XSS漏洞隐患</li>
<li>修复上传头像控制台出现异常</li>
<li>修改用户管理分页不正确的问题</li>
<li>修复验证码记录提示错误</li>
<li>修复request.js缺少Message引用</li>
<li>修复表格时间为空出现的异常</li>
<li>添加Jackson日期反序列化时区配置</li>
<li>调整根据用户权限加载菜单数据树形结构</li>
<li>调整成功登录不恢复按钮防止多次点击</li>
<li>修改用户个人资料同步缓存信息</li>
<li>修复页面同时出现el-upload和Editor不显示处理</li>
<li>修复在角色管理页修改菜单权限偶尔未选中问题</li>
<li>配置文件新增redis密码属性</li>
<li>设置mybatis全局的配置文件</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v2.0.0 - 2019-12-02">
<ol>
<li>新增代码生成</li>
<li>新增@RepeatSubmit注解防止重复提交</li>
<li>新增菜单主目录添加/删除操作</li>
<li>日志记录过滤特殊对象防止转换异常</li>
<li>修改代码生成路由脚本错误</li>
<li>用户上传头像实时同步缓存无需重新登录</li>
<li>调整切换页签后不重新加载数据</li>
<li>添加jsencrypt实现参数的前端加密</li>
<li>系统退出删除用户缓存记录</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v1.1.0 - 2019-11-11">
<ol>
<li>新增在线用户管理</li>
<li>新增按钮组功能实现批量删除导出清空</li>
<li>新增查询条件重置按钮</li>
<li>新增Swagger全局Token配置</li>
<li>新增后端参数校验</li>
<li>修复字典管理页面的日期查询异常</li>
<li>修改时间函数命名防止冲突</li>
<li>去除菜单上级校验默认为顶级</li>
<li>修复用户密码无法修改问题</li>
<li>修复菜单类型为按钮时不显示权限标识</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v1.0.0 - 2019-10-08">
<ol>
<li>若依前后端分离系统正式发布</li>
</ol>
</el-collapse-item>
</el-collapse>
</el-card>
</el-col>
<el-col :xs="24" :sm="24" :md="12" :lg="8">
<el-card class="update-log">
<div slot="header" class="clearfix">
<span>捐赠支持</span>
</div>
<div class="body">
<img
src="@/assets/images/pay.png"
alt="donate"
width="100%"
/>
<span style="display: inline-block; height: 30px; line-height: 30px"
>你可以请作者喝杯咖啡表示鼓励</span
>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: "Index",
name: 'Index',
data() {
return {
//
version: "3.8.6"
};
}
},
methods: {
goTarget(href) {
window.open(href, "_blank");
window.open(href, '_blank')
}
}
};
}
</script>
<style scoped lang="scss">
<style lang="scss" scoped>
.home {
blockquote {
padding: 10px 20px;
@ -965,12 +28,14 @@ export default {
font-size: 17.5px;
border-left: 5px solid #eee;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eee;
}
.col-item {
margin-bottom: 20px;
}

View File

@ -0,0 +1,294 @@
<template>
<div class="app-container home">
<div class="home-header">
<div class="home-header-left">
<h1>项目列表</h1>
</div>
<div class="home-header-right">
<el-input
v-model="queryParams.appName"
class="search-input mr10"
placeholder="请输入关键字"
clearable
@keyup.enter.native="getList"
>
<el-button slot="append" icon="el-icon-search" @click="getList"></el-button>
</el-input>
<el-button-group class="mr10">
<el-button :type="curType === 'card' ? 'primary' : 'default'" icon="el-icon-postcard" @click="checkType('card')">卡片</el-button>
<el-button :type="curType === 'list' ? 'primary' : 'default'" icon="el-icon-notebook-2" @click="checkType('list')">列表</el-button>
</el-button-group>
<el-button type="primary" @click="handleAdd(null)">新增项目</el-button>
</div>
</div>
<!-- <transition name="slide-fade"> -->
<component :is="curType === 'card' ? 'CardView' : 'ListView'"
:list="list"
:loading="loading"
@update="handleAdd"
@del="handleDelete"
@enter="handleEnter"
/>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- </transition> -->
<el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible" center :before-close="dialogBeforeClose">
<el-form ref="form" :model="editForm" :rules="rules">
<el-form-item label="应用名称" label-width="120px" prop="appName">
<el-input v-model="editForm.appName" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="应用描述" label-width="120px" prop="appDesc">
<el-input v-model="editForm.appDesc" autocomplete="off" type="textarea" :rows="3"></el-input>
</el-form-item>
<el-form-item label="上传图片" label-width="120px" prop="picture">
<ImageUpload v-model="editForm.picture" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogClose"> </el-button>
<el-button type="primary" :loading="submitLoading" @click="submitForm"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import CardView from './components/home/card';
import ListView from './components/home/list';
import { getListApi, getListDetail, delList, addList, updateList } from "@/api/system/application";
export default {
name: "Index",
components: {
CardView,
ListView,
},
data() {
return {
loading: false,
curType: 'card',
queryParams: {
pageNum: 1,
pageSize: 10,
},
total: 0,
list: [],
dialogFormVisible: false,
dialogTitle: '新增应用',
//
rules: {
appName: [
{ required: true, message: "应用名称不能为空", trigger: "blur" }
],
appDesc: [
{ required: true, message: "应用描述不能为空", trigger: "blur" }
],
},
editForm: {
id: null,
appName: '',
appDesc: '',
picture: '',
},
submitLoading: false,
}
},
computed: {
routes() {
return this.$store.state.permission.addRoutes;
},
},
async created() {
// this.$store.dispatch('app/toggleSideBarHide', true);
if (this.routes.length === 0) {
let routes = await this.$store.dispatch('GenerateRoutes');
this.$router.addRoutes(routes)
}
this.getList();
},
watch: {
$route(route) {
// this.$store.dispatch('app/toggleSideBarHide', route.path === '/index');
}
},
methods: {
/** 查询应用列列表 */
getList() {
this.loading = true;
getListApi(this.queryParams).then(response => {
console.log(response)
this.list = response.rows;
this.total = response.total;
this.loading = false;
}).catch(() => {
this.loading = false;
});
},
checkType(type) {
this.curType = type;
},
dialogBeforeClose(done) {
this.$refs.form.resetFields();
done();
},
dialogClose() {
this.$refs.form.resetFields();
this.dialogFormVisible = false;
},
// getList(params) {
// return new Promise((resolve, reject) => {
// setTimeout(() => {
// const num = Math.floor(Math.random() * 10);
// const ls = new Array(num).fill(0).map((v,i) => {
// return {
// id: Math.random(),
// name: `${i}`,
// desc: `${i}${i}${i}`,
// createTime: `2024-04-${i + 1}`,
// img: "https://img.yzcdn.cn/vant/cat.jpeg",
// };
// });
// return resolve({
// code: 200,
// data: {
// list: ls,
// total: 86,
// }
// });
// }, 1000);
// });
// },
async handleEnter(row) {
this.$store.dispatch('SetApplication', row);
let routes = this.routes;
if (this.routes.length === 0) {
routes = await this.$store.dispatch('GenerateRoutes');
this.$router.addRoutes(routes)
}
const [first, secound] = routes;
const route = this.resolvePath(first, first.path);
this.$router.push(route);
},
resolvePath(route, basepath) {
if (isExternal(basepath)) {
return basepath;
}
const childRoute = route.children && route.children[0];
if (childRoute) {
return path.resolve(basepath, childRoute.path);
}
return path.resolve(basepath);
},
handleAdd(row) {
if (!row) {
this.editForm = {
id: null,
appName: '',
appDesc: '',
picture: '',
}
this.dialogTitle = '新增应用';
} else {
this.editForm = {
id: row.id,
appName: row.appName,
appDesc: row.appDesc,
picture: row.picture,
}
this.dialogTitle = '编辑应用';
}
this.dialogFormVisible = true;
},
async handleDelete(row) {
this.$confirm('此操作将永久删除该应用, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
beforeClose: (action, instance, done) => {
if (action === 'confirm') {
instance.confirmButtonLoading = true;
this.delFunc(row.id).then(done).finally(() => {
instance.confirmButtonLoading = false;
})
} else {
done();
}
}
});
},
async delFunc(id) {
try {
const res = await delList(id);
this.$message.success('删除成功');
this.getList();
return res;
} catch(e) {
this.$message.error('删除失败');
return Promise.reject(e);
}
},
/** 提交按钮 */
async submitForm() {
await this.$refs["form"].validate();
const data = Object.assign({},this.editForm);
const request = data.id ? updateList : addList;
const msg = data.id ? '修改' : '新增';
this.submitLoading = true;
try {
const { code } = await request(data);
this.$modal.msgSuccess(`${msg}成功!`);
this.submitLoading = false;
this.getList();
this.dialogClose();
} catch (error) {
this.$modal.msgSuccess(`${msg}成功!`);
this.submitLoading = false;
}
},
}
}
</script>
<style lang="scss" scoped>
.top-btn {
display: flex;
justify-content: flex-end;
}
.home-header {
display: flex;
justify-content: space-between;
align-items: center;
.search-input {
width: 240px;
}
}
/* slide-fade 过渡效果的 CSS 类定义 */
.slide-fade-enter-active,
.slide-fade-leave-active {
transition: all 0.8s ease;
}
.slide-fade-leave-active {
position: absolute;
}
.slide-fade-enter-from,
.slide-fade-leave-to {
transform: translateX(-100%); /* 左滑出效果,若需右滑入则改为 translateX(100%) */
opacity: 0;
}
.slide-fade-enter-to,
.slide-fade-leave-from {
transform: translateX(0);
opacity: 1;
}
</style>

View File

@ -1,7 +1,7 @@
<template>
<div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<h3 class="title">若依后台管理系统</h3>
<h3 class="title">SAC后台管理系统</h3>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
@ -73,7 +73,7 @@ export default {
codeUrl: "",
loginForm: {
username: "admin",
password: "admin123",
password: "abc&^321",
rememberMe: false,
code: "",
uuid: ""

View File

@ -1,7 +1,7 @@
<template>
<div class="register">
<el-form ref="registerForm" :model="registerForm" :rules="registerRules" class="register-form">
<h3 class="title">若依后台管理系统</h3>
<h3 class="title">SAC后台管理系统</h3>
<el-form-item prop="username">
<el-input v-model="registerForm.username" type="text" auto-complete="off" placeholder="账号">
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />

View File

@ -0,0 +1,405 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="商品编号" prop="goodsCode">
<el-input
v-model="queryParams.goodsCode"
placeholder="请输入商品编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="审核状态" prop="reviewStatus">
<el-select v-model="queryParams.reviewStatus" placeholder="请选择审核状态" clearable>
<el-option
v-for="dict in dict.type.goods_review_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="商品标题" prop="productTitle">
<el-input
v-model="queryParams.productTitle"
placeholder="请输入商品标题"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="商品原价" prop="originalPrice">
<el-input
v-model="queryParams.originalPrice"
placeholder="请输入商品原价"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="商品类型" prop="goodsType">
<el-select v-model="queryParams.goodsType" placeholder="请选择商品类型" clearable>
<el-option
v-for="dict in dict.type.goods_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="商品规格" prop="goodsSpec">
<el-input
v-model="queryParams.goodsSpec"
placeholder="请输入商品规格"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="商品型号" prop="goodsModel">
<el-input
v-model="queryParams.goodsModel"
placeholder="请输入商品型号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['service:goods:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="el-icon-edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['service:goods:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="el-icon-delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['service:goods:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="el-icon-download"
size="mini"
@click="handleExport"
v-hasPermi="['service:goods:export']"
>导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="goodsList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键" align="center" prop="id" />
<el-table-column label="商品编号" align="center" prop="goodsCode" />
<el-table-column label="审核状态" align="center" prop="reviewStatus">
<template slot-scope="scope">
<dict-tag :options="dict.type.goods_review_status" :value="scope.row.reviewStatus"/>
</template>
</el-table-column>
<el-table-column label="商品标题" align="center" prop="productTitle" />
<el-table-column label="商品图片" align="center" prop="productPicture" width="100">
<template slot-scope="scope">
<image-preview :src="scope.row.productPicture" :width="50" :height="50"/>
</template>
</el-table-column>
<el-table-column label="商品原价" align="center" prop="originalPrice" />
<el-table-column label="商品描述" align="center" prop="productDesc" />
<el-table-column label="商品类型" align="center" prop="goodsType">
<template slot-scope="scope">
<dict-tag :options="dict.type.goods_type" :value="scope.row.goodsType"/>
</template>
</el-table-column>
<el-table-column label="商品规格" align="center" prop="goodsSpec" />
<el-table-column label="商品型号" align="center" prop="goodsModel" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['service:goods:edit']"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['service:goods:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改商品信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="商品编号" prop="goodsCode">
<el-input v-model="form.goodsCode" placeholder="请输入商品编号" />
</el-form-item>
<el-form-item label="审核状态" prop="reviewStatus">
<el-radio-group v-model="form.reviewStatus">
<el-radio
v-for="dict in dict.type.goods_review_status"
:key="dict.value"
:label="parseInt(dict.value)"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="商品标题" prop="productTitle">
<el-input v-model="form.productTitle" placeholder="请输入商品标题" />
</el-form-item>
<el-form-item label="商品图片" prop="productPicture">
<image-upload v-model="form.productPicture"/>
</el-form-item>
<el-form-item label="商品原价" prop="originalPrice">
<el-input v-model="form.originalPrice" placeholder="请输入商品原价" />
</el-form-item>
<el-form-item label="商品描述" prop="productDesc">
<el-input v-model="form.productDesc" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="商品类型" prop="goodsType">
<el-radio-group v-model="form.goodsType">
<el-radio
v-for="dict in dict.type.goods_type"
:key="dict.value"
:label="parseInt(dict.value)"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="商品规格" prop="goodsSpec">
<el-input v-model="form.goodsSpec" placeholder="请输入商品规格" />
</el-form-item>
<el-form-item label="排序" prop="orderNum">
<el-input v-model="form.orderNum" placeholder="请输入排序" />
</el-form-item>
<el-form-item label="商品型号" prop="goodsModel">
<el-input v-model="form.goodsModel" placeholder="请输入商品型号" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listGoods, getGoods, delGoods, addGoods, updateGoods } from "@/api/service/goods";
export default {
name: "Goods",
dicts: ['goods_review_status', 'goods_type'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
goodsList: [],
//
title: "",
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
goodsCode: null,
reviewStatus: null,
productTitle: null,
originalPrice: null,
goodsType: null,
goodsSpec: null,
goodsModel: null
},
//
form: {},
//
rules: {
goodsCode: [
{ required: true, message: "商品编号不能为空", trigger: "blur" }
],
reviewStatus: [
{ required: true, message: "审核状态不能为空", trigger: "change" }
],
productTitle: [
{ required: true, message: "商品标题不能为空", trigger: "blur" }
],
productPicture: [
{ required: true, message: "商品图片不能为空", trigger: "blur" }
],
originalPrice: [
{ required: true, message: "商品原价不能为空", trigger: "blur" }
],
goodsType: [
{ required: true, message: "商品类型不能为空", trigger: "change" }
],
goodsSpec: [
{ required: true, message: "商品规格不能为空", trigger: "blur" }
],
goodsModel: [
{ required: true, message: "商品型号不能为空", trigger: "blur" }
]
}
};
},
created() {
this.getList();
},
methods: {
/** 查询商品信息列表 */
getList() {
this.loading = true;
listGoods(this.queryParams).then(response => {
this.goodsList = response.rows;
this.total = response.total;
this.loading = false;
});
},
//
cancel() {
this.open = false;
this.reset();
},
//
reset() {
this.form = {
id: null,
goodsCode: null,
stockId: null,
reviewStatus: null,
productTitle: null,
productPicture: null,
originalPrice: null,
productDesc: null,
goodsType: null,
goodsSpec: null,
orderNum: null,
isDelete: null,
created: null,
modified: null,
createTime: null,
updateTime: null,
goodsName: null,
goodsModel: null
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加商品信息";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getGoods(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改商品信息";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != null) {
let data = Object.assign({},this.form)
delete data.explain
updateGoods(data).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
});
} else {
addGoods(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids;
this.$modal.confirm('是否确认删除商品信息编号为"' + ids + '"的数据项?').then(function() {
return delGoods(ids);
}).then(() => {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
},
/** 导出按钮操作 */
handleExport() {
this.download('service/goods/export', {
...this.queryParams
}, `goods_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@ -7,7 +7,7 @@ function resolve(dir) {
const CompressionPlugin = require('compression-webpack-plugin')
const name = process.env.VUE_APP_TITLE || '若依管理系统' // 网页标题
const name = process.env.VUE_APP_TITLE || 'SAC管理系统' // 网页标题
const port = process.env.port || process.env.npm_config_port || 80 // 端口
@ -18,7 +18,7 @@ module.exports = {
// 部署生产环境和开发环境下的URL。
// 默认情况下Vue CLI 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
publicPath: process.env.NODE_ENV === 'production' ? '/' : '/',
// 在npm run build 或 yarn build 时 生成文件的目录名称要和baseUrl的生产环境路径一致默认dist
outputDir: 'dist',
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
@ -35,7 +35,8 @@ module.exports = {
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://localhost:7781`,
// target: `http://192.168.1.23:22009`,
target: `http://f6ther.natappfree.cc`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
@ -47,7 +48,7 @@ module.exports = {
css: {
loaderOptions: {
sass: {
sassOptions: { outputStyle: "expanded" }
sassOptions: { outputStyle: 'expanded' }
}
}
},
@ -67,7 +68,7 @@ module.exports = {
algorithm: 'gzip', // 使用gzip压缩
minRatio: 0.8 // 压缩率小于1才会压缩
})
],
]
},
chainWebpack(config) {
config.plugins.delete('preload') // TODO: need test
@ -91,44 +92,44 @@ module.exports = {
.end()
config.when(process.env.NODE_ENV !== 'development', config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}])
.end()
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}])
.end()
config.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single'),
{
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
to: './' //到根目录下
config.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single'),
{
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
to: './' //到根目录下
}
})
}
}