提交 8753b984 作者: 王定

feat: 基本完成灵活用工找人干活模块

上级 dad3526e
......@@ -12,9 +12,39 @@ enum Api {
gitListByCodeDict = '/sys/dictItem/listByCode', // 查询字典
queryByCategoryAndCode = '/sys/labelCategory/queryByCategoryAndCode', // 查询字典
postLaborAdd = '/server/labor/add', // 新增
getLaborAppList = '/server/labor/appList', // APP用工列表查询
getLaborAppDetail = '/server/labor/appDetail', // APP用工详情查询
}
/**
* @param params 请求参数
* @description: APP灵活用工找人干活用工详情查询
*/
export function getLaborAppDetail(params = {}) {
return otherHttp.get({
url: Api.getLaborAppDetail,
params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
})
}
/**
* @param params 请求参数
* @description: APP灵活用工找人干活列表查询
*/
export function getLaborAppList(params = {}) {
return otherHttp.get({
url: Api.getLaborAppList,
params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
})
}
/**
* @param params 请求参数
* @description: 找人干活发布 新增
*/
export function postLaborAdd(params = {}) {
......
......@@ -70,3 +70,7 @@
}
}
.uni-picker-container .uni-picker-action.uni-picker-action-confirm {
color: #5DB66F !important;
}
<script setup lang="ts">
import { reactive, toRefs } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { useUserStore } from '@/store/modules/user'
const userStore = useUserStore()
onLoad((option) => {
console.log(option.id);
import { getCalculateAge } from '@/utils/date'
import * as LinghuoyonggongAPI from '@/api/model/linghuoyonggong';
const pageData = reactive({
loading: false,
workersParam:[],
contactMobile:""
})
// 字典值
const DictData = reactive({
sexArr:[],// 性别
educationArr:[]// 学历
})
onLoad((options) => {
let param = JSON.parse(decodeURIComponent(options.param));
uni.setNavigationBarTitle({
title: '详情'+option.id
title: param.villageName
});
getLaborAppDetail(param.id);
})
onShow(() => {
})
const pageData = reactive({
loading: false,
options: {
area: [],
urgentdegree: [],
type: [],
},
position: [],
})
async function getLaborAppDetail(id: string) {
await LinghuoyonggongAPI.gitListByCodeDict({ code : 'sex'}).then(res=>{
DictData.sexArr = res;
})
await LinghuoyonggongAPI.gitListByCodeDict({ code : 'education'}).then(res=>{
DictData.educationArr = res;
})
await LinghuoyonggongAPI.getLaborAppDetail({ id }).then((res) => {
pageData.workersParam = res.workers;
pageData.contactMobile = res.contactMobile;
})
}
// 返回字典中的中文值
function returnDictZhVel(type:any,val:any){
let valText = "";
if(type == 'gender'){
let arr = DictData.sexArr;
for(let i = 0; i < arr.length;i++){
if(val == parseInt(arr[i].itemValue)){
valText = arr[i].itemText;
break;
}
}
}
if(type == 'edu'){
let arr = DictData.educationArr;
for(let i = 0; i < arr.length;i++){
if(val == parseInt(arr[i].itemValue)){
valText = arr[i].itemText;
break;
}
}
}
return valText;
}
function makePhoneCall(){
uni.makePhoneCall({
phoneNumber: pageData.contactMobile
});
}
</script>
<template>
<view class="details_page">
<view class="details-content">
<view v-if="!pageData.workersParam || pageData.workersParam.length == 0" style="height: 700rpx">
<fui-empty marginTop="100" src="/static/images/no-data.png" title="暂无数据" />
</view>
<view class="yr-person-item" v-for="(item,index) in pageData.workersParam" :key="index">
<view class="yr-person-info">
<view class="person_name_attr">{{item.name}}<text class="person_attr">{{item.attr}}</text></view>
<view class="person-info">{{getCalculateAge(item.birthday)}}{{ returnDictZhVel('gender',item.gender) }}{{ returnDictZhVel('edu',item.edu)}}</view>
<view class="person-info text_overflow_ellipsis">技能:{{item.skill}}</view>
</view>
</view>
</view>
<view class="make-phone-view">
<fui-button text="电话沟通" bold radius="96rpx" @click="makePhoneCall()" height="80rpx"/>
</view>
</view>
<fui-loading isFixed v-if="pageData.loading" backgroundColor="rgba(0, 0, 0, 0.4)" />
......@@ -36,5 +89,50 @@
background: rgba(230, 245, 232, 1);
min-height: 100vh;
width: 750rpx;
padding-top: 24rpx;
position: relative;
.details-content{
width: 694rpx;
background-color: #FFFFFF;
margin-left: 28rpx;
border-radius: 12rpx;
padding: 24rpx;
.yr-person-item{
border-bottom: 2rpx solid #EEEEEE;
margin-bottom: 24rpx;
.yr-person-info{
.person_name_attr{
font-size: 28rpx;
font-weight: 500;
color: #333333;
.person_attr{
font-size: 24rpx;
font-weight: 400;
color: #5DB66F;
margin-left: 12rpx;
}
}
.person-info{
font-size: 24rpx;
color: #999999;
vertical-align: middle;
margin-bottom: 24rpx;
margin-top: 24rpx;
}
}
}
.yr-person-item:last-child{
border-bottom: none;
}
}
.make-phone-view{
width: 690rpx;
height: 80rpx;
position: fixed;
left: 30rpx;
bottom: 62rpx;
}
}
</style>
......@@ -14,28 +14,26 @@
})
onShow(() => {
pageData.search.pageNo = 1
if (pageData.currentEmploymentId === 2) {
pageData.search.publishstatu = 2
pageData.search.createBy = ''
}
if (pageData.currentEmploymentId === 1) {
pageData.search.createBy = userStore.getUserInfo.username
}
pageData.employmentList = []
getEmploymentList()
resetGetEmploymentList()
})
// 页面数据
const pageData = reactive({
loading: false,
requestDebounce:null,
searchValue:"",
search: {
pageNo: 1,
pageSize: 10,
publishstatu: 2,
publishstatu: 1,
type: null,
createBy: '',
},
findSearch: {
pageNo: 1,
pageSize: 10,
keyword:""
},
// 用工类型标签
employmentTabs: [
{ id: 2, name: '找人干活' },
......@@ -94,81 +92,30 @@
if (pageData.loading || (pageData.total > 0 && pageData.employmentList.length >= pageData.total)) {
return
}
pageData.loading = true
pageData.loading = true;
// 添加请求防抖,避免快速连续请求
if (pageData.requestDebounce) {
clearTimeout(pageData.requestDebounce)
}
pageData.requestDebounce = setTimeout(async () => {
try {
/* const res = await fetchWithRetry(() => LinghuoyonggongAPI.employmentList(pageData.search))
const { records, total } = res */
// const res = await fetchWithRetry(() => LinghuoyonggongAPI.employmentList(pageData.search))
let res = null;
if(pageData.currentEmploymentId == 2){
res = await fetchWithRetry(() => LinghuoyonggongAPI.getLaborAppList(pageData.findSearch))
}else{
res = await fetchWithRetry(() => LinghuoyonggongAPI.employmentList(pageData.search))
}
const total = 18;
const records = [
{
"id": "1",
"updateBy": "admin",
"updateTime": "2025/12/17",
"sysOrgCode": "技术部",
"name": "名称",
"picture": "https://gips0.baidu.com/it/u=1690853528,2506870245&fm=3028&app=3028&f=JPEG&fmt=auto?w=1024&h=1024",
"type": "种值",
"content": "工作内容",
"workers": 101,
"price": 220,
"area": "张家界市",
"address": "荷花村",
"longitude": "110.465501",
"latitude": "29.114429",
"urgentdegree": 1,
"starttime": "2025-12-17",
"estimatedendtime": "2025-12-19",
"createBy": "老王",
"createTime": "2025-12-17",
"reviewstatu": "审核状态",
"reviewinfo": " 审核信息",
"publishstatu": "发布状态"
},
{
"id": "1",
"updateBy": "admin",
"updateTime": "2025/12/17",
"sysOrgCode": "技术部",
"name": "名称2",
"picture": "https://gips2.baidu.com/it/u=195724436,3554684702&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960",
"type": "种值2",
"content": "工作内容",
"workers": 101,
"price": 220,
"area": "张家界市",
"address": "荷花村",
"longitude": "110.465501",
"latitude": "29.114429",
"urgentdegree": 1,
"starttime": "2025-12-17",
"estimatedendtime": "2025-12-19",
"createBy": "老王",
"createTime": "2025-12-17",
"reviewstatu": "审核状态",
"reviewinfo": " 审核信息",
"publishstatu": "发布状态"
}
];
const { records, total } = res;
// 批量处理数据,避免多次DOM操作
const processedRecords = records.map((item) => {
// 缓存区域处理结果
item.area = getText(item.area, ' / ')
// 计算天数并缓存结果
if (item.starttime && item.estimatedendtime) {
item.daysDiff = getDaysDiff(item.starttime, item.estimatedendtime)
}
return item
})
......@@ -197,17 +144,7 @@
// 用工类型标签点击事件
function onEmploymentTabClick(tab: any) {
pageData.currentEmploymentId = tab.id
pageData.search.pageNo = 1
pageData.employmentList = []
if (pageData.currentEmploymentId === 1) {
pageData.search.publishstatu = 1
pageData.search.createBy = ''
}
if (pageData.currentEmploymentId === 2) {
pageData.search.createBy = userStore.getUserInfo.username
}
getEmploymentList()
// 在这里添加具体的用工类型标签点击逻辑
resetGetEmploymentList()
}
// 用工项点击事件
......@@ -256,10 +193,35 @@
return diffDays
}
function onSearch(res:any){
uni.showToast({
title: '搜索:' + res.value,
icon: 'none'
})
pageData.employmentList = []
if (pageData.currentEmploymentId === 1) {
pageData.search.pageNo = 1
pageData.search.publishstatu = 1
pageData.search.createBy = res.value
}
if (pageData.currentEmploymentId === 2) {
pageData.findSearch.pageNo = 1;
pageData.findSearch.keyword = res.value;
}
getEmploymentList()
}
// 取消搜索了
function onSearchCancel(){
resetGetEmploymentList();
}
function resetGetEmploymentList(){
pageData.employmentList = []
pageData.searchValue = "";
if (pageData.currentEmploymentId === 1) {
pageData.search.pageNo = 1
pageData.search.publishstatu = 1
pageData.search.createBy = ''
}
if (pageData.currentEmploymentId === 2) {
pageData.findSearch.pageNo = 1;
pageData.findSearch.keyword = "";
}
getEmploymentList()
}
onReachBottom(() => {
console.log('触底了')
......@@ -276,7 +238,8 @@
// 查看找人干活详情
function onDetailsClick(item: any) {
Navigate.to(`/pages/linghuoyonggong/details?id=${item.id}`)
let param = encodeURIComponent(JSON.stringify({id:item.id,villageName:item.villageName}));
Navigate.to('/pages/linghuoyonggong/details?param='+param);
}
</script>
......@@ -300,7 +263,7 @@
<view class="codefun-mt-14 codefun-flex-col group_3">
<view class="top-search-view">
<uni-search-bar radius="100" placeholder="请输入搜索内容" clearButton="auto" cancelButton="none" @confirm="onSearch" />
<uni-search-bar radius="100" v-model="pageData.searchValue" placeholder="请输入搜索内容" clearButton="auto" cancelButton="none" @confirm="onSearch" @cancel="onSearchCancel" @clear="onSearchCancel"/>
</view>
<view class="codefun-flex-row section_2">
<view
......@@ -378,24 +341,23 @@
</view>
</template>
<template v-else>
<view class="work_list_view" v-for="(item,index) in 10" :key="index">
<view class="work_list_view" v-for="item in pageData.employmentList" :key="item.id">
<view class="d-flex j-sb">
<view class="left-width village_number_view">
<view class="village_view text_overflow_ellipsis">先锋村{{index}}</view>
<view class="d-flex align-center"><image class="avatar_icon" src="/static/images/linghuoyonggong/avatar.png" /><text class="text-color">待工人员20</text></view>
<view class="village_view text_overflow_ellipsis">{{ item.villageName }}</view>
<view class="d-flex align-center"><image class="avatar_icon" src="/static/images/linghuoyonggong/avatar.png" /><text class="text-color">待工人员{{item.workers}}</text></view>
</view>
<view class="d-flex align-center justify-center right-width village_distance">
<image class="distance_icon" src="/static/images/linghuoyonggong/distance.png" />
<text class="distance_val text-color">3.2km</text>
<text class="distance_val text-color">2km</text>
</view>
</view>
<view class="d-flex j-sb skill_details_view">
<view class="left-width d-flex j-sb align-center">
<image class="skill_icon" src="/static/images/linghuoyonggong/skill.png" />
<view class="skill_view text_overflow_ellipsis">技能:采摘、饲养、编织、粉刷、种植...</view>
<view class="skill_view text_overflow_ellipsis">技能:{{item.skills.length ? item.skills.join("、") : '未填写'}}</view>
</view>
<view class="right-width see_details_btn" @click="onDetailsClick({id:index})">查看详情</view>
<view class="right-width see_details_btn" @click="onDetailsClick(item)">查看详情</view>
</view>
</view>
......
......@@ -29,3 +29,23 @@ export function formatDate(date: Date | number | string): string {
return `${year}-${month}-${day}`
}
/**
* 根据日期算出年龄
* @param date 日期字符串
* @returns 算出的年龄
*/
export function getCalculateAge(birthDate: Date | string): number {
// 解析出生日期字符串为Date对象
const birthDateObj = new Date(birthDate);
// 获取当前日期
const currentDate = new Date();
// 计算两个日期之间的年份差异
let age = currentDate.getFullYear() - birthDateObj.getFullYear();
// 检查是否还没到生日,如果是,则年龄减1
const m = currentDate.getMonth() - birthDateObj.getMonth();
if (m < 0 || (m === 0 && currentDate.getDate() < birthDateObj.getDate())) {
age--;
}
return age;
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论