小程序接入保安证号接口

This commit is contained in:
wangyilin 2024-12-02 10:17:58 +08:00
parent d12ca65f2c
commit 81d0d1e9f4
12 changed files with 216 additions and 29 deletions

View File

@ -1,7 +1,7 @@
# 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config # 配置文档参考 https://taro-docs.jd.com/docs/next/env-mode-config
TARO_APP_ID="wx0acd1c4fcf94bdd3" TARO_APP_ID="wx0acd1c4fcf94bdd3"
# TARO_APP_BASE_API="http://172.10.10.93:8765" # TARO_APP_BASE_API="http://172.10.10.93:8765"
TARO_APP_BASE_API="https://www.hnjinglian.cn:5678" TARO_APP_BASE_API="http://172.10.10.93:8765"

View File

@ -59,7 +59,6 @@
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"pinia": "^2.2.2", "pinia": "^2.2.2",
"vue": "^3.0.0" "vue": "^3.0.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.8.0", "@babel/core": "^7.8.0",

View File

@ -42,6 +42,7 @@
</view> </view>
</view> </view>
<view style="background-color: #e9eef4; height: 15rpx"></view> <view style="background-color: #e9eef4; height: 15rpx"></view>
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -95,6 +96,8 @@ const subModuleList = ref([
url: '', url: '',
}, },
]) ])
const subNavigation = async (url: string) => Taro.navigateTo({ url }) const subNavigation = async (url: string) => Taro.navigateTo({ url })
</script> </script>

View File

@ -30,7 +30,7 @@ class CustomRequest {
BASE_API: string = process.env.TARO_APP_BASE_API; BASE_API: string = process.env.TARO_APP_BASE_API;
private request<T>(url: string, method: keyof Taro.request.Method, options: ApiOptions, params?: object,): Promise<JsonResult<T>> { private request<T>(url: string, method: keyof Taro.request.Method, options: ApiOptions, params?: object,): Promise<JsonResult<T>> {
// console.log(this.BASE_API,'0000000') console.log(this.BASE_API,'0000000')
return new Promise<JsonResult<T>>((resolve, reject) => { return new Promise<JsonResult<T>>((resolve, reject) => {
if (options.loading) { if (options.loading) {
Taro.showLoading({ Taro.showLoading({

View File

@ -189,7 +189,9 @@ const formAdd = () => {
securityNumber: '', securityNumber: '',
remark: '', remark: '',
homeAddress: '', homeAddress: '',
telephone: '' telephone: '',
photo:'',
noSecurityNumberDesc:''
} as SecurityUserFormParams } as SecurityUserFormParams
Taro.navigateTo({url: `/subPages/projectManager/securityUserForm/securityUserForm?securityUser=${JSON.stringify(params)}&&type=formInput`}) Taro.navigateTo({url: `/subPages/projectManager/securityUserForm/securityUserForm?securityUser=${JSON.stringify(params)}&&type=formInput`})
} }
@ -237,6 +239,7 @@ const detail = (item: ServiceProjectSecurityUserPagerVo) => {
securityUserDetail.value = item securityUserDetail.value = item
} }
const securityUserEdit = (item: ServiceProjectSecurityUserPagerVo) => { const securityUserEdit = (item: ServiceProjectSecurityUserPagerVo) => {
console.log(item)
const params = {...item, sex: item.sex.value} const params = {...item, sex: item.sex.value}
Taro.navigateTo({url: `/subPages/projectManager/securityUserForm/securityUserForm?securityUser=${JSON.stringify(params)}&type=formInput`}) Taro.navigateTo({url: `/subPages/projectManager/securityUserForm/securityUserForm?securityUser=${JSON.stringify(params)}&type=formInput`})
} }

View File

@ -1,8 +1,12 @@
.form { .form {
.formButton { .formButton {
//position: fixed;
bottom: 60px;
display: flex; display: flex;
margin-top: auto; -webkit-justify-content: space-around;
justify-content: space-around; margin-bottom: 10rpx;
margin-bottom: 30px right: 0;
width: 100%;
height: 140px
} }
} }

View File

@ -1,6 +1,18 @@
<template> <template>
<view class="form"> <view class="form">
<nut-form ref="formRef" :model-value="formData" :rules="rules"> <nut-form ref="formRef" :model-value="formData" :rules="rules">
<nut-form-item label="头像" prop="avatar">
<view @click="chooseImage">
<image v-if="!Url" src="@/assets/logo/avatar1.png" style="width:50px;height: 50px"></image>
<image v-else :src="Url" style="width:150px;height: 150px"></image>
</view>
</nut-form-item>
<nut-form-item label="身份证" prop="idCard">
<view style="display: flex;justify-content: space-between;align-items: center">
<nut-input v-model="formData.idCard" placeholder="请填写身份证" type="text" @blur="cardBlur"/>
<view style="color: #3a6bbe;width: 70px;text-align: center;" @click="idCardBlur(formData,0)">查询</view>
</view>
</nut-form-item>
<nut-form-item label="姓名" prop="name"> <nut-form-item label="姓名" prop="name">
<nut-input v-model="formData.name" placeholder="请输入姓名" type="text"/> <nut-input v-model="formData.name" placeholder="请输入姓名" type="text"/>
</nut-form-item> </nut-form-item>
@ -11,9 +23,6 @@
</nut-radio> </nut-radio>
</nut-radio-group> </nut-radio-group>
</nut-form-item> </nut-form-item>
<nut-form-item label="身份证" prop="idCard">
<nut-input v-model="formData.idCard" placeholder="请填写身份证" type="text" @blur="idCardBlur"/>
</nut-form-item>
<nut-form-item label="出生日期" prop="dateOfBirth"> <nut-form-item label="出生日期" prop="dateOfBirth">
<view @click="showPicker = true"> <view @click="showPicker = true">
{{ {{
@ -34,16 +43,19 @@
<nut-form-item label="地址" prop="homeAddress"> <nut-form-item label="地址" prop="homeAddress">
<nut-input v-model="formData.homeAddress" placeholder="请输入地址" type="text"/> <nut-input v-model="formData.homeAddress" placeholder="请输入地址" type="text"/>
</nut-form-item> </nut-form-item>
<nut-form-item label="保安证号" prop="securityNumber"> <nut-form-item label="保安证号" prop="securityNumber">
<nut-input v-model="formData.securityNumber" placeholder="请输入保安证号" type="text"/> <nut-input v-model="formData.securityNumber" placeholder="请输入保安证号" type="text"/>
</nut-form-item> </nut-form-item>
<nut-form-item label="无证说明" v-if="!formData.securityNumber">
<nut-input v-model="formData.noSecurityNumberDesc" placeholder="无证说明" type="text"/>
</nut-form-item>
<nut-form-item label="备注" prop="remark"> <nut-form-item label="备注" prop="remark">
<nut-input v-model="formData.remark" placeholder="请填写备注" type="text"/> <nut-input v-model="formData.remark" placeholder="请填写备注" type="text"/>
</nut-form-item> </nut-form-item>
</nut-form> </nut-form>
<view class="formButton"> <view class="formButton">
<nut-button style="width: 45%" type="success" size="small" @click="submit">提交</nut-button> <nut-button style="width: 45%" type="success" size="small" @click="submit">提交</nut-button>
<nut-button style="width: 45%" size="small" @click="formRef?.reset()">重置表单</nut-button> <nut-button style="width: 45%" size="small" @click="reset">重置表单</nut-button>
</view> </view>
<nut-popup v-model:visible="showPicker" position="bottom"> <nut-popup v-model:visible="showPicker" position="bottom">
<nut-date-picker <nut-date-picker
@ -55,6 +67,15 @@
@cancel="showPicker = false" @cancel="showPicker = false"
></nut-date-picker> ></nut-date-picker>
</nut-popup> </nut-popup>
<nut-dialog content="详情" v-model:visible="visible" @ok="onOk" @cancel="cancel">
<slot>
<view style="margin-bottom: 5px">
<view>姓名{{ securityNumberByIdCard?.name ? securityNumberByIdCard?.name : '无' }}</view>
<view>保安证件号{{ securityNumberByIdCard?.bayzh ? securityNumberByIdCard?.bayzh : '无' }}</view>
<view>身份证{{ securityNumberByIdCard?.sfzhm ? securityNumberByIdCard?.sfzhm : "无" }}</view>
</view>
</slot>
</nut-dialog>
</view> </view>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -65,17 +86,22 @@ import api from "@/request";
import './securityUserForm.scss' import './securityUserForm.scss'
import Taro, {useLoad} from "@tarojs/taro"; import Taro, {useLoad} from "@tarojs/taro";
import dayjs from "dayjs"; import dayjs from "dayjs";
import {SecurityUserFormParams} from "@/types/subPages/projectManager/securityUserForm"; import {SecurityUserFormParams, securityNumberByIdCard} from "@/types/subPages/projectManager/securityUserForm";
import {FormInstance} from "@nutui/nutui-taro"; import {FormInstance} from "@nutui/nutui-taro";
import {generateSimpleObjectName, getResignedObjectUrl} from "@/utils";
const SEX = enumSelectNodes('Sex') const SEX = enumSelectNodes('Sex')
const minioBaseUrl = process.env.TARO_APP_MINIO_URL
const showPicker = ref(false) const showPicker = ref(false)
const Url =ref('')
const type = ref<'formInput' | 'QcCodeInput'>(null!); const type = ref<'formInput' | 'QcCodeInput'>(null!);
const formData = ref<SecurityUserFormParams>({} as any) const formData = ref<SecurityUserFormParams>({} as any)
const formRef = ref<FormInstance>(null!) const formRef = ref<FormInstance>(null!)
const visible = ref<boolean>(false)
const securityNumberByIdCard = ref<securityNumberByIdCard>()
const uploadRef = ref<any>(null)
const modelValue = ref('')
const rules: FormRules = { const rules: FormRules = {
name: [ name: [
@ -94,27 +120,63 @@ const rules: FormRules = {
] ]
}; };
useLoad((options) => { useLoad((options) => {
type.value = options.type; type.value = options.type;
if (type.value === 'QcCodeInput') { if (type.value === 'QcCodeInput') {
formData.value = { formData.value = {
name: '',
serviceProjectId: options.pid, serviceProjectId: options.pid,
securityUnitId: options.uid, securityUnitId: options.uid,
sex: 0, sex: 0,
idCard:null, idCard: null,
telephone:null, telephone: null,
dateOfBirth: null dateOfBirth: null,
noSecurityNumberDesc: options.noSecurityNumberDesc,
photo: options.photo,
} }
} else { } else {
const form = JSON.parse(options.securityUser) const form = JSON.parse(options.securityUser)
formData.value = Object.assign({}, form, {idCard: form.idCard.originalValue, telephone: form.telephone.originalValue}) console.log(form)
formData.value = Object.assign({}, form, {
idCard: form.idCard.originalValue,
telephone: form.telephone.originalValue
})
} }
}) })
const idCardBlur = (e: any) => { const idCardBlur = async (e: any, num: number) => {
const value = e.detail.value const value = e.idCard
if (value) {
Taro.request({
url: 'https://www.hnjinglian.cn:5678/common/querySecurityNumberByIdCard',
data: {
idCard: value
},
method: 'GET',
success: ({data}) => {
visible.value = true
securityNumberByIdCard.value = data.data
}
})
return
} else {
visible.value = false
console.log(value)
}
cardBlur(value, num)
}
const cardBlur = (e, num) => {
let value = ''
if (num === 0) {
value = e
} else {
value = e.detail.value
}
if (!value?.length || value.length < 18) { if (!value?.length || value.length < 18) {
formData.value.dateOfBirth = null; formData.value.dateOfBirth = null;
cancel()
return return
} }
const birthDate = value.substring(6, 14); const birthDate = value.substring(6, 14);
@ -124,7 +186,84 @@ const idCardBlur = (e: any) => {
formData.value.dateOfBirth = new Date(parseInt(year), parseInt(month) - 1, parseInt(day)) formData.value.dateOfBirth = new Date(parseInt(year), parseInt(month) - 1, parseInt(day))
} }
const onOk = () => {
formData.value.securityNumber = securityNumberByIdCard.value?.bayzh
formData.value.name = securityNumberByIdCard.value?.name
}
const cancel = () => {
formData.value.securityNumber = ''
formData.value.name = ''
visible.value = false
}
const chooseImage = () => {
Taro.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: async (resp) => {
Url.value = resp.tempFilePaths[0]
// console.log(resp.tempFilePaths[0])
const objectName = generateSimpleObjectName(resp.tempFiles[0].path, '/securityUser')
const uploadUrl = await getResignedObjectUrl(process.env.TARO_APP_MINIO_BUCKET, objectName)
modelValue.value = '/' + process.env.TARO_APP_MINIO_BUCKET + objectName;
console.log(modelValue)
// Taro.request({
// url: uploadUrl,
// data: resp.tempFiles,
// method: 'PUT',
// header: {
// 'content-type': 'application/json'
// },
// success: (resp) => {
// console.log(resp)
// }
// })
Taro.getFileSystemManager().readFile({
filePath: resp.tempFiles[0].path, //
encoding: 'base64', // base64
success (res) {
console.log(res.data)
// Blob
const blob = b64toBlob(res.data, 'image/jpeg'); // MIME
// File
const file = new File([blob], 'filename.jpg', {type: 'image/jpeg'});
console.log(file)
Taro.request({
url:uploadUrl,
data: file,
method:'PUT',
success:(res)=>{
console.log(res)
}
})
// 使 file
},
fail (err) {
console.error('读取文件失败:', err);
}
});
}
})
}
const b64toBlob = (b64Data, contentType='', sliceSize=512) =>{
const byteCharacters = atob(b64Data);
const byteArrays:any = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
return new Blob(byteArrays, {type: contentType});
}
const submit = () => { const submit = () => {
console.log(formData.value.photo)
formRef.value?.validate().then(async ({valid}) => { formRef.value?.validate().then(async ({valid}) => {
if (valid) { if (valid) {
let url: string; let url: string;
@ -146,16 +285,23 @@ const submit = () => {
securityUnitId: formData.value.securityUnitId, securityUnitId: formData.value.securityUnitId,
name: '', name: '',
workPost: '', workPost: '',
telephone: null , telephone: null,
sex: 0, sex: 0,
nativePlace: '', nativePlace: '',
idCard: null, idCard: null,
dateOfBirth: null, dateOfBirth: null,
securityNumber: '', securityNumber: '',
remark: '', remark: '',
homeAddress: '' homeAddress: '',
noSecurityNumberDesc: '',
photo: ''
} }
uploadRef.value?.clearUploadQueue()
} }
}) })
} }
const reset = () => {
formRef.value?.reset()
}
</script> </script>

View File

@ -0,0 +1,23 @@
import dayjs from "dayjs";
import api from "@/request";
export const generateSimpleObjectName = (fileName: string, parentDir?: String): string => {
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
let objectName = parentDir + dayjs().format('/YYYY/MM/DD/') + uuid.replace(/-/g, '');
console.log(fileName,objectName,'4444')
if (fileName && fileName.length > 0) {
objectName += fileName.substring(fileName.lastIndexOf('.'))
}
console.log(objectName,'888')
return objectName;
}
export const getResignedObjectUrl = async (bucketName: string, objectName: string): Promise<string> => {
return (await api.get<string>('/common/getResignedObjectUrl', {
bucketName,
objectName
})).data as string;
}

View File

@ -25,6 +25,10 @@ declare namespace NodeJS {
TARO_APP_ID: string TARO_APP_ID: string
/** 后台服务接口地址 **/ /** 后台服务接口地址 **/
TARO_APP_BASE_API: string TARO_APP_BASE_API: string
TARO_APP_MINIO_BUCKET:string
TARO_APP_MINIO_URL:string
} }
} }

View File

@ -2,7 +2,7 @@ export interface SecurityUserFormParams {
snowFlakeId?: string; snowFlakeId?: string;
securityUnitId: string; securityUnitId: string;
serviceProjectId: string; serviceProjectId: string;
name?: string; name: string | undefined;
workPost?: string; workPost?: string;
telephone: value | null; telephone: value | null;
sex: number; sex: number;
@ -10,7 +10,9 @@ export interface SecurityUserFormParams {
idCard: value | null; idCard: value | null;
dateOfBirth?: Date | null; dateOfBirth?: Date | null;
securityNumber?: string; securityNumber?: string;
photo?:string;
remark?: string; remark?: string;
noSecurityNumberDesc:string;
homeAddress?: string homeAddress?: string
} }
@ -18,3 +20,9 @@ export interface value{
desensitizedValue?:string desensitizedValue?:string
originalValue?:string originalValue?:string
} }
export interface securityNumberByIdCard{
name: string | undefined
bayzh?: string
sfzhm?: string
}

View File

@ -18,7 +18,6 @@ import MenuItem from "@/components/layout/MenuItem.vue";
const route = useRoute() const route = useRoute()
const activeMenus = computed(() => [route.path]); const activeMenus = computed(() => [route.path]);
console.log(activeMenus)
</script> </script>

View File

@ -206,7 +206,6 @@ const columns: TableProps['columns'] = [
<a-button danger>删除</a-button> <a-button danger>删除</a-button>
</a-popconfirm> </a-popconfirm>
<a-button type="primary" onClick={ async ()=>{ <a-button type="primary" onClick={ async ()=>{
console.log(record,'9999999')
visible.value = true visible.value = true
serviceTitle.value = '编辑服务项目' serviceTitle.value = '编辑服务项目'
idNumberDisabled.value = record.twoType.value !== 'outsource'; idNumberDisabled.value = record.twoType.value !== 'outsource';
@ -402,7 +401,6 @@ const formItemOptions = ref<FormProMaxItemOptions<serviceProjectSaveOrUpdatePara
const UnitId = ref('') const UnitId = ref('')
const submit = async()=>{ const submit = async()=>{
console.log(13123)
await formRef.value.validate() await formRef.value.validate()
const snowFlakeId = ref('') const snowFlakeId = ref('')
if (serviceTitle.value === '新增服务项目') { if (serviceTitle.value === '新增服务项目') {