Files
ks-app-employment-service/packageRc/pages/policy/policyList.vue

694 lines
16 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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="page h5-pc-page"
style="
background-image: url(../../../packageRc/static/pageBg.png);
"
>
<view
class="input-outer-part"
style="padding: 24rpx 32rpx 0; max-height: unset"
>
<view class="search-line">
<input
style="width: 100%"
placeholder="请输入政策名称进行搜索"
v-model="queryParams.searchValue"
border="none"
/>
<img
src="https://rc.jinan.gov.cn/qcwjyH5/static/images/person/search.png"
class="search-icon"
@click="search()"
/>
</view>
<view
class="inner"
:style="{
width: 'calc(100% + 64rpx)',
marginLeft: '-32rpx',
height: zctopShow ? 'auto' : '122rpx',
position: 'relative',
zIndex: zctopShow ? 100 : 2,
}"
>
<PopupList
:checkData="checkData"
@searchCheck="search"
ref="PopupList"
@popupSearch="popupSearch"
/>
</view>
<view
v-if="total"
style="position: relative; padding: 32rpx 0; color: #000"
>
<!-- <view v-if="total" style="position: relative;padding-bottom: 16px;color: #000;"> -->
<text> {{ total }} </text>
</view>
<!-- <scroll-view :scroll-y="true" style="height: calc(100vh - 342rpx);position: relative;z-index: 1;" -->
<scroll-view
:scroll-y="true"
style="height: calc(100vh - 354rpx); position: relative; z-index: 1"
@scrolltolower="getBottomList"
:show-scrollbar="false"
>
<view
style="margin-bottom: 24rpx; border-radius: 16rpx"
class="policy-list"
v-for="(item, index) in tableData"
:key="index"
@click="goPolicyDetail(item)"
>
<view class="title">
<image src="../../../packageRc/static/zcLeft.png" />
{{ item.zcmc }}</view
>
<view class="infos">
<view v-if="item.zcLevel">{{ item.zcLevel }}</view>
<view v-if="item.sourceUnit">{{ item.sourceUnit }}</view>
</view>
<view class="bottom-line">
<view
><uni-icons color="#A2A2A2" type="info" size="12"></uni-icons
>发文日期{{ item.publishTime }}</view
>
<view
><uni-icons color="#A2A2A2" type="eye" size="12"></uni-icons
>浏览量{{ item.viewNum || 0 }}</view
>
</view>
</view>
<view style="padding-bottom: 24rpx">
<img
v-if="!total && !loading"
src="https://rc.jinan.gov.cn/qcwjyH5/static/images/person/empty.png"
style="width: 100%; display: block; margin: 0 auto"
/>
<view v-if="loading"
><u-loading-icon></u-loading-icon>
<view style="text-align: center; color: #8e8e8e; font-size: 24rpx"
>加载中~</view
>
</view>
<view
v-else-if="showMorePage"
style="text-align: center; color: #1a62ce; font-size: 24rpx"
>加载更多
</view>
<view
style="text-align: center; color: #8e8e8e; font-size: 24rpx"
v-else
>没有更多数据了~</view
> </view
>  
</scroll-view>
</view>
</view>
</template>
<script>
import PopupList from "/packageRc/components/PopupLists.vue";
import { getPolicyList } from "@/packageRc/apiRc/policy";
import { getDicts } from "@/packageRc/apiRc/system/dict";
export default {
components: {
PopupList,
},
data() {
return {
queryParams: {
pageNum: 1,
pageSize: 10,
},
total: 0,
showMorePage: true,
tableData: [],
loading: false,
checkData: [],
zctopShow: false,
policyTypeMList: [],
};
},
onLoad(options) {
this.queryParams.zclx = options.zclx;
this.getCheckData();
},
onShow() {
this.search();
},
watch: {
"checkData": {
handler(newVal) {
if (!newVal || newVal.length < 3 || !this.policyTypeMList.length) return;
const typeL = newVal[0].data[newVal[0].activeIndex].dictValue;
// 政策类型不选时,不显示二级分类
const isHidden = !typeL;
if (newVal[1].hidden !== isHidden) {
this.$set(newVal[1], "hidden", isHidden);
}
// 政策类型不选时确保二级分类已选索引重置为0全部
if (isHidden && newVal[1].activeIndex !== 0) {
this.$set(newVal[1], "activeIndex", 0);
}
let filtered = [];
if (typeL) {
filtered = this.policyTypeMList.filter((item) =>
item.dictValue.startsWith(typeL)
);
} else {
filtered = this.policyTypeMList;
}
// Only update if data changed to avoid infinite loop
const newData = [{ dictLabel: "全部", dictValue: "" }].concat(filtered);
if (JSON.stringify(newVal[1].data) !== JSON.stringify(newData)) {
this.$set(newVal[1], "data", newData);
this.$set(newVal[1], "activeIndex", 0);
}
},
deep: true,
},
},
methods: {
async getCheckData() {
const resLevel = await getDicts("zc_level");
const resType1 = await getDicts("policy_type1");
const resType2 = await getDicts("policy_type2");
this.policyTypeMList = resType2.data;
const type1Data = [{ dictLabel: "全部", dictValue: "" }].concat(
resType1.data || []
);
// policyTypeL 与 zclx 不相关,不再使用 zclx 初始化
const initialTypeLIndex = type1Data.findIndex(
(item) => item.dictValue == this.queryParams.policyTypeL
);
this.checkData = [
{
name: "政策类型",
type: "policyTypeL",
data: type1Data,
activeIndex: initialTypeLIndex > -1 ? initialTypeLIndex : 0,
},
{
name: "二级分类",
type: "policyTypeM",
data: [{ dictLabel: "全部", dictValue: "" }].concat(resType2.data || []),
activeIndex: 0,
hidden: true,
},
{
name: "政策级别",
type: "zcLevel",
data: [{ dictLabel: "全部", dictValue: "" }].concat(resLevel.data || []),
activeIndex: 0,
},
];
},
popupSearch(data) {
// 获取此次提交前,旧的政策类型值
const oldTypeL = this.queryParams.policyTypeL || "";
// 获取弹窗提交的实时选值
const selections = {};
data.forEach((item) => {
const active = item.data[item.activeIndex];
selections[item.type] = active.dictLabel === "全部" ? "" : active.dictValue;
});
// 核心判定逻辑:
// 如果发现“政策类型(policyTypeL)”发生了变化
if (selections.policyTypeL !== oldTypeL) {
// 如果改变成了具体的分类,且二级分类传过来的不是该分类下的子类(说明是残留选项没来得及重置)
// 或者是变回了“全部”
// 那么必须强制清空二级分类
if (!selections.policyTypeL || (selections.policyTypeM && !selections.policyTypeM.startsWith(selections.policyTypeL))) {
selections.policyTypeM = "";
const typeMItem = data.find((it) => it.type === "policyTypeM");
if (typeMItem) typeMItem.activeIndex = 0;
}
}
// 将最终确定的值同步到查询参数中
Object.keys(selections).forEach((key) => {
this.$set(this.queryParams, key, selections[key]);
});
this.search();
},
goPolicyDetail(item) {
uni.navigateTo({
url: `/packageRc/pages/policy/policyDetail?id=${item.id}`,
});
},
search() {
this.showMorePage = true;
this.queryParams.pageNum = 1;
this.queryParams.pageSize = 20;
this.tableData = [];
this.total = 0;
this.getList();
},
// 触底加载
getBottomList() {
if (this.queryParams.pageNum * this.queryParams.pageSize >= this.total) {
this.showMorePage = false;
} else if (
this.queryParams.pageNum * this.queryParams.pageSize <
this.total
) {
this.queryParams.pageNum++;
this.getList();
if (
this.queryParams.pageNum * this.queryParams.pageSize >=
this.total
) {
this.showMorePage = false;
}
}
},
// 获取列表
async getList() {
this.loading = true;
getPolicyList(this.queryParams).then((res) => {
this.gettedData(res);
});
},
gettedData(res) {
if (res.code == 200) {
if (res.rows.length < 10) {
this.showMorePage = false;
}
this.loading = false;
this.tableData = this.tableData.concat(res.rows);
this.total = res.total;
} else {
this.loading = false;
// #ifdef H5 || APP-PLUS
// 接口返回非 200 或失败时展示测试数据 (条件编译)
this.tableData = [
{ id: '1', zcmc: '测试政策001关于进一步支持人才发展的若干措施条件编译测试数据', publishTime: '2026-03-10', viewNum: 888, zcLevel: '省级', sourceUnit: '模拟测试部' },
{ id: '2', zcmc: '测试政策002高校毕业生创业补贴申请指南条件编译测试数据', publishTime: '2026-03-10', viewNum: 666, zcLevel: '市级', sourceUnit: '人力资源局' }
];
this.total = 2;
// #endif
uni.showToast({
title: res.msg || '获取列表失败',
icon: "none",
});
}
},
},
};
</script>
<style lang="scss" scoped>
/* 隐藏滚动条 */
::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
}
.page {
background-color: #f4f4f4 !important;
height: 100vh;
background-repeat: no-repeat;
background-size: 100% auto;
}
.search-line {
border-radius: 32px;
background: #ffffff;
box-sizing: border-box;
border: 1px solid #107afd;
height: 64rpx;
border-radius: 32rpx;
padding: 0 32rpx;
display: flex;
align-items: center;
position: relative;
z-index: 110;
margin-top: 24rpx;
.search-icon {
width: 40rpx;
height: 40rpx;
}
}
.job-item {
position: relative;
margin-bottom: 24rpx;
background: #fff;
border-radius: 16rpx;
.item_btn {
height: 100rpx;
border-top: 1px solid #e3e8ee;
}
.line {
position: absolute;
right: 50%;
bottom: 20rpx;
width: 1px;
height: 60rpx;
background-color: #e3e8ee;
}
.status-card {
position: absolute;
right: 0;
top: 0;
border-radius: 0 16rpx 0 16rpx;
width: 160rpx;
line-height: 40rpx;
text-align: center;
color: #fff;
background: #b2c0d1;
border: 1px solid #9ba9b9;
font-size: 24rpx;
&.in {
background: #29d297;
border: 1px solid #1bba83;
}
&.out {
background: #ecb83d;
border: 1px solid #d7892b;
}
&.far {
background: #ec7737;
border: 1px solid #c24f1a;
}
}
.top-container {
padding: 32rpx;
// margin-bottom: 24rpx;
.title-line {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 32rpx;
font-weight: bold;
margin-bottom: 16rpx;
.type-tag {
line-height: 40rpx;
width: 128rpx;
font-size: 24rpx;
color: #fff;
text-align: center;
&.qz {
background: #28cb5e;
}
&.yz {
background: #dd6728;
}
&.cy {
background: #23b5c5;
}
&.px {
background: #dda728;
}
&.qt {
background: #2870dd;
}
}
.title {
color: #3d3d3d;
width: calc(100% - 137rpx);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 40rpx;
}
.salary {
width: 33%;
color: #fa6553;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: right;
}
}
.info {
color: #3d3d3d;
margin-bottom: 7rpx;
font-size: 28rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text {
color: #8e8e8e;
}
.not {
color: #ec7737;
font-weight: bold;
}
.ing {
color: #ecb83d;
font-weight: bold;
}
.finish {
color: #21c88d;
font-weight: bold;
}
}
}
.function-btn {
color: #bf5818;
border-top: 1px solid #e2e8ef;
padding-bottom: 6rpx;
line-height: 90rpx;
text-align: center;
}
}
.self-form {
padding: 32rpx;
.bordered {
border: 1rpx solid #dadbde;
padding: 9px;
border-radius: 4px;
}
}
.button-area {
padding: 24rpx 32rpx 68rpx;
background: #fff;
display: flex;
box-sizing: border-box;
border-radius: 16px 16px 0px 0px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
.btn {
line-height: 72rpx;
width: 176rpx;
margin-right: 16rpx;
font-size: 28rpx;
border: 1px solid #b8c5d4;
color: #282828;
text-align: center;
border-radius: 8rpx;
}
.reset {
background: #dce2e9;
}
.save {
background: linear-gradient(103deg, #1d64cf 0%, #1590d4 99%);
color: #fff;
border: 0;
flex-grow: 1;
}
}
.noValue {
color: rgb(192, 196, 204);
}
.addNeeds {
position: fixed;
right: 0;
bottom: 150rpx;
width: 150rpx;
overflow: hidden;
z-index: 10;
border-radius: 44rpx;
border-radius: 75rpx;
img {
display: block;
width: 100%;
}
}
.df_flex {
display: flex;
view {
flex-grow: 1;
text-align: center;
color: #4c6efb;
}
}
.df_flex_1 {
flex: 1;
}
.df__direction_column {
flex-direction: column;
}
.df_align_center {
align-items: center;
}
.df_justify_center {
justify-content: center;
}
.df_content_between {
justify-content: space-between;
}
.df_shrink_0 {
flex-shrink: 0;
}
/* 日期选择器样式 */
.date-picker-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
box-sizing: border-box;
padding: 0 24rpx;
height: 64rpx;
border: 1px solid #ddd;
border-radius: 4px;
background-color: #fff;
}
// .date-picker-wrapper.noValue {
// background-color: #f9f9f9;
// }
.date-value {
color: #333;
width: 100%;
}
.policy-list {
width: 100%;
margin: 0 auto;
color: #333333;
border-radius: 24rpx;
background: #ffffff;
padding: 32rpx;
margin-bottom: 24rpx;
box-sizing: border-box;
position: relative;
.sign {
position: absolute;
font-size: 24rpx;
right: 0;
top: 0;
padding: 4rpx 14rpx;
border: 1rpx solid #ec4827;
background: rgba(227, 79, 49, 0.09);
border-top-right-radius: 24rpx;
border-bottom-left-radius: 24rpx;
color: #ec4827;
}
.top-line {
display: flex;
justify-content: space-between;
font-size: 24rpx;
color: #a2a2a2;
margin-bottom: 16rpx;
.salary {
font-size: 32rpx;
color: #4c6efb;
font-weight: bold;
}
}
.title {
font-size: 32rpx;
font-weight: bold;
color: #282828;
margin-bottom: 16rpx;
display: flex;
image {
width: 46rpx;
height: 46rpx;
margin-right: 11rpx;
}
}
.infos {
display: flex;
flex-wrap: wrap;
font-size: 24rpx;
margin-bottom: 16rpx;
line-height: 42rpx;
view {
padding: 0 16rpx;
margin-right: 10rpx;
background: #f2f2f2;
}
}
.bottom-line {
display: flex;
justify-content: space-between;
font-size: 24rpx;
color: #a2a2a2;
margin-top: 12rpx;
}
}
/* #ifdef H5 */
.h5-pc-page {
width: 100% !important;
.input-outer-part {
width: 80% !important;
margin: 0 auto !important;
padding-left: 0 !important;
padding-right: 0 !important;
}
.title {
font-size: 48rpx !important;
margin-bottom: 24rpx !important;
}
.infos view {
font-size: 36rpx !important;
line-height: 56rpx !important;
}
.bottom-line {
font-size: 34rpx !important;
margin-top: 24rpx !important;
}
input {
font-size: 36rpx !important;
}
}
/* #endif */
</style>