Learn.Archives.Web/src/views/toschoolinfomanage/index.vue

507 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<!-- 搜索区域 -->
<el-form :model="query" inline class="search-form">
<el-form-item label="学校">
<el-select
v-model="query.school"
placeholder="请选择学校"
clearable
filterable
style="width: 180px"
>
<el-option
v-for="s in schoolOptions"
:key="s.value"
:label="s.label"
:value="s.value"
/>
</el-select>
</el-form-item>
<el-form-item label="年级">
<el-select
v-model="query.grade"
placeholder="请选择年级"
clearable
style="width: 140px"
>
<el-option
v-for="g in gradeOptions"
:key="g.value"
:label="g.label"
:value="g.value"
/>
</el-select>
</el-form-item>
<el-form-item label="赴校人员">
<el-select
v-model="query.people"
placeholder="请选择赴校人员"
clearable
filterable
style="width: 300px"
>
<el-option
v-for="p in peopleOptions"
:key="p.value"
:label="p.text"
:value="p.value"
/>
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-select
v-model="query.solutionEnd"
placeholder="请选择状态"
clearable
style="width: 140px"
>
<el-option label="已完结" :value="true" />
<el-option label="跟进中" :value="false" />
</el-select>
</el-form-item>
<el-form-item label="赴校时间">
<el-date-picker
v-model="query.times"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="YYYY-MM-DD"
unlink-panels
style="width: 300px"
/>
</el-form-item>
<el-form-item> </el-form-item>
</el-form>
<!-- 操作按钮区域 -->
<div style="margin-bottom: 15px">
<el-button type="primary" :icon="Search" @click="handleSearch">查询</el-button>
<el-button @click="handleReset">重置</el-button>
</div>
<!-- 操作按钮区域 -->
<div style="margin-bottom: 10px">
<el-button type="primary" @click="handleAdd">新建</el-button>
<el-button type="success" @click="handleImport">批量导入</el-button>
<el-button type="info" @click="handleExport">导出</el-button>
<el-button type="info" @click="downLoadTpl">下载模版</el-button>
</div>
<!-- 表格区域 -->
<el-table :data="listData" style="width: 100%" :max-height="500">
<el-table-column label="操作" width="200">
<template #default="{ row }">
<!-- <el-button size="small" type="danger" plain @click="onDelete(row)"
>删除</el-button
> -->
<el-popconfirm
confirm-button-text="确定"
cancel-button-text="取消"
icon-color="#626AEF"
title="确定删除吗?"
@confirm="onDelete(row)"
>
<template #reference>
<el-button type="danger" text size="small">删除</el-button>
</template>
</el-popconfirm>
<el-button size="small" type="primary" text @click="onDetailOrFollow(row, true)"
>详情</el-button
>
<el-button
v-if="row.canOperate && !row.solutionEnd"
size="small"
type="success"
text
@click="onDetailOrFollow(row, false)"
>跟进</el-button
>
</template>
</el-table-column>
<el-table-column prop="school" label="学校" min-width="140" />
<el-table-column label="状态" min-width="80">
<template #default="{ row }">
<el-tag :type="row.solutionEnd ? 'success' : 'warning'">
{{ row.solutionEnd ? "已完结" : "跟进中" }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="grade" label="年级" min-width="100" />
<el-table-column prop="people" label="赴校人员" min-width="120" />
<el-table-column prop="times" label="赴校时间" min-width="140" />
<el-table-column prop="feedbackTotals" label="反馈问题数量" min-width="140" />
<el-table-column prop="solveTotals" label="解决问题数量" min-width="140" />
<!-- <el-table-column prop="lastTime" label="最后跟进时间" min-width="160" /> -->
</el-table>
<!-- 分页 -->
<div class="pager">
<el-pagination
background
layout="total, sizes, prev, pager, next, jumper"
:total="total"
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 20, 50, 100]"
@current-change="handlePageChange"
@size-change="handleSizeChange"
/>
</div>
<!-- 新建 -->
<AddModal v-model:visible="isShowAddModal" @handleReset="handleReset" />
<!-- 跟进 -->
<EditModal
v-model:visible="isShowEditModal"
:editModalLoading="editModalLoading"
:detailData="detailData"
:isDetail="isDetail"
@handleReset="handleReset"
/>
</div>
</template>
<!-- 赴校信息管理菜单 -->
<script setup lang="ts" name="Toschoolinfomanage">
import {
addOrEditApi,
getPageListApi,
getSchoolBusinessDetailApi,
deleteSchoolBusinessApi,
getSchoolBusinessPeopleListApi,
importExcel,
} from "@/api/toschoolinfomanage";
import { getSchoolData } from "@/api/userCenter";
import { ref, reactive, computed, onMounted } from "vue";
import dayjs from "dayjs";
import { ElMessage } from "element-plus";
import AddModal from "./addModal.vue";
import { Check, Search } from "@element-plus/icons-vue";
import EditModal from "./editModal.vue";
import { message } from "@/utils/message";
interface TableItem {
id: number;
school: string;
grade: string;
people: string;
canOperate: boolean; // 是否可以跟进
times: string; // YYYY-MM-DD
feedbackTotals: number;
solveTotals: number;
solutionEnd: boolean; // true: 已完结, false: 跟进中
lastTime: string; // YYYY-MM-DD
}
const schoolOptions = ref([]);
const peopleOptions = ref([]);
const isDetail = ref(false);
/**
* 获取学校下拉数据
*/
const getSchoolDataFn = () => {
getSchoolData().then((res) => {
if (res.code == 200) {
schoolOptions.value = res.data.map((i: any) => ({
label: i.text,
value: i.value,
}));
}
});
};
/**
* 获取赴校人员下拉数据
*/
const getSchoolBusinessPeopleList = () => {
getSchoolBusinessPeopleListApi({}).then((res: any) => {
if (res.code == 200) {
peopleOptions.value = (res.data || []).map((i) => {
return {
value: i.text,
text: i.text,
};
});
}
});
};
const isShowAddModal = ref(false);
const isShowEditModal = ref(false);
const editModalLoading = ref(false);
const detailData = ref({});
onMounted(() => {
// addOrEdit();
loadList();
getSchoolDataFn();
getSchoolBusinessPeopleList();
});
const gradeOptions = [
{ label: "初一", value: "初一" },
{ label: "初二", value: "初二" },
{ label: "初三", value: "初三" },
{ label: "高一", value: "高一" },
{ label: "高二", value: "高二" },
{ label: "高三", value: "高三" },
];
/**
* 新建赴校信息提交
*/
const addOrEdit = () => {
addOrEditApi({
id: 0, //id传0代表新增
schoolId: 10079,
schoolName: "系统测试学校",
grade: "初二",
gradeLevel: "",
schoolBusinessUser: ["刘德华123"],
startTime: "2025-07-24T07:28:38",
// remark: "string",
feedbackQuestions: [
{
question: "xb测试反馈问题1双师课堂",
questionType: 10,
sort: "1111111111",
},
// {
// question: "xb测试反馈问题2设备",
// questionType: 15,
// sort: "2"
// },
// {
// question: "xb测试反馈问题2学生",
// questionType: 20,
// sort: "3"
// }
],
isDiscussion: true,
discussion: "开展座谈座谈座谈座谈座谈座谈座谈座谈座谈座谈座谈座谈座谈座谈",
isClassMeeting: true,
classMeeting: "班会情况班会情况班会情况班会情况班会情况班会情况班会情况",
});
};
const query = reactive({
school: "" as string | undefined,
grade: "" as string | undefined,
people: "" as string | undefined,
solutionEnd: undefined,
times: [] as string[],
});
const page = ref(1);
const pageSize = ref(10);
const total = ref(0);
const listData = ref<TableItem[]>([]);
function mapApiItemToRow(item: any): TableItem {
const peopleArr = Array.isArray(item.schoolBusinessUser) ? item.schoolBusinessUser : [];
const start = item.startTime ? dayjs(item.startTime).format("YYYY-MM-DD") : "";
let last = start;
const rec = item.solutionRecord?.record || [];
if (Array.isArray(rec) && rec.length > 0) {
const maxTs = rec
.map((r: any) => r.executionTime)
.filter(Boolean)
.map((t: string) => dayjs(t).valueOf())
.reduce((a: number, b: number) => Math.max(a, b), 0);
if (maxTs) last = dayjs(maxTs).format("YYYY-MM-DD");
}
return {
id: item.id,
school: item.schoolName || "",
grade: item.grade || "",
people: peopleArr.join(""),
times: start,
canOperate: item.canOperate || false, // 是否可以跟进
feedbackTotals: Number(item.feedbackCount) || 0,
solveTotals: Number(item.solveFeedbackCount) || 0,
solutionEnd: item.solutionEnd,
lastTime: last,
};
}
async function loadList() {
const payload: any = {
pageIndex: page.value,
pageSize: pageSize.value,
orderBy: "startTime",
};
if (query.school) payload.schoolId = query.school;
if (query.grade) payload.grade = query.grade;
if (query.people) {
payload.UserName = query.people;
}
if (typeof query.solutionEnd !== "undefined") payload.solutionEnd = query.solutionEnd;
if (Array.isArray(query.times) && query.times.length === 2) {
payload.startTime = query.times[0];
payload.endTime = query.times[1];
}
try {
const res = await getPageListApi(payload);
if (res.code === 200) {
const rows = Array.isArray(res.data?.data) ? res.data.data : [];
listData.value = rows.map(mapApiItemToRow);
total.value = Number(res.data?.total) || rows.length;
} else {
ElMessage.error(res.message || "加载失败");
}
} catch (e) {
ElMessage.error("列表加载失败");
}
}
function rand(min: number, max: number) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function randomDate(start: string, end: string) {
const startTs = dayjs(start).valueOf();
const endTs = dayjs(end).valueOf();
const v = rand(startTs, endTs);
return dayjs(v).format("YYYY-MM-DD");
}
function handleSearch() {
page.value = 1;
loadList();
}
function handleReset() {
query.school = "";
query.grade = "";
query.people = "";
query.solutionEnd = undefined;
query.times = [];
page.value = 1;
loadList();
}
function handlePageChange(p: number) {
page.value = p;
loadList();
}
function handleSizeChange(s: number) {
pageSize.value = s;
page.value = 1;
loadList();
}
function onDelete(row: TableItem) {
console.log(`删除`, row);
deleteSchoolBusinessApi([row.id]).then((res) => {
if (res.code === 200) {
message("删除成功", { type: "success" });
loadList();
}
});
}
/**
* 详情或者跟进
* @param row
*/
function onDetailOrFollow(row: TableItem, disabled = false) {
isDetail.value = disabled;
isShowEditModal.value = true;
editModalLoading.value = true;
getSchoolBusinessDetailApi(row.id)
.then((res) => {
if (res.code === 200 && res.data) {
detailData.value = res.data;
}
})
.finally(() => {
editModalLoading.value = false;
});
}
/**
* 跟进
* @param row
*/
// function onFollow(row: TableItem) {
// isShowEditModal.value = true;
// editModalLoading.value = true;
// console.log(`跟进`);
// getSchoolBusinessDetailApi(row.id)
// .then(res => {
// if (res.code === 200 && res.data) {
// detailData.value = res.data;
// }
// })
// .finally(() => {
// editModalLoading.value = false;
// });
// }
function handleAdd() {
console.log("新建");
isShowAddModal.value = true;
}
function handleImport() {
console.log("批量导入");
let fileE = document.createElement("input");
fileE.type = "file";
var formData = new window.FormData();
fileE.onchange = async function () {
formData.append("file", fileE.files[0]);
let res = await importExcel(fileE.files[0]);
if (res.code != undefined) {
if (res.code !== 200) return ElMessage.error(res.message);
else {
loadList();
return ElMessage.success("所有数据录入成功");
}
} else if (res.type === "application/json") {
let json = await res.text();
if (json !== undefined && json.Code !== 200) {
return ElMessage.error(json.Message);
} else {
loadList();
return ElMessage.success("所有数据录入成功");
}
} else if (res === undefined || res.size === 0) {
loadList();
return ElMessage.success("所有数据录入成功");
}
const url = res && window.URL.createObjectURL(res);
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", "未成功导入的考试信息数据" + ".xlsx");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
ElMessage.success("导入失败,已导出错误数据");
};
try {
fileE.click();
} catch (error) {}
}
function handleExport() {
console.log("导出");
}
function downLoadTpl() {
console.log("下载模版");
const baseUrl = import.meta.env.VITE_API_BASEURL;
const excelImportUsersUrl = `${baseUrl}/SchoolBusiness/DwImportTemplate`;
const link = document.createElement("a");
link.href = excelImportUsersUrl;
link.setAttribute("download", "导入赴校信息模板" + ".xlsx");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
ElMessage.success("下载成功!");
}
</script>
<style lang="scss" scoped>
.search-form {
margin-bottom: 0px;
}
.pager {
display: flex;
justify-content: center;
margin-top: 12px;
}
</style>