<template>
<view class="container">
<view v-if="loadstate">
<movable-area scale-area>
<movable-view direction="horizontal" scale scale-min="0.5" scale-max="2" animation="false"
:scale-value="scale">
<view class="meetingsummary">
<view class="table">
<view class="table-row">
<view class="table-cell label-cell left">会议时间</view>
<view class="table-cell value-cell">
<uni-datetime-picker class="time" type="date" v-model="item.time"
@change="updateMeet" clear-icon />
</view>
</view>
<view class="table-row">
<view class="table-cell label-cell left">会议地点及方式</view>
<view class="table-cell value-cell">
<uni-easyinput type="text" v-model="item.place" @blur="updateMeet" maxlength="-1"
:inputBorder="false" selectable="true" />
</view>
</view>
<view class="table-row">
<view class="table-cell label-cell left">会议组织及主持</view>
<view class="table-cell value-cell">
<uni-easyinput type="text" v-model="item.organize" @blur="updateMeet" maxlength="-1"
:inputBorder="false" selectable="true" />
</view>
</view>
<view class="table-row">
<view class="table-cell label-cell left">会议监督</view>
<view class="table-cell value-cell">
<uni-easyinput type="text" v-model="item.supervise" @blur="updateMeet"
maxlength="-1" :inputBorder="false" selectable="true" />
</view>
</view>
<view class="table-row">
<view class="table-cell label-cell left">会议记录</view>
<view class="table-cell value-cell">
<uni-easyinput type="text" v-model="item.record" @blur="updateMeet" maxlength="-1"
:inputBorder="false" />
</view>
</view>
<view class="table-row">
<view class="table-cell label-cell left">参会人员</view>
<view class="table-cell value-cell">
<uni-easyinput type="text" v-model="item.staff" @blur="updateMeet" maxlength="-1"
:inputBorder="false" selectable="true" />
</view>
</view>
<view class="table-row">
<view class="table-cell label-cell left">未参会人员</view>
<view class="table-cell value-cell">
<uni-easyinput type="text" v-model="item.outstaff" @blur="updateMeet" maxlength="-1"
:inputBorder="false" selectable="true" />
</view>
</view>
</view>
</view>
<view class="work-list">
<uni-table ref="table" border stripe emptyText="暂无更多数据">
<uni-tr>
<uni-th width="70" align="center">序号</uni-th>
<uni-th width="400" align="center">完成事项</uni-th>
<uni-th width="400" align="center">完成标准</uni-th>
<uni-th width="200" align="center">责任人</uni-th>
<uni-th width="200" align="center">完成时间</uni-th>
<uni-th width="200" align="center">进度情况</uni-th>
<uni-th width="200" align="center">完成情况</uni-th>
<uni-th width="100" align="center">延迟天数</uni-th>
<uni-th width="100" align="center">操作</uni-th>
</uni-tr>
<uni-tr v-for="(work, index) in works" :key="work._id" class="work-item">
<uni-td align="center">
<uni-easyinput :clearable="false" type="number" v-model="work.number" maxlength="-1"
:inputBorder="false" @blur="updateWork(work)" auto-height />
</uni-td>
<uni-td align="center">
<uni-easyinput type="textarea" v-model="work.task" maxlength="-1"
:inputBorder="false" @blur="updateWork(work)" auto-height></uni-easyinput>
</uni-td>
<uni-td align="center">
<uni-easyinput type="textarea" v-model="work.standard" maxlength="-1"
:inputBorder="false" @blur="updateWork(work)" auto-height></uni-easyinput>
</uni-td>
<uni-td align="center">
<uni-easyinput type="textarea" v-model="work.responsible" maxlength="-1"
:inputBorder="false" @blur="updateWork(work)" auto-height></uni-easyinput>
</uni-td>
<uni-td align="center">
<uni-datetime-picker type="date" :clear-icon="true" v-model="work.completetime"
@change="updateWork(work)" class="time"/>
</uni-td>
<uni-td align="center">
<uni-easyinput type="textarea" v-model="work.schedule" maxlength="-1"
:inputBorder="false" @blur="updateWork(work)" auto-height></uni-easyinput>
</uni-td>
<uni-td align="center">
<uni-easyinput type="textarea" v-model="work.completestatus" maxlength="-1"
:inputBorder="false" @blur="updateWork(work)" auto-height></uni-easyinput>
</uni-td>
<uni-td align="center">{{ work.delayDays }}</uni-td>
<uni-td align="center">
<button class="delete-button" type="warn" size="mini"
@click.stop="delwork(work._id)">删除</button>
</uni-td>
</uni-tr>
</uni-table>
<view class="add-button" style="margin-top: 20px">
<text class="iconfont icon-tianjia" style="font-size: 40px;color: black;"
@click="addNewWork()"></text>
<text class="iconfont icon-sync-copy"
style="font-size: 40px;color: black;margin-left: 20px;" @click="reload()"></text>
</view>
</view>
</movable-view>
</movable-area>
<view style="height: 200px;"></view>
</view>
<view v-else>
<uni-load-more status="loading"></uni-load-more>
</view>
</view>
</template>
<script>
const auth = uniCloud.getCurrentUserInfo();
let id;
const ch1 = uniCloud.importObject("fwzxch");
const chwork1 = uniCloud.importObject("fwzxchdetail");
export default {
data() {
return {
auth: '',
scale: 1,
loadstate: false,
item: {},
works: [],
showpopup: false,
allFwzxchworks: [],
work: {
number: '',
task: '',
standard: '',
responsible: '',
completetime: '',
schedule: '',
completestatus: '',
fwzxchid: '',
time: '',
delayDays: ''
},
};
},
onLoad(e) {
id = e.id;
this.getFwzxchAndwork()
.then(() => {
return this.updateDelayDaysAndSave(); // 确保延迟天数更新后再渲染
})
.then(() => {
// 数据更新完成后再进行渲染
this.loadstate = true; // 更新加载状态
})
.catch(err => {
console.error('Error loading data:', err);
});
},
// 配置分享
onShareAppMessage() {
return {
title: `${this.item.time} 服务中心晨会会议纪要`, // 使用 JavaScript 模板字符串来动态拼接标题
path: `/pages/fwzxchdetail/fwzxchdetail?id=${id}`, // 分享的页面路径
};
},
onPullDownRefresh() {
this.updateDelayDaysAndSave().then(() => {
return this.getFwzxchAndwork().then(() => {
uni.stopPullDownRefresh(); // 停止下拉刷新状态
console.log("下拉刷新完成");
}).catch(err => {
uni.stopPullDownRefresh(); // 停止刷新,即使出错
console.error(err);
});
});
},
methods: {
reload() {
this.getFwzxchAndwork()
},
getFwzxchAndwork() {
return Promise.all([
ch1.getfwzxchdetail(id, auth).then(res => {
this.item = res.data[0];
}),
chwork1.getfwzxchwork(id, auth).then(res => {
this.allFwzxchworks = res.data;
this.works = [...this.allFwzxchworks]; // 初始化数据
this.loadstate = true;
}),
]);
},
async addNewWork() {
const work = {
number: this.works.length + 1,
task: '',
standard: '',
responsible: '',
completetime: '',
schedule: '',
completestatus: '',
delayDays: 0,
fwzxchid: id, // 需要确保这个字段是有效的
time: this.item.time, // 如果时间是必要的,也确保它是有效的
};
try {
const res = await chwork1.addfwzxchwork(work, auth);
if (res.code === 1) {
uni.showToast({
title: '权限不足',
icon: 'error',
duration: 1000
});
} else if (res.code === 0) {
uni.showToast({
title: '新增成功',
icon: 'success',
duration: 1000
});
work._id = res.data.id;
this.works.push(work);
} else {
uni.showToast({
title: '操作失败,请稍后重试',
icon: 'none'
});
}
} catch (err) {
console.error("新增失败", err);
}
},
async updateWork(work) {
if (!work._id) {
console.error("更新失败,缺少 _id");
return;
}
try {
work.number = Number(work.number);
const result = await chwork1.updatefwzxchwork(work, auth)
if (result.code === 1) {
uni.showToast({
title: '权限不足',
icon: 'error',
duration: 1000
});
} else if (result.code === 0) {
uni.showToast({
title: '修改成功',
icon: 'success',
duration: 1000
});
} else {
uni.showToast({
title: '操作失败,请稍后重试',
icon: 'none'
});
}
} catch (err) {
console.error(err);
uni.showToast({
title: '操作失败,请稍后重试',
icon: 'none'
});
}
},
delwork(id) {
uni.showModal({
title: '确认删除',
content: '确定要删除此项吗?',
success: async (res) => {
if (res.confirm) {
try {
const result = await chwork1.delfwzxchwork(id, auth);
if (result.code === 1) {
uni.showToast({
title: '权限不足',
icon: 'error',
duration: 1000
});
} else if (result.code === 0) {
uni.showToast({
title: '删除成功',
icon: 'success',
duration: 1000
});
await this.getFwzxchAndwork(); // 确保数据加载完成
} else {
uni.showToast({
title: '操作失败,请稍后重试',
icon: 'none'
});
}
} catch (err) {
console.error('Error deleting data:', err);
}
} else if (res.cancel) {
uni.showToast({
title: '取消删除',
icon: 'error',
duration: 1000 // 提示框显示的时长,单位为毫秒,可根据需要调整
});
}
}
});
},
updateDelayDaysAndSave() {
const db = uniCloud.database();
const collection = db.collection('fwzxchwork');
const currentDate = new Date();
return Promise.all(this.works.map((work) => {
if (!work._id) {
console.error("工作项缺少 _id:", work);
return Promise.resolve(); // 如果没有 _id,跳过此项
}
const completeTimeDate = new Date(work.completetime);
const completeTimeDateStart = new Date(completeTimeDate);
completeTimeDateStart.setHours(0, 0, 0, 0); // 设置完成时间的开始时刻
const completeTimeDateEnd = new Date(completeTimeDate);
completeTimeDateEnd.setHours(18, 0, 0, 0); // 设置完成时间的结束时刻
let delayDays = 0;
if (currentDate < completeTimeDateStart) {
delayDays = 0; // 如果当前时间在完成时间之前,则没有延迟
} else if (currentDate >= completeTimeDateStart && currentDate <= completeTimeDateEnd) {
// 如果当前时间在完成时间的当天,并且在 18:00 之前
if (work.schedule && work.completestatus) {
delayDays = 0; // 如果有进度和完成情况,则没有延迟
}
} else if (currentDate > completeTimeDateEnd) {
// 如果当前时间超过了完成时间的 18:00
if (work.schedule && work.completestatus) {
delayDays = work.delayDays || 0; // 如果有进度和完成情况,保留当前延迟天数
} else {
// 否则,计算延迟天数
const timeDiff = currentDate.getTime() - completeTimeDateEnd.getTime();
delayDays = Math.ceil(timeDiff / (1000 * 3600 * 24)); // 向上取整以确保是完整的天数
}
}
console.log("延迟天数:", delayDays);
// 更新数据库中的延迟天数
return collection.doc(work._id).update({
delayDays: delayDays,
}).then(() => {
// 更新本地数据
this.$set(work, 'delayDays', delayDays); // 确保 Vue 响应式更新
}).catch((err) => {
console.error("更新延迟天数失败:", err);
});
}));
},
async updateMeet() {
const result = await ch1.updatefwzxch(this.item, auth);
if (result.code === 1) {
uni.showToast({
title: '权限不足',
icon: 'error',
duration: 1000
});
} else if (result.code === 0) {
uni.showToast({
title: '更新成功',
icon: 'success',
duration: 1000
});
this.works.forEach(async (work) => {
// 如果工作项的时间不同于当前 item.time,则更新
if (work.time !== this.item.time) {
work.time = this.item.time; // 更新本地数据
// 更新数据库中的时间
try {
const updateResult = await chwork1.updatefwzxchwork(work,auth);
if (updateResult.code === 1) {
uni.showToast({
title: '权限不足',
icon: 'error',
duration: 1000
});
} else if (updateResult.code === 0) {
uni.showToast({
title: '更新成功',
icon: 'success',
duration: 1000
});
} else {
uni.showToast({
title: '更新失败,请稍后重试',
icon: 'none'
});
}
} catch (err) {
console.error('更新失败:', err);
uni.showToast({
title: '更新失败,请稍后重试',
icon: 'none'
});
}
}
});
} else {
uni.showToast({
title: '操作失败,请稍后重试',
icon: 'none'
});
}
},
}
}
</script>
<style scoped>
.container {
margin-top: 20px;
padding-left: 20px;
padding-right: 20px;
}
.work-list {
margin-top: 20px;
}
/* 表格宽度自适应内容 */
.table {
display: table;
width: auto;
/* 使表格宽度自适应内容 */
table-layout: auto;
/* 自动根据内容调整列宽 */
border-collapse: collapse;
/* 去除单元格间的空隙 */
}
/* 表格的每一行 */
.table-row {
display: table-row;
width: 100%;
border-bottom: 1px solid black;
}
/* 每一列的单元格 */
.table-cell {
font-size: 18px;
display: table-cell;
padding: 10px;
/* 为单元格添加内边距 */
border: 1px solid black;
/* 给每个单元格加边框 */
word-wrap: break-word;
/* 自动换行,防止文本溢出 */
white-space: nowrap;
/* 禁止换行,保证长文本不会折行 */
min-width: 120px;
/* 防止列宽过窄 */
box-sizing: border-box;
/* 包含内边距在内 */
vertical-align: middle;
/* 垂直居中对齐 */
}
/* 标签列的宽度(固定) */
.label-cell {
width: 120px;
/* 设置标签列的固定宽度 */
text-align: center;
border: 1px solid black;
}
.left {
color: black;
}
/* 内容列的宽度(自适应) */
.value-cell {
border: 1px solid black;
width: auto;
/* 内容列宽度自适应 */
text-align: left;
/* max-width: 400px; */
/* 如果内容过长,可以限制最大宽度,防止过度拉伸 */
word-wrap: break-word;
/* 确保文本内容不会超出单元格 */
}
/* 响应式优化:小屏幕设备下,调整表格布局 */
@media (max-width: 600px) {
.table {
width: 1200px;
/* 设置一个固定宽度,避免超出屏幕 */
}
.label-cell,
.value-cell {
padding: 8px;
/* 减小内边距以适应小屏 */
}
.value-cell {
min-width: 150px;
}
/* 小屏幕下的表格标题文字居中 */
.table-cell {
/* text-align: center; */
}
.left {
text-align: center;
}
}
@media (min-width: 600px) {
.table {
width: 100%;
/* 设置一个固定宽度,避免超出屏幕 */
min-width: 0;
/* 移除固定的最小宽度 */
/* 设置表格的最大宽度为屏幕宽度,避免超出 */
max-width: 100%;
}
.label-cell,
.value-cell {
padding: 8px;
/* 减小内边距以适应小屏 */
}
.value-cell {
min-width: 150px;
/* 设置最小宽度,以避免内容被压缩 */
}
/* 小屏幕下的表格标题文字居中 */
.table-cell {
/* text-align: center; */
}
.left {
text-align: center;
}
}
/* 表格组件样式 */
.uni-table {
width: 100%;
table-layout: fixed;
/* 使表格宽度固定 */
border-collapse: collapse;
/* 去除单元格间的空隙 */
border: 1px solid black;
}
/* textarea 样式 */
/* textarea {
width: 100%;
min-height: 40px;
font-size: 16px;
resize: none;
padding: 5px;
border: none;
white-space: pre-wrap;
word-wrap: break-word;
outline: none;
box-sizing: border-box;
} */
/* flex布局,确保每行内容竖直居中 */
.uni-table-tr {
display: flex;
align-items: center;
/* 确保每行内容竖直居中 */
justify-content: space-between;
/* 保证每个单元格均匀分布 */
width: 100%;
}
/* 强制表格单元格垂直对齐 */
::v-deep .uni-table-td {
height: 100% !important;
vertical-align: middle !important;
}
.uni-table-td {
padding: 5px 5px 0 5px !important;
border: 1px solid black !important;
}
.uni-easyinput__content-textarea {
font-size: 18px !important;
line-height: 1.5 !important;
text-align: left !important;
}
.uni-easyinput__content-input {
font-size: 18px !important;
}
movable-view {
height: 100vh;
width: auto;
}
movable-area {
height: 3000px;
width: auto;
overflow: hidden;
}
</style>