feat(bpm): 审批统一走 BPM,补齐各业务审批详情组件
- 21 个业务列表页与 MES 项目详情页隐藏旧「审核 / 审核不通过」按钮,审批改在协同办公-待办任务中完成
- 新增 16 个审批详情组件 detail/approve/index.vue:
CRM 退费/销户,ERP 采购计划/申请/订单,HRM 转正/绩效考核,
MES 技术确认/设计项目,仓储设备入库/采购入库/杂项出入库/供应商退货/盘点结果,售后赔付
- 新增 HRM 转正 API
Co-Authored-By: Claude <noreply@anthropic.com>
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import type { PageParam, PageResult } from '@vben/request'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace HrmRegularizeApi { |
| | | /** 转æ£ç³è¯· */ |
| | | export interface Regularize { |
| | | id?: number; // ç³è¯·ID |
| | | no?: string; // ç³è¯·åå· |
| | | userId?: number; // ç³è¯·äººID |
| | | userName?: string; // ç³è¯·äººå§å |
| | | deptId?: number; // é¨é¨ID |
| | | deptName?: string; // é¨é¨åç§° |
| | | postId?: number; // å²ä½ID |
| | | postName?: string; // å²ä½åç§° |
| | | employmentType?: number; // å½åç¨å·¥æ§è´¨ |
| | | employmentTypeName?: string; // å½åç¨å·¥æ§è´¨åç§° |
| | | expectedDate?: string; // æè½¬æ£æ¥æ |
| | | reason?: string; // 转æ£åå |
| | | status?: number; // 审æ¹ç¶æï¼0è稿 10审æ¹ä¸ 20éè¿ 30驳å 40已忶 |
| | | statusName?: string; // 审æ¹ç¶æåç§° |
| | | reviewerId?: number; // å®¡æ ¸äººç¼å· |
| | | reviewerName?: string; // å®¡æ ¸äººå§å |
| | | reviewTime?: string; // å®¡æ ¸æ¶é´ |
| | | reviewRemark?: string; // å®¡æ ¸æè§ |
| | | approveTime?: string; // 审æ¹å®ææ¶é´ |
| | | remark?: string; // 夿³¨ |
| | | createTime?: string; // å建æ¶é´ |
| | | } |
| | | |
| | | export interface PageParams extends PageParam { |
| | | no?: string; |
| | | userId?: number; |
| | | status?: number; |
| | | } |
| | | } |
| | | |
| | | /** æ¥è¯¢è½¬æ£ç³è¯·å页 */ |
| | | export function getRegularizePage(params: HrmRegularizeApi.PageParams) { |
| | | return requestClient.get<PageResult<HrmRegularizeApi.Regularize>>( |
| | | '/hrm/regularize/page', |
| | | { params }, |
| | | ); |
| | | } |
| | | |
| | | /** æ¥è¯¢è½¬æ£ç³è¯·è¯¦æ
*/ |
| | | export function getRegularize(id: number) { |
| | | return requestClient.get<HrmRegularizeApi.Regularize>( |
| | | `/hrm/regularize/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | /** æäº¤å®¡æ¹ï¼è稿 / å®¡æ ¸ä¸éè¿ â 审æ¹ä¸ï¼ */ |
| | | export function submitRegularize(id: number) { |
| | | return requestClient.put('/hrm/regularize/submit', null, { params: { id } }); |
| | | } |
| | | |
| | | /** å®¡æ ¸è½¬æ£ç³è¯· */ |
| | | export function auditRegularize( |
| | | id: number, |
| | | pass: boolean, |
| | | reviewRemark?: string, |
| | | ) { |
| | | return requestClient.put('/hrm/regularize/audit', { id, pass, reviewRemark }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { AfterSaleCompensationApi } from '#/api/aftersales/compensation'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { erpPriceInputFormatter, formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getCompensation } from '#/api/aftersales/compensation'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'AfterSaleCompensationApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<AfterSaleCompensationApi.Compensation>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'èµä»åå·', field: 'compensationNo', render: textRender }, |
| | | { |
| | | label: 'èµä»ç±»å', |
| | | field: 'compensationType', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.AFTER_SALE_COMPENSATION_TYPE, value: val }), |
| | | }, |
| | | { label: '客æ·åç§°', field: 'customerName', render: textRender }, |
| | | { |
| | | label: 'èµä»éé¢ï¼å
ï¼', |
| | | field: 'amount', |
| | | render: (val) => erpPriceInputFormatter(val) || '-', |
| | | }, |
| | | { label: 'èµä»å¯¹è±¡', field: 'payee', render: textRender }, |
| | | { label: 'èµä»åå ', field: 'reason', render: textRender }, |
| | | { label: 'å
³èå®åå·¥å', field: 'ticketId', render: textRender }, |
| | | { label: 'å
³èéå®è®¢å', field: 'saleOrderId', render: textRender }, |
| | | { label: '审æ¹ç¶æ', field: 'auditStatusName', render: textRender }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { |
| | | label: 'å®¡æ ¸æ¶é´', |
| | | field: 'reviewTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { |
| | | label: 'å建æ¶é´', |
| | | field: 'createTime', |
| | | render: (val) => formatDateTime(val) as string, |
| | | }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getCompensation(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- èµä»åºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">èµä»åºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | row.auditStatus === AUDIT_STATUS.REJECT, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['aftersales:compensation:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['aftersales:compensation:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: $t('common.delete'), |
| | | type: 'link', |
| | | danger: true, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { CrmCancellationApi } from '#/api/crm/cancellation'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { erpPriceInputFormatter, formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getCancellation } from '#/api/crm/cancellation'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'CrmCancellationApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<CrmCancellationApi.Cancellation>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'éæ·ç¼å·', field: 'cancellationNo', render: textRender }, |
| | | { label: '客æ·åç§°', field: 'customerName', render: textRender }, |
| | | { label: 'ååç¼å·', field: 'contractNo', render: textRender }, |
| | | { |
| | | label: 'éæ·ç±»å', |
| | | field: 'cancellationType', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.CRM_CANCELLATION_TYPE, value: val }), |
| | | }, |
| | | { label: 'éæ·åå ', field: 'cancelReason', render: textRender }, |
| | | { |
| | | label: 'é¢è®¡éæ·æ¥æ', |
| | | field: 'expectedCancelDate', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { |
| | | label: 'å®é
éæ·æ¥æ', |
| | | field: 'actualCancelDate', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { |
| | | label: 'éè´¹éé¢ï¼å
ï¼', |
| | | field: 'refundAmount', |
| | | render: (val) => erpPriceInputFormatter(val) || '-', |
| | | }, |
| | | { label: 'ç³è¯·äºº', field: 'applyUserName', render: textRender }, |
| | | { |
| | | label: 'ç³è¯·æ¶é´', |
| | | field: 'applyTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { |
| | | label: '审æ¹ç¶æ', |
| | | field: 'auditStatus', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.CRM_AUDIT_STATUS, value: val }), |
| | | }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { |
| | | label: 'å®¡æ ¸æ¶é´', |
| | | field: 'reviewTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { |
| | | label: 'å建æ¶é´', |
| | | field: 'createTime', |
| | | render: (val) => formatDateTime(val) as string, |
| | | }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getCancellation(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- éæ·åºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">éæ·åºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | ifShow: row.auditStatus === 0 || row.auditStatus === 30, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['crm:cancellation:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['crm:cancellation:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: $t('common.delete'), |
| | | type: 'link', |
| | | danger: true, |
| | |
| | | ifShow: row.auditStatus === 0 || row.auditStatus === 30, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['crm:contract:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['crm:contract:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'çæéå®è®¢å', |
| | | type: 'link', |
| | | auth: ['crm:contract:update'], |
| | |
| | | ifShow: row.auditStatus === 0 || row.auditStatus === 30, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['crm:invoice:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['crm:invoice:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: $t('common.delete'), |
| | | type: 'link', |
| | | danger: true, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { CrmRefundApi } from '#/api/crm/refund'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { erpPriceInputFormatter, formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getRefund } from '#/api/crm/refund'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'CrmRefundApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<CrmRefundApi.Refund>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'éè´¹ç¼å·', field: 'refundNo', render: textRender }, |
| | | { label: '客æ·åç§°', field: 'customerName', render: textRender }, |
| | | { label: 'ååç¼å·', field: 'contractNo', render: textRender }, |
| | | { |
| | | label: 'é费类å', |
| | | field: 'refundType', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.CRM_REFUND_TYPE, value: val }), |
| | | }, |
| | | { |
| | | label: 'éè´¹éé¢ï¼å
ï¼', |
| | | field: 'refundAmount', |
| | | render: (val) => erpPriceInputFormatter(val) || '-', |
| | | }, |
| | | { label: 'éè´¹åå ', field: 'refundReason', render: textRender }, |
| | | { label: 'ç³è¯·äºº', field: 'applyUserName', render: textRender }, |
| | | { |
| | | label: 'ç³è¯·æ¶é´', |
| | | field: 'applyTime', |
| | | render: (val) => formatDateTime(val) as string, |
| | | }, |
| | | { |
| | | label: '审æ¹ç¶æ', |
| | | field: 'auditStatus', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.CRM_AUDIT_STATUS, value: val }), |
| | | }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { |
| | | label: 'å®¡æ ¸æ¶é´', |
| | | field: 'reviewTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { |
| | | label: 'å建æ¶é´', |
| | | field: 'createTime', |
| | | render: (val) => formatDateTime(val) as string, |
| | | }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getRefund(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- éè´¹åºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">éè´¹åºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | ifShow: row.auditStatus === 0 || row.auditStatus === 30, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['crm:refund:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['crm:refund:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: $t('common.delete'), |
| | | type: 'link', |
| | | danger: true, |
| | |
| | | onClick: handleSubmit.bind(null, row), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['erp:finance-payment:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·æ¯å®¡æ¹äººãææ¾ç¤ºï¼å
¶ä»äººçä¸å°è¯¥æé® |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['erp:finance-payment:audit'], |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'æ¥ç审æ¹', |
| | | type: 'link', |
| | | icon: ACTION_ICON.VIEW, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { ErpPurchaseOrderApi } from '#/api/erp/purchase/order'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import type { TableColumnsType } from 'ant-design-vue'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { |
| | | erpCountInputFormatter, |
| | | erpPriceInputFormatter, |
| | | formatDateTime, |
| | | } from '@vben/utils'; |
| | | |
| | | import { Spin, Table } from 'ant-design-vue'; |
| | | |
| | | import { getPurchaseOrder } from '#/api/erp/purchase/order'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'ErpPurchaseOrderApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<ErpPurchaseOrderApi.PurchaseOrder>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** 订åæç»å */ |
| | | const itemColumns: TableColumnsType = [ |
| | | { title: 'åºå·', key: 'seq', width: 60, align: 'center' }, |
| | | { title: '产ååç§°', dataIndex: 'productName', width: 160 }, |
| | | { title: 'åä½', dataIndex: 'productUnitName', width: 90 }, |
| | | { |
| | | title: 'æ°é', |
| | | dataIndex: 'count', |
| | | width: 100, |
| | | align: 'right', |
| | | customRender: ({ text }) => erpCountInputFormatter(text) || '-', |
| | | }, |
| | | { |
| | | title: 'åä»·ï¼å
ï¼', |
| | | dataIndex: 'productPrice', |
| | | width: 120, |
| | | align: 'right', |
| | | customRender: ({ text }) => erpPriceInputFormatter(text) || '-', |
| | | }, |
| | | { |
| | | title: 'æ»ä»·ï¼å
ï¼', |
| | | dataIndex: 'totalPrice', |
| | | width: 120, |
| | | align: 'right', |
| | | customRender: ({ text }) => erpPriceInputFormatter(text) || '-', |
| | | }, |
| | | { title: '夿³¨', dataIndex: 'remark', width: 140 }, |
| | | ]; |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'éè´è®¢åå·', field: 'no', render: textRender }, |
| | | { label: 'ä¾åºå', field: 'supplierName', render: textRender }, |
| | | { |
| | | label: 'è®¢åæ¶é´', |
| | | field: 'orderTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { |
| | | label: 'ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.ERP_AUDIT_STATUS, value: val }), |
| | | }, |
| | | { |
| | | label: 'å计æ°é', |
| | | field: 'totalCount', |
| | | render: (val) => erpCountInputFormatter(val) || '-', |
| | | }, |
| | | { |
| | | label: 'å计éé¢ï¼å
ï¼', |
| | | field: 'totalPrice', |
| | | render: (val) => erpPriceInputFormatter(val) || '-', |
| | | }, |
| | | { |
| | | label: '伿 çï¼%ï¼', |
| | | field: 'discountPercent', |
| | | render: (val) => (val === 0 || val ? String(val) : '-'), |
| | | }, |
| | | { |
| | | label: 'å®ééé¢ï¼å
ï¼', |
| | | field: 'depositPrice', |
| | | render: (val) => erpPriceInputFormatter(val) || '-', |
| | | }, |
| | | { label: '产ååç§°', field: 'productNames', render: textRender }, |
| | | { label: 'å建人', field: 'creatorName', render: textRender }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { |
| | | label: 'å®¡æ ¸æ¶é´', |
| | | field: 'reviewTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { |
| | | label: 'å建æ¶é´', |
| | | field: 'createTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getPurchaseOrder(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- éè´è®¢ååºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">éè´è®¢ååºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | <!-- éè´è®¢åæç» --> |
| | | <div |
| | | v-if="formData?.items && formData.items.length > 0" |
| | | class="rounded-lg border border-border bg-background p-4" |
| | | > |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">éè´è®¢åæç»</span> |
| | | </div> |
| | | <Table |
| | | :columns="itemColumns" |
| | | :data-source="formData.items" |
| | | :pagination="false" |
| | | bordered |
| | | size="small" |
| | | > |
| | | <template #bodyCell="{ column, index }"> |
| | | <template v-if="column.key === 'seq'">{{ index + 1 }}</template> |
| | | </template> |
| | | </Table> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | onClick: handleSubmit.bind(null, row), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['erp:purchase-order:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·æ¯å®¡æ¹äººãææ¾ç¤ºï¼å
¶ä»äººçä¸å°è¯¥æé® |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['erp:purchase-order:audit'], |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'æ¥ç审æ¹', |
| | | type: 'link', |
| | | icon: ACTION_ICON.VIEW, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { ErpPurchasePlanApi } from '#/api/erp/purchase/plan'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import type { TableColumnsType } from 'ant-design-vue'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { erpCountInputFormatter, formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin, Table } from 'ant-design-vue'; |
| | | |
| | | import { getPurchasePlan } from '#/api/erp/purchase/plan'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'ErpPurchasePlanApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<ErpPurchasePlanApi.PurchasePlan>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** 计åæç»å */ |
| | | const itemColumns: TableColumnsType = [ |
| | | { title: 'åºå·', key: 'seq', width: 60, align: 'center' }, |
| | | { title: '产ååç§°', dataIndex: 'productName', width: 160 }, |
| | | { title: 'åä½', dataIndex: 'productUnitName', width: 90 }, |
| | | { |
| | | title: '计åéè´æ°é', |
| | | dataIndex: 'count', |
| | | width: 120, |
| | | align: 'right', |
| | | customRender: ({ text }) => erpCountInputFormatter(text) || '-', |
| | | }, |
| | | { |
| | | title: 'éæ±æ¥æ', |
| | | dataIndex: 'demandTime', |
| | | width: 160, |
| | | customRender: ({ text }) => (text ? formatDateTime(text) : '-'), |
| | | }, |
| | | { title: '夿³¨', dataIndex: 'remark', width: 140 }, |
| | | ]; |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: '计ååå·', field: 'no', render: textRender }, |
| | | { label: '计ååç§°', field: 'name', render: textRender }, |
| | | { |
| | | label: 'ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.ERP_AUDIT_STATUS, value: val }), |
| | | }, |
| | | { label: 'éæ±æ¥æº', field: 'demandSourceName', render: textRender }, |
| | | { |
| | | label: 'è®¡åæ¥æ', |
| | | field: 'planDate', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'ç¼å¶äºº', field: 'planUserName', render: textRender }, |
| | | { label: 'ç¼å¶é¨é¨', field: 'planDeptName', render: textRender }, |
| | | { label: 'ä¾åºå', field: 'supplierName', render: textRender }, |
| | | { |
| | | label: 'å计æ°é', |
| | | field: 'totalCount', |
| | | render: (val) => erpCountInputFormatter(val) || '-', |
| | | }, |
| | | { |
| | | label: 'æ¯å¦å·²çæéè´ç³è¯·', |
| | | field: 'generatedFlag', |
| | | render: (val) => (val ? 'æ¯' : 'å¦'), |
| | | }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { |
| | | label: 'å®¡æ ¸æ¶é´', |
| | | field: 'reviewTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { label: '产ååç§°', field: 'productNames', render: textRender }, |
| | | { |
| | | label: 'å建æ¶é´', |
| | | field: 'createTime', |
| | | render: (val) => formatDateTime(val) as string, |
| | | }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getPurchasePlan(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- éè´è®¡ååºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">éè´è®¡ååºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | <!-- éè´è®¡åæç» --> |
| | | <div |
| | | v-if="formData?.items && formData.items.length > 0" |
| | | class="rounded-lg border border-border bg-background p-4" |
| | | > |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">éè´è®¡åæç»</span> |
| | | </div> |
| | | <Table |
| | | :columns="itemColumns" |
| | | :data-source="formData.items" |
| | | :pagination="false" |
| | | bordered |
| | | size="small" |
| | | > |
| | | <template #bodyCell="{ column, index }"> |
| | | <template v-if="column.key === 'seq'">{{ index + 1 }}</template> |
| | | </template> |
| | | </Table> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | onClick: handleSubmit.bind(null, row), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['erp:purchase-plan:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·æ¯å®¡æ¹äººãææ¾ç¤ºï¼å
¶ä»äººçä¸å°è¯¥æé® |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['erp:purchase-plan:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç°ï¼ä»
审æ¹äººå¯è§ |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'çæç³è¯·', |
| | | type: 'link', |
| | | auth: ['erp:purchase-plan:generate-request'], |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { ErpPurchaseRequestApi } from '#/api/erp/purchase/request'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import type { TableColumnsType } from 'ant-design-vue'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { |
| | | erpCountInputFormatter, |
| | | erpPriceInputFormatter, |
| | | formatDateTime, |
| | | } from '@vben/utils'; |
| | | |
| | | import { Spin, Table } from 'ant-design-vue'; |
| | | |
| | | import { getPurchaseRequest } from '#/api/erp/purchase/request'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'ErpPurchaseRequestApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<ErpPurchaseRequestApi.PurchaseRequest>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** ç³è¯·æç»å */ |
| | | const itemColumns: TableColumnsType = [ |
| | | { title: 'åºå·', key: 'seq', width: 60, align: 'center' }, |
| | | { title: '产ååç§°', dataIndex: 'productName', width: 160 }, |
| | | { title: 'åä½', dataIndex: 'productUnitName', width: 90 }, |
| | | { |
| | | title: 'æ°é', |
| | | dataIndex: 'count', |
| | | width: 100, |
| | | align: 'right', |
| | | customRender: ({ text }) => erpCountInputFormatter(text) || '-', |
| | | }, |
| | | { |
| | | title: 'åä»·ï¼å
ï¼', |
| | | dataIndex: 'productPrice', |
| | | width: 120, |
| | | align: 'right', |
| | | customRender: ({ text }) => erpPriceInputFormatter(text) || '-', |
| | | }, |
| | | { |
| | | title: 'éæ±æ¥æ', |
| | | dataIndex: 'demandTime', |
| | | width: 160, |
| | | customRender: ({ text }) => (text ? formatDateTime(text) : '-'), |
| | | }, |
| | | { title: '夿³¨', dataIndex: 'remark', width: 140 }, |
| | | ]; |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'ç³è¯·ç¼å·', field: 'no', render: textRender }, |
| | | { label: 'ç³è¯·äºº', field: 'requestUserName', render: textRender }, |
| | | { label: 'ç³è¯·é¨é¨', field: 'requestDeptName', render: textRender }, |
| | | { |
| | | label: 'ç³è¯·æ¶é´', |
| | | field: 'requestTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { |
| | | label: 'ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.ERP_AUDIT_STATUS, value: val }), |
| | | }, |
| | | { label: 'ä¾åºå', field: 'supplierName', render: textRender }, |
| | | { |
| | | label: 'æ»æ°é', |
| | | field: 'totalCount', |
| | | render: (val) => erpCountInputFormatter(val) || '-', |
| | | }, |
| | | { |
| | | label: 'æ»éé¢ï¼å
ï¼', |
| | | field: 'totalPrice', |
| | | render: (val) => erpPriceInputFormatter(val) || '-', |
| | | }, |
| | | { label: 'ç³è¯·çç±', field: 'requestReason', render: textRender }, |
| | | { label: '产ååç§°', field: 'productNames', render: textRender }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { |
| | | label: 'å®¡æ ¸æ¶é´', |
| | | field: 'reviewTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { |
| | | label: 'çæéè´è®¢å', |
| | | field: 'orderNo', |
| | | render: (val) => (val ? String(val) : '-'), |
| | | }, |
| | | { |
| | | label: 'å建æ¶é´', |
| | | field: 'createTime', |
| | | render: (val) => formatDateTime(val) as string, |
| | | }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getPurchaseRequest(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- éè´ç³è¯·åºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">éè´ç³è¯·åºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | <!-- éè´ç³è¯·æç» --> |
| | | <div |
| | | v-if="formData?.items && formData.items.length > 0" |
| | | class="rounded-lg border border-border bg-background p-4" |
| | | > |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">éè´ç³è¯·æç»</span> |
| | | </div> |
| | | <Table |
| | | :columns="itemColumns" |
| | | :data-source="formData.items" |
| | | :pagination="false" |
| | | bordered |
| | | size="small" |
| | | > |
| | | <template #bodyCell="{ column, index }"> |
| | | <template v-if="column.key === 'seq'">{{ index + 1 }}</template> |
| | | </template> |
| | | </Table> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | onClick: handleSubmit.bind(null, row), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['erp:purchase-request:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·æ¯å®¡æ¹äººãææ¾ç¤ºï¼å
¶ä»äººçä¸å°è¯¥æé® |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['erp:purchase-request:audit'], |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'çæè®¢å', |
| | | type: 'link', |
| | | auth: ['erp:purchase-request:generate-order'], |
| | |
| | | // è稿(0) ä¸ å®¡æ ¸ä¸éè¿(30) åå¯æäº¤ï¼åè
éä¿®æ¹åéæ°æäº¤ |
| | | ifShow: row.status === 0 || row.status === 30, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['hrm:attendance-exception:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['hrm:attendance-exception:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | |
| | | ifShow: row.status === 0 || row.status === 30, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['hrm:leave:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['hrm:leave:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'æ¤é', |
| | | type: 'link', |
| | | auth: ['hrm:leave:cancel'], |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { HrmPerformanceAppraiseApi } from '#/api/hrm/performance-appraise'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getAppraise } from '#/api/hrm/performance-appraise'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'HrmPerformanceAppraiseApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<HrmPerformanceAppraiseApi.Appraise>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'æ¹æ¡åç§°', field: 'name', render: textRender }, |
| | | { |
| | | label: 'èæ ¸å¨æç±»å', |
| | | field: 'periodType', |
| | | render: (val) => |
| | | h(DictTag, { |
| | | type: DICT_TYPE.HRM_PERFORMANCE_PERIOD_TYPE, |
| | | value: val, |
| | | }), |
| | | }, |
| | | { label: 'èæ ¸å¨æ', field: 'period', render: textRender }, |
| | | { |
| | | label: 'èæ ¸èå´', |
| | | field: 'scopeType', |
| | | render: (val) => |
| | | h(DictTag, { |
| | | type: DICT_TYPE.HRM_PERFORMANCE_SCOPE_TYPE, |
| | | value: val, |
| | | }), |
| | | }, |
| | | { label: 'æ¹æ¡ç¶æ', field: 'statusName', render: textRender }, |
| | | { label: '审æ¹ç¶æ', field: 'auditStatusName', render: textRender }, |
| | | { label: 'ææ æ°', field: 'itemCount', render: textRender }, |
| | | { label: 'å·²è¯å人æ°', field: 'resultCount', render: textRender }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { |
| | | label: 'å®¡æ ¸æ¶é´', |
| | | field: 'reviewTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { |
| | | label: 'å建æ¶é´', |
| | | field: 'createTime', |
| | | render: (val) => formatDateTime(val) as string, |
| | | }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getAppraise(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- 绩æèæ ¸æ¹æ¡åºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">绩æèæ ¸æ¹æ¡åºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | ifShow: row.auditStatus === AUDIT_STATUS.DRAFT || row.auditStatus === AUDIT_STATUS.REJECT, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['hrm:performance-appraise:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['hrm:performance-appraise:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: $t('common.delete'), |
| | | type: 'link', |
| | | danger: true, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { HrmRegularizeApi } from '#/api/hrm/regularize'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getRegularize } from '#/api/hrm/regularize'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'HrmRegularizeApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<HrmRegularizeApi.Regularize>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'ç³è¯·åå·', field: 'no', render: textRender }, |
| | | { label: 'ç³è¯·äºº', field: 'userName', render: textRender }, |
| | | { label: 'é¨é¨', field: 'deptName', render: textRender }, |
| | | { label: 'å²ä½', field: 'postName', render: textRender }, |
| | | { label: 'å½åç¨å·¥æ§è´¨', field: 'employmentTypeName', render: textRender }, |
| | | { |
| | | label: 'æè½¬æ£æ¥æ', |
| | | field: 'expectedDate', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: '转æ£åå ', field: 'reason', render: textRender }, |
| | | { label: '审æ¹ç¶æ', field: 'statusName', render: textRender }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { |
| | | label: 'å®¡æ ¸æ¶é´', |
| | | field: 'reviewTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { |
| | | label: '审æ¹å®ææ¶é´', |
| | | field: 'approveTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { |
| | | label: 'å建æ¶é´', |
| | | field: 'createTime', |
| | | render: (val) => formatDateTime(val) as string, |
| | | }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getRegularize(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- 转æ£ç³è¯·åºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">转æ£ç³è¯·åºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | ifShow: row.status === 0 || row.status === 30, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['hrm:resignation:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['hrm:resignation:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'æ¤é', |
| | | type: 'link', |
| | | auth: ['hrm:resignation:cancel'], |
| | |
| | | ifShow: row.status === 0 || row.status === 30, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['hrm:transfer:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['hrm:transfer:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'æ¤é', |
| | | type: 'link', |
| | | auth: ['hrm:transfer:cancel'], |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesPdProjectApi } from '#/api/mes/pd/project'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getPdProject } from '#/api/mes/pd/project'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'MesPdProjectApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<MesPdProjectApi.Project>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** æ¶é´å段空å¼å ä½ */ |
| | | function timeRender(val: unknown) { |
| | | return val ? (formatDateTime(val as number) as string) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'ä»»å¡ç¼ç ', field: 'taskCode', render: textRender }, |
| | | { label: 'ä»»å¡åç§°', field: 'taskName', render: textRender }, |
| | | { label: '产åç¼ç ', field: 'productCode', render: textRender }, |
| | | { label: '产ååç§°', field: 'productName', render: textRender }, |
| | | { label: 'çæ¬å·', field: 'version', render: textRender }, |
| | | { |
| | | label: 'ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.MES_PD_PROJECT_STATUS, value: val }), |
| | | }, |
| | | { label: '主设计å¸', field: 'chiefDesignerNickname', render: textRender }, |
| | | { label: '计å宿æ¶é´', field: 'planFinishTime', render: timeRender }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { label: 'å®¡æ ¸æ¶é´', field: 'reviewTime', render: timeRender }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { label: 'å建æ¶é´', field: 'createTime', render: timeRender }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getPdProject(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- 设计项ç®åºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">设计项ç®åºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'primary', |
| | | icon: ACTION_ICON.AUDIT, |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®çå®¡æ ¸äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit, |
| | | onClick: () => handleAudit(true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'default', |
| | | danger: true, |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit, |
| | | onClick: () => handleAudit(false), |
| | | }, |
| | | { |
| | | label: '彿¡£', |
| | | type: 'default', |
| | | ifShow: isPendingArchive, |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['mes:pd-project:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®çå®¡æ ¸äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['mes:pd-project:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: '彿¡£', |
| | | type: 'link', |
| | | auth: ['mes:pd-project:archive'], |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesPdTechConfirmApi } from '#/api/mes/pd/tech-confirm'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getTechConfirm } from '#/api/mes/pd/tech-confirm'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'MesPdTechConfirmApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<MesPdTechConfirmApi.TechConfirm>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: '确认å½ç¼å·', field: 'confirmNo', render: textRender }, |
| | | { label: '客æ·åç§°', field: 'customerName', render: textRender }, |
| | | { label: '产ååç§°', field: 'productName', render: textRender }, |
| | | { label: 'è§æ ¼åå·', field: 'specification', render: textRender }, |
| | | { |
| | | label: '模æ¿ç±»å', |
| | | field: 'templateType', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.PRODUCT_TECH_CONFIRM_TEMPLATE, value: val }), |
| | | }, |
| | | { |
| | | label: 'ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.PRODUCT_TECH_CONFIRM_STATUS, value: val }), |
| | | }, |
| | | { label: 'ç¼å¶äºº', field: 'drafterName', render: textRender }, |
| | | { |
| | | label: 'ç¼å¶æ¶é´', |
| | | field: 'draftTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { |
| | | label: 'å®¡æ ¸æ¶é´', |
| | | field: 'reviewTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { label: '客æ·ç¡®è®¤äºº', field: 'customerConfirmUser', render: textRender }, |
| | | { |
| | | label: '客æ·ç¡®è®¤æ¶é´', |
| | | field: 'customerConfirmTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { |
| | | label: 'å建æ¶é´', |
| | | field: 'createTime', |
| | | render: (val) => (val ? (formatDateTime(val) as string) : '-'), |
| | | }, |
| | | { |
| | | label: 'ææ¯åæ°', |
| | | field: 'techParams', |
| | | render: textRender, |
| | | }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getTechConfirm(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- ææ¯ç¡®è®¤å½åºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">ææ¯ç¡®è®¤å½åºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['mes:pd-tech-confirm:audit'], |
| | | // ä»
ãå¾
å®¡æ ¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®çå®¡æ ¸äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['mes:pd-tech-confirm:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: '客æ·ç¡®è®¤', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesWmEquipmentReceiptApi } from '#/api/mes/wm/equipmentreceipt'; |
| | | import type { MesWmEquipmentReceiptLineApi } from '#/api/mes/wm/equipmentreceipt/line'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import type { TableColumnsType } from 'ant-design-vue'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { erpCountInputFormatter, formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin, Table, Tag } from 'ant-design-vue'; |
| | | |
| | | import { getEquipmentReceipt } from '#/api/mes/wm/equipmentreceipt'; |
| | | import { getEquipmentReceiptLineListByReceiptId } from '#/api/mes/wm/equipmentreceipt/line'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | import { EQUIPMENT_RECEIPT_STATUS_MAP } from '../../data'; |
| | | |
| | | defineOptions({ name: 'MesWmEquipmentReceiptApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<MesWmEquipmentReceiptApi.EquipmentReceipt>(); |
| | | const lines = ref<MesWmEquipmentReceiptLineApi.EquipmentReceiptLine[]>([]); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** æ¶é´å段空å¼å ä½ */ |
| | | function timeRender(val: unknown) { |
| | | return val ? (formatDateTime(val as number) as string) : '-'; |
| | | } |
| | | |
| | | /** æç»å */ |
| | | const lineColumns: TableColumnsType = [ |
| | | { title: 'åºå·', key: 'seq', width: 60, align: 'center' }, |
| | | { title: '设å¤ç¼ç ', dataIndex: 'machineryCode', width: 140 }, |
| | | { title: '设å¤åç§°', dataIndex: 'machineryName', width: 160 }, |
| | | { title: 'ç©æç¼ç ', dataIndex: 'itemCode', width: 120 }, |
| | | { title: 'è§æ ¼åå·', dataIndex: 'specification', width: 140 }, |
| | | { title: '计éåä½', dataIndex: 'unitMeasureName', width: 90 }, |
| | | { |
| | | title: 'å
¥åºæ°é', |
| | | dataIndex: 'quantity', |
| | | width: 110, |
| | | align: 'right', |
| | | customRender: ({ text }) => erpCountInputFormatter(text) || '-', |
| | | }, |
| | | { title: '夿³¨', dataIndex: 'remark', width: 140 }, |
| | | ]; |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'åæ®ç¼ç ', field: 'code', render: textRender }, |
| | | { label: 'åæ®åç§°', field: 'name', render: textRender }, |
| | | { label: 'å
¥åºæ¥æ', field: 'receiptDate', render: timeRender }, |
| | | { label: 'å
¥åºæ¥æº', field: 'source', render: textRender }, |
| | | { |
| | | label: 'åæ®ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h( |
| | | Tag, |
| | | { color: EQUIPMENT_RECEIPT_STATUS_MAP[val as number]?.color }, |
| | | () => |
| | | EQUIPMENT_RECEIPT_STATUS_MAP[val as number]?.text ?? String(val), |
| | | ), |
| | | }, |
| | | { label: 'å®¡æ ¸äºº', field: 'reviewerName', render: textRender }, |
| | | { label: 'å®¡æ ¸æ¶é´', field: 'reviewTime', render: timeRender }, |
| | | { label: 'å®¡æ ¸æè§', field: 'reviewRemark', render: textRender }, |
| | | { label: 'å建æ¶é´', field: 'createTime', render: timeRender }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | const id = Number(props.id); |
| | | formData.value = await getEquipmentReceipt(id); |
| | | lines.value = await getEquipmentReceiptLineListByReceiptId(id); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- 设å¤å
¥åºåºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">设å¤å
¥åºåºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | <!-- 设å¤å
¥åºæç» --> |
| | | <div |
| | | v-if="lines.length > 0" |
| | | class="rounded-lg border border-border bg-background p-4" |
| | | > |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">设å¤å
¥åºæç»</span> |
| | | </div> |
| | | <Table |
| | | :columns="lineColumns" |
| | | :data-source="lines" |
| | | :pagination="false" |
| | | bordered |
| | | size="small" |
| | | > |
| | | <template #bodyCell="{ column, index }"> |
| | | <template v-if="column.key === 'seq'">{{ index + 1 }}</template> |
| | | </template> |
| | | </Table> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['mes:wm:equipment-receipt:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®çå®¡æ ¸äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['mes:wm:equipment-receipt:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'æ§è¡å
¥åº', |
| | | type: 'link', |
| | | auth: ['mes:wm:equipment-receipt:finish'], |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { WlsItemReceiptApi } from '#/api/wls/itemreceipt'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getItemReceipt } from '#/api/wls/itemreceipt'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'WlsItemReceiptApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<WlsItemReceiptApi.ItemReceipt>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** æ¶é´å段空å¼å ä½ */ |
| | | function timeRender(val: unknown) { |
| | | return val ? (formatDateTime(val as number) as string) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'å
¥åºåç¼ç ', field: 'code', render: textRender }, |
| | | { label: 'å
¥åºååç§°', field: 'name', render: textRender }, |
| | | { |
| | | label: 'åæ®ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.MES_WM_ITEM_RECEIPT_STATUS, value: val }), |
| | | }, |
| | | { label: 'å
¥åºæ¥æ', field: 'receiptDate', render: timeRender }, |
| | | { label: 'éè´è®¢åå·', field: 'purchaseOrderCode', render: textRender }, |
| | | { label: 'ä¾åºå', field: 'vendorName', render: textRender }, |
| | | { label: 'ä»åº', field: 'warehouseName', render: textRender }, |
| | | { label: 'åºåº', field: 'locationName', render: textRender }, |
| | | { label: 'åºä½', field: 'areaName', render: textRender }, |
| | | { label: 'å°è´§éç¥å', field: 'noticeCode', render: textRender }, |
| | | { label: 'æ¥ææ£éªå', field: 'iqcCode', render: textRender }, |
| | | { label: 'å建æ¶é´', field: 'createTime', render: timeRender }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getItemReceipt(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- éè´å
¥åºåºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">éè´å
¥åºåºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | onClick: handleStock.bind(null, row), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['mes:wm-item-receipt:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®çå®¡æ ¸äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['mes:wm-item-receipt:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'æ§è¡å
¥åº', |
| | | type: 'link', |
| | | auth: ['mes:wm-item-receipt:finish'], |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { WlsMiscIssueApi } from '#/api/wls/miscissue'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getMiscIssue } from '#/api/wls/miscissue'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'WlsMiscIssueApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<WlsMiscIssueApi.MiscIssue>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** æ¶é´å段空å¼å ä½ */ |
| | | function timeRender(val: unknown) { |
| | | return val ? (formatDateTime(val as number) as string) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'åºåºåç¼å·', field: 'code', render: textRender }, |
| | | { label: 'åºåºååç§°', field: 'name', render: textRender }, |
| | | { |
| | | label: 'ä¸å¡ç±»å', |
| | | field: 'type', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.MES_WM_MISC_ISSUE_TYPE, value: val }), |
| | | }, |
| | | { |
| | | label: 'åæ®ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.MES_WM_MISC_ISSUE_STATUS, value: val }), |
| | | }, |
| | | { label: 'åºåºæ¥æ', field: 'issueDate', render: timeRender }, |
| | | { label: 'æ¥æºåæ®ç±»å', field: 'sourceDocType', render: textRender }, |
| | | { label: 'æ¥æºåæ®ç¼ç ', field: 'sourceDocCode', render: textRender }, |
| | | { label: 'å建æ¶é´', field: 'createTime', render: timeRender }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getMiscIssue(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- æé¡¹åºåºåºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">æé¡¹åºåºåºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['mes:wm-misc-issue:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®çå®¡æ ¸äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['mes:wm-misc-issue:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'æ§è¡åºåº', |
| | | type: 'link', |
| | | auth: ['mes:wm-misc-issue:finish'], |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { WlsMiscReceiptApi } from '#/api/wls/miscreceipt'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getMiscReceipt } from '#/api/wls/miscreceipt'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'WlsMiscReceiptApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<WlsMiscReceiptApi.MiscReceipt>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** æ¶é´å段空å¼å ä½ */ |
| | | function timeRender(val: unknown) { |
| | | return val ? (formatDateTime(val as number) as string) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'å
¥åºåç¼å·', field: 'code', render: textRender }, |
| | | { label: 'å
¥åºååç§°', field: 'name', render: textRender }, |
| | | { |
| | | label: 'æé¡¹ç±»å', |
| | | field: 'type', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.MES_WM_MISC_RECEIPT_TYPE, value: val }), |
| | | }, |
| | | { |
| | | label: 'åæ®ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.MES_WM_MISC_RECEIPT_STATUS, value: val }), |
| | | }, |
| | | { label: 'å
¥åºæ¥æ', field: 'receiptDate', render: timeRender }, |
| | | { label: 'æ¥æºåæ®ç±»å', field: 'sourceDocType', render: textRender }, |
| | | { label: 'æ¥æºåæ®ç¼ç ', field: 'sourceDocCode', render: textRender }, |
| | | { label: 'å建æ¶é´', field: 'createTime', render: timeRender }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getMiscReceipt(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- æé¡¹å
¥åºåºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">æé¡¹å
¥åºåºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['mes:wm:misc-receipt:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®çå®¡æ ¸äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['mes:wm:misc-receipt:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'æ§è¡å
¥åº', |
| | | type: 'link', |
| | | auth: ['mes:wm-misc-receipt:finish'], |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { WlsReturnVendorApi } from '#/api/wls/returnvendor'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getReturnVendor } from '#/api/wls/returnvendor'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'WlsReturnVendorApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<WlsReturnVendorApi.ReturnVendor>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** æ¶é´å段空å¼å ä½ */ |
| | | function timeRender(val: unknown) { |
| | | return val ? (formatDateTime(val as number) as string) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'éè´§åç¼å·', field: 'code', render: textRender }, |
| | | { label: 'éè´§ååç§°', field: 'name', render: textRender }, |
| | | { |
| | | label: 'åæ®ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.MES_WM_RETURN_VENDOR_STATUS, value: val }), |
| | | }, |
| | | { label: 'éè´è®¢åå·', field: 'purchaseOrderCode', render: textRender }, |
| | | { label: 'ä¾åºåç¼ç ', field: 'vendorCode', render: textRender }, |
| | | { label: 'ä¾åºååç§°', field: 'vendorName', render: textRender }, |
| | | { label: 'éè´§æ¥æ', field: 'returnDate', render: timeRender }, |
| | | { label: 'éè´§åå ', field: 'returnReason', render: textRender }, |
| | | { label: 'è¿åå·', field: 'transportCode', render: textRender }, |
| | | { label: 'èç³»çµè¯', field: 'transportTelephone', render: textRender }, |
| | | { label: 'å建æ¶é´', field: 'createTime', render: timeRender }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getReturnVendor(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- ä¾åºåéè´§åºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">ä¾åºåéè´§åºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['mes:wm-return-vendor:audit'], |
| | | // ä»
ãå¾
æ£è´§ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®çå®¡æ ¸äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['mes:wm-return-vendor:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: $t('common.edit'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { WlsStockTakingTaskApi } from '#/api/wls/stocktaking/task'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { h, onMounted, ref } from 'vue'; |
| | | |
| | | import { ContentWrap } from '@vben/common-ui'; |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { formatDateTime } from '@vben/utils'; |
| | | |
| | | import { Spin } from 'ant-design-vue'; |
| | | |
| | | import { getStockTaking } from '#/api/wls/stocktaking/task'; |
| | | import { DictTag } from '#/components/dict-tag'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | defineOptions({ name: 'WlsStockTakingTaskApproveDetail' }); |
| | | |
| | | const props = defineProps<{ id: string }>(); |
| | | |
| | | const loading = ref(false); |
| | | const formData = ref<WlsStockTakingTaskApi.StockTakingTask>(); |
| | | |
| | | /** ææ¬åæ®µç©ºå¼å ä½ */ |
| | | function textRender(val: unknown) { |
| | | return val === 0 || val ? String(val) : '-'; |
| | | } |
| | | |
| | | /** æ¶é´å段空å¼å ä½ */ |
| | | function timeRender(val: unknown) { |
| | | return val ? (formatDateTime(val as number) as string) : '-'; |
| | | } |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | bordered: true, |
| | | column: 2, |
| | | schema: [ |
| | | { label: 'ä»»å¡ç¼ç ', field: 'code', render: textRender }, |
| | | { label: 'ä»»å¡åç§°', field: 'name', render: textRender }, |
| | | { |
| | | label: 'çç¹ç±»å', |
| | | field: 'type', |
| | | render: (val) => |
| | | h(DictTag, { type: DICT_TYPE.MES_WM_STOCK_TAKING_TYPE, value: val }), |
| | | }, |
| | | { |
| | | label: 'åæ®ç¶æ', |
| | | field: 'status', |
| | | render: (val) => |
| | | h(DictTag, { |
| | | type: DICT_TYPE.MES_WM_STOCK_TAKING_TASK_STATUS, |
| | | value: val, |
| | | }), |
| | | }, |
| | | { |
| | | label: 'çç¹æ¥æ', |
| | | field: 'takingDate', |
| | | render: (val) => (val ? (formatDateTime(val as string) as string) : '-'), |
| | | }, |
| | | { label: 'çç¹äºº', field: 'userNickname', render: textRender }, |
| | | { label: 'çç¹æ¹æ¡ç¼ç ', field: 'planCode', render: textRender }, |
| | | { label: 'çç¹æ¹æ¡åç§°', field: 'planName', render: textRender }, |
| | | { |
| | | label: 'æ¯å¦ç²ç', |
| | | field: 'blindFlag', |
| | | render: (val) => (val ? 'æ¯' : 'å¦'), |
| | | }, |
| | | { |
| | | label: 'æ¯å¦å»ç»åºå', |
| | | field: 'frozen', |
| | | render: (val) => (val ? 'æ¯' : 'å¦'), |
| | | }, |
| | | { label: 'å¼å§æ¶é´', field: 'startTime', render: timeRender }, |
| | | { label: 'ç»ææ¶é´', field: 'endTime', render: timeRender }, |
| | | { |
| | | label: 'å建æ¶é´', |
| | | field: 'createTime', |
| | | render: (val) => (val ? (formatDateTime(val as string) as string) : '-'), |
| | | }, |
| | | { label: '夿³¨', field: 'remark', render: textRender }, |
| | | ] as DescriptionItemSchema[], |
| | | }); |
| | | |
| | | onMounted(async () => { |
| | | try { |
| | | loading.value = true; |
| | | formData.value = await getStockTaking(Number(props.id)); |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <ContentWrap class="m-2"> |
| | | <Spin :spinning="loading" tip="å è½½ä¸..."> |
| | | <div class="space-y-4"> |
| | | <!-- çç¹ä»»å¡åºæ¬ä¿¡æ¯ --> |
| | | <div class="rounded-lg border border-border bg-background p-4"> |
| | | <div class="mb-4 flex items-center gap-2"> |
| | | <span class="inline-block h-4 w-1 rounded bg-primary" /> |
| | | <span class="text-base font-semibold">çç¹ä»»å¡åºæ¬ä¿¡æ¯</span> |
| | | </div> |
| | | <Descriptions :data="formData" /> |
| | | </div> |
| | | </div> |
| | | </Spin> |
| | | </ContentWrap> |
| | | </template> |
| | |
| | | }, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['mes:wm-stock-taking-task:audit'], |
| | | // ä»
ãç»æå®¡æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®çå®¡æ ¸äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['mes:wm-stock-taking-task:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: 'åæ¶', |
| | | type: 'link', |
| | | danger: true, |