Files
UserclassFront/src/views/itemSet.vue
T
lijing 7e49587c10 feat: 迁移 Vue3 + Vite + view-ui-plus(对齐 NoticeFront 框架)
- 构建:Vue CLI 4 → Vite 5,入口迁至根 index.html(含 env-config + 主题通道 loader)
- 技术栈:Vue 2.6 → Vue 3.4,view-design → view-ui-plus 1.3.24,vue-router 3 → 4(hash)
- 壳层重写:App.vue / components/layout.vue 对齐 Notice 骨架(logo-badge、icon-* 通道图标、resolveMenuPage、crumb-home 基线)
- 机械转换:具名 slot → template #x、.sync → v-model:、@click.native、$set、beforeDestroy、/deep/ → :deep()
- render:h('Button')/h('Input') → 真组件 + 扁平 props/onClick
- 组件适配:vuedraggable 4 的 #item 插槽;vue-treeselect → @zanmato/vue3-treeselect;Page 分页改 v-model + pageSize 显式回写
- 清理:删除 Vue2 死代码(layout_old/bak/child、App.Net、codeModal、未引用组件)
- 修复:深链接首次加载被重定向到首个模块(router.isReady)

验证:vite build 通过;headless CDP 全 15 路由无异常;教师列表 2 行渲染、操作列按钮点击弹窗正常。
2026-10-20 15:16:52 +08:00

563 lines
19 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 class="page-container">
<div class="btn-top-wrap">
<Button type="primary" @click="openAddModal">添加学年学期</Button>
</div>
<!-- 表格 -->
<Table
:columns="tableColumns"
:data="yeartermlist"
stripe
:height="useTableHeight()+112"
class="term-table"
/>
<!-- 新增弹窗 -->
<Modal v-model="addModalVisible" title="添加学年学期" width="720" class="modalform">
<Form
:model="addForm"
ref="addFormRef"
:rules="formRules"
label-width="120px"
class="modal-form"
>
<div class="form-block-title">学年设置</div>
<FormItem label="新学年">
<Input disabled :value="addForm.year + '学年'" />
</FormItem>
<Row :gutter="16">
<Col span="12">
<FormItem label="开始日期" prop="yearStartDate">
<DatePicker
disabled
:value="strToDate(addForm.yearStartDate)"
format="yyyy-MM-dd"
placeholder="请选择日期"
></DatePicker>
</FormItem>
</Col>
<Col span="12">
<FormItem label="结束日期" prop="yearEndDate">
<DatePicker
:value="strToDate(addForm.yearEndDate)"
@on-change="(date) => addForm.yearEndDate = dateToStr(date)"
format="yyyy-MM-dd"
placeholder="请选择日期"
></DatePicker>
</FormItem>
</Col>
</Row>
<div class="form-block-title">学期设置</div>
<FormItem label="升学日期" prop="upgradeDate">
<DatePicker
:value="strToDate(addForm.upgradeDate)"
@on-change="(date) => addForm.upgradeDate = dateToStr(date)"
format="yyyy-MM-dd"
placeholder="请选择日期"
></DatePicker>
</FormItem>
<div class="form-block-title">第一学期设置</div>
<Row :gutter="16">
<Col span="12">
<FormItem label="开始日期" prop="firstTermStartDate">
<DatePicker
type="date"
:value="strToDate(addForm.firstTermStartDate)"
@on-change="(date) => addForm.firstTermStartDate = dateToStr(date)"
format="yyyy-MM-dd"
placeholder="请选择日期"
></DatePicker>
</FormItem>
</Col>
<Col span="12">
<FormItem label="结束日期" prop="firstTermEndDate">
<DatePicker
type="date"
:value="strToDate(addForm.firstTermEndDate)"
@on-change="(date) => addForm.firstTermEndDate = dateToStr(date)"
format="yyyy-MM-dd"
placeholder="请选择日期"
></DatePicker>
</FormItem>
</Col>
</Row>
<div class="form-block-title">第二学期设置</div>
<Row :gutter="16">
<Col span="12">
<FormItem label="开始日期" prop="secondTermStartDate">
<DatePicker
:value="strToDate(addForm.secondTermStartDate)"
@on-change="(date) => addForm.secondTermStartDate = dateToStr(date)"
format="yyyy-MM-dd"
placeholder="请选择日期"
></DatePicker>
</FormItem>
</Col>
<Col span="12">
<FormItem label="结束日期" prop="secondTermEndDate">
<DatePicker
:value="strToDate(addForm.secondTermEndDate)"
@on-change="(date) => addForm.secondTermEndDate = dateToStr(date)"
format="yyyy-MM-dd"
placeholder="请选择日期"
></DatePicker>
</FormItem>
</Col>
</Row>
</Form>
<template #footer><div class="modal-footer">
<Button @click="addModalVisible = false">取消</Button>
<Button type="primary" @click="submitAdd">提交</Button>
</div></template>
</Modal>
<!-- 编辑弹窗 -->
<Modal v-model="editModalVisible" title="修改学年学期" width="720" class="modalform">
<Form
:model="editForm"
ref="editFormRef"
:rules="formRules"
label-width="120px"
class="modal-form"
>
<div class="form-block-title">学年设置</div>
<FormItem label="新学年">
<Input disabled :value="editForm.year + '学年'" />
</FormItem>
<Row :gutter="16">
<Col span="12">
<FormItem label="开始日期" prop="yearStartDate">
<DatePicker
disabled
:value="strToDate(editForm.yearStartDate)"
format="yyyy-MM-dd"
></DatePicker>
</FormItem>
</Col>
<Col span="12">
<FormItem label="结束日期" prop="yearEndDate">
<DatePicker
:value="strToDate(editForm.yearEndDate)"
@on-change="(date) => editForm.yearEndDate = dateToStr(date)"
format="yyyy-MM-dd"
></DatePicker>
</FormItem>
</Col>
</Row>
<div class="form-block-title">学期设置</div>
<FormItem label="升学日期" prop="upgradeDate">
<DatePicker
:value="strToDate(editForm.upgradeDate)"
@on-change="(date) => editForm.upgradeDate = dateToStr(date)"
format="yyyy-MM-dd"
></DatePicker>
</FormItem>
<div class="form-block-title">第一学期设置</div>
<Row :gutter="16">
<Col span="12">
<FormItem label="开始日期" prop="firstTermStartDate">
<DatePicker
:value="strToDate(editForm.firstTermStartDate)"
@on-change="(date) => editForm.firstTermStartDate = dateToStr(date)"
format="yyyy-MM-dd"
></DatePicker>
</FormItem>
</Col>
<Col span="12">
<FormItem label="结束日期" prop="firstTermEndDate">
<DatePicker
:value="strToDate(editForm.firstTermEndDate)"
@on-change="(date) => editForm.firstTermEndDate = dateToStr(date)"
format="yyyy-MM-dd"
></DatePicker>
</FormItem>
</Col>
</Row>
<div class="form-block-title">第二学期设置</div>
<Row :gutter="16">
<Col span="12">
<FormItem label="开始日期" prop="secondTermStartDate">
<DatePicker
:value="strToDate(editForm.secondTermStartDate)"
@on-change="(date) => editForm.secondTermStartDate = dateToStr(date)"
format="yyyy-MM-dd"
></DatePicker>
</FormItem>
</Col>
<Col span="12">
<FormItem label="结束日期" prop="secondTermEndDate">
<DatePicker
:value="strToDate(editForm.secondTermEndDate)"
@on-change="(date) => editForm.secondTermEndDate = dateToStr(date)"
format="yyyy-MM-dd"
></DatePicker>
</FormItem>
</Col>
</Row>
</Form>
<template #footer><div class="modal-footer">
<Button @click="editModalVisible = false">取消</Button>
<Button type="primary" @click="submitEdit">保存</Button>
</div></template>
</Modal>
</div>
</template>
<script>
import { Button } from "view-ui-plus";
import { self_viewport } from "@/mixins/self_viewport";
export default {
name: "AcademicYearTerm",
data() {
return {
tableColumns: [
{
title: "学年",
key: "year",
align: "center",
render: (h, params) => {
const row = params.row;
const text = row.nowYear ? `${row.year}学年(当前学年)` : `${row.year}学年`;
return h("div", { style: "line-height: 56px" }, text);
}
},
{
title: "学年开始日期",
key: "yearStartDate",
align: "center",
render: (h, params) => h("div", { style: "line-height: 56px" }, params.row.yearStartDate)
},
{
title: "学年结束日期",
key: "yearEndDate",
align: "center",
render: (h, params) => h("div", { style: "line-height: 56px" }, params.row.yearEndDate)
},
{
title: "学期名称",
key: "termName",
align: "center",
render: (h, params) => {
return h("div", [
h("div", "第一学期"),
h("div", { style: "margin-top: 8px" }, "第二学期")
]);
}
},
{
title: "起始日期",
key: "startDate",
align: "center",
render: (h, params) => {
return h("div", [
h("div", params.row.firstTermStartDate),
h("div", { style: "margin-top: 8px" }, params.row.secondTermStartDate)
]);
}
},
{
title: "截止日期",
key: "endDate",
align: "center",
render: (h, params) => {
return h("div", [
h("div", params.row.firstTermEndDate),
h("div", { style: "margin-top: 8px" }, params.row.secondTermEndDate)
]);
}
},
{
title: "操作",
key: "action",
width: 90,
align: "center",
render: (h, params) => {
return h(Button,
{icon: "ios-create",
shape: "circle",
onClick: () => {
this.openEditModal(params.row);
}}
);
}
}
],
yeartermlist: [],
addModalVisible: false,
addForm: {
year: new Date().getFullYear(),
yearStartDate: new Date().getFullYear() + "-07-15",
yearEndDate: "",
upgradeDate: "",
firstTermStartDate: "",
firstTermEndDate: "",
secondTermStartDate: "",
secondTermEndDate: ""
},
editModalVisible: false,
editForm: {
id: null,
year: "",
yearStartDate: "",
yearEndDate: "",
upgradeDate: "",
firstTermStartDate: "",
firstTermEndDate: "",
secondTermStartDate: "",
secondTermEndDate: ""
},
// 修复formRules语法错误
formRules: {
year: [{ required: true, message: "请填写学年", trigger: "blur" }],
yearStartDate: [{ required: true, message: "请选择学年开始日期", trigger: "change" }],
yearEndDate: [{ required: true, message: "请选择学年结束日期", trigger: "change" }],
upgradeDate: [{ required: true, message: "请选择升学日期", trigger: "change" }],
firstTermStartDate: [{ required: true, message: "请选择第一学期开始日期", trigger: "change" }],
firstTermEndDate: [{ required: true, message: "请选择第一学期结束日期", trigger: "change" }],
secondTermStartDate: [{ required: true, message: "请选择第二学期开始日期", trigger: "change" }],
secondTermEndDate: [{ required: true, message: "请选择第二学期结束日期", trigger: "change" }]
}
};
},
mixins: [self_viewport],
mounted() {
this.getschsystemlist();
},
methods: {
// 日期转换:Date对象 → yyyy-MM-dd 标准字符串
dateToStr(date) {
if (!date) return "";
const y = new Date(date).getFullYear();
const m = String(new Date(date).getMonth() + 1).padStart(2, "0");
const d = String(new Date(date).getDate()).padStart(2, "0");
return `${y}-${m}-${d}`;
},
// 日期转换:字符串/后端ISO时间 → Date对象 给DatePicker回填
strToDate(inputStr) {
if (!inputStr) return null;
// 处理后端带T的ISO格式
let str = inputStr.includes("T") ? inputStr.split("T")[0] : inputStr;
const arr = str.split("-");
if (arr.length !== 3) return null;
const year = arr[0];
const month = arr[1].padStart(2, "0");
const day = arr[2].padStart(2, "0");
const standard = `${year}-${month}-${day}`;
const date = new Date(standard);
// 非法日期返回空
return isNaN(date.getTime()) ? null : date;
},
//获取学校绑定学制列表
getschsystemlist() {
const _this = this;
var item = {};
_this.$api.get(APIConfig.BschClassSystem.getyeartermlist, item, resp => {
if (resp.code == 0) {
_this.yeartermlist = resp.data;
} else {
_this.yeartermlist = [];
}
});
},
openAddModal() {
this.$nextTick(() => {
this.$refs.addFormRef?.resetFields();
});
const curYear = new Date().getFullYear();
this.addForm = {
year: curYear,
yearStartDate: curYear + "-07-15",
yearEndDate: "",
upgradeDate: "",
firstTermStartDate: "",
firstTermEndDate: "",
secondTermStartDate: "",
secondTermEndDate: ""
};
this.addModalVisible = true;
},
submitAdd() {
this.$refs.addFormRef.validate(valid => {
if (!valid) return;
const form = this.addForm;
// 1、学年数字校验(对齐后端 @Min(2000) @Positive)
const yearNum = Number(form.year);
if (!Number.isInteger(yearNum) || yearNum <= 0) {
this.$Message.error("学年必须为正整数");
return;
}
if (yearNum < 2000) {
this.$Message.error("学年不能小于2000");
return;
}
// 快速转日期
const getDate = (s) => new Date(s);
const ys = getDate(form.yearStartDate);
const ye = getDate(form.yearEndDate);
const t1s = getDate(form.firstTermStartDate);
const t1e = getDate(form.firstTermEndDate);
const t2s = getDate(form.secondTermStartDate);
const t2e = getDate(form.secondTermEndDate);
const up = getDate(form.upgradeDate);
if (ys > ye) {
this.$Message.error("学年开始日期不能晚于学年结束日期");
return;
}
if (t1s > t1e) {
this.$Message.error("第一学期开始日期不能晚于第一学期结束日期");
return;
}
if (t2s > t2e) {
this.$Message.error("第二学期开始日期不能晚于第二学期结束日期");
return;
}
if (t1e > t2s) {
this.$Message.error("第一学期结束日期不能晚于第二学期开始日期");
return;
}
if (up < ye) {
this.$Message.error("毕业日期不能早于学年结束日期");
return;
}
// 组装提交参数,year传数字,日期传标准yyyy-MM-dd字符串
const submitData = {
year: yearNum,
yearStartDate: form.yearStartDate,
yearEndDate: form.yearEndDate,
firstTermStartDate: form.firstTermStartDate,
firstTermEndDate: form.firstTermEndDate,
secondTermStartDate: form.secondTermStartDate,
secondTermEndDate: form.secondTermEndDate,
upgradeDate: form.upgradeDate
};
const url = APIConfig.BschClassSystem.yeartermadd;
this.$api.post(url, JSON.stringify(submitData), resp => {
if (resp.code == 0) {
this.$Message.success("添加成功!");
this.addModalVisible = false;
this.getschsystemlist();
} else if (resp.code == 4) {
this.$Message.info(resp.msg);
}
});
});
},
openEditModal(row) {
this.$nextTick(() => {
this.$refs.editFormRef?.resetFields();
});
this.editForm = {
id: row.id,
year: row.year,
yearStartDate: row.yearStartDate,
yearEndDate: row.yearEndDate,
upgradeDate: row.upgradeDate,
firstTermStartDate: row.firstTermStartDate,
firstTermEndDate: row.firstTermEndDate,
secondTermStartDate: row.secondTermStartDate,
secondTermEndDate: row.secondTermEndDate
};
this.editModalVisible = true;
},
submitEdit() {
this.$refs.editFormRef.validate(valid => {
if (!valid) return;
const form = this.editForm;
console.log(JSON.stringify(form));
// 学年数字校验
const yearNum = Number(form.year);
if (!Number.isInteger(yearNum) || yearNum <= 0) {
this.$Message.error("学年必须为正整数");
return;
}
if (yearNum < 2000) {
this.$Message.error("学年不能小于2000");
return;
}
const getDate = (s) => new Date(s);
const ys = getDate(form.yearStartDate);
const ye = getDate(form.yearEndDate);
const t1s = getDate(form.firstTermStartDate);
const t1e = getDate(form.firstTermEndDate);
const t2s = getDate(form.secondTermStartDate);
const t2e = getDate(form.secondTermEndDate);
const up = getDate(form.upgradeDate);
if (ys > ye) {
this.$Message.error("学年开始日期不能晚于学年结束日期");
return;
}
if (t1s > t1e) {
this.$Message.error("第一学期开始日期不能晚于第一学期结束日期");
return;
}
if (t2s > t2e) {
this.$Message.error("第二学期开始日期不能晚于第二学期结束日期");
return;
}
if (t1e > t2s) {
this.$Message.error("第一学期结束日期不能晚于第二学期开始日期");
return;
}
if (up < ye) {
this.$Message.error("毕业日期不能早于学年结束日期");
return;
}
// 编辑提交参数
const submitData = {
id: form.id,
year: yearNum,
yearStartDate: form.yearStartDate,
yearEndDate: form.yearEndDate,
firstTermStartDate: form.firstTermStartDate,
firstTermEndDate: form.firstTermEndDate,
secondTermStartDate: form.secondTermStartDate,
secondTermEndDate: form.secondTermEndDate,
upgradeDate: form.upgradeDate
};
const url = APIConfig.BschClassSystem.yeartermedit;
this.$api.post(url, JSON.stringify(submitData), resp => {
if (resp.code == 0) {
this.$Message.success("修改成功!");
this.editModalVisible = false;
this.getschsystemlist();
} else if (resp.code == 4) {
this.$Message.info(resp.msg);
}
});
});
}
}
};
</script>
<style scoped>
.page-container {
padding:0 16px;
background: #fff;
}
.page-title {
font-size: 24px;
font-weight: 500;
margin: 0 0 12px;
}
.btn-top-wrap {
background: #f7f8fa;
border-radius: 4px;
padding: 10px;
/* margin: 10px 0 15px; */
}
.term-table :deep(.ivu-table-row td) {
padding: 6px 0;
}
.form-block-title {
font-size: 16px;
font-weight: 500;
margin: 10px 0 10px;
padding-left: 6px;
border-left: 4px solid #2d8cf0;
}
.modal-footer {
text-align: right;
}
.modalform :deep(.ivu-modal-body) {
padding:10px;
}
</style>