feat: 原材料盘点表
This commit is contained in:
parent
6a68e724df
commit
2af6a94072
|
@ -1412,6 +1412,8 @@ declare namespace API {
|
|||
agent: string;
|
||||
/** 领料单号 */
|
||||
issuanceNumber?: number;
|
||||
/** 项目 */
|
||||
project: string;
|
||||
/** 备注 */
|
||||
remark: string;
|
||||
/** 附件 */
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export enum DictEnum {
|
||||
ContractType = 'contract_type',
|
||||
ContractType = 'contract_type', // 合同类型
|
||||
Unit = 'unit', // 单位
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@ import Api from '@/api';
|
|||
import { store } from '@/store';
|
||||
import { DictEnum } from '@/enums/dictEnum';
|
||||
const needCachedKey = [
|
||||
DictEnum.ContractType, // 合同类型
|
||||
DictEnum.ContractType,
|
||||
DictEnum.Unit
|
||||
];
|
||||
|
||||
export const useDictStore = defineStore('dict', () => {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
import { Button } from 'ant-design-vue';
|
||||
import AttachmentManage from '@/components/business/attachment-manage/index.vue';
|
||||
import AttachmentUpload from '@/components/business/attachment-upload/index.vue';
|
||||
import { ref, onMounted, type FunctionalComponent } from 'vue';
|
||||
import { ref, onMounted, type FunctionalComponent } from 'vue';
|
||||
defineOptions({
|
||||
name: 'Contract',
|
||||
});
|
||||
|
@ -96,7 +96,7 @@ import { ref, onMounted, type FunctionalComponent } from 'vue';
|
|||
];
|
||||
});
|
||||
|
||||
const openAttachmentUploadModal = async (record: API.ContractEntity) => {
|
||||
const openAttachmentUploadModal = async (record: TableListItem) => {
|
||||
isUploadPopupVisiable.value = true;
|
||||
fnModal.show({
|
||||
width: 800,
|
||||
|
@ -169,7 +169,7 @@ import { ref, onMounted, type FunctionalComponent } from 'vue';
|
|||
dynamicTableInstance?.reload();
|
||||
};
|
||||
|
||||
const FilesRender: FunctionalComponent<TableListItem> = (contract: API.ContractEntity) => {
|
||||
const FilesRender: FunctionalComponent<TableListItem> = (contract: TableListItem) => {
|
||||
const [fnModal] = useModal();
|
||||
return (
|
||||
<Button
|
||||
|
@ -183,7 +183,7 @@ import { ref, onMounted, type FunctionalComponent } from 'vue';
|
|||
);
|
||||
};
|
||||
|
||||
const openFilesManageModal = (fnModal, contract: API.ContractEntity) => {
|
||||
const openFilesManageModal = (fnModal, contract: TableListItem) => {
|
||||
const fileIds = contract.files?.map((item) => item.id) || [];
|
||||
fnModal.show({
|
||||
width: 1200,
|
||||
|
|
|
@ -1,97 +1,167 @@
|
|||
import type { TableColumn } from '@/components/core/dynamic-table';
|
||||
import { ContractStatusEnum } from '@/enums/contractEnum';
|
||||
import { DictEnum } from '@/enums/dictEnum';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { formatToDate } from '@/utils/dateUtil';
|
||||
import { Tag, Button } from 'ant-design-vue';
|
||||
import { Tag } from 'ant-design-vue';
|
||||
|
||||
export type TableListItem = API.ContractEntity;
|
||||
export type TableListItem = API.MaterialsInventoryEntity;
|
||||
export type TableColumnItem = TableColumn<TableListItem>;
|
||||
const dictStore = useDictStore();
|
||||
export const baseColumns: TableColumnItem[] = [
|
||||
{
|
||||
title: '公司名称',
|
||||
width: 120,
|
||||
dataIndex: 'companyName',
|
||||
},
|
||||
{
|
||||
title: '产品名称',
|
||||
width: 180,
|
||||
dataIndex: 'product',
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
width: 60,
|
||||
hideInSearch: true,
|
||||
dataIndex: 'unit',
|
||||
formItemProps: {
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: dictStore
|
||||
.getDictItemsByCode(DictEnum.Unit)
|
||||
.map(({ label, id }) => ({ value: id, label })),
|
||||
},
|
||||
},
|
||||
customRender: ({ record }) => {
|
||||
return dictStore.getDictItemsByCode(DictEnum.Unit)?.length
|
||||
? dictStore.getDictItemsByCode(DictEnum.Unit).find((item) => item.id === record.unit)
|
||||
?.label || ''
|
||||
: '';
|
||||
},
|
||||
},
|
||||
|
||||
export const baseColumns = (ctx: {
|
||||
contractTypes: API.DictItemEntity[];
|
||||
dynamicTableInstance;
|
||||
}): TableColumnItem[] => {
|
||||
const { contractTypes } = ctx;
|
||||
return [
|
||||
{
|
||||
title: '编号',
|
||||
width: 100,
|
||||
maxWidth: 100,
|
||||
fixed: 'left',
|
||||
dataIndex: 'contractNumber',
|
||||
},
|
||||
{
|
||||
title: '标题',
|
||||
width: 180,
|
||||
dataIndex: 'title',
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
width: 80,
|
||||
formItemProps: {
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: contractTypes.map(({ label, id }) => ({ value: id, label })),
|
||||
{
|
||||
title: '库存数量',
|
||||
hideInSearch: true,
|
||||
width: 80,
|
||||
dataIndex: 'previousInventoryQuantity',
|
||||
},
|
||||
{
|
||||
title: '单价',
|
||||
hideInSearch: true,
|
||||
width: 80,
|
||||
dataIndex: 'previousUnitPrice',
|
||||
},
|
||||
{
|
||||
title: '金额',
|
||||
hideInSearch: true,
|
||||
width: 80,
|
||||
dataIndex: 'previousAmount',
|
||||
},
|
||||
{
|
||||
title: '入库',
|
||||
children: [
|
||||
{
|
||||
title: '入库时间',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
dataIndex: 'inventoryTime',
|
||||
customRender: ({ record }) => {
|
||||
return formatToDate(record.inventoryTime);
|
||||
},
|
||||
},
|
||||
dataIndex: 'type',
|
||||
customRender: ({ record }) => {
|
||||
return contractTypes?.length
|
||||
? contractTypes.find((item) => item.id === record.type)?.label || ''
|
||||
: '';
|
||||
{
|
||||
title: '数量',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
dataIndex: 'inventoryQuantity',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '甲方',
|
||||
width: 120,
|
||||
dataIndex: 'partyA',
|
||||
},
|
||||
{
|
||||
title: '乙方',
|
||||
width: 120,
|
||||
dataIndex: 'partyB',
|
||||
},
|
||||
{
|
||||
title: '签订时间',
|
||||
width: 60,
|
||||
maxWidth: 60,
|
||||
hideInSearch: true,
|
||||
dataIndex: 'signingDate',
|
||||
customRender: ({ record }) => {
|
||||
return formatToDate(record.signingDate);
|
||||
{
|
||||
title: '单价',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
dataIndex: 'inventoryUnitPrice',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '交付期限',
|
||||
width: 60,
|
||||
maxWidth: 60,
|
||||
hideInSearch: true,
|
||||
dataIndex: 'deliveryDeadline',
|
||||
customRender: ({ record }) => {
|
||||
return formatToDate(record.deliveryDeadline);
|
||||
{
|
||||
title: '金额',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
dataIndex: 'inventoryAmount',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '审核结果',
|
||||
dataIndex: 'status',
|
||||
maxWidth: 60,
|
||||
width: 60,
|
||||
fixed:'right',
|
||||
formItemProps: {
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: Object.values(ContractStatusEnum)
|
||||
.filter((value) => typeof value === 'number')
|
||||
.map((item) => formatStatus(item as ContractStatusEnum)),
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '出库',
|
||||
children: [
|
||||
{
|
||||
title: '出库时间',
|
||||
width: 120,
|
||||
dataIndex: 'outime',
|
||||
align: 'center',
|
||||
customRender: ({ record }) => {
|
||||
return formatToDate(record.outime);
|
||||
},
|
||||
},
|
||||
customRender: ({ record }) => {
|
||||
const { color, label } = formatStatus(record.status);
|
||||
return <Tag color={color}>{label}</Tag>;
|
||||
{
|
||||
title: '出库数量',
|
||||
width: 80,
|
||||
dataIndex: 'outQuantity',
|
||||
align: 'center',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '出库单价',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
dataIndex: 'outUnitPrice',
|
||||
},
|
||||
{
|
||||
title: '出库金额',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
dataIndex: 'outAmount',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '结存数量',
|
||||
hideInSearch: true,
|
||||
width: 80,
|
||||
dataIndex: 'currentInventoryQuantity',
|
||||
},
|
||||
|
||||
];
|
||||
};
|
||||
{
|
||||
title: '单价',
|
||||
hideInSearch: true,
|
||||
width: 80,
|
||||
dataIndex: 'currentUnitPrice',
|
||||
},
|
||||
{
|
||||
title: '金额',
|
||||
hideInSearch: true,
|
||||
width: 80,
|
||||
dataIndex: 'currentAmount',
|
||||
},
|
||||
{
|
||||
title: '经办人',
|
||||
width: 80,
|
||||
dataIndex: 'agent',
|
||||
},
|
||||
{
|
||||
title: '领料单号',
|
||||
width: 80,
|
||||
dataIndex: 'issuanceNumber',
|
||||
},
|
||||
{
|
||||
title: '项目',
|
||||
width: 80,
|
||||
dataIndex: 'project',
|
||||
},
|
||||
{
|
||||
title: '备注',
|
||||
width: 80,
|
||||
dataIndex: 'remark',
|
||||
},
|
||||
];
|
||||
|
||||
export function formatStatus(status: ContractStatusEnum): {
|
||||
color: string;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<template>
|
||||
test
|
||||
<div v-if="columns?.length">
|
||||
<DynamicTable
|
||||
row-key="id"
|
||||
|
@ -43,91 +42,80 @@
|
|||
const [DynamicTable, dynamicTableInstance] = useTable();
|
||||
const [showModal] = useFormModal();
|
||||
const [fnModal] = useModal();
|
||||
const { getDictItemsByCode } = useDictStore();
|
||||
const contractTypes = ref<API.DictItemEntity[]>([]);
|
||||
|
||||
const getContractTypes = async () => {
|
||||
contractTypes.value = await getDictItemsByCode(DictEnum.ContractType);
|
||||
};
|
||||
const isUploadPopupVisiable = ref(false);
|
||||
|
||||
// contractList;
|
||||
let columns = ref<TableColumnItem[]>();
|
||||
onMounted(() => {
|
||||
getContractTypes().then((res) => {
|
||||
columns.value = [
|
||||
...baseColumns({
|
||||
dynamicTableInstance,
|
||||
contractTypes: contractTypes.value,
|
||||
}),
|
||||
{
|
||||
title: '附件',
|
||||
width: 50,
|
||||
maxWidth: 50,
|
||||
hideInSearch: true,
|
||||
fixed: 'right',
|
||||
dataIndex: 'files',
|
||||
customRender: ({ record }) => <FilesRender {...record} />,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
maxWidth: 80,
|
||||
width: 80,
|
||||
minWidth: 80,
|
||||
dataIndex: 'ACTION',
|
||||
hideInSearch: true,
|
||||
fixed: 'right',
|
||||
actions: ({ record }) => [
|
||||
{
|
||||
icon: 'ant-design:edit-outlined',
|
||||
tooltip: '编辑',
|
||||
auth: {
|
||||
perm: 'app:contract:update',
|
||||
effect: 'disable',
|
||||
},
|
||||
onClick: () => openEditModal(record),
|
||||
columns.value = [
|
||||
...baseColumns,
|
||||
{
|
||||
title: '附件',
|
||||
width: 50,
|
||||
maxWidth: 50,
|
||||
hideInSearch: true,
|
||||
fixed: 'right',
|
||||
dataIndex: 'files',
|
||||
customRender: ({ record }) => <FilesRender {...record} />,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
maxWidth: 80,
|
||||
width: 80,
|
||||
minWidth: 80,
|
||||
dataIndex: 'ACTION',
|
||||
hideInSearch: true,
|
||||
fixed: 'right',
|
||||
actions: ({ record }) => [
|
||||
{
|
||||
icon: 'ant-design:edit-outlined',
|
||||
tooltip: '编辑',
|
||||
auth: {
|
||||
perm: 'app:contract:update',
|
||||
effect: 'disable',
|
||||
},
|
||||
{
|
||||
icon: 'ant-design:delete-outlined',
|
||||
color: 'red',
|
||||
tooltip: '删除此合同',
|
||||
auth: 'app:contract:delete',
|
||||
popConfirm: {
|
||||
title: '你确定要删除吗?',
|
||||
placement: 'left',
|
||||
onConfirm: () => delRowConfirm(record.id),
|
||||
},
|
||||
onClick: () => openEditModal(record),
|
||||
},
|
||||
{
|
||||
icon: 'ant-design:delete-outlined',
|
||||
color: 'red',
|
||||
tooltip: '删除此记录',
|
||||
auth: 'app:contract:delete',
|
||||
popConfirm: {
|
||||
title: '你确定要删除吗?',
|
||||
placement: 'left',
|
||||
onConfirm: () => delRowConfirm(record.id),
|
||||
},
|
||||
{
|
||||
icon: 'ant-design:cloud-upload-outlined',
|
||||
tooltip: '上传附件',
|
||||
onClick: () => openAttachmentUploadModal(record),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
});
|
||||
},
|
||||
{
|
||||
icon: 'ant-design:cloud-upload-outlined',
|
||||
tooltip: '上传附件',
|
||||
onClick: () => openAttachmentUploadModal(record),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const openAttachmentUploadModal = async (record: API.ContractEntity) => {
|
||||
isUploadPopupVisiable.value = true;
|
||||
fnModal.show({
|
||||
width: 800,
|
||||
title: `合同编号: ${record.contractNumber}`,
|
||||
content: () => {
|
||||
return (
|
||||
<AttachmentUpload
|
||||
onClose={handleUploadClose}
|
||||
afterUploadCallback={(files) => {
|
||||
afterUploadCallback(files, record.id);
|
||||
}}
|
||||
></AttachmentUpload>
|
||||
);
|
||||
},
|
||||
destroyOnClose: true,
|
||||
open: isUploadPopupVisiable.value,
|
||||
footer: null,
|
||||
});
|
||||
const openAttachmentUploadModal = async (record: TableListItem) => {
|
||||
// isUploadPopupVisiable.value = true;
|
||||
// fnModal.show({
|
||||
// width: 800,
|
||||
// title: `记录编号: ${record.contractNumber}`,
|
||||
// content: () => {
|
||||
// return (
|
||||
// <AttachmentUpload
|
||||
// onClose={handleUploadClose}
|
||||
// afterUploadCallback={(files) => {
|
||||
// afterUploadCallback(files, record.id);
|
||||
// }}
|
||||
// ></AttachmentUpload>
|
||||
// );
|
||||
// },
|
||||
// destroyOnClose: true,
|
||||
// open: isUploadPopupVisiable.value,
|
||||
// footer: null,
|
||||
// });
|
||||
};
|
||||
const handleUploadClose = (hasSuccess: boolean) => {
|
||||
fnModal.hide();
|
||||
|
@ -145,44 +133,44 @@
|
|||
* @description 打开新增/编辑弹窗
|
||||
*/
|
||||
const openEditModal = async (record: Partial<TableListItem>) => {
|
||||
const [formRef] = await showModal({
|
||||
modalProps: {
|
||||
title: `${record.id ? '编辑' : '新增'}合同`,
|
||||
width: '50%',
|
||||
onFinish: async (values) => {
|
||||
const params = {
|
||||
...values,
|
||||
signingDate: formatToDate(values.signingDate),
|
||||
deliveryDeadline: formatToDate(values.deliveryDeadline),
|
||||
};
|
||||
if (record.id) {
|
||||
await Api.contract.contractUpdate({ id: record.id }, params);
|
||||
} else {
|
||||
await Api.contract.contractCreate(params);
|
||||
}
|
||||
dynamicTableInstance?.reload();
|
||||
},
|
||||
},
|
||||
formProps: {
|
||||
labelWidth: 100,
|
||||
schemas: contractSchemas(contractTypes.value),
|
||||
},
|
||||
});
|
||||
// const [formRef] = await showModal({
|
||||
// modalProps: {
|
||||
// title: `${record.id ? '编辑' : '新增'}盘点记录`,
|
||||
// width: '50%',
|
||||
// onFinish: async (values) => {
|
||||
// const params = {
|
||||
// ...values,
|
||||
// signingDate: formatToDate(values.signingDate),
|
||||
// deliveryDeadline: formatToDate(values.deliveryDeadline),
|
||||
// };
|
||||
// if (record.id) {
|
||||
// await Api.contract.contractUpdate({ id: record.id }, params);
|
||||
// } else {
|
||||
// await Api.contract.contractCreate(params);
|
||||
// }
|
||||
// dynamicTableInstance?.reload();
|
||||
// },
|
||||
// },
|
||||
// formProps: {
|
||||
// labelWidth: 100,
|
||||
// schemas: contractSchemas(contractTypes.value),
|
||||
// },
|
||||
// });
|
||||
|
||||
// 如果是编辑的话,需要获取角色详情
|
||||
if (record.id) {
|
||||
const info = await Api.contract.contractInfo({ id: record.id });
|
||||
formRef?.setFieldsValue({
|
||||
...info,
|
||||
});
|
||||
}
|
||||
// // 如果是编辑的话,需要获取角色详情
|
||||
// if (record.id) {
|
||||
// const info = await Api.contract.contractInfo({ id: record.id });
|
||||
// formRef?.setFieldsValue({
|
||||
// ...info,
|
||||
// });
|
||||
// }
|
||||
};
|
||||
const delRowConfirm = async (record) => {
|
||||
await Api.contract.contractDelete({ id: record });
|
||||
dynamicTableInstance?.reload();
|
||||
};
|
||||
|
||||
const FilesRender: FunctionalComponent<TableListItem> = (contract: API.ContractEntity) => {
|
||||
const FilesRender: FunctionalComponent<TableListItem> = (contract: TableListItem) => {
|
||||
const [fnModal] = useModal();
|
||||
return (
|
||||
<Button
|
||||
|
@ -196,22 +184,22 @@
|
|||
);
|
||||
};
|
||||
|
||||
const openFilesManageModal = (fnModal, contract: API.ContractEntity) => {
|
||||
const fileIds = contract.files?.map((item) => item.id) || [];
|
||||
fnModal.show({
|
||||
width: 1200,
|
||||
title: `附件管理`,
|
||||
content: () => {
|
||||
return (
|
||||
<AttachmentManage
|
||||
fileIds={fileIds}
|
||||
onDelete={(unlinkIds) => unlinkAttachments(contract.id, unlinkIds)}
|
||||
></AttachmentManage>
|
||||
);
|
||||
},
|
||||
destroyOnClose: true,
|
||||
footer: null,
|
||||
});
|
||||
const openFilesManageModal = (fnModal, contract: TableListItem) => {
|
||||
// const fileIds = contract.files?.map((item) => item.id) || [];
|
||||
// fnModal.show({
|
||||
// width: 1200,
|
||||
// title: `附件管理`,
|
||||
// content: () => {
|
||||
// return (
|
||||
// <AttachmentManage
|
||||
// fileIds={fileIds}
|
||||
// onDelete={(unlinkIds) => unlinkAttachments(contract.id, unlinkIds)}
|
||||
// ></AttachmentManage>
|
||||
// );
|
||||
// },
|
||||
// destroyOnClose: true,
|
||||
// footer: null,
|
||||
// });
|
||||
};
|
||||
const unlinkAttachments = async (id: number, unlinkIds: number[]) => {
|
||||
await Api.contract.unlinkAttachments({ id }, { fileIds: unlinkIds });
|
||||
|
|
Loading…
Reference in New Issue