- 构建: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 行渲染、操作列按钮点击弹窗正常。
563 lines
19 KiB
Vue
563 lines
19 KiB
Vue
<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> |