<template>
|
<div>
|
<!-- 新建任务按钮 -->
|
<div class="header-container">
|
<el-button type="primary" @click="openDialog('create')">
|
<i class="el-icon-plus"></i> 新建预警规则
|
</el-button>
|
</div>
|
|
<!-- 通用弹窗组件 -->
|
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="600px" custom-class="custom-dialog"
|
@open="handleDialogOpen" @closed="handleDialogClose">
|
<el-form label-width="100px" :disabled="isViewMode" ref="form" :rules="formRules" :model="currentFile">
|
<el-form-item label="图标" prop="fileUrl">
|
<!-- 图标上传组件 -->
|
<el-upload class="avatar-uploader" action="#" :show-file-list="false" :auto-upload="false"
|
:disabled="isViewMode" :on-change="handleIconChange" :before-upload="beforeIconUpload">
|
<!-- 图片预览 -->
|
<div class="icon-preview-container">
|
<el-image v-if="currentFile.iconUrl" :src="currentFile.iconUrl" fit="cover" />
|
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
</div>
|
|
<!-- 操作提示 -->
|
<div slot="tip" class="el-upload__tip">
|
只能上传jpg/png文件,且不超过2MB
|
</div>
|
</el-upload>
|
</el-form-item>
|
|
<el-form-item label="文件名称" prop="fileName">
|
<el-input v-model="currentFile.fileName" placeholder="请输入文件名称" />
|
</el-form-item>
|
|
<el-form-item label="预警规则" prop="warningRules">
|
<el-input type="textarea" :rows="6" v-model="currentFile.warningRules" resize="none">
|
</el-input>
|
</el-form-item>
|
|
<!-- <el-form-item label="分数阈值" >
|
<el-slider v-model="currentFile.rangeValue" :min="0" :max="1" :step="0.1" show-input/>
|
</el-form-item> -->
|
</el-form>
|
|
<span slot="footer" class="dialog-footer">
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button type="primary" @click="handleConfirm" v-if="!isViewMode">
|
确 定
|
</el-button>
|
</span>
|
</el-dialog>
|
|
<div class="file-manager-container">
|
<!-- 滚动区域容器 -->
|
<div class="scrollable-list">
|
<el-row v-if="files.length > 0" :gutter="20">
|
<el-col v-for="(file, index) in files" :key="file.ruleId" :span="5" class="file-col">
|
<el-card :class="['file-card', { 'selected': file.selected }]" @click.native="toggleSelect(file)">
|
<!-- 文件标题部分 -->
|
<div class="file-header">
|
<span class="file-index" hidden>{{ index + 1 }}</span>
|
<!-- <i class="el-icon-document file-icon"></i> -->
|
<el-image style="width: 30px;height: 30px;" :src="file.iconUrl" class="result-image" />
|
<div class="file-title">{{ file.fileName }}</div>
|
</div>
|
|
<!-- 文件描述 -->
|
<div class="file-desc">
|
{{ file.warningRules }}
|
</div>
|
|
<!-- 操作按钮组 -->
|
<div class="file-actions">
|
<!-- <el-button type="text" @click.stop="handleEdit(file)"> -->
|
<el-button type="text" @click.stop="openDialog('edit', file)">
|
<i class="el-icon-edit"></i> 编辑
|
</el-button>|
|
<el-button type="text" @click.stop="openDialog('view', file)">
|
<i class="el-icon-view"></i> 查看
|
</el-button>|
|
<el-button type="text" @click.stop="handleDelete(file)">
|
<i class="el-icon-delete"></i> 删除
|
</el-button>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
<!-- 新增空状态显示 -->
|
<el-empty v-else description="暂无预警规则"></el-empty>
|
</div>
|
|
</div>
|
<div class="footer-container">
|
<el-pagination @current-change="handleCurrentChange" :page-size="16" layout="prev, pager, next"
|
:total="this.pagination.total">
|
</el-pagination>
|
</div>
|
</div>
|
|
</template>
|
|
<script>
|
import WarnAPI from '@/api/WarningRuleView'
|
export default {
|
data() {
|
return {
|
userInfo: {},
|
image_path: require("@/assets/img/下载.png"),
|
// 新增表单验证规则
|
formRules: {
|
// fileName: [
|
// { required: true, message: '文件名称不能为空', trigger: 'blur' }
|
// ],
|
// warningRules: [
|
// { required: true, message: '预警规则不能为空', trigger: 'blur' }
|
// ]
|
},
|
// 新增分页参数
|
pagination: {
|
page: 1,
|
pageSize: 16,
|
total: 0,
|
totalPage: 1
|
},
|
dialogVisible: false,
|
dialogType: 'create', // create/edit/view
|
currentFile: this.initFile(),
|
form: {
|
fileName: '',
|
warningRules: '',
|
rangeValue: 0
|
},
|
files: [
|
]
|
}
|
},
|
created(){
|
this.userInfo = sessionStorage.getItem("userInfo") && JSON.parse(sessionStorage.getItem("userInfo"))
|
},
|
mounted() {
|
this.fetchFiles()
|
},
|
computed: {
|
dialogTitle() {
|
return {
|
create: '添加预警规则',
|
edit: '编辑预警规则',
|
view: '预警规则详情'
|
}[this.dialogType]
|
},
|
isViewMode() {
|
return this.dialogType === 'view'
|
}
|
},
|
methods: {
|
// 处理图标文件变化
|
handleIconChange(file) {
|
// 在查看模式下禁止操作
|
if (this.isViewMode) return false;
|
|
// 创建临时URL预览
|
const reader = new FileReader();
|
reader.onload = (e) => {
|
this.$set(this.currentFile, 'iconUrl', e.target.result);
|
this.$set(this.currentFile, 'iconUrl2', e.target.result);
|
};
|
reader.readAsDataURL(file.raw);
|
return false;
|
},
|
|
// 上传前的验证
|
beforeIconUpload(file) {
|
const isImage = ['image/jpeg', 'image/png', 'image/gif'].includes(file.type);
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
|
if (!isImage) {
|
this.$message.error('只能上传图片格式!');
|
}
|
if (!isLt2M) {
|
this.$message.error('图片大小不能超过 2MB!');
|
}
|
|
return isImage && isLt2M;
|
},
|
// 弹窗打开时的处理
|
handleDialogOpen() {
|
this.$nextTick(() => {
|
this.$refs.form.clearValidate()
|
})
|
},
|
// 弹窗关闭时的处理
|
handleDialogClose() {
|
this.$refs.form.resetFields()
|
this.formRules = {}
|
},
|
// 获取文件列表
|
async fetchFiles() {
|
try {
|
const res = await WarnAPI.getFiles({
|
page: this.pagination.page,
|
pageSize: this.pagination.pageSize
|
})
|
// 更新分页数据前先校验当前页码
|
const totalPage = res.data.pagination.totalPage
|
const currentPage = this.pagination.page > totalPage
|
? totalPage
|
: res.data.pagination.page
|
this.pagination = {
|
...this.pagination,
|
page: currentPage,
|
total: res.data.pagination.total,
|
totalPage: totalPage
|
}
|
this.files = res.data.list
|
this.pagination.total = res.data.pagination.total
|
this.pagination.totalPage = res.data.pagination.totalPage
|
} catch (error) {
|
this.$message.error('获取预警列表失败')
|
console.error('API Error:', error)
|
}
|
},
|
//初始化滑块
|
formatTooltip(val) {
|
return val / 100;
|
},
|
// 初始化文件数据
|
initFile() {
|
return {
|
ruleId: null,
|
fileName: '',
|
warningRules: '',
|
rangeValue: 50,
|
iconUrl:''
|
}
|
},
|
|
// 打开弹窗(统一入口)
|
openDialog(type, file = null) {
|
if (type != 'view') {
|
this.formRules = {
|
fileName: [
|
{ required: true, message: '文件名称不能为空', trigger: 'blur' }
|
],
|
warningRules: [
|
{ required: true, message: '预警规则不能为空', trigger: 'blur' }
|
]
|
}
|
}
|
this.dialogType = type
|
this.currentFile = file ? { ...file } : this.initFile()
|
this.dialogVisible = true
|
},
|
|
// 弹窗确认
|
handleConfirm() {
|
// 提交前手动触发校验
|
this.$refs.form.validate(valid => {
|
if (valid) {
|
// 根据类型执行不同操作
|
const operation = {
|
create: this.createFile,
|
edit: this.updateFile
|
}[this.dialogType]
|
|
operation && operation(this.currentFile)
|
this.dialogVisible = false
|
}
|
})
|
},
|
|
// 创建文件
|
async createFile(file) {
|
// console.info("userInfo:"+JSON.stringify(this.userInfo))
|
try {
|
// 实际调用API接口
|
await WarnAPI.createFile({
|
fileName: file.fileName,
|
warningRules: file.warningRules,
|
rangeValue: file.rangeValue,
|
createUser:this.userInfo.id,
|
iconUrl:file.iconUrl2?file.iconUrl2:"/opt/smart/icon/task_icon.png"
|
})
|
this.$message.success('添加成功')
|
this.fetchFiles()
|
} catch (error) {
|
this.$message.error('添加失败')
|
console.error('API Error:', error)
|
}
|
},
|
|
// 更新文件
|
async updateFile(file) {
|
try {
|
// console.info(file)
|
// 实际调用API接口
|
await WarnAPI.updateFile({
|
ruleId: file.ruleId,
|
fileName: file.fileName,
|
warningRules: file.warningRules,
|
rangeValue: file.rangeValue,
|
iconUrl:file.iconUrl2
|
})
|
this.$message.success('编辑成功')
|
this.fetchFiles()
|
} catch (error) {
|
this.$message.error('编辑失败')
|
console.error('API Error:', error)
|
}
|
},
|
// 分页处理
|
handleCurrentChange(page) {
|
this.pagination.page = page
|
this.fetchFiles()
|
console.info(this.pagination)
|
},
|
toggleSelect(file) {
|
file.selected = !file.selected
|
},
|
async handleDelete(file) {
|
this.$confirm('即将删除该文件,所有内容将无法找回, 是否继续?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning'
|
}).then(async () => {
|
try {
|
let res = await WarnAPI.deleteFile({
|
ruleId: file.ruleId
|
})
|
|
if (res && res.status != 200) {
|
this.$message.error(res.msg)
|
return false
|
}
|
// 删除成功后自动修正页码
|
if (this.files.length === 1 && this.pagination.page > 1) {
|
this.pagination.page -= 1
|
}
|
this.$message.success('删除成功')
|
this.fetchFiles()
|
} catch (error) {
|
this.$message.error('删除失败')
|
console.error('API Error:', error)
|
}
|
}).catch(() => {
|
this.$message({
|
type: 'info',
|
message: '已取消删除'
|
});
|
});
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
/* 图标上传样式 */
|
.avatar-uploader {
|
.icon-preview-container {
|
margin-right: 240px;
|
width: 60px;
|
height: 60px;
|
border: 1px dashed #d9d9d9;
|
border-radius: 6px;
|
cursor: pointer;
|
position: relative;
|
overflow: hidden;
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
|
.el-image {
|
width: 100%;
|
height: 100%;
|
}
|
|
.el-icon-plus {
|
font-size: 28px;
|
color: #8c939d;
|
}
|
|
&:hover {
|
border-color: #409EFF;
|
}
|
}
|
|
::v-deep .el-upload__tip {
|
margin-top: 5px;
|
margin-right: 240px;
|
font-size: 12px;
|
color: #606266;
|
}
|
}
|
|
/* 新增滚动区域样式 */
|
.scrollable-list {
|
max-height: 500px;
|
/* 控制滚动区域的最大高度 */
|
overflow-y: auto;
|
/* 添加纵向滚动条 */
|
padding: 10px;
|
border-radius: 4px;
|
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05);
|
|
/* 自定义滚动条样式 */
|
&::-webkit-scrollbar {
|
width: 8px;
|
}
|
|
&::-webkit-scrollbar-thumb {
|
background-color: #c1c1c1;
|
border-radius: 4px;
|
|
&:hover {
|
background-color: #a8a8a8;
|
}
|
}
|
|
&::-webkit-scrollbar-track {
|
background: #f1f1f1;
|
border-radius: 4px;
|
}
|
}
|
|
/* 新增按钮容器样式 */
|
.header-container {
|
display: flex;
|
justify-content: flex-end;
|
margin-top: 10px;
|
margin-right: 20px;
|
|
|
}
|
|
.footer-container {
|
margin-top: 10px;
|
/* 确保分页固定在底部 */
|
}
|
|
.file-manager-container {
|
// min-height: 750px;
|
padding: 20px;
|
background: #fff;
|
position: relative;
|
/* 新增定位基准 */
|
|
.new-task-btn {
|
/* 移除绝对定位 */
|
position: absolute;
|
right: 30px;
|
top: 20px;
|
}
|
|
.file-col {
|
margin-bottom: 60px;
|
margin-right: 60px;
|
width: 302px;
|
height: 210px;
|
}
|
|
.file-card {
|
cursor: pointer;
|
transition: all 0.3s;
|
border: 2px solid transparent;
|
|
// &.selected {
|
// border-color: #409EFF;
|
// }
|
|
.file-header {
|
display: flex;
|
align-items: center;
|
margin-bottom: 12px;
|
|
.file-index {
|
width: 24px;
|
height: 24px;
|
background: #409EFF;
|
color: white;
|
border-radius: 50%;
|
text-align: center;
|
line-height: 24px;
|
margin-right: 8px;
|
}
|
|
.file-icon {
|
color: #409EFF;
|
font-size: 24px;
|
margin-right: 8px;
|
}
|
|
.file-title {
|
margin-left: 10px;
|
font-weight: bold;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
}
|
|
.file-desc {
|
color: #666;
|
font-size: 12px;
|
line-height: 1.5; // 根据实际字体大小调整
|
height: 3em; // 2行 x 1.5行高 = 3em(推荐使用相对单位)
|
overflow: hidden;
|
text-overflow: ellipsis;
|
display: -webkit-box;
|
-webkit-line-clamp: 2;
|
-webkit-box-orient: vertical;
|
margin-bottom: 12px;
|
text-align: left;
|
// 新增以下两行
|
word-wrap: break-word;
|
white-space: normal; // 或使用 pre-line
|
}
|
|
.file-actions {
|
border-top: 1px solid #eee;
|
padding-top: 12px;
|
// text-align: right;
|
|
.el-button {
|
padding: 0 8px;
|
color: #666;
|
|
i {
|
margin-right: 4px;
|
}
|
}
|
}
|
}
|
}
|
|
/* 弹窗样式 */
|
:deep(.custom-dialog) {
|
border-radius: 8px;
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
.el-dialog__header {
|
border-bottom: 1px solid #ebeef5;
|
padding: 16px 20px;
|
|
.el-dialog__title {
|
font-size: 16px;
|
color: #303133;
|
}
|
}
|
|
.el-dialog__body {
|
padding: 20px 30px;
|
}
|
|
.dialog-input {
|
width: 80%;
|
|
.el-input__inner {
|
border-color: #dcdfe6;
|
}
|
}
|
|
.dialog-textarea {
|
.el-textarea__inner {
|
font-family: 'Microsoft YaHei', sans-serif;
|
line-height: 1.6;
|
color: #606266;
|
border-color: #dcdfe6;
|
}
|
}
|
|
.dialog-slider {
|
width: 70%;
|
margin-right: 20px;
|
flex: 1; // 滑块自适应宽度
|
}
|
|
.score-value {
|
color: rgb(4, 8, 12);
|
font-weight: bold;
|
margin-right: 15px;
|
}
|
|
.dialog-footer {
|
.el-button {
|
padding: 10px 20px;
|
|
&--primary {
|
background: #409EFF;
|
border-color: #409EFF;
|
}
|
}
|
}
|
}
|
|
.content-pre {
|
white-space: pre-wrap;
|
word-break: break-word;
|
margin: 0;
|
font-size: 13px;
|
line-height: 1.6;
|
}
|
</style>
|