feat: 出入库模块完善,组件封装完善

This commit is contained in:
louis 2024-03-06 11:39:41 +08:00
parent 55884200da
commit 989cbfc69a
13 changed files with 280 additions and 189 deletions

View File

@ -12,8 +12,10 @@
import { useRoute } from 'vue-router';
import { transformI18n } from './hooks/useI18n';
import { LockScreen } from '@/components/basic/lockscreen';
const route = useRoute();
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
dayjs.locale('zh-cn');
watchEffect(() => {
if (route.meta?.title) {
//

View File

@ -50,7 +50,7 @@ export async function materialsInOutInfo(
options?: RequestOptions,
) {
const { id: param0, ...queryParams } = params;
return request<API.MaterialsInOutEntity>(`/api/contract/${param0}`, {
return request<API.MaterialsInOutEntity>(`/api/materials-in-out/${param0}`, {
method: 'GET',
params: { ...queryParams },
...(options || {}),
@ -61,7 +61,7 @@ export async function materialsInOutInfo(
export async function unlinkAttachments(
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
params: API.MaterialsInOutUpdateParams,
body: API.MaterialsInOutDto,
body: API.MaterialsInOutUpdateDto,
options?: RequestOptions,
) {
const { id: param0, ...queryParams } = params;

View File

@ -1561,7 +1561,7 @@ declare namespace API {
/** 所属公司 */
company: CompanyEntity;
/** 单位 */
unit: string;
unit: DictItemEntity;
/** 是否删除 */
isDelete: string;
/** 附件 */
@ -1576,7 +1576,7 @@ declare namespace API {
/** 所属公司 */
companyId?: number;
/** 单位 */
unit?: string;
unitId?: number;
fileIds?: number[];
};
type ProductUpdateParams = {
@ -1636,7 +1636,7 @@ declare namespace API {
/** 出库或入库 */
inOrOut: number;
/** 单位(字典) */
unit: number;
unit: DictItemEntity;
/** 时间 */
time: Date;
/** 数量 */
@ -1661,16 +1661,12 @@ declare namespace API {
};
type MaterialsInOutDto = {
/** 公司名称 */
companyName: string;
/** 产品Id */
productId: number;
/** 产品信息 */
product?: ProductEntity;
/** 出库或入库 */
inOrOut: number;
/** 单位(字典) */
unit: number;
/** 时间 */
time: Date;
/** 数量 */
@ -1680,39 +1676,37 @@ declare namespace API {
/** 金额 */
amount: number;
/** 经办人 */
agent: string;
agent?: string;
/** 领料单号 */
issuanceNumber?: number;
/** 项目 */
project: string;
project?: string;
/** 备注 */
remark: string;
remark?: string;
/** 附件 */
fileIds?: number[];
};
type MaterialsInOutUpdateDto = {
/** 公司名称 */
companyName: string;
/** 产品Id */
productId: number;
productId?: number;
/** 出库或入库 */
inOrOut: number;
/** 单位(字典) */
unit: number;
inOrOut?: number;
/** 时间 */
time: Date;
time?: Date;
/** 数量 */
quantity: number;
quantity?: number;
/** 单价 */
unitPrice: number;
unitPrice?: number;
/** 金额 */
amount: number;
amount?: number;
/** 经办人 */
agent: string;
agent?: string;
/** 领料单号 */
issuanceNumber?: number;
/** 项目 */
project: string;
project?: string;
/** 备注 */
remark: string;
remark?: string;
/** 附件 */
fileIds?: number[];
};

View File

@ -27,9 +27,9 @@
:is="getComponent"
v-else-if="getComponent"
:ref="setItemRef(schema.field)"
:allow-clear="true"
v-bind="getComponentProps"
v-model:[modelValueType]="modelValue"
:allow-clear="true"
:disabled="getDisable"
:loading="schema.loading"
v-on="componentEvents"

View File

@ -8,6 +8,7 @@ import type { LocaleType } from './config';
import type { Locale } from 'ant-design-vue/es/locale-provider';
import { useLocaleStoreWithOut } from '@/store/modules/locale';
import dayjs from 'dayjs';
interface LangModule {
message: Recordable;
@ -35,6 +36,7 @@ export function useLocale() {
return i18n.global.getLocaleMessage(unref(getLocale)).antdLocale;
});
// Switching the language will change the locale of useI18n
// And submit to configuration modification
async function changeLocale(locale: LocaleType) {
@ -43,7 +45,8 @@ export function useLocale() {
if (currentLocale === locale) {
return locale;
}
dayjs.locale(locale.toLocaleLowerCase());
// dayjs.locale(locale);
if (loadLocalePool.includes(locale)) {
setI18nLanguage(locale);
return locale;

View File

@ -3,93 +3,93 @@
* @description , ts
*/
const permissions = [
"system:user:list",
"system:role:list",
"system:menu:list",
"system:online:list",
"system:log:login:list",
"system:serve:stat",
"system:task:list",
"system:user:create",
"system:user:delete",
"system:user:update",
"system:user:read",
"system:role:create",
"system:role:delete",
"system:role:update",
"system:role:read",
"system:menu:create",
"system:menu:delete",
"system:menu:update",
"system:menu:read",
"system:online:kick",
"system:task:create",
"system:task:delete",
"system:task:once",
"system:task:read",
"system:task:start",
"system:task:stop",
"system:task:update",
"system:log:task:list",
"system:tools:email",
"tools:email:send",
"tool:storage:list",
"upload:upload",
"tool:storage:delete",
"system:user:password",
"system:dict-type:list",
"system:dict-type:create",
"system:dict-type:update",
"system:dict-type:delete",
"system:dict-type:info",
"system:dept:list",
"system:dept:create",
"system:dept:update",
"system:dept:delete",
"system:dept:read",
"app:health:network",
"app:health: database",
"system:param-config:list",
"system:param-config:read",
"system:param-config:create",
"system:param-config:update",
"system:param-config:delete",
"system:dict-item:list",
"system:dict-item:create",
"system:dict-item:update",
"system:dict-item:delete",
"system:dict-item:info",
"netdisk:manage:list",
"netdisk:manage:create",
"netdisk:manage:read",
"netdisk:manage:update",
"netdisk:manage:delete",
"netdisk:manage:token",
"netdisk:manage:mark",
"netdisk:manage:download",
"netdisk:manage:rename",
"netdisk:manage:copy",
"netdisk:manage:cut",
"netdisk:overview:desc",
"app:contract:list",
"app:materials_inventory:list",
"app:contract:update",
"app:contract:delete",
"app:contract:read",
"app:contract:create",
"app:materials_inventory:create",
"app:materials_inventory:update",
"app:materials_inventory:delete",
"app:company:list",
"app:company:read",
"app:company:create",
"app:company:update",
"app:company:delete",
"app:product:list",
"app:product:read",
"app:product:create",
"app:product:update",
"app:product:delete"
'system:user:list',
'system:role:list',
'system:menu:list',
'system:online:list',
'system:log:login:list',
'system:serve:stat',
'system:task:list',
'system:user:create',
'system:user:delete',
'system:user:update',
'system:user:read',
'system:role:create',
'system:role:delete',
'system:role:update',
'system:role:read',
'system:menu:create',
'system:menu:delete',
'system:menu:update',
'system:menu:read',
'system:online:kick',
'system:task:create',
'system:task:delete',
'system:task:once',
'system:task:read',
'system:task:start',
'system:task:stop',
'system:task:update',
'system:log:task:list',
'system:tools:email',
'tools:email:send',
'tool:storage:list',
'upload:upload',
'tool:storage:delete',
'system:user:password',
'system:dict-type:list',
'system:dict-type:create',
'system:dict-type:update',
'system:dict-type:delete',
'system:dict-type:info',
'system:dept:list',
'system:dept:create',
'system:dept:update',
'system:dept:delete',
'system:dept:read',
'app:health:network',
'app:health: database',
'system:param-config:list',
'system:param-config:read',
'system:param-config:create',
'system:param-config:update',
'system:param-config:delete',
'system:dict-item:list',
'system:dict-item:create',
'system:dict-item:update',
'system:dict-item:delete',
'system:dict-item:info',
'netdisk:manage:list',
'netdisk:manage:create',
'netdisk:manage:read',
'netdisk:manage:update',
'netdisk:manage:delete',
'netdisk:manage:token',
'netdisk:manage:mark',
'netdisk:manage:download',
'netdisk:manage:rename',
'netdisk:manage:copy',
'netdisk:manage:cut',
'netdisk:overview:desc',
'app:contract:list',
'materials_inventory:history_in_out:list',
'app:contract:update',
'app:contract:delete',
'app:contract:read',
'app:contract:create',
'materials_inventory:history_in_out:create',
'materials_inventory:history_in_out:update',
'materials_inventory:history_in_out:delete',
'app:company:list',
'app:company:read',
'app:company:create',
'app:company:update',
'app:company:delete',
'app:product:list',
'app:product:read',
'app:product:create',
'app:product:update',
'app:product:delete',
] as const;
export type PermissionType = (typeof permissions)[number];

View File

@ -2,4 +2,4 @@ import dashboard from './dashboard';
import demos from './demos';
import account from './account';
export default [...demos, ...dashboard, ...account];
export default [/* ...demos, */...dashboard, ...account];

View File

@ -17,7 +17,7 @@ export const useDictStore = defineStore('dict', () => {
});
};
getDictTypes();
const getDictItemsByCode = (code: string): API.DictItemEntity[] => {
const getDictItemsByCode = (code: DictEnum): API.DictItemEntity[] => {
return dictTypes.value.find((item) => item.code === code)?.dictItems || [];
};

View File

@ -7,37 +7,28 @@ import { Tag } from 'ant-design-vue';
export type TableListItem = API.MaterialsInOutEntity;
export type TableColumnItem = TableColumn<TableListItem>;
const dictStore = useDictStore();
export const baseColumns: TableColumnItem[] = [
{
title: '产品名称',
width: 180,
dataIndex: 'product',
customRender: ({ record }) => {
return record.product?.name || '';
},
},
{
title: '单位',
width: 60,
width: 40,
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 || ''
: '';
return record.unit?.label || '';
},
},
{
title: '入库/出库',
width: 80,
width: 60,
dataIndex: 'inOrOut',
formItemProps: {
component: 'Select',
@ -54,10 +45,12 @@ export const baseColumns: TableColumnItem[] = [
},
{
title: '时间',
width: 120,
width: 60,
align: 'center',
dataIndex: 'time',
formItemProps: { component: 'RangePicker' },
formItemProps: {
component: 'MonthPicker',
},
customRender: ({ record }) => {
return formatToDate(record.time);
},
@ -65,7 +58,7 @@ export const baseColumns: TableColumnItem[] = [
{
title: '数量',
hideInSearch: true,
width: 80,
width: 60,
dataIndex: 'quantity',
},
{

View File

@ -1,10 +1,12 @@
import type { FormSchema } from '@/components/core/schema-form/';
import { ContractStatusEnum } from '@/enums/contractEnum';
import { formatStatus } from './columns';
import Api from '@/api';
import { debounce } from 'lodash-es';
import { MaterialsInOutEnum } from '@/enums/materialsInventoryEnum';
import { DictEnum } from '@/enums/dictEnum';
import { useDictStore } from '@/store/modules/dict';
import { toRaw } from 'vue';
const { getDictItemsByCode } = useDictStore();
export const formSchemas: FormSchema<API.MaterialsInOutEntity>[] = [
{
field: 'productId',
@ -25,17 +27,16 @@ export const formSchemas: FormSchema<API.MaterialsInOutEntity>[] = [
options: [],
getPopupContainer: () => document.body,
defaultActiveFirstOption: true,
onChange: async (value) => {
if (!value) {
const options = await getProductOptions();
onClear: async () => {
const newSchema = {
field: schema.field,
componentProps: {
options,
options: [] as LabelValueOptions,
},
};
const options = await getProductOptions().finally(() => (schema.loading = false));
newSchema.componentProps.options = options;
formInstance?.updateSchema([newSchema]);
}
},
request: () => {
return getProductOptions();
@ -66,14 +67,77 @@ export const formSchemas: FormSchema<API.MaterialsInOutEntity>[] = [
span: 8,
},
componentProps: {
allowClear: false,
options: [
{ label: '出库', value: MaterialsInOutEnum.Out },
{ label: '入库', value: MaterialsInOutEnum.In },
],
},
},
{
label: '时间',
field: 'time',
component: 'DatePicker',
colProps: {
span: 12,
},
},
{
label: '数量',
field: 'quantity',
component: 'InputNumber',
colProps: {
span: 12,
},
},
{
label: '单价',
field: 'unitPrice',
component: 'InputNumber',
colProps: {
span: 12,
},
},
{
label: '金额',
field: 'amount',
component: 'InputNumber',
colProps: {
span: 12,
},
},
{
label: '经办人',
field: 'agent',
component: 'Input',
colProps: {
span: 12,
},
},
{
label: '领料单号',
field: 'issuanceNumber',
component: 'Input',
colProps: {
span: 12,
},
},
{
label: '项目',
field: 'project',
component: 'Input',
colProps: {
span: 12,
},
},
{
label: '备注',
field: 'remark',
component: 'InputTextArea',
},
// {
// field: 'title',
// field: 'label',
// component: 'Input',
// label: '合同标题',
// rules: [{ required: true, type: 'string' }],
@ -155,7 +219,7 @@ export const formSchemas: FormSchema<API.MaterialsInOutEntity>[] = [
// checkable: true,
// vModelKey: 'checkedKeys',
// fieldNames: {
// title: 'name',
// label: 'name',
// key: 'id',
// },
// style: {

View File

@ -2,7 +2,7 @@
<div v-if="columns?.length">
<DynamicTable
row-key="id"
header-title="原材料盘点"
header-title="原材料出入库记录"
title-tooltip=""
:data-request="Api.materialsInOut.materialsInOutList"
:columns="columns"
@ -13,7 +13,7 @@
<template #toolbar>
<a-button
type="primary"
:disabled="!$auth('system:role:create')"
:disabled="!$auth('materials_inventory:history_in_out:create')"
@click="openEditModal({})"
>
新增
@ -56,9 +56,8 @@
},
{
title: '操作',
maxWidth: 150,
width: 150,
minWidth: 150,
maxWidth: 80,
width: 80,
dataIndex: 'ACTION',
hideInSearch: true,
fixed: 'right',
@ -67,7 +66,7 @@
icon: 'ant-design:edit-outlined',
tooltip: '编辑',
auth: {
perm: 'app:contract:update',
perm: 'materials_inventory:history_in_out:update',
effect: 'disable',
},
onClick: () => openEditModal(record),
@ -76,7 +75,7 @@
icon: 'ant-design:delete-outlined',
color: 'red',
tooltip: '删除此记录',
auth: 'app:contract:delete',
auth: 'materials_inventory:history_in_out:delete',
popConfirm: {
title: '你确定要删除吗?',
placement: 'left',
@ -121,7 +120,10 @@
files: { filename: { path: string; id: number } }[],
id: number,
) => {
await Api.contract.contractUpdate({ id }, { fileIds: files.map((item) => item.filename.id) });
await Api.materialsInOut.materialsInOutUpdate(
{ id },
{ fileIds: files.map((item) => item.filename.id) },
);
dynamicTableInstance?.reload();
};
@ -134,15 +136,18 @@
title: `${record.id ? '编辑' : '新增'}出入库记录`,
width: '50%',
onFinish: async (values) => {
const params: API.MaterialsInOutUpdateDto = {
const params = {
...values,
// signingDate: formatToDate(values.signingDate),
// deliveryDeadline: formatToDate(values.deliveryDeadline),
};
if (record.id) {
await Api.materialsInOut.materialsInOutUpdate({ id: record.id }, params);
await Api.materialsInOut.materialsInOutUpdate(
{ id: record.id },
params as API.MaterialsInOutUpdateDto,
);
} else {
await Api.materialsInOut.materialsInOutCreate(params);
await Api.materialsInOut.materialsInOutCreate(params as API.MaterialsInOutDto);
}
dynamicTableInstance?.reload();
},
@ -154,50 +159,50 @@
});
//
if (record.id) {
const info = await Api.contract.contractInfo({ id: record.id });
const info = await Api.materialsInOut.materialsInOutInfo({ id: record.id });
formRef?.setFieldsValue({
...info,
});
}
};
const delRowConfirm = async (record) => {
await Api.contract.contractDelete({ id: record });
await Api.materialsInOut.materialsInOutDelete({ id: record });
dynamicTableInstance?.reload();
};
const FilesRender: FunctionalComponent<TableListItem> = (contract: TableListItem) => {
const FilesRender: FunctionalComponent<TableListItem> = (materialsInOut: TableListItem) => {
const [fnModal] = useModal();
return (
<Button
type="link"
onClick={() => {
openFilesManageModal(fnModal, contract);
openFilesManageModal(fnModal, materialsInOut);
}}
>
{contract.files?.length || 0}
{materialsInOut.files?.length || 0}
</Button>
);
};
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 openFilesManageModal = (fnModal, tableData: TableListItem) => {
const fileIds = tableData.files?.map((item) => item.id) || [];
fnModal.show({
width: 1200,
title: `附件管理`,
content: () => {
return (
<AttachmentManage
fileIds={fileIds}
onDelete={(unlinkIds) => unlinkAttachments(tableData.id, unlinkIds)}
></AttachmentManage>
);
},
destroyOnClose: true,
footer: null,
});
};
const unlinkAttachments = async (id: number, unlinkIds: number[]) => {
await Api.contract.unlinkAttachments({ id }, { fileIds: unlinkIds });
await Api.materialsInOut.unlinkAttachments({ id }, { fileIds: unlinkIds });
dynamicTableInstance?.reload();
};
</script>

View File

@ -15,4 +15,11 @@ export const baseColumns: TableColumnItem[] = [
return record?.company?.name || '';
},
},
{
title: '单位',
dataIndex: 'unit',
customRender: ({ record }) => {
return record?.unit?.label || '';
},
},
];

View File

@ -1,7 +1,9 @@
import Api from '@/api';
import type { FormSchema } from '@/components/core/schema-form/';
import { DictEnum } from '@/enums/dictEnum';
import { useDictStore } from '@/store/modules/dict';
import { debounce } from 'lodash-es';
import { nextTick, toRaw } from 'vue';
const { getDictItemsByCode } = useDictStore();
export const formSchemas: FormSchema<API.ProductDto>[] = [
{
field: 'name',
@ -12,6 +14,28 @@ export const formSchemas: FormSchema<API.ProductDto>[] = [
span: 12,
},
},
{
label: '单位',
component: 'Select',
field: 'unitId',
componentProps: ({ formInstance, schema, formModel }) => ({
showSearch: true,
filterOption: (input: string, option: any) => {
return option.label.indexOf(input) >= 0;
},
fieldNames: {
label: 'label',
value: 'value',
},
options: getDictItemsByCode(DictEnum.Unit).map((item) => ({
value: item.id,
label: item.label,
})),
getPopupContainer: () => document.body,
defaultActiveFirstOption: true,
}),
},
{
field: 'companyId',
component: 'Select',
@ -28,7 +52,6 @@ export const formSchemas: FormSchema<API.ProductDto>[] = [
getPopupContainer: () => document.body,
defaultActiveFirstOption: true,
onChange: async (value) => {
console.log('onChange');
if (!value) {
formInstance?.setFieldsValue({ companyId: undefined });
const options = await getCompanyOptions();