Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
basic-uniapp-v3
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-uniapp-v3
Commits
8753b984
提交
8753b984
authored
12月 19, 2025
作者:
王定
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 基本完成灵活用工找人干活模块
上级
dad3526e
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
227 行增加
和
113 行删除
+227
-113
linghuoyonggong.ts
src/api/model/linghuoyonggong.ts
+30
-0
public.less
src/common/public.less
+4
-0
details.vue
src/pages/linghuoyonggong/details.vue
+116
-18
linghuoyonggong.vue
src/pages/linghuoyonggong/linghuoyonggong.vue
+57
-95
publishEmployment.vue
src/pages/linghuoyonggong/publishEmployment.vue
+0
-0
date.ts
src/utils/date.ts
+20
-0
没有找到文件。
src/api/model/linghuoyonggong.ts
浏览文件 @
8753b984
...
...
@@ -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
=
{})
{
...
...
src/common/public.less
浏览文件 @
8753b984
...
...
@@ -70,3 +70,7 @@
}
}
.uni-picker-container .uni-picker-action.uni-picker-action-confirm {
color: #5DB66F !important;
}
src/pages/linghuoyonggong/details.vue
浏览文件 @
8753b984
<
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
:
750
rpx
;
padding-top
:
24
rpx
;
position
:
relative
;
.details-content{
width
:
694
rpx
;
background-color
:
#FFFFFF
;
margin-left
:
28
rpx
;
border-radius
:
12
rpx
;
padding
:
24
rpx
;
.yr-person-item{
border-bottom
:
2
rpx
solid
#EEEEEE
;
margin-bottom
:
24
rpx
;
.yr-person-info{
.person_name_attr{
font-size
:
28
rpx
;
font-weight
:
500
;
color
:
#333333
;
.person_attr{
font-size
:
24
rpx
;
font-weight
:
400
;
color
:
#5DB66F
;
margin-left
:
12
rpx
;
}
}
.person-info
{
font-size
:
24
rpx
;
color
:
#999999
;
vertical-align
:
middle
;
margin-bottom
:
24
rpx
;
margin-top
:
24
rpx
;
}
}
}
.yr-person-item
:last-child
{
border-bottom
:
none
;
}
}
.make-phone-view
{
width
:
690
rpx
;
height
:
80
rpx
;
position
:
fixed
;
left
:
30
rpx
;
bottom
:
62
rpx
;
}
}
</
style
>
src/pages/linghuoyonggong/linghuoyonggong.vue
浏览文件 @
8753b984
...
...
@@ -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>
...
...
src/pages/linghuoyonggong/publishEmployment.vue
浏览文件 @
8753b984
差异被折叠。
点击展开。
src/utils/date.ts
浏览文件 @
8753b984
...
...
@@ -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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论