<template>
|
<div class="app-container">
|
<!-- 服务评价概览:模拟员工业绩评分 -->
|
<el-row :gutter="16" class="mb16">
|
<el-col :span="8">
|
<el-card shadow="never">
|
<div class="kpi-title">本月平均评分</div>
|
<div class="kpi-value">
|
{{ overallAvgScore.toFixed(1) }}
|
<span class="kpi-unit">分</span>
|
</div>
|
<el-rate v-model="overallAvgScore" disabled show-score score-template="{value} / 5" />
|
</el-card>
|
</el-col>
|
<el-col :span="8">
|
<el-card shadow="never">
|
<div class="kpi-title">已评价维修工单</div>
|
<div class="kpi-value">
|
{{ ratedCount }}
|
<span class="kpi-unit">单</span>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="8">
|
<el-card shadow="never">
|
<div class="kpi-title">待评价维修工单</div>
|
<div class="kpi-value kpi-warning">
|
{{ pendingCount }}
|
<span class="kpi-unit">单</span>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<!-- 查询条件:管理员按工程师 / 客户 / 时间追溯评价 -->
|
<div class="search_form">
|
<div>
|
<span class="search_title">维修工程师:</span>
|
<el-input
|
v-model="searchForm.engineerName"
|
placeholder="请输入工程师姓名"
|
style="width: 180px"
|
clearable
|
@keyup.enter.native="handleQuery"
|
/>
|
|
<span class="search_title ml10">客户名称:</span>
|
<el-input
|
v-model="searchForm.customerName"
|
placeholder="请输入客户名称"
|
style="width: 180px"
|
clearable
|
@keyup.enter.native="handleQuery"
|
/>
|
|
<span class="search_title ml10">完成时间:</span>
|
<el-date-picker
|
v-model="searchForm.dateRange"
|
type="daterange"
|
range-separator="至"
|
start-placeholder="开始日期"
|
end-placeholder="结束日期"
|
value-format="YYYY-MM-DD"
|
format="YYYY-MM-DD"
|
clearable
|
/>
|
|
<span class="search_title ml10">评价状态:</span>
|
<el-select
|
v-model="searchForm.status"
|
placeholder="请选择"
|
style="width: 140px"
|
clearable
|
>
|
<el-option label="待评价" value="pending" />
|
<el-option label="已评价" value="rated" />
|
</el-select>
|
|
<el-button type="primary" @click="handleQuery" style="margin-left: 10px">
|
搜索
|
</el-button>
|
<el-button @click="resetSearch">重置</el-button>
|
</div>
|
<div>
|
<el-button icon="Download" @click="handleExport">
|
导出评价统计
|
</el-button>
|
</div>
|
</div>
|
|
<!-- 维修评价列表:模拟“维修完成后触发评价”场景 -->
|
<div class="table_list">
|
<el-table
|
:data="tableData"
|
border
|
style="width: 100%"
|
height="calc(100vh - 24em)"
|
:header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
|
>
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
<el-table-column prop="orderNo" label="维修工单号" width="160" show-overflow-tooltip />
|
<el-table-column prop="deviceName" label="设备名称" width="160" show-overflow-tooltip />
|
<el-table-column prop="customerName" label="客户名称" width="180" show-overflow-tooltip />
|
<el-table-column prop="engineerName" label="维修工程师" width="120" />
|
<el-table-column prop="completeTime" label="维修完成时间" width="180" />
|
<el-table-column prop="score" label="星级评分" width="140" align="center">
|
<template #default="scope">
|
<el-rate v-if="scope.row.score" v-model="scope.row.score" disabled />
|
<span v-else>-</span>
|
</template>
|
</el-table-column>
|
<el-table-column prop="status" label="评价状态" width="100" align="center">
|
<template #default="scope">
|
<el-tag
|
:type="scope.row.status === 'rated' ? 'success' : 'warning'"
|
size="small"
|
>
|
{{ scope.row.status === 'rated' ? '已评价' : '待评价' }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column prop="feedback" label="客户反馈" show-overflow-tooltip />
|
<el-table-column label="操作" width="160" align="center" fixed="right">
|
<template #default="scope">
|
<el-button
|
v-if="scope.row.status === 'pending'"
|
type="primary"
|
link
|
size="small"
|
@click="openEvaluate(scope.row)"
|
>
|
去评价
|
</el-button>
|
<el-button
|
v-else
|
type="primary"
|
link
|
size="small"
|
@click="openEvaluate(scope.row)"
|
>
|
查看 / 修改评价
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
|
<!-- 评价弹框:模拟“维修完成后弹出客户端评价” -->
|
<el-dialog
|
v-model="dialogVisible"
|
:title="dialogTitle"
|
width="520px"
|
destroy-on-close
|
>
|
<div class="dialog-order-info" v-if="currentOrder">
|
<div>维修工单:{{ currentOrder.orderNo }}</div>
|
<div>设备名称:{{ currentOrder.deviceName }}</div>
|
<div>维修工程师:{{ currentOrder.engineerName }}</div>
|
</div>
|
<el-form
|
ref="formRef"
|
:model="form"
|
:rules="rules"
|
label-width="100px"
|
>
|
<el-form-item label="星级评分:" prop="score">
|
<el-rate v-model="form.score" :max="5" />
|
</el-form-item>
|
<el-form-item label="文字反馈:" prop="feedback">
|
<el-input
|
v-model="form.feedback"
|
type="textarea"
|
:rows="4"
|
placeholder="请填写对本次维修服务的评价,如响应速度、专业程度、沟通体验等"
|
/>
|
</el-form-item>
|
</el-form>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button type="primary" @click="handleSubmit">提 交 评 价</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, reactive, computed } from "vue";
|
import { ElMessage } from "element-plus";
|
|
// 模拟维修工单 + 客户评价数据
|
const rawOrders = ref([
|
{
|
id: 1,
|
orderNo: "WX-2024-1201-001",
|
deviceName: "空压机 A1 号",
|
customerName: "华南电子科技有限公司",
|
engineerName: "王师傅",
|
completeTime: "2024-12-01 10:30:00",
|
completeDate: "2024-12-01",
|
status: "rated",
|
score: 5,
|
feedback: "维修非常专业,响应速度快,现场解释也很清晰,满意。",
|
},
|
{
|
id: 2,
|
orderNo: "WX-2024-1201-002",
|
deviceName: "注塑机 B3 号",
|
customerName: "华东精密制造有限公司",
|
engineerName: "李师傅",
|
completeTime: "2024-12-01 15:20:00",
|
completeDate: "2024-12-01",
|
status: "rated",
|
score: 4,
|
feedback: "整体还不错,就是到场时间稍微长了一点,希望后面能再快一些。",
|
},
|
{
|
id: 3,
|
orderNo: "WX-2024-1202-003",
|
deviceName: "焊接机器人 C2 号",
|
customerName: "西南新能源科技股份",
|
engineerName: "张师傅",
|
completeTime: "2024-12-02 11:05:00",
|
completeDate: "2024-12-02",
|
status: "pending",
|
score: null,
|
feedback: "",
|
},
|
{
|
id: 4,
|
orderNo: "WX-2024-1203-005",
|
deviceName: "测试台 D1 号",
|
customerName: "北方汽车零部件有限公司",
|
engineerName: "王师傅",
|
completeTime: "2024-12-03 09:50:00",
|
completeDate: "2024-12-03",
|
status: "pending",
|
score: null,
|
feedback: "",
|
},
|
]);
|
|
// 查询表单
|
const searchForm = reactive({
|
engineerName: "",
|
customerName: "",
|
dateRange: [],
|
status: "",
|
});
|
|
// 列表数据
|
const tableData = ref([...rawOrders.value]);
|
|
// 统计:整体评分、已评价 / 待评价数量
|
const ratedOrders = computed(() =>
|
rawOrders.value.filter((o) => o.status === "rated" && o.score)
|
);
|
|
const overallAvgScore = computed(() => {
|
if (!ratedOrders.value.length) return 0;
|
const sum = ratedOrders.value.reduce((acc, cur) => acc + (cur.score || 0), 0);
|
return sum / ratedOrders.value.length;
|
});
|
|
const ratedCount = computed(() => ratedOrders.value.length);
|
const pendingCount = computed(
|
() => rawOrders.value.filter((o) => o.status === "pending").length
|
);
|
|
// 查询 / 重置
|
const recomputeTable = () => {
|
const list = rawOrders.value.filter((item) => {
|
if (
|
searchForm.engineerName &&
|
!item.engineerName.includes(searchForm.engineerName.trim())
|
) {
|
return false;
|
}
|
if (
|
searchForm.customerName &&
|
!item.customerName.includes(searchForm.customerName.trim())
|
) {
|
return false;
|
}
|
if (searchForm.status && item.status !== searchForm.status) {
|
return false;
|
}
|
if (Array.isArray(searchForm.dateRange) && searchForm.dateRange.length === 2) {
|
const [start, end] = searchForm.dateRange;
|
if (item.completeDate < start || item.completeDate > end) {
|
return false;
|
}
|
}
|
return true;
|
});
|
tableData.value = list;
|
};
|
|
const handleQuery = () => {
|
recomputeTable();
|
};
|
|
const resetSearch = () => {
|
searchForm.engineerName = "";
|
searchForm.customerName = "";
|
searchForm.dateRange = [];
|
searchForm.status = "";
|
recomputeTable();
|
};
|
|
// 导出(演示)
|
const handleExport = () => {
|
ElMessage.success("当前为演示页面,评价导出功能未对接实际接口");
|
};
|
|
// 评价弹框
|
const dialogVisible = ref(false);
|
const dialogTitle = ref("维修服务评价");
|
const currentOrder = ref(null);
|
const formRef = ref(null);
|
const form = reactive({
|
score: 0,
|
feedback: "",
|
});
|
|
const rules = {
|
score: [{ required: true, message: "请选择星级评分", trigger: "change" }],
|
feedback: [{ required: true, message: "请填写文字反馈", trigger: "blur" }],
|
};
|
|
// 打开评价:模拟“维修完成确认后弹出评价弹框”
|
const openEvaluate = (row) => {
|
currentOrder.value = row;
|
dialogTitle.value =
|
row.status === "pending" ? "维修服务评价" : "查看 / 修改评价";
|
form.score = row.score || 0;
|
form.feedback = row.feedback || "";
|
dialogVisible.value = true;
|
};
|
|
// 提交评价:同步到本地“员工业绩统计”
|
const handleSubmit = () => {
|
if (!formRef.value) return;
|
formRef.value.validate((valid) => {
|
if (!valid || !currentOrder.value) return;
|
|
const target = rawOrders.value.find((o) => o.id === currentOrder.value.id);
|
if (target) {
|
target.score = form.score;
|
target.feedback = form.feedback;
|
target.status = "rated";
|
}
|
|
ElMessage.success("评价提交成功,已同步至员工业绩统计");
|
dialogVisible.value = false;
|
recomputeTable();
|
});
|
};
|
|
// 初始化列表
|
recomputeTable();
|
</script>
|
|
<style scoped lang="scss">
|
.mb16 {
|
margin-bottom: 16px;
|
}
|
|
.kpi-title {
|
font-size: 13px;
|
color: #909399;
|
}
|
|
.kpi-value {
|
margin-top: 6px;
|
font-size: 24px;
|
font-weight: 600;
|
color: #303133;
|
}
|
|
.kpi-unit {
|
font-size: 12px;
|
margin-left: 4px;
|
color: #909399;
|
}
|
|
.kpi-warning {
|
color: #e6a23c;
|
}
|
|
.dialog-order-info {
|
margin-bottom: 12px;
|
font-size: 13px;
|
color: #606266;
|
line-height: 1.8;
|
}
|
|
.dialog-footer {
|
text-align: right;
|
}
|
</style>
|