442 lines
9.9 KiB
Vue
442 lines
9.9 KiB
Vue
<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>
|