lsw 10 ماه پیش
والد
کامیت
fae00faf0b

+ 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_mw2qeijcty.ttf?t=1718292578740') format('truetype');
+	src: url('https://at.alicdn.com/t/c/font_4507607_ch9z9m4p6f.ttf?t=1718331025322') format('truetype');
 	/* src: url('~@/static/font/iconfont.ttf') format('truetype'); */
 }
 .icon {

+ 9 - 4
app/common/common.scss

@@ -48,7 +48,7 @@
 	color: white;
 	background-color: $main-color;
 	border-radius: 30px;
-	font-size: 14px;
+	font-size: 15px;
 	text-align: center;
 	padding: 5px;
 	margin-top: 15px;
@@ -134,7 +134,7 @@
 		text-align: left;
 	}
 	.hor {
-		flex: 1;
+		flex:0.7;
 		text-align: center;
 		padding-top: 5px;
 	}
@@ -308,6 +308,12 @@
 			padding-top: 10px;
 		}
 	}
+	.btn {
+		width: 80%;
+		.icon{
+			padding-right: 5px;
+		}
+	}
 }
 .yd {
 	width: 4px;
@@ -446,8 +452,7 @@
 				float: left;
 				width: 71%;
 				font-weight: bold;
-				.icon{
-					
+				.icon {
 				}
 			}
 			.salary {

+ 13 - 4
app/components/filters/filters.vue

@@ -87,9 +87,17 @@ export default {
 		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),
-				positionId: this.positionId
+				experience:
+					this.experience
+						.filter((item) => item.check && item.name != '不限')
+						.map((item) => item.name)
+						.toString() || '',
+				salary:
+					this.salary
+						.filter((item) => item.check)
+						.map((item) => item.name)
+						.toString() || '',
+				positionId: this.positionId || ''
 			});
 		},
 		go(url) {
@@ -101,7 +109,7 @@ export default {
 			this.positionName = '不限';
 			this.positionId = '';
 			this.$forceUpdate();
-			this.$emit('confirm', { experience: [], salary: [], positionId: '' });
+			this.$emit('confirm', { experience: '', salary: '', positionId: '' });
 			this.$emit('input', false);
 		},
 		close() {
@@ -122,6 +130,7 @@ export default {
 		padding-left: 5px;
 		.icon {
 			float: right;
+			font-size: 20px;
 		}
 	}
 	.item {

+ 112 - 0
app/components/sift/sift.vue

@@ -0,0 +1,112 @@
+<template>
+	<u-popup :show="value" @close="close()" round="15" :closeable="true" :mask-close-able="true">
+		<view class="ppopup">
+			<u-divider text="简历筛选" style="margin-top: 25px; margin-bottom: -5px"></u-divider>
+			<view class="item">
+				<view class="title">年龄范围</view>
+				<view class="form_group" style="display: flex">
+					<view class="start">
+						<input type="number" placeholder="开始" v-model="item.minAge" maxlength="2" />
+					</view>
+					<view class="hor">至</view>
+					<view class="start">
+						<input type="number" placeholder="结束" v-model="item.maxAge" maxlength="2" />
+					</view>
+				</view>
+			</view>
+			<view class="item">
+				<view class="title">工作经验</view>
+				<view class="form_group" style="display: flex">
+					<view class="start">
+						<input type="number" placeholder="开始" v-model="item.minExperience" maxlength="2" />
+					</view>
+					<view class="hor">至</view>
+					<view class="start">
+						<input type="number" placeholder="结束" v-model="item.maxExperience" maxlength="2" />
+					</view>
+				</view>
+			</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
+		}
+	},
+	data() {
+		return {
+			item: {}
+		};
+	},
+	methods: {
+		confirm() {
+			if (parseInt(this.item.maxAge) < parseInt(this.item.minAge)) {
+				uni.showModal({ content: '开始年龄不能小于结束年龄', showCancel: false });
+				return false;
+			}
+			if (parseInt(this.item.maxExperience) < parseInt(this.item.minExperience)) {
+				uni.showModal({ content: '开始经验不能小于结束经验', showCancel: false });
+				return false;
+			}
+			this.$emit('input', false);
+			this.$emit('confirm', this.item);
+		},
+		clear() {
+			this.item = { maxAge: '', minAge: '', minExperience: '', maxExperience: '' };
+			this.$forceUpdate();
+			this.$emit('confirm', this.item);
+			this.$emit('input', false);
+		},
+		close() {
+			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;
+		.icon {
+			float: right;
+		}
+	}
+	.item {
+		overflow: hidden;
+		input {
+			text-align: center;
+		}
+	}
+	.f {
+		margin: 7px;
+		.btn {
+			margin-top: 10px;
+			padding: 0px;
+		}
+		.ex {
+			background-color: #f3f3f3;
+			color: #6b6b6b;
+		}
+	}
+}
+</style>

+ 7 - 0
app/pages.json

@@ -203,6 +203,13 @@
 				"navigationBarTitleText": "简历列表",
 				"enablePullDownRefresh": true
 			}
+		},
+		{
+			"path" : "pages/user/resume/preview",
+			"style" : 
+			{
+				"navigationBarTitleText" : "查看简历"
+			}
 		}
 	],
 	"tabBar": {

+ 1 - 3
app/pages/job/list.vue

@@ -57,9 +57,7 @@ export default {
 			this.refresh();
 		},
 		confirm(e) {
-			this.param.experience = e.experience.map((item) => item.name).toString() || '';
-			this.param.salary = e.salary.map((item) => item.name).toString() || '';
-			this.param.positionId = e.positionId || '';
+			Object.assign(this.param,e);
 			this.refresh();
 		},
 		go(url) {

+ 1 - 1
app/pages/user/resume/deliver/receive/index.vue

@@ -1,6 +1,6 @@
 <template>
 	<view class="main pt0">
-		<view class="item" v-for="(item, index) in list" :key="index" @click="go('/pages/user/resume/deliver/receive/list?id=' + item.id)">
+		<view class="item" v-for="(item, index) in list" :key="index" @click="go('/pages/user/resume/deliver/receive/list?id=' + item.id + '&title=' + item.title + '&total=' + item.total)">
 			<view class="title omit">{{ item.title }}</view>
 			<view class="desc">
 				<view class="progress">

+ 75 - 21
app/pages/user/resume/deliver/receive/list.vue

@@ -1,14 +1,38 @@
 <template>
 	<view class="main pt0">
-		<view class="item" v-for="(item, index) in list" :key="index" @click="go('/pages/user/resume/deliver/receive/list?id=' + item.id)">
-			<image :src="ip + item.avatar" mode="widthFix" class="avatar"></image>
-			<view class="con">
-				<view class="name">{{ item.name }}</view>
-				<text class="desc">{{ item.sex }} · {{ item.age }}岁 · {{ item.experience }}</text>
+		<view class="tab">
+			<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="item" v-for="(item, index) in list" :key="index" @click="go('/pages/user/resume/preview?id=' + item.id)">
+			<view class="top">
+				<image :src="ip + item.avatar" mode="widthFix" class="avatar"></image>
+				<view class="state" style="color: #4caf50" v-if="item.isRead == 1">
+					<text class="icon">&#xe614;</text>
+					<text>已阅</text>
+				</view>
+				<view class="state" v-else>
+					<text class="icon">&#xe614;</text>
+					<text>未读</text>
+				</view>
+				<view class="con">
+					<view class="name">{{ item.name }}</view>
+					<text class="desc">{{ item.sex }} · {{ item.age }}岁 · {{ item.experience }}年经验</text>
+				</view>
+			</view>
+			<view class="flex">
+				<view class="f" v-if="item.state == 0">待处理</view>
+				<view class="f agree" v-if="item.state == 1 && item.isAccept == 0">已邀待对方同意</view>
+				<view class="f agree" v-if="item.state == 1 && item.isAccept == 1">对方同意面试</view>
+				<view class="f danger" v-if="item.state == 1 && item.isAccept == 2">对方已拒绝</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>
+		<sift v-model="show" @confirm="confirm"></sift>
 	</view>
 </template>
 <script>
@@ -16,13 +40,22 @@ export default {
 	data() {
 		return {
 			ip: this.http.ip,
+			tab: [
+				{ name: '全部', isRead: '' },
+				{ name: '已阅', isRead: 1 },
+				{ name: '未读', isRead: 0 }
+			],
 			list: [],
-			param: { pageNum: 1, pageSize: 10, isRead: 0 },
-			loadMore: true
+			param: { pageNum: 1, pageSize: 10 },
+			loadMore: true,
+			show: false
 		};
 	},
 	onLoad(e) {
 		this.param.positionId = e.id;
+		setTimeout(() => {
+			uni.setNavigationBarTitle({ title: e.title + '(' + e.total + ')' });
+		}, 300);
 		this.getData();
 	},
 	methods: {
@@ -40,6 +73,14 @@ export default {
 		go(url) {
 			uni.navigateTo({ url: url });
 		},
+		tabClick(e) {
+			this.param.isRead = e.isRead;
+			this.refresh();
+		},
+		confirm(e) {
+			Object.assign(this.param, e);
+			this.refresh();
+		},
 		//刷新数据
 		refresh() {
 			this.loadMore = true;
@@ -72,23 +113,36 @@ export default {
 	padding: 15px;
 	overflow: hidden;
 	margin-bottom: 12px;
-	.avatar {
-		float: left;
-		width: 50px;
-		height: 50px;
-		border-radius: 50%;
-	}
-	.con {
-		float: left;
-		padding-left: 10px;
-		.name {
-			font-weight: bold;
-			padding-bottom: 3px;
+	.top {
+		overflow: hidden;
+		.avatar {
+			float: left;
+			width: 50px;
+			height: 50px;
+			border-radius: 50%;
 		}
-		.desc {
-			color: $font-c;
+		.state {
+			float: right;
 			font-size: 14px;
 		}
+		.con {
+			float: left;
+			padding-left: 10px;
+			.name {
+				font-weight: bold;
+				padding-bottom: 3px;
+			}
+			.desc {
+				color: $font-c;
+				font-size: 14px;
+			}
+		}
+	}
+	.flex {
+		border-top: 1px solid $line;
+		padding-top: 10px;
+		font-size: 14px;
+		margin-top: 13px;
 	}
 }
 </style>

+ 3 - 3
app/pages/user/resume/index.vue

@@ -1,5 +1,5 @@
 <template>
-	<view class="resume animated fadeInDownBig">
+	<view class="resume">
 		<view class="row">
 			<!--个人信息-->
 			<view class="top" @click="go('/pages/user/resume/edit?item=' + JSON.stringify(item))">
@@ -8,7 +8,7 @@
 						<text>{{ item.name ? item.name : '姓名' }}</text>
 					</view>
 					<view class="item">年龄:{{ item.age }},性别:{{ item.sex }}</view>
-					<view class="item">工作经验:{{ item.experience }}</view>
+					<view class="item">工作经验:{{ item.experience }}</view>
 					<view class="item">手机号码:{{ item.phone }}</view>
 					<view class="item">电子邮箱:{{ item.email }}</view>
 				</view>
@@ -24,7 +24,7 @@
 		</view>
 		<!--求职期望-->
 		<view class="row">
-			<view class="label" @click="go('/pages/user/resume/desire?desire=' + JSON.stringify(item.desire))">
+			<view class="label">
 				<text class="title">求职期望</text>
 			</view>
 			<view class="item">工作城市:{{ item.cityName }}</view>

+ 88 - 0
app/pages/user/resume/preview.vue

@@ -0,0 +1,88 @@
+<template>
+	<view class="resume">
+		<view class="row">
+			<!--个人信息-->
+			<view class="top">
+				<view class="sm6">
+					<view class="name">
+						<text>{{ item.name ? item.name : '姓名' }}</text>
+					</view>
+					<view class="item">年龄:{{ item.age }},性别:{{ item.sex }}</view>
+					<view class="item">工作经验:{{ item.experience }}年</view>
+					<view class="item">手机号码:{{ item.phone }}</view>
+					<view class="item">电子邮箱:{{ item.email }}</view>
+				</view>
+				<image :src="item.avatar ? ip + item.avatar : '../../../static/ls.jpg'" mode="widthFix" class="tx" v-if="item.avatar"></image>
+			</view>
+		</view>
+		<!--个人优势-->
+		<view class="row">
+			<view class="label">
+				<text class="title">个人优势</text>
+			</view>
+			<view class="item">{{ item.advantage }}</view>
+		</view>
+		<!--求职期望-->
+		<view class="row">
+			<view class="label">
+				<text class="title">求职期望</text>
+			</view>
+			<view class="item">工作城市:{{ item.cityName }}</view>
+			<view class="item">意向工作:{{ item.positionName }}</view>
+			<view class="item">期望薪资:{{ item.salary }}</view>
+		</view>
+		<button class="btn" @click="invite()">
+			<text class="icon">&#xe6a3;</text>
+			<text>面试邀请</text>
+		</button>
+		<button class="btn" @click="call()">
+			<text class="icon">&#xe644;</text>
+			<text>拨打电话</text>
+		</button>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			ip: this.http.ip,
+			id: '',
+			item: {}
+		};
+	},
+	onLoad(e) {
+		this.id = e.id;
+		this.http.request({
+			url: '/app/deliver/detail/' + e.id,
+			success: (res) => {
+				this.item = res.data.data;
+			}
+		});
+	},
+	methods: {
+		invite() {
+			uni.showModal({
+				title: '提示',
+				content: '确定发送面试邀请',
+				success: (res) => {
+					if (res.confirm) {
+						this.http.request({
+							url: '/app/deliver/invite/' + this.id,
+							success: (res) => {
+								uni.showToast({ title: '发送成功' });
+							}
+						});
+					}
+				}
+			});
+		},
+		call() {
+			uni.makePhoneCall({
+				phoneNumber: this.item.phone
+			});
+		}
+	}
+};
+</script>
+<style lang="scss"></style>

+ 2 - 2
ruoyi-admin/src/main/java/com/ruoyi/web/work/api/Api_ResumeDeliverController.java

@@ -57,12 +57,12 @@ public class Api_ResumeDeliverController extends BaseController {
         return getDataTable(list);
     }
 
-    @PostMapping("/detail/{id}")
+    @GetMapping("/detail/{id}")
     public AjaxResult detail(@PathVariable("id") Long id) {
         return resumeDeliverService.detail(id);
     }
 
-    @PostMapping("/invite/{id}")
+    @GetMapping("/invite/{id}")
     public AjaxResult invite(@PathVariable("id") Long id) {
         return resumeDeliverService.invite(id);
     }

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

@@ -41,7 +41,7 @@ public class Resume{
     private String advantage;
 
     @ApiModelProperty(value = "工作经验:根=据参与工作时间自动计算")
-    private String experience;
+    private Integer experience;
 
     @NotBlank(message = "参与工作时间不能为空")
     @ApiModelProperty(value = "参与工作时间")

+ 17 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/ResumeDeliver.java

@@ -4,6 +4,7 @@ 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 io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.experimental.Accessors;
@@ -70,4 +71,20 @@ public class ResumeDeliver{
     @ApiModelProperty(value = "维度")
     private String latitude;
 
+    @JsonIgnore
+    @TableField(exist = false)
+    private Integer minAge;
+
+    @JsonIgnore
+    @TableField(exist = false)
+    private Integer maxAge;
+
+    @JsonIgnore
+    @TableField(exist = false)
+    private Integer minExperience;
+
+    @JsonIgnore
+    @TableField(exist = false)
+    private Integer maxExperience;
+
 }

+ 0 - 2
ruoyi-admin/src/main/java/com/ruoyi/web/work/domain/vo/ReceiveListVo.java

@@ -16,8 +16,6 @@ public class ReceiveListVo {
 
     private Long id;
 
-    private Long resumeId;
-
     private String name;
 
     private String avatar;

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

@@ -43,7 +43,7 @@ public interface IResumeDeliverService extends IService<ResumeDeliver> {
 
 
     /**
-     * 查看简历
+     * 企业查看简历
      *
      * @param id
      * @return

+ 16 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/ResumeDeliverServiceImpl.java

@@ -5,6 +5,7 @@ import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.web.work.api.util.AppUtil;
 import com.ruoyi.web.work.domain.Position;
+import com.ruoyi.web.work.domain.Resume;
 import com.ruoyi.web.work.domain.ResumeDeliver;
 import com.ruoyi.web.work.domain.dto.ResumeDeliverDto;
 import com.ruoyi.web.work.domain.vo.ReceiveListVo;
@@ -12,6 +13,7 @@ import com.ruoyi.web.work.domain.vo.ReceiveVo;
 import com.ruoyi.web.work.mapper.ResumeDeliverMapper;
 import com.ruoyi.web.work.service.IPositionService;
 import com.ruoyi.web.work.service.IResumeDeliverService;
+import com.ruoyi.web.work.service.IResumeService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -29,6 +31,9 @@ public class ResumeDeliverServiceImpl extends ServiceImpl<ResumeDeliverMapper, R
     @Autowired
     private IPositionService positionService;
 
+    @Autowired
+    private IResumeService resumeService;
+
     @Override
     public List<ResumeDeliver> selectList(ResumeDeliver resumeDeliver) {
         return resumeDeliverMapper.selectList(resumeDeliver);
@@ -73,6 +78,15 @@ public class ResumeDeliverServiceImpl extends ServiceImpl<ResumeDeliverMapper, R
         if (resumeDeliver == null || !resumeDeliver.getEnterpriseId().equals(AppUtil.getUser().getId())) {
             return AjaxResult.error("简历不存在或非法操作");
         }
+        if (resumeDeliver.getIsAccept() == 2) {
+            return AjaxResult.error("求职者已拒绝,无法重复发送");
+        }
+        if (resumeDeliver.getIsAccept() == 1) {
+            return AjaxResult.error("求职者已同意,请及时安排线下面试");
+        }
+        if (resumeDeliver.getState() == 1) {
+            return AjaxResult.error("已发送邀请,等待求职者同意");
+        }
         resumeDeliver.setState(1);
         if (!updateById(resumeDeliver)) {
             throw new ServiceException("发生面试邀请失败");
@@ -90,7 +104,8 @@ public class ResumeDeliverServiceImpl extends ServiceImpl<ResumeDeliverMapper, R
             resumeDeliver.setIsRead(1);
             updateById(resumeDeliver);
         }
-        return AjaxResult.success(resumeDeliver);
+        Resume resume = resumeService.getById(resumeDeliver.getUserId());
+        return AjaxResult.success(resume);
     }
 
     @Override

+ 1 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/work/service/impl/ResumeServiceImpl.java

@@ -51,7 +51,7 @@ public class ResumeServiceImpl extends ServiceImpl<ResumeMapper, Resume> impleme
         resume.setAge(Integer.parseInt(DateUtils.getYear()) - Integer.parseInt(resume.getBirthday().substring(0, 4)));
         //计算工作经验
         int year = Integer.parseInt(DateUtils.getYear()) - Integer.parseInt(resume.getJoinDate().substring(0, 4));
-        resume.setExperience(year == 0 ? "1年以内" : year + "年经验");
+        resume.setExperience(year == 0 ? 1 : year);
         if (!updateById(resume)) {
             throw new ServiceException("编辑简历失败");
         }

+ 3 - 1
ruoyi-admin/src/main/resources/mapper/work/ResumeDeliverMapper.xml

@@ -52,7 +52,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="receiveList" resultType="com.ruoyi.web.work.domain.vo.ReceiveListVo">
         SELECT
-            r.id AS resumeId,
             r.name,
             r.avatar,
             r.sex,
@@ -67,6 +66,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             AND d.enterprise_id =#{enterpriseId}
         <if test="state != null "> and d.state = #{state}</if>
         <if test="isAccept != null "> and d.is_accept = #{isAccept}</if>
+        <if test="isRead != null "> and d.is_read = #{isRead}</if>
+        <if test="minAge != null and maxAge !=null">AND r.age <![CDATA[ >= ]]> #{minAge} AND r.age <![CDATA[ <= ]]> #{maxAge}</if>
+        <if test="minExperience != null and maxExperience !=null">AND r.experience <![CDATA[ >= ]]> #{minExperience} AND r.experience <![CDATA[ <= ]]> #{maxExperience}</if>
         ORDER BY d.id DESC
     </select>
 

+ 0 - 17
ruoyi-admin/src/main/resources/mapper/work/ResumeMapper.xml

@@ -8,23 +8,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         select * from tb_resume
         <where>  
             <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
-            <if test="avatar != null  and avatar != ''"> and avatar = #{avatar}</if>
-            <if test="sex != null  and sex != ''"> and sex = #{sex}</if>
-            <if test="age != null "> and age = #{age}</if>
-            <if test="qualification != null  and qualification != ''"> and qualification = #{qualification}</if>
-            <if test="experience != null  and experience != ''"> and experience = #{experience}</if>
-            <if test="joinDate != null  and joinDate != ''"> and join_date = #{joinDate}</if>
-            <if test="phone != null  and phone != ''"> and phone = #{phone}</if>
-            <if test="birthday != null  and birthday != ''"> and birthday = #{birthday}</if>
-            <if test="email != null  and email != ''"> and email = #{email}</if>
-            <if test="wx != null  and wx != ''"> and wx = #{wx}</if>
-            <if test="advantage != null  and advantage != ''"> and advantage = #{advantage}</if>
-            <if test="state != null  and state != ''"> and state = #{state}</if>
-            <if test="desire != null  and desire != ''"> and desire = #{desire}</if>
-            <if test="education != null  and education != ''"> and education = #{education}</if>
-            <if test="project != null  and project != ''"> and project = #{project}</if>
-            <if test="work != null  and work != ''"> and work = #{work}</if>
-            <if test="isShow != null "> and is_show = #{isShow}</if>
         </where>
     </select>