页面适配

This commit is contained in:
2025-12-12 13:39:23 +08:00
parent 60b4d2bef0
commit 9bc3c0fb7c
18 changed files with 574 additions and 1650 deletions

View File

@@ -1,39 +1,46 @@
<template>
<view>
<!-- #ifdef H5 -->
<transition-group name="blur-fade-stagger" tag="view">
<view v-for="(job, index) in dataSource" :key="job.id" :style="{ '--i': 2 }">
<view class="cards" @click="nextDetail(job)">
<view class="card-company">
<text class="company line_1">{{ job.gsmc }}</text>
</view>
<view class="card-bottom">
<view class="fl_box fs_14">
<!-- <dict-tree-Label class="mar_ri10" dictType="industry" :value="job.industry"></dict-tree-Label>
<!-- #endif -->
<view v-for="(job, index) in dataSource" :key="job.id" :style="{ '--i': 2 }">
<view class="cards" @click="nextDetail(job)">
<view class="card-company">
<text class="company line_1">{{ job.gsmc }}</text>
</view>
<view class="card-bottom">
<view class="fl_box fs_14">
<!-- <dict-tree-Label class="mar_ri10" dictType="industry" :value="job.industry"></dict-tree-Label>
<dict-Label dictType="scale" :value="job.scale"></dict-Label> -->
<view>{{ job.gsxy }}</view>
</view>
<view class="ris">
<text class="fs_14">
在招职位·
<text class="color_256BFA">{{ job.zzgwsl || '-' }}</text>
</text>
</view>
</view>
<view class="card-tags">
<view class="tag" v-if="job.nature">
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
<view class="tag" v-if="job.qyxz">
{{ job.qyxz }}
</view>
</view>
<view>{{ job.gsxy }}</view>
</view>
<view class="ris">
<text class="fs_14">
在招职位·
<text class="color_256BFA">{{ job.zzgwsl || '-' }}</text>
</text>
</view>
</view>
<view class="card-tags">
<view class="tag" v-if="job.nature">
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
<dict-Label dictType="nature" :value="job.nature"></dict-Label>
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
<view class="tag" v-if="job.qyxz">
{{ job.qyxz }}
</view>
</view>
</view>
</view>
<!-- #ifdef H5 -->
</transition-group>
<!-- #endif -->
</view>
</template>
<script setup>
@@ -44,70 +51,70 @@ const recommedIndexDb = useRecommedIndexedDBStore();
const dataSource = ref([]);
const props = defineProps({
list: {
type: Array,
default: () => [],
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
zphId: {
type: String,
default: '',
},
list: {
type: Array,
default: () => [],
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
zphId: {
type: String,
default: '',
},
});
const processedIds = new Set();
watch(
() => props.list,
(newList) => {
if (!Array.isArray(newList)) return;
() => props.list,
(newList) => {
if (!Array.isArray(newList)) return;
let shouldReset = false;
let shouldReset = false;
if (dataSource.value.length > newList.length) {
shouldReset = true;
} else if (dataSource.value.length > 0 && newList.length > 0) {
// 注意:这里沿用你代码中使用的 item.id 作为唯一标识
const oldId = dataSource.value[0].id;
const newId = newList[0].id;
if (oldId !== newId) {
shouldReset = true;
}
}
if (dataSource.value.length > newList.length) {
shouldReset = true;
} else if (dataSource.value.length > 0 && newList.length > 0) {
// 注意:这里沿用你代码中使用的 item.id 作为唯一标识
const oldId = dataSource.value[0].id;
const newId = newList[0].id;
if (oldId !== newId) {
shouldReset = true;
}
}
if (shouldReset) {
dataSource.value = [];
processedIds.clear();
}
if (shouldReset) {
dataSource.value = [];
processedIds.clear();
}
const newItems = newList.filter((item) => !processedIds.has(item.id));
const newItems = newList.filter((item) => !processedIds.has(item.id));
if (newItems.length === 0) return;
if (newItems.length === 0) return;
newItems.forEach((item) => processedIds.add(item.id));
const delay = 50;
newItems.forEach((item, index) => {
setTimeout(() => {
dataSource.value.push(item);
}, index * delay);
});
},
{ immediate: true, deep: true }
newItems.forEach((item) => processedIds.add(item.id));
const delay = 50;
newItems.forEach((item, index) => {
setTimeout(() => {
dataSource.value.push(item);
}, index * delay);
});
},
{ immediate: true, deep: true }
);
function nextDetail(company) {
navTo(
`/packageA/pages/UnitDetails/UnitDetails?companyId=${company.gsID}&companyName=${company.gsmc}&zphId=${props.zphId}&dataType=2`
);
navTo(
`/packageA/pages/UnitDetails/UnitDetails?companyId=${company.gsID}&companyName=${company.gsmc}&zphId=${props.zphId}&dataType=2`
);
}
</script>

View File

@@ -138,7 +138,7 @@ function nextDetail(job) {
if (job.isPublish) {
return $api.msg('已过期');
}
navTo(`/packageA/pages/post/post?jobId=${btoa(job.jobId)}&dataType=${job.dataType}`);
navTo(`/packageA/pages/post/post?jobId=${encodeURIComponent(job.jobId)}&dataType=${job.dataType}`);
}
</script>

View File

@@ -139,7 +139,7 @@ function nextDetail(job) {
return $api.msg('已过期');
}
// 根据数据类型跳转到不同的详情页
navTo(`/packageA/pages/post/post?jobId=${btoa(job.jobId)}&dataType=${job.dataType}`);
navTo(`/packageA/pages/post/post?jobId=${encodeURIComponent(job.jobId)}&dataType=${job.dataType}`);
}
</script>

View File

@@ -138,7 +138,7 @@ function nextDetail(job) {
if (job.isPublish) {
return $api.msg('已过期');
}
navTo(`/packageA/pages/post/post?jobId=${btoa(job.jobId)}&dataType=${job.dataType}`);
navTo(`/packageA/pages/post/post?jobId=${encodeURIComponent(job.jobId)}&dataType=${job.dataType}`);
}
</script>

View File

@@ -1,46 +1,52 @@
<template>
<view>
<!-- #ifdef H5 -->
<transition-group name="blur-fade-stagger" tag="view">
<view v-for="job in dataSource" :key="job.id || job.jobId" :style="{ '--i': 2 }">
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
<view class="card-company">
<text class="company">{{ job.jobTitle }}</text>
<view class="salary">
<Salary-Expectation
:max-salary="job.maxSalary"
:min-salary="job.minSalary"
></Salary-Expectation>
</view>
</view>
<view class="card-companyName">{{ job.gwmc }}</view>
<view class="card-tags">
<view class="tag">
<dict-Label dictType="education" :value="job.education"></dict-Label>
</view>
<view class="tag">
<dict-Label dictType="experience" :value="job.experience"></dict-Label>
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
</view>
<view class="card-bottom">
<view>{{ job.postingDate }}</view>
<view>
<convert-distance
:alat="job.latitude"
:along="job.longitude"
:blat="latitude"
:blong="longitude"
></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label>
</view>
</view>
<!-- #endif -->
<view v-for="job in dataSource" :key="job.id || job.jobId" :style="{ '--i': 2 }">
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
<view class="card-company">
<text class="company">{{ job.jobTitle }}</text>
<view class="salary">
<Salary-Expectation
:max-salary="job.maxSalary"
:min-salary="job.minSalary"
></Salary-Expectation>
</view>
<view class="date-jobTitle" v-else>
{{ job.title }}
</view>
<view class="card-companyName">{{ job.gwmc }}</view>
<view class="card-tags">
<view class="tag">
<dict-Label dictType="education" :value="job.education"></dict-Label>
</view>
<view class="tag">
<dict-Label dictType="experience" :value="job.experience"></dict-Label>
</view>
<view class="tag">
{{ vacanciesTo(job.vacancies) }}
</view>
</view>
<view class="card-bottom">
<view>{{ job.postingDate }}</view>
<view>
<convert-distance
:alat="job.latitude"
:along="job.longitude"
:blat="latitude"
:blong="longitude"
></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label>
</view>
</view>
</view>
<view class="date-jobTitle" v-else>
{{ job.title }}
</view>
</view>
<!-- #ifdef H5 -->
</transition-group>
<!-- #endif -->
</view>
</template>
<script setup>
@@ -50,85 +56,85 @@ import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js
const recommedIndexDb = useRecommedIndexedDBStore();
const dataSource = ref([]);
const props = defineProps({
list: {
type: Array,
default: '标题',
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
list: {
type: Array,
default: '标题',
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
});
const listData = computed(() => {
if (props.seeDate && props.list.length) {
const ulist = toRaw(props.list);
const [reslist, lastDate] = insertSortData(ulist, props.seeDate);
return reslist;
}
return props.list;
if (props.seeDate && props.list.length) {
const ulist = toRaw(props.list);
const [reslist, lastDate] = insertSortData(ulist, props.seeDate);
return reslist;
}
return props.list;
});
const processedIds = new Set();
watch(
() => props.list,
(newList) => {
if (!Array.isArray(newList)) return;
() => props.list,
(newList) => {
if (!Array.isArray(newList)) return;
// --- 新增逻辑开始 ---
// 判断是否需要重置数据 (例如点击了搜索、切换了Tab、或下拉刷新)
let shouldReset = false;
// --- 新增逻辑开始 ---
// 判断是否需要重置数据 (例如点击了搜索、切换了Tab、或下拉刷新)
let shouldReset = false;
// 场景1: 新列表长度比当前渲染的列表短说明发生了重置如从20条变成了10条
if (dataSource.value.length > newList.length) {
shouldReset = true;
}
// 场景2: 列表不为空且第一条数据的ID发生了变化说明是全新的搜索结果
else if (dataSource.value.length > 0 && newList.length > 0) {
const oldId = dataSource.value[0].id || dataSource.value[0].jobId;
const newId = newList[0].id || newList[0].jobId;
if (oldId !== newId) {
shouldReset = true;
}
}
// 场景1: 新列表长度比当前渲染的列表短说明发生了重置如从20条变成了10条
if (dataSource.value.length > newList.length) {
shouldReset = true;
}
// 场景2: 列表不为空且第一条数据的ID发生了变化说明是全新的搜索结果
else if (dataSource.value.length > 0 && newList.length > 0) {
const oldId = dataSource.value[0].id || dataSource.value[0].jobId;
const newId = newList[0].id || newList[0].jobId;
if (oldId !== newId) {
shouldReset = true;
}
}
// 如果判定为重置则清空现有数据和ID记录
if (shouldReset) {
dataSource.value = [];
processedIds.clear();
}
// --- 新增逻辑结束 ---
// 如果判定为重置则清空现有数据和ID记录
if (shouldReset) {
dataSource.value = [];
processedIds.clear();
}
// --- 新增逻辑结束 ---
const newItems = newList.filter((item) => !processedIds.has(item.id || item.jobId));
const newItems = newList.filter((item) => !processedIds.has(item.id || item.jobId));
if (newItems.length === 0) return;
if (newItems.length === 0) return;
newItems.forEach((item) => processedIds.add(item.id || item.jobId));
const delay = 50;
newItems.forEach((item, index) => {
setTimeout(() => {
dataSource.value.push(item);
}, index * delay);
});
},
{ immediate: true, deep: true } // 建议加上 deep虽然这里监听的是数组引用变化
newItems.forEach((item) => processedIds.add(item.id || item.jobId));
const delay = 50;
newItems.forEach((item, index) => {
setTimeout(() => {
dataSource.value.push(item);
}, index * delay);
});
},
{ immediate: true, deep: true } // 建议加上 deep虽然这里监听的是数组引用变化
);
function nextDetail(job) {
// 记录岗位类型,用作数据分析
if (job.jobCategory) {
const recordData = recommedIndexDb.JobParameter(job);
recommedIndexDb.addRecord(recordData);
}
navTo(`/packageA/pages/post/post?jobId=${btoa(job.jobId)}&dataType=1`);
// 记录岗位类型,用作数据分析
if (job.jobCategory) {
const recordData = recommedIndexDb.JobParameter(job);
recommedIndexDb.addRecord(recordData);
}
navTo(`/packageA/pages/post/post?jobId=${encodeURIComponent(job.jobId)}&dataType=1`);
}
</script>

View File

@@ -1,46 +1,52 @@
<template>
<view>
<!-- #ifdef H5 -->
<transition-group name="blur-fade-stagger" tag="view">
<view v-for="job in dataSource" :key="job.id" :style="{ '--i': 2 }">
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
<view class="card-company">
<text class="company">{{ job.gwmc }}</text>
<view class="salary">
<Salary-Expectation
:max-salary="job.maxSalary"
:min-salary="job.minSalary"
></Salary-Expectation>
</view>
</view>
<view class="card-companyName">{{ job.gsmc }}</view>
<view class="card-tags">
<view class="tag">
{{ job.xlyq == '不限' ? '学历不限' : job.xlyq }}
</view>
<view class="tag">
{{ job.gwgzjy == '不限' ? '经验不限' : job.gwgzjy }}
</view>
<view class="tag">
{{ vacanciesTo(job.zprs) }}
</view>
</view>
<view class="card-bottom">
<view>{{ parseDateTime(job.createTime).date }}</view>
<view>
<!-- <convert-distance
<!-- #endif -->
<view v-for="job in dataSource" :key="job.id" :style="{ '--i': 2 }">
<view v-if="!job.isTitle" class="cards" @click="nextDetail(job)">
<view class="card-company">
<text class="company">{{ job.gwmc }}</text>
<view class="salary">
<Salary-Expectation
:max-salary="job.maxSalary"
:min-salary="job.minSalary"
></Salary-Expectation>
</view>
</view>
<view class="card-companyName">{{ job.gsmc }}</view>
<view class="card-tags">
<view class="tag">
{{ job.xlyq == '不限' ? '学历不限' : job.xlyq }}
</view>
<view class="tag">
{{ job.gwgzjy == '不限' ? '经验不限' : job.gwgzjy }}
</view>
<view class="tag">
{{ vacanciesTo(job.zprs) }}
</view>
</view>
<view class="card-bottom">
<view>{{ parseDateTime(job.createTime).date }}</view>
<view>
<!-- <convert-distance
:alat="job.latitude"
:along="job.longitude"
:blat="latitude"
:blong="longitude"
></convert-distance>
<dict-Label class="mar_le10" dictType="area" :value="job.jobLocationAreaCode"></dict-Label> -->
</view>
</view>
</view>
<view class="date-jobTitle" v-else>
{{ job.title }}
</view>
</view>
</view>
<view class="date-jobTitle" v-else>
{{ job.title }}
</view>
</view>
<!-- #ifdef H5 -->
</transition-group>
<!-- #endif -->
</view>
</template>
<script setup>
@@ -50,76 +56,76 @@ import { useRecommedIndexedDBStore } from '@/stores/useRecommedIndexedDBStore.js
const recommedIndexDb = useRecommedIndexedDBStore();
const dataSource = ref([]);
const props = defineProps({
list: {
type: Array,
default: '标题',
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
list: {
type: Array,
default: '标题',
},
longitude: {
type: Number,
default: 120.382665,
},
latitude: {
type: Number,
default: 36.066938,
},
seeDate: {
type: String,
default: '',
},
});
const listData = computed(() => {
if (props.seeDate && props.list.length) {
const ulist = toRaw(props.list);
const [reslist, lastDate] = insertSortData(ulist, props.seeDate);
return reslist;
}
return props.list;
if (props.seeDate && props.list.length) {
const ulist = toRaw(props.list);
const [reslist, lastDate] = insertSortData(ulist, props.seeDate);
return reslist;
}
return props.list;
});
const processedIds = new Set();
watch(
() => props.list,
(newList) => {
if (!Array.isArray(newList)) return;
const newItems = newList.filter((item) => !processedIds.has(item.id));
if (newItems.length === 0) return;
newItems.forEach((item) => processedIds.add(item.id));
const delay = 50;
newItems.forEach((item, index) => {
setTimeout(() => {
dataSource.value.push(item);
}, index * delay);
});
},
{ immediate: true }
() => props.list,
(newList) => {
if (!Array.isArray(newList)) return;
const newItems = newList.filter((item) => !processedIds.has(item.id));
if (newItems.length === 0) return;
newItems.forEach((item) => processedIds.add(item.id));
const delay = 50;
newItems.forEach((item, index) => {
setTimeout(() => {
dataSource.value.push(item);
}, index * delay);
});
},
{ immediate: true }
);
function nextDetail(job) {
// 记录岗位类型,用作数据分析
if (job.jobCategory) {
const recordData = recommedIndexDb.JobParameter(job);
recommedIndexDb.addRecord(recordData);
}
navTo(`/packageA/pages/post/post?jobId=${btoa(job.id)}&dataType=2`);
// 记录岗位类型,用作数据分析
if (job.jobCategory) {
const recordData = recommedIndexDb.JobParameter(job);
recommedIndexDb.addRecord(recordData);
}
navTo(`/packageA/pages/post/post?jobId=${encodeURIComponent(job.id)}&dataType=2`);
}
function parseDateTime(datetimeStr) {
if (!datetimeStr) return { time: '', date: '' };
if (!datetimeStr) return { time: '', date: '' };
const dateObj = new Date(datetimeStr);
const dateObj = new Date(datetimeStr);
if (isNaN(dateObj.getTime())) return { time: '', date: '' }; // 无效时间
if (isNaN(dateObj.getTime())) return { time: '', date: '' }; // 无效时间
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
const day = String(dateObj.getDate()).padStart(2, '0');
const hours = String(dateObj.getHours()).padStart(2, '0');
const minutes = String(dateObj.getMinutes()).padStart(2, '0');
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
const day = String(dateObj.getDate()).padStart(2, '0');
const hours = String(dateObj.getHours()).padStart(2, '0');
const minutes = String(dateObj.getMinutes()).padStart(2, '0');
return {
time: `${hours}:${minutes}`,
date: `${year}-${month}-${day}`,
};
return {
time: `${hours}:${minutes}`,
date: `${year}-${month}-${day}`,
};
}
</script>