Files
im-uniapp/pages/workbench/construction/construction.vue
2025-07-24 15:45:18 +08:00

442 lines
9.9 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<!-- 操作说明 -->
<view class="operation-tip">
<u-icon name="info-circle" color="#007bff" size="16"></u-icon>
<text class="tip-text">点击对应的卡片可以查看详情</text>
</view>
<!-- 新增按钮 -->
<view class="add-button-container">
<u-button
type="primary"
@click="showAddForm"
:custom-style="{ borderRadius: '50rpx', height: '80rpx' }"
>
<u-icon name="plus" color="#fff" size="20" style="margin-right: 10rpx;"></u-icon>
新增汇报
</u-button>
</view>
<!-- 数据列表 -->
<view class="masonry-list">
<view
v-for="(item, index) in reportSummaryList"
:key="item.summaryId"
class="masonry-card"
@click="handleRowClick(item)"
>
<view class="card-title">{{ item.reportTitle || '-' }}</view>
<view class="card-info">
<view class="info-row">
<text class="label">最近汇报时间</text>
<text>{{ formatDate(item.lastUpdateTime) }}</text>
</view>
<view class="info-row">
<text class="label">汇报日期</text>
<text>{{ formatDate(item.reportDate) }}</text>
</view>
<view class="info-row">
<text class="label">汇报人</text>
<text>{{ item.reporter || '-' }}</text>
</view>
<view class="info-row">
<text class="label">涉及项目</text>
<text>{{ item.projectName || '-' }}</text>
</view>
<view class="info-row">
<text class="label">备注</text>
<text>{{ item.remark || '-' }}</text>
</view>
</view>
</view>
</view>
<!-- 分页 -->
<u-loadmore
v-if="total > 0"
:status="loadMoreStatus"
@loadmore="loadMore"
></u-loadmore>
<!-- 新增表单弹窗 -->
<uni-popup ref="formPopup" type="bottom" :mask-click="false">
<view class="form-popup-content">
<view class="popup-header">
<text class="popup-title">新增汇报</text>
<u-icon name="close" size="20" @click="closeForm"></u-icon>
</view>
<view class="form-content">
<u-form :model="form" ref="uForm" :rules="rules">
<u-form-item label="汇报标题" prop="reportTitle">
<u-input
v-model="form.reportTitle"
placeholder="请输入汇报标题"
:border="true"
/>
</u-form-item>
<u-form-item label="汇报日期" prop="reportDate">
<uni-datetime-picker
v-model="form.reportDate"
type="datetime"
:clear-icon="true"
placeholder="请选择汇报日期"
@change="onDateChange"
/>
</u-form-item>
<u-form-item label="汇报人" prop="reporter">
<u-input
v-model="form.reporter"
placeholder="请输入汇报人"
:border="true"
/>
</u-form-item>
<u-form-item label="涉及项目" prop="projectId">
<uni-data-select
v-model="form.projectId"
:localdata="projectList"
placeholder="请选择涉及项目"
@change="handleProjectChange"
/>
</u-form-item>
<u-form-item label="备注" prop="remark">
<u-textarea
v-model="form.remark"
placeholder="请输入内容"
:height="120"
:border="true"
/>
</u-form-item>
</u-form>
</view>
<view class="popup-footer">
<u-button @click="closeForm" :custom-style="{ flex: 1 }">取消</u-button>
<u-button type="primary" @click="submitForm" :custom-style="{ flex: 1 }">确定</u-button>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
import { listProject } from '@/api/oa/project'
import { listReportSummary, addReportSummary } from '@/api/oa/reportSummary'
export default {
data() {
return {
projectList: [],
loading: true,
total: 0,
reportSummaryList: [],
queryParams: {
pageNum: 1,
pageSize: 10,
reportTitle: undefined,
reportDate: undefined,
reporter: undefined,
projectId: undefined,
type: 1
},
loadMoreStatus: 'loadmore',
// 表单数据
form: {
reportTitle: '',
reportDate: '',
reporter: '',
projectId: '',
remark: '',
type: 1
},
// 表单验证规则
rules: {
reportTitle: {
type: 'string',
required: true,
message: '请输入汇报标题',
trigger: ['blur', 'change']
},
reportDate: {
type: 'string',
required: true,
message: '请选择汇报日期',
trigger: ['blur', 'change']
},
reporter: {
type: 'string',
required: true,
message: '请输入汇报人',
trigger: ['blur', 'change']
},
projectId: {
type: 'string',
required: true,
message: '请选择涉及项目',
trigger: ['blur', 'change']
}
}
}
},
onLoad() {
this.getList();
this.getProjectList();
},
methods: {
getList() {
this.loading = true;
listReportSummary(this.queryParams).then(response => {
this.reportSummaryList = response.rows || [];
this.total = response.total || 0;
this.loading = false;
this.selectedIds = [];
this.selectAll = false;
if (this.reportSummaryList.length <= this.total) {
this.loadMoreStatus = 'nomore';
}
}).catch(() => {
this.loading = false;
});
},
getProjectList() {
listProject({ pageNum: 1, pageSize: 9999 }).then(res => {
const rawData = res.rows || [];
// 按照 uni-data-select 的标准格式处理数据
this.projectList = rawData.map(item => ({
value: item.projectId,
text: item.projectName,
// 保留原始数据用于提交
projectId: item.projectId,
projectName: item.projectName,
projectNum: item.projectNum,
projectCode: item.projectCode
}));
}).catch(err => {
console.error('获取项目列表失败:', err);
uni.showToast({
title: '获取项目列表失败',
icon: 'none'
});
});
},
formatDate(date) {
if (!date) return '-';
const d = new Date(date);
return `${d.getFullYear()}-${(d.getMonth()+1).toString().padStart(2,'0')}-${d.getDate().toString().padStart(2,'0')}`;
},
loadMore() {
if (this.loadMoreStatus === 'nomore') return;
this.loadMoreStatus = 'loading';
this.queryParams.pageNum += 1;
listReportSummary(this.queryParams).then(response => {
const newData = response.rows || [];
this.reportSummaryList = [...this.reportSummaryList, ...newData];
this.total = response.total || 0;
if (newData.length < this.queryParams.pageSize) {
this.loadMoreStatus = 'nomore';
} else {
this.loadMoreStatus = 'loadmore';
}
}).catch(() => {
this.loadMoreStatus = 'loadmore';
this.queryParams.pageNum -= 1;
});
},
// 点击行跳转到详情页
handleRowClick(item) {
uni.navigateTo({
url: `/pages/workbench/construction/detail?summaryId=${item.summaryId}&reportTitle=${encodeURIComponent(item.reportTitle || '')}&reporter=${encodeURIComponent(item.reporter || '')}&projectName=${encodeURIComponent(item.projectName || '')}`
});
},
// 项目选择变化处理
handleProjectChange(value) {
this.form.projectId = value;
},
// 日期选择变化处理
onDateChange(value) {
this.form.reportDate = value;
},
// 显示新增表单
showAddForm() {
this.resetForm();
this.$refs.formPopup.open();
},
// 关闭表单
closeForm() {
this.$refs.formPopup.close();
this.resetForm();
},
// 重置表单
resetForm() {
this.form = {
reportTitle: '',
reportDate: '',
reporter: '',
projectId: '',
remark: '',
type: 1
};
// 清除验证状态
if (this.$refs.uForm) {
this.$refs.uForm.clearValidate();
}
},
// 提交表单
submitForm() {
this.$refs.uForm.validate().then(valid => {
if (valid) {
this.submitData();
}
}).catch(errors => {
console.log('表单验证失败:', errors);
});
},
// 提交数据
submitData() {
uni.showLoading({
title: '提交中...'
});
addReportSummary(this.form).then(response => {
uni.hideLoading();
uni.showToast({
title: '添加成功',
icon: 'success'
});
this.closeForm();
// 刷新列表
this.queryParams.pageNum = 1;
this.getList();
}).catch(error => {
uni.hideLoading();
uni.showToast({
title: '添加失败',
icon: 'none'
});
console.error('添加汇报失败:', error);
});
}
}
}
</script>
<style lang="scss">
.container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
.operation-tip {
display: flex;
align-items: center;
gap: 10rpx;
padding: 20rpx;
background-color: #e3f2fd;
border-radius: 8rpx;
margin-bottom: 20rpx;
border-left: 4rpx solid #007bff;
.tip-text {
font-size: 28rpx;
color: #007bff;
font-weight: 500;
}
}
.add-button-container {
display: flex;
justify-content: center;
margin-bottom: 30rpx;
}
.masonry-list {
column-count: 2;
column-gap: 24rpx;
padding: 10rpx 0;
}
.masonry-card {
width: calc(100%% - 18rpx);
margin-bottom: 24rpx;
background: #fff;
border-radius: 16rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.06);
display: inline-block;
break-inside: avoid;
padding: 32rpx 24rpx;
cursor: pointer;
transition: box-shadow 0.2s;
&:active {
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.10);
background: #f8f9fa;
}
.card-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 16rpx;
color: #007bff;
}
.card-info {
display: flex;
flex-direction: column;
gap: 8rpx;
.info-row {
display: flex;
.label {
color: #888;
min-width: 120rpx;
}
}
}
}
.form-popup-content {
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
overflow: hidden;
width: 100%;
max-height: 80vh;
display: flex;
flex-direction: column;
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #e9ecef;
.popup-title {
font-size: 32rpx;
font-weight: bold;
}
}
.form-content {
padding: 30rpx;
flex: 1;
overflow-y: auto;
}
.popup-footer {
display: flex;
gap: 20rpx;
padding: 30rpx;
border-top: 1rpx solid #e9ecef;
}
}
</style>