Compare commits
No commits in common. "9d647f8645ee3ca5e2f328a6b7f154496005a68f" and "26d075953ed24d6a1cca4b136b911edd6912e4ab" have entirely different histories.
9d647f8645
...
26d075953e
|
|
@ -1,23 +0,0 @@
|
||||||
import { http } from "@/utils/http";
|
|
||||||
import type { Res } from "@/utils/http/types";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description 获取学校枚举下拉
|
|
||||||
* @param {string} type 枚举类型 type=StatusEnum
|
|
||||||
* @return {object}
|
|
||||||
*/
|
|
||||||
export function getenum(data) {
|
|
||||||
return http.request<Res<any>>("post", `/back/schools/QueryCombo`, {
|
|
||||||
data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @description 获取学校枚举下拉
|
|
||||||
* @param {string} type 枚举类型 type=StatusEnum
|
|
||||||
* @return {object}
|
|
||||||
*/
|
|
||||||
export function getPageList(data) {
|
|
||||||
return http.request<Res<any>>("post", `/SchoolBusiness/QueryPageList`, {
|
|
||||||
data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -20,9 +20,6 @@ import { Dialog, TableColumn, TableConfig } from "./hTable";
|
||||||
import hTableEdit from "./hTableEdit.vue";
|
import hTableEdit from "./hTableEdit.vue";
|
||||||
import { hTableAPI } from "@/api/hTable";
|
import { hTableAPI } from "@/api/hTable";
|
||||||
import { getenum } from "@/api/enum";
|
import { getenum } from "@/api/enum";
|
||||||
//按钮权限
|
|
||||||
import { hasPerms } from "@/utils/auth";
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
//** 传入的表单数据 */
|
//** 传入的表单数据 */
|
||||||
Row: {
|
Row: {
|
||||||
|
|
@ -281,7 +278,7 @@ function handleReloadPaged(reload = true) {
|
||||||
data.ConditionalType = "Like";
|
data.ConditionalType = "Like";
|
||||||
}
|
}
|
||||||
data.FieldName = name.charAt(0).toUpperCase() + name.slice(1);
|
data.FieldName = name.charAt(0).toUpperCase() + name.slice(1);
|
||||||
data.FieldValue = table.value.column[name].value.toString();
|
data.FieldValue = table.value.column[name].value;
|
||||||
|
|
||||||
if (table.value.column[name].searchType != undefined) {
|
if (table.value.column[name].searchType != undefined) {
|
||||||
data.ConditionalType = table.value.column[name].searchType || 0;
|
data.ConditionalType = table.value.column[name].searchType || 0;
|
||||||
|
|
@ -303,10 +300,11 @@ async function fetchInitData() {
|
||||||
const element = table.value.column[key];
|
const element = table.value.column[key];
|
||||||
if (element.type === "dropdown") {
|
if (element.type === "dropdown") {
|
||||||
if (!element.setting.datasource) {
|
if (!element.setting.datasource) {
|
||||||
// 不安全取消 存在值就不处理
|
// 存在值就不处理
|
||||||
// let rdata = await eval(element.setting.datasourceStr);
|
|
||||||
// element.setting.datasource = rdata.data;
|
let rdata = await eval(element.setting.datasourceStr);
|
||||||
// console.log(key + " " + element.setting.datasourceStr, rdata);
|
element.setting.datasource = rdata.data;
|
||||||
|
console.log(key + " " + element.setting.datasourceStr, rdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
|
|
@ -382,9 +380,9 @@ function fetchPagedData() {
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-if="o.type.trim() == 'datetime'"
|
v-if="o.type.trim() == 'datetime'"
|
||||||
v-model="o.value as Date"
|
v-model="o.value as Date"
|
||||||
|
format="yyyy-MM-dd"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
type="date"
|
type="date"
|
||||||
format="YYYY-MM-DD"
|
|
||||||
value-format="YYYY-MM-DD"
|
|
||||||
:placeholder="o.label"
|
:placeholder="o.label"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
|
|
@ -399,7 +397,7 @@ function fetchPagedData() {
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in o.setting.datasource"
|
v-for="item in o.setting.datasource"
|
||||||
:key="item.value"
|
:key="item.Value"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
:label="item[o.setting.maplabel]"
|
:label="item[o.setting.maplabel]"
|
||||||
:value="item[o.setting.mapValue]"
|
:value="item[o.setting.mapValue]"
|
||||||
|
|
@ -466,9 +464,7 @@ function fetchPagedData() {
|
||||||
<div v-if="table.operationTop" class="toolbar-container">
|
<div v-if="table.operationTop" class="toolbar-container">
|
||||||
<!-- 头部按钮组 -->
|
<!-- 头部按钮组 -->
|
||||||
<el-button
|
<el-button
|
||||||
v-for="(e, i) in table.operationColumnData.filter(
|
v-for="(e, i) in table.operationColumnData.filter(s => s.topBtn)"
|
||||||
s => s.topBtn && hasPerms(s.perms)
|
|
||||||
)"
|
|
||||||
v-show="execute(e['show'], {}, e)"
|
v-show="execute(e['show'], {}, e)"
|
||||||
:key="i"
|
:key="i"
|
||||||
:type="e.btnStyle || 'info'"
|
:type="e.btnStyle || 'info'"
|
||||||
|
|
@ -499,9 +495,7 @@ function fetchPagedData() {
|
||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<div class="columnTemplate">
|
<div class="columnTemplate">
|
||||||
<el-button
|
<el-button
|
||||||
v-for="(e, i) in table.operationColumnData.filter(
|
v-for="(e, i) in table.operationColumnData.filter(s => !s.topBtn)"
|
||||||
s => !s.topBtn && hasPerms(s.perms)
|
|
||||||
)"
|
|
||||||
v-show="execute(e['show'], scope, e)"
|
v-show="execute(e['show'], scope, e)"
|
||||||
:key="i"
|
:key="i"
|
||||||
class="btn"
|
class="btn"
|
||||||
|
|
@ -577,28 +571,26 @@ function fetchPagedData() {
|
||||||
.columnTemplate .btn {
|
.columnTemplate .btn {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.columnTemplate {
|
.columnTemplate {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
place-content: flex-start flex-start;
|
|
||||||
align-items: center;
|
|
||||||
-webkit-box-orient: horizontal;
|
-webkit-box-orient: horizontal;
|
||||||
-webkit-box-direction: normal;
|
-webkit-box-direction: normal;
|
||||||
|
-ms-flex-direction: row;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sty .tab_tip {
|
.sty .tab_tip {
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-container {
|
.toolbar-container {
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.maxWidth600px {
|
.maxWidth600px {
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,354 +0,0 @@
|
||||||
<!-- 新建赴校信息 -->
|
|
||||||
<template>
|
|
||||||
<el-dialog
|
|
||||||
v-model="dialogVisible"
|
|
||||||
title="新建赴校信息"
|
|
||||||
width="800px"
|
|
||||||
align-center
|
|
||||||
>
|
|
||||||
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
|
||||||
<el-divider>基础信息</el-divider>
|
|
||||||
<el-row :gutter="12">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="学校" prop="baseInfo.school">
|
|
||||||
<el-select
|
|
||||||
v-model="form.baseInfo.school"
|
|
||||||
placeholder="请选择学校"
|
|
||||||
clearable
|
|
||||||
filterable
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="s in schoolOptions"
|
|
||||||
:key="s.value"
|
|
||||||
:label="s.label"
|
|
||||||
:value="s.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="年级" prop="baseInfo.grade">
|
|
||||||
<el-select
|
|
||||||
v-model="form.baseInfo.grade"
|
|
||||||
placeholder="请选择年级"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="g in gradeOptions"
|
|
||||||
:key="g.value"
|
|
||||||
:label="g.label"
|
|
||||||
:value="g.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="赴校时间" prop="baseInfo.date">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="form.baseInfo.date"
|
|
||||||
type="date"
|
|
||||||
value-format="YYYY-MM-DD"
|
|
||||||
placeholder="请选择日期"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="赴校人员" prop="baseInfo.people">
|
|
||||||
<el-input
|
|
||||||
v-model="form.baseInfo.people"
|
|
||||||
placeholder="请输入人员姓名,逗号分隔"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-divider>基础工作</el-divider>
|
|
||||||
<el-row :gutter="12">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="开展座谈" prop="work.talk">
|
|
||||||
<el-radio-group v-model="form.work.talk">
|
|
||||||
<el-radio :label="true">是</el-radio>
|
|
||||||
<el-radio :label="false">否</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="座谈情况">
|
|
||||||
<el-input
|
|
||||||
v-model="form.work.talkDetail"
|
|
||||||
:disabled="!form.work.talk"
|
|
||||||
placeholder="请输入座谈情况"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="开展班会" prop="work.classMeeting">
|
|
||||||
<el-radio-group v-model="form.work.classMeeting">
|
|
||||||
<el-radio :label="true">是</el-radio>
|
|
||||||
<el-radio :label="false">否</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="班会情况">
|
|
||||||
<el-input
|
|
||||||
v-model="form.work.classMeetingDetail"
|
|
||||||
:disabled="!form.work.classMeeting"
|
|
||||||
placeholder="请输入班会情况"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-divider>反馈问题</el-divider>
|
|
||||||
<div style="height: 370px; overflow-y: auto">
|
|
||||||
<div
|
|
||||||
v-for="group in feedbackGroups"
|
|
||||||
:key="group.key"
|
|
||||||
class="feedback-group"
|
|
||||||
>
|
|
||||||
<div class="feedback-header">
|
|
||||||
<span class="group-title">{{ group.name }}</span>
|
|
||||||
<el-button type="primary" link @click="addProblem(group.key)"
|
|
||||||
>添加问题</el-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="form.feedback[group.key].length === 0"
|
|
||||||
class="feedback-empty"
|
|
||||||
>
|
|
||||||
暂无问题
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-for="(item, idx) in form.feedback[group.key]"
|
|
||||||
:key="item.id"
|
|
||||||
class="feedback-item"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="item.text"
|
|
||||||
:placeholder="`请输入${group.name}问题描述`"
|
|
||||||
/>
|
|
||||||
<el-button type="danger" text @click="removeProblem(group.key, idx)"
|
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<el-divider />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="onCancel">取 消</el-button>
|
|
||||||
<el-button type="primary" :loading="submitting" @click="onSubmit"
|
|
||||||
>确 定</el-button
|
|
||||||
>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="AddModal">
|
|
||||||
import { ref, reactive, computed } from "vue";
|
|
||||||
import type { FormInstance, FormRules } from "element-plus";
|
|
||||||
import { ElMessage } from "element-plus";
|
|
||||||
|
|
||||||
const props = defineProps<{ visible: boolean }>();
|
|
||||||
const emit = defineEmits<{ (e: "update:visible", value: boolean): void }>();
|
|
||||||
const dialogVisible = computed({
|
|
||||||
get: () => props.visible,
|
|
||||||
set: v => emit("update:visible", v)
|
|
||||||
});
|
|
||||||
|
|
||||||
const formRef = ref<FormInstance>();
|
|
||||||
function uid() {
|
|
||||||
return Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
||||||
}
|
|
||||||
|
|
||||||
const schoolOptions = ref([
|
|
||||||
{ label: "第一中学", value: "第一中学" },
|
|
||||||
{ label: "第二中学", value: "第二中学" },
|
|
||||||
{ label: "实验中学", value: "实验中学" },
|
|
||||||
{ label: "外国语学校", value: "外国语学校" }
|
|
||||||
]);
|
|
||||||
const gradeOptions = [
|
|
||||||
{ label: "高一", value: "高一" },
|
|
||||||
{ label: "高二", value: "高二" },
|
|
||||||
{ label: "高三", value: "高三" },
|
|
||||||
{ label: "初三", value: "初三" }
|
|
||||||
];
|
|
||||||
|
|
||||||
type FeedbackKey =
|
|
||||||
| "leaders"
|
|
||||||
| "classroom"
|
|
||||||
| "equipment"
|
|
||||||
| "students"
|
|
||||||
| "others";
|
|
||||||
interface FeedbackItem {
|
|
||||||
id: string;
|
|
||||||
text: string;
|
|
||||||
}
|
|
||||||
interface FormModel {
|
|
||||||
baseInfo: {
|
|
||||||
school?: string;
|
|
||||||
grade?: string;
|
|
||||||
date?: string;
|
|
||||||
people: string;
|
|
||||||
};
|
|
||||||
work: {
|
|
||||||
talk: boolean;
|
|
||||||
talkDetail: string;
|
|
||||||
classMeeting: boolean;
|
|
||||||
classMeetingDetail: string;
|
|
||||||
};
|
|
||||||
feedback: Record<FeedbackKey, FeedbackItem[]>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const form = reactive<FormModel>({
|
|
||||||
baseInfo: {
|
|
||||||
school: undefined,
|
|
||||||
grade: undefined,
|
|
||||||
date: undefined,
|
|
||||||
people: ""
|
|
||||||
},
|
|
||||||
work: {
|
|
||||||
talk: false,
|
|
||||||
talkDetail: "",
|
|
||||||
classMeeting: false,
|
|
||||||
classMeetingDetail: ""
|
|
||||||
},
|
|
||||||
feedback: {
|
|
||||||
leaders: [],
|
|
||||||
classroom: [],
|
|
||||||
equipment: [],
|
|
||||||
students: [],
|
|
||||||
others: []
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const rules: FormRules = {
|
|
||||||
"baseInfo.school": [
|
|
||||||
{ required: true, message: "请选择学校", trigger: "change" }
|
|
||||||
],
|
|
||||||
"baseInfo.grade": [
|
|
||||||
{ required: true, message: "请选择年级", trigger: "change" }
|
|
||||||
],
|
|
||||||
"baseInfo.date": [
|
|
||||||
{ required: true, message: "请选择赴校时间", trigger: "change" }
|
|
||||||
],
|
|
||||||
"baseInfo.people": [
|
|
||||||
{ required: true, message: "请输入赴校人员", trigger: "blur" }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
const feedbackGroups = [
|
|
||||||
{ key: "leaders", name: "学校领导班子" },
|
|
||||||
{ key: "classroom", name: "双师课堂" },
|
|
||||||
{ key: "equipment", name: "设备" },
|
|
||||||
{ key: "students", name: "学生" },
|
|
||||||
{ key: "others", name: "其他" }
|
|
||||||
] as { key: FeedbackKey; name: string }[];
|
|
||||||
|
|
||||||
function addProblem(key: FeedbackKey) {
|
|
||||||
form.feedback[key].push({ id: uid(), text: "" });
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeProblem(key: FeedbackKey, index: number) {
|
|
||||||
form.feedback[key].splice(index, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增:反馈问题非空校验
|
|
||||||
const feedbackGroupNameMap: Record<FeedbackKey, string> = {
|
|
||||||
leaders: "学校领导班子",
|
|
||||||
classroom: "双师课堂",
|
|
||||||
equipment: "设备",
|
|
||||||
students: "学生",
|
|
||||||
others: "其他"
|
|
||||||
};
|
|
||||||
function validateFeedbackNotEmpty() {
|
|
||||||
for (const g of feedbackGroups) {
|
|
||||||
const items = form.feedback[g.key] || [];
|
|
||||||
if (items.length === 0) continue; // 允许为 0
|
|
||||||
for (const it of items) {
|
|
||||||
if (!it.text || !it.text.trim()) {
|
|
||||||
ElMessage.error(`${feedbackGroupNameMap[g.key]} 的问题内容不能为空`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const submitting = ref(false);
|
|
||||||
|
|
||||||
function onCancel() {
|
|
||||||
dialogVisible.value = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onSubmit() {
|
|
||||||
if (!formRef.value) return;
|
|
||||||
await formRef.value.validate(valid => {
|
|
||||||
if (!valid) return;
|
|
||||||
// 新增:校验反馈问题不为空
|
|
||||||
if (!validateFeedbackNotEmpty()) return;
|
|
||||||
submitting.value = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
submitting.value = false;
|
|
||||||
console.log("Submit payload:", JSON.parse(JSON.stringify(form)));
|
|
||||||
ElMessage.success("提交成功(已使用假数据)");
|
|
||||||
dialogVisible.value = false;
|
|
||||||
resetForm();
|
|
||||||
}, 600);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetForm() {
|
|
||||||
form.baseInfo.school = undefined;
|
|
||||||
form.baseInfo.grade = undefined;
|
|
||||||
form.baseInfo.date = undefined;
|
|
||||||
form.baseInfo.people = "";
|
|
||||||
form.work.talk = false;
|
|
||||||
form.work.talkDetail = "";
|
|
||||||
form.work.classMeeting = false;
|
|
||||||
form.work.classMeetingDetail = "";
|
|
||||||
(Object.keys(form.feedback) as FeedbackKey[]).forEach(k => {
|
|
||||||
form.feedback[k] = [];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.feedback-group {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feedback-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin: 6px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-title {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feedback-item {
|
|
||||||
display: flex;
|
|
||||||
gap: 8px;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feedback-empty {
|
|
||||||
margin: 4px 0 8px;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-dialog__body) {
|
|
||||||
max-height: 70vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div style="padding: 20px">
|
<div>
|
||||||
<!-- 搜索区域 -->
|
<!-- 搜索区域 -->
|
||||||
<el-form :model="query" inline label-width="80px" class="search-form">
|
<el-form :model="query" inline label-width="80px" class="search-form">
|
||||||
<el-form-item label="学校">
|
<el-form-item label="学校">
|
||||||
|
|
@ -69,14 +69,9 @@
|
||||||
<el-button @click="handleReset">重置</el-button>
|
<el-button @click="handleReset">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<!-- 操作按钮区域 -->
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
<!-- 表格区域 -->
|
<!-- 表格区域 -->
|
||||||
<el-table :data="listData" border style="width: 100%">
|
<el-table :data="pagedData" border style="width: 100%">
|
||||||
<el-table-column prop="school" label="学校" min-width="140" />
|
<el-table-column prop="school" label="学校" min-width="140" />
|
||||||
<el-table-column prop="grade" label="年级" min-width="100" />
|
<el-table-column prop="grade" label="年级" min-width="100" />
|
||||||
<el-table-column prop="people" label="赴校人员" min-width="120" />
|
<el-table-column prop="people" label="赴校人员" min-width="120" />
|
||||||
|
|
@ -119,7 +114,7 @@
|
||||||
<el-pagination
|
<el-pagination
|
||||||
background
|
background
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
:total="total"
|
:total="filteredList.length"
|
||||||
:current-page="page"
|
:current-page="page"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:page-sizes="[10, 20, 50, 100]"
|
||||||
|
|
@ -128,15 +123,13 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<AddModal v-model:visible="isShowAddModal" />
|
|
||||||
</template>
|
</template>
|
||||||
<!-- 赴校信息管理菜单 -->
|
<!-- 赴校信息管理菜单 -->
|
||||||
<script setup lang="ts" name="Toschoolinfomanage">
|
<script setup lang="ts" name="Toschoolinfomanage">
|
||||||
import { getenum, getPageList } from "@/api/toschoolinfomanage";
|
import { ref, reactive, computed } from "vue";
|
||||||
import { ref, reactive, computed, onMounted } from "vue";
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import AddModal from "./addModal.vue";
|
|
||||||
interface TableItem {
|
interface TableItem {
|
||||||
id: number;
|
id: number;
|
||||||
school: string;
|
school: string;
|
||||||
|
|
@ -149,24 +142,12 @@ interface TableItem {
|
||||||
lastTime: string; // YYYY-MM-DD
|
lastTime: string; // YYYY-MM-DD
|
||||||
}
|
}
|
||||||
|
|
||||||
const schoolOptions = ref([
|
const schoolOptions = [
|
||||||
{ label: "第一中学", value: "第一中学" },
|
{ label: "第一中学", value: "第一中学" },
|
||||||
{ label: "第二中学", value: "第二中学" },
|
{ label: "第二中学", value: "第二中学" },
|
||||||
{ label: "实验中学", value: "实验中学" },
|
{ label: "实验中学", value: "实验中学" },
|
||||||
{ label: "外国语学校", value: "外国语学校" }
|
{ label: "外国语学校", value: "外国语学校" }
|
||||||
]);
|
];
|
||||||
const isShowAddModal = ref(false);
|
|
||||||
onMounted(() => {
|
|
||||||
getenum({ TextName: "Name", ValueName: "Id" }).then(res => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
schoolOptions.value = res.data.map(i => ({
|
|
||||||
label: i.text,
|
|
||||||
value: i.value
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
loadList();
|
|
||||||
});
|
|
||||||
|
|
||||||
const gradeOptions = [
|
const gradeOptions = [
|
||||||
{ label: "高一", value: "高一" },
|
{ label: "高一", value: "高一" },
|
||||||
|
|
@ -183,69 +164,11 @@ const query = reactive({
|
||||||
times: [] as string[]
|
times: [] as string[]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 点击查询后生效的条件,避免输入框每次输入都触发筛选
|
||||||
|
const appliedQuery = ref({ ...query });
|
||||||
|
|
||||||
const page = ref(1);
|
const page = ref(1);
|
||||||
const pageSize = ref(10);
|
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,
|
|
||||||
feedbackTotals: Number(item.feedbackCount) || 0,
|
|
||||||
solveTotals: Number(item.solveFeedbackCount) || 0,
|
|
||||||
status: item.solutionEnd ? 1 : 2,
|
|
||||||
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.people = query.people.trim();
|
|
||||||
if (typeof query.status !== "undefined")
|
|
||||||
payload.solutionEnd = query.status === 1;
|
|
||||||
if (Array.isArray(query.times) && query.times.length === 2) {
|
|
||||||
payload.startTimeBegin = query.times[0];
|
|
||||||
payload.startTimeEnd = query.times[1];
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const res = await getPageList(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) {
|
function rand(min: number, max: number) {
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
|
@ -258,9 +181,63 @@ function randomDate(start: string, end: string) {
|
||||||
return dayjs(v).format("YYYY-MM-DD");
|
return dayjs(v).format("YYYY-MM-DD");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createMockList(len = 87): TableItem[] {
|
||||||
|
const peoplePool = ["张三", "李四", "王五", "赵六", "陈七", "刘八", "黄九"];
|
||||||
|
const list: TableItem[] = [];
|
||||||
|
for (let i = 1; i <= len; i++) {
|
||||||
|
const school = schoolOptions[rand(0, schoolOptions.length - 1)].value;
|
||||||
|
const grade = gradeOptions[rand(0, gradeOptions.length - 1)].value;
|
||||||
|
const times = randomDate("2024-01-01", "2025-12-31");
|
||||||
|
const lastTime = dayjs(times).add(rand(0, 120), "day").format("YYYY-MM-DD");
|
||||||
|
const feedbackTotals = rand(0, 20);
|
||||||
|
const solveTotals = rand(0, feedbackTotals);
|
||||||
|
const status = rand(1, 2) as 1 | 2;
|
||||||
|
list.push({
|
||||||
|
id: i,
|
||||||
|
school,
|
||||||
|
grade,
|
||||||
|
people: peoplePool[rand(0, peoplePool.length - 1)],
|
||||||
|
times,
|
||||||
|
feedbackTotals,
|
||||||
|
solveTotals,
|
||||||
|
status,
|
||||||
|
lastTime
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
const allData = ref<TableItem[]>(createMockList());
|
||||||
|
|
||||||
|
const filteredList = computed(() => {
|
||||||
|
const q = appliedQuery.value;
|
||||||
|
return allData.value.filter(item => {
|
||||||
|
const matchSchool = q.school ? item.school === q.school : true;
|
||||||
|
const matchGrade = q.grade ? item.grade === q.grade : true;
|
||||||
|
const matchPeople = q.people ? item.people.includes(q.people.trim()) : true;
|
||||||
|
const matchStatus = q.status ? item.status === q.status : true;
|
||||||
|
let matchTimes = true;
|
||||||
|
if (Array.isArray(q.times) && q.times.length === 2) {
|
||||||
|
const [start, end] = q.times;
|
||||||
|
const d = dayjs(item.times);
|
||||||
|
matchTimes =
|
||||||
|
d.isAfter(dayjs(start).subtract(1, "day")) &&
|
||||||
|
d.isBefore(dayjs(end).add(1, "day"));
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
matchSchool && matchGrade && matchPeople && matchStatus && matchTimes
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const pagedData = computed(() => {
|
||||||
|
const start = (page.value - 1) * pageSize.value;
|
||||||
|
return filteredList.value.slice(start, start + pageSize.value);
|
||||||
|
});
|
||||||
|
|
||||||
function handleSearch() {
|
function handleSearch() {
|
||||||
|
appliedQuery.value = { ...query } as any;
|
||||||
page.value = 1;
|
page.value = 1;
|
||||||
loadList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleReset() {
|
function handleReset() {
|
||||||
|
|
@ -269,42 +246,32 @@ function handleReset() {
|
||||||
query.people = "";
|
query.people = "";
|
||||||
query.status = undefined;
|
query.status = undefined;
|
||||||
query.times = [];
|
query.times = [];
|
||||||
|
appliedQuery.value = { ...query } as any;
|
||||||
page.value = 1;
|
page.value = 1;
|
||||||
loadList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handlePageChange(p: number) {
|
function handlePageChange(p: number) {
|
||||||
page.value = p;
|
page.value = p;
|
||||||
loadList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSizeChange(s: number) {
|
function handleSizeChange(s: number) {
|
||||||
pageSize.value = s;
|
pageSize.value = s;
|
||||||
page.value = 1;
|
page.value = 1;
|
||||||
loadList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDelete(row: TableItem) {
|
function onDelete(row: TableItem) {
|
||||||
console.log(`删除`);
|
console.log(`删除:${row.school} - ${row.people}`);
|
||||||
|
ElMessage.success(`已删除:${row.school} - ${row.people}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDetail(row: TableItem) {
|
function onDetail(row: TableItem) {
|
||||||
console.log(`详情`);
|
console.log(`详情:${row.school} - ${row.people}`);
|
||||||
|
ElMessage.info(`详情:${row.school} - ${row.people}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFollow(row: TableItem) {
|
function onFollow(row: TableItem) {
|
||||||
console.log(`跟进`);
|
console.log(`跟进:${row.school} - ${row.people}`);
|
||||||
}
|
ElMessage.success(`跟进:${row.school} - ${row.people}`);
|
||||||
|
|
||||||
function handleAdd() {
|
|
||||||
console.log("新建");
|
|
||||||
isShowAddModal.value = true;
|
|
||||||
}
|
|
||||||
function handleImport() {
|
|
||||||
console.log("批量导入");
|
|
||||||
}
|
|
||||||
function handleExport() {
|
|
||||||
console.log("导出");
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue