合同签署 合同审核 接口完善 页面优化
This commit is contained in:
parent
cf7f5eb115
commit
cd3d71586b
|
|
@ -1,6 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="select-all-container" :style="containerStyle">
|
<view class="select-all-container" :style="containerStyle">
|
||||||
<up-button text="全选" type="primary" :customStyle="buttonStyle" @tap="handleSelectAll" />
|
<up-button
|
||||||
|
type="primary"
|
||||||
|
@tap="handleSelectAll"
|
||||||
|
:customStyle="buttonStyle"
|
||||||
|
:text="isAllChecked ? '取消全选' : '全选'"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -8,15 +13,13 @@
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { getSafeAreaInfo } from '@/utils/safeArea'
|
import { getSafeAreaInfo } from '@/utils/safeArea'
|
||||||
|
|
||||||
/**
|
|
||||||
* 审核页面全选按钮组件
|
|
||||||
* 业务背景:用于批量操作场景,提供全选功能
|
|
||||||
* 设计决策:
|
|
||||||
* 1. 固定在底部右侧,方便用户操作
|
|
||||||
* 2. 适配安全区,确保在底部有安全区的设备上正常显示
|
|
||||||
* 3. 使用国网绿主题色,保持视觉一致性
|
|
||||||
*/
|
|
||||||
const emit = defineEmits(['selectAll'])
|
const emit = defineEmits(['selectAll'])
|
||||||
|
const props = defineProps({
|
||||||
|
isAllChecked: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// 容器样式,适配底部安全区
|
// 容器样式,适配底部安全区
|
||||||
const containerStyle = computed(() => {
|
const containerStyle = computed(() => {
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,14 @@
|
||||||
"navigationBarBackgroundColor": "#07c160"
|
"navigationBarBackgroundColor": "#07c160"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/work/contract-sign/detail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "电子合同信息",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarBackgroundColor": "#07c160"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/work/wage-view/index",
|
"path": "pages/work/wage-view/index",
|
||||||
"style": {
|
"style": {
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,16 @@
|
||||||
<text class="label" style="margin-left: 20rpx">签订日期:</text>
|
<text class="label" style="margin-left: 20rpx">签订日期:</text>
|
||||||
<text class="value">{{ item.signingDate }}</text>
|
<text class="value">{{ item.signingDate }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view class="row" v-if="activeTab != 0">
|
||||||
|
<text class="label">甲方签署状态:</text>
|
||||||
|
<text
|
||||||
|
class="value"
|
||||||
|
:style="{ color: item.isSign == 1 ? '#4caf50' : '#ed7b2f' }"
|
||||||
|
>
|
||||||
|
{{ item.isSign == 1 ? '已签署' : '待签署' || '-' }}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,737 @@
|
||||||
|
<template>
|
||||||
|
<view class="page-container">
|
||||||
|
<!-- 导航栏 -->
|
||||||
|
<NavBarModal navBarTitle="电子合同信息">
|
||||||
|
<template #left>
|
||||||
|
<view class="back-btn" @tap="handleBack">
|
||||||
|
<up-icon name="arrow-left" size="20" color="#fff" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</NavBarModal>
|
||||||
|
|
||||||
|
<!-- 内容区域 -->
|
||||||
|
<view class="content-wrapper" :style="contentStyle">
|
||||||
|
<!-- 下拉选择器 -->
|
||||||
|
<view v-if="documentOptions.length > 0" class="picker-section">
|
||||||
|
<CommonPicker
|
||||||
|
placeholder="请选择文档"
|
||||||
|
:options="documentOptions"
|
||||||
|
v-model="currentDocumentValue"
|
||||||
|
@change="handleDocumentChange"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="error" class="error-wrapper">
|
||||||
|
<up-icon name="close-circle" size="80" color="#e34d59" />
|
||||||
|
<text class="error-text">{{ error }}</text>
|
||||||
|
<up-button
|
||||||
|
text="重试"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
:customStyle="{ marginTop: '32rpx' }"
|
||||||
|
@tap="loadDocument"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="pdfUrl" class="document-wrapper">
|
||||||
|
<DocumentPreview
|
||||||
|
:file-url="pdfUrl"
|
||||||
|
file-type="pdf"
|
||||||
|
preview-service="pdfjs"
|
||||||
|
:auto-load="true"
|
||||||
|
:show-retry="true"
|
||||||
|
:show-download="true"
|
||||||
|
:container-style="{ width: '100%', height: '100%' }"
|
||||||
|
@load="handleDocumentLoad"
|
||||||
|
@error="handleDocumentError"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 空状态 -->
|
||||||
|
<view v-else class="empty-wrapper">
|
||||||
|
<up-icon name="file-text" size="80" color="#ccc" />
|
||||||
|
<text class="empty-text">暂无文档</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<view class="button-section">
|
||||||
|
<up-button
|
||||||
|
text="返回"
|
||||||
|
type="default"
|
||||||
|
:customStyle="backButtonStyle"
|
||||||
|
@tap="handleBack"
|
||||||
|
/>
|
||||||
|
<template v-if="!isSigned">
|
||||||
|
<up-button
|
||||||
|
text="查看视频"
|
||||||
|
type="default"
|
||||||
|
:customStyle="videoButtonStyle"
|
||||||
|
@tap="handleViewVideo"
|
||||||
|
/>
|
||||||
|
<up-button
|
||||||
|
text="签署"
|
||||||
|
type="primary"
|
||||||
|
:customStyle="signButtonStyle"
|
||||||
|
@tap="handleSign"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 签署弹窗 -->
|
||||||
|
<up-popup :show="showSignModal" mode="center" round="20" @close="handleCancelSign">
|
||||||
|
<view class="sign-popup">
|
||||||
|
<view class="sign-title">签署</view>
|
||||||
|
<scroll-view class="sign-body" scroll-y>
|
||||||
|
<view class="sign-block">
|
||||||
|
<text class="block-title">确认信息</text>
|
||||||
|
<view class="info-text">
|
||||||
|
<text>您确定要签署这份合同吗?</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="stamp-section">
|
||||||
|
<up-button
|
||||||
|
text="获取公章"
|
||||||
|
type="primary"
|
||||||
|
@tap="handleGetStamp"
|
||||||
|
:customStyle="getStampButtonStyle"
|
||||||
|
:loading="stampLoading"
|
||||||
|
/>
|
||||||
|
<view class="stamp-label">电子公章</view>
|
||||||
|
<view class="stamp-preview" v-if="stampImageUrl">
|
||||||
|
<image :src="stampImageUrl" mode="aspectFit" class="stamp-image" />
|
||||||
|
</view>
|
||||||
|
<view v-else class="stamp-placeholder">
|
||||||
|
<text class="placeholder-text">暂无公章</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="sign-actions">
|
||||||
|
<up-button
|
||||||
|
text="取消"
|
||||||
|
type="default"
|
||||||
|
@tap="handleCancelSign"
|
||||||
|
:customStyle="cancelBtnStyle"
|
||||||
|
/>
|
||||||
|
<up-button
|
||||||
|
text="确认"
|
||||||
|
type="primary"
|
||||||
|
@tap="handleConfirmSign"
|
||||||
|
:customStyle="confirmBtnStyle"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</up-popup>
|
||||||
|
|
||||||
|
<!-- 视频全屏弹窗 -->
|
||||||
|
<up-popup :show="showVideoModal" mode="center" round="20" @close="showVideoModal = false">
|
||||||
|
<view class="video-popup">
|
||||||
|
<view class="video-header">
|
||||||
|
<text class="video-title">查看视频</text>
|
||||||
|
<up-icon name="close" size="24" color="#333" @tap="showVideoModal = false" />
|
||||||
|
</view>
|
||||||
|
<view class="video-container">
|
||||||
|
<video
|
||||||
|
v-if="videoUrl"
|
||||||
|
:src="videoUrl"
|
||||||
|
controls
|
||||||
|
class="video-player"
|
||||||
|
:enable-play-gesture="true"
|
||||||
|
:show-fullscreen-btn="true"
|
||||||
|
:show-center-play-btn="true"
|
||||||
|
:enable-progress-gesture="true"
|
||||||
|
object-fit="contain"
|
||||||
|
></video>
|
||||||
|
<view v-else class="video-empty">
|
||||||
|
<text>暂无视频</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</up-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import NavBarModal from '@/components/NavBarModal/index.vue'
|
||||||
|
import DocumentPreview from '@/components/DocumentPreview/index.vue'
|
||||||
|
import CommonPicker from '@/components/CommonPicker/index.vue'
|
||||||
|
import { getContentStyle } from '@/utils/safeArea'
|
||||||
|
import { signContractAPI, getUserElectronicStampAPI } from '@/services/realName/contractSign'
|
||||||
|
import { useMemberStore, useCommonStore } from '@/stores'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
const memberStore = useMemberStore()
|
||||||
|
const commonStore = useCommonStore()
|
||||||
|
|
||||||
|
const contentStyle = computed(() => {
|
||||||
|
return getContentStyle({
|
||||||
|
includeNavBar: true,
|
||||||
|
includeStatusBar: true,
|
||||||
|
includeBottomSafeArea: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 合同数据
|
||||||
|
const contractData = ref({})
|
||||||
|
// PDF文档URL
|
||||||
|
const pdfUrl = ref('')
|
||||||
|
// 视频URL
|
||||||
|
const videoUrl = ref('')
|
||||||
|
// 是否已签署
|
||||||
|
const isSigned = ref(false)
|
||||||
|
// 签署弹窗
|
||||||
|
const showSignModal = ref(false)
|
||||||
|
const cancelBtnStyle = { flex: 1, marginRight: '16rpx' }
|
||||||
|
const confirmBtnStyle = { flex: 1 }
|
||||||
|
// 视频弹窗
|
||||||
|
const showVideoModal = ref(false)
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(false)
|
||||||
|
// 错误信息
|
||||||
|
const error = ref('')
|
||||||
|
// 公章相关
|
||||||
|
const stampImageUrl = ref('')
|
||||||
|
const stampImagePath = ref('')
|
||||||
|
const stampLoading = ref(false)
|
||||||
|
const getStampButtonStyle = {
|
||||||
|
width: '100%',
|
||||||
|
height: '88rpx',
|
||||||
|
marginBottom: '24rpx',
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文档选项
|
||||||
|
const documentOptions = ref([])
|
||||||
|
const currentDocumentValue = ref('contract')
|
||||||
|
|
||||||
|
// 按钮样式
|
||||||
|
const backButtonStyle = computed(() => {
|
||||||
|
return {
|
||||||
|
flex: 1,
|
||||||
|
marginRight: '16rpx',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
border: '1rpx solid #07c160',
|
||||||
|
color: '#07c160',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const videoButtonStyle = computed(() => {
|
||||||
|
return {
|
||||||
|
flex: 1,
|
||||||
|
marginRight: '16rpx',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
border: '1rpx solid #07c160',
|
||||||
|
color: '#07c160',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const signButtonStyle = computed(() => {
|
||||||
|
return {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: '#07c160',
|
||||||
|
borderColor: '#07c160',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化文档选项
|
||||||
|
*/
|
||||||
|
const initDocumentOptions = () => {
|
||||||
|
const options = []
|
||||||
|
if (contractData.value.personPdfUrl) {
|
||||||
|
options.push({ label: '电子合同', value: 'contract' })
|
||||||
|
}
|
||||||
|
if (contractData.value.aqxysPath) {
|
||||||
|
options.push({ label: '安全协议书', value: 'safety' })
|
||||||
|
}
|
||||||
|
documentOptions.value = options
|
||||||
|
if (options.length > 0) {
|
||||||
|
currentDocumentValue.value = options[0].value
|
||||||
|
handleDocumentChange({ value: options[0].value })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理文档切换
|
||||||
|
*/
|
||||||
|
const handleDocumentChange = (option) => {
|
||||||
|
const value = option.value || option
|
||||||
|
if (value === 'contract') {
|
||||||
|
loadDocument(contractData.value.personPdfUrl)
|
||||||
|
} else if (value === 'safety') {
|
||||||
|
loadDocument(contractData.value.aqxysPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回上一页
|
||||||
|
*/
|
||||||
|
const handleBack = () => {
|
||||||
|
uni.navigateBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看视频
|
||||||
|
*/
|
||||||
|
const handleViewVideo = () => {
|
||||||
|
if (!videoUrl.value) {
|
||||||
|
uni.$u.toast('暂无视频')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
showVideoModal.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PDF加载完成
|
||||||
|
*/
|
||||||
|
const handleDocumentLoad = (data) => {
|
||||||
|
console.log('PDF加载完成:', data)
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PDF加载错误
|
||||||
|
*/
|
||||||
|
const handleDocumentError = (data) => {
|
||||||
|
console.error('PDF加载失败:', data)
|
||||||
|
error.value = data.error || 'PDF加载失败'
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签署
|
||||||
|
*/
|
||||||
|
const handleSign = () => {
|
||||||
|
showSignModal.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消签署
|
||||||
|
*/
|
||||||
|
const handleCancelSign = () => {
|
||||||
|
showSignModal.value = false
|
||||||
|
stampImageUrl.value = '' // 关闭时清空公章图片
|
||||||
|
stampImagePath.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公章
|
||||||
|
*/
|
||||||
|
const handleGetStamp = async () => {
|
||||||
|
const phone = memberStore.realNameUserInfo.phone
|
||||||
|
if (!phone) {
|
||||||
|
uni.$u.toast('手机号不存在')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stampLoading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getUserElectronicStampAPI({ phone })
|
||||||
|
if (res.res === 1 && res.obj) {
|
||||||
|
const imageUrl = res?.obj?.sealUrl
|
||||||
|
stampImagePath.value = imageUrl
|
||||||
|
if (imageUrl) {
|
||||||
|
// 如果是相对路径,需要拼接完整URL
|
||||||
|
if (imageUrl.startsWith('http')) {
|
||||||
|
stampImageUrl.value = imageUrl
|
||||||
|
} else {
|
||||||
|
stampImageUrl.value = import.meta.env.VITE_API_FILE_ASE_URL + imageUrl
|
||||||
|
}
|
||||||
|
uni.$u.toast('获取公章成功')
|
||||||
|
} else {
|
||||||
|
uni.$u.toast('未找到公章信息')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.$u.toast(res.resMsg || '获取公章失败')
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('获取公章失败:', err)
|
||||||
|
uni.$u.toast('获取公章失败,请稍后重试')
|
||||||
|
} finally {
|
||||||
|
stampLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认签署
|
||||||
|
*/
|
||||||
|
const handleConfirmSign = () => {
|
||||||
|
handleSignContract()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 签署操作
|
||||||
|
*/
|
||||||
|
const handleSignContract = async () => {
|
||||||
|
if (!contractData.value.id) {
|
||||||
|
uni.$u.toast('合同信息不完整')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stampImagePath.value) {
|
||||||
|
uni.$u.toast('请先获取公章')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
uni.showLoading({
|
||||||
|
title: '签署中...',
|
||||||
|
mask: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await signContractAPI({
|
||||||
|
companySeal: stampImagePath.value, // 公司公章
|
||||||
|
subPdfUrl: contractData.value.personPdfUrl,
|
||||||
|
legalSeal: null,
|
||||||
|
aqxysPath: contractData.value.aqxysPath,
|
||||||
|
partBIdCard: contractData.value.partBIdCard,
|
||||||
|
id: contractData.value.id,
|
||||||
|
isSign: 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
uni.hideLoading()
|
||||||
|
|
||||||
|
if (res.res == 1) {
|
||||||
|
uni.$u.toast('签署成功')
|
||||||
|
showSignModal.value = false
|
||||||
|
// 返回上一页并刷新
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack()
|
||||||
|
// 通知父组件刷新列表
|
||||||
|
uni.$emit('refreshList')
|
||||||
|
}, 500)
|
||||||
|
} else {
|
||||||
|
uni.$u.toast(res.resMsg || '签署失败')
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
uni.hideLoading()
|
||||||
|
uni.$u.toast('签署失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载文档
|
||||||
|
*/
|
||||||
|
const loadDocument = (url) => {
|
||||||
|
if (!url) {
|
||||||
|
error.value = '暂无文档'
|
||||||
|
pdfUrl.value = ''
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
loading.value = true
|
||||||
|
error.value = ''
|
||||||
|
|
||||||
|
// 如果是相对路径,需要拼接完整URL
|
||||||
|
if (url.startsWith('http')) {
|
||||||
|
pdfUrl.value = url
|
||||||
|
} else {
|
||||||
|
pdfUrl.value = import.meta.env.VITE_API_FILE_ASE_URL + url
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('加载文档失败:', err)
|
||||||
|
error.value = '加载失败,请重试'
|
||||||
|
pdfUrl.value = ''
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载视频
|
||||||
|
*/
|
||||||
|
const loadVideo = () => {
|
||||||
|
try {
|
||||||
|
if (contractData.value.videoUrl) {
|
||||||
|
const url = contractData.value.videoUrl
|
||||||
|
if (url.startsWith('http')) {
|
||||||
|
videoUrl.value = url
|
||||||
|
} else {
|
||||||
|
videoUrl.value = import.meta.env.VITE_API_FILE_ASE_URL + url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('加载视频失败:', err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面加载
|
||||||
|
*/
|
||||||
|
onLoad((options) => {
|
||||||
|
if (options.params) {
|
||||||
|
try {
|
||||||
|
contractData.value = JSON.parse(decodeURIComponent(options.params))
|
||||||
|
|
||||||
|
// 判断是否已签署
|
||||||
|
isSigned.value = contractData.value.isSign == 1
|
||||||
|
|
||||||
|
// 初始化文档选项
|
||||||
|
initDocumentOptions()
|
||||||
|
|
||||||
|
// 加载视频
|
||||||
|
loadVideo()
|
||||||
|
} catch (err) {
|
||||||
|
console.error('解析合同数据失败:', err)
|
||||||
|
uni.$u.toast('合同数据加载失败')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.$u.toast('缺少合同数据')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page-container {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker-section {
|
||||||
|
padding: 24rpx 32rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1rpx solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 80rpx 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 80rpx 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-text {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #e34d59;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
position: relative;
|
||||||
|
background: #fff;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 80rpx 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
margin-top: 24rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-section {
|
||||||
|
display: flex;
|
||||||
|
padding: 32rpx;
|
||||||
|
gap: 16rpx;
|
||||||
|
background: #fff;
|
||||||
|
border-top: 1rpx solid #e5e5e5;
|
||||||
|
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 64rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-btn:active {
|
||||||
|
background: rgba(255, 255, 255, 0.3);
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-popup {
|
||||||
|
width: 640rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-height: 80vh;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 32rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 32rpx;
|
||||||
|
padding-bottom: 20rpx;
|
||||||
|
border-bottom: 2rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-body {
|
||||||
|
max-height: 60vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-block {
|
||||||
|
margin-bottom: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.block-title {
|
||||||
|
display: block;
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-text {
|
||||||
|
padding: 20rpx;
|
||||||
|
background: #f8f8f8;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
border: 1rpx solid #e5e5e5;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp-section {
|
||||||
|
margin-bottom: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp-preview {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 200rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #f8f8f8;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
border: 1rpx solid #e5e5e5;
|
||||||
|
padding: 20rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp-image {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 300rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 200rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #f8f8f8;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
border: 1rpx solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16rpx;
|
||||||
|
margin-top: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-popup {
|
||||||
|
width: 90vw;
|
||||||
|
max-width: 750rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #000;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 24rpx 32rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 60vh;
|
||||||
|
min-height: 400rpx;
|
||||||
|
max-height: 80vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #000;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-player {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-empty {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #999;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
<ReviewSearchBar
|
<ReviewSearchBar
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
@action="handleBatchSign"
|
@action="handleBatchSign"
|
||||||
action-button-text="批量签署"
|
:action-button-text="showSignActions ? '批量签署' : ''"
|
||||||
v-model="queryParams.keyWord"
|
v-model="queryParams.keyWord"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -52,6 +52,7 @@
|
||||||
|
|
||||||
<view
|
<view
|
||||||
class="sign-status"
|
class="sign-status"
|
||||||
|
v-if="activeTab != 0"
|
||||||
:style="{ color: item.isSign == 1 ? '#4caf50' : '#ed7b2f' }"
|
:style="{ color: item.isSign == 1 ? '#4caf50' : '#ed7b2f' }"
|
||||||
>
|
>
|
||||||
{{ item.isSign == 1 ? '已签署' : '待签署' }}
|
{{ item.isSign == 1 ? '已签署' : '待签署' }}
|
||||||
|
|
@ -106,12 +107,16 @@
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 全选按钮(仅待签署) -->
|
<!-- 全选按钮(仅待签署) -->
|
||||||
<ReviewSelectAll v-if="showSignActions" @selectAll="handleSelectAll" />
|
<ReviewSelectAll
|
||||||
|
v-if="showSignActions"
|
||||||
|
@selectAll="handleSelectAll"
|
||||||
|
:isAllChecked="isAllChecked"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 签署确认弹窗 -->
|
<!-- 签署确认弹窗 -->
|
||||||
<up-popup :show="showSignModal" mode="center" round="20" @close="handleCancelSign">
|
<up-popup :show="showSignModal" mode="center" round="20" @close="handleCancelSign">
|
||||||
<view class="sign-popup">
|
<view class="sign-popup">
|
||||||
<view class="sign-title">确认签署</view>
|
<view class="sign-title">签署</view>
|
||||||
<scroll-view class="sign-body" scroll-y>
|
<scroll-view class="sign-body" scroll-y>
|
||||||
<view class="sign-block">
|
<view class="sign-block">
|
||||||
<text class="block-title">确认信息</text>
|
<text class="block-title">确认信息</text>
|
||||||
|
|
@ -119,6 +124,22 @@
|
||||||
<text>您确定要签署选中的 {{ checkedCount }} 份合同吗?</text>
|
<text>您确定要签署选中的 {{ checkedCount }} 份合同吗?</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="stamp-section">
|
||||||
|
<up-button
|
||||||
|
text="获取公章"
|
||||||
|
type="primary"
|
||||||
|
@tap="handleGetStamp"
|
||||||
|
:customStyle="getStampButtonStyle"
|
||||||
|
:loading="stampLoading"
|
||||||
|
/>
|
||||||
|
<view class="stamp-label">电子公章</view>
|
||||||
|
<view class="stamp-preview" v-if="stampImageUrl">
|
||||||
|
<image :src="stampImageUrl" mode="aspectFit" class="stamp-image" />
|
||||||
|
</view>
|
||||||
|
<view v-else class="stamp-placeholder">
|
||||||
|
<text class="placeholder-text">暂无公章</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view class="sign-actions">
|
<view class="sign-actions">
|
||||||
<up-button
|
<up-button
|
||||||
text="取消"
|
text="取消"
|
||||||
|
|
@ -127,7 +148,7 @@
|
||||||
:customStyle="cancelBtnStyle"
|
:customStyle="cancelBtnStyle"
|
||||||
/>
|
/>
|
||||||
<up-button
|
<up-button
|
||||||
text="确认签署"
|
text="确认"
|
||||||
type="primary"
|
type="primary"
|
||||||
@tap="handleConfirmSign"
|
@tap="handleConfirmSign"
|
||||||
:customStyle="confirmBtnStyle"
|
:customStyle="confirmBtnStyle"
|
||||||
|
|
@ -140,7 +161,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import NavBarModal from '@/components/NavBarModal/index.vue'
|
import NavBarModal from '@/components/NavBarModal/index.vue'
|
||||||
import ReviewTabBar from '@/components/ReviewTabBar/index.vue'
|
import ReviewTabBar from '@/components/ReviewTabBar/index.vue'
|
||||||
|
|
@ -148,13 +169,17 @@ import ReviewSearchBar from '@/components/ReviewSearchBar/index.vue'
|
||||||
import ReviewEmptyState from '@/components/ReviewEmptyState/index.vue'
|
import ReviewEmptyState from '@/components/ReviewEmptyState/index.vue'
|
||||||
import ReviewSelectAll from '@/components/ReviewSelectAll/index.vue'
|
import ReviewSelectAll from '@/components/ReviewSelectAll/index.vue'
|
||||||
import { getContentStyle } from '@/utils/safeArea'
|
import { getContentStyle } from '@/utils/safeArea'
|
||||||
import { getContractSignListAPI, signContractAPI } from '@/services/realName/contractSign'
|
import {
|
||||||
|
signContractAPI,
|
||||||
|
getContractSignListAPI,
|
||||||
|
getUserElectronicStampAPI,
|
||||||
|
} from '@/services/realName/contractSign'
|
||||||
import { useMemberStore, useCommonStore } from '@/stores'
|
import { useMemberStore, useCommonStore } from '@/stores'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
const memberStore = useMemberStore()
|
const memberStore = useMemberStore()
|
||||||
const commonStore = useCommonStore()
|
const commonStore = useCommonStore()
|
||||||
|
const isAllChecked = ref(false)
|
||||||
const queryParams = ref({
|
const queryParams = ref({
|
||||||
isSign: 0, // 0待签署 1已签署
|
isSign: 0, // 0待签署 1已签署
|
||||||
proId: commonStore.activeProjectId,
|
proId: commonStore.activeProjectId,
|
||||||
|
|
@ -179,6 +204,14 @@ const showSignActions = computed(() => activeTab.value === 0)
|
||||||
const showSignModal = ref(false)
|
const showSignModal = ref(false)
|
||||||
const cancelBtnStyle = { flex: 1, marginRight: '16rpx' }
|
const cancelBtnStyle = { flex: 1, marginRight: '16rpx' }
|
||||||
const confirmBtnStyle = { flex: 1 }
|
const confirmBtnStyle = { flex: 1 }
|
||||||
|
const stampImageUrl = ref('')
|
||||||
|
const stampImagePath = ref('')
|
||||||
|
const stampLoading = ref(false)
|
||||||
|
const getStampButtonStyle = {
|
||||||
|
width: '100%',
|
||||||
|
height: '88rpx',
|
||||||
|
marginBottom: '24rpx',
|
||||||
|
}
|
||||||
|
|
||||||
// 已选中的数量
|
// 已选中的数量
|
||||||
const checkedCount = computed(() => {
|
const checkedCount = computed(() => {
|
||||||
|
|
@ -209,6 +242,11 @@ const handleSearch = (keyword) => {
|
||||||
*/
|
*/
|
||||||
const handleBatchSign = () => {
|
const handleBatchSign = () => {
|
||||||
if (!showSignActions.value) return
|
if (!showSignActions.value) return
|
||||||
|
|
||||||
|
if (list.value.length === 0) {
|
||||||
|
uni.$u.toast('暂无可签署合同')
|
||||||
|
return
|
||||||
|
}
|
||||||
const checkedList = list.value.filter((item) => item.isChecked)
|
const checkedList = list.value.filter((item) => item.isChecked)
|
||||||
if (checkedList.length === 0) {
|
if (checkedList.length === 0) {
|
||||||
uni.$u.toast('请选择要签署的合同')
|
uni.$u.toast('请选择要签署的合同')
|
||||||
|
|
@ -222,6 +260,46 @@ const handleBatchSign = () => {
|
||||||
*/
|
*/
|
||||||
const handleCancelSign = () => {
|
const handleCancelSign = () => {
|
||||||
showSignModal.value = false
|
showSignModal.value = false
|
||||||
|
stampImageUrl.value = '' // 关闭时清空公章图片
|
||||||
|
stampImagePath.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取公章
|
||||||
|
*/
|
||||||
|
const handleGetStamp = async () => {
|
||||||
|
const phone = memberStore.realNameUserInfo.phone
|
||||||
|
if (!phone) {
|
||||||
|
uni.$u.toast('手机号不存在')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stampLoading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getUserElectronicStampAPI({ phone })
|
||||||
|
if (res.res === 1 && res.obj) {
|
||||||
|
const imageUrl = res?.obj?.sealUrl
|
||||||
|
stampImagePath.value = imageUrl
|
||||||
|
if (imageUrl) {
|
||||||
|
// 如果是相对路径,需要拼接完整URL
|
||||||
|
if (imageUrl.startsWith('http')) {
|
||||||
|
stampImageUrl.value = imageUrl
|
||||||
|
} else {
|
||||||
|
stampImageUrl.value = import.meta.env.VITE_API_FILE_ASE_URL + imageUrl
|
||||||
|
}
|
||||||
|
uni.$u.toast('获取公章成功')
|
||||||
|
} else {
|
||||||
|
uni.$u.toast('未找到公章信息')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.$u.toast(res.resMsg || '获取公章失败')
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('获取公章失败:', err)
|
||||||
|
uni.$u.toast('获取公章失败,请稍后重试')
|
||||||
|
} finally {
|
||||||
|
stampLoading.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -237,6 +315,7 @@ const handleConfirmSign = () => {
|
||||||
const handleSelectAll = () => {
|
const handleSelectAll = () => {
|
||||||
if (!showSignActions.value) return
|
if (!showSignActions.value) return
|
||||||
const allChecked = list.value.every((item) => item.isChecked)
|
const allChecked = list.value.every((item) => item.isChecked)
|
||||||
|
isAllChecked.value = !allChecked
|
||||||
list.value = list.value.map((item) => ({ ...item, isChecked: !allChecked }))
|
list.value = list.value.map((item) => ({ ...item, isChecked: !allChecked }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,7 +334,7 @@ const handleCardClick = (item) => {
|
||||||
// 待签署状态,点击可以选择复选框
|
// 待签署状态,点击可以选择复选框
|
||||||
const params = encodeURIComponent(JSON.stringify(item))
|
const params = encodeURIComponent(JSON.stringify(item))
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pages/work/contract-review/detail?params=${params}`,
|
url: `/pages/work/contract-sign/detail?params=${params}`,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,6 +368,11 @@ const handleSign = async () => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!stampImagePath.value) {
|
||||||
|
uni.$u.toast('请先获取公章')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 显示加载提示
|
// 显示加载提示
|
||||||
uni.showLoading({
|
uni.showLoading({
|
||||||
title: '签署中...',
|
title: '签署中...',
|
||||||
|
|
@ -299,11 +383,13 @@ const handleSign = async () => {
|
||||||
// 创建所有签署请求的 Promise 数组
|
// 创建所有签署请求的 Promise 数组
|
||||||
const signPromises = checkedList.map((item) => {
|
const signPromises = checkedList.map((item) => {
|
||||||
return signContractAPI({
|
return signContractAPI({
|
||||||
signer: memberStore?.realNameUserInfo.id,
|
companySeal: stampImagePath.value, // 公司公章
|
||||||
signTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
subPdfUrl: item.personPdfUrl,
|
||||||
isSign: 1, // 1已签署
|
legalSeal: null,
|
||||||
|
aqxysPath: item.aqxysPath,
|
||||||
partBIdCard: item.partBIdCard,
|
partBIdCard: item.partBIdCard,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
|
isSign: 1,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -362,6 +448,14 @@ const handleBack = () => {
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
loadList()
|
loadList()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
uni.$on('refreshList', loadList)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
uni.$off('refreshList', loadList)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
@ -523,6 +617,51 @@ onLoad(() => {
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stamp-section {
|
||||||
|
margin-bottom: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp-preview {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 200rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #f8f8f8;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
border: 1rpx solid #e5e5e5;
|
||||||
|
padding: 20rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp-image {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 300rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stamp-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 200rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #f8f8f8;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
border: 1rpx solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
.sign-actions {
|
.sign-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,18 @@ export const getContractSignListAPI = (data) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 签署接口
|
// 合同签署
|
||||||
export const signContractAPI = (data) => {
|
export const signContractAPI = (data) => {
|
||||||
return realNameHttp({
|
return realNameHttp({
|
||||||
url: `/workPerson/updateSign?${initParams(data)}`,
|
url: `/workPerson/updateSign?${initParams(data)}`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 根据手机号码获取用户的电子公章
|
||||||
|
export const getUserElectronicStampAPI = (data) => {
|
||||||
|
return realNameHttp({
|
||||||
|
url: `/personIdentify/selectSubMsgByPhone?${initParams(data)}`,
|
||||||
|
method: 'POST',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue