dev #16
|
|
@ -286,24 +286,39 @@ export interface ConditionalModel {
|
|||
}
|
||||
|
||||
/** 搜索条件 */
|
||||
export interface SearchConditions {
|
||||
export class SearchConditions {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
constructor() {
|
||||
this.show = true;
|
||||
this.showPage = true;
|
||||
this.PageIndex = 0;
|
||||
this.PageSize = 20;
|
||||
this.OrderBy = "Id";
|
||||
this.OrderByType = 1;
|
||||
this.defaultConditions = [];
|
||||
this.Conditions = [];
|
||||
}
|
||||
/** 是否显示搜索 */
|
||||
show: boolean;
|
||||
show?: boolean;
|
||||
/** 显示分页器 */
|
||||
showPage?:boolean;
|
||||
/** 当前页码 */
|
||||
PageIndex: number;
|
||||
PageIndex?: number;
|
||||
/** 每页大小 */
|
||||
PageSize: number;
|
||||
PageSize?: number;
|
||||
/** 排序字段 */
|
||||
OrderBy: string;
|
||||
OrderBy?: string;
|
||||
/**排序顺序
|
||||
* @tips 0:升序 1:降序
|
||||
* @默认 = 1
|
||||
*/
|
||||
OrderByType?: 0 | 1;
|
||||
/** 默认查询条件 */
|
||||
defaultConditions: ConditionalModel[];
|
||||
defaultConditions?: ConditionalModel[];
|
||||
/** 查询条件 */
|
||||
Conditions: any[];
|
||||
Conditions?: any[];
|
||||
}
|
||||
|
||||
/** 表格配置 */
|
||||
|
|
@ -345,6 +360,9 @@ export function intTableData(tValue: TableConfig): TableConfig {
|
|||
if (!tValue.pageData) tValue.pageData = { total: 0 };
|
||||
if (tValue.operationTop === undefined) tValue.operationTop = true;
|
||||
|
||||
//分页查询配置
|
||||
tValue.search= { ...new SearchConditions(), ...tValue.search };
|
||||
|
||||
// 处理 column 的属性
|
||||
for (const key in tValue.column) {
|
||||
tValue.column[key] = { ...new TableColumn(), ...tValue.column[key] };
|
||||
|
|
|
|||
|
|
@ -429,39 +429,6 @@ function fetchPagedData() {
|
|||
<el-button type="default" @click="searchReload()">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="dialog-container">
|
||||
<el-dialog
|
||||
v-if="dialog.visible"
|
||||
v-model="dialog.visible"
|
||||
:class="dialog.title ? '' : 'noHeader'"
|
||||
:title="dialog.title"
|
||||
:width="dialog.width"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="dialog.close"
|
||||
:before-close="tableClose"
|
||||
append-to-body
|
||||
>
|
||||
<hTableEdit
|
||||
v-if="dialog.edit.visible"
|
||||
:id="dialog.edit.id"
|
||||
:tableData="table"
|
||||
:row="dialog.edit.row"
|
||||
:tagData="dialog.edit.tagData"
|
||||
@handlePagedCallback="handleAddCallback"
|
||||
/>
|
||||
<component
|
||||
:is="dialog.custom.component"
|
||||
v-if="dialog.custom.visible"
|
||||
:style="{ height: 'calc( ' + dialog.custom.height + ' - 84px )' }"
|
||||
:iscomponent="true"
|
||||
:custom="dialog.custom.custom"
|
||||
:CancelCallback="handleAddCallback"
|
||||
:data="dialog.custom.data"
|
||||
@handlePagedCallback="handleAddCallback"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="table.operationTop" class="toolbar-container">
|
||||
|
|
@ -484,7 +451,6 @@ function fetchPagedData() {
|
|||
:data="table.data"
|
||||
:border="table.border"
|
||||
:highlight-current-row="true"
|
||||
style="width: 100%"
|
||||
:row-key="rowKeyFun"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="sortChange"
|
||||
|
|
@ -563,6 +529,7 @@ function fetchPagedData() {
|
|||
</el-table-column>
|
||||
</el-table>
|
||||
<div
|
||||
v-if="table.search.showPage"
|
||||
style="
|
||||
padding-top: 15px;
|
||||
display: flex;
|
||||
|
|
@ -580,6 +547,40 @@ function fetchPagedData() {
|
|||
@current-change="pageIndexChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="dialog-container">
|
||||
<el-dialog
|
||||
v-if="dialog.visible"
|
||||
v-model="dialog.visible"
|
||||
:class="dialog.title ? '' : 'noHeader'"
|
||||
:title="dialog.title"
|
||||
:width="dialog.width"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="dialog.close"
|
||||
:before-close="tableClose"
|
||||
class="max-w-[95vw] overflow-x-auto"
|
||||
append-to-body
|
||||
>
|
||||
<hTableEdit
|
||||
v-if="dialog.edit.visible"
|
||||
:id="dialog.edit.id"
|
||||
:tableData="table"
|
||||
:row="dialog.edit.row"
|
||||
:tagData="dialog.edit.tagData"
|
||||
@handlePagedCallback="handleAddCallback"
|
||||
/>
|
||||
<component
|
||||
:is="dialog.custom.component"
|
||||
v-if="dialog.custom.visible"
|
||||
:style="{ height: 'calc( ' + dialog.custom.height + ' - 84px )' }"
|
||||
:iscomponent="true"
|
||||
:custom="dialog.custom.custom"
|
||||
:CancelCallback="handleAddCallback"
|
||||
:data="dialog.custom.data"
|
||||
@handlePagedCallback="handleAddCallback"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ const tableData: TableConfig = intTableData({
|
|||
grade: {
|
||||
label: "年级",
|
||||
width: "100px",
|
||||
custom: (row) => row.gradeLevel + row.gradeYear + "届",
|
||||
search: new TableColumnSearch(true),
|
||||
},
|
||||
className: {
|
||||
|
|
|
|||
|
|
@ -31,12 +31,7 @@ const tableData: TableConfig = intTableData({
|
|||
search: {
|
||||
// 查询条件
|
||||
show: true,
|
||||
PageIndex: 0,
|
||||
PageSize: 20,
|
||||
OrderBy: "Id", // 排序
|
||||
OrderByType: 1, // 排序方式
|
||||
defaultConditions: [], // 默认查询条件
|
||||
Conditions: [],
|
||||
PageSize: 999,
|
||||
},
|
||||
operationColumn: true, // 显示操作按钮
|
||||
operationColumnData: [
|
||||
|
|
@ -47,7 +42,7 @@ const tableData: TableConfig = intTableData({
|
|||
btnType: "custom",
|
||||
btnStyle: "primary",
|
||||
custom: {
|
||||
title: "考试学生班级详情", // 弹出框title
|
||||
title: "考试班级详情", // 弹出框title
|
||||
src: "exam/classExamRecord", // 组件路径
|
||||
width: "1600px", // 弹框宽度
|
||||
height: "800px", // 弹框高度
|
||||
|
|
@ -64,6 +59,7 @@ const tableData: TableConfig = intTableData({
|
|||
grade: {
|
||||
label: "年级",
|
||||
width: "120px",
|
||||
custom: (row) => row.gradeLevel + row.gradeYear + "届",
|
||||
search: new TableColumnSearch(true),
|
||||
},
|
||||
className: {
|
||||
|
|
@ -90,7 +86,6 @@ const tableData: TableConfig = intTableData({
|
|||
},
|
||||
onLineRanking: {
|
||||
label: "重本率排名",
|
||||
width: "100px",
|
||||
},
|
||||
},
|
||||
data: [],
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ const tableData: TableConfig = intTableData({
|
|||
// 查询条件
|
||||
show: true,
|
||||
PageIndex: 0,
|
||||
PageSize: 20,
|
||||
PageSize: 999,
|
||||
OrderByType: 1, // 排序方式
|
||||
OrderBy: "Id", // 排序
|
||||
defaultConditions: [
|
||||
|
|
@ -85,7 +85,8 @@ const tableData: TableConfig = intTableData({
|
|||
},
|
||||
grade: {
|
||||
label: "年级",
|
||||
width: "60px",
|
||||
width: "90px",
|
||||
custom: (row) => row.gradeLevel + row.gradeYear + "届",
|
||||
search: new TableColumnSearch(true),
|
||||
},
|
||||
|
||||
|
|
@ -104,24 +105,23 @@ const tableData: TableConfig = intTableData({
|
|||
},
|
||||
maxScore: {
|
||||
label: "最高分[赋分]",
|
||||
width: "140px",
|
||||
width: "130px",
|
||||
},
|
||||
minScore: {
|
||||
label: "最低分[赋分]",
|
||||
width: "140px",
|
||||
width: "130px",
|
||||
},
|
||||
average: {
|
||||
label: "总平均分[赋分]",
|
||||
custom: (row) => `${Math.round(row.average)}`,
|
||||
width: "140px",
|
||||
width: "130px",
|
||||
},
|
||||
average1: {
|
||||
label: "资源校平均分[赋分]",
|
||||
width: "160px",
|
||||
width: "100px",
|
||||
},
|
||||
averageRank: {
|
||||
label: "总平均分排名",
|
||||
width: "110px",
|
||||
},
|
||||
rank: {
|
||||
label: "远端平均/资源校平均",
|
||||
|
|
|
|||
|
|
@ -110,14 +110,27 @@ const tableData: TableConfig = intTableData({
|
|||
rules: ruleRequired,
|
||||
},
|
||||
},
|
||||
grade: {
|
||||
gradeLevel: {
|
||||
label: "年级",
|
||||
width: "100px",
|
||||
type: "dropdown",
|
||||
custom: (row) => row.gradeLevel + row.gradeYear + "届",
|
||||
search: new TableColumnSearch(true),
|
||||
edit: {
|
||||
add: true,
|
||||
edit: false,
|
||||
rules: ruleRequiredGrade,
|
||||
rules: ruleRequired,
|
||||
},
|
||||
},
|
||||
gradeYear: {
|
||||
label: "毕业年份",
|
||||
width: "100px",
|
||||
show: false,
|
||||
search: new TableColumnSearch(true),
|
||||
edit: {
|
||||
add: true,
|
||||
edit: false,
|
||||
rules: ruleRequiredNumber,
|
||||
},
|
||||
},
|
||||
testPaperType: {
|
||||
|
|
@ -162,7 +175,7 @@ const tableData: TableConfig = intTableData({
|
|||
},
|
||||
startTime: {
|
||||
label: "考试时间",
|
||||
width: "210px",
|
||||
width: "180px",
|
||||
type: "datetime",
|
||||
custom: (row) => row.startTime?.replace("T", " ").substring(0, 10) ?? "",
|
||||
search: new TableColumnSearch(true),
|
||||
|
|
@ -197,7 +210,8 @@ const showTable = ref(false);
|
|||
onMounted(async () => {
|
||||
//初始化数据原
|
||||
|
||||
// tableData.column.level.setting.datasource = (await getenum("GradeEnum")).data;
|
||||
tableData.column.gradeLevel.setting.datasource =
|
||||
(await getenum("GradeLevelEnum")).data.map(s=>{return {value : s.text,text:s.text}});
|
||||
|
||||
tableData.column.testPaperType.setting.datasource = (
|
||||
await getenum("TestPaperTypeEnum")
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ const tableData: TableConfig = intTableData({
|
|||
search: {
|
||||
// 查询条件
|
||||
show: true,
|
||||
PageIndex: 0,
|
||||
PageSize: 60,
|
||||
showPage: false,
|
||||
PageSize: 9999,
|
||||
OrderBy: "AssignRanking", // 排序
|
||||
OrderByType: 0,
|
||||
defaultConditions: [
|
||||
|
|
@ -153,7 +153,7 @@ const exam = props.data[0];
|
|||
<div>
|
||||
<div class="p-[10px] text-[1.5rem]">
|
||||
<strong>学校:</strong>{{ exam.schoolName }} <strong>年级:</strong
|
||||
>{{ exam.gradeLevel + exam.gradeYear }} <strong>班级:</strong
|
||||
>{{ exam.gradeLevel + exam.gradeYear }}届 <strong>班级:</strong
|
||||
>{{ exam.className }} <strong>考试名称:</strong
|
||||
>{{ exam.examName }}
|
||||
<!-- <strong>考试类型:</strong>{{exam.className}}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,9 @@ const tableData: TableConfig = intTableData({
|
|||
search: {
|
||||
// 查询条件
|
||||
show: true,
|
||||
showPage:false,
|
||||
PageIndex: 0,
|
||||
PageSize: 999,
|
||||
PageSize: 9999,
|
||||
OrderBy: "Id", // 排序
|
||||
OrderByType: 1,
|
||||
defaultConditions: [
|
||||
|
|
|
|||
|
|
@ -109,7 +109,9 @@
|
|||
<div class="subjectTagEnableDiv">
|
||||
<el-tag v-if="position.enable === false" type="info">已禁用</el-tag>
|
||||
<el-tag>{{ position.schoolName || "-" }}</el-tag>
|
||||
<el-tag type="success">{{ position.grade || "-" }}</el-tag>
|
||||
<el-tag type="success">{{
|
||||
position.graduationYear ? position.graduationYear + "届" : "-"
|
||||
}}</el-tag>
|
||||
<el-tag type="primary" class="classTag">{{
|
||||
position.className || "-"
|
||||
}}</el-tag>
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@
|
|||
|
||||
<el-table-column prop="studentId" label="职务" width="120" />
|
||||
|
||||
<el-table-column label="任教信息">
|
||||
<el-table-column label="任教信息" min-width="500">
|
||||
<template #default="scope">
|
||||
<div
|
||||
v-for="(position, index) in scope.row.positions"
|
||||
|
|
@ -171,7 +171,6 @@
|
|||
<el-tag type="info">{{
|
||||
position.graduationYear ? position.graduationYear + "届" : "-"
|
||||
}}</el-tag>
|
||||
<el-tag type="info">{{ position.grade || "-" }}</el-tag>
|
||||
<el-tag type="info">{{ position.className || "-" }}</el-tag>
|
||||
<el-tag type="info">{{ position.subjectName || "-" }}</el-tag>
|
||||
<el-tag type="info">{{ position.name || "-" }}</el-tag>
|
||||
|
|
|
|||
|
|
@ -28,8 +28,13 @@
|
|||
</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-form-item label="年级" prop="baseInfo.gradeLevel">
|
||||
<el-select
|
||||
v-model="form.baseInfo.gradeLevel"
|
||||
placeholder="请年级"
|
||||
clearable
|
||||
style="width: 120px"
|
||||
>
|
||||
<el-option
|
||||
v-for="g in gradeOptions"
|
||||
:key="g.value"
|
||||
|
|
@ -37,6 +42,12 @@
|
|||
:value="g.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input-number
|
||||
style="width: 120px"
|
||||
v-model="form.baseInfo.gradeYear"
|
||||
:min="2020"
|
||||
:max="2100"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
|
|
@ -69,6 +80,25 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="预计解决时间" prop="baseInfo.endTime">
|
||||
<el-date-picker
|
||||
v-model="form.baseInfo.endTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选预计解决时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div>
|
||||
提示:到期前<span class="text-yellow-500">{3天}</span>会黄色警告, 小于<span
|
||||
class="text-red-500"
|
||||
>{1天}</span
|
||||
>红色警告
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider>基础工作</el-divider>
|
||||
|
|
@ -198,13 +228,11 @@ const getSchoolBusinessPeopleList = () => {
|
|||
};
|
||||
getSchoolDataFn();
|
||||
getSchoolBusinessPeopleList();
|
||||
|
||||
const gradeOptions = [
|
||||
{ label: "初一", value: "初一" },
|
||||
{ label: "初二", value: "初二" },
|
||||
{ label: "初三", value: "初三" },
|
||||
{ label: "高一", value: "高一" },
|
||||
{ label: "高二", value: "高二" },
|
||||
{ label: "高三", value: "高三" },
|
||||
{ label: "高", value: "高" },
|
||||
{ label: "初", value: "初" },
|
||||
{ label: "小", value: "小" },
|
||||
];
|
||||
|
||||
type FeedbackKey = "leaders" | "classroom" | "equipment" | "students" | "others";
|
||||
|
|
@ -215,8 +243,10 @@ interface FeedbackItem {
|
|||
interface FormModel {
|
||||
baseInfo: {
|
||||
school?: string;
|
||||
grade?: string;
|
||||
gradeYear?: number;
|
||||
gradeLevel?: string;
|
||||
date?: string;
|
||||
endTime?: string;
|
||||
people: string[];
|
||||
};
|
||||
work: {
|
||||
|
|
@ -231,7 +261,8 @@ interface FormModel {
|
|||
const form = reactive<FormModel>({
|
||||
baseInfo: {
|
||||
school: undefined,
|
||||
grade: undefined,
|
||||
gradeLevel: "高",
|
||||
gradeYear: 2025,
|
||||
date: undefined,
|
||||
people: [],
|
||||
},
|
||||
|
|
@ -263,7 +294,7 @@ watch(
|
|||
);
|
||||
const rules: FormRules = {
|
||||
"baseInfo.school": [{ required: true, message: "请选择学校", trigger: "change" }],
|
||||
"baseInfo.grade": [{ required: true, message: "请选择年级", trigger: "change" }],
|
||||
"baseInfo.gradeLevel": [{ required: true, message: "请选择年级", trigger: "change" }],
|
||||
"baseInfo.date": [{ required: true, message: "请选择赴校时间", trigger: "change" }],
|
||||
"baseInfo.people": [
|
||||
{ required: true, message: "请选择赴校人员", trigger: "change" },
|
||||
|
|
@ -412,9 +443,9 @@ async function onSubmit() {
|
|||
id: 0, //id传0代表新增
|
||||
schoolId: form.baseInfo.school,
|
||||
schoolName: schoolOptions.value.find((i) => i.value == form.baseInfo.school).label,
|
||||
grade: form.baseInfo.grade,
|
||||
// 固定传空字符串
|
||||
gradeLevel: "",
|
||||
gradeLevel: form.baseInfo.gradeLevel,
|
||||
gradeYear: form.baseInfo.gradeYear,
|
||||
schoolBusinessUser: form.baseInfo.people,
|
||||
startTime: form.baseInfo.date,
|
||||
isDiscussion: form.work.talk,
|
||||
|
|
@ -445,7 +476,7 @@ async function onSubmit() {
|
|||
|
||||
function resetForm() {
|
||||
form.baseInfo.school = undefined;
|
||||
form.baseInfo.grade = undefined;
|
||||
form.baseInfo.gradeLevel = undefined;
|
||||
form.baseInfo.date = undefined;
|
||||
form.baseInfo.people = [];
|
||||
form.work.talk = false;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
{{ safeDetail.schoolName || safeDetail.school || "-" }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="年级">
|
||||
{{ safeDetail.grade || safeDetail.gradeLevel || "-" }}
|
||||
{{ safeDetail.gradeLevel + safeDetail.gradeYear }}届
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="赴校人员">
|
||||
{{
|
||||
|
|
@ -41,6 +41,10 @@
|
|||
<el-descriptions-item label="赴校时间">
|
||||
{{ safeDetail.startTimeStr || safeDetail.startTime }}
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="预计完结时间">
|
||||
{{ safeDetail.endTime != null ? safeDetail.endTime.split("T")[0] : "--" }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<el-divider />
|
||||
|
|
@ -76,34 +80,63 @@
|
|||
<span> 未解决问题:{{ unresolvedCount }} </span>
|
||||
</div>
|
||||
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
|
||||
<el-tab-pane
|
||||
v-for="(i, idx) in sortData(safeDetail.feedbackQuestions || [])"
|
||||
:key="idx"
|
||||
:label="'问题' + (idx + 1) + (i.solution ? '(✅已解决)' : '(未解决)')"
|
||||
:name="idx"
|
||||
>
|
||||
<el-tab-pane v-for="(i, idx) in questions" :key="idx" :name="idx">
|
||||
<template #label>
|
||||
<span class="custom-tabs-label" :class="i.solution ? `text-[#67c23a]` : ``">
|
||||
<span>问题{{ idx + 1 }}</span>
|
||||
<el-icon>
|
||||
<Select v-if="i.solution" />
|
||||
</el-icon>
|
||||
</span>
|
||||
</template>
|
||||
<div style="font-size: 12px; margin-bottom: 4px">
|
||||
<span>问题类型:</span> <span>{{ queType[i.questionType] }}</span>
|
||||
</div>
|
||||
<div style="padding: 10px; background-color: #f3f3f3">
|
||||
{{ i.question }}
|
||||
</div>
|
||||
<div v-if="i.solution" style="font-size: 12px; margin-top: 10px">
|
||||
<span> 解决时间:{{ i.endTimeStr || i.endTime }} </span>
|
||||
<div
|
||||
v-for="(rec, rIdx) in i.recordArr || []"
|
||||
:key="rIdx"
|
||||
style="margin-top: 10px"
|
||||
>
|
||||
<div>
|
||||
执行记录{{ rIdx + 1 }}:{{ rec.operator || "" }} {{ rec.executionTimeStr }}
|
||||
</div>
|
||||
<div style="padding: 5px; background-color: #f3f3f3">
|
||||
{{ rec.executionRecords }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="i.solution" style="font-size: 12px; margin-top: 20px">
|
||||
<span class="text-amber-400 font-bold">
|
||||
解决时间:{{ i.endTimeStr || i.endTime }}
|
||||
</span>
|
||||
<div style="padding: 10px; background-color: #f3f3f3">
|
||||
{{ i.solution }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="mt-1.5">
|
||||
<el-button
|
||||
v-show="!isDetail"
|
||||
type="text"
|
||||
v-else
|
||||
link
|
||||
:disabled="i.solution"
|
||||
style="margin-top: 5px; font-size: 12px"
|
||||
class="markTitle"
|
||||
@click="addQRecord(i)"
|
||||
>
|
||||
添加执行记录
|
||||
</el-button>
|
||||
<el-button
|
||||
v-show="!isDetail"
|
||||
link
|
||||
style="margin-top: 5px; font-size: 12px"
|
||||
class="markTitle"
|
||||
@click="markTitle(i)"
|
||||
>
|
||||
标记已解决
|
||||
</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-divider />
|
||||
|
|
@ -128,7 +161,7 @@
|
|||
<!-- 添加按钮区域 -->
|
||||
<div style="margin-top: 5px; display: flex; gap: 20px">
|
||||
<el-button
|
||||
type="text"
|
||||
link
|
||||
style="margin-top: 5px; font-size: 12px"
|
||||
class="markTitle"
|
||||
v-show="!isDetail"
|
||||
|
|
@ -139,8 +172,10 @@
|
|||
<el-button
|
||||
style="margin-top: 5px; font-size: 12px"
|
||||
class="markTitle"
|
||||
type="text"
|
||||
link
|
||||
v-show="!isDetail"
|
||||
:disabled="unresolvedCount != 0"
|
||||
title="请先解决所有问题后再添加完结情况"
|
||||
@click="addFinish"
|
||||
>
|
||||
{{ finishRecord ? "修改完结情况" : "添加完结情况" }}
|
||||
|
|
@ -160,7 +195,7 @@
|
|||
border-radius: 4px;
|
||||
"
|
||||
>
|
||||
<div style="font-weight: bold; color: #409eff">
|
||||
<div style="font-weight: bold; color: #67c23a">
|
||||
执行记录{{ index + 1 }}:{{ record.operator }} {{ record.time }}
|
||||
</div>
|
||||
<div style="margin-top: 5px; white-space: pre-wrap">
|
||||
|
|
@ -180,9 +215,7 @@
|
|||
border: 1px solid #b3d8ff;
|
||||
"
|
||||
>
|
||||
<div style="font-weight: bold; color: #a69400">
|
||||
完结情况:{{ finishRecord.time }}
|
||||
</div>
|
||||
<div class="text-amber-400 font-bold">完结情况:{{ finishRecord.time }}</div>
|
||||
<div style="margin-top: 5px; white-space: pre-wrap">
|
||||
{{ finishRecord.content }}
|
||||
</div>
|
||||
|
|
@ -230,7 +263,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts" name="EditModal">
|
||||
import { ref, reactive, computed, defineProps, defineEmits, watch } from "vue";
|
||||
import { ref, reactive, computed, defineProps, defineEmits, watch, onMounted } from "vue";
|
||||
import type { FormInstance, FormRules, TabsPaneContext } from "element-plus";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { getSchoolData } from "@/api/userCenter";
|
||||
|
|
@ -238,13 +271,23 @@ import { getSchoolBusinessPeopleListApi, addOrEditApi } from "@/api/toschoolinfo
|
|||
import { setFips } from "crypto";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
import { isAllEmpty } from "@pureadmin/utils";
|
||||
import { Select, CloseBold } from "@element-plus/icons-vue";
|
||||
|
||||
const activeName = ref<any>(0);
|
||||
onMounted(() => {
|
||||
console.log("onMounted ");
|
||||
|
||||
questions = ref(sortData(safeDetail.value.feedbackQuestions));
|
||||
});
|
||||
const handleClick = (tab: TabsPaneContext, event: Event) => {
|
||||
console.log(tab.props.name, event);
|
||||
activeName.value = tab.props.name;
|
||||
};
|
||||
const gradeOptions = [
|
||||
{ label: "高", value: "高" },
|
||||
{ label: "初", value: "初" },
|
||||
{ label: "小", value: "小" },
|
||||
];
|
||||
const props = defineProps<{
|
||||
visible: boolean;
|
||||
detailData: any;
|
||||
|
|
@ -305,6 +348,7 @@ const operationContentLabel = computed(() => {
|
|||
case "markSolved":
|
||||
return "解决情况";
|
||||
case "addRecord":
|
||||
case "addQRecord":
|
||||
return "执行记录";
|
||||
case "addFinish":
|
||||
return "完结情况";
|
||||
|
|
@ -345,10 +389,12 @@ const queType = {
|
|||
* 获取未解决问题数量
|
||||
* @param data
|
||||
*/
|
||||
const handleUnHandleQust = (data: Array<any>) => {
|
||||
const handleUnHandleQust = (data: Array<any>): number => {
|
||||
return (data || []).filter((i) => !i?.solution).length;
|
||||
};
|
||||
|
||||
const sortData = (data: Array<any>) => {
|
||||
if (data == null || data.length == 0) return [];
|
||||
const categorizedData = [
|
||||
...data
|
||||
.filter((item) => item.questionType === 1)
|
||||
|
|
@ -373,6 +419,7 @@ const statusText = computed(() => (safeDetail.value?.solutionEnd ? "已完结" :
|
|||
const statusType = computed(() =>
|
||||
safeDetail.value?.solutionEnd ? "success" : "warning"
|
||||
);
|
||||
let questions = ref(sortData(safeDetail.value.feedbackQuestions));
|
||||
const solutionText = computed({
|
||||
get: () => safeDetail.value?.solutionRecord?.solution || "",
|
||||
set: (value: string) => {
|
||||
|
|
@ -388,6 +435,7 @@ const unresolvedCount = computed(() => {
|
|||
const list = (safeDetail.value?.feedbackQuestions as any[]) || [];
|
||||
return list.filter((item) => !item?.solution).length;
|
||||
});
|
||||
|
||||
const markTitle = (data: any) => {
|
||||
console.log("标记已解决", data);
|
||||
operationType.value = "markSolved";
|
||||
|
|
@ -398,6 +446,14 @@ const markTitle = (data: any) => {
|
|||
operationFormRef.value?.clearValidate();
|
||||
operationDialogVisible.value = true;
|
||||
};
|
||||
const addQRecord = (data: any) => {
|
||||
console.log("添加问题执行记录", data);
|
||||
operationType.value = "addQRecord";
|
||||
currentMarkedQuestion.value = data;
|
||||
// 预填已有值
|
||||
operationFormRef.value?.clearValidate();
|
||||
operationDialogVisible.value = true;
|
||||
};
|
||||
const addRecord = () => {
|
||||
console.log("添加执行记录");
|
||||
operationType.value = "addRecord";
|
||||
|
|
@ -433,7 +489,11 @@ const closeOperationDialog = () => {
|
|||
// 重置当前标记项
|
||||
currentMarkedQuestion.value = null;
|
||||
};
|
||||
|
||||
const userName = computed(() => {
|
||||
return isAllEmpty(useUserStoreHook()?.nickName)
|
||||
? useUserStoreHook()?.userName
|
||||
: useUserStoreHook()?.nickName;
|
||||
});
|
||||
const confirmOperation = async () => {
|
||||
if (!operationFormRef.value) return;
|
||||
|
||||
|
|
@ -441,9 +501,21 @@ const confirmOperation = async () => {
|
|||
await operationFormRef.value.validate();
|
||||
|
||||
const { operationTime, operationContent } = operationForm;
|
||||
|
||||
// 根据操作类型处理数据
|
||||
switch (operationType.value) {
|
||||
case "addQRecord":
|
||||
// 添加执行记录
|
||||
if (currentMarkedQuestion.value) {
|
||||
if (currentMarkedQuestion.value.recordArr == undefined) {
|
||||
currentMarkedQuestion.value.recordArr = [];
|
||||
}
|
||||
currentMarkedQuestion.value.recordArr.push({
|
||||
executionTime: operationTime,
|
||||
executionRecords: operationContent,
|
||||
operator: userName.value,
|
||||
});
|
||||
}
|
||||
break;
|
||||
case "addRecord":
|
||||
// 添加执行记录
|
||||
executionRecords.value.push({
|
||||
|
|
@ -454,11 +526,7 @@ const confirmOperation = async () => {
|
|||
if (!props.detailData.solutionRecord) props.detailData.solutionRecord = {} as any;
|
||||
if (!Array.isArray(props.detailData.solutionRecord.record))
|
||||
props.detailData.solutionRecord.record = [];
|
||||
const userName = computed(() => {
|
||||
return isAllEmpty(useUserStoreHook()?.nickName)
|
||||
? useUserStoreHook()?.userName
|
||||
: useUserStoreHook()?.nickName;
|
||||
});
|
||||
|
||||
props.detailData.solutionRecord.record.push({
|
||||
executionTime: operationTime,
|
||||
executionRecords: operationContent,
|
||||
|
|
@ -532,6 +600,14 @@ function onClickSave() {
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-tabs-label .el-icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.custom-tabs-label span {
|
||||
vertical-align: middle;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -555,7 +631,6 @@ function onClickSave() {
|
|||
}
|
||||
.markTitle:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
v-model="query.grade"
|
||||
placeholder="请选择年级"
|
||||
clearable
|
||||
style="width: 140px"
|
||||
style="width: 120px"
|
||||
>
|
||||
<el-option
|
||||
v-for="g in gradeOptions"
|
||||
|
|
@ -31,7 +31,8 @@
|
|||
:label="g.label"
|
||||
:value="g.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-select >
|
||||
<el-input-number v-show="query.grade" v-model="query.gradeYear" :min="2020" :max="2100"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="赴校人员">
|
||||
<el-select
|
||||
|
|
@ -88,7 +89,12 @@
|
|||
<el-button type="info" @click="downLoadTpl">下载模版</el-button>
|
||||
</div>
|
||||
<!-- 表格区域 -->
|
||||
<el-table :data="listData" style="width: 100%" :max-height="500">
|
||||
<el-table
|
||||
:data="listData"
|
||||
style="width: 100%"
|
||||
:max-height="500"
|
||||
:row-class-name="tableRowClassName"
|
||||
>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template #default="{ row }">
|
||||
<!-- <el-button size="small" type="danger" plain @click="onDelete(row)"
|
||||
|
|
@ -127,9 +133,17 @@
|
|||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="grade" label="年级" min-width="100" />
|
||||
<el-table-column label="年级" min-width="100" >
|
||||
<template #default="{ row }">
|
||||
{{ row.gradeLevel+row.gradeYear }}届
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="people" label="赴校人员" min-width="120" />
|
||||
<el-table-column prop="times" label="赴校时间" min-width="140" />
|
||||
<el-table-column label="赴校时间/解决时间" min-width="140">
|
||||
<template #default="{ row }">
|
||||
{{ row.times }}{{ row.endTime ? " / " + row.endTime : "" }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="feedbackTotals" label="反馈问题数量" min-width="140" />
|
||||
<el-table-column prop="solveTotals" label="解决问题数量" min-width="140" />
|
||||
|
||||
|
|
@ -155,6 +169,7 @@
|
|||
<!-- 跟进 -->
|
||||
<EditModal
|
||||
v-model:visible="isShowEditModal"
|
||||
v-if="isShowEditModal"
|
||||
:editModalLoading="editModalLoading"
|
||||
:detailData="detailData"
|
||||
:isDetail="isDetail"
|
||||
|
|
@ -187,6 +202,7 @@ interface TableItem {
|
|||
people: string;
|
||||
canOperate: boolean; // 是否可以跟进
|
||||
times: string; // YYYY-MM-DD
|
||||
endTime: string; //预计解决时间
|
||||
feedbackTotals: number;
|
||||
solveTotals: number;
|
||||
solutionEnd: boolean; // true: 已完结, false: 跟进中
|
||||
|
|
@ -196,6 +212,20 @@ interface TableItem {
|
|||
const schoolOptions = ref([]);
|
||||
const peopleOptions = ref([]);
|
||||
const isDetail = ref(false);
|
||||
|
||||
const tableRowClassName = ({ row, rowIndex }: { row: any; rowIndex: number }) => {
|
||||
if (row.endTime == null || row.endTime == "" || row.solutionEnd) return "";
|
||||
const nD = new Date();
|
||||
const d = new Date(row.endTime + " ");
|
||||
const daysDiff = Math.floor((d.getTime() - nD.getTime()) / (1000 * 60 * 60 * 24));
|
||||
if (daysDiff >= 2) {
|
||||
return "warning-row";
|
||||
} else if (daysDiff < 2) {
|
||||
return "error-row";
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取学校下拉数据
|
||||
*/
|
||||
|
|
@ -236,12 +266,9 @@ onMounted(() => {
|
|||
});
|
||||
|
||||
const gradeOptions = [
|
||||
{ label: "初一", value: "初一" },
|
||||
{ label: "初二", value: "初二" },
|
||||
{ label: "初三", value: "初三" },
|
||||
{ label: "高一", value: "高一" },
|
||||
{ label: "高二", value: "高二" },
|
||||
{ label: "高三", value: "高三" },
|
||||
{ label: "高", value: "高" },
|
||||
{ label: "初", value: "初" },
|
||||
{ label: "小", value: "小" },
|
||||
];
|
||||
/**
|
||||
* 新建赴校信息提交
|
||||
|
|
@ -283,6 +310,7 @@ const addOrEdit = () => {
|
|||
const query = reactive({
|
||||
school: "" as string | undefined,
|
||||
grade: "" as string | undefined,
|
||||
gradeYear: 2025 as number ,
|
||||
people: "" as string | undefined,
|
||||
solutionEnd: undefined,
|
||||
times: [] as string[],
|
||||
|
|
@ -309,8 +337,11 @@ function mapApiItemToRow(item: any): TableItem {
|
|||
id: item.id,
|
||||
school: item.schoolName || "",
|
||||
grade: item.grade || "",
|
||||
gradeYear: item.gradeYear || "",
|
||||
gradeLevel: item.gradeLevel || "",
|
||||
people: peopleArr.join(","),
|
||||
times: start,
|
||||
endTime: item.endTime ? dayjs(item.endTime).format("YYYY-MM-DD") : "",
|
||||
canOperate: item.canOperate || false, // 是否可以跟进
|
||||
feedbackTotals: Number(item.feedbackCount) || 0,
|
||||
solveTotals: Number(item.solveFeedbackCount) || 0,
|
||||
|
|
@ -326,7 +357,7 @@ async function loadList() {
|
|||
orderBy: "startTime",
|
||||
};
|
||||
if (query.school) payload.schoolId = query.school;
|
||||
if (query.grade) payload.grade = query.grade;
|
||||
if (query.grade && query.gradeYear) payload.grade = query.grade+query.gradeYear;
|
||||
if (query.people) {
|
||||
payload.UserName = query.people;
|
||||
}
|
||||
|
|
@ -401,12 +432,12 @@ function onDelete(row: TableItem) {
|
|||
*/
|
||||
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;
|
||||
isShowEditModal.value = true;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
|
|
@ -504,4 +535,12 @@ function downLoadTpl() {
|
|||
justify-content: center;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
:deep(.el-table .warning-row) {
|
||||
--el-table-tr-bg-color: rgb(253, 246, 236);
|
||||
}
|
||||
|
||||
:deep(.el-table .error-row) {
|
||||
--el-table-tr-bg-color: rgb(255, 227, 227);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue