From 83f5b5fcced236f5ebd4542d3a9ff9d7faf135d6 Mon Sep 17 00:00:00 2001
From: zhouxiaofeng <2946471396@qq.com>
Date: Tue, 30 Jun 2026 16:36:26 +0800
Subject: [PATCH] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E7=9B=B8=E5=AF=B9=E6=96=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/launch.js | 15 ++
.../launch/components/mixedSignModal.vue | 200 +++++++++++++++---
2 files changed, 189 insertions(+), 26 deletions(-)
diff --git a/src/api/launch.js b/src/api/launch.js
index 75ab817..4fbaca6 100644
--- a/src/api/launch.js
+++ b/src/api/launch.js
@@ -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`,
diff --git a/src/views/contract/launch/components/mixedSignModal.vue b/src/views/contract/launch/components/mixedSignModal.vue
index 7e45dd6..9bb93d1 100644
--- a/src/views/contract/launch/components/mixedSignModal.vue
+++ b/src/views/contract/launch/components/mixedSignModal.vue
@@ -532,6 +532,37 @@
+
+
相对方签署确认
+
+
✓
+
○
+
{{ name }}
+
{{ counterpartyConfirmMap[name]?.method === 'manual' ? '(代确认)' : '(已确认)' }}
+
我已签署完成
+
+
+ 所有相对方确认后方可正常结束,未确认仍可强制结束
+
+
+
{
+ 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,33 +1830,52 @@ async function handleCompleteContract() {
return;
}
- Modal.confirm({
- title: "确认结束",
- content: "确认结束合约?结束后将无法再继续添加签章。",
- okType: "danger",
- onOk: async () => {
- completing.value = true;
- try {
- const res = await completeContract(contractId.value);
- if (!isSuccessResponse(res)) {
- message.error(getResponseMessage(res, "结束合约失败"));
- return;
- }
+ // 检查相对方签署确认情况
+ await loadCounterpartyConfirm();
+ const notConfirmed = unconfirmedPartyNames.value;
+ if (notConfirmed.length) {
+ Modal.confirm({
+ 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;
+ }
- contractStatus.value = 2000;
- updateBusinessStatusByContractStatus(2000);
- if (businessRecord.value?.id) {
- await writeBackLaunchSealFinished(2000);
- }
- clearContractState();
- message.success("合约已完成");
- } catch {
- message.error("结束合约失败");
- } finally {
- completing.value = false;
- }
- },
- });
+ // 全部已确认,正常结束
+ doEndContract();
+}
+
+async function doEndContract() {
+ completing.value = true;
+ try {
+ const res = await completeContract(contractId.value);
+ if (!isSuccessResponse(res)) {
+ message.error(getResponseMessage(res, "结束合约失败"));
+ return;
+ }
+
+ contractStatus.value = 2000;
+ updateBusinessStatusByContractStatus(2000);
+ if (businessRecord.value?.id) {
+ await writeBackLaunchSealFinished(2000);
+ }
+ clearContractState();
+ message.success("合约已完成");
+ } catch {
+ message.error("结束合约失败");
+ } 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;
+}