Browse Source

1.0.1完善

main
jiangAB 6 days ago
parent
commit
09db1caadf
  1. 199
      api/httpSetting.js
  2. 33
      api/index.js
  3. 551
      components/popup-drawer/popup-drawer.vue
  4. 67
      components/recruitment/recruitment.vue
  5. 275
      package-lock.json
  6. 5
      package.json
  7. 6
      pages.json
  8. 133
      pages/index/index.vue
  9. 98
      pages/my/my.vue
  10. 154
      pages/my/myFavorites.vue
  11. 1109
      pages/positionDetail/positionDetail.vue
  12. 78
      pages/searchPositions/searchPositions.vue
  13. BIN
      static/collect-active.png
  14. BIN
      static/collect-gray.png
  15. BIN
      static/comment.png
  16. 18
      utils/index.js

199
api/httpSetting.js

@ -1,114 +1,133 @@
// api.js
// 导入qs库
import qs from "qs";
// 基础URL,可以根据环境来设置
// uEnvDev
const accountInfo = wx.getAccountInfoSync();
// env类型 develop:开发版、trial:体验版、release:正式版
export const env = accountInfo.miniProgram.envVersion;
if (!env) {
console.error("获取运行环境失败!");
console.error("获取运行环境失败!");
}
const baseApi = {
// 开发版
develop: "http://110.40.156.216:30005/api",
// 体验版
trial: "http://110.40.156.216:30005/api",
// 正式版
release: "http://110.40.156.216:30005/api"
// 开发版
develop: "http://110.40.156.216:30005/api",
// 体验版
trial: "http://110.40.156.216:30005/api",
// 正式版
release: "http://110.40.156.216:30005/api",
};
console.log(env, 'env')
console.log(env, "env");
// request请求baseURL
const BASE_URL = baseApi[env] || 'http://110.40.156.216:30005/api';
const BASE_URL = baseApi[env] || "http://110.40.156.216:30005/api";
function request(url, method, data = {}) {
const loginRes = uni.getStorageSync('loginRes') || {};
const UTCOffset = new Date().getTimezoneOffset();
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + url, // 完整的URL
method: method,
data: data,
header: {
'AccessToken': loginRes.accessToken || '-1', // 请求头,可根据需要调整
'UserId': loginRes.appUserId || '-1', // 请求头,可根据需要调整
'LanguageType': 0,
},
success: (res) => {
if (res.statusCode === 200) {
console.log(res)
if (res.data.code === 200 | res.data.code === 0) {
resolve(res.data)
} else {
reject(res.data)
}
} else {
reject(res);
}
},
fail: (err) => {
uni.showToast({
title: '请求错误', // 提示的文本内容
icon: 'none', // 提示的图标,可选值:'success' | 'loading' | 'none'
duration: 2000 // 提示框的显示时间,单位为毫秒,默认1500ms
});
reject(err); // 请求失败
}
});
});
const loginRes = uni.getStorageSync("loginRes") || {};
const UTCOffset = new Date().getTimezoneOffset();
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + url, // 完整的URL
method: method,
data: data,
header: {
AccessToken: loginRes.accessToken || "-1", // 请求头,可根据需要调整
UserId: loginRes.appUserId || "-1", // 请求头,可根据需要调整
LanguageType: 0,
},
success: (res) => {
if (res.statusCode === 200) {
console.log(res);
if ((res.data.code === 200) | (res.data.code === 0)) {
resolve(res.data);
} else {
reject(res.data);
}
} else {
reject(res);
}
},
fail: (err) => {
uni.showToast({
title: "请求错误", // 提示的文本内容
icon: "none", // 提示的图标,可选值:'success' | 'loading' | 'none'
duration: 2000, // 提示框的显示时间,单位为毫秒,默认1500ms
});
reject(err); // 请求失败
},
});
});
}
// 使用uni.addInterceptor拦截请求,处理GET请求中的数组参数
uni.addInterceptor("request", {
invoke(args) {
// request 触发前拼接 url
const { data, method } = args;
if (method === "GET") {
// 如果是get请求,且params是数组类型如arr=[1,2],则转换成arr=1&arr=2
const newData = qs.stringify(data, {
arrayFormat: "repeat",
});
delete args.data;
args.url = `${args.url}?${newData}`;
}
},
success(args) {},
fail(err) {},
complete(res) {},
});
// GET 请求
export function get(url, params = {}) {
return request(url, 'GET', params);
return request(url, "GET", params);
}
// POST 请求
export function post(url, data = {}) {
return request(url, 'POST', data);
}
export function uploadFile(url, filePath = '', data = {}) {
const loginRes = uni.getStorageSync('loginRes') || {};
return new Promise((resolve, reject) => {
uni.uploadFile({
url: BASE_URL + url, // 完整的URL
filePath: filePath,
name: 'image',
header: {
'AccessToken': loginRes.accessToken || '-1', // 请求头,可根据需要调整
'UserId': loginRes.appUserId || '-1', // 请求头,可根据需要调整
LanguageType: 0,
// 其他需要的请求头信息(如Token)
},
formData: data,
success: (res) => {
if (res.statusCode === 200) {
if (res.data.code === 500) {
uni.showToast({
title: '系统错误', // 提示的文本内容
icon: 'none', // 提示的图标,可选值:'success' | 'loading' | 'none'
duration: 2000 // 提示框的显示时间,单位为毫秒,默认1500ms
});
}
if (res.data.code === 20001) {
reject(res.data);
}
resolve(res.data); // 返回数据
} else {
reject(res.data); // 返回错误信息
}
},
fail: (err) => {
uni.showToast({
title: '请求错误', // 提示的文本内容
icon: 'none', // 提示的图标,可选值:'success' | 'loading' | 'none'
duration: 2000 // 提示框的显示时间,单位为毫秒,默认1500ms
});
reject(err); // 请求失败
}
});
})
return request(url, "POST", data);
}
export function uploadFile(url, filePath = "", data = {}) {
const loginRes = uni.getStorageSync("loginRes") || {};
return new Promise((resolve, reject) => {
uni.uploadFile({
url: BASE_URL + url, // 完整的URL
filePath: filePath,
name: "image",
header: {
AccessToken: loginRes.accessToken || "-1", // 请求头,可根据需要调整
UserId: loginRes.appUserId || "-1", // 请求头,可根据需要调整
LanguageType: 0,
// 其他需要的请求头信息(如Token)
},
formData: data,
success: (res) => {
if (res.statusCode === 200) {
if (res.data.code === 500) {
uni.showToast({
title: "系统错误", // 提示的文本内容
icon: "none", // 提示的图标,可选值:'success' | 'loading' | 'none'
duration: 2000, // 提示框的显示时间,单位为毫秒,默认1500ms
});
}
if (res.data.code === 20001) {
reject(res.data);
}
resolve(res.data); // 返回数据
} else {
reject(res.data); // 返回错误信息
}
},
fail: (err) => {
uni.showToast({
title: "请求错误", // 提示的文本内容
icon: "none", // 提示的图标,可选值:'success' | 'loading' | 'none'
duration: 2000, // 提示框的显示时间,单位为毫秒,默认1500ms
});
reject(err); // 请求失败
},
});
});
}

33
api/index.js

@ -15,3 +15,36 @@ export const appserEditUser = (params ={}) => post('/app/user/editUser', params)
export const factoryMapGetListPage = (params ={}) => get('/app/factoryMap/getListPage', params);
export const factoryMapGetJobById = (factoryId, params ={}) => get(`/app/factoryMap/getJob/${factoryId}`, params);
export const tagGetListPage = (params ={}) => get('/app/job/getTags', params);
/**
* 获取收藏列表
*/
export const collectGetCollectList = (params ={}) => get('/collect/getCollectList', params);
/**
* 添加收藏
*/
export const collectAdd = (params ={}) => post('/collect/add', params);
/**
* 取消收藏
*/
export const collectCancel = (params ={}) => post('/collect/cancel', params);
/**
* 获取评论列表
*/
export const commentGetFirstLevelComment= (params ={}) => get('/comment/getFirstLevelComment', params);
/**
* 添加评论
*/
export const commentAdd = (params ={}) => post('/comment/add', params);
/**
* 删除评论
*/
export const commentDelete = (params ={}) => post('/comment/delete', params);

551
components/popup-drawer/popup-drawer.vue

@ -1,278 +1,273 @@
<template>
<view class="drawer-container">
<!-- 蒙层 -->
<!-- <view
class="mask"
:class="{ show: visibleInner && isFullScreen }"
:style="{ top: isFullScreen ? '0' : halfY + 'px' }"
@click="close"
/> -->
<!-- 抽屉 -->
<view
class="drawer"
:class="{
dragging: isDragging
}"
:style="{ transform: `translateY(${translateY}px)` }"
@touchstart="onStart"
@touchmove.stop.prevent="onMove"
@touchend="onEnd"
>
<!-- 顶部拖拽条 -->
<view class="header" @touchstart.stop="onStart">
<view class="bar"></view>
</view>
<!-- 内容 -->
<view class="content">
<slot></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: "PopupDrawer",
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
visibleInner: false,
//
isDragging: false,
startY: 0,
currentY: 0,
//
windowHeight: 0,
halfY: 0,
fullY: 0,
translateY: 0,
startTranslateY: 0,
//
isFullScreen: false
};
},
watch: {
visible: {
immediate: true,
handler(v) {
if (v) {
this.open();
} else {
this.close();
}
}
}
},
created() {
const res = uni.getSystemInfoSync();
this.windowHeight = res.windowHeight;
this.halfY = this.windowHeight * 0.5;
this.fullY = 0;
this.translateY = this.halfY;
},
methods: {
/** 打开 */
open() {
this.visibleInner = true;
this.isFullScreen = false; //
this.$nextTick(() => {
this.animateTo(this.halfY);
});
},
/** 关闭 */
close() {
this.isFullScreen = false;
this.animateTo(this.windowHeight, () => {
this.visibleInner = false;
this.$emit("update:visible", false);
this.$emit("close");
});
},
/** 手势开始 */
onStart(e) {
//
e.preventDefault();
e.stopPropagation();
this.isDragging = true;
this.startY = e.touches[0].clientY;
this.startTranslateY = this.translateY;
},
/** 手势移动 */
onMove(e) {
//
e.preventDefault();
e.stopPropagation();
if (!this.isDragging) return;
const moveY = e.touches[0].clientY - this.startY;
let newY = this.startTranslateY + moveY;
//
if (newY < 0) newY = 0;
if (newY > this.windowHeight) newY = this.windowHeight;
this.translateY = newY;
},
/** 手势结束(吸附逻辑) */
onEnd(e) {
e.preventDefault();
e.stopPropagation();
this.isDragging = false;
const moveY = e.changedTouches[0].clientY - this.startY;
// ---------------------------
// 1.
// ---------------------------
if (this.translateY === this.fullY) { // translateY = 0
// 80
if (moveY > 80) {
this.isFullScreen = false;
return this.animateTo(this.halfY);
}
//
if (moveY < -50) {
this.isFullScreen = true;
return this.animateTo(this.fullY);
}
}
// ---------------------------
// 2.
// ---------------------------
if (this.translateY >= this.halfY - 10 && this.translateY <= this.halfY + 10) {
//
if (moveY < -80) {
this.isFullScreen = true;
return this.animateTo(this.fullY);
}
//
if (moveY > 0 && moveY < 120) {
this.isFullScreen = false;
return this.animateTo(this.halfY);
}
}
// ---------------------------
// 3.
// ---------------------------
if (moveY > 120) {
this.isFullScreen = false;
return this.close();
}
// ---------------------------
// 4.
// ---------------------------
const points = [this.fullY, this.halfY];
let nearest = points.reduce((prev, curr) =>
Math.abs(curr - this.translateY) < Math.abs(prev - this.translateY) ? curr : prev
);
this.isFullScreen = (nearest === this.fullY);
this.animateTo(nearest);
},
/** 动画过渡(使用 RAF,不卡顿) */
animateTo(targetY, callback) {
//
const animation = uni.createAnimation({
duration: 250,
timingFunction: "cubic-bezier(0.25, 0.1, 0.25, 1)"
});
animation.translateY(targetY).step();
this.animationData = animation.export();
this.translateY = targetY;
if (callback) {
setTimeout(callback, 260);
}
}
}
};
</script>
<style lang="scss" scoped>
.drawer-container {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none; /* 默认不阻挡交互 */
z-index: 9999;
.mask {
position: absolute;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.45);
opacity: 0;
transition: opacity 0.25s;
pointer-events: auto; /* 蒙层接收交互 */
&.show {
opacity: 1;
}
}
.drawer {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #fff;
border-radius: 24rpx 24rpx 0 0;
transition: transform 0.25s ease-out;
pointer-events: auto; /* 抽屉部分接收交互 */
&.dragging {
transition: none !important;
}
.header {
width: 100%;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
.bar {
width: 120rpx;
height: 12rpx;
border-radius: 6rpx;
background: #ccc;
}
}
.content {
height: calc(100% - 80rpx);
overflow-y: auto;
}
}
}
</style>
<template>
<view class="drawer-container">
<!-- 蒙层 -->
<!-- <view
class="mask"
:class="{ show: visibleInner && isFullScreen }"
:style="{ top: isFullScreen ? '0' : halfY + 'px' }"
@click="close"
/> -->
<!-- 抽屉 -->
<view class="drawer" :class="{
dragging: isDragging
}" :style="{ transform: `translateY(${translateY}px)` }">
<!-- 顶部拖拽条 -->
<view class="header" @touchstart.stop="onStart" @touchmove.stop.prevent="onMove" @touchend="onEnd">
<view class="bar"></view>
</view>
<!-- 内容 -->
<view class="content">
<slot></slot>
</view>
</view>
</view>
</template>
<script>
export default {
name: "PopupDrawer",
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
visibleInner: false,
//
isDragging: false,
startY: 0,
currentY: 0,
//
windowHeight: 0,
halfY: 0,
fullY: 0,
translateY: 0,
startTranslateY: 0,
//
isFullScreen: false
};
},
watch: {
visible: {
immediate: true,
handler(v) {
if (v) {
this.open();
} else {
this.close();
}
}
}
},
created() {
const res = uni.getSystemInfoSync();
this.windowHeight = res.windowHeight;
this.halfY = this.windowHeight * 0.5;
this.fullY = 0;
//
this.translateY = this.windowHeight;
},
methods: {
/** 打开 */
open() {
this.visibleInner = true;
this.isFullScreen = false; //
this.$nextTick(() => {
this.animateTo(this.halfY);
});
},
/** 关闭 */
close() {
this.isFullScreen = false;
this.animateTo(this.windowHeight, () => {
this.visibleInner = false;
this.$emit("update:visible", false);
this.$emit("close");
});
},
/** 手势开始 */
onStart(e) {
//
e.preventDefault();
e.stopPropagation();
this.isDragging = true;
this.startY = e.touches[0].clientY;
this.startTranslateY = this.translateY;
},
/** 手势移动 */
onMove(e) {
//
e.preventDefault();
e.stopPropagation();
if (!this.isDragging) return;
const moveY = e.touches[0].clientY - this.startY;
let newY = this.startTranslateY + moveY;
//
if (newY < 0) newY = 0;
if (newY > this.windowHeight) newY = this.windowHeight;
this.translateY = newY;
},
/** 手势结束(吸附逻辑) */
onEnd(e) {
e.preventDefault();
e.stopPropagation();
this.isDragging = false;
const moveY = e.changedTouches[0].clientY - this.startY;
//
// ---------------------------
// 1.
// ---------------------------
if (this.isFullScreen) { // translateY = 0
if (moveY > 50) {
this.isFullScreen = false;
return this.animateTo(this.halfY);
}
//
if (moveY < -50) {
this.isFullScreen = true;
return this.animateTo(this.fullY);
}
}
// ---------------------------
// 2.
// ---------------------------
if (!this.isFullScreen) {
if (moveY < -80) {
this.isFullScreen = true;
return this.animateTo(this.fullY);
}
//
if (moveY > 0 && moveY < 50) {
this.isFullScreen = false;
return this.animateTo(this.halfY);
}
}
// ---------------------------
// 3.
// ---------------------------
if (moveY > 50 && !this.isFullScreen) {
this.isFullScreen = false;
return this.close();
}
// ---------------------------
// 4.
// ---------------------------
const points = [this.fullY, this.halfY];
let nearest = points.reduce((prev, curr) =>
Math.abs(curr - this.translateY) < Math.abs(prev - this.translateY) ? curr : prev
);
this.isFullScreen = (nearest === this.fullY);
this.animateTo(nearest);
},
/** 动画过渡(使用 RAF,不卡顿) */
animateTo(targetY, callback) {
//
const animation = uni.createAnimation({
duration: 250,
timingFunction: "cubic-bezier(0.25, 0.1, 0.25, 1)"
});
animation.translateY(targetY).step();
this.animationData = animation.export();
this.translateY = targetY;
if (callback) {
setTimeout(callback, 260);
}
}
}
};
</script>
<style lang="scss" scoped>
.drawer-container {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
/* 默认不阻挡交互 */
z-index: 9999;
.mask {
position: absolute;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.45);
opacity: 0;
transition: opacity 0.25s;
pointer-events: auto;
/* 蒙层接收交互 */
&.show {
opacity: 1;
}
}
.drawer {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #fff;
border-radius: 24rpx 24rpx 0 0;
transition: transform 0.25s ease-out;
pointer-events: auto;
/* 抽屉部分接收交互 */
&.dragging {
transition: none !important;
}
.header {
width: 100%;
height: 60rpx;
display: flex;
justify-content: center;
align-items: center;
.bar {
width: 120rpx;
height: 12rpx;
border-radius: 6rpx;
background: #ccc;
}
}
.content {
height: calc(100% - 80rpx);
overflow-y: auto;
}
}
}
</style>

67
components/recruitment/recruitment.vue

@ -2,8 +2,15 @@
<view class="recruitment-card">
<!-- 卡片头部信息 -->
<view class="card-head">
<div class="factory-info">
<h3 class="factory-name">{{dataSource.factoryName || '默认工厂'}}</h3>
<div class="factory-info">
<!-- view.header -->
<h3 class="factory-name">{{dataSource.factoryName || '默认工厂'}}</h3>
<view v-if="isFavorite" class="add-collect" @click="handleCancelCollect(dataSource.jobId)">
<image src='/static/collect-active.png' mode="widthFix"></image>
</view>
<view v-else class="add-collect" @click="handleCollect(dataSource.jobId)">
<image src="/static/collect-gray.png" mode="widthFix"></image>
</view>
<!-- <span class="factory-type">{{dataSource.factoryType || '电子厂'}}</span> -->
</div>
<div class="card-actions">
@ -22,8 +29,8 @@
<view class="work-info">
<text class="work-time">{{dataSource.workTime || '8:00-20:00'}}</text>
<text class="work-type">{{dataSource.gender}}</text>
<text class="work-content">{{dataSource.jobName || '主营汽车线束'}}</text>
<span v-if="!!dataSource.distanceMeters" class="distance">{{`距你${Math.round(dataSource.distanceMeters)}`}}</span>
<text class="work-content">{{dataSource.jobName || '主营汽车线束'}}</text>
<span v-if="!!dataSource.distanceMeters" class="distance">{{`距你${Math.round(dataSource.distanceMeters)}`}}</span>
<text v-for="item in dataSource.tags" class="work-type">{{item.tagName}}</text>
</view>
@ -45,7 +52,9 @@
</view>
</template>
<script>
<script>
import { collectAdd, collectCancel } from '../../api';
export default {
name: "recruitment",
props: {
@ -56,7 +65,7 @@
},
data() {
return {
isFavorite: false
isFavorite: !!this.dataSource.isCollect
};
},
computed: {
@ -92,7 +101,24 @@
return this.dataSource.companyData || this.companyData;
}
},
methods: {
methods: {
async handleCollect(jobId) {
console.log(jobId)
try {
await collectAdd({ jobId })
this.isFavorite = !this.isFavorite;
} catch(err) {
console.log(err)
}
},
async handleCancelCollect (jobId) {
try {
await collectCancel({ jobId })
this.isFavorite = !this.isFavorite;
} catch(err) {
console.log(err)
}
},
//
makeCall(e) {
e.stopPropagation();
@ -100,14 +126,11 @@
phoneNumber: this.dataSource.phoneNumber
});
},
//
toggleFavorite(e) {
e.stopPropagation();
this.isFavorite = !this.isFavorite;
},
handleGoToDetail(e) {
// dataSourceJSONURL
const encodedData = encodeURIComponent(JSON.stringify(this.dataSource));
uni.navigateTo({
url: '/pages/positionDetail/positionDetail'
url: `/pages/positionDetail/positionDetail?dataSource=${encodedData}`
})
}
}
@ -129,9 +152,21 @@
.factory-info {
width: 100%;
display: flex;
align-items: center;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-bottom: 8px;
margin-bottom: 8px;
.add-collect {
width: 48rpx;
height: 48rpx;
display: flex;
align-items: center;
justify-content: center;
image {
width: 100%;
height: 100%;
}
}
.factory-name {
font-size: 18px;
font-weight: 700;
@ -199,7 +234,7 @@
gap: 12px;
font-size: 12px;
color: #666;
margin-bottom: 12px;
margin-bottom: 12px;
flex-wrap: wrap;
}

275
package-lock.json

@ -0,0 +1,275 @@
{
"name": "laowumap",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"dependencies": {
"qs": "^6.14.0"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://repo.huaweicloud.com/repository/npm/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.4",
"resolved": "https://repo.huaweicloud.com/repository/npm/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://repo.huaweicloud.com/repository/npm/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://repo.huaweicloud.com/repository/npm/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://repo.huaweicloud.com/repository/npm/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://repo.huaweicloud.com/repository/npm/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
}
}
}

5
package.json

@ -0,0 +1,5 @@
{
"dependencies": {
"qs": "^6.14.0"
}
}

6
pages.json

@ -45,6 +45,12 @@
{
"navigationBarTitleText" : "登录"
}
},
{
"path": "pages/my/myFavorites",
"style": {
"navigationBarTitleText": "收藏岗位"
}
}
],

133
pages/index/index.vue

@ -1,6 +1,7 @@
<template>
<view class="index-page">
<map style="height: 100vh; width: 100vw;" id="myMap" :markers="markers" show-location show-compass
<map :latitude="defaultMapCenter.latitude" :longitude="defaultMapCenter.longitude"
style="height: 100vh; width: 100vw;" id="myMap" :markers="markers" show-location show-compass
@updated="handleMapLoad" @markertap="onMarkerTap"></map>
<view class="selectors-group">
<view class="distance-selector" @click="openDistancePicker">
@ -41,27 +42,23 @@
</picker-view>
</view>
<view class="rec-swiper">
<!-- <view class="rec-swiper">
<recruitment></recruitment>
</view>
</view> -->
<!-- 弹出层示例 -->
<popup-drawer :visible="showPopup" @update:visible="showPopup = $event" @close="onPopupClose">
<view class="popup-content">
<view class="popup-title">弹出层标题</view>
<!-- <view class="popup-title">弹出层标题</view> -->
<view class="popup-body">
<p>这是弹出层的内容区域</p>
<p>你可以在这里放置任何内容</p>
<p>按住顶部拖拽区域可以上拉至全屏</p>
<p>向下拉动可以关闭弹出层</p>
<template v-for="item in jobFromFactoryList">
<recruitment :dataSource="item"></recruitment>
<view class="driver"></view>
</template>
</view>
</view>
</popup-drawer>
<!-- 触发按钮 -->
<view class="trigger-button" @click="showPopup = true">
打开弹出层
</view>
</view>
</template>
@ -74,6 +71,7 @@
onLoad
} from '@dcloudio/uni-app'
import {
factoryMapGetJobById,
factoryMapGetListPage
} from '../../api';
import {
@ -86,15 +84,20 @@
const showRegionPicker = ref(false);
const selectedRegion = ref('江苏省');
const regionValue = ref(0);
const defaultMapCenter = ref({
latitude: null,
longitude: null
})
//
const showDistancePicker = ref(false);
const selectedDistance = ref(1); // 1km
const distanceValue = ref(0);
//
const showPopup = ref(false);
const jobFromFactoryList = ref([])
//
const distanceData = ref([{
label: '1',
@ -139,7 +142,7 @@
try {
const storedRegion = uni.getStorageSync('selectedRegionInfo');
if (storedRegion) {
return JSON.parse(storedRegion);
return storedRegion;
}
} catch (e) {
console.error('读取本地存储的地区信息失败', e);
@ -148,13 +151,9 @@
};
//
const setStoredRegionInfo = (province, label) => {
const setStoredRegionInfo = (value) => {
try {
const regionInfo = {
province,
label
};
uni.setStorageSync('selectedRegionInfo', JSON.stringify(regionInfo));
uni.setStorageSync('selectedRegionInfo', value);
} catch (e) {
console.error('保存地区信息到本地存储失败', e);
}
@ -193,7 +192,7 @@
showRegionPicker.value = false;
//
setStoredRegionInfo(province.label);
setStoredRegionInfo(province.value);
//
handleGetFactoryList(province.label);
@ -214,9 +213,8 @@
lat: null,
lng: null
}
const markers = ref([
{
id: 'default1',
const markers = ref([/* {
id: 1,
latitude: 31.230416,
longitude: 121.473701,
title: '默认点位1',
@ -230,7 +228,7 @@
}
},
{
id: 'default2',
id: 2,
latitude: 31.230416,
longitude: 121.473701,
title: '默认点位2',
@ -242,7 +240,7 @@
textAlign: 'center',
fontSize: 18,
}
}
} */
])
const handleGetFactoryList = async (province = '江苏省') => {
uni.showLoading({
@ -300,19 +298,62 @@
const onPopupClose = () => {
showPopup.value = false;
}
const onMarkerTap = (e) => {
const onPopupOpen = () => {
showPopup.value = true
}
const onMarkerTap = async (e) => {
const markerId = e.markerId;
console.log(markerId)
console.log(e)
onPopupOpen()
if (!(userLatLng.lat && userLatLng.lng)) {
userLatLng = await getLatLng()
}
const params = {
...(userLatLng.lat && userLatLng.lng ? userLatLng : {}),
}
try {
const res = await factoryMapGetJobById(markerId)
console.log(res)
jobFromFactoryList.value = res.data
} catch (err) {
console.log(err)
}
}
const handleMapLoad = async () => {
//
if (!(userLatLng.lat && userLatLng.lng)) {
userLatLng = await getLatLng();
}
//
if (userLatLng.lat && userLatLng.lng) {
//
// const mapContext = uni.createMapContext('myMap');
defaultMapCenter.value = {
latitude: userLatLng.lat,
longitude: userLatLng.lng
}
//
/* mapContext.includePoints({
points: [{latitude: userLatLng.lat, longitude: userLatLng.lng}],
padding: [100, 100, 100, 100] //
}); */
console.log('地图视角已设置为用户当前位置');
} else {
console.log('无法获取用户位置,使用默认视角');
}
}
onLoad(() => {
//
const storedRegion = getStoredRegionInfo();
if (storedRegion) {
// 使
selectedRegion.value = storedRegion.label;
handleGetFactoryList(storedRegion.province);
selectedRegion.value = storedRegion;
handleGetFactoryList(storedRegion);
} else {
// 使
handleGetFactoryList();
@ -326,6 +367,12 @@
overflow: hidden;
position: relative;
.driver {
width: 100%;
height: 1px;
background-color: #eee;
}
.selectors-group {
position: absolute;
top: 25rpx;
@ -434,7 +481,7 @@
border-radius: 16px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.trigger-button {
position: fixed;
bottom: 120rpx;
@ -448,25 +495,23 @@
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
z-index: 998;
}
.popup-content {
padding: 20rpx;
// padding: 20rpx;
}
.popup-title {
font-size: 36rpx;
font-weight: bold;
text-align: center;
margin-bottom: 30rpx;
}
.popup-body {
font-size: 28rpx;
line-height: 1.6;
}
.popup-body p {
margin-bottom: 20rpx;
box-sizing: border-box;
// padding: 15rpx;
}
}
</style>

98
pages/my/my.vue

@ -21,12 +21,12 @@
<!-- 功能区域 -->
<view class="features-section">
<view class="feature-item" @click="myComments">
<!-- <view class="feature-item" @click="myComments">
<view class="feature-icon">
<text class="icon-content">📝</text>
</view>
<text class="feature-name">我的评价</text>
</view>
</view> -->
<view class="feature-item" @click="myFavorites">
<view class="feature-icon">
@ -35,12 +35,12 @@
<text class="feature-name">收藏岗位</text>
</view>
<view class="feature-item" @click="contactService">
<button class="feature-item contact-button" open-type="contact" bindcontact="handleContact">
<view class="feature-icon">
<text class="icon-content">📞</text>
</view>
<text class="feature-name">咨询客服</text>
</view>
</button>
</view>
<!-- 底部占位避免内容被底部导航栏遮挡 -->
<view class="bottom-space"></view>
@ -51,6 +51,7 @@
import { computed } from 'vue';
import { useUserStore } from '../../stores/user.js';
import { appUserEditAvatar } from '../../api/index.js';
import { isLoggedIn } from '../../utils/index.js';
const userStore = useUserStore();
const loginRes = computed(() => userStore.loginRes);
const userInfo = computed(() => userStore.userInfo);
@ -63,6 +64,19 @@ const loginRegister = () => {
})
}
const myFavorites = () => {
if (!isLoggedIn()) {
uni.showToast({
title: '未登录',
icon: 'none'
})
}
uni.navigateTo({
url: '/pages/my/myFavorites'
})
}
const goToProfile = () => {
if (loginRes.value && loginRes.value.accessToken) {
//
@ -76,6 +90,63 @@ const goToProfile = () => {
})
}
}
const contactService = () => {
//
//
// 使uni.openCustomerServiceChat
// "url empty"
// 使
//
// #ifdef MP-WEIXIN
uni.openCustomerServiceChat({
extInfo: { url: '' }, //
corpId: '', // ID
success: (res) => {
console.log('打开客服聊天界面成功', res)
},
fail: (err) => {
console.error('打开客服聊天界面失败', err)
//
uni.showModal({
title: '提示',
content: '暂无法打开客服页面,您可以尝试拨打客服电话:400-xxx-xxxx',
showCancel: true,
cancelText: '取消',
confirmText: '拨打',
success: function (res) {
if (res.confirm) {
//
uni.makePhoneCall({
phoneNumber: '400-xxx-xxxx' //
})
}
}
})
}
})
// #endif
// #ifndef MP-WEIXIN
//
uni.showModal({
title: '联系我们',
content: '客服电话:400-xxx-xxxx\n服务时间:周一至周日 9:00-18:00',
showCancel: true,
cancelText: '取消',
confirmText: '拨打',
success: function (res) {
if (res.confirm) {
//
uni.makePhoneCall({
phoneNumber: '400-xxx-xxxx' //
})
}
}
})
// #endif
}
</script>
<style lang="scss">
@ -174,6 +245,25 @@ const goToProfile = () => {
background-color: #f0f9ff;
}
}
.contact-button {
background: transparent;
border: 0px!important;
outline: none;
padding: 0;
margin: 0;
width: auto;
height: auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
tap-highlight-color: transparent;
}
.contact-button::after {
border: 0px!important;
}
}
//

154
pages/my/myFavorites.vue

@ -0,0 +1,154 @@
<template>
<view class="favorites-page">
<scroll-view class="search-list" scroll-y :refresher-enabled="true" :refresher-triggered="refreshing"
@refresherrefresh="onRefresh" @scrolltolower="onLoadMore">
<template v-for="item in list" :key="item.jobId">
<recruitment :dataSource="item"></recruitment>
<view class="driver"></view>
</template>
<view class="loading-more">
<text v-if="loadingMore">加载中...</text>
<text v-else-if="noMoreData">没有更多数据了</text>
</view>
</scroll-view>
</view>
</template>
<script setup>
import {
onLoad
} from '@dcloudio/uni-app'
import {
collectCancel,
collectGetCollectList,
getAppJobVO, tagGetListPage
} from '../../api';
import {
ref
} from 'vue';
import {
delay
} from '../../utils';
let currentPage = 1
const list = ref([])
const refreshing = ref(false)
const loadingMore = ref(false)
const noMoreData = ref(false)
const pageSize = ref(10)
const hanleGetList = async (params = {}) => {
const res = await collectGetCollectList({
pageNum: currentPage,
pageSize: pageSize.value,
...params
})
console.log(res)
res.data.records = res.data.records.map((item) => ({
...item,
isCollect: true
}))
if (currentPage === 1) {
//
list.value = res.data.records
} else {
//
if (res.data.records.length > 0) {
list.value.records = [...list.value.records, ...res.data.records]
currentPage++
} else {
noMoreData.value = true
}
}
}
onLoad(() => {
currentPage = 1
hanleGetList()
})
const onRefresh = async () => {
console.log("刷新")
refreshing.value = true
loadingMore.value = false
noMoreData.value = false
try {
await delay(1000)
currentPage = 1
await hanleGetList()
} catch (err) {
console.log(err)
uni.showToast({
title: '刷新失败',
icon: 'none'
})
} finally {
refreshing.value = false
}
}
const onLoadMore = async () => {
//
console.log("dao dibule")
if (loadingMore.value || noMoreData.value) return
loadingMore.value = true
currentPage++
try {
await delay(1000)
await hanleGetList()
} catch (error) {
uni.showToast({
title: '加载失败',
icon: 'none'
})
currentPage--
} finally {
loadingMore.value = false
}
}
</script>
<style lang="scss">
.favorites-page {
//
height: 100vh;
display: flex;
flex-direction: column;
background-color: #f8f8f8;
// -
.search-list {
height: 100vh;
box-sizing: border-box;
padding: 4px;
// flex: 1;
// overflow-y: auto;
//
::-webkit-scrollbar {
display: none;
}
-ms-overflow-style: none;
scrollbar-width: none;
}
.driver {
width: 100%;
height: 1px;
background-color: #eee;
}
.loading-more {
text-align: center;
padding: 16px 0;
font-size: 14px;
color: #999;
}
}
</style>

1109
pages/positionDetail/positionDetail.vue

File diff suppressed because it is too large

78
pages/searchPositions/searchPositions.vue

@ -8,17 +8,13 @@
</view>
<!-- 搜索标签 -->
<view class="search-tags">
<view class="tag" :class="{ active: activeTag === '长白班' }" @click="onTagClick('长白班')">长白班</view>
<view class="tag" :class="{ active: activeTag === '高工资' }" @click="onTagClick('高工资')">高工资</view>
<view class="tag" :class="{ active: activeTag === '包吃住' }" @click="onTagClick('包吃住')">包吃住</view>
<view class="tag" :class="{ active: activeTag === '日结' }" @click="onTagClick('日结')">日结</view>
<view class="tag" :class="{ active: activeTag === '大龄工' }" @click="onTagClick('大龄工')">大龄工</view>
<view v-for="item in tagList" :key="item.tagId" class="tag" :class="{ active: activeTag.includes(item.tagId) }" @click="onTagClick(item.tagId)">{{ item.tagName || '标签' }}</view>
</view>
</view>
<scroll-view class="search-list" scroll-y :refresher-enabled="true" :refresher-triggered="refreshing"
@refresherrefresh="onRefresh" @scrolltolower="onLoadMore">
<template v-for="item in list.records" :key="item.jobId">
<template v-for="item in list" :key="item.jobId">
<recruitment :dataSource="item"></recruitment>
<view class="driver"></view>
</template>
@ -35,7 +31,7 @@
onLoad
} from '@dcloudio/uni-app'
import {
getAppJobVO
getAppJobVO, tagGetListPage
} from '../../api';
import {
ref
@ -50,6 +46,8 @@
const loadingMore = ref(false)
const noMoreData = ref(false)
const pageSize = ref(10)
const tagList = ref([])
const activeTag = ref([])
let userLatLng = {
lat: null,
lng: null
@ -69,7 +67,7 @@
if (currentPage === 1) {
//
list.value = res.data
list.value = res.data.records
} else {
//
@ -82,10 +80,26 @@
}
}
const handleGetTag = async () => {
const { data } = await tagGetListPage()
tagList.value = data
}
const onTagClick = (tagId) => {
//
const index = activeTag.value.indexOf(tagId);
if (index > -1) {
activeTag.value.splice(index, 1);
} else {
activeTag.value.push(tagId);
}
onSearch()
}
onLoad(() => {
currentPage = 1
hanleGetJobList()
handleGetTag()
})
@ -108,23 +122,6 @@
} finally {
refreshing.value = false
}
/* refreshing.value = true
currentPage.value = 1
noMoreData.value = false
try {
await hanleGetJobList()
uni.showToast({
title: '刷新成功',
icon: 'success'
})
} catch (error) {
uni.showToast({
title: '刷新失败',
icon: 'none'
})
} finally {
refreshing.value = false
} */
}
const onLoadMore = async () => {
@ -152,39 +149,14 @@
const onSearch = () => {
console.log(searchKeyword.value)
const params = {
keyword: searchKeyword.value
keyword: searchKeyword.value,
tagIds: activeTag.value // get
}
//
currentPage = 1
noMoreData.value = false
hanleGetJobList(params)
}
/* // 导入recruitment组件
import recruitment from '@/components/recruitment/recruitment.vue';
export default {
//
components: {
recruitment
},
data() {
return {
searchKeyword: '',
activeTag: ''
}
},
methods: {
//
onSearch() {
//
console.log('搜索关键词:', this.searchKeyword);
},
//
onTagClick(tag) {
this.activeTag = this.activeTag === tag ? '' : tag;
console.log('点击标签:', tag);
}
}
} */
</script>
<style lang="scss">

BIN
static/collect-active.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
static/collect-gray.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
static/comment.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

18
utils/index.js

@ -35,4 +35,20 @@ export function getLatLng() {
// console.log('开始');
// await delay(2000); // 延时 2 秒
// console.log('2秒后执行');
// }
// }
/**
* 判断用户是否已登录
* @returns {boolean} - 返回用户是否已登录
*/
export function isLoggedIn() {
try {
// 从loginRes中读取token,与user.js中的登录存储逻辑保持一致
const loginRes = uni.getStorageSync('loginRes');
console.log(loginRes)
return !!(loginRes && loginRes.accessToken); // 确保loginRes存在且包含token
} catch (error) {
console.error('检查登录状态时出错:', error);
return false;
}
}
Loading…
Cancel
Save