czq
parent
d90126b45c
commit
67283cf653
@ -1,5 +1,11 @@
|
||||
import userApi from './user';
|
||||
import postApi from './post';
|
||||
import resourceApi from './resource';
|
||||
import scheduleApi from './schedule';
|
||||
|
||||
export {
|
||||
userApi
|
||||
userApi,
|
||||
postApi,
|
||||
resourceApi,
|
||||
scheduleApi
|
||||
};
|
||||
|
@ -0,0 +1,102 @@
|
||||
import { get, post, put, del } from './request';
|
||||
|
||||
// 资源类型定义
|
||||
export interface ResourceItem {
|
||||
id: number;
|
||||
title: string;
|
||||
description?: string;
|
||||
fileUrl: string;
|
||||
fileSize: number;
|
||||
fileType: string;
|
||||
userId: number;
|
||||
nickname: string;
|
||||
avatar?: string;
|
||||
categoryId: number;
|
||||
categoryName: string;
|
||||
downloadCount: number;
|
||||
likeCount: number;
|
||||
isLiked?: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface ResourceCategory {
|
||||
id: number;
|
||||
name: string;
|
||||
description?: string;
|
||||
icon?: string;
|
||||
}
|
||||
|
||||
export interface ResourceParams {
|
||||
page?: number;
|
||||
size?: number;
|
||||
categoryId?: number;
|
||||
keyword?: string;
|
||||
userId?: number;
|
||||
}
|
||||
|
||||
export interface UploadResourceParams {
|
||||
title: string;
|
||||
description?: string;
|
||||
categoryId: number;
|
||||
file: File;
|
||||
}
|
||||
|
||||
export interface UpdateResourceParams {
|
||||
title?: string;
|
||||
description?: string;
|
||||
categoryId?: number;
|
||||
}
|
||||
|
||||
// 资源API
|
||||
export default {
|
||||
// 获取资源列表
|
||||
getResources(params: ResourceParams = {}) {
|
||||
return get<{ code: number; data: { total: number; list: ResourceItem[]; pages: number } }>('/resources', params);
|
||||
},
|
||||
|
||||
// 获取资源详情
|
||||
getResourceDetail(id: number) {
|
||||
return get<{ code: number; data: ResourceItem }>(`/resources/${id}`);
|
||||
},
|
||||
|
||||
// 上传资源
|
||||
uploadResource(data: FormData) {
|
||||
return post<{ code: number; data: { resourceId: number } }>('/resources', data);
|
||||
},
|
||||
|
||||
// 更新资源信息
|
||||
updateResource(id: number, data: UpdateResourceParams) {
|
||||
return put<{ code: number; message: string }>(`/resources/${id}`, data);
|
||||
},
|
||||
|
||||
// 删除资源
|
||||
deleteResource(id: number) {
|
||||
return del<{ code: number; message: string }>(`/resources/${id}`);
|
||||
},
|
||||
|
||||
// 下载资源
|
||||
downloadResource(id: number) {
|
||||
return get<{ code: number; data: { fileUrl: string; fileName: string; fileType: string } }>(`/resources/${id}/download`);
|
||||
},
|
||||
|
||||
// 点赞/取消点赞资源
|
||||
likeResource(id: number) {
|
||||
return post<{ code: number; message: string }>(`/resources/${id}/like`);
|
||||
},
|
||||
|
||||
// 获取用户上传的资源列表
|
||||
getUserResources(userId: number) {
|
||||
return get<{ code: number; data: { total: number; list: ResourceItem[]; pages: number } }>(`/resources/user/${userId}`);
|
||||
},
|
||||
|
||||
// 获取当前用户上传的资源列表
|
||||
getMyResources(params: { page?: number; size?: number } = {}) {
|
||||
return get<{ code: number; data: { total: number; list: ResourceItem[]; pages: number } }>('/resources/my', params);
|
||||
},
|
||||
|
||||
// 获取资源分类
|
||||
getResourceCategories() {
|
||||
return get<{ code: number; data: { list: ResourceCategory[]; total: number } }>('/categories');
|
||||
}
|
||||
};
|
@ -0,0 +1,294 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:title="isEditing ? '编辑日程' : '添加日程'"
|
||||
width="500px"
|
||||
@closed="handleClosed"
|
||||
>
|
||||
<el-form :model="form" label-width="80px" :rules="rules" ref="formRef">
|
||||
<el-form-item label="标题" prop="title">
|
||||
<el-input v-model="form.title" placeholder="请输入日程标题"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="全天" prop="isAllDay">
|
||||
<el-switch v-model="form.isAllDay" :active-value="1" :inactive-value="0"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="startTime">
|
||||
<el-date-picker
|
||||
v-if="form.isAllDay === 1"
|
||||
v-model="form.startDate"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
></el-date-picker>
|
||||
<el-date-picker
|
||||
v-else
|
||||
v-model="form.startTime"
|
||||
type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
value-format="YYYY-MM-DDTHH:mm:00"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endTime">
|
||||
<el-date-picker
|
||||
v-if="form.isAllDay === 1"
|
||||
v-model="form.endDate"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
:disabled-date="disabledEndDate"
|
||||
></el-date-picker>
|
||||
<el-date-picker
|
||||
v-else
|
||||
v-model="form.endTime"
|
||||
type="datetime"
|
||||
placeholder="选择日期时间"
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
value-format="YYYY-MM-DDTHH:mm:00"
|
||||
:disabled-date="disabledEndDate"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="地点" prop="location">
|
||||
<el-input v-model="form.location" placeholder="请输入地点"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="提醒" prop="reminder">
|
||||
<el-select v-model="form.reminder" placeholder="请选择提醒时间">
|
||||
<el-option label="不提醒" :value="0"></el-option>
|
||||
<el-option label="5分钟前" :value="5"></el-option>
|
||||
<el-option label="15分钟前" :value="15"></el-option>
|
||||
<el-option label="30分钟前" :value="30"></el-option>
|
||||
<el-option label="1小时前" :value="60"></el-option>
|
||||
<el-option label="2小时前" :value="120"></el-option>
|
||||
<el-option label="1天前" :value="1440"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="颜色" prop="color">
|
||||
<el-color-picker v-model="form.color"></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input
|
||||
v-model="form.description"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入日程描述"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm" :loading="submitting">
|
||||
保存
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, watch, defineProps, defineEmits } from 'vue';
|
||||
import { ElMessage, FormInstance } from 'element-plus';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
schedule: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
initialDate: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
initialHour: {
|
||||
type: Number,
|
||||
default: undefined
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:visible', 'submit', 'delete']);
|
||||
|
||||
// 对话框状态
|
||||
const dialogVisible = computed({
|
||||
get: () => props.visible,
|
||||
set: (val) => emit('update:visible', val)
|
||||
});
|
||||
|
||||
// 表单引用
|
||||
const formRef = ref<FormInstance>();
|
||||
const submitting = ref(false);
|
||||
|
||||
// 表单数据
|
||||
const form = reactive({
|
||||
id: undefined as number | undefined,
|
||||
title: '',
|
||||
isAllDay: 0,
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
location: '',
|
||||
reminder: 0,
|
||||
color: '#409EFF',
|
||||
description: ''
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
title: [{ required: true, message: '请输入日程标题', trigger: 'blur' }],
|
||||
startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
|
||||
endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
|
||||
startDate: [{ required: true, message: '请选择开始日期', trigger: 'change' }],
|
||||
endDate: [{ required: true, message: '请选择结束日期', trigger: 'change' }]
|
||||
};
|
||||
|
||||
// 监听props变化
|
||||
watch(() => props.visible, (val) => {
|
||||
if (val) {
|
||||
initForm();
|
||||
}
|
||||
});
|
||||
|
||||
// 初始化表单
|
||||
const initForm = () => {
|
||||
if (props.isEditing && props.schedule) {
|
||||
// 编辑模式
|
||||
form.id = props.schedule.id;
|
||||
form.title = props.schedule.title;
|
||||
form.isAllDay = props.schedule.isAllDay;
|
||||
form.location = props.schedule.location || '';
|
||||
form.reminder = props.schedule.reminder || 0;
|
||||
form.color = props.schedule.color || '#409EFF';
|
||||
form.description = props.schedule.description || '';
|
||||
|
||||
if (form.isAllDay === 1) {
|
||||
form.startDate = dayjs(props.schedule.startTime).format('YYYY-MM-DD');
|
||||
form.endDate = dayjs(props.schedule.endTime).format('YYYY-MM-DD');
|
||||
} else {
|
||||
form.startTime = dayjs(props.schedule.startTime).format('YYYY-MM-DDTHH:mm:00');
|
||||
form.endTime = dayjs(props.schedule.endTime).format('YYYY-MM-DDTHH:mm:00');
|
||||
}
|
||||
} else {
|
||||
// 添加模式
|
||||
form.id = undefined;
|
||||
form.title = '';
|
||||
form.isAllDay = 0;
|
||||
form.location = '';
|
||||
form.reminder = 0;
|
||||
form.color = getRandomColor();
|
||||
form.description = '';
|
||||
|
||||
// 设置初始日期和时间
|
||||
const initialDate = props.initialDate || new Date();
|
||||
const initialHour = props.initialHour !== undefined ? props.initialHour : initialDate.getHours();
|
||||
|
||||
const startDate = dayjs(initialDate);
|
||||
const endDate = dayjs(initialDate).add(1, 'hour');
|
||||
|
||||
form.startDate = startDate.format('YYYY-MM-DD');
|
||||
form.endDate = startDate.format('YYYY-MM-DD');
|
||||
|
||||
form.startTime = startDate.hour(initialHour).minute(0).format('YYYY-MM-DDTHH:mm:00');
|
||||
form.endTime = startDate.hour(initialHour + 1).minute(0).format('YYYY-MM-DDTHH:mm:00');
|
||||
}
|
||||
};
|
||||
|
||||
// 禁用结束日期早于开始日期
|
||||
const disabledEndDate = (time: Date) => {
|
||||
if (form.isAllDay === 1) {
|
||||
return dayjs(time).isBefore(dayjs(form.startDate));
|
||||
} else {
|
||||
return dayjs(time).isBefore(dayjs(form.startTime));
|
||||
}
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const submitForm = async () => {
|
||||
if (!formRef.value) return;
|
||||
|
||||
await formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
submitting.value = true;
|
||||
|
||||
try {
|
||||
// 构建提交数据
|
||||
const data: any = {
|
||||
title: form.title,
|
||||
isAllDay: form.isAllDay,
|
||||
location: form.location,
|
||||
reminder: form.reminder,
|
||||
color: form.color,
|
||||
description: form.description
|
||||
};
|
||||
|
||||
// 处理日期时间
|
||||
if (form.isAllDay === 1) {
|
||||
data.startTime = `${form.startDate}T00:00:00`;
|
||||
data.endTime = `${form.endDate}T23:59:59`;
|
||||
} else {
|
||||
data.startTime = form.startTime;
|
||||
data.endTime = form.endTime;
|
||||
}
|
||||
|
||||
// 提交数据
|
||||
emit('submit', {
|
||||
id: form.id,
|
||||
...data
|
||||
});
|
||||
|
||||
dialogVisible.value = false;
|
||||
} catch (error) {
|
||||
console.error('提交日程失败:', error);
|
||||
ElMessage.error('提交日程失败');
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 处理对话框关闭
|
||||
const handleClosed = () => {
|
||||
formRef.value?.resetFields();
|
||||
};
|
||||
|
||||
// 获取随机颜色
|
||||
const getRandomColor = () => {
|
||||
const colors = [
|
||||
'#409EFF', // 蓝色
|
||||
'#67C23A', // 绿色
|
||||
'#E6A23C', // 黄色
|
||||
'#F56C6C', // 红色
|
||||
'#909399', // 灰色
|
||||
'#9966CC', // 紫色
|
||||
'#FF9900', // 橙色
|
||||
'#19CAAD', // 青色
|
||||
'#8CC7B5', // 浅绿
|
||||
'#A0EEE1', // 浅青
|
||||
'#BEE7E9', // 浅蓝
|
||||
'#BEEDC7', // 浅绿
|
||||
'#D6D5B7', // 浅黄
|
||||
'#D1BA74', // 浅棕
|
||||
'#E6CEAC', // 浅橙
|
||||
'#ECAD9E' // 浅红
|
||||
];
|
||||
return colors[Math.floor(Math.random() * colors.length)];
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
Binary file not shown.
Loading…
Reference in new issue