<script setup> import { ref } from "vue"; import { onLoad, onPullDownRefresh, onReachBottom, onPageScroll } from "@dcloudio/uni-app"; import { getProjectInfoList, } from "@/api/work/projectInfo.js"; import { getPolicyList, } from "@/api/work/policy.js"; import { getContactList, } from "@/api/work/contact.js"; import { addFocus, cancelFocus } from "@/api/work/focus.js"; // 搜索项目 const searchTabs = [{ name: '项目' }, { name: '文件' }, { name: '通信' }]; const activeTabs = ref('项目'); const searchTabsClick = function(e) { activeTabs.value = e.name; searchPlaceholder.value = searchPlaceholderObj[e.name]; reSearch(e.name); }; // 搜索输入 let searchPlaceholderObj = { "项目": "请输入项目名称", "文件": "请输入文件名称", "通信": "行业单位名称/责任人姓名/领导姓名", } let searchPlaceholder = ref('请输入项目名称'); let searchContent = ref(null); const searchClean = function() { searchContent.value = null; }; // 搜索功能 let searchInfo = ref({ pageNo: 1, pageSize: 10, }); let paramsObj = { "项目": "subName", "文件": "title", "通信": "name", }; const getList = function(type) { let params = Object.assign({}, searchInfo.value); params[paramsObj[type]] = searchContent.value; if (type === "项目") { getProjectInfoList(params).then(res => { itemList.value = itemList.value.concat(res.data.list); listTotal.value = res.data.total; if (res.data.total == searchInfo.value.pageNo * searchInfo.value.pageSize - (10 - res.data.list .length)) moreListFlag = false; }) } if (type === "文件") { getPolicyList(params).then(res => { itemList.value = itemList.value.concat(res.data.list); listTotal.value = res.data.total; if (res.data.total == searchInfo.value.pageNo * searchInfo.value.pageSize - (10 - res.data.list .length)) moreListFlag = false; }) } if (type === "通信") { getContactList(params).then(res => { itemList.value = res.data.list; listTotal.value = res.data.list.length; moreListFlag = false; }) } } const reSearch = function(type) { searchInfo.value.pageNo = 1; moreListFlag = true; itemList.value = []; listTotal.value = 0; getList(type); }; // 搜索结果 let itemList = ref([]); let listTotal = ref(0); // 折叠/展开 const changeFoldItem = (status, id) => { let item = itemList.value.find(item => item.id === id); item.unfold = status; } const projectDetail = function(id, subName) { uni.navigateTo({ url: `/pages/projectInfo/detail/index?id=${id}&subName=${subName}` }) } const fileDetail = function(title, id) { uni.navigateTo({ url: `/pages/policy/detail/index?title=${title}&id=${id}`, }); } let popupShow = ref(false); let popupTitle = ref(null); let callShow = ref(false); const showPopup = function(text) { callShow.value = true; popupTitle.value = text popupShow.value = true } const hidePopup = function() { popupShow.value = false callShow.value = false } const pasteItem = function() { uni.setClipboardData({ data: popupTitle.value }); } const callItem = function() { plus.device.dial(popupTitle.value, true); } onLoad(() => { getList("项目") }) onPullDownRefresh(() => { try { reSearch(activeTabs.value); } finally { uni.stopPullDownRefresh() } }) let moreListFlag = true; let noEmpty = ref(false) onReachBottom(() => { if (!moreListFlag) { noEmpty.value = true } searchInfo.value.pageNo++; getList(activeTabs.value); }) function goToReport(type, subId, subName) { if (type === 'wtdb') { uni.navigateTo({ url: `/pages/problemSupervision/index?type=${type}&subId=${subId}&subName=${subName}` }) } else if (type === 'qtldjbm') { uni.navigateTo({ url: `/pages/leadersList/index?type=${type}&subId=${subId}&subName=${subName}` }) } else if (type === 'xcyx') { uni.navigateTo({ url: `/pages/projectImageAndVideo/index?type=${type}&subId=${subId}&subName=${subName}` }) } else if (type === 'more') { uni.navigateTo({ url: `/pages/morePage/index?type=${type}&subId=${subId}&subName=${subName}` }) } else { uni.navigateTo({ url: `/pages/projectInfo/report/index?type=${type}&subId=${subId}&subName=${subName}` }) } } function goToDetail(id, subName) { uni.navigateTo({ url: `/pages/projectInfo/detail/index?id=${id}&subName=${subName}` }) } // 收藏/取消 function changeFocus(id, status) { let item = itemList.value.find(item => item.id === id); if (status) { cancelFocus({ subId: id }).then(res => { if (res.code === 200) { item.isAttention = 0; } }).catch(() => { uni.showToast({ title: "更改收藏状态失败。", icon: "none", duration: 2000 }) }) } else { addFocus({ subId: id }).then(res => { if (res.code === 200) { item.isAttention = 1; } }).catch(() => { uni.showToast({ title: "更改收藏状态失败。", icon: "none", duration: 2000 }) }) } } let itemIndex = ref(-1); function openFold(index) { if (itemIndex.value == index) { itemIndex.value = -1; } else { itemIndex.value = index; } } let scrollTop = ref(0); onPageScroll((e) => { scrollTop.value = e.scrollTop }) </script> <template> <view class="container"> <page-title>搜索</page-title> <view class="search-box"> <!-- 搜索 --> <view class="search"> <view class="search-input"> <view class="search-icon"></view> <input :placeholder='searchPlaceholder' v-model="searchContent" placeholder-style="color: #D8D8D8;font-size:24rpx" /> </view> <view class="search-clean" :class="searchContent?.length>0?'':'search-hide'" @click="searchClean()"> </view> <view class="search-btn" @click="reSearch(activeTabs)"> <view class="search-line"> </view> 确认 </view> </view> <view class=""> <u-tabs :list="searchTabs" @click="searchTabsClick" inactiveStyle="color: rgba(255,255,255,0.6);font-weight: 500;font-size: 32rpx;white-space:nowrap;width:10%;" activeStyle="color: #FFFFFF;font-weight: 500;font-size: 32rpx;white-space:nowrap;border:none;width:10%;"></u-tabs> </view> </view> <!-- 列表 --> <view v-if="activeTabs === '项目'" class="cards-list"> <view class="items-list" v-for="(item,index) in itemList" :key="index"> <!-- 未折叠卡片 --> <view class="card"> <!-- 项目名称 --> <view class="project-layer"> <text class="card-name-num">{{(index+1<10?'0'+(index+1):index+1)}}</text> <view class="name">{{item.subName ?? "--"}}</view> <view class="card-status" @click="openFold(index)"> <image class="status-light" src="@/static/images/red.svg" mode="" v-if="item.status_fgw=='2'"></image> <image class="status-light" src="@/static/images/green.svg" mode="" v-if="item.status_fgw=='0'||item.status_fgw==null"></image> <image class="status-light" src="@/static/images/yellow.svg" mode="" v-if="item.status_fgw=='1'"> </image> <view class="status-name"> {{item.status ?? "--"}} </view> <image class="status-switch" src="@/static/images/liaghtUp.svg" mode="" :class="item.isOpen ?'card-status-icon-change' :''"> </image> </view> </view> <view class="card-content-box" :style="itemIndex==index ? {height:'300rpx'} :''"> <view class="line" style="margin-top: 0;margin-bottom: 20rpx;"> </view> <!-- 总投资(万元) --> <view class="card-item"> <view class="card-item-name">总投资(万元)</view> <view class="card-item-content">{{item.amtTotal ?? "--"}}</view> </view> <!-- 年度计划投资-申报单位(万元) --> <view class="card-item"> <view class="card-item-name">年度计划投资</view> <view class="card-item-content">{{item.yearAmt ?? "--"}}</view> </view> <!-- 已完成投资(万元)--> <view class="card-item"> <view class="card-item-name">年度完成投资</view> <view class="card-item-content">{{item.yearAmtSj ?? "--"}}</view> </view> <!-- 当前状态 --> <view class="card-item"> <view class="card-item-name">当前状态</view> <view class="card-item-content red">{{item.status ?? "--"}}</view> </view> <view class="card-btn-list" > <view class="button" @click="goToReport('weekly',item.id,item.subName)"> 周报 </view> <view class="button" @click="goToReport('monthly',item.id,item.subName)"> 月报 </view> <view class="button" v-if="!item.isAttention" @click="changeFocus(item.id,item.isAttention)"> 关注 </view> <view class="button" @click="changeFocus(item.id,item.isAttention)" v-else> 取消关注 </view> <view class="button" v-if="item.usersub == 1" @click="goToDetail(item.id,item.subName)"> 项目详情 </view> <view class="button" v-else @click="goToDetail(item.id,item.subName)"> 查看 </view> <view class="button" @click="goToReport('more',item.id,item.subName)"> 更多 </view> </view> </view> </view> </view> <view class="empty-btn" v-if="noEmpty&&itemList.length!==0"> 无更多内容 </view> </view> <view v-if="activeTabs === '文件'" class="cards-list"> <view class="card wenjian-card card-only" v-for="(item,index) in itemList" :key="index" style="padding-top: 20rpx !important;padding-bottom: 20rpx !important;"> <!-- <card-title :numerator="index+1" :denominator="listTotal"></card-title> --> <view class="card-item wenjian-item"> <view class=" name-content"> <view class="card-item-name">分类</view> <view class="card-item-content" style="display: flex;justify-content: space-between;align-items: center;"> {{item.columnName?? "--"}} <!-- <view class="card-item" style="justify-content: flex-end;"> --> <view class="card-btn fat-btn" style="width: 20%;" @click="fileDetail(item.title,item.id)"> 查看</view> <!-- </view> --> </view> </view> <view class="name-content"> <view class="card-item-name">名称</view> <view class="card-item-content">{{item.title??"--"}}</view> </view> </view> <!-- <view class="card-item"> <view class="card-item-name">时间</view> <view class="card-item-content">{{item.rptDate??"--"}}</view> </view> --> </view> <view class="empty-btn" v-if="noEmpty&&itemList.length!==0"> 无更多内容 </view> </view> <view v-if="activeTabs === '通信'" class="cards-list"> <view class="card card-only" v-for="(item,index) in itemList" :key="index" style="padding-top: 20rpx !important;padding-bottom: 20rpx !important;"> <!-- <card-title :numerator="index+1" :denominator="listTotal"></card-title> --> <view class="one-only-card"> <text class="card-name-num">{{(index+1<10?'0'+(index+1):index+1)}}</text> <view class="card-item "> <!-- <view class="card-item-name">行业单位</view> --> <view class="card-item-content only-item">{{item.unitName || "--"}}</view> </view> <view class="card-item spe-item" v-if="item.departName"> <!-- <view class="card-item-name">科室</view> --> <view class="card-item-content spe-item-content">{{item.departName || "--"}}</view> </view> </view> <view class="line"></view> <view class="card-item" v-if="item.zrrName || item.zrrTel"> <view class="card-item-name">项目负责人</view> <view class="card-item-content">{{item.zrrName || "--"}}</view> </view> <view class="card-item" @click="showPopup(item.zrrTel)" v-if="item.zrrName || item.zrrTel"> <view class="card-item-name">联系人电话</view> <view class="card-item-content zrrTel">{{item.zrrTel || "--"}}</view> </view> <view class="line" v-if="item.leadName || item.leadTel"></view> <view class="card-item" v-if="item.leadName || item.leadTel"> <view class="card-item-name">分管领导人</view> <view class="card-item-content">{{item.leadName || "--"}}</view> </view> <view class="card-item" @click="showPopup(item.leadTel)" v-if="item.leadName || item.leadTel"> <view class="card-item-name">联系人电话</view> <view class="card-item-content zrrTel">{{item.leadTel || "--"}}</view> </view> <view class="line" v-if="item.ptName || item.telPt"></view> <view class="card-item" v-if="item.ptName || item.telPt"> <view class="card-item-name">平台管理人</view> <view class="card-item-content">{{item.ptName || "--"}}</view> </view> <view class="card-item" @click="showPopup(item.telPt)" v-if="item.ptName || item.telPt"> <view class="card-item-name">联系人电话</view> <view class="card-item-content zrrTel">{{item.telPt || "--"}}</view> </view> </view> <view class="empty-btn" v-if="noEmpty&&itemList.length!==0"> 无更多内容 </view> </view> <u-back-top :scroll-top="scrollTop"></u-back-top> <u-popup :show="popupShow" @close="hidePopup()" mode="bottom" :round="20" closeOnClickOverlay> <view class="popup-content"> <view class="popup-item popup-title">{{popupTitle}}</view> <view class="popup-item" @click="pasteItem()">复制</view> <view class="popup-item" v-show="callShow" @click="callItem()">拨打</view> <view class="popup-item popup-close" @click="hidePopup()">关闭</view> </view> </u-popup> </view> </template> <style lang="scss" scoped> :deep(.u-tabs__wrapper__nav) { justify-content: flex-start; } :deep(.u-tabs__wrapper__nav__line) { background-color: transparent !important; } :deep(.u-tabs__wrapper__scroll-view-wrapper), :ddep(.uni-scroll-view) { overflow: visible !important; } :deep(.u-tabs__wrapper__nav__item) { width: 30%; } .red { color: #E02020 !important; } .search-box { position: fixed; top: calc(var(--status-bar-height) + 50px); display: flex; flex-direction: row; justify-content: center; align-items: center; // margin-top: calc(var(--status-bar-height) + 50px); width: 100%; height: 120rpx; // padding: 0 28rpx; background-color: #002F69; // background-color: #fff; z-index: 99; } .empty-btn { width: 100%; line-height: 60rpx; display: flex; align-items: center; justify-content: center; color: #B5B5B5; } .zrrTel { color: #1763E7 !important; } .leadTel { color: #16AD49 !important; } .ptTel { color: #FF530F !important; } .blue { color: #1763E7 !important; } .card { width: 90%; margin: 0 auto; .card-name { min-height: 30rpx; } } .cards-list { display: flex; flex-direction: column !important; gap: 20rpx; } .card-btn { display: flex; justify-content: center; align-items: center; width: 200rpx; height: 48rpx; background: #D6ECFF; border-radius: 30rpx; font-weight: 500; font-size: 28rpx; color: #002F69; } .line { width: 100%; height: 1px; border-top: 1px dashed #DDDDDD; margin: 10rpx auto; } .search-line { margin-right: 24rpx; width: 0; height: 28rpx; border-left: 2rpx solid #EBEBEB; } .wenjian-card { padding: 24rpx 20rpx; display: flex; flex-direction: column; justify-content: space-between; .wenjian-item { display: flex; flex-direction: column; justify-content: flex-start; width: 100%; .name-content { display: flex; flex-direction: row !important; justify-content: flex-start; width: 100%; gap: 16rpx; } } } .card-item .card-item-name { // width: 200rpx; white-space: nowrap; font-size: 28rpx !important; } .card-item .card-item-content { width: 94%; display: -webkit-box; /* 使用旧版的弹性盒子布局 */ -webkit-box-orient: vertical; /* 设置为垂直方向排列 */ overflow: hidden; /* 隐藏溢出内容 */ text-overflow: ellipsis; /* 使用省略号表示溢出内容 */ -webkit-line-clamp: 2; /* 显示的行数 */ } .policy-item { width: 696rpx; // height: 44px; background: #FFFFFF; box-shadow: 0px 0px 8rpx 0px #D8EEFF; border-radius: 10rpx; margin: 0 auto; // height: 188rpx; display: flex; flex-direction: column; align-items: center; padding-right: 16rpx; padding-left: 10rpx; .un-fold { display: flex; flex-direction: row; align-items: center; height: 128rpx; // padding: 0 8rpx; width: 100%; .search-item-icon { width: 96rpx; height: 78rpx; margin: 38rpx auto 40rpx; background-image: url('@/static/policy-file.png'); background-size: 100% 100%; } } .fold { width: 100%; padding-bottom: 24rpx; transition: all .3s; height: 270rpx; .card-item { width: 100%; display: flex; flex-direction: row; line-height: 44rpx; .card-item-name { font-weight: 500; font-size: 24rpx; color: #B5B5B5; line-height: 44rpx; // margin-right: 16rpx; // width: 400rpx; } .card-item-content { font-weight: 500; font-size: 28rpx; color: #333333; line-height: 44rpx; } } .item-special { width: 634rpx; height: 56rpx; border-radius: 30rpx; border: 2rpx solid #EBEBEB; margin: 0 auto; line-height: 56rpx; margin-bottom: 24rpx; .name-special, .content-special { font-weight: 500; font-size: 24rpx; color: #7A85E0; } } } .search-item-text { width: 420rpx; // max-width: 146rpx; // min-height: 40rpx; // margin: 0 auto; text-align: center; line-height: 40rpx; font-weight: 500; font-size: 28rpx; color: #222222; // background: #E2ECFF; border-radius: 8rpx; display: flex; justify-content: flex-start; text-align: left; } .detail-fold { display: flex; flex-direction: row; align-items: center; width: 160rpx; white-space: nowrap; image { width: 32rpx; height: 32rpx; min-width: 32rpx; // margin-left: 16rpx; } } } .project-btn { width: 48% !important; background: #1869F6; } .focus-btn { width: 48% !important; background-color: #fff; border-radius: 16rpx 16rpx 16rpx 16rpx; border: 3rpx solid #1869F6; color: #1869F6; } .focus-btn-no { width: 48% !important; background-color: #fff; border-radius: 16rpx 16rpx 16rpx 16rpx; border: 3rpx solid #FF2D2D; color: #FF2D2D; } .more-btn { background-color: #fff; color: #1869F6; font-size: 32rpx; } .switch { position: absolute; // top: 112%; left: 4%; width: 92%; height: 110rpx; padding-top: 30rpx; margin: 0 auto 32rpx; background-color: #fff; border-radius: 28rpx; } .search { // position: absolute; // top: calc(var(--status-bar-height) + 280rpx); // left: 4%; display: flex; align-items: center; justify-content: space-between; width: 50%; height: 68rpx; padding-left: 10rpx; box-sizing: border-box; background-color: #fff; border-radius: 16rpx; .search-input { display: flex; align-items: center; input { width: 70%; } .search-icon { width: 28rpx; height: 32rpx; margin-right: 26rpx; background-image: url('@/static/search-black.png'); background-size: 100% 100%; } } .search-clean { width: 30rpx; height: 30rpx; background-image: url('@/static/search-clean.png'); background-size: 100% 100%; } .search-hide { background: none; } } .search-btn { // position: absolute; // top: calc(var(--status-bar-height) + 280rpx); // right: 4%; margin-right: 18rpx; display: flex; align-items: center; justify-content: center; width: 10%; height: 68rpx; padding: 0 30rpx; box-sizing: border-box; // background-color: #1763E7; font-size: 24rpx; color: #002F69; // border-radius: 34rpx; white-space: nowrap; // border-left: 2rpx solid #EBEBEB; } .cards-list { width: 100% !important; position: absolute; top: calc(var(--status-bar-height) + 250rpx); .phone { color: #1763E7; } .leader-phone { color: #06BC43; } } .popup-content { text-align: center; border-radius: 20rpx 20rpx 0 0; background-color: #f3f3f3; .popup-item { height: 100rpx; line-height: 100rpx; color: #343437; font-size: 32rpx; background-color: #fff; border-bottom: 2rpx solid #EAF0FA; } .popup-title { color: #9E9E9E; border-radius: 20rpx 20rpx 0 0; } .popup-close { margin-top: 20rpx; border-top: 2rpx solid #EAF0FA; } } .card-padding { padding: 16rpx 40rpx 60rpx; // overflow: hidden; } .card-fold { position: relative; width: 100%; min-height: 152rpx; margin-bottom: 20rpx; padding: 24rpx 30rpx 52rpx; box-sizing: border-box; background: #FFFFFF; border-radius: 40rpx; overflow: hidden; } .card-fold-option { position: absolute; display: flex; justify-content: space-between; align-items: center; left: 0; bottom: 0; width: 100%; height: 38rpx; padding: 0 40rpx; box-sizing: border-box; background: linear-gradient(270deg, #CADDFF 4%, rgba(219, 232, 255, 0) 100%); z-index: 999; .card-fold-count { flex: 1; font-size: 28rpx; color: #1869F6; } .card-fold-center { flex: 1; .card-fold-btn { width: 32rpx; height: 20rpx; margin: 0 auto; background-image: url("@/static/icon-fold.png"); background-size: 100% 100%; } .card-unfold-btn { transform: rotate(180deg); } } .card-fold-chaos { flex: 1; } } .card-fold-red { background: linear-gradient(270deg, #FF8080 0%, rgba(219, 232, 255, 0) 100%); .card-fold-count { color: #FF0000; } .card-fold-center { .card-fold-btn { background-image: url("@/static/icon-fold-red.png"); } } } .card-fold-yellow { background: linear-gradient(270deg, #FFAA00 4%, rgba(219, 232, 255, 0) 100%); .card-fold-count { color: #E19703; } .card-fold-center { .card-fold-btn { background-image: url("@/static/icon-fold-yellow.png"); } } } .card-name-num { width: 64rpx; height: 64rpx; border-radius: 4rpx; border: 2rpx solid #F4F4F4; font-size: 24rpx; color: #B5B5B5; display: flex; align-items: center; justify-content: center; } .card .project-layer { justify-content: flex-start; .name { font-weight: 500; font-size: 28rpx; color: #222222; } } .status-light { width: 60rpx !important; height: 60rpx !important; position: absolute !important; right: 0; top: -46rpx !important; } .one-only-card { width: 100%; display: flex; justify-content: space-between; .only-item { font-weight: 500 !important; font-size: 28rpx !important; color: #002F69 !important; } .spe-item { text-align: right; .spe-item-content { font-weight: 500 !important; font-size: 28rpx !important; color: #6C90C1 !important; } } } </style>