552 lines
16 KiB
Vue
552 lines
16 KiB
Vue
<template>
|
||
<!-- 人员关键信息表单 -->
|
||
<view style="height: 100%">
|
||
<up-form
|
||
labelWidth="120"
|
||
labelPosition="left"
|
||
:model="keyInfoForm"
|
||
:rules="keyInfoFormRules"
|
||
ref="keyInfoFormRef"
|
||
>
|
||
<up-cell style="padding: 0 13px">
|
||
<template #icon>
|
||
<text class="red-text"> 此页面全部为必填项 </text>
|
||
</template>
|
||
</up-cell>
|
||
<up-form-item label="工种" prop="postName" :borderBottom="true">
|
||
<up-cell
|
||
isLink
|
||
size="large"
|
||
style="width: 100%"
|
||
@tap="onOpenPiker(1)"
|
||
:border="false"
|
||
:disabled="props.formType == 2"
|
||
>
|
||
<template #icon>
|
||
<text :class="{ 'color-text': keyInfoForm.postName }" class="time-text">
|
||
{{ keyInfoForm.postName || '选择工种' }}
|
||
</text>
|
||
</template>
|
||
</up-cell>
|
||
</up-form-item>
|
||
<up-form-item label="手机号" prop="phone" :borderBottom="true">
|
||
<up-input
|
||
clearable
|
||
border="none"
|
||
placeholder="请输入手机号"
|
||
v-model="keyInfoForm.phone"
|
||
:disabled="props.formType == 2"
|
||
/>
|
||
</up-form-item>
|
||
<up-form-item label="入场工程" prop="proName" :borderBottom="true">
|
||
<up-cell
|
||
isLink
|
||
size="large"
|
||
style="width: 100%"
|
||
@tap="onOpenPiker(2)"
|
||
:border="false"
|
||
:disabled="props.formType == 2"
|
||
>
|
||
<template #icon>
|
||
<text :class="{ 'color-text': keyInfoForm.proName }" class="time-text">
|
||
{{ keyInfoForm.proName || '选择入场工程' }}
|
||
</text>
|
||
</template>
|
||
</up-cell>
|
||
</up-form-item>
|
||
<up-form-item label="入场分包" prop="subName" :borderBottom="true">
|
||
<up-cell
|
||
isLink
|
||
size="large"
|
||
style="width: 100%"
|
||
@tap="onOpenPiker(3)"
|
||
:border="false"
|
||
:disabled="props.formType == 2"
|
||
>
|
||
<template #icon>
|
||
<text :class="{ 'color-text': keyInfoForm.subName }" class="time-text">
|
||
{{ keyInfoForm.subName || '选择入场分包' }}
|
||
</text>
|
||
</template>
|
||
</up-cell>
|
||
</up-form-item>
|
||
<up-form-item label="入场班组" prop="teamName" :borderBottom="true">
|
||
<up-cell
|
||
isLink
|
||
size="large"
|
||
style="width: 100%"
|
||
@tap="onOpenPiker(4)"
|
||
:border="false"
|
||
:disabled="props.formType == 2"
|
||
>
|
||
<template #icon>
|
||
<text :class="{ 'color-text': keyInfoForm.teamName }" class="time-text">
|
||
{{ keyInfoForm.teamName || '选择入场班组' }}
|
||
</text>
|
||
</template>
|
||
</up-cell>
|
||
</up-form-item>
|
||
|
||
<up-cell style="padding: 0 13px">
|
||
<template #icon>
|
||
<text class="red-text"> 特征信息采集 </text>
|
||
</template>
|
||
</up-cell>
|
||
<up-form-item label="人脸照片采集" prop="faceImg">
|
||
<up-upload
|
||
multiple
|
||
:maxCount="1"
|
||
name="faceImg"
|
||
accept="image"
|
||
@delete="deletePic"
|
||
@afterRead="afterRead"
|
||
:capture="['camera']"
|
||
:fileList="keyInfoForm.faceImg"
|
||
/>
|
||
</up-form-item>
|
||
</up-form>
|
||
|
||
<view class="red-text tip-container">
|
||
<text> 提醒事项: </text>
|
||
<text> 1: 入场后,即为入场即可考勤打卡</text>
|
||
<text> 2: 手机号会自动创建施工人员级别APP帐号,默认密码:HDsbd@123456</text>
|
||
<text> 3: 人脸照片采集用于考勤打卡(APP打卡、考勤机打卡) </text>
|
||
</view>
|
||
|
||
<!-- 工种 -->
|
||
<up-picker
|
||
:show="postPickerShow"
|
||
closeOnClickOverlay
|
||
@cancel="onCancelPost"
|
||
@confirm="onConfirmPost"
|
||
:columns="postPickerColumns"
|
||
@close="postPickerShow = false"
|
||
/>
|
||
<!-- 工程 -->
|
||
<up-picker
|
||
:show="proPickerShow"
|
||
@cancel="onCancelPro"
|
||
closeOnClickOverlay
|
||
@confirm="onConfirmPro"
|
||
:columns="proPickerColumns"
|
||
@close="proPickerShow = false"
|
||
/>
|
||
<!-- 分包 -->
|
||
<up-picker
|
||
:show="subPickerShow"
|
||
@cancel="onCancelSub"
|
||
closeOnClickOverlay
|
||
@confirm="onConfirmSub"
|
||
:columns="subPickerColumns"
|
||
@close="subPickerShow = false"
|
||
/>
|
||
<!-- 班组 -->
|
||
<up-picker
|
||
:show="teamPickerShow"
|
||
@cancel="onCancelTeam"
|
||
closeOnClickOverlay
|
||
@confirm="onConfirmTeam"
|
||
:columns="teamPickerColumns"
|
||
@close="teamPickerShow = false"
|
||
/>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup name="keyInfoForm">
|
||
import { ref, onMounted, watch } from 'vue'
|
||
import {
|
||
getPostTypeSelectListAPI,
|
||
getSubSelectListByConditionAPI,
|
||
getTeamSelectListByConditionAPI,
|
||
getLotProjectSelectListByConditionAPI,
|
||
} from '@/services/common'
|
||
|
||
const keyInfoFormRef = ref(null) // 关键信息校验表单ref
|
||
const photoIds = ref('') // 上传文件列表 存储ID
|
||
const keyInfoForm = ref({
|
||
proId: '', // 入场工程
|
||
postId: '', // 工种
|
||
subId: '', // 入场分包
|
||
phone: '', // 手机号码
|
||
teamId: '', // 入场班组
|
||
proName: '', // 入场工程名称
|
||
subName: '', // 入场分包名称
|
||
teamName: '', // 入场班组名称
|
||
postName: '', // 工种名称
|
||
faceImg: [], // 人脸照片
|
||
}) // 身份证表单数据
|
||
const keyInfoFormRules = ref({
|
||
postName: [
|
||
{
|
||
type: 'string',
|
||
required: true,
|
||
message: '请选择工种',
|
||
},
|
||
],
|
||
phone: [
|
||
{
|
||
type: 'string',
|
||
required: true,
|
||
message: '请输入手机号',
|
||
},
|
||
{
|
||
pattern: /^1[3-9]\d{9}$/,
|
||
message: '请输入正确的手机号',
|
||
},
|
||
],
|
||
proName: [
|
||
{
|
||
type: 'string',
|
||
required: true,
|
||
message: '请选择入场工程',
|
||
},
|
||
],
|
||
subName: [
|
||
{
|
||
type: 'string',
|
||
required: true,
|
||
message: '请选择入场分包',
|
||
},
|
||
],
|
||
teamName: [
|
||
{
|
||
type: 'string',
|
||
required: true,
|
||
message: '请选择入场班组',
|
||
},
|
||
],
|
||
faceImg: [
|
||
{
|
||
type: 'array',
|
||
required: true,
|
||
message: '请上传人脸照片',
|
||
},
|
||
],
|
||
}) // 身份证表单规则
|
||
|
||
const postPickerShow = ref(false) // 工种选择器
|
||
const proPickerShow = ref(false) // 工程选择器
|
||
const subPickerShow = ref(false) // 分包选择器
|
||
const teamPickerShow = ref(false) // 班组选择器
|
||
const postPickerColumns = ref([[]]) // 工种选择器列
|
||
|
||
const proPickerColumns = ref([[]]) // 工程选择器列
|
||
|
||
const subPickerColumns = ref([[]]) // 分包选择器列
|
||
const teamPickerColumns = ref([[]]) // 班组选择器列
|
||
|
||
// 打开选择器
|
||
const onOpenPiker = (type) => {
|
||
switch (type) {
|
||
case 1:
|
||
postPickerShow.value = true
|
||
break
|
||
case 2:
|
||
proPickerShow.value = true
|
||
break
|
||
case 3:
|
||
subPickerShow.value = true
|
||
break
|
||
case 4:
|
||
teamPickerShow.value = true
|
||
break
|
||
}
|
||
}
|
||
|
||
// 工种确认
|
||
const onConfirmPost = (e) => {
|
||
keyInfoForm.value.postName = e.value[0].text
|
||
keyInfoForm.value.postId = e.value[0].value
|
||
postPickerShow.value = false
|
||
}
|
||
|
||
// 工种取消
|
||
const onCancelPost = () => {
|
||
keyInfoForm.value.postName = ''
|
||
keyInfoForm.value.postId = ''
|
||
postPickerShow.value = false
|
||
}
|
||
|
||
// 工程确认
|
||
const onConfirmPro = (e) => {
|
||
keyInfoForm.value.proName = e.value[0].text
|
||
keyInfoForm.value.proId = e.value[0].value
|
||
proPickerShow.value = false
|
||
getSubSelectListByCondition(e.value[0].value)
|
||
}
|
||
|
||
// 工程取消
|
||
const onCancelPro = () => {
|
||
keyInfoForm.value.proName = ''
|
||
keyInfoForm.value.proId = ''
|
||
keyInfoForm.value.subName = ''
|
||
keyInfoForm.value.subId = ''
|
||
keyInfoForm.value.teamName = ''
|
||
keyInfoForm.value.teamId = ''
|
||
proPickerShow.value = false
|
||
subPickerColumns.value[0] = []
|
||
teamPickerColumns.value[0] = []
|
||
}
|
||
|
||
// 分包确认
|
||
const onConfirmSub = (e) => {
|
||
keyInfoForm.value.subName = e.value[0].text
|
||
keyInfoForm.value.subId = e.value[0].value
|
||
subPickerShow.value = false
|
||
getTeamSelectListByCondition(e.value[0].value)
|
||
}
|
||
|
||
// 分包取消
|
||
const onCancelSub = () => {
|
||
keyInfoForm.value.subName = ''
|
||
keyInfoForm.value.subId = ''
|
||
keyInfoForm.value.teamName = ''
|
||
keyInfoForm.value.teamId = ''
|
||
subPickerShow.value = false
|
||
teamPickerColumns.value[0] = []
|
||
}
|
||
|
||
// 班组确认
|
||
const onConfirmTeam = (e) => {
|
||
keyInfoForm.value.teamName = e.value[0].text
|
||
keyInfoForm.value.teamId = e.value[0].value
|
||
teamPickerShow.value = false
|
||
}
|
||
|
||
// 班组取消
|
||
const onCancelTeam = () => {
|
||
keyInfoForm.value.teamName = ''
|
||
keyInfoForm.value.teamId = ''
|
||
teamPickerShow.value = false
|
||
}
|
||
|
||
// 删除图片
|
||
const deletePic = (e) => {
|
||
// console.log(e)
|
||
keyInfoForm.value.faceImg = []
|
||
}
|
||
|
||
// 上传图片
|
||
const afterRead = (e) => {
|
||
console.log(e, '选择的文件')
|
||
const type = e.file[0].type
|
||
if (!type.includes('image')) {
|
||
uni.$u.toast('请上传图片格式')
|
||
return
|
||
}
|
||
|
||
const files = [
|
||
{
|
||
file: e.file[0].url,
|
||
name: 'file',
|
||
uri: e.file[0].url,
|
||
},
|
||
]
|
||
uni.uploadFile({
|
||
url: '/bmw/worker/faceDetection',
|
||
files: files,
|
||
name: 'file',
|
||
isUploadFile: true,
|
||
success: (res) => {
|
||
const data = JSON.parse(res.data)
|
||
if (data.code === 200) {
|
||
uni.uploadFile({
|
||
url: '/bmw/app/uploadFile',
|
||
files: files,
|
||
name: 'file',
|
||
isUploadFile: true,
|
||
formData: {
|
||
type: 1,
|
||
},
|
||
success: (res) => {
|
||
const data = JSON.parse(res.data)
|
||
if (data.code === 200) {
|
||
keyInfoForm.value.faceImg.push({
|
||
...e.file[0],
|
||
})
|
||
// 走上传逻辑 上传成功后把ID插入到fileList中
|
||
// keyInfoForm.value.photoIds = data.data
|
||
photoIds.value = data.data
|
||
} else {
|
||
uni.$u.toast('上传失败')
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
uni.$u.toast('上传失败,请重新上传')
|
||
},
|
||
})
|
||
} else {
|
||
uni.$u.toast('人脸识别失败')
|
||
keyInfoForm.value.faceImg = []
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
uni.$u.toast('人脸识别失败')
|
||
},
|
||
})
|
||
//
|
||
}
|
||
|
||
// 表单校验
|
||
const validateKeyInfoForm = async () => {
|
||
return new Promise((resolve, reject) => {
|
||
keyInfoFormRef.value
|
||
.validate()
|
||
.then((valid) => {
|
||
if (valid) {
|
||
let data = {}
|
||
if (photoIds.value) {
|
||
data = { photoIds: photoIds.value, ...keyInfoForm.value }
|
||
} else {
|
||
data = { ...keyInfoForm.value }
|
||
}
|
||
|
||
let params = {
|
||
isValid: true,
|
||
data,
|
||
}
|
||
|
||
resolve(params)
|
||
}
|
||
})
|
||
.catch((err) => {
|
||
reject(false)
|
||
})
|
||
})
|
||
}
|
||
|
||
// 获取工种
|
||
const getPostTypeSelectList = async () => {
|
||
try {
|
||
const { rows: res } = await getPostTypeSelectListAPI()
|
||
if (res && res.length > 0) {
|
||
postPickerColumns.value[0] = res.map((item) => {
|
||
return {
|
||
text: item.postName,
|
||
value: item.id,
|
||
}
|
||
})
|
||
}
|
||
} catch (error) {}
|
||
}
|
||
|
||
// 获取工程
|
||
const getLotProjectSelectListByCondition = async () => {
|
||
try {
|
||
const { data: res } = await getLotProjectSelectListByConditionAPI({})
|
||
if (res && res.length > 0) {
|
||
proPickerColumns.value[0] = res.map((item) => {
|
||
return {
|
||
text: item.name,
|
||
value: item.id,
|
||
}
|
||
})
|
||
}
|
||
} catch (error) {}
|
||
}
|
||
// 获取分包
|
||
const getSubSelectListByCondition = async (proId) => {
|
||
try {
|
||
const { data: res } = await getSubSelectListByConditionAPI({ proId })
|
||
// console.log(res, 'res--9996')
|
||
if (res && res.length > 0) {
|
||
subPickerColumns.value[0] = res.map((item) => {
|
||
return {
|
||
text: item.name,
|
||
value: item.id,
|
||
}
|
||
})
|
||
}
|
||
} catch (error) {}
|
||
}
|
||
|
||
// 获取班组
|
||
const getTeamSelectListByCondition = async (subId) => {
|
||
try {
|
||
const { data: res } = await getTeamSelectListByConditionAPI({ subId })
|
||
|
||
if (res && res.length > 0) {
|
||
teamPickerColumns.value[0] = res.map((item) => {
|
||
return {
|
||
text: item.name,
|
||
value: item.id,
|
||
}
|
||
})
|
||
}
|
||
} catch (error) {}
|
||
}
|
||
|
||
onMounted(() => {
|
||
getPostTypeSelectList()
|
||
getLotProjectSelectListByCondition()
|
||
})
|
||
|
||
const props = defineProps({
|
||
keyInfo: {
|
||
type: Object,
|
||
default: () => {},
|
||
},
|
||
formType: {
|
||
type: [Number, String], // 表单类型
|
||
default: 1,
|
||
},
|
||
})
|
||
|
||
const updateKeyInfoInfo = () => {
|
||
Object.assign(keyInfoForm.value, props.keyInfo)
|
||
// console.log(keyInfoForm.value, 'keyInfoForm.value')
|
||
}
|
||
|
||
// 向父组件暴露方法
|
||
defineExpose({
|
||
validateKeyInfoForm,
|
||
updateKeyInfoInfo,
|
||
})
|
||
|
||
// 增加监听
|
||
watch(
|
||
props.keyInfo,
|
||
(newVal) => {
|
||
if (Object.keys(newVal).length > 0) {
|
||
Object.assign(keyInfoForm.value, newVal)
|
||
}
|
||
},
|
||
{
|
||
immediate: true,
|
||
},
|
||
)
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
@import '@/uni.scss';
|
||
|
||
.blue-text {
|
||
font-size: 14px;
|
||
color: $uni-color-primary;
|
||
}
|
||
|
||
.u-form-item {
|
||
padding: 0 15px;
|
||
}
|
||
|
||
::v-deep .u-cell__body {
|
||
padding: 13px 0;
|
||
}
|
||
|
||
.color-text {
|
||
color: rgb(48, 49, 51) !important;
|
||
}
|
||
|
||
.time-text {
|
||
color: rgb(192, 196, 204);
|
||
}
|
||
|
||
.tip-container {
|
||
padding: 0 13px;
|
||
margin-top: 30px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
}
|
||
</style>
|