Files
ibs-fullstack/ruoyi-ui/src/views/workmng/warningtask/index.vue

512 lines
14 KiB
Vue
Raw Normal View History

2026-02-26 14:51:13 +08:00
<template>
<div class="app-container" style="padding: 0px !important;">
<el-row :gutter="24" style="padding: 0 30px;">
2026-02-26 14:51:13 +08:00
<el-col :span="6">
<el-card class="stat-card stat-card-blue">
<div class="stat-icon">
<i class="el-icon-bell"></i>
2026-02-26 14:51:13 +08:00
</div>
<div class="stat-content">
<div class="stat-title">总预警推送次数</div>
<div class="stat-value">{{ cardInfo.alterCount }}</div>
2026-02-26 14:51:13 +08:00
</div>
</el-card>
</el-col>
<el-col :span="6">
<el-card class="stat-card stat-card-blue2">
<div class="stat-icon">
<i class="el-icon-data-analysis"></i>
2026-02-26 14:51:13 +08:00
</div>
<div class="stat-content">
<div class="stat-title">反馈完成率</div>
<div class="stat-value">{{ cardInfo.completeRate + '%' }}</div>
2026-02-26 14:51:13 +08:00
</div>
</el-card>
</el-col>
</el-row>
<el-form
:model="searchArray"
ref="searchArrayRef"
size="small"
:inline="true"
style="margin-top:20px;"
>
<el-form-item label="日期">
<el-date-picker
v-model="reportTime"
placeholder="请选择日期"
@change="initCardList"
style="width:100%"
/>
</el-form-item>
2026-02-26 14:51:13 +08:00
<el-form-item label="状态" prop="status">
<el-select v-model="searchArray.status" placeholder="请选择状态" style="width: 100%" clearable>
<el-option
v-for="item in statusList"
:key="item.value"
:value="item.value"
:label="item.label"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="预警类型" prop="alterType">
<el-select
2026-02-26 14:51:13 +08:00
v-model="searchArray.alterType"
placeholder="请选择预警类型"
2026-02-26 14:51:13 +08:00
clearable
style="width:100%"
>
<el-option
v-for="item in alterTypeOptions"
:key="item"
:label="item"
:value="item"
></el-option>
</el-select>
2026-02-26 14:51:13 +08:00
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="searchFn">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetFn">重置</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="tableData">
2026-02-26 14:51:13 +08:00
<template>
<el-table-column label="序号" prop="xh" width="80">
<template slot-scope="scope">
<span>{{ scope.$index+1 }}</span>
</template>
</el-table-column>
<el-table-column label="客户姓名" width="120" prop="custName" min-width="100" show-overflow-tooltip />
<el-table-column label="客户号" width="230" prop="custId" min-width="140" show-overflow-tooltip />
<el-table-column label="客户内码" width="200" prop="custIsn" min-width="140" show-overflow-tooltip />
<el-table-column label="客户经理" width="200" prop="userInfo" min-width="140" show-overflow-tooltip />
<el-table-column label="预警类型" width="250" prop="alterType" min-width="100" show-overflow-tooltip />
<el-table-column label="预警详情" prop="alterDetail" min-width="100" show-overflow-tooltip />
<el-table-column label="是否已读" prop="isReed" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="scope.row.isReed === '0'"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="备注" width="250" prop="remark" min-width="100" show-overflow-tooltip />
<el-table-column label="状态" width="150" prop="status" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{ scope.row.status | formatFilter('status',statusList) }}</span>
</template>
</el-table-column>
<!-- <el-table-column label="操作" align="center" width="160">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="editFn(scope.row)">处理</el-button>
</template>
</el-table-column> -->
</template>
</el-table>
<el-pagination
:page-sizes="[10, 20, 30, 50]"
:page-size="pageSize"
layout="->,total,prev,pager,next,sizes"
:total="total"
:current-page="pageNum"
@current-change="currentChangeFn"
@size-change="sizeChangeFn"
></el-pagination>
2026-02-26 14:51:13 +08:00
<el-dialog
:title="dialogTitle"
:visible.sync="visibleFlag"
width="800px"
append-to-body
v-if="visibleFlag"
>
<el-form ref="dialogFormRef" :model="dialogForm" :rules="dialogFormRules" label-width="120px">
<el-row>
<el-col :span="24">
<el-form-item label="客户姓名" prop="custName">
<el-input
v-model="dialogForm.custName"
placeholder="请输入客户姓名"
clearable
style="width:100%"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="客户号" prop="custId">
<el-input
v-model="dialogForm.custId"
placeholder="请输入客户号"
clearable
style="width:100%"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="预警类型" prop="alterType">
<el-input
v-model="dialogForm.alterType"
placeholder="请输入预警类型"
clearable
style="width:100%"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="预警详情" prop="alterDetail">
<el-input
v-model="dialogForm.alterDetail"
placeholder="请输入预警详情"
clearable
style="width:100%"
>
</el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="状态" prop="status">
<el-select
v-model="dialogForm.status"
placeholder="请选择状态"
clearable
style="width:100%"
>
<el-option
v-for="item in statusList"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input
v-model="dialogForm.remark"
placeholder="请输入备注"
clearable
style="width:100%"
>
</el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer">
<el-button type="primary" @click="dialogOkfn"> </el-button>
<el-button @click="dialogCancelfn"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
warningworkRecordList,
warningworkRecordSubmit,
warningCardNum,
getAlterTypes
2026-02-26 14:51:13 +08:00
} from "@/api/system/home";
import _ from "lodash";
import dayjs from "dayjs";
import { mapGetters } from "vuex";
export default {
name: "workmngdaytaskindex",
computed: {
...mapGetters(["roles"]),
isShowFlag() {
let arr = _.intersection(this.roles, [
"admin",
"headAdmin",
"branchAdmin",
"headPublic",
"headPrivate",
"outletAdmin",
"headOps"
]);
if (arr.length > 0) {
return true;
} else {
return false;
}
}
},
data() {
return {
reportTime: new Date(),
cardInfo: {
alterCount: '',
completeRate: '',
},
statusList: [
{
label: "未完成",
value: "0"
},
{
label: "已完成",
value: "2"
}
],
alterTypeOptions: [],
2026-02-26 14:51:13 +08:00
searchArray: {
status: "",
alterType: ""
},
pageNum: 1,
pageSize: 10,
tableData: [],
total: 0,
loading: false,
dialogTitle: '',
dialogForm: {
custName: '',
custId: '',
alterType: '',
alterDetail: '',
status: ''
},
visibleFlag: false,
dialogFormRules: {
status: [{ required: true, message: "不能为空", trigger: "blur" }],
custName: [{ required: true, message: "不能为空", trigger: "blur" }],
custId: [{ required: true, message: "不能为空", trigger: "blur" }],
alterType: [
{ required: true, message: "不能为空", trigger: "blur" }
],
alterDetail: [
{ required: true, message: "不能为空", trigger: "blur" }
]
}
};
},
created() {
this.resetFn();
this.initCardList();
this.getAlterTypeList();
2026-02-26 14:51:13 +08:00
},
filters: {
formatFilter(v, type, list) {
if (type == "status") {
let arr = _.filter(list, { value: v });
return arr.length > 0 ? arr[0].label : '';
}
}
},
methods: {
getAlterTypeList() {
getAlterTypes().then(res => {
if (res.code === 200) {
this.alterTypeOptions = res.data || [];
}
});
},
2026-02-26 14:51:13 +08:00
initCardList() {
warningCardNum({ reportTime: this.reportTime ? dayjs(this.reportTime).format('YYYY-MM-DD') + ' 23:59:59' : '' }).then(res => {
this.cardInfo = res
})
},
resetFn() {
this.searchArray = {
status: "",
alterType: ""
};
this.searchFn();
},
searchFn() {
this.pageNum = 1;
this.pageSize = 10;
this.total = 0;
this.queryListFn();
},
queryListFn() {
this.loading = true;
let p = {
...this.searchArray,
pageNum: this.pageNum,
pageSize: this.pageSize
};
warningworkRecordList(p).then(response => {
this.loading = false;
if (response.code == 200) {
this.tableData = response.rows || [];
this.total = response.total || 0;
} else {
this.$message.error(response.msg || "操作失败");
}
});
},
currentChangeFn(val) {
this.pageNum = val;
this.queryListFn();
},
sizeChangeFn(val) {
this.pageSize = val;
this.queryListFn();
},
editFn(row) {
this.dialogTitle = "修改";
this.dialogForm = row;
this.visibleFlag = true;
// this.$nextTick(() => {
// this.$refs.dialogFormRef.resetFields();
// });
},
dialogOkfn() {
this.$refs["dialogFormRef"].validate(valid => {
if (valid) {
warningworkRecordSubmit(this.dialogForm).then(response => {
if (response.code == "200") {
let msg = "修改成功";
this.$message.success(msg);
this.visibleFlag = false;
this.resetFn();
} else {
this.$message.error(response.msg || "操作失败");
}
});
}
});
},
dialogCancelfn() {
this.visibleFlag = false;
},
}
};
</script>
<style lang="scss" scoped>
::v-deep .el-pagination {
margin-top: 15px;
2026-02-26 14:51:13 +08:00
}
// 统计卡片样式
.stat-card {
2026-02-26 14:51:13 +08:00
height: 100px;
border-radius: 8px;
margin-top: 25px;
border: none;
display: flex;
align-items: center;
padding: 0 20px;
position: relative;
overflow: hidden;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
2026-02-26 14:51:13 +08:00
// 左侧装饰条
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
background: rgba(255, 255, 255, 0.5);
}
2026-02-26 14:51:13 +08:00
.stat-icon {
width: 50px;
height: 50px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.2);
margin-right: 12px;
flex-shrink: 0;
i {
font-size: 22px;
color: #fff;
}
}
2026-02-26 14:51:13 +08:00
.stat-content {
flex: 1;
display: flex;
align-items: center;
gap: 10px;
.stat-title {
font-size: 14px;
color: rgba(255, 255, 255, 0.9);
white-space: nowrap;
}
.stat-value {
font-size: 20px;
color: #fff;
font-weight: bold;
}
}
// 蓝色渐变卡片1左上深→右下浅
&.stat-card-blue {
background: linear-gradient(135deg, #1e7ee6 0%, #a0cfff 100%);
}
// 蓝色渐变卡片2左上浅→右下深
&.stat-card-blue2 {
background: linear-gradient(135deg, #a0cfff 0%, #1e7ee6 100%);
}
2026-02-26 14:51:13 +08:00
}
.header-radio {
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #ebebeb;
.el-radio-button {
flex: 1;
::v-deep .el-radio-button__inner {
width: 100%;
border: none;
font-weight: 400;
letter-spacing: 0.44px;
line-height: 25px;
font-size: 16px;
color: #666666;
padding: 11px 0 12px 0;
}
::v-deep .el-radio-button__orig-radio:checked + .el-radio-button__inner {
background-color: #4886f8;
font-weight: 400;
color: #ffffff;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
&:nth-child(2) {
&::before,
&::after {
content: "";
position: absolute;
top: 50%;
transform: translateY(-50%);
height: 21px;
width: 1px;
background: #ebebeb;
z-index: 1;
}
&::after {
right: 1px;
}
}
&.is-active {
&::before,
&::after {
content: none;
}
}
}
}
</style>