diff --git a/src/App.vue b/src/App.vue index c322889..422a19c 100644 --- a/src/App.vue +++ b/src/App.vue @@ -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) { // 翻译网页标题 diff --git a/src/api/backend/api/materialsInOut.ts b/src/api/backend/api/materialsInOut.ts index 2d18155..bf7bfbd 100644 --- a/src/api/backend/api/materialsInOut.ts +++ b/src/api/backend/api/materialsInOut.ts @@ -50,7 +50,7 @@ export async function materialsInOutInfo( options?: RequestOptions, ) { const { id: param0, ...queryParams } = params; - return request(`/api/contract/${param0}`, { + return request(`/api/materials-in-out/${param0}`, { method: 'GET', params: { ...queryParams }, ...(options || {}), @@ -60,8 +60,8 @@ export async function materialsInOutInfo( /** 解除原材料出入库记录和附件关联 PUT /api/materials-in-out/unlink-attachments/${param0} */ export async function unlinkAttachments( // 叠加生成的Param类型 (非body参数swagger默认没有生成对象) - params: API.MaterialsInOutUpdateParams, - body: API.MaterialsInOutDto, + params: API.MaterialsInOutUpdateParams, + body: API.MaterialsInOutUpdateDto, options?: RequestOptions, ) { const { id: param0, ...queryParams } = params; diff --git a/src/api/backend/api/typings.d.ts b/src/api/backend/api/typings.d.ts index a331c6f..5801299 100644 --- a/src/api/backend/api/typings.d.ts +++ b/src/api/backend/api/typings.d.ts @@ -1537,7 +1537,7 @@ declare namespace API { page?: number; pageSize?: number; name?: string; - productId?:number; + productId?: number; field?: string; order?: 'ASC' | 'DESC'; _t?: number; @@ -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[]; }; diff --git a/src/components/core/schema-form/src/schema-form-item.vue b/src/components/core/schema-form/src/schema-form-item.vue index ead3a31..0cf0212 100644 --- a/src/components/core/schema-form/src/schema-form-item.vue +++ b/src/components/core/schema-form/src/schema-form-item.vue @@ -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" diff --git a/src/locales/useLocale.ts b/src/locales/useLocale.ts index 2168275..7f24cb0 100644 --- a/src/locales/useLocale.ts +++ b/src/locales/useLocale.ts @@ -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; diff --git a/src/permission/permCode.ts b/src/permission/permCode.ts index ed65976..665d28b 100644 --- a/src/permission/permCode.ts +++ b/src/permission/permCode.ts @@ -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]; diff --git a/src/router/routes/modules/index.ts b/src/router/routes/modules/index.ts index bdfc3cf..01fcde2 100644 --- a/src/router/routes/modules/index.ts +++ b/src/router/routes/modules/index.ts @@ -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]; diff --git a/src/store/modules/dict.ts b/src/store/modules/dict.ts index 08b3fe1..78a3e2b 100644 --- a/src/store/modules/dict.ts +++ b/src/store/modules/dict.ts @@ -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 || []; }; diff --git a/src/views/materials-inventory/in-out/columns.tsx b/src/views/materials-inventory/in-out/columns.tsx index 1835016..7d3717e 100644 --- a/src/views/materials-inventory/in-out/columns.tsx +++ b/src/views/materials-inventory/in-out/columns.tsx @@ -7,37 +7,28 @@ import { Tag } from 'ant-design-vue'; export type TableListItem = API.MaterialsInOutEntity; export type TableColumnItem = TableColumn; -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', }, { diff --git a/src/views/materials-inventory/in-out/formSchemas.ts b/src/views/materials-inventory/in-out/formSchemas.ts index b5e91d8..0e20658 100644 --- a/src/views/materials-inventory/in-out/formSchemas.ts +++ b/src/views/materials-inventory/in-out/formSchemas.ts @@ -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[] = [ { field: 'productId', @@ -13,7 +15,7 @@ export const formSchemas: FormSchema[] = [ colProps: { span: 16, }, - helpMessage:'如未找到对应产品,请先去产品管理添加产品。', + helpMessage: '如未找到对应产品,请先去产品管理添加产品。', rules: [{ required: true, type: 'number' }], componentProps: ({ formInstance, schema, formModel }) => ({ showSearch: true, @@ -25,17 +27,16 @@ export const formSchemas: FormSchema[] = [ options: [], getPopupContainer: () => document.body, defaultActiveFirstOption: true, - onChange: async (value) => { - if (!value) { - const options = await getProductOptions(); - const newSchema = { - field: schema.field, - componentProps: { - options, - }, - }; - formInstance?.updateSchema([newSchema]); - } + onClear: async () => { + const newSchema = { + field: schema.field, + componentProps: { + 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[] = [ 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[] = [ // checkable: true, // vModelKey: 'checkedKeys', // fieldNames: { - // title: 'name', + // label: 'name', // key: 'id', // }, // style: { diff --git a/src/views/materials-inventory/in-out/index.vue b/src/views/materials-inventory/in-out/index.vue index cb5a1b4..9d0f6a6 100644 --- a/src/views/materials-inventory/in-out/index.vue +++ b/src/views/materials-inventory/in-out/index.vue @@ -2,7 +2,7 @@
新增 @@ -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 = (contract: TableListItem) => { + const FilesRender: FunctionalComponent = (materialsInOut: TableListItem) => { const [fnModal] = useModal(); return ( ); }; - const openFilesManageModal = (fnModal, contract: TableListItem) => { - // const fileIds = contract.files?.map((item) => item.id) || []; - // fnModal.show({ - // width: 1200, - // title: `附件管理`, - // content: () => { - // return ( - // unlinkAttachments(contract.id, unlinkIds)} - // > - // ); - // }, - // destroyOnClose: true, - // footer: null, - // }); + const openFilesManageModal = (fnModal, tableData: TableListItem) => { + const fileIds = tableData.files?.map((item) => item.id) || []; + fnModal.show({ + width: 1200, + title: `附件管理`, + content: () => { + return ( + unlinkAttachments(tableData.id, unlinkIds)} + > + ); + }, + 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(); }; diff --git a/src/views/materials-inventory/product/columns.tsx b/src/views/materials-inventory/product/columns.tsx index 56936c3..af8aa05 100644 --- a/src/views/materials-inventory/product/columns.tsx +++ b/src/views/materials-inventory/product/columns.tsx @@ -15,4 +15,11 @@ export const baseColumns: TableColumnItem[] = [ return record?.company?.name || ''; }, }, + { + title: '单位', + dataIndex: 'unit', + customRender: ({ record }) => { + return record?.unit?.label || ''; + }, + }, ]; diff --git a/src/views/materials-inventory/product/formSchemas.ts b/src/views/materials-inventory/product/formSchemas.ts index 31bb15a..e45115d 100644 --- a/src/views/materials-inventory/product/formSchemas.ts +++ b/src/views/materials-inventory/product/formSchemas.ts @@ -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[] = [ { field: 'name', @@ -12,6 +14,28 @@ export const formSchemas: FormSchema[] = [ 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[] = [ getPopupContainer: () => document.body, defaultActiveFirstOption: true, onChange: async (value) => { - console.log('onChange'); if (!value) { formInstance?.setFieldsValue({ companyId: undefined }); const options = await getCompanyOptions();