master
lion 3 months ago
parent 48c9a71c19
commit 4e55f9b882

@ -0,0 +1,60 @@
import request from "@/utils/request";
function customParamsSerializer(params) {
let result = '';
for (let key in params) {
if (params.hasOwnProperty(key)) {
if (Array.isArray(params[key])) {
params[key].forEach((item,index) => {
if(item.key){
result += `${key}[${index}][key]=${item.key}&${key}[${index}][op]=${item.op}&${key}[${index}][value]=${item.value}&`;
}else{
result +=`${key}[${index}]=${item}&`
}
});
} else {
result += `${key}=${params[key]}&`;
}
}
}
return result.slice(0, -1);
}
export function index(params,isLoading = false) {
return request({
method: "get",
url: "/api/admin/calendars/index",
params,
paramsSerializer: customParamsSerializer,
isLoading
})
}
export function show(params, isLoading = true) {
return request({
method: "get",
url: "/api/admin/calendars/show",
params,
isLoading
})
}
export function save(data) {
return request({
method: "post",
url: "/api/admin/calendars/save",
data
})
}
export function destroy(params) {
return request({
method: "get",
url: "/api/admin/calendars/destroy",
params
})
}

@ -0,0 +1,321 @@
<template>
<div>
<xy-dialog ref="dialog" :width="70" :is-show.sync="isShow" :type="'form'" :title="type === 'add' ? '新增日程' : '编辑日程'"
:form="form" :rules='rules' @submit="submit">
<template v-slot:type>
<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.type" @change="changeType" placeholder="请选择日程类型" clearable style="width: 100%;">
<el-option v-for="item in type_options" :key="item.id" :label="item.value" :value="item.id">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-if="form.type===1||form.type===2" v-slot:course_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_id" :disabled="canSelect" @change="changeCourse" placeholder="请选择课程"
clearable style="width: 100%;">
<el-option v-for="item in course_options" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-if="form.type===2" v-slot:course_content_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_content_id" @change="changeCourseContent" placeholder="请选择课表" clearable
style="width: 100%;">
<el-option v-for="item in course_content_options" :key="item.id" :label="item.theme" :value="item.id">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:title>
<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.title" placeholder="请输入标题" clearable style="width: 100%;"></el-input>
</div>
</div>
</template>
<template v-if="form.type===4" v-slot:url>
<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.url" placeholder="请输入跳转链接,例:/news/2025-07-02/146.html" clearable
style="width: 100%;"></el-input>
</div>
</div>
</template>
<template v-slot:date>
<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.date" style="width: 100%;"
type="date" value-format="yyyy-MM-dd" format="yyyy-MM-dd" placeholder="选择日期时间" align="right">
</el-date-picker>
</div>
</div>
</template>
<template v-slot:start_time>
<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.start_time"
style="width: 100%;"
value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd HH:mm:ss"
type="datetime" placeholder="选择日期时间" align="right"
:picker-options="pickerOptions">
</el-date-picker>
</div>
</div>
</template>
<template v-slot:end_time>
<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.end_time"
style="width: 100%;"
value-format="yyyy-MM-dd HH:mm:ss" format="yyyy-MM-dd HH:mm:ss"
type="datetime" placeholder="选择日期时间" align="right"
:picker-options="pickerOptions">
</el-date-picker>
</div>
</div>
</template>
<template v-slot:content>
<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">
<my-tinymce v-if="showTinymce" @input="saveContent" :value="form.content"></my-tinymce>
</div>
</div>
</template>
</xy-dialog>
</div>
</template>
<script>
import {
show,
save
} from "@/api/calendars/index.js"
import {
index as courseIndex
} from "@/api/course/index.js"
import {
index as courseContentIndex
} from "@/api/course/courseContent.js"
export default {
components: {
},
data() {
return {
isShow: false,
type: 'add',
id: '',
showTinymce: false,
pickerOptions: {
shortcuts: [{
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
}
}, {
text: '昨天',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', date);
}
}, {
text: '一周前',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', date);
}
}]
},
type_options: [{
id: 1,
value: '课程'
}, {
id: 2,
value: '课表'
}, {
id: 3,
value: '自定义事件'
}, {
id: 4,
value: '资讯'
}],
course_options: [],
canSelect: false,
form: {
type: '',
course_id: '',
course_content_id: '',
title: '',
url: '',
date: '',
start_time: '',
end_time: '',
content: '',
},
rules: {
title: [{
required: true,
message: '请输入标题'
}],
start_time: [{
required: true,
message: '请选择开始时间'
}],
end_time: [{
required: true,
message: '请选择结束时间'
}],
}
}
},
created() {
this.getCourseList()
},
methods: {
async getCourseList() {
const res = await courseIndex({
page: 1,
page_size: 999,
sort_name: 'id',
sort_type: 'DESC',
show_relation: ['image']
})
this.course_options = res.data
},
async getCourseContentList(course_id) {
const res = await courseContentIndex({
page: 1,
page_size: 999,
filter: [{
key: 'course_id',
op: 'like',
value: course_id
}]
})
if (res.data.length < 1) {
this.$Message.warning("该课程暂无课表")
return
}
this.course_options = res.data
},
saveContent(e) {
this.form.content = e
},
changeType(e) {
console.log("type", e)
},
changeCourse(e) {
console.log("course", e)
if (e && e === 2) {
this.form.course_content_id = ''
this.getCourseContentList(e)
}
},
changeCourseContent() {
},
submit() {
if (this.id) {
this.form.id = this.id
}
if (this.type == 'add') {
this.form.id = ''
}
save({
...this.form
}).then(res => {
this.$message({
type: 'success',
message: this.type === 'add' ? '新增成功' : '编辑成功'
})
this.isShow = false
this.$emit('refresh')
})
},
getDetail() {
show({
id: this.id,
show_relation: ['image']
}).then(res => {
this.form = this.base.requestToForm(res, this.form)
this.showTinymce = true
})
}
},
watch: {
isShow(newVal) {
if (newVal) {
if (this.type === 'editor') {
this.getDetail()
}else{
this.showTinymce = true
}
} else {
this.id = ''
this.showTinymce = false
this.form = {
type: '',
course_id: '',
course_content_id: '',
title: '',
url: '',
date: '',
start_time: '',
end_time: '',
content: '',
}
this.$refs['dialog'].reset()
}
},
}
}
</script>
<style scoped lang="scss">
::v-deep .content {
flex-basis: 100%;
}
</style>

@ -25,7 +25,7 @@
@click="fetchData">拉取并关联</el-button>
</el-form>
<el-button type="success" icon="el-icon-plus" style="width:100%;margin-top:10px;"
@click="openCreateModal">新建日历事件</el-button>
@click="openCreateModal('add')">新建日历事件</el-button>
</div>
<!-- 日历预览区 -->
<div class="admin-panel" style="min-width:0;flex:2;">
@ -55,75 +55,14 @@
style="margin-left:8px;">到期后{{ expireText(ev.expire) }}</el-tag>
</div>
<div style="margin-top:4px;">
<el-button size="mini" type="primary" icon="el-icon-edit" @click="editEvent(idx)"></el-button>
<el-button size="mini" type="primary" icon="el-icon-edit" @click="openCreateModal('editor',idx.id)"></el-button>
</div>
</el-timeline-item>
</el-timeline>
</div>
</div>
</div>
<!-- 新建/编辑事件弹窗 -->
<el-dialog :title="modalTitle" :visible.sync="modalVisible" width="420px">
<el-form :model="modalForm" label-width="80px" size="small">
<el-form-item label="事件类型">
<el-select v-model="modalForm.type">
<el-option label="课程" value="course" />
<el-option label="活动" value="activity" />
<el-option label="移动课堂" value="workshop" />
</el-select>
</el-form-item>
<el-form-item label="标题">
<el-input v-model="modalForm.title" />
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker v-model="modalForm.start" type="datetime" value-format="yyyy-MM-ddTHH:mm" />
</el-form-item>
<el-form-item label="结束时间">
<el-date-picker v-model="modalForm.end" type="datetime" value-format="yyyy-MM-ddTHH:mm" />
</el-form-item>
<el-form-item label="地点">
<el-input v-model="modalForm.location" />
</el-form-item>
<el-form-item label="主讲/负责人">
<el-input v-model="modalForm.teacher" />
</el-form-item>
<el-form-item label="描述">
<el-input type="textarea" v-model="modalForm.description" :rows="2" />
</el-form-item>
<el-form-item label="到期后操作">
<el-select v-model="modalForm.expire">
<el-option label="无" value="none" />
<el-option label="标记为已过期" value="mark" />
<el-option label="自动删除" value="delete" />
<el-option label="发送提醒" value="remind" />
</el-select>
</el-form-item>
</el-form>
<div slot="footer">
<el-button @click="modalVisible=false"></el-button>
<el-button type="primary" @click="saveEvent"></el-button>
</div>
</el-dialog>
<!-- 事件详情弹窗 -->
<el-dialog title="事件详情" :visible.sync="eventDetailVisible" width="350px" :show-close="true">
<div v-if="eventDetail">
<b>{{ eventDetail.title }}</b>
<el-tag size="mini" style="margin-left:8px;">{{ typeText(eventDetail.className) }}</el-tag>
<div style="margin:8px 0 4px 0;">
<span><i class="el-icon-time"></i> {{ eventDetail.start | formatDateTime }} ~
{{ eventDetail.end | formatDateTime }}</span>
</div>
<div v-if="eventDetail.location"><i class="el-icon-location-outline"></i> {{ eventDetail.location }}</div>
<div v-if="eventDetail.teacher"><i class="el-icon-user"></i> {{ eventDetail.teacher }}</div>
<div v-if="eventDetail.description"><i class="el-icon-document"></i> {{ eventDetail.description }}</div>
<div v-if="eventDetail.expire && eventDetail.expire !== 'none'" style="margin-top:6px;">
<el-tag size="mini" type="warning">到期后{{ expireText(eventDetail.expire) }}</el-tag>
</div>
</div>
<div slot="footer">
<el-button @click="eventDetailVisible=false"></el-button>
</div>
</el-dialog>
<addCalendar ref="addCalendar" @refresh="getList"></addCalendar>
</div>
</template>
@ -177,8 +116,15 @@
teacher: '创业导师团',
description: '创新创业实战训练'
}]
};
export default {
};
import addCalendar from "./components/addCalendar.vue"
import {
index
} from "@/api/calendars/index.js"
export default {
components:{
addCalendar
},
data() {
return {
dataType: 'course',
@ -213,15 +159,29 @@
const evDate = new Date(ev.start);
return evDate.getMonth() === month && evDate.getFullYear() === year;
});
},
selectMonth(){
console.log(this.calendarDate)
const now = this.calendarDate instanceof Date ? this.calendarDate : new Date(this.calendarDate);
const month = now.getMonth()+1<10?'0'+(now.getMonth()+1):now.getMonth()+1;
const year = now.getFullYear();
return year+'-'+month;
}
},
watch: {
dataType: 'onTypeChange'
},
created() {
this.onTypeChange();
this.onTypeChange();
this.getList()
},
methods: {
methods: {
async getList(){
const res = await index({
month:this.selectMonth
})
},
onTypeChange() {
this.dataList = mockData[this.dataType] || [];
this.dataId = '';
@ -252,20 +212,12 @@
});
}
},
openCreateModal() {
this.modalTitle = '新建事件';
this.modalForm = {
type: 'course',
title: '',
start: '',
end: '',
location: '',
teacher: '',
description: '',
expire: 'none'
};
this.editingIndex = null;
this.modalVisible = true;
openCreateModal(type,id) {
if(id){
this.$refs.addCalendar.id = id
}
this.$refs.addCalendar.type = type
this.$refs.addCalendar.isShow = true
},
saveEvent() {
if (!this.modalForm.title || !this.modalForm.start || !this.modalForm.end) {

@ -209,7 +209,34 @@
},
viewResults(survey) {
this.resultsSurveyData = survey;
this.resultsSurveyData = {
id: 1,
title: '问卷1',
description: '请对本次智能制造专题课程进行评价和反馈',
status: 'published',
type: 'feedback',
bindType: 'course',
bindCourse: '2025产业加速营 | 智能制造专题',
createTime: '2025-06-01 10:00',
deadline: '2025-06-10 23:59',
responses: 1,
questions: 6,
avgScore: 4.6,
questions: [
{
id: 101,
type: 'single',
title: '单选框',
options: ['单选1', '单选2',]
},
// {
// id: 102,
// type: 'rate',
// title: '',
// rateMax: 5
// }
]
};
this.resultsDialogVisible = true;
},
previewSurvey(survey) {

Loading…
Cancel
Save