feat: 原材料盘点表

This commit is contained in:
louis 2024-03-04 14:17:40 +08:00
parent 6a68e724df
commit 2af6a94072
6 changed files with 272 additions and 210 deletions

View File

@ -1412,6 +1412,8 @@ declare namespace API {
agent: string; agent: string;
/** 领料单号 */ /** 领料单号 */
issuanceNumber?: number; issuanceNumber?: number;
/** 项目 */
project: string;
/** 备注 */ /** 备注 */
remark: string; remark: string;
/** 附件 */ /** 附件 */

View File

@ -1,3 +1,4 @@
export enum DictEnum { export enum DictEnum {
ContractType = 'contract_type', ContractType = 'contract_type', // 合同类型
Unit = 'unit', // 单位
} }

View File

@ -4,7 +4,8 @@ import Api from '@/api';
import { store } from '@/store'; import { store } from '@/store';
import { DictEnum } from '@/enums/dictEnum'; import { DictEnum } from '@/enums/dictEnum';
const needCachedKey = [ const needCachedKey = [
DictEnum.ContractType, // 合同类型 DictEnum.ContractType,
DictEnum.Unit
]; ];
export const useDictStore = defineStore('dict', () => { export const useDictStore = defineStore('dict', () => {

View File

@ -33,7 +33,7 @@
import { Button } from 'ant-design-vue'; import { Button } from 'ant-design-vue';
import AttachmentManage from '@/components/business/attachment-manage/index.vue'; import AttachmentManage from '@/components/business/attachment-manage/index.vue';
import AttachmentUpload from '@/components/business/attachment-upload/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({ defineOptions({
name: 'Contract', 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; isUploadPopupVisiable.value = true;
fnModal.show({ fnModal.show({
width: 800, width: 800,
@ -169,7 +169,7 @@ import { ref, onMounted, type FunctionalComponent } from 'vue';
dynamicTableInstance?.reload(); dynamicTableInstance?.reload();
}; };
const FilesRender: FunctionalComponent<TableListItem> = (contract: API.ContractEntity) => { const FilesRender: FunctionalComponent<TableListItem> = (contract: TableListItem) => {
const [fnModal] = useModal(); const [fnModal] = useModal();
return ( return (
<Button <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) || []; const fileIds = contract.files?.map((item) => item.id) || [];
fnModal.show({ fnModal.show({
width: 1200, width: 1200,

View File

@ -1,97 +1,167 @@
import type { TableColumn } from '@/components/core/dynamic-table'; import type { TableColumn } from '@/components/core/dynamic-table';
import { ContractStatusEnum } from '@/enums/contractEnum'; import { ContractStatusEnum } from '@/enums/contractEnum';
import { DictEnum } from '@/enums/dictEnum';
import { useDictStore } from '@/store/modules/dict';
import { formatToDate } from '@/utils/dateUtil'; 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>; 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[]; title: '库存数量',
dynamicTableInstance; hideInSearch: true,
}): TableColumnItem[] => { width: 80,
const { contractTypes } = ctx; dataIndex: 'previousInventoryQuantity',
return [ },
{ {
title: '编号', title: '单价',
width: 100, hideInSearch: true,
maxWidth: 100, width: 80,
fixed: 'left', dataIndex: 'previousUnitPrice',
dataIndex: 'contractNumber', },
}, {
{ title: '金额',
title: '标题', hideInSearch: true,
width: 180, width: 80,
dataIndex: 'title', dataIndex: 'previousAmount',
}, },
{ {
title: '类型', title: '入库',
width: 80, children: [
formItemProps: { {
component: 'Select', title: '入库时间',
componentProps: { width: 120,
options: contractTypes.map(({ label, id }) => ({ value: id, label })), align: 'center',
dataIndex: 'inventoryTime',
customRender: ({ record }) => {
return formatToDate(record.inventoryTime);
}, },
}, },
dataIndex: 'type', {
customRender: ({ record }) => { title: '数量',
return contractTypes?.length width: 80,
? contractTypes.find((item) => item.id === record.type)?.label || '' align: 'center',
: ''; dataIndex: 'inventoryQuantity',
}, },
}, {
{ title: '单价',
title: '甲方', width: 80,
width: 120, align: 'center',
dataIndex: 'partyA', dataIndex: 'inventoryUnitPrice',
},
{
title: '乙方',
width: 120,
dataIndex: 'partyB',
},
{
title: '签订时间',
width: 60,
maxWidth: 60,
hideInSearch: true,
dataIndex: 'signingDate',
customRender: ({ record }) => {
return formatToDate(record.signingDate);
}, },
}, {
{ title: '金额',
title: '交付期限', width: 80,
width: 60, align: 'center',
maxWidth: 60, dataIndex: 'inventoryAmount',
hideInSearch: true,
dataIndex: 'deliveryDeadline',
customRender: ({ record }) => {
return formatToDate(record.deliveryDeadline);
}, },
}, ],
{ },
title: '审核结果', {
dataIndex: 'status', title: '出库',
maxWidth: 60, children: [
width: 60, {
fixed:'right', title: '出库时间',
formItemProps: { width: 120,
component: 'Select', dataIndex: 'outime',
componentProps: { align: 'center',
options: Object.values(ContractStatusEnum) customRender: ({ record }) => {
.filter((value) => typeof value === 'number') return formatToDate(record.outime);
.map((item) => formatStatus(item as ContractStatusEnum)),
}, },
}, },
customRender: ({ record }) => { {
const { color, label } = formatStatus(record.status); title: '出库数量',
return <Tag color={color}>{label}</Tag>; 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): { export function formatStatus(status: ContractStatusEnum): {
color: string; color: string;

View File

@ -1,5 +1,4 @@
<template> <template>
test
<div v-if="columns?.length"> <div v-if="columns?.length">
<DynamicTable <DynamicTable
row-key="id" row-key="id"
@ -43,91 +42,80 @@
const [DynamicTable, dynamicTableInstance] = useTable(); const [DynamicTable, dynamicTableInstance] = useTable();
const [showModal] = useFormModal(); const [showModal] = useFormModal();
const [fnModal] = useModal(); const [fnModal] = useModal();
const { getDictItemsByCode } = useDictStore();
const contractTypes = ref<API.DictItemEntity[]>([]);
const getContractTypes = async () => {
contractTypes.value = await getDictItemsByCode(DictEnum.ContractType);
};
const isUploadPopupVisiable = ref(false); const isUploadPopupVisiable = ref(false);
// contractList; // contractList;
let columns = ref<TableColumnItem[]>(); let columns = ref<TableColumnItem[]>();
onMounted(() => { onMounted(() => {
getContractTypes().then((res) => { columns.value = [
columns.value = [ ...baseColumns,
...baseColumns({ {
dynamicTableInstance, title: '附件',
contractTypes: contractTypes.value, width: 50,
}), maxWidth: 50,
{ hideInSearch: true,
title: '附件', fixed: 'right',
width: 50, dataIndex: 'files',
maxWidth: 50, customRender: ({ record }) => <FilesRender {...record} />,
hideInSearch: true, },
fixed: 'right', {
dataIndex: 'files', title: '操作',
customRender: ({ record }) => <FilesRender {...record} />, maxWidth: 80,
}, width: 80,
{ minWidth: 80,
title: '操作', dataIndex: 'ACTION',
maxWidth: 80, hideInSearch: true,
width: 80, fixed: 'right',
minWidth: 80, actions: ({ record }) => [
dataIndex: 'ACTION', {
hideInSearch: true, icon: 'ant-design:edit-outlined',
fixed: 'right', tooltip: '编辑',
actions: ({ record }) => [ auth: {
{ perm: 'app:contract:update',
icon: 'ant-design:edit-outlined', effect: 'disable',
tooltip: '编辑',
auth: {
perm: 'app:contract:update',
effect: 'disable',
},
onClick: () => openEditModal(record),
}, },
{ onClick: () => openEditModal(record),
icon: 'ant-design:delete-outlined', },
color: 'red', {
tooltip: '删除此合同', icon: 'ant-design:delete-outlined',
auth: 'app:contract:delete', color: 'red',
popConfirm: { tooltip: '删除此记录',
title: '你确定要删除吗?', auth: 'app:contract:delete',
placement: 'left', popConfirm: {
onConfirm: () => delRowConfirm(record.id), title: '你确定要删除吗?',
}, placement: 'left',
onConfirm: () => delRowConfirm(record.id),
}, },
{ },
icon: 'ant-design:cloud-upload-outlined', {
tooltip: '上传附件', icon: 'ant-design:cloud-upload-outlined',
onClick: () => openAttachmentUploadModal(record), tooltip: '上传附件',
}, onClick: () => openAttachmentUploadModal(record),
], },
}, ],
]; },
}); ];
}); });
const openAttachmentUploadModal = async (record: API.ContractEntity) => { const openAttachmentUploadModal = async (record: TableListItem) => {
isUploadPopupVisiable.value = true; // isUploadPopupVisiable.value = true;
fnModal.show({ // fnModal.show({
width: 800, // width: 800,
title: `合同编号: ${record.contractNumber}`, // title: `: ${record.contractNumber}`,
content: () => { // content: () => {
return ( // return (
<AttachmentUpload // <AttachmentUpload
onClose={handleUploadClose} // onClose={handleUploadClose}
afterUploadCallback={(files) => { // afterUploadCallback={(files) => {
afterUploadCallback(files, record.id); // afterUploadCallback(files, record.id);
}} // }}
></AttachmentUpload> // ></AttachmentUpload>
); // );
}, // },
destroyOnClose: true, // destroyOnClose: true,
open: isUploadPopupVisiable.value, // open: isUploadPopupVisiable.value,
footer: null, // footer: null,
}); // });
}; };
const handleUploadClose = (hasSuccess: boolean) => { const handleUploadClose = (hasSuccess: boolean) => {
fnModal.hide(); fnModal.hide();
@ -145,44 +133,44 @@
* @description 打开新增/编辑弹窗 * @description 打开新增/编辑弹窗
*/ */
const openEditModal = async (record: Partial<TableListItem>) => { const openEditModal = async (record: Partial<TableListItem>) => {
const [formRef] = await showModal({ // const [formRef] = await showModal({
modalProps: { // modalProps: {
title: `${record.id ? '编辑' : '新增'}合同`, // title: `${record.id ? '' : ''}`,
width: '50%', // width: '50%',
onFinish: async (values) => { // onFinish: async (values) => {
const params = { // const params = {
...values, // ...values,
signingDate: formatToDate(values.signingDate), // signingDate: formatToDate(values.signingDate),
deliveryDeadline: formatToDate(values.deliveryDeadline), // deliveryDeadline: formatToDate(values.deliveryDeadline),
}; // };
if (record.id) { // if (record.id) {
await Api.contract.contractUpdate({ id: record.id }, params); // await Api.contract.contractUpdate({ id: record.id }, params);
} else { // } else {
await Api.contract.contractCreate(params); // await Api.contract.contractCreate(params);
} // }
dynamicTableInstance?.reload(); // dynamicTableInstance?.reload();
}, // },
}, // },
formProps: { // formProps: {
labelWidth: 100, // labelWidth: 100,
schemas: contractSchemas(contractTypes.value), // schemas: contractSchemas(contractTypes.value),
}, // },
}); // });
// // //
if (record.id) { // if (record.id) {
const info = await Api.contract.contractInfo({ id: record.id }); // const info = await Api.contract.contractInfo({ id: record.id });
formRef?.setFieldsValue({ // formRef?.setFieldsValue({
...info, // ...info,
}); // });
} // }
}; };
const delRowConfirm = async (record) => { const delRowConfirm = async (record) => {
await Api.contract.contractDelete({ id: record }); await Api.contract.contractDelete({ id: record });
dynamicTableInstance?.reload(); dynamicTableInstance?.reload();
}; };
const FilesRender: FunctionalComponent<TableListItem> = (contract: API.ContractEntity) => { const FilesRender: FunctionalComponent<TableListItem> = (contract: TableListItem) => {
const [fnModal] = useModal(); const [fnModal] = useModal();
return ( return (
<Button <Button
@ -196,22 +184,22 @@
); );
}; };
const openFilesManageModal = (fnModal, contract: API.ContractEntity) => { const openFilesManageModal = (fnModal, contract: TableListItem) => {
const fileIds = contract.files?.map((item) => item.id) || []; // const fileIds = contract.files?.map((item) => item.id) || [];
fnModal.show({ // fnModal.show({
width: 1200, // width: 1200,
title: `附件管理`, // title: ``,
content: () => { // content: () => {
return ( // return (
<AttachmentManage // <AttachmentManage
fileIds={fileIds} // fileIds={fileIds}
onDelete={(unlinkIds) => unlinkAttachments(contract.id, unlinkIds)} // onDelete={(unlinkIds) => unlinkAttachments(contract.id, unlinkIds)}
></AttachmentManage> // ></AttachmentManage>
); // );
}, // },
destroyOnClose: true, // destroyOnClose: true,
footer: null, // footer: null,
}); // });
}; };
const unlinkAttachments = async (id: number, unlinkIds: number[]) => { const unlinkAttachments = async (id: number, unlinkIds: number[]) => {
await Api.contract.unlinkAttachments({ id }, { fileIds: unlinkIds }); await Api.contract.unlinkAttachments({ id }, { fileIds: unlinkIds });