| | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { ErpSaleOrderApi } from '#/api/erp/sale/order'; |
| | | |
| | | import { ref } from 'vue'; |
| | | import { onMounted, ref } from 'vue'; |
| | | import { useRoute, useRouter } from 'vue-router'; |
| | | |
| | | import { DocAlert, Page, useVbenModal } from '..\..\..\..\packages\effects\common-ui\src'; |
| | | import { downloadFileFromBlobPart, isEmpty } from '..\..\..\..\packages\utils\src'; |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | import { downloadFileFromBlobPart, isEmpty } from '@vben/utils'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | import { message, Tag, Tooltip } from 'ant-design-vue'; |
| | | |
| | | import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { |
| | | cancelSaleOrder, |
| | | deleteSaleOrder, |
| | | enableSaleOrder, |
| | | exportSaleOrder, |
| | | getSaleOrderPage, |
| | | updateSaleOrderStatus, |
| | | } from '#/api/erp/sale/order'; |
| | | import { generateFromSaleOrder } from '#/api/mes/wm/salesnotice'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | | import SalesNoticeForm from '#/views/wls/salesnotice/modules/form.vue'; |
| | | |
| | | /** ERP 销售订单列表 */ |
| | | defineOptions({ name: 'ErpSaleOrder' }); |
| | | |
| | | const router = useRouter(); |
| | | const route = useRoute(); |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | | connectedComponent: Form, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [SalesNoticeFormModal, salesNoticeFormModalApi] = useVbenModal({ |
| | | connectedComponent: SalesNoticeForm, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | /** 作废销售订单 */ |
| | | async function handleCancel(row: ErpSaleOrderApi.SaleOrder) { |
| | | const hideLoading = message.loading({ |
| | | content: '正在作废该订单...', |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | await cancelSaleOrder(row.id!); |
| | | message.success('作废成功'); |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | /** 启用销售订单(恢复已作废订单) */ |
| | | async function handleEnable(row: ErpSaleOrderApi.SaleOrder) { |
| | | const hideLoading = message.loading({ |
| | | content: '正在启用该订单...', |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | await enableSaleOrder(row.id!); |
| | | message.success('启用成功'); |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | const checkedIds = ref<number[]>([]); |
| | | function handleRowCheckboxChange({ |
| | | records, |
| | |
| | | formModalApi.setData({ formType: 'detail', id: row.id }).open(); |
| | | } |
| | | |
| | | /** 查看关联合同 */ |
| | | function handleViewContract(row: ErpSaleOrderApi.SaleOrder) { |
| | | if (row.contractId) { |
| | | router.push({ |
| | | path: `/crm/contract/detail/${row.contractId}`, |
| | | }); |
| | | } |
| | | } |
| | | |
| | | /** 生成发货通知单 */ |
| | | async function handleGenerateNotice(row: ErpSaleOrderApi.SaleOrder) { |
| | | try { |
| | | const noticeId = await generateFromSaleOrder(row.id!); |
| | | message.success('生成发货通知单成功'); |
| | | handleRefresh(); |
| | | // 直接打开发货通知单详情弹框 |
| | | salesNoticeFormModalApi |
| | | .setData({ formType: 'detail', id: noticeId }) |
| | | .open(); |
| | | } catch (e) { |
| | | console.error(e); |
| | | } |
| | | } |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | | formOptions: { |
| | | schema: useGridFormSchema(), |
| | |
| | | proxyConfig: { |
| | | ajax: { |
| | | query: async ({ page }, formValues) => { |
| | | // 生产状态搜索参数转换:-1(无需生产) → needProduction=0 |
| | | const { productionStatus, ...rest } = formValues; |
| | | const params: Record<string, any> = { ...rest }; |
| | | if (productionStatus === -1) { |
| | | params.needProduction = 0; |
| | | } else if (productionStatus != null) { |
| | | params.productionStatus = productionStatus; |
| | | params.needProduction = 1; |
| | | } |
| | | return await getSaleOrderPage({ |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | ...formValues, |
| | | ...params, |
| | | }); |
| | | }, |
| | | }, |
| | |
| | | checkboxChange: handleRowCheckboxChange, |
| | | }, |
| | | }); |
| | | |
| | | /** 处理从合同跳转过来的查询参数 */ |
| | | onMounted(() => { |
| | | const orderId = route.query.id; |
| | | if (orderId) { |
| | | formModalApi.setData({ formType: 'detail', id: Number(orderId) }).open(); |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Page auto-content-height> |
| | | <template #doc> |
| | | <DocAlert |
| | | title="【销售】销售订单、出库、退货" |
| | | url="https://doc.iocoder.cn/erp/sale/" |
| | | /> |
| | | </template> |
| | | |
| | | <FormModal @success="handleRefresh" /> |
| | | <SalesNoticeFormModal /> |
| | | <Grid table-title="销售订单列表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #no="{ row }"> |
| | | <Tooltip v-if="row.status === 30" title="该订单已作废,订单已失效"> |
| | | <span class="text-red-500 cursor-pointer" @click="handleDetail(row)"> |
| | | {{ row.no }} |
| | | </span> |
| | | </Tooltip> |
| | | <a v-else class="text-primary cursor-pointer" @click="handleDetail(row)"> |
| | | {{ row.no }} |
| | | </a> |
| | | </template> |
| | | <template #contractNo="{ row }"> |
| | | <a v-if="row.contractId" class="text-primary cursor-pointer" @click="handleViewContract(row)"> |
| | | {{ row.contractNo }} |
| | | </a> |
| | | <span v-else>-</span> |
| | | </template> |
| | | <template #status="{ row }"> |
| | | <Tag v-if="row.status === 10" color="warning">未审核</Tag> |
| | | <Tag v-if="row.status === 20" color="success">已审核</Tag> |
| | | <Tag v-if="row.status === 30" color="error">已作废</Tag> |
| | | </template> |
| | | <template #needProduction="{ row }"> |
| | | <Tag v-if="row.needProduction === 1" color="success">是</Tag> |
| | | <Tag v-else color="default">否</Tag> |
| | | </template> |
| | | <template #outStatus="{ row }"> |
| | | <Tag v-if="row.outStatus === 0" color="default">未出库</Tag> |
| | | <Tag v-else-if="row.outStatus === 1" color="processing">已预留</Tag> |
| | | <Tag v-else-if="row.outStatus === 2" color="warning">部分出库</Tag> |
| | | <Tag v-else-if="row.outStatus === 3" color="success">全部出库</Tag> |
| | | </template> |
| | | <template #productionStatus="{ row }"> |
| | | <template v-if="row.needProduction !== 1"> |
| | | <Tag color="default">无需生产</Tag> |
| | | </template> |
| | | <template v-else> |
| | | <Tag v-if="row.productionStatus === 0" color="warning">未完成</Tag> |
| | | <Tag v-else-if="row.productionStatus === 1" color="success">已完成</Tag> |
| | | </template> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| | | auth: ['erp:sale-order:update'], |
| | | ifShow: () => row.status !== 20, |
| | | ifShow: () => row.status === 10, |
| | | onClick: handleEdit.bind(null, row), |
| | | }, |
| | | { |
| | | label: row.status === 10 ? '审批' : '反审批', |
| | | label: '审批', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['erp:sale-order:update-status'], |
| | | ifShow: () => row.status === 10, |
| | | popConfirm: { |
| | | title: `确认${row.status === 10 ? '审批' : '反审批'}${row.no}吗?`, |
| | | confirm: handleUpdateStatus.bind( |
| | | null, |
| | | row, |
| | | row.status === 10 ? 20 : 10, |
| | | ), |
| | | title: `确认审批${row.no}吗?`, |
| | | confirm: handleUpdateStatus.bind(null, row, 20), |
| | | }, |
| | | }, |
| | | { |
| | | label: '反审批', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['erp:sale-order:update-status'], |
| | | ifShow: () => row.status === 20, |
| | | popConfirm: { |
| | | title: `确认反审批${row.no}吗?`, |
| | | confirm: handleUpdateStatus.bind(null, row, 10), |
| | | }, |
| | | }, |
| | | { |
| | | label: '作废', |
| | | type: 'link', |
| | | icon: 'ant-design:stop-outlined', |
| | | auth: ['erp:sale-order:cancel'], |
| | | ifShow: () => row.status === 20, |
| | | popConfirm: { |
| | | title: `确认作废${row.no}吗?作废后不可恢复!`, |
| | | confirm: handleCancel.bind(null, row), |
| | | }, |
| | | }, |
| | | { |
| | | label: '启用', |
| | | type: 'link', |
| | | icon: 'ant-design:check-circle-outlined', |
| | | auth: ['erp:sale-order:enable'], |
| | | ifShow: () => row.status === 30, |
| | | popConfirm: { |
| | | title: `确认启用${row.no}吗?`, |
| | | confirm: handleEnable.bind(null, row), |
| | | }, |
| | | }, |
| | | { |
| | | label: '生成发货通知单', |
| | | type: 'link', |
| | | icon: 'ant-design:file-protect-outlined', |
| | | auth: ['mes:wm-sales-notice:create'], |
| | | ifShow: () => row.status === 20 && row.canCreateSalesNotice, |
| | | onClick: handleGenerateNotice.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.delete'), |
| | |
| | | danger: true, |
| | | icon: ACTION_ICON.DELETE, |
| | | auth: ['erp:sale-order:delete'], |
| | | ifShow: () => row.status === 10, |
| | | popConfirm: { |
| | | title: $t('ui.actionMessage.deleteConfirm', [row.no]), |
| | | confirm: handleDelete.bind(null, [row.id!]), |