lsw 10 tháng trước cách đây
mục cha
commit
7539b1e87a

+ 1 - 1
app/App.vue

@@ -30,7 +30,7 @@ button::after {
 /**挂载iconfont字体图标*/
 @font-face {
 	font-family: 'iconfont';
-	src: url('https://at.alicdn.com/t/c/font_4507607_9c1mwi5mgz.ttf?t=1717727595574') format('truetype');
+	src: url('https://at.alicdn.com/t/c/font_4507607_i7so1emprg.ttf?t=1718172901995') format('truetype');
 	/* src: url('~@/static/font/iconfont.ttf') format('truetype'); */
 }
 .icon {

+ 30 - 72
app/common/common.scss

@@ -50,7 +50,6 @@
 	font-size: 14px;
 	text-align: center;
 	padding: 5px;
-	box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.2);
 	margin-top: 15px;
 }
 .form_group {
@@ -207,93 +206,44 @@
 		padding-top: 5px;
 	}
 }
-.jobs {
-	margin-top: 10px;
-	margin-left: -6px;
-	margin-right: -6px;
-	.full_time {
-		float: left;
-		width: 50%;
-		.out {
-			padding: 6px;
-			.int {
-				padding: 10px;
-				background-color: white;
-				overflow: hidden;
-				border-radius: 7px;
-				box-shadow: $box-shadow;
-				image {
-					width: 100%;
-					height: 100px;
-				}
-				.title {
-					font-size: 14px;
-					padding-top: 3px;
-					font-weight: bold;
-				}
-				.desc {
-					font-size: 13px;
-					padding-top: 3px;
-				}
-				.price {
-					padding-top: 3px;
-					font-size: 14px;
-					font-weight: bold;
-					color: #ff5722;
-				}
-				.address {
-					padding-top: 3px;
-					font-size: 12px;
-					color: $font-c;
-					.icon {
-						padding-right: 2px;
-					}
-				}
-			}
-		}
-	}
-	.part_time {
-		padding: 10px;
-		background-color: white;
+.item_job {
+	padding: 10px;
+	background-color: white;
+	overflow: hidden;
+	border-radius: 7px;
+	margin-bottom: 10px;
+	.top {
 		overflow: hidden;
-		border-radius: 7px;
-		margin-bottom: 10px;
 		.title {
 			font-size: 14px;
 			padding-top: 3px;
 			font-weight: bold;
+			float: left;
+			width: 70%;
 		}
-		.date {
-			font-size: 13px;
-			padding: 1px 8px;
-			background-color: #e3e3e3;
-			border-radius: 4px;
-			margin-top: 5px;
-			color: white;
-		}
-		.price {
+		.salary {
 			padding-top: 5px;
 			font-size: 15px;
 			font-weight: bold;
 			color: #ff5722;
 			margin-bottom: 5px;
+			float: right;
 		}
+	}
+	.bot {
+		border-top: 1px solid $line;
+		font-size: 12px;
+		color: $font-c;
+		padding-top: 10px;
 		.address {
-			padding-top: 10px;
-			font-size: 12px;
-			color: $font-c;
-			border-top: 1px solid $line;
-			margin-top: 12px;
+			float: left;
+			width: 70%;
 			.icon {
 				padding-right: 2px;
 			}
-			.add {
-				float: right;
-				color: white;
-				background-color: $main-color;
-				padding: 3px 20px;
-				border-radius: 20px;
-			}
+		}
+		.distance {
+			float: right;
 		}
 	}
 }
@@ -525,3 +475,11 @@
 .danger {
 	color: #f44336;
 }
+.filters {
+	float: right;
+	margin-top: -32px;
+	color: $font-c;
+	.icon {
+		padding-right: 3px;
+	}
+}

+ 25 - 4
app/common/util.js

@@ -7,7 +7,7 @@ function formatTime(time) {
 	var minute = parseInt(time / 60)
 	time = time % 60
 	var second = time
-	return ([hour, minute, second]).map(function(n) {
+	return ([hour, minute, second]).map(function (n) {
 		n = n.toString()
 		return n[1] ? n : '0' + n
 	}).join(':')
@@ -196,10 +196,30 @@ const getData = (obj = 'education') => {
 		return ["0-20人", "20-99人", "100-499人", "500-999人", "1000-9999人", "10000人以上"]
 	}
 	// 结算方式
-	if(obj == 'unit') {
-		return ["日结", "单结",]
+	if (obj == 'unit') {
+		return ["日结", "单结", ]
 	}
 }
+const toRadians = (degree) => {
+	return degree * Math.PI / 180;
+}
+const distance = (latitude1, longitude1, latitude2, longitude2) => {
+	var R = 6371;
+	var deltaLatitude = toRadians(latitude2 - latitude1);
+	var deltaLongitude = toRadians(longitude2 - longitude1);
+	latitude1 = toRadians(latitude1);
+	latitude2 = toRadians(latitude2);
+	var a = Math.sin(deltaLatitude / 2) *
+		Math.sin(deltaLatitude / 2) +
+		Math.cos(latitude1) *
+		Math.cos(latitude2) *
+		Math.sin(deltaLongitude / 2) *
+		Math.sin(deltaLongitude / 2);
+	var c = 2 * Math.atan2(Math.sqrt(a),
+		Math.sqrt(1 - a));
+	var d = R * c;
+	return d;
+}
 /**
  * 格式化时间
  */
@@ -226,5 +246,6 @@ module.exports = {
 	getDate: getDate,
 	getDaysBetween: getDaysBetween,
 	getdiffdate: getdiffdate,
-	getData: getData
+	getData: getData,
+	distance: distance
 }

+ 130 - 0
app/components/filters/filters.vue

@@ -0,0 +1,130 @@
+<template>
+	<u-popup :show="value" @close="close()" round="15">
+		<view class="ppopup">
+			<u-divider text="条件筛选"></u-divider>
+			<scroll-view scroll-y="true" style="height: 450px">
+				<view class="item">
+					<view class="title">薪资待遇</view>
+					<view class="tags" v-for="(item, index) in salary" :key="item.index" @click="select('salary', item, index)">
+						<view class="out">
+							<view class="int" :class="{ active: item.check }">{{ item.name }}</view>
+						</view>
+					</view>
+				</view>
+				<view class="item">
+					<view class="title">经验要求</view>
+					<view class="tags" v-for="(item, index) in experience" :key="item.name" @click="select('experience', item, index)">
+						<view class="out">
+							<view class="int" :class="{ active: item.check }">{{ item.name }}</view>
+						</view>
+					</view>
+				</view>
+			</scroll-view>
+			<view class="flex">
+				<view class="f">
+					<button class="btn ex" @click="clear()">清除</button>
+				</view>
+				<view class="f">
+					<button class="btn" @click="confirm()">确认</button>
+				</view>
+			</view>
+		</view>
+	</u-popup>
+</template>
+
+<script>
+export default {
+	name: 'filters',
+	props: {
+		value: {
+			type: Boolean,
+			default: true
+		},
+		list: {
+			type: Array
+		}
+	},
+	data() {
+		return {
+			type: 0,
+			show: true,
+			experience: [{ name: '不限' }, { name: '1年以内' }, { name: '1-3年' }, { name: '3-5年' }, { name: '5-10年' }, { name: '10年以上' }],
+			salary: [{ name: '不限' }, { name: '1-3k' }, { name: '3-5k' }, { name: '5-10k' }, { name: '10-20k' }, { name: '20-50k' }, { name: '50k以上' }]
+		};
+	},
+	watch: {
+		value(newValue) {
+			this.show = newValue;
+		}
+	},
+	methods: {
+		select(tag, item, index) {
+			if (tag == 'salary') {
+				this.salary.forEach((i) => (i.check = false));
+				item.check = true;
+			} else {
+				if (index == 0) {
+					this[tag].forEach((i) => (i.check = false));
+					item.check = true;
+				} else {
+					this[tag][0].check = false;
+					item.check = !item.check;
+				}
+			}
+			this.$forceUpdate();
+		},
+		confirm(item) {
+			this.$emit('input', false);
+			this.$emit('confirm', {
+				experience: this.experience.filter((item) => item.check && item.name != '不限'),
+				salary: this.salary.filter((item) => item.check)
+			});
+		},
+		clear() {
+			this.salary.forEach((i) => (i.check = false));
+			this.experience.forEach((i) => (i.check = false));
+			this.$forceUpdate();
+		},
+		close() {
+			this.show = false;
+			this.$emit('input', false);
+		}
+	}
+};
+</script>
+
+<style lang="scss">
+.ppopup {
+	padding: 10px;
+	.title {
+		font-size: 17px;
+		margin-top: 12px;
+		margin-bottom: 12px;
+		font-weight: bold;
+		padding-left: 5px;
+	}
+	.item {
+		overflow: hidden;
+		.tags {
+			width: 33.33%;
+			.int {
+				&.active {
+					background-color: $main-color;
+					color: white;
+				}
+			}
+		}
+	}
+	.f {
+		margin: 7px;
+		.btn {
+			margin-top: 10px;
+			padding: 0px;
+		}
+		.ex {
+			background-color: #f3f3f3;
+			color: #6b6b6b;
+		}
+	}
+}
+</style>

+ 3 - 0
app/main.js

@@ -19,6 +19,9 @@ App.mpType = 'app'
 Vue.prototype.getUser = function() {
 	return uni.getStorageSync('user');
 }
+Vue.prototype.getLocation = function() {
+	return uni.getStorageSync('location');
+}
 Vue.prototype.hasPermi = util.hasPermi;
 Vue.prototype.hasLogin = () => {
 	if (uni.getStorageSync('user') === '' || uni.getStorageSync('user') === null) {

+ 126 - 121
app/manifest.json

@@ -1,122 +1,127 @@
 {
-	"name": "国医瑾明",
-	"appid": "__UNI__6E1FB4F",
-	"description": "",
-	"versionName": "1.0.3",
-	"versionCode": 103,
-	"transformPx": false,
-	/* 5+App特有相关 */
-	"app-plus": {
-		"usingComponents": true,
-		"nvueStyleCompiler": "uni-app",
-		"compilerVersion": 3,
-		"splashscreen": {
-			"alwaysShowBeforeRender": true,
-			"waiting": true,
-			"autoclose": true,
-			"delay": 0
-		},
-		/* 模块配置 */
-		"modules": {
-			"VideoPlayer": {},
-			"Camera": {}
-		},
-		/* 应用发布信息 */
-		"distribute": {
-			/* android打包配置 */
-			"android": {
-				"permissions": [
-					"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
-					"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
-					"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
-					"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
-					"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
-					"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.CAMERA\"/>",
-					"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
-					"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
-					"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
-					"<uses-feature android:name=\"android.hardware.camera\"/>",
-					"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
-					"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />",
-					"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />"
-				]
-			},
-			/* ios打包配置 */
-			"ios": {
-				"dSYMs": false
-			},
-			/* SDK配置 */
-			"sdkConfigs": {
-				"ad": {},
-				"maps": {
-					"amap": {
-						"name": "clsd",
-						"appkey_ios": "",
-						"appkey_android": ""
-					}
-				}
-			},
-			"icons": {
-				"android": {
-					"hdpi": "unpackage/res/icons/72x72.png",
-					"xhdpi": "unpackage/res/icons/96x96.png",
-					"xxhdpi": "unpackage/res/icons/144x144.png",
-					"xxxhdpi": "unpackage/res/icons/192x192.png"
-				},
-				"ios": {
-					"appstore": "unpackage/res/icons/1024x1024.png",
-					"ipad": {
-						"app": "unpackage/res/icons/76x76.png",
-						"app@2x": "unpackage/res/icons/152x152.png",
-						"notification": "unpackage/res/icons/20x20.png",
-						"notification@2x": "unpackage/res/icons/40x40.png",
-						"proapp@2x": "unpackage/res/icons/167x167.png",
-						"settings": "unpackage/res/icons/29x29.png",
-						"settings@2x": "unpackage/res/icons/58x58.png",
-						"spotlight": "unpackage/res/icons/40x40.png",
-						"spotlight@2x": "unpackage/res/icons/80x80.png"
-					},
-					"iphone": {
-						"app@2x": "unpackage/res/icons/120x120.png",
-						"app@3x": "unpackage/res/icons/180x180.png",
-						"notification@2x": "unpackage/res/icons/40x40.png",
-						"notification@3x": "unpackage/res/icons/60x60.png",
-						"settings@2x": "unpackage/res/icons/58x58.png",
-						"settings@3x": "unpackage/res/icons/87x87.png",
-						"spotlight@2x": "unpackage/res/icons/80x80.png",
-						"spotlight@3x": "unpackage/res/icons/120x120.png"
-					}
-				}
-			}
-		}
-	},
-	/* 快应用特有相关 */
-	"quickapp": {},
-	/* 小程序特有相关 */
-	"mp-weixin": {
-		"appid": "wxf07c98cd41e54b21",
-		"setting": {
-			"urlCheck": false,
-			"minified": true
-		},
-		"usingComponents": true,
-		"requiredPrivateInfos": ["chooseLocation", "getLocation"]
-	},
-	"mp-alipay": {
-		"usingComponents": true
-	},
-	"mp-baidu": {
-		"usingComponents": true
-	},
-	"mp-toutiao": {
-		"usingComponents": true
-	},
-	"uniStatistics": {
-		"enable": false
-	},
-	"vueVersion": "2"
-}
+    "name" : "国医瑾明",
+    "appid" : "__UNI__6E1FB4F",
+    "description" : "",
+    "versionName" : "1.0.3",
+    "versionCode" : 103,
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "usingComponents" : true,
+        "nvueStyleCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        /* 模块配置 */
+        "modules" : {
+            "VideoPlayer" : {},
+            "Camera" : {}
+        },
+        /* 应用发布信息 */
+        "distribute" : {
+            /* android打包配置 */
+            "android" : {
+                "permissions" : [
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />",
+                    "<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />"
+                ]
+            },
+            /* ios打包配置 */
+            "ios" : {
+                "dSYMs" : false
+            },
+            /* SDK配置 */
+            "sdkConfigs" : {
+                "ad" : {},
+                "maps" : {
+                    "amap" : {
+                        "name" : "clsd",
+                        "appkey_ios" : "",
+                        "appkey_android" : ""
+                    }
+                }
+            },
+            "icons" : {
+                "android" : {
+                    "hdpi" : "unpackage/res/icons/72x72.png",
+                    "xhdpi" : "unpackage/res/icons/96x96.png",
+                    "xxhdpi" : "unpackage/res/icons/144x144.png",
+                    "xxxhdpi" : "unpackage/res/icons/192x192.png"
+                },
+                "ios" : {
+                    "appstore" : "unpackage/res/icons/1024x1024.png",
+                    "ipad" : {
+                        "app" : "unpackage/res/icons/76x76.png",
+                        "app@2x" : "unpackage/res/icons/152x152.png",
+                        "notification" : "unpackage/res/icons/20x20.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "proapp@2x" : "unpackage/res/icons/167x167.png",
+                        "settings" : "unpackage/res/icons/29x29.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "spotlight" : "unpackage/res/icons/40x40.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png"
+                    },
+                    "iphone" : {
+                        "app@2x" : "unpackage/res/icons/120x120.png",
+                        "app@3x" : "unpackage/res/icons/180x180.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "notification@3x" : "unpackage/res/icons/60x60.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "settings@3x" : "unpackage/res/icons/87x87.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png",
+                        "spotlight@3x" : "unpackage/res/icons/120x120.png"
+                    }
+                }
+            }
+        }
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "wxf07c98cd41e54b21",
+        "setting" : {
+            "urlCheck" : false,
+            "minified" : true
+        },
+        "usingComponents" : true,
+        "requiredPrivateInfos" : [ "chooseLocation", "getLocation" ],
+        "permission" : {
+            "scope.userLocation" : {
+                "desc" : "你的位置信息讲用于获取职位地址与你位置距离"
+            }
+        }
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    },
+    "vueVersion" : "2"
+}

+ 25 - 32
app/pages.json

@@ -130,59 +130,52 @@
 			}
 		},
 		{
-			"path" : "pages/job/position/classification",
-			"style" : 
-			{
-				"navigationBarTitleText" : "选择职位"
+			"path": "pages/job/position/classification",
+			"style": {
+				"navigationBarTitleText": "选择职位"
 			}
 		},
 		{
-			"path" : "pages/job/position/city",
-			"style" : 
-			{
-				"navigationBarTitleText" : "选择城市"
+			"path": "pages/job/position/city",
+			"style": {
+				"navigationBarTitleText": "选择城市"
 			}
 		},
 		{
-			"path" : "pages/user/enterprise/index",
-			"style" : 
-			{
-				"navigationBarTitleText" : "企业认证"
+			"path": "pages/user/enterprise/index",
+			"style": {
+				"navigationBarTitleText": "企业认证"
 			}
 		},
 		{
-			"path" : "pages/job/position/manage/list",
-			"style" : 
-			{
-				"navigationBarTitleText" : "职位管理"
+			"path": "pages/job/position/manage/list",
+			"style": {
+				"navigationBarTitleText": "职位管理"
 			}
 		},
 		{
-			"path" : "pages/job/position/manage/push",
-			"style" : 
-			{
-				"navigationBarTitleText" : "职位发布"
+			"path": "pages/job/position/manage/push",
+			"style": {
+				"navigationBarTitleText": "职位发布"
 			}
 		},
 		{
-			"path" : "pages/news/index",
-			"style" : 
-			{
-				"navigationBarTitleText" : "新闻资讯"
+			"path": "pages/news/index",
+			"style": {
+				"navigationBarTitleText": "新闻资讯"
 			}
 		},
 		{
-			"path" : "pages/news/detail",
-			"style" : 
-			{
-				"navigationBarTitleText" : "新闻详情"
+			"path": "pages/news/detail",
+			"style": {
+				"navigationBarTitleText": "新闻详情"
 			}
 		},
 		{
-			"path" : "pages/job/list",
-			"style" : 
-			{
-				"navigationBarTitleText" : "全职"
+			"path": "pages/job/list",
+			"style": {
+				"navigationBarTitleText": "全职",
+				"enablePullDownRefresh": true
 			}
 		}
 	],

+ 17 - 0
app/pages/index/index.vue

@@ -118,6 +118,7 @@ export default {
 		};
 	},
 	onShow() {
+		this.getLocation();
 		if (this.hasLogin()) {
 			//this.getUserInfo();
 		}
@@ -132,6 +133,22 @@ export default {
 		});
 	},
 	methods: {
+		getLocation() {
+			uni.authorize({
+				scope: 'scope.userLocation',
+				success: (s) => {
+					uni.getLocation({
+						type: 'wgs84',
+						success: (res) => {
+							uni.setStorageSync('location', res);
+						}
+					});
+				},
+				fail(res) {
+					uni.showModal({ title: '提示', content: '定位失败,请检查是否允许定位', showCancel: false });
+				}
+			});
+		},
 		detail() {
 			uni.navigateTo({
 				url: '/pages/clsd/job/detail'

+ 39 - 28
app/pages/job/list.vue

@@ -1,24 +1,34 @@
 <template>
 	<view class="main">
-		<!--搜索-->
 		<view class="search">
-			<u-search placeholder="企业名称" bgColor="white" :showAction="false"></u-search>
+			<u-search placeholder="职位名称" bgColor="white" :showAction="false"></u-search>
 		</view>
-		<!--找工作-->
 		<view class="tab">
-			<u-tabs :list="tab"></u-tabs>
+			<u-tabs :list="tab" @click="tabClick"></u-tabs>
+			<view class="filters" @click="show = true">
+				<text class="icon">&#xe68c;</text>
+				<text>筛选</text>
+			</view>
 		</view>
-		<view class="jobs">
-			<view class="part_time" v-for="(item, index) in list" :key="index" @click="detail()">
-				<view class="title omit">{{ item.title }}</view>
-				<view class="price">{{ item.price }}元/天</view>
-				<text class="date">4.16-4.17</text>
-				<view class="address">
-					<text @click.stop="company()">{{ item.name }}</text>
-					<text class="add">申请</text>
+		<view class="list">
+			<view class="item_job" v-for="(item, index) in list" :key="index" @click="detail()">
+				<view class="top">
+					<view class="title omit">{{ item.title }}</view>
+					<view class="salary">{{ item.salary }}</view>
+				</view>
+				<view class="bot">
+					<view class="address omit">
+						<text>{{ item.regionName }}</text>
+						<text class="icon">&#xe757;</text>
+						<text>{{ item.location }}</text>
+					</view>
+					<view class="distance" v-if="item.distance">距离你{{ item.distance }}km</view>
 				</view>
 			</view>
+			<view class="loading" v-if="loadMore"><u-loadmore :status="loadMore ? 'loading' : 'nomore'" /></view>
+			<u-empty v-if="!loadMore && list.length == 0"></u-empty>
 		</view>
+		<filters v-model="show" @confirm="confirm"></filters>
 	</view>
 </template>
 <script>
@@ -26,15 +36,20 @@ export default {
 	data() {
 		return {
 			tab: [
-				{ name: '最新', value: 0 },
-				{ name: '附近', value: 1 }
+				{ name: '最新', orderBy: 'id' },
+				{ name: '附近', orderBy: 'distance' }
 			],
 			list: [],
-			param: { pageNum: 1, pageSize: 10, type: 0 },
-			loadMore: true
+			param: { pageNum: 1, pageSize: 10, type: 0, orderBy: 'id' },
+			loadMore: true,
+			show: false
 		};
 	},
 	onLoad(e) {
+		if (this.getLocation()) {
+			this.param.latitude = this.getLocation().latitude;
+			this.param.longitude = this.getLocation().longitude;
+		}
 		this.getData();
 	},
 	methods: {
@@ -49,15 +64,15 @@ export default {
 				}
 			});
 		},
-		click(e, tag) {
-			this.param[tag] = this[tag][e.index].value;
-			if (tag == 'audit') {
-				this.current = e.index;
-			}
+		tabClick(e) {
+			this.param.orderBy = e.orderBy;
 			this.refresh();
 		},
-		selectClick(e) {
-			uni.navigateTo({ url: '/pages/job/position/manage/push?type=' + e.value });
+		confirm(e) {
+			this.param.educationList = e.education.map((item) => item.name);
+			this.param.salary = e.salary.map((item) => item.name).toString();
+			this.param.experienceList = e.experience.map((item) => item.name);
+			//this.refresh();
 		},
 		detail(item) {
 			uni.navigateTo({ url: '/pages/job/position/manage/push?id=' + item.id });
@@ -87,8 +102,4 @@ export default {
 };
 </script>
 
-<style lang="scss">
-.jobs {
-	margin-top: 0px;
-}
-</style>
+<style lang="scss"></style>

+ 1 - 1
app/pages/job/position/manage/push.vue

@@ -131,7 +131,7 @@ export default {
 					//注意区分直辖市;
 					let city = addressList.length >= 3 ? addressList[1] : addressList[0];
 					let region = addressList.length >= 3 ? addressList[2] : addressList[1];
-					this.item.this.item.location = res.name;
+					this.item.location = res.name;
 					this.item.address = res.address;
 					this.item.longitude = res.longitude;
 					this.item.latitude = res.latitude;

+ 4 - 3
ruoyi-admin/src/main/java/com/ruoyi/web/work/api/Api_PositionController.java

@@ -5,7 +5,9 @@ import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.web.work.api.config.BaseController;
 import com.ruoyi.web.work.domain.Position;
 import com.ruoyi.web.work.domain.dto.PositionDto;
+import com.ruoyi.web.work.domain.dto.PositionQueryDto;
 import com.ruoyi.web.work.domain.dto.PositionStateDto;
+import com.ruoyi.web.work.domain.vo.PositionListVo;
 import com.ruoyi.web.work.service.IPositionService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
@@ -26,15 +28,14 @@ public class Api_PositionController extends BaseController {
     private IPositionService positionService;
 
     @GetMapping("/list")
-    public TableDataInfo list(Position position) {
+    public TableDataInfo list(@Validated PositionQueryDto dto) {
         startPage();
-        List<Position> list = positionService.indexList(position);
+        List<PositionListVo> list = positionService.indexList(dto);
         return getDataTable(list);
     }
 
     @GetMapping("/manage/list")
     public TableDataInfo manageList(Position position) {
-        position.setUserId(getUser().getId());
         startPage();
         List<Position> list = positionService.manageList(position);
         return getDataTable(list);

+ 13 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/Position.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.annotation.FieldFill;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.ruoyi.web.work.domain.base.BaseData;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.experimental.Accessors;
@@ -20,7 +22,7 @@ import java.util.Date;
 @Data
 @TableName(value = "tb_position")
 @Accessors(chain = true)
-public class Position{
+public class Position extends BaseData {
     private static final long serialVersionUID = 1L;
 
     private Long id;
@@ -120,4 +122,14 @@ public class Position{
     private Integer status;
 
 
+    @TableField(exist = false)
+    @JsonIgnore
+    private String regionId;
+
+    @TableField(exist = false)
+    private String distance;
+
+    @TableField(exist = false)
+    @JsonIgnore
+    private String orderBy;
 }

+ 38 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/dto/PositionQueryDto.java

@@ -0,0 +1,38 @@
+package com.ruoyi.web.work.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+
+/**
+ * @author lsw
+ * @date 2024-06-07
+ */
+@Data
+@Accessors(chain = true)
+public class PositionQueryDto {
+
+    @NotNull(message = "职位类型为空")
+    @Min(value = 0, message = "type 只能是 0 或者 1")
+    @Max(value = 1, message = "type 只能是 0 或者 1")
+    private Integer type;
+
+    @ApiModelProperty(value = "职位名称")
+    private String title;
+
+    @ApiModelProperty(value = "经度")
+    private String longitude;
+
+    @ApiModelProperty(value = "维度")
+    private String latitude;
+
+    @NotNull(message = "参数错误")
+    @Pattern(regexp = "^(id|distance)$", message = "orderBy 参数值只能是 id 或 distance")
+    private String orderBy;
+
+}

+ 35 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/vo/PositionListVo.java

@@ -0,0 +1,35 @@
+package com.ruoyi.web.work.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @author lsw
+ * @date 2024-06-07
+ */
+@Data
+@Accessors(chain = true)
+public class PositionListVo{
+
+    private Long id;
+
+    @ApiModelProperty(value = "职位名称")
+    private String title;
+
+    @ApiModelProperty(value = "经验要求")
+    private String experience;
+
+    @ApiModelProperty(value = "薪资范围")
+    private String salary;
+
+    @ApiModelProperty(value = "地区名称")
+    private String regionName;
+
+    @ApiModelProperty(value = "地点名")
+    private String location;
+
+    @ApiModelProperty(value = "距离km")
+    private String distance;
+
+}

+ 3 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/work/mapper/PositionMapper.java

@@ -2,6 +2,8 @@ package com.ruoyi.web.work.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.ruoyi.web.work.domain.Position;
+import com.ruoyi.web.work.domain.dto.PositionQueryDto;
+import com.ruoyi.web.work.domain.vo.PositionListVo;
 
 import java.util.List;
 
@@ -14,5 +16,5 @@ public interface PositionMapper extends BaseMapper<Position> {
 
     List<Position> manageList(Position position);
 
-    List<Position> indexList(Position position);
+    List<PositionListVo> indexList(PositionQueryDto dto);
 }

+ 3 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/IPositionService.java

@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.web.work.domain.Position;
 import com.ruoyi.web.work.domain.dto.PositionDto;
+import com.ruoyi.web.work.domain.dto.PositionQueryDto;
 import com.ruoyi.web.work.domain.dto.PositionStateDto;
+import com.ruoyi.web.work.domain.vo.PositionListVo;
 
 import java.util.List;
 
@@ -17,7 +19,7 @@ public interface IPositionService extends IService<Position> {
 
     List<Position> manageList(Position position);
 
-    List<Position> indexList(Position position);
+    List<PositionListVo> indexList(PositionQueryDto dto);
 
     /**
      * 发布职位

+ 7 - 2
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/PositionServiceImpl.java

@@ -3,11 +3,14 @@ package com.ruoyi.web.work.service.impl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.PageUtils;
 import com.ruoyi.web.work.api.util.AppUtil;
 import com.ruoyi.web.work.domain.Column;
 import com.ruoyi.web.work.domain.Position;
 import com.ruoyi.web.work.domain.dto.PositionDto;
+import com.ruoyi.web.work.domain.dto.PositionQueryDto;
 import com.ruoyi.web.work.domain.dto.PositionStateDto;
+import com.ruoyi.web.work.domain.vo.PositionListVo;
 import com.ruoyi.web.work.mapper.PositionMapper;
 import com.ruoyi.web.work.service.IColumnService;
 import com.ruoyi.web.work.service.IPositionService;
@@ -36,12 +39,14 @@ public class PositionServiceImpl extends ServiceImpl<PositionMapper, Position> i
 
     @Override
     public List<Position> manageList(Position position) {
+        position.setUserId(AppUtil.getUser().getId());
+        PageUtils.orderBy("id desc");
         return positionMapper.manageList(position);
     }
 
     @Override
-    public List<Position> indexList(Position position) {
-        return positionMapper.indexList(position);
+    public List<PositionListVo> indexList(PositionQueryDto dto) {
+        return positionMapper.indexList(dto);
     }
 
     @Override

+ 17 - 9
ruoyi-admin/src/main/resources/mapper/work/PositionMapper.xml

@@ -3,10 +3,10 @@
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.ruoyi.web.work.mapper.PositionMapper">
-    
+
     <select id="selectList" resultType="com.ruoyi.web.work.domain.Position">
         select * from tb_position
-        <where>  
+        <where>
             <if test="userId != null "> and user_id = #{userId}</if>
             <if test="type != null "> and type = #{type}</if>
             <if test="title != null  and title != ''"> and title like concat('%', #{name}, '%')</if>
@@ -21,15 +21,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="title != null  and title != ''"> and title like concat('%', #{name}, '%')</if>
         </where>
     </select>
-    <select id="indexList" resultType="com.ruoyi.web.work.domain.Position">
+    <select id="indexList" resultType="com.ruoyi.web.work.domain.vo.PositionListVo">
         SELECT
-            *
+        id,
+        title,
+        experience,
+        salary,
+        region_name,
+        location
+        <if test="longitude != '' and latitude != '' ">,ROUND( ST_Distance_Sphere ( POINT ( #{longitude}, #{latitude} ), POINT ( longitude, latitude ))/ 1000, 2 ) AS distance</if>
         FROM
-            tb_position
+        tb_position
         WHERE
-            state = 0
-          AND audit = 1
-          AND type = #{type}
-        <if test="title != null  and title != ''"> and title like concat('%', #{name}, '%')</if>
+        state = 0
+        AND audit = 1
+        AND type = #{type}
+        <if test="title != null  and title != ''"> AND title LIKE concat('%', #{name}, '%')</if>
+        <if test="orderBy=='distance'">ORDER BY distance ASC</if>
+        <if test="orderBy=='id'">ORDER BY id DESC</if>
     </select>
 </mapper>