Files
im-uniapp/pages/workbench/construction/construction.vue

442 lines
9.9 KiB
Vue
Raw Normal View History

2025-07-05 16:09:43 +08:00
<template>
2025-07-05 16:48:46 +08:00
<view class="container">
<!-- 操作说明 -->
<view class="operation-tip">
<u-icon name="info-circle" color="#007bff" size="16"></u-icon>
2025-07-08 13:45:04 +08:00
<text class="tip-text">点击对应的卡片可以查看详情</text>
</view>
<!-- 新增按钮 -->
<view class="add-button-container">
<u-button
type="primary"
2025-07-24 15:45:18 +08:00
@click="showAddForm"
2025-07-08 13:45:04 +08:00
:custom-style="{ borderRadius: '50rpx', height: '80rpx' }"
>
<u-icon name="plus" color="#fff" size="20" style="margin-right: 10rpx;"></u-icon>
新增汇报
</u-button>
2025-07-05 16:48:46 +08:00
</view>
<!-- 数据列表 -->
2025-07-08 13:45:04 +08:00
<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>
2025-07-05 16:48:46 +08:00
</view>
2025-07-08 13:45:04 +08:00
<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>
2025-07-05 16:48:46 +08:00
</view>
2025-07-08 13:45:04 +08:00
</view>
2025-07-05 16:48:46 +08:00
</view>
<!-- 分页 -->
<u-loadmore
v-if="total > 0"
:status="loadMoreStatus"
@loadmore="loadMore"
></u-loadmore>
2025-07-08 13:45:04 +08:00
<!-- 新增表单弹窗 -->
<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>
2025-07-05 16:09:43 +08:00
</view>
</template>
<script>
2025-07-05 16:48:46 +08:00
import { listProject } from '@/api/oa/project'
2025-07-08 13:45:04 +08:00
import { listReportSummary, addReportSummary } from '@/api/oa/reportSummary'
2025-07-05 16:48:46 +08:00
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
},
2025-07-08 13:45:04 +08:00
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']
}
}
2025-07-05 16:48:46 +08:00
}
},
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;
2025-07-08 13:45:04 +08:00
if (this.reportSummaryList.length <= this.total) {
this.loadMoreStatus = 'nomore';
}
2025-07-05 16:48:46 +08:00
}).catch(() => {
this.loading = false;
});
2025-07-05 16:09:43 +08:00
},
2025-07-05 16:48:46 +08:00
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);
2025-07-05 16:48:46 +08:00
uni.showToast({
title: '获取项目列表失败',
2025-07-05 16:48:46 +08:00
icon: 'none'
});
});
},
2025-07-05 16:48:46 +08:00
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;
2025-07-08 13:45:04 +08:00
},
// 日期选择变化处理
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();
}
},
2025-07-08 13:45:04 +08:00
// 提交表单
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);
});
}
2025-07-05 16:09:43 +08:00
}
2025-07-05 16:48:46 +08:00
}
2025-07-05 16:09:43 +08:00
</script>
<style lang="scss">
2025-07-05 16:48:46 +08:00
.container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
.operation-tip {
2025-07-05 16:48:46 +08:00
display: flex;
align-items: center;
gap: 10rpx;
padding: 20rpx;
background-color: #e3f2fd;
border-radius: 8rpx;
2025-07-05 16:48:46 +08:00
margin-bottom: 20rpx;
border-left: 4rpx solid #007bff;
.tip-text {
font-size: 28rpx;
color: #007bff;
font-weight: 500;
}
2025-07-05 16:48:46 +08:00
}
2025-07-08 13:45:04 +08:00
.add-button-container {
display: flex;
justify-content: center;
margin-bottom: 30rpx;
2025-07-05 16:48:46 +08:00
}
2025-07-08 13:45:04 +08:00
.masonry-list {
column-count: 2;
column-gap: 24rpx;
padding: 10rpx 0;
2025-07-05 16:48:46 +08:00
}
2025-07-05 16:09:43 +08:00
2025-07-08 13:45:04 +08:00
.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;
2025-07-05 16:48:46 +08:00
}
2025-07-08 13:45:04 +08:00
.card-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 16rpx;
color: #007bff;
}
.card-info {
display: flex;
flex-direction: column;
gap: 8rpx;
.info-row {
2025-07-05 16:48:46 +08:00
display: flex;
2025-07-08 13:45:04 +08:00
.label {
color: #888;
min-width: 120rpx;
2025-07-05 16:48:46 +08:00
}
}
}
}
.form-popup-content {
2025-07-05 16:48:46 +08:00
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
2025-07-05 16:48:46 +08:00
overflow: hidden;
width: 100%;
max-height: 80vh;
display: flex;
flex-direction: column;
2025-07-05 16:48:46 +08:00
.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;
2025-07-05 16:48:46 +08:00
}
.popup-footer {
display: flex;
gap: 20rpx;
padding: 30rpx;
border-top: 1rpx solid #e9ecef;
}
}
2025-07-05 16:09:43 +08:00
</style>