From bef3d94968fc70667f3123cb23ee69550e08a5ca Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 15 十月 2026 14:03:17 +0800
Subject: [PATCH] feat(crm): 优化合同管理及待办功能
---
src/views/crm/backlog/index.vue | 40 +++++--
src/views/crm/backlog/modules/receivable-plan-remind-list.vue | 30 ++++-
src/api/crm/contract/index.ts | 5 +
src/views/mes/md/workstation/workshop/data.ts | 15 ---
src/views/crm/backlog/modules/customer-follow-list.vue | 5 +
src/views/crm/backlog/modules/customer-put-pool-remind-list.vue | 10 +
src/views/crm/saleQuotation/index.vue | 16 +++
src/views/crm/backlog/modules/receivable-audit-list.vue | 41 +++++--
src/utils/contract-document.ts | 8 +
src/views/crm/backlog/modules/customer-today-contact-list.vue | 5 +
src/views/mes/md/workstation/components/workshop-select.vue | 4
src/views/crm/backlog/modules/contract-audit-list.vue | 36 ++++++-
src/views/crm/contract/index.vue | 8 +
src/views/crm/backlog/modules/contract-remind-list.vue | 31 +++++
src/views/crm/contract/detail/index.vue | 8 +
src/views/mes/home/modules/alert-panel.vue | 8 -
16 files changed, 196 insertions(+), 74 deletions(-)
diff --git a/src/api/crm/contract/index.ts b/src/api/crm/contract/index.ts
index 808b869..a37a8d7 100644
--- a/src/api/crm/contract/index.ts
+++ b/src/api/crm/contract/index.ts
@@ -93,6 +93,11 @@
);
}
+/** 鎸夎喘閿�鍚堝悓妯℃澘涓嬭浇 Word 鏂囦欢 */
+export function downloadContractDocument(id: number) {
+ return requestClient.download('/crm/contract/download-document', { params: { id } });
+}
+
/** 鏌ヨ鍚堝悓璇︽儏 */
export function getContract(id: number) {
return requestClient.get<CrmContractApi.Contract>(
diff --git a/src/utils/contract-document.ts b/src/utils/contract-document.ts
new file mode 100644
index 0000000..f1e10c0
--- /dev/null
+++ b/src/utils/contract-document.ts
@@ -0,0 +1,8 @@
+import { downloadFileFromBlobPart } from '@vben/utils';
+import { downloadContractDocument } from '#/api/crm/contract';
+
+export async function downloadContractWord(id: number, no?: string) {
+ const source = await downloadContractDocument(id);
+ const suffix = (no || String(id)).replaceAll(/[\\/:*?"<>|]/g, '_');
+ downloadFileFromBlobPart({ fileName: `璐攢鍚堝悓-${suffix}.docx`, source });
+}
diff --git a/src/views/crm/backlog/index.vue b/src/views/crm/backlog/index.vue
index a183a22..432531f 100644
--- a/src/views/crm/backlog/index.vue
+++ b/src/views/crm/backlog/index.vue
@@ -1,4 +1,6 @@
<script lang="ts" setup>
+import type { Ref } from 'vue';
+
import { computed, onActivated, onMounted, ref, watch } from 'vue';
import { Page } from '@vben/common-ui';
@@ -78,16 +80,32 @@
leftMenu.value = item.menu;
}
-/** 鑾峰彇鏁伴噺 */
-async function getCount() {
- customerTodayContactCount.value = await getTodayContactCustomerCount();
- customerPutPoolRemindCount.value = await getPutPoolRemindCustomerCount();
- customerFollowCount.value = await getFollowCustomerCount();
- clueFollowCount.value = await getFollowClueCount();
- if (!automaticApproval.value) contractAuditCount.value = await getAuditContractCount();
- contractRemindCount.value = await getRemindContractCount();
- if (!automaticApproval.value) receivableAuditCount.value = await getAuditReceivableCount();
- receivablePlanRemindCount.value = await getReceivablePlanRemindCount();
+/** 鐙珛鍔犺浇鍚勭被鏁伴噺锛屽崟涓帴鍙eけ璐ヤ笉闃绘柇鍏朵粬寰呭姙銆� */
+let countRequest: Promise<void> | undefined;
+function getCount() {
+ if (countRequest) return countRequest;
+ const requests: [Ref<number>, () => Promise<number>][] = [
+ [customerTodayContactCount, getTodayContactCustomerCount],
+ [customerPutPoolRemindCount, getPutPoolRemindCustomerCount],
+ [customerFollowCount, getFollowCustomerCount],
+ [clueFollowCount, getFollowClueCount],
+ [contractRemindCount, getRemindContractCount],
+ [receivablePlanRemindCount, getReceivablePlanRemindCount],
+ ];
+ if (!automaticApproval.value) {
+ requests.push(
+ [contractAuditCount, getAuditContractCount],
+ [receivableAuditCount, getAuditReceivableCount],
+ );
+ }
+ countRequest = Promise.allSettled(
+ requests.map(async ([count, request]) => {
+ count.value = await request();
+ }),
+ ).then(() => undefined).finally(() => {
+ countRequest = undefined;
+ });
+ return countRequest;
}
/** 婵�娲绘椂 */
@@ -126,7 +144,7 @@
</template>
</List>
</Card>
- <component class="ml-4 w-4/5" :is="currentComponent" />
+ <component class="ml-4 w-4/5" :is="currentComponent" @refresh="getCount" />
</div>
</Page>
</template>
diff --git a/src/views/crm/backlog/modules/contract-audit-list.vue b/src/views/crm/backlog/modules/contract-audit-list.vue
index 98f944c..c43df5d 100644
--- a/src/views/crm/backlog/modules/contract-audit-list.vue
+++ b/src/views/crm/backlog/modules/contract-audit-list.vue
@@ -5,7 +5,7 @@
import { useRouter } from 'vue-router';
-import { Button } from 'ant-design-vue';
+import { Button, Tag } from 'ant-design-vue';
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getContractPage } from '#/api/crm/contract';
@@ -29,17 +29,21 @@
}
/** 鎵撳紑瀹㈡埛璇︽儏 */
function handleCustomerDetail(row: CrmContractApi.Contract) {
- push({ name: 'CrmCustomerDetail', params: { id: row.id } });
+ if (row.customerId) push({ name: 'CrmCustomerDetail', params: { id: row.customerId } });
}
/** 鎵撳紑鑱旂郴浜鸿鎯� */
function handleContactDetail(row: CrmContractApi.Contract) {
- push({ name: 'CrmContactDetail', params: { id: row.id } });
+ if (row.signContactId) push({ name: 'CrmContactDetail', params: { id: row.signContactId } });
}
/** 鎵撳紑鍟嗘満璇︽儏 */
function handleBusinessDetail(row: CrmContractApi.Contract) {
- push({ name: 'CrmBusinessDetail', params: { id: row.id } });
+ if (row.businessId) push({ name: 'CrmBusinessDetail', params: { id: row.businessId } });
+}
+
+function handleViewOrder(row: CrmContractApi.Contract) {
+ if (row.orderId) push({ name: 'ErpSaleOrder', query: { id: row.orderId } });
}
const [Grid] = useVbenVxeGrid({
@@ -87,6 +91,11 @@
<template>
<Grid>
+ <template #no="{ row }">
+ <Button type="link" @click="handleContractDetail(row)">
+ {{ row.no }}
+ </Button>
+ </template>
<template #name="{ row }">
<Button type="link" @click="handleContractDetail(row)">
{{ row.name }}
@@ -102,10 +111,23 @@
{{ row.businessName }}
</Button>
</template>
- <template #contactName="{ row }">
+ <template #signContactName="{ row }">
<Button type="link" @click="handleContactDetail(row)">
- {{ row.contactName }}
+ {{ row.signContactName }}
</Button>
+ </template>
+ <template #auditStatus="{ row }">
+ <Tag v-if="row.auditStatus === 0">鏈彁浜�</Tag>
+ <Tag v-else-if="row.auditStatus === 10" color="warning">瀹℃壒涓�</Tag>
+ <Tag v-else-if="row.auditStatus === 20" color="success">瀹℃牳閫氳繃</Tag>
+ <Tag v-else-if="row.auditStatus === 30" color="error">瀹℃牳涓嶉�氳繃</Tag>
+ <Tag v-else-if="row.auditStatus === 40">宸插彇娑�</Tag>
+ <Tag v-else-if="row.auditStatus === 50" color="error">宸蹭綔搴�</Tag>
+ <span v-else>鈥�</span>
+ </template>
+ <template #orderNo="{ row }">
+ <Button v-if="row.orderId" type="link" @click="handleViewOrder(row)">{{ row.orderNo }}</Button>
+ <span v-else>鈥�</span>
</template>
<template #actions="{ row }">
<TableAction
@@ -114,6 +136,8 @@
label: '鏌ョ湅瀹℃壒',
type: 'link',
icon: ACTION_ICON.VIEW,
+ auth: ['crm:contract:update'],
+ ifShow: !!row.processInstanceId,
onClick: handleProcessDetail.bind(null, row),
},
]"
diff --git a/src/views/crm/backlog/modules/contract-remind-list.vue b/src/views/crm/backlog/modules/contract-remind-list.vue
index a394b3b..cdd4078 100644
--- a/src/views/crm/backlog/modules/contract-remind-list.vue
+++ b/src/views/crm/backlog/modules/contract-remind-list.vue
@@ -5,7 +5,7 @@
import { useRouter } from 'vue-router';
-import { Button } from 'ant-design-vue';
+import { Button, Tag } from 'ant-design-vue';
import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getContractPage } from '#/api/crm/contract';
@@ -30,17 +30,21 @@
/** 鎵撳紑瀹㈡埛璇︽儏 */
function handleCustomerDetail(row: CrmContractApi.Contract) {
- push({ name: 'CrmCustomerDetail', params: { id: row.id } });
+ if (row.customerId) push({ name: 'CrmCustomerDetail', params: { id: row.customerId } });
}
/** 鎵撳紑鑱旂郴浜鸿鎯� */
function handleContactDetail(row: CrmContractApi.Contract) {
- push({ name: 'CrmContactDetail', params: { id: row.id } });
+ if (row.signContactId) push({ name: 'CrmContactDetail', params: { id: row.signContactId } });
}
/** 鎵撳紑鍟嗘満璇︽儏 */
function handleBusinessDetail(row: CrmContractApi.Contract) {
- push({ name: 'CrmBusinessDetail', params: { id: row.id } });
+ if (row.businessId) push({ name: 'CrmBusinessDetail', params: { id: row.businessId } });
+}
+
+function handleViewOrder(row: CrmContractApi.Contract) {
+ if (row.orderId) push({ name: 'ErpSaleOrder', query: { id: row.orderId } });
}
const [Grid] = useVbenVxeGrid({
@@ -88,6 +92,11 @@
<template>
<Grid>
+ <template #no="{ row }">
+ <Button type="link" @click="handleContractDetail(row)">
+ {{ row.no }}
+ </Button>
+ </template>
<template #name="{ row }">
<Button type="link" @click="handleContractDetail(row)">
{{ row.name }}
@@ -108,6 +117,19 @@
{{ row.signContactName }}
</Button>
</template>
+ <template #auditStatus="{ row }">
+ <Tag v-if="row.auditStatus === 0">鏈彁浜�</Tag>
+ <Tag v-else-if="row.auditStatus === 10" color="warning">瀹℃壒涓�</Tag>
+ <Tag v-else-if="row.auditStatus === 20" color="success">瀹℃牳閫氳繃</Tag>
+ <Tag v-else-if="row.auditStatus === 30" color="error">瀹℃牳涓嶉�氳繃</Tag>
+ <Tag v-else-if="row.auditStatus === 40">宸插彇娑�</Tag>
+ <Tag v-else-if="row.auditStatus === 50" color="error">宸蹭綔搴�</Tag>
+ <span v-else>鈥�</span>
+ </template>
+ <template #orderNo="{ row }">
+ <Button v-if="row.orderId" type="link" @click="handleViewOrder(row)">{{ row.orderNo }}</Button>
+ <span v-else>鈥�</span>
+ </template>
<template #actions="{ row }">
<TableAction
:actions="[
@@ -115,6 +137,7 @@
label: '鏌ョ湅瀹℃壒',
type: 'link',
auth: ['crm:contract:update'],
+ ifShow: !!row.processInstanceId,
onClick: handleProcessDetail.bind(null, row),
},
]"
diff --git a/src/views/crm/backlog/modules/customer-follow-list.vue b/src/views/crm/backlog/modules/customer-follow-list.vue
index 6e344d0..4eae0ad 100644
--- a/src/views/crm/backlog/modules/customer-follow-list.vue
+++ b/src/views/crm/backlog/modules/customer-follow-list.vue
@@ -4,6 +4,7 @@
import type { CrmCustomerApi } from '#/api/crm/customer';
import { useRouter } from 'vue-router';
+import { erpNumberFormatter } from '@vben/utils';
import { Button } from 'ant-design-vue';
@@ -68,6 +69,10 @@
<template #name="{ row }">
<Button type="link" @click="handleDetail(row)">{{ row.name }}</Button>
</template>
+ <template #contracts="{ row }">
+ <span v-if="row.contractCount">{{ row.contractCount }} 浠� 路 楼{{ erpNumberFormatter(row.contractTotalPrice, 2) }}</span>
+ <span v-else>鈥�</span>
+ </template>
<template #actions="{ row }">
<Button type="link" @click="handleDetail(row)">鏌ョ湅璇︽儏</Button>
</template>
diff --git a/src/views/crm/backlog/modules/customer-put-pool-remind-list.vue b/src/views/crm/backlog/modules/customer-put-pool-remind-list.vue
index fe78245..c64788e 100644
--- a/src/views/crm/backlog/modules/customer-put-pool-remind-list.vue
+++ b/src/views/crm/backlog/modules/customer-put-pool-remind-list.vue
@@ -4,11 +4,12 @@
import type { CrmCustomerApi } from '#/api/crm/customer';
import { useRouter } from 'vue-router';
+import { erpNumberFormatter } from '@vben/utils';
import { Button } from 'ant-design-vue';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getCustomerPage } from '#/api/crm/customer';
+import { getPutPoolRemindCustomerPage } from '#/api/crm/customer';
import { useGridColumns } from '#/views/crm/customer/data';
import { SCENE_TYPES } from '../data';
@@ -42,10 +43,9 @@
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
- return await getCustomerPage({
+ return await getPutPoolRemindCustomerPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
- pool: true, // 鍥哄畾 鍏捣鍙傛暟涓� true
...formValues,
});
},
@@ -68,6 +68,10 @@
<template #name="{ row }">
<Button type="link" @click="handleDetail(row)">{{ row.name }}</Button>
</template>
+ <template #contracts="{ row }">
+ <span v-if="row.contractCount">{{ row.contractCount }} 浠� 路 楼{{ erpNumberFormatter(row.contractTotalPrice, 2) }}</span>
+ <span v-else>鈥�</span>
+ </template>
<template #actions="{ row }">
<Button type="link" @click="handleDetail(row)">鏌ョ湅璇︽儏</Button>
</template>
diff --git a/src/views/crm/backlog/modules/customer-today-contact-list.vue b/src/views/crm/backlog/modules/customer-today-contact-list.vue
index 03d0b25..a37e099 100644
--- a/src/views/crm/backlog/modules/customer-today-contact-list.vue
+++ b/src/views/crm/backlog/modules/customer-today-contact-list.vue
@@ -4,6 +4,7 @@
import type { CrmCustomerApi } from '#/api/crm/customer';
import { useRouter } from 'vue-router';
+import { erpNumberFormatter } from '@vben/utils';
import { Button } from 'ant-design-vue';
@@ -78,6 +79,10 @@
<template #name="{ row }">
<Button type="link" @click="handleDetail(row)">{{ row.name }}</Button>
</template>
+ <template #contracts="{ row }">
+ <span v-if="row.contractCount">{{ row.contractCount }} 浠� 路 楼{{ erpNumberFormatter(row.contractTotalPrice, 2) }}</span>
+ <span v-else>鈥�</span>
+ </template>
<template #actions="{ row }">
<Button type="link" @click="handleDetail(row)">鏌ョ湅璇︽儏</Button>
</template>
diff --git a/src/views/crm/backlog/modules/receivable-audit-list.vue b/src/views/crm/backlog/modules/receivable-audit-list.vue
index a2a80be..de37fe4 100644
--- a/src/views/crm/backlog/modules/receivable-audit-list.vue
+++ b/src/views/crm/backlog/modules/receivable-audit-list.vue
@@ -7,13 +7,14 @@
import { Button, message } from 'ant-design-vue';
-import { useVbenVxeGrid } from '#/adapter/vxe-table';
+import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getReceivablePage, updateReceivableStatus } from '#/api/crm/receivable';
import { useGridColumns } from '#/views/crm/receivable/data';
import { AUDIT_STATUS } from '../data';
const { push } = useRouter();
+const emit = defineEmits<{ refresh: [] }>();
/** 瀹℃牳 */
async function handleAudit(row: CrmReceivableApi.Receivable) {
@@ -24,7 +25,8 @@
try {
await updateReceivableStatus(row.id!, 20);
message.success('瀹℃牳鎴愬姛');
- gridApi.query();
+ await gridApi.query();
+ emit('refresh');
} finally {
hideLoading();
}
@@ -42,7 +44,11 @@
/** 鎵撳紑鍚堝悓璇︽儏 */
function handleContractDetail(row: CrmReceivableApi.Receivable) {
- push({ name: 'CrmContractDetail', params: { id: row.contractId } });
+ if (row.contractId) push({ name: 'CrmContractDetail', params: { id: row.contractId } });
+}
+
+function handleInvoiceDetail(row: CrmReceivableApi.Receivable) {
+ if (row.invoiceId) push({ name: 'CrmInvoiceDetail', params: { id: row.invoiceId } });
}
const [Grid, gridApi] = useVbenVxeGrid({
@@ -50,7 +56,7 @@
schema: [
{
fieldName: 'auditStatus',
- label: '鍚堝悓鐘舵��',
+ label: '瀹℃牳鐘舵��',
component: 'Select',
componentProps: {
allowClear: true,
@@ -70,6 +76,7 @@
return await getReceivablePage({
pageNo: page.currentPage,
pageSize: page.pageSize,
+ sceneType: 1,
...formValues,
});
},
@@ -100,18 +107,26 @@
</Button>
</template>
<template #contractNo="{ row }">
- <Button type="link" @click="handleContractDetail(row)">
- {{ row.contractNo }}
+ <Button v-if="row.contractId" type="link" @click="handleContractDetail(row)">
+ {{ row.contract?.no ?? row.contractNo ?? '鈥�' }}
</Button>
+ <span v-else>鈥�</span>
+ </template>
+ <template #invoiceNo="{ row }">
+ <template v-if="row.invoice">
+ <Button type="link" @click="handleInvoiceDetail(row)">{{ row.invoice.no }}</Button>
+ <span> / {{ row.invoice.invoiceNo ?? '鈥�' }} / 楼{{ row.invoice.price ?? 0 }}</span>
+ </template>
+ <span v-else>鈥�</span>
</template>
<template #actions="{ row }">
- <Button
- v-if="row.auditStatus === 10"
- type="link"
- @click="handleAudit(row)"
- >
- 瀹℃牳
- </Button>
+ <TableAction :actions="[{
+ label: '瀹℃牳',
+ type: 'link',
+ auth: ['crm:receivable:update'],
+ ifShow: row.auditStatus === 10,
+ onClick: handleAudit.bind(null, row),
+ }]" />
</template>
</Grid>
</template>
diff --git a/src/views/crm/backlog/modules/receivable-plan-remind-list.vue b/src/views/crm/backlog/modules/receivable-plan-remind-list.vue
index 4bafa46..697e673 100644
--- a/src/views/crm/backlog/modules/receivable-plan-remind-list.vue
+++ b/src/views/crm/backlog/modules/receivable-plan-remind-list.vue
@@ -9,7 +9,7 @@
import { Button } from 'ant-design-vue';
-import { useVbenVxeGrid } from '#/adapter/vxe-table';
+import { TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { getReceivablePlanPage } from '#/api/crm/receivable/plan';
import Form from '#/views/crm/receivable/modules/form.vue';
import { useGridColumns } from '#/views/crm/receivable/plan/data';
@@ -17,15 +17,21 @@
import { RECEIVABLE_REMIND_TYPE } from '../data';
const { push } = useRouter();
+const emit = defineEmits<{ refresh: [] }>();
+
+function handleRefresh() {
+ gridApi.query();
+ emit('refresh');
+}
const [FormModal, formModalApi] = useVbenModal({
connectedComponent: Form,
destroyOnClose: true,
});
-/** 鎵撳紑鍥炴璇︽儏 */
+/** 鎵撳紑鍥炴璁″垝璇︽儏 */
function handleDetail(row: CrmReceivablePlanApi.Plan) {
- push({ name: 'CrmReceivableDetail', params: { id: row.id } });
+ push({ name: 'CrmReceivablePlanDetail', params: { id: row.id } });
}
/** 鎵撳紑瀹㈡埛璇︽儏 */
@@ -35,15 +41,16 @@
/** 鍒涘缓鍥炴 */
function handleCreateReceivable(row: CrmReceivablePlanApi.Plan) {
+ if (row.receivableId) return;
formModalApi.setData({ plan: row }).open();
}
-const [Grid] = useVbenVxeGrid({
+const [Grid, gridApi] = useVbenVxeGrid({
formOptions: {
schema: [
{
fieldName: 'remindType',
- label: '鍚堝悓鐘舵��',
+ label: '鍥炴鐘舵��',
component: 'Select',
componentProps: {
allowClear: true,
@@ -63,6 +70,7 @@
return await getReceivablePlanPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
+ sceneType: 1,
...formValues,
});
},
@@ -82,7 +90,7 @@
<template>
<div>
- <FormModal />
+ <FormModal @success="handleRefresh" />
<Grid>
<template #customerName="{ row }">
<Button type="link" @click="handleCustomerDetail(row)">
@@ -93,9 +101,13 @@
<Button type="link" @click="handleDetail(row)">{{ row.period }}</Button>
</template>
<template #actions="{ row }">
- <Button type="link" @click="handleCreateReceivable(row)">
- 鍒涘缓鍥炴
- </Button>
+ <TableAction :actions="[{
+ label: '鍒涘缓鍥炴',
+ type: 'link',
+ auth: ['crm:receivable:create'],
+ ifShow: !row.receivableId,
+ onClick: handleCreateReceivable.bind(null, row),
+ }]" />
</template>
</Grid>
</div>
diff --git a/src/views/crm/contract/detail/index.vue b/src/views/crm/contract/detail/index.vue
index 310c838..cd14401 100644
--- a/src/views/crm/contract/detail/index.vue
+++ b/src/views/crm/contract/detail/index.vue
@@ -17,6 +17,7 @@
import { OperateLog } from '#/components/operate-log';
import { ACTION_ICON, TableAction } from '#/components/table-action';
import { $t } from '#/locales';
+import { downloadContractWord } from '#/utils/contract-document';
import { FollowUp } from '#/views/crm/followup';
import { PermissionList, TransferForm } from '#/views/crm/permission';
import { ProductDetailsList } from '#/views/crm/product/components';
@@ -119,6 +120,13 @@
onClick: handleEdit,
},
{
+ label: '涓嬭浇鍚堝悓',
+ type: 'primary',
+ icon: 'lucide:download',
+ auth: ['crm:contract:query'],
+ onClick: () => downloadContractWord(contractId, contract.no),
+ },
+ {
label: '杞Щ',
type: 'primary',
ifShow: permissionListRef?.validateOwnerUser,
diff --git a/src/views/crm/contract/index.vue b/src/views/crm/contract/index.vue
index c57bffe..cd8650e 100644
--- a/src/views/crm/contract/index.vue
+++ b/src/views/crm/contract/index.vue
@@ -21,6 +21,7 @@
} from '#/api/crm/contract';
import { $t } from '#/locales';
import { automaticApproval } from '#/store/audit-policy';
+import { downloadContractWord } from '#/utils/contract-document';
import { useGridColumns, useGridFormSchema } from './data';
import Form from './modules/form.vue';
@@ -332,6 +333,13 @@
<TableAction
:actions="[
{
+ label: '涓嬭浇鍚堝悓',
+ type: 'link',
+ icon: 'lucide:download',
+ auth: ['crm:contract:query'],
+ onClick: () => downloadContractWord(row.id, row.no),
+ },
+ {
label: $t('common.edit'),
type: 'link',
icon: ACTION_ICON.EDIT,
diff --git a/src/views/crm/saleQuotation/index.vue b/src/views/crm/saleQuotation/index.vue
index 9a221d3..cf01246 100644
--- a/src/views/crm/saleQuotation/index.vue
+++ b/src/views/crm/saleQuotation/index.vue
@@ -15,6 +15,7 @@
getSaleQuotationPage,
} from '#/api/crm/saleQuotation';
import { $t } from '#/locales';
+import { downloadContractWord } from '#/utils/contract-document';
import type { CrmSaleQuotationAiApi } from '#/api/crm/saleQuotation/ai';
@@ -107,6 +108,12 @@
async onOk() {
const contractId = await convertSaleQuotationToContract(row.id!);
message.success('杞悎鍚屾垚鍔�');
+ gridApi.query();
+ try {
+ await downloadContractWord(contractId);
+ } catch {
+ message.warning('鍚堝悓宸插垱寤猴紝鏂囦欢涓嬭浇澶辫触锛屽彲鍦ㄥ悎鍚岃鎯呬腑閲嶆柊涓嬭浇');
+ }
push({ name: 'CrmContractDetail', params: { id: contractId } });
},
});
@@ -218,6 +225,13 @@
ifShow: !!row.contractId,
},
{
+ label: '涓嬭浇鍚堝悓',
+ type: 'link',
+ auth: ['crm:contract:query'],
+ onClick: () => downloadContractWord(row.contractId!, row.contractNo),
+ ifShow: !!row.contractId,
+ },
+ {
label: $t('common.delete'),
type: 'link',
danger: true,
@@ -233,4 +247,4 @@
</template>
</Grid>
</Page>
-</template>
\ No newline at end of file
+</template>
diff --git a/src/views/mes/home/modules/alert-panel.vue b/src/views/mes/home/modules/alert-panel.vue
index 8584cce..1acc6d0 100644
--- a/src/views/mes/home/modules/alert-panel.vue
+++ b/src/views/mes/home/modules/alert-panel.vue
@@ -20,14 +20,6 @@
/** 寰呭姙鎻愰啋鍒楄〃锛氭爣绛俱�佹弿杩般�佸浘鏍囥�佺洰鏍囪矾鐢卞悕绉般�佹暟閲� */
const alertItems = computed(() => [
{
- count: props.summary.andonActiveCount,
- desc: '鏈缃殑瀹夌伅鍛煎彨',
- icon: 'lucide:bell-ring',
- iconClass: 'bg-red-50 text-red-500',
- label: '瀹夌伅鎶ヨ',
- routeName: 'MesProAndonRecord',
- },
- {
count: props.summary.repairActiveCount,
desc: '寰呭鐞嗙殑缁翠慨璁㈠崟',
icon: 'lucide:wrench',
diff --git a/src/views/mes/md/workstation/components/workshop-select.vue b/src/views/mes/md/workstation/components/workshop-select.vue
index bf71b92..3b525d0 100644
--- a/src/views/mes/md/workstation/components/workshop-select.vue
+++ b/src/views/mes/md/workstation/components/workshop-select.vue
@@ -82,10 +82,6 @@
<div v-if="selectedItem" class="leading-6">
<div>缂栫爜锛歿{ selectedItem.code || '-' }}</div>
<div>鍚嶇О锛歿{ selectedItem.name || '-' }}</div>
- <div>
- 闈㈢Н锛�
- {{ selectedItem.area !== null ? `${selectedItem.area} 銕 : '-' }}
- </div>
<div>璐熻矗浜猴細{{ selectedItem.chargeUserName || '-' }}</div>
</div>
</template>
diff --git a/src/views/mes/md/workstation/workshop/data.ts b/src/views/mes/md/workstation/workshop/data.ts
index 21e977d..3b8fbe2 100644
--- a/src/views/mes/md/workstation/workshop/data.ts
+++ b/src/views/mes/md/workstation/workshop/data.ts
@@ -76,16 +76,6 @@
rules: 'required',
},
{
- fieldName: 'area',
- label: '闈㈢Н',
- component: 'InputNumber',
- componentProps: {
- class: '!w-full',
- min: 0,
- precision: 2,
- },
- },
- {
fieldName: 'chargeUserId',
label: '璐熻矗浜�',
component: 'ApiSelect',
@@ -168,11 +158,6 @@
field: 'name',
title: '杞﹂棿鍚嶇О',
minWidth: 150,
- },
- {
- field: 'area',
- title: '闈㈢Н',
- width: 120,
},
{
field: 'chargeUserName',
--
Gitblit v1.9.3