|
|
<template>
|
|
|
<div>
|
|
|
<xy-dialog
|
|
|
ref="dialog"
|
|
|
:width="80"
|
|
|
:is-show.sync="isShow"
|
|
|
:type="'form'"
|
|
|
:title="type === 'add' ? '新增计划' : '编辑计划'"
|
|
|
:form="form"
|
|
|
:rules="rules"
|
|
|
@submit="submit"
|
|
|
>
|
|
|
<template v-slot:year>
|
|
|
<div class="xy-table-item">
|
|
|
<div class="xy-table-item-label" style="font-weight: bold">
|
|
|
<span style="color: red; font-weight: bold; padding-right: 4px;">*</span>计划年份:
|
|
|
</div>
|
|
|
<div class="xy-table-item-content">
|
|
|
<el-date-picker
|
|
|
v-model="form.year"
|
|
|
type="year"
|
|
|
value-format="yyyy"
|
|
|
format="yyyy"
|
|
|
placeholder="请选择计划年份"
|
|
|
style="width: 100%;"
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<template v-slot:plan_system_id>
|
|
|
<div class="xy-table-item">
|
|
|
<div class="xy-table-item-label" style="font-weight: bold">
|
|
|
<span style="color: red; font-weight: bold; padding-right: 4px;">*</span>计划体系:
|
|
|
</div>
|
|
|
<div class="xy-table-item-content">
|
|
|
<el-select v-model="form.plan_system_id" filterable clearable placeholder="请选择计划体系" style="width: 100%;">
|
|
|
<el-option
|
|
|
v-for="item in planSystemList"
|
|
|
:key="item.id"
|
|
|
:label="item.name"
|
|
|
:value="item.id"
|
|
|
/>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<template v-slot:course_type_id>
|
|
|
<div class="xy-table-item">
|
|
|
<div class="xy-table-item-label" style="font-weight: bold">
|
|
|
<span style="color: red; font-weight: bold; padding-right: 4px;">*</span>课程体系:
|
|
|
</div>
|
|
|
<div class="xy-table-item-content">
|
|
|
<el-select v-model="form.course_type_id" filterable clearable placeholder="请选择课程体系" style="width: 100%;">
|
|
|
<el-option
|
|
|
v-for="item in courseTypesList"
|
|
|
:key="item.id"
|
|
|
:label="item.name"
|
|
|
:value="item.id"
|
|
|
/>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<template v-slot:course_name>
|
|
|
<div class="xy-table-item">
|
|
|
<div class="xy-table-item-label" style="font-weight: bold">
|
|
|
<span style="color: red; font-weight: bold; padding-right: 4px;">*</span>课程名称:
|
|
|
</div>
|
|
|
<div class="xy-table-item-content">
|
|
|
<el-input v-model="form.course_name" placeholder="请输入课程名称" clearable style="width: 100%;" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<template v-slot:details>
|
|
|
<div class="xy-table-item">
|
|
|
<div class="xy-table-item-label detail-label" style="font-weight: bold">
|
|
|
<span style="color: red; font-weight: bold; padding-right: 4px;">*</span>模块/期数:
|
|
|
</div>
|
|
|
<div class="xy-table-item-content">
|
|
|
<div class="detail-wrap">
|
|
|
<div class="detail-toolbar">
|
|
|
<el-button type="primary" size="small" @click="addDetail">新增一条</el-button>
|
|
|
</div>
|
|
|
<el-table :data="form.details" border size="small" style="width: 100%;">
|
|
|
<el-table-column label="名称" min-width="180">
|
|
|
<template slot-scope="scope">
|
|
|
<el-input v-model="scope.row.name" placeholder="请输入模块/期数名称,非必填" size="small" />
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="月份" width="120">
|
|
|
<template slot-scope="scope">
|
|
|
<el-select v-model="scope.row.month" placeholder="月份" size="small" style="width: 100%;">
|
|
|
<el-option
|
|
|
v-for="item in monthOptions"
|
|
|
:key="item.value"
|
|
|
:label="item.label"
|
|
|
:value="item.value"
|
|
|
/>
|
|
|
</el-select>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="地点" min-width="180">
|
|
|
<template slot-scope="scope">
|
|
|
<el-select v-model="scope.row.location_id" filterable placeholder="请选择地点" size="small" style="width: 100%;">
|
|
|
<el-option
|
|
|
v-for="item in locationList"
|
|
|
:key="item.id"
|
|
|
:label="item.name"
|
|
|
:value="item.id"
|
|
|
/>
|
|
|
</el-select>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="负责人" min-width="160">
|
|
|
<template slot-scope="scope">
|
|
|
<el-input v-model="scope.row.owner_name" placeholder="请输入负责人" size="small" />
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column label="操作" width="100" align="center">
|
|
|
<template slot-scope="scope">
|
|
|
<el-button type="danger" size="mini" @click="removeDetail(scope.$index)">删除</el-button>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
<div class="detail-tip">至少保留一条模块/期数;名称可不填,月份、地点、负责人必填。</div>
|
|
|
<div v-if="type === 'editor'" class="danger-actions">
|
|
|
<el-button type="danger" size="small" @click="handleDeletePlan">删除计划</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
</xy-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import { showMockPlan as show, saveMockPlan as save, destroyMockPlan as destroy } from "../mockService.js";
|
|
|
|
|
|
const getCurrentYear = () => String(new Date().getFullYear());
|
|
|
|
|
|
const createDetail = () => ({
|
|
|
id: "",
|
|
|
name: "",
|
|
|
month: "",
|
|
|
location_id: "",
|
|
|
owner_name: "",
|
|
|
});
|
|
|
|
|
|
const getDefaultForm = () => ({
|
|
|
year: getCurrentYear(),
|
|
|
plan_system_id: "",
|
|
|
course_type_id: "",
|
|
|
course_name: "",
|
|
|
details: [createDetail()],
|
|
|
});
|
|
|
|
|
|
export default {
|
|
|
data() {
|
|
|
return {
|
|
|
isShow: false,
|
|
|
type: "add",
|
|
|
id: "",
|
|
|
courseTypesList: [],
|
|
|
planSystemList: [],
|
|
|
locationList: [],
|
|
|
form: getDefaultForm(),
|
|
|
rules: {
|
|
|
year: [{
|
|
|
required: true,
|
|
|
message: "请选择计划年份",
|
|
|
}],
|
|
|
plan_system_id: [{
|
|
|
required: true,
|
|
|
message: "请选择计划体系",
|
|
|
}],
|
|
|
course_type_id: [{
|
|
|
required: true,
|
|
|
message: "请选择课程体系",
|
|
|
}],
|
|
|
course_name: [{
|
|
|
required: true,
|
|
|
message: "请输入课程名称",
|
|
|
}],
|
|
|
},
|
|
|
monthOptions: Array.from({ length: 12 }, (_, index) => ({
|
|
|
value: index + 1,
|
|
|
label: `${index + 1}月`,
|
|
|
})),
|
|
|
};
|
|
|
},
|
|
|
methods: {
|
|
|
addDetail() {
|
|
|
this.form.details.push(createDetail());
|
|
|
},
|
|
|
removeDetail(index) {
|
|
|
if (this.form.details.length === 1) {
|
|
|
this.$message.warning("模块/期数至少保留一条");
|
|
|
return;
|
|
|
}
|
|
|
this.form.details.splice(index, 1);
|
|
|
},
|
|
|
normalizeDetail(item) {
|
|
|
return {
|
|
|
id: item.id || "",
|
|
|
name: item.name || item.module_name || "",
|
|
|
month: item.month === 0 ? 0 : Number(item.month || ""),
|
|
|
location_id: item.location_id || item.location?.id || "",
|
|
|
owner_name: item.owner_name || item.owner || item.principal || "",
|
|
|
};
|
|
|
},
|
|
|
getDetailListFromResponse(res) {
|
|
|
const list = res.details || res.detail_list || res.modules || res.items || [];
|
|
|
if (!Array.isArray(list) || !list.length) {
|
|
|
return [createDetail()];
|
|
|
}
|
|
|
return list.map((item) => this.normalizeDetail(item));
|
|
|
},
|
|
|
validateDetails() {
|
|
|
if (!Array.isArray(this.form.details) || this.form.details.length === 0) {
|
|
|
this.$message.warning("请至少新增一条模块/期数");
|
|
|
return false;
|
|
|
}
|
|
|
for (let index = 0; index < this.form.details.length; index += 1) {
|
|
|
const item = this.form.details[index];
|
|
|
if (!item.month) {
|
|
|
this.$message.warning(`第 ${index + 1} 条模块/期数未选择月份`);
|
|
|
return false;
|
|
|
}
|
|
|
if (!item.location_id) {
|
|
|
this.$message.warning(`第 ${index + 1} 条模块/期数未选择地点`);
|
|
|
return false;
|
|
|
}
|
|
|
if (!item.owner_name) {
|
|
|
this.$message.warning(`第 ${index + 1} 条模块/期数未填写负责人`);
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
return true;
|
|
|
},
|
|
|
submit() {
|
|
|
if (!this.validateDetails()) {
|
|
|
return;
|
|
|
}
|
|
|
const payload = {
|
|
|
id: this.type === "editor" ? this.id : "",
|
|
|
year: this.form.year,
|
|
|
plan_system_id: this.form.plan_system_id,
|
|
|
course_type_id: this.form.course_type_id,
|
|
|
course_name: this.form.course_name,
|
|
|
details: this.form.details.map((item) => ({
|
|
|
id: item.id || "",
|
|
|
name: item.name || "",
|
|
|
month: Number(item.month),
|
|
|
location_id: item.location_id,
|
|
|
owner_name: item.owner_name,
|
|
|
})),
|
|
|
};
|
|
|
save(payload).then(() => {
|
|
|
this.$message({
|
|
|
type: "success",
|
|
|
message: this.type === "add" ? "新增成功" : "编辑成功",
|
|
|
});
|
|
|
this.isShow = false;
|
|
|
this.$emit("refresh");
|
|
|
});
|
|
|
},
|
|
|
getDetail() {
|
|
|
show({ id: this.id }).then((res) => {
|
|
|
this.form = {
|
|
|
year: String(res.year || getCurrentYear()),
|
|
|
plan_system_id: res.plan_system_id || res.plan_system?.id || res.plan_system_detail?.id || "",
|
|
|
course_type_id: res.course_type_id || res.course_type?.id || res.type_detail?.id || "",
|
|
|
course_name: res.course_name || res.name || "",
|
|
|
details: this.getDetailListFromResponse(res),
|
|
|
};
|
|
|
});
|
|
|
},
|
|
|
handleDeletePlan() {
|
|
|
this.$confirm(
|
|
|
"删除该计划将删除所有的模块/期数,是否确认删除?",
|
|
|
"提示",
|
|
|
{
|
|
|
type: "warning",
|
|
|
confirmButtonText: "确定",
|
|
|
cancelButtonText: "取消",
|
|
|
}
|
|
|
).then(() => {
|
|
|
destroy({ id: this.id }).then(() => {
|
|
|
this.$message.success("删除成功");
|
|
|
this.isShow = false;
|
|
|
this.$emit("refresh");
|
|
|
});
|
|
|
}).catch(() => {});
|
|
|
},
|
|
|
resetForm() {
|
|
|
this.id = "";
|
|
|
this.form = getDefaultForm();
|
|
|
this.$refs.dialog.reset();
|
|
|
},
|
|
|
},
|
|
|
watch: {
|
|
|
isShow(newVal) {
|
|
|
if (newVal) {
|
|
|
if (this.type === "editor" && this.id) {
|
|
|
this.getDetail();
|
|
|
}
|
|
|
} else if (this.$refs.dialog) {
|
|
|
this.resetForm();
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
::v-deep .year,
|
|
|
::v-deep .plan_system_id,
|
|
|
::v-deep .course_type_id,
|
|
|
::v-deep .course_name,
|
|
|
::v-deep .details {
|
|
|
flex-basis: 100%;
|
|
|
}
|
|
|
|
|
|
.detail-label {
|
|
|
align-self: flex-start;
|
|
|
padding-top: 8px;
|
|
|
}
|
|
|
|
|
|
.detail-wrap {
|
|
|
width: 100%;
|
|
|
}
|
|
|
|
|
|
.detail-toolbar {
|
|
|
margin-bottom: 10px;
|
|
|
}
|
|
|
|
|
|
.detail-tip {
|
|
|
margin-top: 8px;
|
|
|
font-size: 12px;
|
|
|
color: #909399;
|
|
|
}
|
|
|
|
|
|
.danger-actions {
|
|
|
margin-top: 16px;
|
|
|
text-align: right;
|
|
|
}
|
|
|
</style>
|