446 lines
11 KiB
Vue
446 lines
11 KiB
Vue
|
|
<template>
|
|||
|
|
<view class="project-page">
|
|||
|
|
<!-- 新增按钮 -->
|
|||
|
|
<view class="add-btn-row">
|
|||
|
|
<u-search placeholder="根据项目名称搜索" v-model="queryParams.projectName" class="search-input" :show-action="false"
|
|||
|
|
@search="handleSearch" />
|
|||
|
|
<view class="button-group">
|
|||
|
|
</input>
|
|||
|
|
<uni-icons type="gift" size="30" @click="toggleQualityFilter" :color="qualityFilter ? '#ffcc00' : '#333'" />
|
|||
|
|
<uni-icons type="search" size="30" @click="openSettingsPopup" color="#333"></uni-icons>
|
|||
|
|
<uni-icons
|
|||
|
|
type="plus"
|
|||
|
|
size="30"
|
|||
|
|
@click="handleAdd"
|
|||
|
|
color="#333"
|
|||
|
|
/>
|
|||
|
|
<uni-drawer ref="filterDrawer" mode="right" :width="300">
|
|||
|
|
<view class="popup-content">
|
|||
|
|
<view class="filter-title">更多筛选条件</view>
|
|||
|
|
<view class="filter-item">
|
|||
|
|
<text class="filter-label">项目类型</text>
|
|||
|
|
<oa-dict-select v-model="queryParams.projectType" dict-type="sys_project_type" placeholder="请选择项目类型"
|
|||
|
|
@change="handleQuery" clearable />
|
|||
|
|
</view>
|
|||
|
|
<view class="filter-item">
|
|||
|
|
<text class="filter-label">贸易类型</text>
|
|||
|
|
<oa-dict-select v-model="queryParams.tradeType" dict-type="sys_trade_type" placeholder="请选择贸易类型"
|
|||
|
|
@change="handleQuery" clearable />
|
|||
|
|
</view>
|
|||
|
|
<view class="filter-item">
|
|||
|
|
<text class="filter-label">项目代号</text>
|
|||
|
|
<oa-dict-select v-model="queryParams.projectCode" dict-type="sys_project_code" placeholder="请选择代号类型"
|
|||
|
|
@change="handleQuery" clearable filterable />
|
|||
|
|
</view>
|
|||
|
|
<view class="filter-item">
|
|||
|
|
<text class="filter-label">日期范围</text>
|
|||
|
|
<uni-datetime-picker v-model="searchTime" type="daterange" rangeSeparator="至" start-placeholder="开始日期"
|
|||
|
|
end-placeholder="结束日期" @change="handleQuery" />
|
|||
|
|
</view>
|
|||
|
|
<view class="filter-actions">
|
|||
|
|
<button class="primary" @click="handleQuery">查询</button>
|
|||
|
|
<button @click="resetQuery">重置</button>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</uni-drawer>
|
|||
|
|
<!-- <uni-icons type="plus" size="30" @click="handleAdd" color="#333" /> -->
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 项目列表 -->
|
|||
|
|
<scroll-view scroll-y @scrolltolower="loadMore" :style="{ height: scrollHeight + 'px' }">
|
|||
|
|
<view class="project-grid">
|
|||
|
|
<view class="project-card" v-for="item in projectList" @click="handleDetail(item)">
|
|||
|
|
<view class="project-title">
|
|||
|
|
{{ item.projectName }}
|
|||
|
|
<uni-tag v-if="item.projectStatus == 1" size="mini" type="success" text="进度完成"></uni-tag>
|
|||
|
|
<uni-tag v-else-if="item.projectStatus == 0" size="mini" type="warning" text="进行中"></uni-tag>
|
|||
|
|
</view>
|
|||
|
|
<view class="project-info">
|
|||
|
|
<text>{{ item.functionary }}</text>
|
|||
|
|
<!-- <text :style="getRemainTimeStyle(item.remainTime)" v-if="item.projectStatus == 0">
|
|||
|
|
剩余时间:{{ item.remainTime }}天
|
|||
|
|
</text> -->
|
|||
|
|
<text>{{ item.projectNum }}元</text>
|
|||
|
|
<text>项目总金额:{{ item.funds }}元</text>
|
|||
|
|
<text v-if="item.prePay > 0" style="color: #ffcc00;">预付款:{{ item.prePay }}元</text>
|
|||
|
|
<view
|
|||
|
|
style="display: flex; justify-content: flex-start; gap: 10rpx; position: absolute; bottom: 20rpx; margin-top: 10rpx;">
|
|||
|
|
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<!-- 加载更多组件 -->
|
|||
|
|
<uni-load-more :status="loadMoreStatus"></uni-load-more>
|
|||
|
|
</scroll-view>
|
|||
|
|
</view>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
import {
|
|||
|
|
listProject,
|
|||
|
|
addProject,
|
|||
|
|
updateProject,
|
|||
|
|
delProject,
|
|||
|
|
getProject
|
|||
|
|
} from '@/api/oa/project.js'
|
|||
|
|
export default {
|
|||
|
|
data() {
|
|||
|
|
return {
|
|||
|
|
projectList: [],
|
|||
|
|
form: {},
|
|||
|
|
editType: '', // add/edit
|
|||
|
|
page: 1, // 当前页码
|
|||
|
|
pageSize: 10, // 每页项目数量
|
|||
|
|
selectedProject: {}, // 选中的项目
|
|||
|
|
loadMoreStatus: 'more', // 加载更多状态
|
|||
|
|
scrollHeight: 0, // 滚动区域高度
|
|||
|
|
qualityFilter: false, // 优质筛选开关
|
|||
|
|
searchTime: [], // 日期范围
|
|||
|
|
queryParams: {
|
|||
|
|
projectName: '',
|
|||
|
|
projectType: '',
|
|||
|
|
tradeType: '',
|
|||
|
|
projectCode: '',
|
|||
|
|
projectStatus: ''
|
|||
|
|
},
|
|||
|
|
dict: {
|
|||
|
|
type: {
|
|||
|
|
sys_project_type: [],
|
|||
|
|
sys_trade_type: [],
|
|||
|
|
sys_project_code: [],
|
|||
|
|
sys_project_status: []
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
onShow() {
|
|||
|
|
this.getList();
|
|||
|
|
this.calculateScrollHeight();
|
|||
|
|
// TODO: 这里应请求字典数据填充dict.type
|
|||
|
|
},
|
|||
|
|
methods: {
|
|||
|
|
getStatusLabel(val) {
|
|||
|
|
const arr = this.dict.type.sys_project_status;
|
|||
|
|
const found = arr.find(i => i.value === val);
|
|||
|
|
return found ? found.label : '';
|
|||
|
|
},
|
|||
|
|
openSettingsPopup() {
|
|||
|
|
this.$nextTick(() => {
|
|||
|
|
if (this.$refs.filterDrawer) this.$refs.filterDrawer.open();
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
handleSearch() {
|
|||
|
|
this.page = 1;
|
|||
|
|
this.projectList = [];
|
|||
|
|
this.getList();
|
|||
|
|
},
|
|||
|
|
handleQuery() {
|
|||
|
|
this.page = 1;
|
|||
|
|
this.projectList = [];
|
|||
|
|
if (this.$refs.filterDrawer) this.$refs.filterDrawer.close();
|
|||
|
|
// 日期范围处理
|
|||
|
|
if (this.searchTime && this.searchTime.length === 2) {
|
|||
|
|
this.queryParams.beginDate = this.searchTime[0];
|
|||
|
|
this.queryParams.endDate = this.searchTime[1];
|
|||
|
|
} else {
|
|||
|
|
this.queryParams.beginDate = '';
|
|||
|
|
this.queryParams.endDate = '';
|
|||
|
|
}
|
|||
|
|
this.getList();
|
|||
|
|
},
|
|||
|
|
resetQuery() {
|
|||
|
|
this.queryParams = {
|
|||
|
|
projectName: '',
|
|||
|
|
projectType: '',
|
|||
|
|
tradeType: '',
|
|||
|
|
projectCode: '',
|
|||
|
|
projectStatus: ''
|
|||
|
|
};
|
|||
|
|
this.searchTime = [];
|
|||
|
|
this.handleQuery();
|
|||
|
|
},
|
|||
|
|
filterCode(val) {
|
|||
|
|
// 可根据需要自定义筛选逻辑
|
|||
|
|
return true;
|
|||
|
|
},
|
|||
|
|
calculateScrollHeight() {
|
|||
|
|
const systemInfo = uni.getSystemInfoSync();
|
|||
|
|
const tabHeight = 75; // tab高度
|
|||
|
|
const containerPadding = 40; // 容器padding
|
|||
|
|
this.scrollHeight = systemInfo.windowHeight - tabHeight - containerPadding + 80;
|
|||
|
|
},
|
|||
|
|
getList() {
|
|||
|
|
const params = {
|
|||
|
|
pageNum: this.page,
|
|||
|
|
pageSize: this.pageSize,
|
|||
|
|
...this.queryParams
|
|||
|
|
};
|
|||
|
|
if (this.qualityFilter) {
|
|||
|
|
params.prePay = 0.1; // 添加优质筛选参数
|
|||
|
|
}
|
|||
|
|
listProject(params).then(res => {
|
|||
|
|
const newProjects = (res.rows || []).map(row => ({
|
|||
|
|
...row,
|
|||
|
|
projectTypeLabel: row.projectType,
|
|||
|
|
projectStatusLabel: row.projectStatus,
|
|||
|
|
}));
|
|||
|
|
this.projectList = [...this.projectList, ...newProjects];
|
|||
|
|
|
|||
|
|
if (newProjects.length < this.pageSize) {
|
|||
|
|
this.loadMoreStatus = 'noMore'; // 没有更多数据
|
|||
|
|
} else {
|
|||
|
|
this.loadMoreStatus = 'more'; // 还有更多数据
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
loadMore() {
|
|||
|
|
if (this.loadMoreStatus === 'more') {
|
|||
|
|
console.log('加载更多');
|
|||
|
|
this.page++;
|
|||
|
|
this.getList();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
handleAdd() {
|
|||
|
|
uni.navigateTo({
|
|||
|
|
url: '/pages/workbench/profit/cost?id=' + '0'
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
handleDetail(item) {
|
|||
|
|
uni.navigateTo({
|
|||
|
|
url: '/pages/workbench/profit/cost?id=' + item.projectId
|
|||
|
|
})
|
|||
|
|
},
|
|||
|
|
toggleQualityFilter() {
|
|||
|
|
this.qualityFilter = !this.qualityFilter; // 切换优质筛选状态
|
|||
|
|
this.page = 1; // 重置页码
|
|||
|
|
this.projectList = []; // 清空当前项目列表
|
|||
|
|
this.getList(); // 重新获取项目列表
|
|||
|
|
},
|
|||
|
|
openEditPopup(item) {
|
|||
|
|
this.editType = 'edit';
|
|||
|
|
getProject(item.projectId).then(res => {
|
|||
|
|
this.form = {
|
|||
|
|
...res.data
|
|||
|
|
};
|
|||
|
|
this.$refs.editPopup.open();
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
closePopup() {
|
|||
|
|
this.$refs.editPopup.close();
|
|||
|
|
},
|
|||
|
|
submitForm() {
|
|||
|
|
if (this.editType === 'add') {
|
|||
|
|
addProject(this.form).then(() => {
|
|||
|
|
this.getList();
|
|||
|
|
this.closePopup();
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
updateProject(this.form).then(() => {
|
|||
|
|
this.getList();
|
|||
|
|
this.closePopup();
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
handleClosure(item) {
|
|||
|
|
const update = {
|
|||
|
|
...item,
|
|||
|
|
projectStatus: '1'
|
|||
|
|
};
|
|||
|
|
updateProject(update).then(() => {
|
|||
|
|
this.getList();
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
handleDelete(item) {
|
|||
|
|
delProject(item.projectId).then(() => {
|
|||
|
|
this.getList();
|
|||
|
|
});
|
|||
|
|
},
|
|||
|
|
openDetailPopup(item) {
|
|||
|
|
this.selectedProject = item;
|
|||
|
|
this.$refs.detailPopup.open();
|
|||
|
|
},
|
|||
|
|
closeDetailPopup() {
|
|||
|
|
this.$refs.detailPopup.close();
|
|||
|
|
},
|
|||
|
|
getRemainTimeStyle(remainTime) {
|
|||
|
|
if (remainTime > 10) {
|
|||
|
|
return {
|
|||
|
|
color: '#3c763d'
|
|||
|
|
}; // 绿色
|
|||
|
|
} else if (remainTime > 5) {
|
|||
|
|
return {
|
|||
|
|
color: '#8a6d3b'
|
|||
|
|
}; // 黄色
|
|||
|
|
} else {
|
|||
|
|
return {
|
|||
|
|
color: '#a94442'
|
|||
|
|
}; // 红色
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped>
|
|||
|
|
.add-btn-row {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: flex-end;
|
|||
|
|
/* 右对齐 */
|
|||
|
|
align-items: center;
|
|||
|
|
margin: 20rpx;
|
|||
|
|
gap: 10rpx;
|
|||
|
|
/* 按钮之间的间距 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.button-group {
|
|||
|
|
display: flex;
|
|||
|
|
gap: 10px;
|
|||
|
|
/* 按钮之间的间距 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.popup-content {
|
|||
|
|
background-color: #fff;
|
|||
|
|
/* 设置纯白背景 */
|
|||
|
|
padding: 24px 18px 18px 18px;
|
|||
|
|
/* 上右下左内边距 */
|
|||
|
|
border-radius: 14px;
|
|||
|
|
/* 圆角 */
|
|||
|
|
min-height: 100vh;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.filter-title {
|
|||
|
|
font-size: 20px;
|
|||
|
|
font-weight: bold;
|
|||
|
|
color: #333;
|
|||
|
|
margin-bottom: 18px;
|
|||
|
|
text-align: left;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.filter-item {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
margin-bottom: 18px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.filter-label {
|
|||
|
|
min-width: 80px;
|
|||
|
|
font-size: 16px;
|
|||
|
|
color: #666;
|
|||
|
|
margin-right: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.filter-item oa-dict-select,
|
|||
|
|
.filter-item picker,
|
|||
|
|
.filter-item uni-datetime-picker {
|
|||
|
|
flex: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.filter-item .uni-input {
|
|||
|
|
background: #f7f7f7;
|
|||
|
|
border-radius: 6px;
|
|||
|
|
padding: 8px 12px;
|
|||
|
|
font-size: 15px;
|
|||
|
|
color: #333;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.filter-actions {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: center;
|
|||
|
|
gap: 18px;
|
|||
|
|
margin-top: 10px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.filter-actions button {
|
|||
|
|
min-width: 90px;
|
|||
|
|
padding: 8px 0;
|
|||
|
|
border-radius: 6px;
|
|||
|
|
font-size: 16px;
|
|||
|
|
background: #2979ff;
|
|||
|
|
color: #fff;
|
|||
|
|
border: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.filter-actions button:not(.primary) {
|
|||
|
|
background: #f5f5f5;
|
|||
|
|
color: #333;
|
|||
|
|
border: 1px solid #e0e0e0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.close-button {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: flex-end;
|
|||
|
|
/* 右对齐 */
|
|||
|
|
margin-bottom: 10px;
|
|||
|
|
/* 底部间距 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.project-grid {
|
|||
|
|
display: flex;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.project-card {
|
|||
|
|
border: 1px solid #ccc;
|
|||
|
|
/* 边框 */
|
|||
|
|
border-radius: 10px;
|
|||
|
|
/* 圆角 */
|
|||
|
|
background-color: #fff;
|
|||
|
|
/* 背景色 */
|
|||
|
|
margin: 10px;
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
width: calc(50% - 20px);
|
|||
|
|
/* 每行两个卡片 */
|
|||
|
|
padding: 20px 15px;
|
|||
|
|
/* 添加内边距 */
|
|||
|
|
position: relative;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.project-title {
|
|||
|
|
font-size: 20px;
|
|||
|
|
/* 项目名称字号 */
|
|||
|
|
font-weight: bold;
|
|||
|
|
/* 加粗 */
|
|||
|
|
color: #333;
|
|||
|
|
/* 主字体颜色 */
|
|||
|
|
margin-bottom: 5px;
|
|||
|
|
/* 下边距 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.project-info text {
|
|||
|
|
display: block;
|
|||
|
|
/* 每个信息占一行 */
|
|||
|
|
margin-top: 5px;
|
|||
|
|
/* 上边距 */
|
|||
|
|
color: #666;
|
|||
|
|
/* 较淡的字体颜色 */
|
|||
|
|
font-size: 16px;
|
|||
|
|
/* 信息字号 */
|
|||
|
|
line-height: 1.5;
|
|||
|
|
/* 行间距 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.project-info {
|
|||
|
|
margin-top: 10px;
|
|||
|
|
/* 项目信息与标题之间的间距 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 新增的样式 */
|
|||
|
|
.horizontal-actions {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
/* 在一行内均匀分布 */
|
|||
|
|
margin-top: 10px;
|
|||
|
|
/* 添加顶部间距 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.horizontal-actions button {
|
|||
|
|
flex: 1;
|
|||
|
|
/* 按钮均分宽度 */
|
|||
|
|
margin: 0 5px;
|
|||
|
|
/* 按钮之间的间距 */
|
|||
|
|
}
|
|||
|
|
</style>
|