Commit 7b0f0f59 authored by “yiyousong”'s avatar “yiyousong”

feat: 评价数据报表接口调试

parent 542cec95
......@@ -8,6 +8,8 @@ import "element-ui/lib/theme-chalk/index.css";
Vue.use(ElementUI);
import { message } from "@/utils/resetMessage";
Vue.prototype.$message = message;
import ElImageViewer from "element-ui/packages/image/src/image-viewer";
Vue.component("ElImageViewer", ElImageViewer);
// 公共样式
import "@/assets/css/normalize.css";
import "@/assets/css/reset.css";
......
......@@ -3,40 +3,52 @@
<!-- 顶部搜索 -->
<div class="w-ful flex items-center justify-between">
<div class="flex items-center gap-4">
<el-button type="primary" size="small">导出</el-button>
<el-button
type="primary"
size="small"
:loading="exportLoading"
@click="exportExcel"
>导出</el-button
>
<div class="text-[#909399]">
评价次数:<span class="take-total-num">223</span>
评价次数:<span class="take-total-num">{{ total }}</span>
</div>
<div class="text-[14px] text-[#909399]">
统计时间段:2024-12-12 ~ 2024-12-12
统计时间段:{{ searchForm.time[0] }} ~ {{ searchForm.time[1] }}
</div>
</div>
<div class="flex items-center">
<el-form ref="form" inline size="small" :model="form">
<el-form ref="searchForm" inline size="small" :model="searchForm">
<el-form-item>
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
<el-select style="width: 130px" v-model="searchForm.type">
<el-option
v-for="(v, key) in searchType"
:key="key"
:label="v"
:value="Number(key)"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input v-model="form.name"></el-input>
<el-input
v-model="searchForm.keyword"
placeholder="请输入关键字"
clearable
@keyup.native.enter="handleSearch"
></el-input>
</el-form-item>
<el-form-item>
<el-date-picker
v-model="form.value"
type="daterange"
<y-date-picker
v-model="searchForm.time"
align="right"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:picker-options="pickerOptions"
>
</el-date-picker>
</y-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary">搜索</el-button>
<el-button type="primary" @click="handleSearch">搜索</el-button>
</el-form-item>
</el-form>
</div>
......@@ -46,33 +58,57 @@
popper-class="search-popover"
>
<div class="w-full">
<el-form ref="form2" inline size="small" :model="form2">
<el-form-item>
<el-checkbox-group v-model="form2.type">
<el-checkbox label="预约业务" name="type"></el-checkbox>
<el-checkbox label="呼叫业务" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form ref="searchForm2" inline size="small" :model="searchForm2">
<el-form-item>
<el-select v-model="form2.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
<el-select
style="width: 150px"
v-model="searchForm2.pjOption"
clearable
placeholder="请选择评价选项"
>
<el-option
v-for="(v, i) in pjOption"
:key="i"
:label="v"
:value="v"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="form2.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
<el-select
style="width: 180px"
filterable
clearable
v-model="searchForm2.sectionName"
placeholder="请选择部门"
>
<el-option
v-for="v in deptList"
:key="v.id"
:label="v.name"
:value="v.name"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="form2.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
<el-select
style="width: 180px"
v-model="searchForm2.hallName"
filterable
clearable
placeholder="请选择大厅"
>
<el-option
v-for="v in hallList"
:key="v.id"
:label="v.hallName"
:value="v.hallName"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary">搜索</el-button>
<el-button type="primary" @click="handleSearch">搜索</el-button>
</el-form-item>
</el-form>
</div>
......@@ -83,6 +119,7 @@
</el-popover>
</div>
<div class="main max-w-[1396px] flex-1">
<div>
<y-table
ref="MyTable"
:loading="loading"
......@@ -90,18 +127,36 @@
:column="column"
border
tooltip-effect="dark"
:max-height="600"
:max-height="580"
:row-key="(row) => row.id"
@selection-change="handleSelectionChange"
></y-table>
</div>
<Pagination
:total="total"
:current.sync="current"
:size.sync="size"
@get="getEvaluateList"
></Pagination>
</div>
<!-- 详情 -->
<EvaluateDetails :show.sync="show"></EvaluateDetails>
<EvaluateDetails :show.sync="show" :info="detailsInfo"></EvaluateDetails>
</div>
</template>
<script>
import EvaluateDetails from "./components/EvaluateDetails.vue";
import { getEvaluateList } from "@/api/market";
import { getDepartment, getHall } from "@/api/site";
import { dataSection } from "@/utils";
import { export2Excel } from "@/utils/exportExcel";
import storage from "@/utils/storage";
let searchType = {
1: "按窗口编号",
2: "按群众姓名",
3: "按群众手机号",
};
let pjOption = ["非常满意", "满意", "基本满意", "不满意", "非常不满意"];
export default {
components: {
EvaluateDetails,
......@@ -110,40 +165,25 @@ export default {
return {
show: false,
loading: false,
pickerOptions: {
shortcuts: [
{
text: "最近一周",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
exportLoading: false,
searchType,
pjOption,
size: 10,
current: 1,
total: 0,
searchForm: {
type: 1,
keyword: "",
time: [
this.$moment().format("YYYY-MM-DD"),
this.$moment().format("YYYY-MM-DD"),
],
siteId: storage.get(2, "siteId"),
},
form: {},
form2: {
type: [],
searchForm2: {
pjOption: "", // 评价选项
sectionName: "", // 部门名称
hallName: "", // 大厅名称
},
tableData: [
{
......@@ -151,11 +191,15 @@ export default {
},
],
selectionRows: [],
detailsInfo: {},
deptList: [], // 部门列表
hallList: [], // 大厅列表
column: [
{
type: "selection",
width: "50",
align: "center",
reserveSelection: true,
fixed: "left",
},
{
......@@ -164,117 +208,130 @@ export default {
width: "50",
align: "center",
fixed: "left",
index: (index) => {
return index + 1 + (this.current - 1) * this.size;
},
{
label: "站点名称",
align: "center",
width: "150",
prop: "name",
},
{
label: "业务名称",
label: "站点名称",
align: "center",
width: "150",
prop: "siteName",
},
{
label: "预约编码",
label: "身份证号",
align: "center",
width: "150",
prop: "peopleIdcard",
},
{
label: "叫号状态",
label: "姓名",
align: "center",
width: "150",
prop: "peopleName",
},
{
label: "窗口名",
label: "性别",
align: "center",
width: "150",
prop: "peopleSex",
},
{
label: "窗口编",
label: "手机",
align: "center",
width: "150",
prop: "peoplePhone",
},
{
label: "流水号",
label: "评价选项",
align: "center",
width: "150",
prop: "pjOption",
},
{
label: "呼叫转移",
label: "评价标签",
align: "center",
width: "150",
prop: "contentTag",
},
{
label: "身份证号",
label: "部门",
align: "center",
width: "150",
prop: "sectionName",
},
{
label: "姓名",
label: "大厅",
align: "center",
width: "150",
prop: "hallName",
},
{
label: "手机号",
label: "评价来源",
align: "center",
width: "150",
prop: "pjSource",
},
{
label: "工作人员",
label: "手输意见",
align: "center",
width: "150",
prop: "opinion",
},
{
label: "工号",
align: "center",
width: "150",
},
{
label: "取号方式",
label: "窗口名",
align: "center",
width: "150",
prop: "windowName",
},
{
label: "部门名称",
label: "窗口编号",
align: "center",
width: "150",
prop: "windowFromnum",
},
{
label: "大厅名称",
label: "窗口评价",
align: "center",
width: "150",
prop: "pjxt",
},
{
label: "取号时间",
label: "工作人员",
align: "center",
width: "150",
prop: "workmanName",
},
{
label: "叫号时间",
label: "工号",
align: "center",
width: "150",
prop: "workmanNumber",
},
{
label: "结束时间",
label: "评价状态",
align: "center",
width: "150",
prop: "evaluatestatus",
},
{
label: "等待时间",
label: "评价指向",
align: "center",
width: "150",
prop: "pjType",
},
{
label: "办理时间",
label: "评价时间",
align: "center",
width: "150",
prop: "pjTime",
},
{
label: "扩展编号",
align: "center",
width: "150",
prop: "extNum",
},
{
label: "操作",
......@@ -297,14 +354,146 @@ export default {
],
};
},
created() {
this.getEvaluateList();
this.getDepartment();
this.getHall();
},
methods: {
// 获取站点
getSite(data) {
this.current = 1;
this.size = 10;
if (data.type == "site") {
this.searchForm.siteId = data.id;
this.getEvaluateList();
this.getDepartment();
this.getHall();
} else {
this.tableData = [];
this.total = 0;
}
},
// 获取数据函数
async getData(form = {}) {
let obj = {
page: this.current,
size: this.size,
pjTimeStart: this.searchForm.time[0],
pjTimeEnd: this.searchForm.time[1],
siteId: this.searchForm.siteId,
};
let val = `%${this.searchForm.keyword}%`;
switch (this.searchForm.type) {
case 1:
obj.windowFromnum = val;
break;
case 2:
obj.peopleName = val;
break;
case 3:
obj.peoplePhone = val;
break;
}
let res = await getEvaluateList({
...obj,
...this.searchForm2,
...form,
});
if (res.data.code == 1) {
return res.data.data;
} else {
return {
data: [],
total: 0,
};
}
},
// 获取表格数据
async getEvaluateList(form = {}) {
this.loading = true;
let { data, total } = await this.getData(form);
data.forEach((v) => {
v.pjTime = this.$moment(v.pjTime).format("YYYY-MM-DD HH:mm:ss");
});
this.tableData = data;
this.total = total;
this.loading = false;
},
// 获取站点部门
async getDepartment() {
let res = await getDepartment({
page: 1,
size: -1,
siteId: this.searchForm.siteId,
});
if (res.data.code == 1) {
let { data } = res.data.data;
this.deptList = data;
}
},
// 获取大厅
async getHall() {
let res = await getHall({
page: 1,
size: -1,
siteId: this.searchForm.siteId,
});
if (res.data.code == 1) {
let { data } = res.data.data;
this.hallList = data;
}
},
checkDetails(row) {
console.log(row);
let data = this.$cloneDeep(row);
this.detailsInfo = data;
this.show = true;
},
handleSelectionChange(rows) {
this.selectionRows = rows;
},
handleSearch() {
this.current = 1;
this.$clearSelection("MyTable");
this.getEvaluateList();
},
// 导出表格
exportExcel() {
this.exportLoading = true;
let table = this.column.filter((v) => v.prop);
let tHeader = table.map((v) => v.label);
let filterVal = table.map((v) => v.prop);
if (this.selectionRows.length) {
let data = this.$cloneDeep(this.selectionRows);
export2Excel(
tHeader,
filterVal,
data,
"评价数据报表" + this.$moment().format("YYYYMMDDHHmmss")
);
} else {
dataSection(this.getData, {}, (data) => {
if (!data.length) {
this.$message.warning("暂无数据");
return;
}
data.forEach((v) => {
v.pjTime = this.$moment(v.pjTime).format("YYYY-MM-DD HH:mm:ss");
});
export2Excel(
tHeader,
filterVal,
data,
"评价数据报表" + this.$moment().format("YYYYMMDDHHmmss")
);
});
}
this.exportLoading = false;
},
},
};
</script>
......
......@@ -172,45 +172,6 @@ export default {
size: 10,
current: 1,
selectionRow: [],
pickerOptions: {
shortcuts: [
{
text: "今天",
onClick(picker) {
const end = new Date();
const start = new Date();
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一周",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
],
},
searchForm: {
type: 1,
keyword: "",
......@@ -346,49 +307,30 @@ export default {
align: "center",
width: "150",
prop: "taketime",
formatter: (row) => {
return this.$moment(row.taketime).format("YYYY-MM-DD HH:mm:ss");
},
},
{
label: "叫号时间",
align: "center",
width: "150",
prop: "calltime",
formatter: (row) => {
return this.$moment(row.taketime).format("YYYY-MM-DD HH:mm:ss");
},
},
{
label: "结束时间",
align: "center",
width: "150",
prop: "endtime",
formatter: (row) => {
return this.$moment(row.taketime).format("YYYY-MM-DD HH:mm:ss");
},
},
{
label: "等待时间",
align: "center",
width: "150",
prop: "waitTime",
formatter: (row) => {
if (row.waitTime) {
return formatSeconds(row.waitTime);
}
},
},
{
label: "办理时间",
align: "center",
width: "150",
prop: "handleTime",
formatter: (row) => {
if (row.handleTime) {
return formatSeconds(row.handleTime);
}
},
},
{
label: "扩展编号",
......@@ -478,6 +420,16 @@ export default {
async getQueueList(form = {}) {
this.loading = true;
let { data, total } = await this.getData(form);
data.forEach((v) => {
v.taketime =
v.taketime && this.$moment(v.taketime).format("YYYY-MM-DD HH:mm:ss");
v.endtime =
v.endtime && this.$moment(v.endtime).format("YYYY-MM-DD HH:mm:ss");
v.calltime =
v.calltime && this.$moment(v.calltime).format("YYYY-MM-DD HH:mm:ss");
v.waitTime = v.waitTime && formatSeconds(v.waitTime);
v.handleTime = v.handleTime && formatSeconds(v.handleTime);
});
this.tableData = data;
this.total = total;
this.loading = false;
......@@ -530,18 +482,6 @@ export default {
let filterVal = table.map((v) => v.prop);
if (this.selectionRow.length) {
let data = this.$cloneDeep(this.selectionRow);
data.forEach((v) => {
v.taketime =
v.taketime &&
this.$moment(v.taketime).format("YYYY-MM-DD HH:mm:ss");
v.endtime =
v.endtime && this.$moment(v.endtime).format("YYYY-MM-DD HH:mm:ss");
v.calltime =
v.calltime &&
this.$moment(v.calltime).format("YYYY-MM-DD HH:mm:ss");
v.waitTime = v.waitTime && formatSeconds(v.waitTime);
v.handleTime = v.handleTime && formatSeconds(v.handleTime);
});
export2Excel(
tHeader,
filterVal,
......
......@@ -12,15 +12,37 @@
size="medium"
labelClassName="label-name"
>
<template v-for="(v, i) in dataInfo">
<el-descriptions-item
v-for="(v, i) in detailsList"
v-if="
(v.prop == 'photoautograph' || v.prop == 'picture') && v.content
"
:key="i"
:label="v.title"
>
<img
class="w-[50px] cursor-pointer"
:src="v.content"
@click="handlePreview(v.content)"
/>
</el-descriptions-item>
<el-descriptions-item v-else :key="i" :label="v.title">
{{ v.content }}
</el-descriptions-item>
</template>
</el-descriptions>
</div>
<!-- 图片查看 -->
<el-image-viewer
v-if="preview"
:appendToBody="false"
:on-close="
() => {
(preview = false), (filepaths = []);
}
"
:url-list="filepaths"
/>
</el-drawer>
</template>
......@@ -31,129 +53,166 @@ export default {
type: Boolean,
default: false,
},
info: {
required: true,
type: Object,
default: () => {},
},
},
data() {
return {
preview: false,
filepaths: [],
detailsList: [
{
title: "身份证号",
content: "测试",
prop: "peopleIdcard",
content: "",
},
{
title: "姓名",
content: "测试",
prop: "peopleName",
content: "",
},
{
title: "性别",
content: "测试",
prop: "peopleSex",
content: "",
},
{
title: "手机号",
content: "测试",
prop: "peoplePhone",
content: "",
},
{
title: "评价选项",
content: "测试",
prop: "pjOption",
content: "",
},
{
title: "评价标签",
content: "测试",
prop: "contentTag",
content: "",
},
{
title: "评价人图片地址",
content: "测试",
prop: "picUrl",
content: "",
},
{
title: "部门",
content: "测试",
prop: "sectionName",
content: "",
},
{
title: "大厅名称",
content: "测试",
prop: "hallName",
content: "",
},
{
title: "评价来源",
content: "测试",
prop: "pjSource",
content: "",
},
{
title: "手输意见",
content: "测试",
prop: "opinion",
content: "",
},
{
title: "窗口名称",
content: "测试",
prop: "windowName",
content: "",
},
{
title: "窗口编号",
content: "测试",
prop: "windowFromnum",
content: "",
},
{
title: "排队编号",
content: "测试",
prop: "flounum",
content: "",
},
{
title: "窗口评价",
content: "测试",
prop: "pjxt",
content: "",
},
{
title: "工作人员姓名",
content: "测试",
prop: "workmanName",
content: "",
},
{
title: "工作人员工号",
content: "测试",
prop: "workmanNumber",
content: "",
},
{
title: "评价器MAC地址",
content: "测试",
prop: "devicenum",
content: "",
},
{
title: "评价状态",
content: "测试",
prop: "evaluatestatus",
content: "",
},
{
title: "截图还是评价",
content: "测试",
prop: "evaluatetype",
content: "",
},
{
title: "截图地",
content: "测试",
title: "截图地址",
prop: "photobefor",
content: "",
},
{
title: "签字图片",
content: "测试",
prop: "photoautograph",
content: "",
},
{
title: "抓拍评价人照片",
content: "测试",
prop: "picture",
content: "",
},
{
title: "音视频地址",
content: "测试",
prop: "process",
content: "",
},
{
title: "评价标记",
content: "测试",
prop: "eyevaluate",
content: "",
},
{
title: "评价指向",
content: "测试",
prop: "pjType",
content: "",
},
{
title: "评价时间",
content: "测试",
prop: "pjTime",
content: "",
},
{
title: "站点编码",
content: "测试",
prop: "siteCode",
content: "",
},
{
title: "站点名称",
content: "测试",
prop: "siteName",
content: "",
},
{
title: "扩展编号",
content: "测试",
prop: "extNum",
content: "",
},
],
};
......@@ -167,12 +226,24 @@ export default {
this.$emit("update:show", val);
},
},
dataInfo() {
this.detailsList.forEach((v) => {
v.content = this.info[v.prop];
});
return this.detailsList;
},
},
methods: {
handlePreview(url) {
this.filepaths = [url];
this.preview = true;
},
},
};
</script>
<style lang="less" scoped>
:deep(.label-name) {
width: 180px !important;
width: 120px !important;
}
</style>
......@@ -25,7 +25,6 @@
</template>
<script>
import { formatSeconds } from "@/utils";
export default {
props: {
show: {
......@@ -190,15 +189,7 @@ export default {
},
dataInfo() {
this.detailsList.forEach((v) => {
if (v.prop == "taketime" || v.prop == "endtime") {
v.content = this.$moment(this.info[v.prop]).format(
"YYYY-MM-DD HH:mm:ss"
);
} else if (v.prop == "waitTime" || v.prop == "handleTime") {
v.content = formatSeconds(this.info[v.prop]);
} else {
v.content = this.info[v.prop];
}
});
return this.detailsList;
},
......
......@@ -148,7 +148,7 @@ export const dataSection = async (fn, searchForm = {}, callback) => {
dataList = [...dataList, ...data];
Vue.prototype.$app.loading = true;
Vue.prototype.$app.percentage = parseInt((dataList.length / total) * 100);
if (dataList.length >= total || data.data.length == 0) {
if (dataList.length >= total || data.length == 0) {
if (callback) callback(dataList);
Vue.prototype.$app.loading = false;
Vue.prototype.$app.percentage = 1;
......
......@@ -10,6 +10,13 @@ module.exports = defineConfig({
// "^/file": "",
// }
},
"/uploads": {
target: process.env.VUE_APP_API_BASE_URL,
changeOrigin: true,
// pathRewrite:{
// "^/file": "",
// }
},
},
},
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment