<template>
|
<view class="container">
|
<!-- 日历选择区 -->
|
<view class="schedule-section">
|
<view class="section-header">
|
<uni-datetime-picker
|
type="date"
|
:insert="true"
|
v-model="selectedDate"
|
@change="onDateChange"
|
/>
|
<button class="add-btn" type="primary" size="mini" @click="handleAddSchedule()">新增日程</button>
|
</view>
|
|
<scroll-view scroll-y class="schedule-list">
|
<view v-if="schedules.length === 0" class="empty-state">
|
<text>该日暂无日程安排</text>
|
</view>
|
<view v-for="item in schedules" :key="item.id" class="schedule-card">
|
<view class="card-content">
|
<view class="project-info">
|
<uni-icons type="folder-add" size="16" color="#2979ff"></uni-icons>
|
<text class="project-name">{{ getProjectName(item.projectId) }}</text>
|
</view>
|
<text class="content-text">{{ item.content }}</text>
|
<view class="time-info">
|
<uni-icons type="calendar" size="14" color="#999"></uni-icons>
|
<text class="time-text">完成:{{ item.completedTime || '未设置' }}</text>
|
</view>
|
</view>
|
<view class="card-actions">
|
<view class="action-item" @click="handleEditSchedule(item)">
|
<uni-icons type="compose" size="18" color="#666"></uni-icons>
|
<text>编辑</text>
|
</view>
|
<view class="action-item delete" @click="handleDeleteSchedule(item)">
|
<uni-icons type="trash" size="18" color="#f56c6c"></uni-icons>
|
<text>删除</text>
|
</view>
|
</view>
|
</view>
|
</scroll-view>
|
</view>
|
|
<!-- 新增/编辑弹窗 (自定义实现) -->
|
<view v-if="showPopup" class="custom-popup-mask" @click="closePopup">
|
<view class="custom-popup-content" @click.stop>
|
<view class="popup-header">
|
<text>{{ diaLogTitle }}</text>
|
<uni-icons type="closeempty" size="24" @click="closePopup"></uni-icons>
|
</view>
|
|
<view class="form-container">
|
<view class="form-item">
|
<text class="label">选择项目 <text class="required">*</text></text>
|
<picker
|
@change="onProjectChange"
|
:value="projectIndex"
|
:range="allProjects"
|
range-key="name"
|
>
|
<view class="picker-view">
|
{{ projectIndex > -1 ? allProjects[projectIndex].name : '请选择项目' }}
|
</view>
|
</picker>
|
</view>
|
|
<view class="form-item">
|
<text class="label">工作内容 <text class="required">*</text></text>
|
<textarea
|
v-model="scheduleForm.content"
|
placeholder="请输入工作内容"
|
class="custom-textarea"
|
auto-height
|
/>
|
</view>
|
|
<view class="form-item">
|
<text class="label">完成日期 <text class="required">*</text></text>
|
<uni-datetime-picker
|
type="date"
|
:clear-icon="false"
|
v-model="scheduleForm.completedTime"
|
/>
|
</view>
|
</view>
|
|
<view class="popup-footer">
|
<button class="submit-btn" type="primary" @click="submitSaveSchedule()">确 定</button>
|
</view>
|
</view>
|
</view>
|
|
<!-- <BottomTabBar active="report" /> -->
|
</view>
|
</template>
|
|
<script>
|
import { add, update, del, listByDate } from "@/api/workbench/workbench";
|
import { getProjectSelectList } from "@/api/index";
|
import { formatCalendarDate, formatDateToFrontend } from "@/utils/date.js";
|
import BottomTabBar from '@/components/BottomTabBar.vue'
|
|
export default {
|
components: { BottomTabBar },
|
data() {
|
return {
|
showPopup: false,
|
projectIndex: -1,
|
selectedDate: formatCalendarDate(new Date()),
|
diaLogTitle: "新增日程",
|
schedules: [],
|
allProjects: [],
|
scheduleForm: {
|
id: '',
|
projectId: '',
|
content: '',
|
completedTime: ''
|
}
|
};
|
},
|
computed: {
|
projectOptions() {
|
return Array.isArray(this.allProjects) ? this.allProjects.map(p => ({ value: p.id, text: p.name })) : [];
|
}
|
},
|
onLoad() {
|
this.initData();
|
},
|
methods: {
|
async initData() {
|
try {
|
const res = await getProjectSelectList();
|
if(res.statusCode === 200){
|
// 转换一下
|
this.allProjects = Object.entries(res.data.data).map(([id, name]) => ({
|
id: id, // 项目ID(如"151")
|
name: name // 项目名称(如"射洪市万林钢厂片区棚户区改造项目")
|
}));
|
}
|
this.getScheduleList();
|
} catch (e) {
|
console.error(e);
|
this.allProjects = [];
|
}
|
},
|
async getScheduleList() {
|
const form ={
|
completedTime: formatDateToFrontend(this.selectedDate),
|
projectId:"all"
|
}
|
try {
|
const res = await listByDate(form);
|
// 过滤出选中日期的日程
|
if(res.statusCode ===200){
|
const list = res.data.data;
|
this.schedules = list.filter(s => s.date === this.selectedDate);
|
}
|
} catch (e) {
|
console.error(e);
|
this.schedules = [];
|
}
|
},
|
getProjectName(id) {
|
if (!Array.isArray(this.allProjects)) return '未知项目';
|
const project = this.allProjects.find(p => p.id == id);
|
return project ? project.name : '未知项目';
|
},
|
onDateChange(val) {
|
this.selectedDate = val;
|
this.getScheduleList();
|
},
|
onProjectChange(e) {
|
this.projectIndex = e.detail.value;
|
this.scheduleForm.projectId = this.allProjects[this.projectIndex].id;
|
},
|
handleAddSchedule() {
|
this.diaLogTitle = "新增日程";
|
this.resetScheduleForm();
|
this.showPopup = true;
|
},
|
handleEditSchedule(item) {
|
this.diaLogTitle = "编辑日程";
|
this.scheduleForm = {
|
id: item.id,
|
projectId: item.projectId,
|
content: item.title || item.content, // 兼容处理
|
completedTime: item.completedTime
|
};
|
|
if (Array.isArray(this.allProjects)) {
|
this.projectIndex = this.allProjects.findIndex(p => p.id == item.projectId);
|
}
|
this.showPopup = true;
|
},
|
async handleDeleteSchedule(item) {
|
uni.showModal({
|
title: '提示',
|
content: '确定要删除该日程吗?',
|
success: async (res) => {
|
if (res.confirm) {
|
try {
|
const result = await del(item.id);
|
if (result.statusCode === 200) {
|
uni.showToast({ title: '删除成功' });
|
this.getScheduleList();
|
}
|
} catch (e) {
|
console.error(e);
|
}
|
}
|
}
|
});
|
},
|
closePopup() {
|
this.showPopup = false;
|
},
|
resetScheduleForm() {
|
this.scheduleForm = {
|
id: '',
|
projectId: '',
|
content: '',
|
completedTime: ''
|
};
|
this.projectIndex = -1;
|
},
|
async submitSaveSchedule() {
|
if (!this.scheduleForm.projectId) {
|
uni.showToast({ title: '请选择项目', icon: 'none' });
|
return;
|
}
|
if (!this.scheduleForm.content) {
|
uni.showToast({ title: '请输入日程内容', icon: 'none' });
|
return;
|
}
|
if (!this.scheduleForm.completedTime) {
|
uni.showToast({ title: '请选择完成日期', icon: 'none' });
|
return;
|
}
|
console.log(this.scheduleForm)
|
try {
|
|
let result;
|
if (this.scheduleForm.id) {
|
const submitData = {
|
id:this.scheduleForm.id,
|
content: this.scheduleForm.content,
|
completedTime: formatDateToFrontend(this.scheduleForm.completedTime),
|
projectId:this.scheduleForm.projectId
|
};
|
result = await update(submitData);
|
} else {
|
const submitData = {
|
content: this.scheduleForm.content,
|
completedTime: formatDateToFrontend(this.scheduleForm.completedTime),
|
projectId:this.scheduleForm.projectId
|
};
|
result = await add(submitData);
|
}
|
if (result.statusCode === 200) {
|
uni.showToast({ title: '保存成功' });
|
this.closePopup();
|
this.getScheduleList();
|
}
|
} catch (e) {
|
console.error(e);
|
}
|
}
|
}
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
.container {
|
background-color: #f5f7fa;
|
min-height: 100vh;
|
padding: 20rpx;
|
display: flex;
|
flex-direction: column;
|
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
|
}
|
|
.calendar-card {
|
background-color: #fff;
|
margin-bottom: 20rpx;
|
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
|
}
|
|
.schedule-section {
|
flex: 1;
|
padding: 20rpx;
|
display: flex;
|
flex-direction: column;
|
|
.section-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20rpx;
|
|
.title {
|
font-size: 30rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
|
.add-btn {
|
margin: 0;
|
background-color: #2979ff;
|
}
|
}
|
}
|
|
.schedule-list {
|
flex: 1;
|
}
|
|
.schedule-card {
|
background-color: #fff;
|
border-radius: 12rpx;
|
padding: 24rpx;
|
margin-bottom: 20rpx;
|
display: flex;
|
justify-content: space-between;
|
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
|
|
.card-content {
|
flex: 1;
|
|
.project-info {
|
display: flex;
|
align-items: center;
|
margin-bottom: 12rpx;
|
gap: 8rpx;
|
|
.project-name {
|
font-size: 26rpx;
|
color: #2979ff;
|
font-weight: 500;
|
}
|
}
|
|
.content-text {
|
font-size: 28rpx;
|
color: #333;
|
display: block;
|
margin-bottom: 16rpx;
|
line-height: 1.4;
|
}
|
|
.time-info {
|
display: flex;
|
align-items: center;
|
gap: 8rpx;
|
|
.time-text {
|
font-size: 22rpx;
|
color: #999;
|
}
|
}
|
}
|
|
.card-actions {
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
gap: 20rpx;
|
padding-left: 20rpx;
|
border-left: 1rpx solid #f0f0f0;
|
margin-left: 20rpx;
|
|
.action-item {
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
font-size: 20rpx;
|
color: #666;
|
|
&.delete {
|
color: #f56c6c;
|
}
|
}
|
}
|
}
|
|
.empty-state {
|
text-align: center;
|
padding: 100rpx 0;
|
color: #999;
|
font-size: 28rpx;
|
}
|
|
.custom-popup-mask {
|
position: fixed;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background-color: rgba(0, 0, 0, 0.5);
|
z-index: 1000;
|
display: flex;
|
flex-direction: column;
|
justify-content: flex-end;
|
}
|
|
.custom-popup-content {
|
background-color: #fff;
|
border-radius: 24rpx 24rpx 0 0;
|
padding: 30rpx;
|
animation: slideUp 0.3s ease-out;
|
|
.popup-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 30rpx;
|
font-size: 32rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
}
|
|
@keyframes slideUp {
|
from { transform: translateY(100%); }
|
to { transform: translateY(0); }
|
}
|
|
.form-container {
|
.form-item {
|
margin-bottom: 30rpx;
|
|
.label {
|
display: block;
|
font-size: 28rpx;
|
color: #666;
|
margin-bottom: 12rpx;
|
|
.required {
|
color: #f56c6c;
|
margin-left: 4rpx;
|
}
|
}
|
|
.picker-view {
|
height: 80rpx;
|
line-height: 80rpx;
|
border: 1rpx solid #dcdfe6;
|
border-radius: 8rpx;
|
padding: 0 20rpx;
|
font-size: 28rpx;
|
color: #333;
|
background-color: #fff;
|
}
|
|
.custom-textarea {
|
width: 100%;
|
min-height: 160rpx;
|
border: 1rpx solid #dcdfe6;
|
border-radius: 8rpx;
|
padding: 20rpx;
|
font-size: 28rpx;
|
color: #333;
|
box-sizing: border-box;
|
}
|
|
::v-deep .uni-date-editor {
|
width: 100%;
|
.uni-date-x {
|
height: 80rpx;
|
border-color: #dcdfe6;
|
border-radius: 8rpx;
|
background-color: #fff;
|
}
|
.uni-date-x--border {
|
border-color: #dcdfe6;
|
}
|
.uni-date-input {
|
font-size: 28rpx;
|
color: #333;
|
}
|
}
|
}
|
}
|
|
.popup-footer {
|
margin-top: 40rpx;
|
padding-bottom: env(safe-area-inset-bottom);
|
.submit-btn {
|
width: 100%;
|
background-color: #2979ff;
|
height: 88rpx;
|
line-height: 88rpx;
|
border-radius: 44rpx;
|
font-size: 30rpx;
|
color: #fff;
|
}
|
}
|
</style>
|