主页面
图片回显
<vxe-column field="icon" title="应用图标" align="center">
<template slot-scope="scope">
<el-image style="height: 40px;width: 40px;" :src="scope.row.icon"></el-image>
</template>
</vxe-column>
主界面打开dialog的form表单
//添加应用
private addApplication() {
;(this.$refs.addUpdateApplication as any).dialogVisible = true
;(this.$refs.addUpdateApplication as any).editMode = false
}
表单页面
form表单的upload写法
public dialogVisible: Boolean = false
public editMode: Boolean = false
<el-form-item label="应用图标">
<el-upload class="upload-demo" ref="upload" action="" :on-remove="handleRemove" :file-list="file_list" :on-change="getFile" :auto-upload="false" list-type="picture" :limit="1">
<el-button size="small" type="primary">上传应用图标</el-button>
</el-upload>
</el-form-item>
</el-form>
file数据
fileList数据
//存图片
private file_list: any[] = []
// 移除上传的文件时的回调
private handleRemove() {
this.form.icon = ''
this.$delete(this.file_list, 0)
}
//清除表单数据
private clearForm() {
this.form = {}
this.form.appPaltform = 'pc'
this.$delete(this.file_list, 0)
}
// 图片转base64
private getBase64(file) {
return new Promise(function(resolve, reject) {
let reader = new FileReader()
let imgResult = ''
reader.readAsDataURL(file)
reader.onload = function() {
imgResult = reader.result as any
}
reader.onerror = function(error) {
reject(error)
}
reader.onloadend = function() {
resolve(imgResult)
}
})
}
//文件变化事件
// 当文件状态改变、添加文件、上传成功和上传失败时调用
private getFile(file, fileList) {
//获取5.png的 png字符串
let fileType = file.name.substring(file.name.lastIndexOf('.') + 1)
//限制图片大小
let fileSize = file.size / 1024 / 1024 < 5
//如果图片格式不是png/jpg或者jpeg
if (fileType !== 'png' && fileType !== 'jpg' && fileType !== 'jpeg') {
//清空已上传的文件列表(该方法不支持在 before-upload 中调用)
;(this.$refs.upload as any).clearFiles()
this.$message.warning('上传文件只能是 .png、.jpg、jpeg格式!')
return false
//如果尺寸不对
} else if (!fileSize) {
;(this.$refs.upload as any).clearFiles()
this.$message.warning('上传文件大小不能超过 5MB!')
return false
} else {
//转base64
this.getBase64(file.raw).then((res) => {
//res就是图片的地址
//把图片地址放到form里,调接口再传
this.form.icon = res
})
}
}
表单确认
//编辑/添加应用
private async upload() {
;(this.$refs['form'] as any).validate(async (valid) => {
if (valid) {
let res = await AddOrUpdateApplication(this.form)
this.handleClose()
} else {
this.$message.warning('表单不符合要求')
return false
}
})
}
以下是全部代码
1.主页面
<template>
<div style="height: 100%;width: 100%;position: relative;">
<div class="table-frame showApp-list">
<!-- 应用展示 -->
<div class="showApp_title">
<span style="display:inline-block;margin-left:0.5%">应用展示</span>
</div>
<div class="showApp_Container">
<div class="appCard" v-for="item in tableData" :key="item.id">
<div class="card-imgContainer">
<img :src="item.icon" @click="clickImg(item.url)" class="card-img" />
</div>
<div class="card-text">
{{ item.name }}
</div>
</div>
</div>
<!-- 应用图标 -->
</div>
<div style="height: calc(80% - 20px);width: 100%;">
<xTable ref="xtable" :tableData="tableData" :tablePage="{}" :showSearchBtn="true" :showClearSearchInfoBtn="true" :isShowPage="false" :showSearchBox="true" :tableConfigure="tableConfigure" @onSearch="getAllApplication" @onClientSearchInfo="searchReset">
<template v-slot:searchBox>
<el-col :span="5">
<div class="grid-content bg-purple">
<p class="input-name">应用名称:</p>
<el-input v-model="searchInput.appName" clearable></el-input>
</div>
</el-col>
<el-col :span="5">
<div class="grid-content bg-purple">
<p class="input-name">应用链接:</p>
<el-input v-model="searchInput.appUrl" clearable></el-input>
</div>
</el-col>
<el-col :span="5">
<div class="grid-content bg-purple">
<p class="input-name">应用类型:</p>
<el-select v-model="searchInput.appPaltform" clearable @change="selectChange" placeholder="请选择">
<el-option key="pc" label="pc" value="pc"></el-option>
<el-option key="app" label="app" value="app"></el-option>
</el-select>
</div>
</el-col>
</template>
<template #optionBtns>
<div class="operationBtnBox">
<el-row>
<el-button class="blueDelete_box" @click="removeUserMultiple">
<div>
<svg-icon icon-class="blueDelete_small"></svg-icon>
<p>批量删除</p>
</div>
</el-button>
<el-button class="add_box" @click="addApplication">
<div>
<svg-icon icon-class="add_small"></svg-icon>
<p>添加</p>
</div>
</el-button>
</el-row>
</div>
</template>
<template v-slot:columns>
<vxe-column type="checkbox" width="4%" align="center"></vxe-column>
<vxe-column field="id" title="应用ID" align="center"></vxe-column>
<vxe-column field="name" title="应用名称" align="center"></vxe-column>
<vxe-column field="url" title="应用链接" align="center">
<template slot-scope="scope">
<el-link :href="scope.row.url" type="primary">{{ scope.row.url }}</el-link>
</template>
</vxe-column>
<vxe-column field="webHost" title="应用IP地址" align="center"></vxe-column>
<vxe-column field="webPort" title="应用端口" align="center"></vxe-column>
<vxe-column field="webPathTemplate" title="应用地址通配符" align="center"></vxe-column>
<vxe-column field="gateWayPathTemplate" title="网关地址通配符" align="center"></vxe-column>
<vxe-column field="icon" title="应用图标" align="center">
<template slot-scope="scope">
<el-image style="height: 40px;width: 40px;" :src="scope.row.icon"></el-image>
</template>
</vxe-column>
<vxe-column field="appPaltform" title="应用类型" align="center"></vxe-column>
<vxe-column title="应用操作" width="10%" align="center">
<template slot-scope="scope">
<el-button type="text" class="edit-textButton" @click.stop="editApplication(scope.row)">编辑</el-button>
<span class="dividerLine">|</span>
<el-button type="text" class="remove-textButton" @click.stop="deleteApplication([scope.row.id])">删除</el-button>
</template>
</vxe-column>
</template>
</xTable>
</div>
<addUpdateApplication :formObject="formObject" ref="addUpdateApplication" />
</div>
</template>
<script lang="ts">
import addUpdateApplication from './addUpdateApplication.vue'
import xTable from '@src/components/TableBase/baseTable.vue'
import PageBase from '@src/views/PageBase'
import { Component, Prop, Vue, Emit, Watch } from 'vue-property-decorator'
import { GetAllApplication, DeleteApplication } from '../../serviceAPIs/service'
@Component({
components: {
xTable,
addUpdateApplication
}
})
export default class Index extends PageBase {
private formObject: {} = {}
private searchInput: any = { appName: '', appUrl: '', appPaltform: '' }
private tableData: any[] = []
private tableDataCache: any[] = []
// private tablePage: any = {
// total: 0,
// currentPage: 1,
// pageSize: 10
// }
// table设置
private tableConfigure: any = {
tableTitle: '应用列表',
imgSrc: ''
}
@Watch('searchInput', { deep: true })
private watchSearchInput(val) {
if (!val.appName && !val.appUrl && !val.appPaltform) {
this.getAllApplication()
}
}
mounted() {
this.getAllApplication()
}
private clickImg(url) {
this.$confirm('确认进入应用?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(() => {
window.location.href = url
})
.catch(() => {
this.$message({
type: 'info',
message: '取消进入应用'
})
})
}
private selectChange(option) {
this.searchInput.appPaltform = option
}
// 获取所有应用、查询
public async getAllApplication() {
let res = await GetAllApplication(this.searchInput)
if (this.searchInput.appPaltform) {
this.tableData = res.filter((item) => {
return item.appPaltform == this.searchInput.appPaltform
})
} else {
this.tableData = res
}
this.tableDataCache = JSON.parse(JSON.stringify(res))
}
public searchReset() {
this.searchInput = {
appName: '',
appUrl: '',
appPaltform: ''
}
}
// private toApplicationPlatform() {
// this.$router.push('/systemSettings/application_platform')
// }
//添加应用
private addApplication() {
;(this.$refs.addUpdateApplication as any).dialogVisible = true
;(this.$refs.addUpdateApplication as any).editMode = false
}
//批量删除
private removeUserMultiple() {
let selectedRows = (this.$refs.xtable as any).getChooseRows() as any[]
let selectIds = selectedRows.map((o) => o.id)
if (selectIds.length == 0) {
this.$message.warning('至少选择一个应用')
} else {
this.deleteApplication(selectIds)
}
}
//删除应用
private deleteApplication(val) {
this.$confirm('删除应用?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
let res = await DeleteApplication(val)
this.$message.success('删除成功!')
this.getAllApplication()
})
.catch(() => {
this.$message('删除取消')
})
}
//编辑应用
private editApplication(val) {
;(this.$refs.addUpdateApplication as any).dialogVisible = true
;(this.$refs.addUpdateApplication as any).editMode = true
// 将formObject传递给addApplication,val是当前行的信息
this.formObject = val
}
}
</script>
<style lang="less" scoped>
@import '@/assets/monitorStyle.less';
/deep/ .vxe-table--body-wrapper.body--wrapper {
height: calc(98% - 33px);
}
/deep/.table-box .el-button {
margin-right: 0px;
}
.showApp_Container {
height: calc(100% - 26px);
width: 100%;
display: flex;
flex-direction: row;
}
.appCard {
height: 100%;
width: 5.6%;
margin-right: 20px;
box-shadow: 0px 0px 4px rgba(22, 103, 255, 0.2);
font-size: 12px;
display: flex;
flex-direction: column;
}
.showApp-list {
height: 20%;
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 20px;
}
.card-imgContainer {
height: 64%;
width: 100%;
display: flex;
justify-content: center;
align-items: flex-end;
}
.card-text {
height: 36%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.card-img {
width: 40px;
height: 40px;
}
// 搜素按钮颜色
// /deep/ .input-box[data-v-476658ad] .seachBtn {
// padding: 7px 12px;
// margin-left: 20px;
// border: 1px solid #18aeb7;
// color: #fff;
// background: #18aeb7;
// }
// 应用平台展示
.showapp {
width: 100%;
height: 20%;
margin-bottom: 20px;
background-color: #fff;
border-radius: 5px;
}
.showApp_title {
border-left: 6px solid var(--lyl_sideDecoration);
width: 100%;
height: 26px;
font-weight: bold;
font-size: 20px;
padding-right: 10px;
margin-bottom: 15px;
}
::v-deep .table-box[data-v-476658ad] .vxe-header--row {
background-size: cover;
color: black;
font-weight: bold;
}
</style>
2.表单页面
<template>
<el-dialog :title="editMode ? '编辑一个应用' : '添加一个应用'" :close-on-click-modal="false" :visible.sync="dialogVisible" @close="dialogClose" width="30%">
<el-form ref="form" :rules="rules" :model="form" label-width="80px">
<el-form-item label="应用名称" prop="name">
<el-input v-model="form.name" maxlength="60" :show-word-limit="false" clearable></el-input>
</el-form-item>
<el-form-item label="应用链接" prop="url">
<el-input v-model="form.url" maxlength="2000" :show-word-limit="false" clearable></el-input>
</el-form-item>
<el-form-item label="应用IP地址" prop="webHost">
<el-input v-model="form.webHost" maxlength="60" :show-word-limit="false" clearable></el-input>
</el-form-item>
<el-form-item label="应用端口" prop="webPort">
<el-input-number :min="0" :max="80000" v-model="form.webPort" clearable :show-word-limit="false"></el-input-number>
</el-form-item>
<el-form-item label="应用地址通配符" prop="webPathTemplate">
<el-input v-model="form.webPathTemplate" maxlength="60" :show-word-limit="false" clearable></el-input>
</el-form-item>
<el-form-item label="网关地址通配符" prop="gateWayPathTemplate">
<el-input v-model="form.gateWayPathTemplate" maxlength="60" :show-word-limit="false" clearable></el-input>
</el-form-item>
<el-form-item label="应用类型">
<el-select v-model="form.appPaltform" placeholder="请选择">
<el-option key="pc" label="pc" value="pc" />
<el-option key="app" label="app" value="app" />
</el-select>
</el-form-item>
<el-form-item label="应用图标">
<el-upload class="upload-demo" ref="upload" action="" :on-remove="handleRemove" :file-list="file_list" :on-change="getFile" :auto-upload="false" list-type="picture" :limit="1">
<el-button size="small" type="primary">上传应用图标</el-button>
</el-upload>
</el-form-item>
</el-form>
<span slot="footer">
<el-button size="small" @click="handleClose">取消</el-button>
<el-button size="small" type="primary" @click="upload">提交</el-button>
</span>
</el-dialog>
</template>
<script lang="ts">
import ComponentBase from '@src/views/ComponentBase'
import { Component, Prop, Vue, Emit, Watch } from 'vue-property-decorator'
import { AddOrUpdateApplication } from '../../serviceAPIs/service'
@Component({})
export default class addUpdateApplication extends ComponentBase {
@Watch('formObject')
private watch_formObject(val: any) {
this.form = val
this.file_list = [{ url: val.icon }]
}
public dialogVisible: Boolean = false
public editMode: Boolean = false
// private isImage: Boolean = false
private file_list: any[] = []
private form: any = {
name: '',
url: '',
icon: '',
appPaltform: 'pc'
}
private rules: any = {
name: [{ required: true, message: '请输入应用名', trigger: 'blur' }, { min: 1, max: 60, message: '应用名字数要在1到60之间', trigger: ['blur', 'change'] }],
url: [
{ required: true, message: '请输入应用链接', trigger: 'blur' },
{ min: 1, max: 2000, message: '应用链接字数要在1到2000之间', trigger: ['blur', 'change'] },
{
message: '应用链接不合法',
trigger: ['blur', 'change'],
pattern: /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\*\+,;=.]+$/
}
]
}
//编辑/添加应用
private async upload() {
;(this.$refs['form'] as any).validate(async (valid) => {
if (valid) {
let res = await AddOrUpdateApplication(this.form)
this.handleClose()
} else {
this.$message.warning('表单不符合要求')
return false
}
})
}
// 移除上传的文件时的回调
private handleRemove() {
this.form.icon = ''
this.$delete(this.file_list, 0)
}
// 对话框关闭时重新调取数据
private dialogClose() {
this.clearForm()
;(this.$parent as any).getAllApplication()
}
// 关闭对话框,清除表单
private handleClose() {
this.dialogVisible = false
// this.clearForm()
}
private clearForm() {
this.form = {}
this.form.appPaltform = 'pc'
this.$delete(this.file_list, 0)
}
// 当文件状态改变、添加文件、上传成功和上传失败时调用
private getFile(file, fileList) {
let fileType = file.name.substring(file.name.lastIndexOf('.') + 1)
let fileSize = file.size / 1024 / 1024 < 5
if (fileType !== 'png' && fileType !== 'jpg' && fileType !== 'jpeg') {
;(this.$refs.upload as any).clearFiles()
this.$message.warning('上传文件只能是 .png、.jpg、jpeg格式!')
return false
} else if (!fileSize) {
;(this.$refs.upload as any).clearFiles()
this.$message.warning('上传文件大小不能超过 5MB!')
return false
} else {
// this.isImage = true
this.getBase64(file.raw).then((res) => {
this.form.icon = res
})
}
}
// 图片转base64
private getBase64(file) {
return new Promise(function(resolve, reject) {
let reader = new FileReader()
let imgResult = ''
reader.readAsDataURL(file)
reader.onload = function() {
imgResult = reader.result as any
}
reader.onerror = function(error) {
reject(error)
}
reader.onloadend = function() {
resolve(imgResult)
}
})
}
@Prop({
default: {}
})
formObject: {}
}
</script>
<style scoped></style>