YNUtdPlatform/pages/realName/workbench/contractWitness/index.vue

693 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page">
<u-navbar class="u-navbar" title="合同见证" placeholder @leftClick="leftClick" leftIconColor="#fff" bgColor="#00337A" :titleStyle="{ color: '#FFF', fontSize: '32rpx' }"/>
<scroll-view class="content" scroll-y="true">
<view class="img-view">
<view class="view-item">
<view style="width: 20%;">工程名称</view>
<view style="margin-left: 40rpx;width: 70%;">{{proName}}</view>
</view>
<view class="view-item" style="display: block;">
<view>合同见证</view>
<view class="img-box">
<view class="img-item upload-btn" @click="open()">
<image class="img" src="@/static/realName/tianjia-img.png" mode=""></image>
</view>
<view class="img-item" v-if="imgUrl!=''" @click="openImg">
<image class="img" :src="imgUrl" mode=""></image>
</view>
<view class="img-item" v-if="pdfUrl!=''" @click="openPdf">
<image class="img" src="../../../../static/realName/pdf.png" mode=""></image>
</view>
<xe-upload ref="XeUpload" :options="uploadOptions" @callback="handleUploadCallback"></xe-upload>
</view>
</view>
<view class="view-item">
<view>人脸识别</view>
<view style="margin-left: 40rpx;" class="btn" @click="distinguish">点击人脸识别</view>
</view>
<view class="view-item" v-if="faceData.name">
<view>姓名</view>
<view style="margin-left: 40rpx;width: 70%;">{{faceData.name}}</view>
</view>
<view class="view-item" v-if="faceData.idNumber">
<view>身份证</view>
<view style="margin-left: 40rpx;width: 70%;">{{faceData.idNumber}}</view>
</view>
<view class="view-item" v-if="faceData.age">
<view>年龄</view>
<view style="margin-left: 40rpx;width: 70%;">{{faceData.age}}</view>
</view>
</view>
<view class="img-view" style="margin-bottom: 40rpx;">
<u--form class="addForm" :model="entryContractBean" ref="cForm">
<view class="form-input-box">
<view style="width:25%;height: 100%;">
<text>合同编号</text>
</view>
<u-form-item prop='contractCode' style="width:70%;height: 100%;" >
<u--input v-model="entryContractBean.contractCode" type="text" placeholder="请输入" maxlength="40" border="surround" clearable></u--input>
</u-form-item>
</view>
<view style="width: 100%;height: auto;">
<view style="width:25%;height: 100%;margin: 20rpx;">
<text>合同期限类型</text>
</view>
<u-form-item prop='laborContractType' style="width:98%;height: 100%;margin: 0 auto;" >
<u-radio-group v-model="entryContractBean.laborContractType" placement="row" style="border: 1rpx solid #ccc;padding:20rpx 0rpx;border-radius: 10rpx;display: flex;">
<u-radio label="完成一定工作为期限的合同" name="以完成一定工作为期限的合同" style="margin-right: 0rpx;transform:scale(0.8);"></u-radio>
<u-radio label="固定期限合同" name="固定期限合同" style="transform:scale(0.8);"></u-radio>
</u-radio-group>
</u-form-item>
</view>
<view class="form-input-box">
<view style="width:25%;height: 100%;">
<text>人员角色</text>
</view>
<u-form-item prop='role' style="width:70%;height: 100%;" >
<uni-data-select v-model="entryContractBean.role" :localdata="roleList"></uni-data-select>
</u-form-item>
</view>
<view class="form-input-box">
<view style="width:25%;height: 100%;">
<text>合同签订日期</text>
</view>
<u-form-item prop='contractValidDate' style="width:70%;height: 100%;" >
<uni-datetime-picker type="date" :clear-icon="false" format="YYYY-MM-DD" v-model="entryContractBean.contractValidDate"/>
</u-form-item>
</view>
<view class="form-input-box">
<view style="width:25%;height: 100%;">
<text>合同终止日期</text>
</view>
<u-form-item prop='contractInvalidDate' style="width:70%;height: 100%;" >
<uni-datetime-picker type="date" :clear-icon="false" format="YYYY-MM-DD" v-model="entryContractBean.contractInvalidDate"/>
</u-form-item>
</view>
<view class="form-input-box">
<view style="width:25%;height: 100%;">
<text>合同类型</text>
</view>
<u-form-item prop='contractType' style="width:70%;height: 100%;" >
<u--input v-model="entryContractBean.contractType" type="text" readonly border="surround"></u--input>
</u-form-item>
</view>
<view class="form-input-box">
<view style="width:25%;height: 100%;">
<text>工资核定方式</text>
</view>
<u-form-item prop='wageApprovedWay' style="width:70%;height: 100%;" >
<u--input v-model="entryContractBean.wageApprovedWay" type="text" readonly border="surround"></u--input>
</u-form-item>
</view>
<view class="form-input-box">
<view style="width:25%;height: 100%;">
<text>工资核定标准</text>
</view>
<u-form-item prop='wageCriterion' style="width:70%;height: 100%;" >
<u--input v-model="entryContractBean.wageCriterion" type="number" placeholder="请输入" maxlength="3" border="surround" clearable></u--input>
</u-form-item>
</view>
<view class="form-input-box">
<view style="width:25%;height: 100%;">
<text>是否参加城乡居民医疗保险</text>
</view>
<u-form-item prop='isYiLiao' style="width:70%;height: 100%;" >
<u-radio-group v-model="entryContractBean.isYiLiao" placement="row" style="border: 1rpx solid #ccc;padding: 16rpx;border-radius: 10rpx;">
<u-radio label="否" name="否" style="margin-right: 40rpx;"></u-radio>
<u-radio label="是" name="是"></u-radio>
</u-radio-group>
</u-form-item>
</view>
<view class="form-input-box">
<view style="width:25%;height: 100%;">
<text>是否参加城乡居民养老保险</text>
</view>
<u-form-item prop='isYangLao' style="width:70%;height: 100%;" >
<u-radio-group v-model="entryContractBean.isYangLao" placement="row" style="border: 1rpx solid #ccc;padding: 16rpx;border-radius: 10rpx;">
<u-radio label="否" name="否" style="margin-right: 40rpx;"></u-radio>
<u-radio label="是" name="是"></u-radio>
</u-radio-group>
</u-form-item>
</view>
<view class="form-input-box">
<view style="width:25%;height: 100%;">
<text>是否在职</text>
</view>
<u-form-item prop='whetherOnJob' style="width:70%;height: 100%;" >
<u-radio-group v-model="entryContractBean.whetherOnJob" placement="row" style="border: 1rpx solid #ccc;padding: 16rpx;border-radius: 10rpx;">
<u-radio label="否" name="否" style="margin-right: 40rpx;"></u-radio>
<u-radio label="是" name="是"></u-radio>
</u-radio-group>
</u-form-item>
</view>
</u--form>
</view>
<view class="sumbit-btn" @click="sumbit">确 定</view>
</scroll-view>
<!-- 新增人员表单 -->
<u-popup :show="showPopup" mode="center" @close="close" >
<view style="width:600rpx;height: 100%;position: relative;background-color: #fff;">
<view class="popup-header">
<view style="width: 10%;height: 80rpx;"></view>
<view style="width: 80%;height: 80rpx;line-height: 80rpx;text-align: center;font-weight: bold;">请选择类型</view>
<u-icon style="width: 10%;" name="close" color="#000" size="24" @click="close"></u-icon>
</view>
<view class="popup-content">
<view class="btn2" @click="openPhotograph">拍照</view>
<view class="btn2" @click="chooseFiles">PDF</view>
</view>
</view>
</u-popup>
<u-popup :show="showImgPopup" mode="center" @close="closeImg" >
<view style="width:500rpx;height: 100%;position: relative;background-color: #fff;">
<view class="popup-content" style="height: 50vh;">
<image style="width: 100%;height: 100%;" :src="imgUrl" mode=""></image>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import { pathToBase64, base64ToPath } from 'image-tools';
import chooseFile from '../../util/chooseFile.js';
import config from '@/config'
export default {
data() {
return {
showPopup:false,
showImgPopup:false,
imgUrl:'',
pdfUrl:'',
faceData:{},
proName:"xxx工程",
proId:uni.getStorageSync('realNameUser').proId,
entryContractBean:{
"id":'',
"idNumber":"",
"proId":"",//工程id
"uploadDate": "",//日期
"uploadTime": "",//时间
"uploadId": uni.getStorageSync('realNameUser').userId,//上传人id
"witnessType": "1",
"isActive": "1",
"witnessPath": "",//图片地址
"contractCode": "",//合同编号
// "contractPath": "",//合同见证照片
"role": "",//人员角色
"laborContractType": "固定期限合同",//合同期限类型
"contractValidDate": this.getCurrentDate(),//合同签订日期
"contractInvalidDate": this.getCurrentDate(),//合同终止日期
"contractType": "纸质合同",//合同类型
"wageApprovedWay": "天",//工资核定方式
"wageCriterion": "",//工资核定标准
"isYiLiao": "是",//是否参加城乡居民医疗保险
"isYangLao": "是",//是否参加城乡居民养老保险
"whetherOnJob": "是"//是否在职
},
roleList:[
{value:'管理人员',text:'管理人员'},
{value:'务工人员',text:'务工人员'},
{value:'劳资专管员',text:'劳资专管员'}
],
uploadOptions: {
// url: 'http://192.168.31.185:3000/api/upload', // 不传入上传地址则返回本地链接
},
// imgs: [],
// imgsId: [],
}
},
onLoad() {
this.getPro()
console.log('🚀 ~ mounted ~ mounted-index:')
},
onShow() {
},
methods: {
// 获取工程名称
getPro(){
let param={
id:this.proId,
subId:-1
}
uni.request({
url: config.realAppUrl + '/offLine/getPro',
method: 'post',
data: param,
header: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: uni.getStorageSync('realNameToken')
},
success: res => {
res = res.data;
if(res.code==200){
console.log(res)
this.proName = res.data[0].abbreviation||"";
}
},
fail: err => {
console.log(err)
}
})
},
//人脸识别采集
distinguish(){
console.log('人脸识别采集')
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['camera'],
success: res => {
console.log('🚀 ~ res-拍照:', res)
this.imgToBase64(res.tempFilePaths[0]).then(base64 => {
// console.log(base64)
uni.uploadFile({
url: config.realFileUrl+'file/getFaceRecognition', //服务器地址
fileType:"image",//ZFB必填,不然报错
filePath: res.tempFilePaths[0],//这个就是我们上面拍照返回或者先中照片返回的数组
formData: {
file:base64,
photoType:'face',
},
success: (uploadFileRes) => {
console.log(uploadFileRes)
if(uploadFileRes.statusCode==200){
uploadFileRes=JSON.parse(uploadFileRes.data)
console.log(uploadFileRes)
if(uploadFileRes.code==200){
if(uploadFileRes.data.face){
this.faceData=JSON.parse(uploadFileRes.data.personData)
console.log(this.faceData)
if(this.faceData){
this.entryContractBean.idNumber = this.faceData.idNumber;
this.entryContractBean.proId = this.faceData.proId;
// this.proName = this.faceData.proName;
let birthday = new Date(this.faceData.birthday).getTime();
let now = new Date().getTime();
let hours = (now-birthday)/3600000;
let year = Math.floor(hours / (24 * 30 * 12));
this.faceData.age = year
uni.$u.toast('人脸认证成功!');
}else{
uni.$u.toast('识别失败');
}
}else{
uni.$u.toast(uploadFileRes.msg);
}
}else{
uni.$u.toast(uploadFileRes.msg);
}
}else{
uni.$u.toast('识别失败');
}
},
fail: err => {
uni.$u.toast('识别失败');
console.log(err)
}
});
})
},
fail: err => {
console.log('🚀 ~ err:', err)
}
})
},
open(){this.showPopup=true;},
close(){this.showPopup=false;},
openImg(){this.showImgPopup=true;},
closeImg(){this.showImgPopup=false;},
// 拍照录入
openPhotograph() {
this.showPopup = false
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['camera'],
success: res => {
console.log('🚀 ~ res-拍照:', res)
uni.uploadFile({
url: config.realFileUrl+`file/upload`, //服务器地址
fileType:"image",//ZFB必填,不然报错
filePath: res.tempFilePaths[0],//这个就是我们上面拍照返回或者先中照片返回的数组
name: "imgFile",
formData: {
photoType:'Contract',
},
success: (uploadFileRes) => {
console.log(uploadFileRes)
if(uploadFileRes.statusCode==200){
this.entryContractBean.witnessPath=JSON.parse(uploadFileRes.data).data.url;
}else{
uni.$u.toast('上传失败');
}
},
fail: err => {
uni.$u.toast('上传失败');
console.log(err)
}
});
this.imgToBase64(res.tempFilePaths[0]).then(base64 => {
this.imgUrl=base64
})
},
fail: err => {
console.log('🚀 ~ err:', err)
}
})
},
imgToBase64(data) {
return new Promise((resolve, reject) => {
pathToBase64(data)
.then(base64 => {
resolve(base64)
})
.catch(error => {
console.error(error)
reject(error)
})
})
},
handleUploadCallback(e) {
console.log(e)
console.log(e.data[0].tempFilePath)
if(e.type=="choose"){
if(e.data[0].type.split("/")[1]=="pdf"){
uni.uploadFile({
url: config.realFileUrl+`file/upload`, //服务器地址
// fileType:"image",//ZFB必填,不然报错
filePath: e.data[0].tempFilePath,//这个就是我们上面拍照返回或者先中照片返回的数组
name: "file",
formData: {
photoType:'Contract',
},
success: (uploadFileRes) => {
console.log(uploadFileRes);
if(uploadFileRes.statusCode==200){
this.entryContractBean.witnessPath=JSON.parse(uploadFileRes.data).data.url;
this.pdfUrl = e.data[0].tempFilePath
uni.$u.toast('上传成功');
}else{
uni.$u.toast('上传失败');
}
}
});
}else{
uni.$u.toast('只能上传Pdf文件');
}
}
// e.type: ['choose', 'success', 'warning']
// choose 是options没有传入url返回临时链接时触发
// success 是上传成功返回对应的数据时触发
// warning 上传或者选择文件失败触发
// ......
},
chooseFiles(){
this.showPopup = false
this.$refs.XeUpload.upload('file', {});
},
openPdf(){
console.log("pdf")
uni.navigateTo({
url: `/pages/realName/workbench/contractWitness/contractPdf?pdfUrl=${this.pdfUrl}`
})
},
sumbit(){
this.entryContractBean.id=this.uuid()
console.log(this.entryContractBean.id)
if(this.entryContractBean.idNumber==''){
uni.$u.toast('未进行人脸验证!');
}else if(this.entryContractBean.witnessPath==''){
uni.$u.toast('合同见证未上传!');
}else if(this.entryContractBean.contractCode==''){
uni.$u.toast('请填写合同编号');
}else if(this.entryContractBean.role==''){
uni.$u.toast('请选择人员角色');
}else if(this.entryContractBean.contractValidDate==''){
uni.$u.toast('请选择合同签订日期');
}else if(this.entryContractBean.contractInvalidDate==''){
uni.$u.toast('请选择合同终止日期');
}else if(this.entryContractBean.wageCriterion==''){
uni.$u.toast('请填写工资核定标准');
}else if(Number(this.entryContractBean.wageCriterion)>600){
uni.$u.toast('工资核定标准为60~600');
}else if(Number(this.entryContractBean.wageCriterion)<60){
uni.$u.toast('工资核定标准为60~600');
}else{
this.entryContractBean.uploadDate = this.timeFormat(null,'yyyy-mm-dd');
this.entryContractBean.uploadTime = this.timeFormat(null,'yyyy-mm-dd hh:MM:ss');
console.log(this.entryContractBean)
uni.showModal({
title: `确认上传合同见证?`,
cancelText: '取消',
confirmText: '确定',
success: res => {
if (res.confirm) {
this.uploadContract();
}
}
});
}
},
uploadContract(){
uni.request({
url: config.realAppUrl+'/contractWitness/uploadContract',
method: 'post',
data: this.entryContractBean,
header: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: uni.getStorageSync('realNameToken')
},
success: res => {
console.log(res)
res = res.data;
if(res.code==200){
uni.showToast({
title: res.data,
icon: 'none'
})
uni.navigateBack({
delta: 1 // 返回到已存在的页面
});
}else{
uni.showToast({
title: res.msg,
icon: 'none'
})
}
},
fail: err => {
console.log(err)
}
})
},
// 返回
leftClick() {
console.log('返回')
uni.navigateBack({
delta: 1 // 返回
});
},
getCurrentDate() {
const now = new Date();
return `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
},
timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') {
let date
// 若传入时间为假值,则取当前时间
if (!dateTime) {
date = new Date()
}
// 若为unix秒时间戳则转为毫秒时间戳逻辑有点奇怪但不敢改以保证历史兼容
else if (/^\d{10}$/.test(dateTime?.toString().trim())) {
date = new Date(dateTime * 1000)
}
// 若用户传入字符串格式时间戳new Date无法解析需做兼容
else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) {
date = new Date(Number(dateTime))
}
// 处理平台性差异在Safari/Webkit中new Date仅支持/作为分割符的字符串时间
// 处理 '2022-07-10 01:02:03',跳过 '2022-07-10T01:02:03'
else if (typeof dateTime === 'string' && dateTime.includes('-') && !dateTime.includes('T')) {
date = new Date(dateTime.replace(/-/g, '/'))
}
// 其他都认为符合 RFC 2822 规范
else {
date = new Date(dateTime)
}
const timeSource = {
'y': date.getFullYear().toString(), // 年
'm': (date.getMonth() + 1).toString().padStart(2, '0'), // 月
'd': date.getDate().toString().padStart(2, '0'), // 日
'h': date.getHours().toString().padStart(2, '0'), // 时
'M': date.getMinutes().toString().padStart(2, '0'), // 分
's': date.getSeconds().toString().padStart(2, '0') // 秒
// 有其他格式化字符需求可以继续添加,必须转化成字符串
}
for (const key in timeSource) {
const [ret] = new RegExp(`${key}+`).exec(formatStr) || []
if (ret) {
// 年可能只需展示两位
const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0
formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex))
}
}
return formatStr
},
uuid() {
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 32; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23];
var uuid = s.join("");
return uuid;
}
},
}
</script>
<style lang="scss">
.page {
width: 100vw;
height: 100vh;
background-color: #f8f8f8;
box-sizing: border-box;
font: 24rpx;
.content{
width: 100%;
height: 90vh;
margin-top: 20rpx;
background-color: #f8f8f8;
padding-bottom: 40rpx;
}
.img-view{
width: 94%;
margin: 20rpx auto;
background-color: #FFF;
border-radius: 10rpx;
}
.btn{
background-color:#00337A;
color: #FFF;
padding:10rpx 20rpx;
border-radius: 10rpx;
}
.view-item{
width: 94%;
margin: 0rpx auto;
padding:20rpx;
display: flex;
border-bottom: 1rpx solid #f8f8f8;
font-size: 26rpx;
}
.img-box{
width: 94%;
height: auto;
margin: 0rpx auto;
padding:20rpx;
display: flex;
border-bottom: 1rpx solid #f8f8f8;
.img-item {
float: left;
width: 200upx;
height: 200upx;
border: 1px solid #ddd;
margin: 0 22rpx 20upx 0upx;
position: relative;
box-sizing: border-box;
background: #eee;
.img {
display: block;
width: 100%;
height: 100%;
}
.remove-btn {
position: absolute;
top: -18upx;
right: -18upx;
width: 44upx;
height: 44upx;
z-index: 2;
}
}
.upload-btn {
display: flex;
justify-content: center;
align-items: center;
.img {
width: 60upx;
height: 60upx;
margin: unset;
}
}
}
.btn2{
color: #999;
margin-top: 20rpx;
margin-left: 20rpx;
padding: 20rpx;
}
.popup-header{
width: 100%;
height: 80rpx;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #fff;
}
.popup-content{
width: 100%;
height: 15vh;
background-color: #fff;
}
.addForm{
width: 100%;
height: auto;
font-size: 26rpx;
.form-input-box{
padding: 0 20rpx;
display: flex;
align-items: center;
border-bottom: 1rpx solid #eee;
}
}
.sumbit-btn{
width: 94%;
height: 80rpx;
margin: 0 auto;
margin-bottom: 100rpx;
display: flex;align-items: center;justify-content: center;
background: #00337A;
color: #FFF;
border-radius: 10rpx;
}
}
</style>