获取相对方
This commit is contained in:
@@ -129,6 +129,21 @@ export function saveContractCollectInfo(id, data) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getCounterpartyConfirm(id) {
|
||||
return request({
|
||||
url: `/contract/launch/${id}/counterparty-confirm`,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
export function confirmCounterparty(id, data) {
|
||||
return request({
|
||||
url: `/contract/launch/${id}/counterparty-confirm`,
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
export function archiveLaunch(id, data = {}) {
|
||||
return request({
|
||||
url: `/contract/launch/${id}/archive`,
|
||||
|
||||
@@ -532,6 +532,37 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="counterpartyPartyNames.length" class="counterparty-confirm-section">
|
||||
<div class="counterparty-confirm-title">相对方签署确认</div>
|
||||
<div
|
||||
v-for="name in counterpartyPartyNames"
|
||||
:key="name"
|
||||
class="counterparty-confirm-row"
|
||||
>
|
||||
<span
|
||||
v-if="counterpartyConfirmMap[name]?.confirmed"
|
||||
class="confirm-status status-done"
|
||||
>✓</span>
|
||||
<span v-else class="confirm-status status-pending">○</span>
|
||||
<span class="confirm-name">{{ name }}</span>
|
||||
<span
|
||||
v-if="counterpartyConfirmMap[name]?.confirmed"
|
||||
class="confirm-method"
|
||||
>{{ counterpartyConfirmMap[name]?.method === 'manual' ? '(代确认)' : '(已确认)' }}</span>
|
||||
<a-button
|
||||
v-else
|
||||
size="small"
|
||||
type="primary"
|
||||
ghost
|
||||
:loading="counterpartyConfirmLoading"
|
||||
@click="handleConfirmCounterparty(name)"
|
||||
>我已签署完成</a-button>
|
||||
</div>
|
||||
<div v-if="unconfirmedPartyNames.length" class="counterparty-confirm-note">
|
||||
所有相对方确认后方可正常结束,未确认仍可强制结束
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="btn btn-success"
|
||||
:class="{
|
||||
@@ -647,6 +678,7 @@ import {
|
||||
toRef,
|
||||
reactive,
|
||||
computed,
|
||||
h,
|
||||
nextTick,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
@@ -679,6 +711,8 @@ import {
|
||||
finishLaunchSeal,
|
||||
downloadLaunchFile,
|
||||
saveLaunchSealInfo,
|
||||
getCounterpartyConfirm,
|
||||
confirmCounterparty,
|
||||
} from "@/api/launch.js";
|
||||
|
||||
const SUCCESS_CODE = "0000";
|
||||
@@ -1056,6 +1090,7 @@ async function showModal(contractIdParam, businessRecordParam) {
|
||||
await loadContract(contractIdToLoad);
|
||||
await nextTick();
|
||||
calcDisplaySize();
|
||||
await loadCounterpartyConfirm();
|
||||
modalLoading.value = false;
|
||||
return;
|
||||
}
|
||||
@@ -1077,6 +1112,7 @@ async function showModal(contractIdParam, businessRecordParam) {
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
await loadCounterpartyConfirm();
|
||||
modalLoading.value = false;
|
||||
}
|
||||
|
||||
@@ -1138,6 +1174,8 @@ const pdfImages = ref([]);
|
||||
const imageWidth = ref(793);
|
||||
const imageHeight = ref(1122);
|
||||
const completing = ref(false);
|
||||
const counterpartyConfirmMap = ref({});
|
||||
const counterpartyConfirmLoading = ref(false);
|
||||
|
||||
async function loadContract(cid) {
|
||||
try {
|
||||
@@ -1264,6 +1302,44 @@ const fetchingSeals = ref(false);
|
||||
const sealList = ref([]);
|
||||
const sealDefaultScale = ref(1.0);
|
||||
|
||||
/** 解析相对方名单(分号分隔) */
|
||||
const counterpartyPartyNames = computed(() => {
|
||||
const text = businessRecord.value?.counterpartySummary || '';
|
||||
return text.split(/[;;]/).map(s => s.trim()).filter(Boolean);
|
||||
});
|
||||
|
||||
/** 未确认的相对方名单 */
|
||||
const unconfirmedPartyNames = computed(() => {
|
||||
return counterpartyPartyNames.value.filter(name => !counterpartyConfirmMap.value[name]?.confirmed);
|
||||
});
|
||||
|
||||
async function loadCounterpartyConfirm() {
|
||||
if (!businessRecord.value?.id) return;
|
||||
counterpartyConfirmLoading.value = true;
|
||||
try {
|
||||
const res = await getCounterpartyConfirm(businessRecord.value.id);
|
||||
if (isSuccessResponse(res) && res.result) {
|
||||
counterpartyConfirmMap.value = res.result || {};
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
counterpartyConfirmLoading.value = false;
|
||||
}
|
||||
|
||||
async function handleConfirmCounterparty(companyName) {
|
||||
if (!businessRecord.value?.id) return;
|
||||
try {
|
||||
const res = await confirmCounterparty(businessRecord.value.id, { companyName });
|
||||
if (isSuccessResponse(res) && res.result) {
|
||||
counterpartyConfirmMap.value = res.result || {};
|
||||
message.success(`已确认:${companyName}`);
|
||||
} else {
|
||||
message.error(getResponseMessage(res, '确认失败'));
|
||||
}
|
||||
} catch {
|
||||
message.error('确认失败');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
queryName.value = '周小锋';
|
||||
queryIdOrMobile.value = '17681520782';
|
||||
@@ -1754,11 +1830,32 @@ async function handleCompleteContract() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查相对方签署确认情况
|
||||
await loadCounterpartyConfirm();
|
||||
const notConfirmed = unconfirmedPartyNames.value;
|
||||
if (notConfirmed.length) {
|
||||
Modal.confirm({
|
||||
title: "确认结束",
|
||||
content: "确认结束合约?结束后将无法再继续添加签章。",
|
||||
okType: "danger",
|
||||
onOk: async () => {
|
||||
title: '以下相对方尚未确认签署完成',
|
||||
content: h('div', [
|
||||
h('p', { style: { color: '#e6a23c', marginBottom: '12px' } }, `共 ${notConfirmed.length} 个相对方未确认:`),
|
||||
...notConfirmed.map(n =>
|
||||
h('p', { style: { margin: '4px 0', color: '#f56c6c' } }, '⚠ ' + n)
|
||||
),
|
||||
h('p', { style: { color: '#999', fontSize: '12px', marginTop: '12px' } }, '仍可强制结束合约,建议各方确认后再结束。'),
|
||||
]),
|
||||
okText: '强制结束',
|
||||
okType: 'danger',
|
||||
cancelText: '暂不结束',
|
||||
onOk: () => doEndContract(),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 全部已确认,正常结束
|
||||
doEndContract();
|
||||
}
|
||||
|
||||
async function doEndContract() {
|
||||
completing.value = true;
|
||||
try {
|
||||
const res = await completeContract(contractId.value);
|
||||
@@ -1779,8 +1876,6 @@ async function handleCompleteContract() {
|
||||
} finally {
|
||||
completing.value = false;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function handleDownloadContract() {
|
||||
@@ -2718,4 +2813,57 @@ watch(visible, (value) => {
|
||||
width: 320px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 相对方签署确认 */
|
||||
.counterparty-confirm-section {
|
||||
margin: 14px 0;
|
||||
padding: 10px 12px;
|
||||
background: #f8fafc;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #eef2f6;
|
||||
}
|
||||
.counterparty-confirm-title {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.counterparty-confirm-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 0;
|
||||
font-size: 12px;
|
||||
border-bottom: 1px dashed #eef2f6;
|
||||
}
|
||||
.counterparty-confirm-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.confirm-status {
|
||||
font-size: 14px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.confirm-status.status-done {
|
||||
color: #67c23a;
|
||||
}
|
||||
.confirm-status.status-pending {
|
||||
color: #c0c4cc;
|
||||
}
|
||||
.confirm-name {
|
||||
flex: 1;
|
||||
color: #2c3e50;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.confirm-method {
|
||||
font-size: 11px;
|
||||
color: #909399;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.counterparty-confirm-note {
|
||||
margin-top: 6px;
|
||||
font-size: 11px;
|
||||
color: #909399;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user