Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
H
hr-mobile-view
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
anjia-hr
hr-mobile-view
Commits
67115fa1
Commit
67115fa1
authored
Mar 31, 2026
by
刘斌
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: 增加兼职扫码填信息
parent
1099f528
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
954 additions
and
0 deletions
+954
-0
rsbuild.config.ts
rsbuild.config.ts
+6
-0
App.vue
src/App.vue
+4
-0
index.ts
src/partTime/index.ts
+5
-0
partTimeInfo.vue
src/partTime/partTimeInfo.vue
+939
-0
No files found.
rsbuild.config.ts
View file @
67115fa1
...
@@ -26,6 +26,12 @@ export default defineConfig({
...
@@ -26,6 +26,12 @@ export default defineConfig({
],
],
},
},
},
},
source
:
{
entry
:
{
index
:
'./src/index.ts'
,
partTime
:
'./src/partTime/index.ts'
,
},
},
server
:
{
server
:
{
proxy
:
{
proxy
:
{
// http://localhost:3000/api -> http://localhost:3000/api
// http://localhost:3000/api -> http://localhost:3000/api
...
...
src/App.vue
View file @
67115fa1
<!--
- @File: App.vue
- @Description: 全职人员信息录入页面
-->
<
template
>
<
template
>
<div
class=
"page"
>
<div
class=
"page"
>
<van-form
@
submit=
"onSubmit"
required=
"auto"
>
<van-form
@
submit=
"onSubmit"
required=
"auto"
>
...
...
src/partTime/index.ts
0 → 100644
View file @
67115fa1
import
{
createApp
}
from
'vue'
;
import
PartTimeInfo
from
'./partTimeInfo.vue'
;
import
'../index.css'
;
createApp
(
PartTimeInfo
).
mount
(
'#root'
);
src/partTime/partTimeInfo.vue
0 → 100644
View file @
67115fa1
<!--
- @File: partTimeInfo.vue
- @Description: 兼职人员信息录入页面
-->
<
template
>
<div
class=
"page"
>
<van-form
@
submit=
"onSubmit"
required=
"auto"
>
<div
class=
"section-card"
>
<div
class=
"section-title"
>
基本信息
</div>
<div
class=
"form-item"
v-if=
"!hasDid"
>
<div
class=
"item-label"
>
所属板块
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.plate"
readonly
clickable
name=
"plateId"
class=
"custom-field"
placeholder=
"请选择所属板块"
:rules=
"[
{ required: !hasDid, message: '请选择所属板块' }]"
:border="false"
@click="showPlatePicker = true"
>
<template
#
right-icon
>
<van-icon
name=
"arrow-down"
color=
"#969799"
size=
"12"
/>
</
template
>
</van-field>
</div>
<div
class=
"form-row-2col"
>
<div
class=
"form-col"
>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
姓名
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.name"
name=
"name"
class=
"custom-field"
placeholder=
"请输入姓名"
:rules=
"[{ required: true, message: '请填写姓名' }]"
:border=
"false"
/>
</div>
</div>
<div
class=
"form-col"
>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
性别
<span
style=
"color: #ee0a24"
>
*
</span></div>
<div
class=
"custom-input dropdown-input"
style=
"padding: 0 12px; height: 44px;"
>
<van-radio-group
v-model=
"form.gender"
direction=
"horizontal"
style=
"width: 100%; height: 100%;"
>
<van-radio
name=
"0"
>
男
</van-radio>
<van-radio
name=
"1"
>
女
</van-radio>
</van-radio-group>
</div>
</div>
</div>
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
手机号码
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.phoneNumber"
name=
"phoneNumber"
type=
"tel"
class=
"custom-field"
placeholder=
"请输入手机号码"
:rules=
"phoneRules"
:border=
"false"
/>
</div>
<div
class=
"form-row-2col"
>
<div
class=
"form-col"
>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
出生日期
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.birthDate"
readonly
clickable
name=
"birthDate"
class=
"custom-field"
placeholder=
"请选择"
:rules=
"[{ required: true, message: '请选择出生日期' }]"
:border=
"false"
@
click=
"showBirthPicker = true"
>
<
template
#
right-icon
>
<van-icon
name=
"calendar-o"
color=
"#969799"
/>
</
template
>
</van-field>
</div>
</div>
<div
class=
"form-col"
>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
年龄
</div>
<van-field
v-model=
"form.age"
name=
"age"
type=
"digit"
class=
"custom-field"
placeholder=
"请输入年龄"
:rules=
"ageRules"
:border=
"false"
/>
</div>
</div>
</div>
<div
class=
"form-row-2col"
>
<div
class=
"form-col"
>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
民族
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.ethnicity"
name=
"ethnicity"
class=
"custom-field"
placeholder=
"请输入民族"
:rules=
"[{ required: true, message: '请输入民族' }]"
:border=
"false"
/>
</div>
</div>
<div
class=
"form-col"
>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
籍贯
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.nativePlace"
name=
"nativePlace"
class=
"custom-field"
placeholder=
"请输入籍贯"
:rules=
"[{ required: true, message: '请输入籍贯' }]"
:border=
"false"
/>
<div
class=
"help-text"
>
如:**省**市
</div>
</div>
</div>
</div>
<div
class=
"form-item-horizontal"
>
<div
class=
"item-label"
>
婚姻状况
<span
style=
"color: #ee0a24"
>
*
</span></div>
<div
class=
"custom-input"
style=
"padding: 10px 12px; flex: 1;"
>
<van-radio-group
v-model=
"form.maritalStatus"
direction=
"horizontal"
>
<van-radio
name=
"2"
style=
"margin-right: 12px;"
>
未婚
</van-radio>
<van-radio
name=
"1"
style=
"margin-right: 12px;"
>
已婚
</van-radio>
<van-radio
name=
"3"
>
离异
</van-radio>
</van-radio-group>
</div>
</div>
<div
class=
"form-item-horizontal"
>
<div
class=
"item-label"
>
政治面貌
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.politicalText"
readonly
clickable
name=
"politicalStatus"
class=
"custom-field"
placeholder=
"请选择"
:rules=
"[{ required: true, message: '请选择政治面貌' }]"
:border=
"false"
style=
"flex: 1;"
@
click=
"showPoliticalPicker = true"
>
<
template
#
right-icon
>
<van-icon
name=
"arrow-down"
color=
"#969799"
size=
"12"
/>
</
template
>
</van-field>
</div>
<div
class=
"form-item-horizontal"
>
<div
class=
"item-label"
>
照片
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
name=
"photo"
:rules=
"[{
required: true,
message: '请上传照片并等待上传成功',
validator: (val) => val && val.length > 0 && form.ossId > 0
}]"
:border=
"false"
style=
"flex: 1; padding: 0; background: transparent;"
>
<
template
#
input
>
<van-uploader
v-model=
"form.photoList"
:max-count=
"1"
:max-size=
"20 * 1024 * 1024"
:after-read=
"afterRead"
@
delete=
"onDeletePhoto"
@
oversize=
"onOversize"
/>
</
template
>
</van-field>
</div>
<div
class=
"form-item-horizontal"
>
<div
class=
"item-label"
>
身份证号码
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.idCardNumber"
name=
"idCardNumber"
class=
"custom-field"
placeholder=
"请输入身份证号码"
:rules=
"idRules"
:border=
"false"
style=
"flex: 1;"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
家庭地址
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.homeAddress"
name=
"homeAddress"
type=
"textarea"
rows=
"2"
autosize
class=
"custom-field"
placeholder=
"请输入家庭地址"
:rules=
"[{ required: true, message: '请输入家庭地址' }]"
:border=
"false"
/>
<div
class=
"help-text"
>
例如:**市**区**街道**小区*号楼*单元*0*(具体到门牌号,写现居住地址)
</div>
</div>
</div>
<div
class=
"section-card"
>
<div
class=
"section-title"
>
教育经历(全日制)
</div>
<div
class=
"form-row-2col"
>
<div
class=
"form-col"
>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
学历
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.fulltimeEducation"
name=
"fulltimeEducation"
class=
"custom-field"
placeholder=
"请输入学历"
:rules=
"[{ required: true, message: '请输入学历' }]"
:border=
"false"
/>
</div>
</div>
<div
class=
"form-col"
>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
学位
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.fulltimeDegree"
name=
"fulltimeDegree"
class=
"custom-field"
placeholder=
"请输入学位"
:rules=
"[{ required: true, message: '请输入学位' }]"
:border=
"false"
/>
</div>
</div>
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
毕业院校
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.fulltimeSchool"
name=
"fulltimeSchool"
class=
"custom-field"
placeholder=
"请输入毕业院校"
:rules=
"[{ required: true, message: '请输入毕业院校' }]"
:border=
"false"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
专业
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.fulltimeMajor"
name=
"fulltimeMajor"
class=
"custom-field"
placeholder=
"请输入专业"
:rules=
"[{ required: true, message: '请输入专业' }]"
:border=
"false"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
毕业时间
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.fulltimeGraduationDate"
readonly
clickable
name=
"fulltimeGraduationDate"
class=
"custom-field"
placeholder=
"请选择"
:rules=
"[{ required: true, message: '请选择毕业时间' }]"
:border=
"false"
@
click=
"showFullGraduatePicker = true"
>
<
template
#
right-icon
>
<van-icon
name=
"calendar-o"
color=
"#969799"
/>
</
template
>
</van-field>
</div>
</div>
<div
class=
"section-card"
>
<div
class=
"section-title"
>
其他信息
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
银行卡号
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.bankCardNumber"
name=
"bankCardNumber"
class=
"custom-field"
placeholder=
"请输入银行卡号"
:rules=
"[{ required: true, message: '请输入银行卡号' }]"
:border=
"false"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
开户行
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.bankName"
name=
"bankName"
class=
"custom-field"
placeholder=
"请输入开户行"
:rules=
"[{ required: true, message: '请输入开户行' }]"
:border=
"false"
/>
</div>
<div
class=
"form-item-horizontal"
>
<div
class=
"item-label"
>
公司内是否有亲属关系
<span
style=
"color: #ee0a24"
>
*
</span></div>
<div
class=
"custom-input"
style=
"padding: 10px 12px; flex: 1;"
>
<van-radio-group
v-model=
"form.hasRelativeInCompany"
direction=
"horizontal"
>
<van-radio
name=
"Y"
style=
"margin-right: 12px;"
>
是
</van-radio>
<van-radio
name=
"N"
>
否
</van-radio>
</van-radio-group>
</div>
</div>
<div
class=
"form-item"
v-if=
"form.hasRelativeInCompany === 'Y'"
>
<div
class=
"item-label"
>
亲属姓名
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.relativeName"
name=
"relativeName"
class=
"custom-field"
placeholder=
"请输入亲属姓名"
:rules=
"[{ required: form.hasRelativeInCompany === 'Y', message: '请输入亲属姓名' }]"
:border=
"false"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
紧急联系人
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.emergencyContact"
name=
"emergencyContact"
class=
"custom-field"
placeholder=
"请输入紧急联系人"
:rules=
"[{ required: true, message: '请输入紧急联系人' }]"
:border=
"false"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
紧急联系人电话
<span
style=
"color: #ee0a24"
>
*
</span></div>
<van-field
v-model=
"form.emergencyContactPhone"
name=
"emergencyContactPhone"
type=
"tel"
class=
"custom-field"
placeholder=
"请输入紧急联系人电话"
:rules=
"phoneRules"
:border=
"false"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
介绍人
</div>
<van-field
v-model=
"form.introducer"
name=
"introducer"
class=
"custom-field"
placeholder=
"请输入介绍人"
:border=
"false"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"item-label"
>
介绍人关系
</div>
<van-field
v-model=
"form.introducerRelation"
name=
"introducerRelation"
class=
"custom-field"
placeholder=
"请输入介绍人关系"
:border=
"false"
/>
</div>
</div>
<div
class=
"actions"
>
<van-button
round
block
type=
"primary"
:loading=
"submitting"
native-type=
"submit"
>
提交
</van-button>
</div>
</van-form>
<van-popup
v-model:show=
"showPlatePicker"
position=
"bottom"
>
<van-picker
:columns=
"plateOptions"
@
confirm=
"onPlateConfirm"
@
cancel=
"showPlatePicker = false"
/>
</van-popup>
<van-popup
v-model:show=
"showPoliticalPicker"
position=
"bottom"
>
<van-picker
:columns=
"politicalOptions"
@
confirm=
"onPoliticalConfirm"
@
cancel=
"showPoliticalPicker = false"
/>
</van-popup>
<van-popup
v-model:show=
"showBirthPicker"
position=
"bottom"
>
<van-date-picker
v-model=
"birthValues"
title=
"选择日期"
:min-date=
"minDate"
:max-date=
"maxDate"
@
confirm=
"onBirthConfirm"
@
cancel=
"showBirthPicker = false"
/>
</van-popup>
<van-popup
v-model:show=
"showFullGraduatePicker"
position=
"bottom"
>
<van-date-picker
v-model=
"fullGraduateValues"
title=
"选择年月"
:min-date=
"graduationMinDate"
:max-date=
"graduationMaxDate"
:columns-type=
"['year','month']"
@
confirm=
"onFullGraduateConfirm"
@
cancel=
"showFullGraduatePicker = false"
/>
</van-popup>
</div>
</template>
<
script
setup
lang=
"ts"
>
import
{
useDebounceFn
}
from
'@vueuse/core'
;
import
axios
from
'axios'
;
import
type
{
UploaderFileListItem
}
from
'vant'
;
import
{
onBeforeUnmount
,
onMounted
,
reactive
,
ref
,
watch
,
}
from
'vue'
;
const
form
=
reactive
({
plateId
:
0
,
plate
:
''
,
name
:
''
,
phoneNumber
:
''
,
gender
:
'0'
,
genderText
:
'男'
,
photoList
:
[]
as
UploaderFileListItem
[],
ossId
:
0
,
idCardNumber
:
''
,
birthDate
:
''
,
age
:
''
as
number
|
''
,
homeAddress
:
''
,
ethnicity
:
''
,
nativePlace
:
''
,
maritalStatus
:
'2'
,
maritalText
:
'未婚'
,
politicalStatus
:
''
,
politicalText
:
''
,
emergencyContact
:
''
,
emergencyContactPhone
:
''
,
introducer
:
''
,
introducerRelation
:
''
,
fulltimeEducation
:
''
,
fulltimeSchool
:
''
,
fulltimeMajor
:
''
,
fulltimeGraduationDate
:
''
,
fulltimeDegree
:
''
,
bankCardNumber
:
''
,
bankName
:
''
,
hasRelativeInCompany
:
'N'
,
relativeName
:
''
,
tid
:
''
,
});
const
_today
=
new
Date
();
const
_todayYear
=
_today
.
getFullYear
();
const
minDate
=
new
Date
(
_todayYear
-
75
,
0
,
1
);
const
maxDate
=
new
Date
(
_todayYear
-
10
,
0
,
1
);
const
graduationMinDate
=
new
Date
(
_todayYear
-
50
,
1
);
const
graduationMaxDate
=
new
Date
(
_todayYear
+
3
,
12
);
const
phoneRules
=
[
{
required
:
true
,
message
:
'请填写手机号码'
},
{
pattern
:
/^1
\d{10}
$/
,
message
:
'手机号格式错误'
},
];
const
idRules
=
[
{
required
:
true
,
message
:
'请填写身份证号码'
},
{
pattern
:
/^
(\d{15}
|
\d{17}[\d
Xx
])
$/
,
message
:
'身份证格式错误'
},
];
const
ageRules
=
[{
pattern
:
/^
\d{1,3}
$/
,
message
:
'年龄格式错误'
}];
const
showPlatePicker
=
ref
(
false
);
const
plateOptions
=
ref
<
{
text
:
string
;
value
:
number
}[]
>
([]);
const
showPoliticalPicker
=
ref
(
false
);
const
showBirthPicker
=
ref
(
false
);
const
submitting
=
ref
(
false
);
const
submitSuccess
=
ref
(
false
);
const
showFullGraduatePicker
=
ref
(
false
);
async
function
afterRead
(
items
:
UploaderFileListItem
|
UploaderFileListItem
[])
{
const
item
=
Array
.
isArray
(
items
)
?
items
[
0
]
:
items
;
item
.
status
=
'uploading'
;
item
.
message
=
'上传中...'
;
try
{
const
fd
=
new
FormData
();
fd
.
append
(
'file'
,
item
.
file
as
File
);
const
{
data
:
responseData
,
status
}
=
await
axios
.
post
(
'/api/employee/info/photo/upload'
,
fd
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
},
timeout
:
60
_000
,
},
);
if
(
status
>=
200
&&
status
<
300
&&
responseData
.
success
)
{
const
data
=
responseData
.
data
;
if
(
data
.
url
)
{
form
.
ossId
=
data
.
ossId
;
item
.
url
=
data
.
url
;
item
.
status
=
'done'
;
item
.
message
=
'上传成功'
;
}
else
{
item
.
status
=
'failed'
;
item
.
message
=
'上传失败'
;
showFailToast
(
'上传失败'
);
}
}
else
{
item
.
status
=
'failed'
;
item
.
message
=
'上传失败'
;
showFailToast
(
responseData
.
errMessage
||
'上传失败'
);
}
}
catch
(
e
)
{
item
.
status
=
'failed'
;
item
.
message
=
'上传失败'
;
showFailToast
(
'图片上传失败'
);
}
}
function
onDeletePhoto
()
{
form
.
ossId
=
0
;
}
function
onOversize
()
{
showFailToast
(
'文件大小不能超过20MB'
);
}
const
_tid
=
new
URL
(
window
.
location
.
href
).
searchParams
.
get
(
'tid'
);
if
(
_tid
)
{
form
.
tid
=
_tid
;
}
const
_did
=
new
URL
(
window
.
location
.
href
).
searchParams
.
get
(
'did'
);
const
hasDid
=
ref
(
!!
_did
);
if
(
_did
)
{
form
.
plateId
=
Number
(
_did
);
}
const
politicalOptions
=
[
{
value
:
'1'
,
text
:
'党员'
},
{
value
:
'2'
,
text
:
'预备党员'
},
{
value
:
'3'
,
text
:
'群众'
},
{
value
:
'4'
,
text
:
'团员'
},
{
value
:
'5'
,
text
:
'入党积极分子'
},
];
const
birthValues
=
ref
<
string
[]
>
([
_todayYear
-
25
+
''
,
'01'
,
'01'
]);
const
fullGraduateValues
=
ref
<
string
[]
>
([
_todayYear
-
10
+
''
,
'01'
]);
async
function
fetchPlateList
()
{
try
{
const
{
data
:
responseData
}
=
await
axios
.
get
(
'/api/employee/sysDept/queryPlateList'
);
if
(
responseData
.
success
&&
Array
.
isArray
(
responseData
.
data
))
{
plateOptions
.
value
=
responseData
.
data
.
map
((
item
:
{
id
:
number
;
name
:
string
})
=>
({
text
:
item
.
name
,
value
:
item
.
id
,
}));
}
else
{
showFailToast
(
responseData
.
errMessage
||
'获取板块列表失败'
);
}
}
catch
(
error
)
{
console
.
error
(
'Failed to fetch plate list'
,
error
);
showFailToast
(
'获取板块列表失败'
);
}
}
function
onPlateConfirm
(
payload
:
{
selectedOptions
:
{
text
:
string
;
value
:
number
}[];
})
{
const
opt
=
payload
.
selectedOptions
[
0
];
form
.
plateId
=
opt
.
value
;
form
.
plate
=
opt
.
text
;
showPlatePicker
.
value
=
false
;
}
function
onPoliticalConfirm
(
payload
:
{
selectedOptions
:
{
text
:
string
;
value
:
string
}[];
})
{
const
opt
=
payload
.
selectedOptions
[
0
];
form
.
politicalStatus
=
opt
.
value
;
form
.
politicalText
=
opt
.
text
;
showPoliticalPicker
.
value
=
false
;
}
function
onBirthConfirm
(
payload
:
{
selectedValues
:
string
[]
})
{
const
[
y
,
m
,
d
]
=
payload
.
selectedValues
;
form
.
birthDate
=
`
${
y
}
-
${
m
}
-
${
d
}
`
;
showBirthPicker
.
value
=
false
;
}
function
onFullGraduateConfirm
(
payload
:
{
selectedValues
:
string
[]
})
{
const
[
y
,
m
]
=
payload
.
selectedValues
;
form
.
fulltimeGraduationDate
=
`
${
y
}
-
${
m
}
`
;
showFullGraduatePicker
.
value
=
false
;
}
watch
(
()
=>
form
.
birthDate
,
(
v
)
=>
{
if
(
!
v
)
return
;
const
parts
=
v
.
split
(
'-'
).
map
((
x
)
=>
Number
(
x
));
if
(
parts
.
length
===
3
)
{
const
now
=
new
Date
();
const
birth
=
new
Date
(
parts
[
0
],
parts
[
1
]
-
1
,
parts
[
2
]);
let
a
=
now
.
getFullYear
()
-
birth
.
getFullYear
();
const
m
=
now
.
getMonth
()
-
birth
.
getMonth
();
const
d
=
now
.
getDate
()
-
birth
.
getDate
();
if
(
m
<
0
||
(
m
===
0
&&
d
<
0
))
a
--
;
form
.
age
=
a
;
}
},
);
const
CACHE_KEY
=
'HR_PART_TIME_FORM_CACHE'
;
function
saveCache
()
{
if
(
!
submitSuccess
.
value
)
{
try
{
const
photoList
=
Array
.
isArray
(
form
.
photoList
)
?
form
.
photoList
.
map
((
x
:
any
)
=>
({
url
:
x
?.
url
,
name
:
x
?.
name
}))
:
[];
const
data
=
{
plateId
:
form
.
plateId
,
plate
:
form
.
plate
,
name
:
form
.
name
,
phoneNumber
:
form
.
phoneNumber
,
gender
:
form
.
gender
,
genderText
:
form
.
genderText
,
photoList
,
ossId
:
form
.
ossId
,
idCardNumber
:
form
.
idCardNumber
,
birthDate
:
form
.
birthDate
,
age
:
form
.
age
,
homeAddress
:
form
.
homeAddress
,
ethnicity
:
form
.
ethnicity
,
nativePlace
:
form
.
nativePlace
,
maritalStatus
:
form
.
maritalStatus
,
maritalText
:
form
.
maritalText
,
politicalStatus
:
form
.
politicalStatus
,
politicalText
:
form
.
politicalText
,
emergencyContact
:
form
.
emergencyContact
,
emergencyContactPhone
:
form
.
emergencyContactPhone
,
introducer
:
form
.
introducer
,
introducerRelation
:
form
.
introducerRelation
,
fulltimeEducation
:
form
.
fulltimeEducation
,
fulltimeSchool
:
form
.
fulltimeSchool
,
fulltimeMajor
:
form
.
fulltimeMajor
,
fulltimeGraduationDate
:
form
.
fulltimeGraduationDate
,
fulltimeDegree
:
form
.
fulltimeDegree
,
bankCardNumber
:
form
.
bankCardNumber
,
bankName
:
form
.
bankName
,
hasRelativeInCompany
:
form
.
hasRelativeInCompany
,
relativeName
:
form
.
relativeName
,
tid
:
form
.
tid
,
};
localStorage
.
setItem
(
CACHE_KEY
,
JSON
.
stringify
(
data
));
}
catch
(
e
)
{
console
.
error
(
'Save cache failed'
,
e
);
}
}
}
function
loadCache
()
{
try
{
const
cached
=
localStorage
.
getItem
(
CACHE_KEY
);
if
(
cached
)
{
const
data
=
JSON
.
parse
(
cached
);
Object
.
assign
(
form
,
data
);
if
(
_did
)
{
form
.
plateId
=
Number
(
_did
);
form
.
plate
=
''
;
}
if
(
_tid
)
{
form
.
tid
=
_tid
;
}
}
}
catch
(
e
)
{
console
.
error
(
'Load cache failed'
,
e
);
}
}
const
scheduleSave
=
useDebounceFn
(
()
=>
{
if
(
submitSuccess
.
value
)
return
;
saveCache
();
},
1000
,
{
maxWait
:
5000
},
)
as
unknown
as
{
():
void
;
cancel
:
()
=>
void
};
watch
(
form
,
scheduleSave
,
{
deep
:
true
});
const
saveImmediately
=
()
=>
{
scheduleSave
.
cancel
();
saveCache
();
};
onMounted
(()
=>
{
if
(
!
hasDid
.
value
)
{
fetchPlateList
();
}
loadCache
();
const
onVisibilityChange
=
()
=>
{
if
(
document
.
visibilityState
===
'hidden'
)
saveImmediately
();
};
const
onPageHide
=
()
=>
{
saveImmediately
();
};
const
onPageShow
=
()
=>
{
loadCache
();
};
(
window
as
any
).
__onVisibilityChange__
=
onVisibilityChange
;
(
window
as
any
).
__onPageHide__
=
onPageHide
;
(
window
as
any
).
__onPageShow__
=
onPageShow
;
document
.
addEventListener
(
'visibilitychange'
,
onVisibilityChange
);
window
.
addEventListener
(
'pagehide'
,
onPageHide
);
window
.
addEventListener
(
'beforeunload'
,
saveImmediately
);
window
.
addEventListener
(
'pageshow'
,
onPageShow
);
});
onBeforeUnmount
(()
=>
{
const
onVisibilityChange
=
(
window
as
any
).
__onVisibilityChange__
;
const
onPageHide
=
(
window
as
any
).
__onPageHide__
;
const
onPageShow
=
(
window
as
any
).
__onPageShow__
;
if
(
onVisibilityChange
)
{
document
.
removeEventListener
(
'visibilitychange'
,
onVisibilityChange
);
}
if
(
onPageHide
)
{
window
.
removeEventListener
(
'pagehide'
,
onPageHide
);
}
window
.
removeEventListener
(
'beforeunload'
,
saveImmediately
);
if
(
onPageShow
)
{
window
.
removeEventListener
(
'pageshow'
,
onPageShow
);
}
saveImmediately
();
});
async
function
onSubmit
()
{
if
(
submitSuccess
.
value
)
{
showToast
(
'您已提交
\
n无需再次提交'
);
return
;
}
if
(
submitting
.
value
)
return
;
if
(
form
.
photoList
.
length
>
0
&&
form
.
ossId
===
0
)
{
showFailToast
(
'照片正在上传或上传失败,请稍后重试'
);
return
;
}
submitting
.
value
=
true
;
try
{
const
payload
=
{
plateId
:
form
.
plateId
,
plate
:
form
.
plate
,
name
:
form
.
name
,
phoneNumber
:
form
.
phoneNumber
,
gender
:
form
.
gender
,
birthDate
:
form
.
birthDate
,
age
:
form
.
age
,
ethnicity
:
form
.
ethnicity
,
nativePlace
:
form
.
nativePlace
,
maritalStatus
:
form
.
maritalStatus
,
politicalStatus
:
form
.
politicalStatus
,
idCardNumber
:
form
.
idCardNumber
,
homeAddress
:
form
.
homeAddress
,
emergencyContact
:
form
.
emergencyContact
,
emergencyContactPhone
:
form
.
emergencyContactPhone
,
introducer
:
form
.
introducer
,
introducerRelation
:
form
.
introducerRelation
,
fulltimeEducation
:
form
.
fulltimeEducation
,
fulltimeSchool
:
form
.
fulltimeSchool
,
fulltimeMajor
:
form
.
fulltimeMajor
,
fulltimeGraduationDate
:
form
.
fulltimeGraduationDate
?
form
.
fulltimeGraduationDate
+
'-01'
:
form
.
fulltimeGraduationDate
,
fulltimeDegree
:
form
.
fulltimeDegree
,
ossId
:
form
.
ossId
,
bankCardNumber
:
form
.
bankCardNumber
,
bankName
:
form
.
bankName
,
hasRelativeInCompany
:
form
.
hasRelativeInCompany
,
relativeName
:
form
.
relativeName
,
tenantId
:
form
.
tid
,
};
const
{
data
:
responseData
,
status
}
=
await
axios
.
post
(
'/api/employee/baseInfo/partTimeInfo'
,
payload
,
);
if
(
status
>=
200
&&
status
<
300
)
{
if
(
responseData
.
success
)
{
submitSuccess
.
value
=
true
;
localStorage
.
removeItem
(
CACHE_KEY
);
showSuccessToast
({
message
:
'提交成功'
,
duration
:
5000
});
}
else
{
showFailToast
(
responseData
.
errMessage
||
'提交失败'
);
}
}
else
{
showFailToast
(
'提交失败'
);
}
}
catch
(
e
)
{
showFailToast
(
'提交失败'
);
}
finally
{
submitting
.
value
=
false
;
}
}
</
script
>
<
style
scoped
>
.page
{
padding
:
12px
12px
88px
;
min-height
:
100vh
;
background
:
#f5f5f5
;
}
.form-item-horizontal
{
display
:
flex
;
align-items
:
center
;
margin-bottom
:
16px
;
}
.form-item-horizontal
.item-label
{
margin-bottom
:
0
;
margin-right
:
12px
;
min-width
:
70px
;
flex-shrink
:
0
;
}
.actions
{
position
:
fixed
;
bottom
:
0
;
left
:
0
;
right
:
0
;
z-index
:
1000
;
padding
:
12px
;
background
:
var
(
--van-background-2
);
box-shadow
:
0
-4px
12px
rgba
(
0
,
0
,
0
,
0.06
);
}
.section-card
{
background
:
#fff
;
border-radius
:
12px
;
padding
:
16px
;
box-shadow
:
0
1px
4px
rgba
(
0
,
0
,
0
,
0.04
);
border
:
1px
solid
#ebedf0
;
margin-bottom
:
16px
;
}
.section-title
{
font-size
:
16px
;
font-weight
:
600
;
color
:
#323233
;
margin-bottom
:
16px
;
display
:
flex
;
align-items
:
center
;
}
.help-text
{
font-size
:
12px
;
color
:
#969799
;
margin-top
:
4px
;
line-height
:
1.5
;
}
.van-cell.custom-field
{
background-color
:
#f7f8fa
;
border-radius
:
8px
;
padding
:
10px
12px
;
}
.van-cell.custom-field
::after
{
display
:
none
;
}
.native-input
{
width
:
100%
;
border
:
none
;
background
:
transparent
;
outline
:
none
;
padding
:
0
;
margin
:
0
;
font-size
:
16px
;
color
:
#323233
;
}
.dropdown-input
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
}
.form-item
{
margin-bottom
:
16px
;
}
.item-label
{
font-size
:
14px
;
color
:
#646566
;
margin-bottom
:
8px
;
}
.custom-input
{
background-color
:
#f7f8fa
;
border-radius
:
8px
;
padding
:
10px
12px
;
}
.form-row-2col
{
display
:
flex
;
gap
:
12px
;
margin-bottom
:
16px
;
}
.form-col
{
flex
:
1
;
}
.date-input-box
{
background-color
:
#f7f8fa
;
border-radius
:
8px
;
padding
:
10px
12px
;
font-size
:
14px
;
color
:
#323233
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
}
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment