feat: 下载文件功能,全局loading组件封装,导出盘点表初步
This commit is contained in:
parent
7c6ead4c66
commit
963ad25032
|
@ -47,6 +47,7 @@
|
|||
"dayjs": "~1.11.10",
|
||||
"echarts": "^5.5.0",
|
||||
"file-saver": "~2.0.5",
|
||||
"js-file-download": "^0.4.12",
|
||||
"lodash-es": "~4.17.21",
|
||||
"mitt": "~3.0.1",
|
||||
"nprogress": "~1.0.0-1",
|
||||
|
@ -78,13 +79,12 @@
|
|||
"@vitejs/plugin-vue": "~5.0.4",
|
||||
"@vitejs/plugin-vue-jsx": "~3.1.0",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"commitizen": "~4.3.0",
|
||||
"cliui": "^8.0.1",
|
||||
"cz-customizable": "^7.0.0",
|
||||
"commitizen": "~4.3.0",
|
||||
"conventional-changelog-cli": "~4.1.0",
|
||||
"standard-version": "^9.5.0",
|
||||
"core-js": "^3.36.0",
|
||||
"cross-env": "~7.0.3",
|
||||
"cz-customizable": "^7.0.0",
|
||||
"eslint": "~8.57.0",
|
||||
"eslint-config-prettier": "~9.1.0",
|
||||
"eslint-define-config": "~2.1.0",
|
||||
|
@ -103,6 +103,7 @@
|
|||
"prettier": "~3.2.5",
|
||||
"pretty-quick": "~4.0.0",
|
||||
"rimraf": "~5.0.5",
|
||||
"standard-version": "^9.5.0",
|
||||
"stylelint": "~16.2.1",
|
||||
"stylelint-config-property-sort-order-smacss": "^10.0.0",
|
||||
"stylelint-config-recommended": "~14.0.0",
|
||||
|
|
|
@ -32,6 +32,9 @@ dependencies:
|
|||
file-saver:
|
||||
specifier: ~2.0.5
|
||||
version: 2.0.5
|
||||
js-file-download:
|
||||
specifier: ^0.4.12
|
||||
version: 0.4.12
|
||||
lodash-es:
|
||||
specifier: ~4.17.21
|
||||
version: 4.17.21
|
||||
|
@ -7727,6 +7730,10 @@ packages:
|
|||
resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==}
|
||||
dev: true
|
||||
|
||||
/js-file-download@0.4.12:
|
||||
resolution: {integrity: sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==}
|
||||
dev: false
|
||||
|
||||
/js-tokens@4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
|
|
|
@ -28,6 +28,19 @@ export async function materialsInventoryList(
|
|||
});
|
||||
}
|
||||
|
||||
/** 导出原材料盘点表 GET /api/materials-inventory/export*/
|
||||
export async function materialsInventoryExport(
|
||||
// 叠加生成的Param类型 (非body参数swagger默认没有生成对象)
|
||||
params: API.MaterialsInventoryExportParams,
|
||||
options?: RequestOptions,
|
||||
) {
|
||||
const { ...queryParams } = params;
|
||||
return request(`/api/materials-inventory/export`, {
|
||||
method: 'GET',
|
||||
params: { ...queryParams },
|
||||
...(options || { responseType: 'blob', isReturnResult: false }),
|
||||
});
|
||||
}
|
||||
/** 新增原材料盘点 POST /api/materials-inventory */
|
||||
export async function materialsInventoryCreate(
|
||||
body: API.MaterialsInventoryDto,
|
||||
|
|
|
@ -1361,6 +1361,11 @@ declare namespace API {
|
|||
id: number;
|
||||
};
|
||||
|
||||
type MaterialsInventoryExportParams = {
|
||||
time: string;
|
||||
projectId: number;
|
||||
};
|
||||
|
||||
type MaterialsInventoryInfoParams = {
|
||||
id: number;
|
||||
};
|
||||
|
@ -1667,7 +1672,7 @@ declare namespace API {
|
|||
time?: string;
|
||||
inventoryNumber?: string;
|
||||
isCreateOut?: boolean;
|
||||
project?:string;
|
||||
project?: string;
|
||||
field?: string;
|
||||
order?: 'ASC' | 'DESC';
|
||||
_t?: number;
|
||||
|
@ -1701,7 +1706,7 @@ declare namespace API {
|
|||
/** 项目 */
|
||||
project: ProjectEntity;
|
||||
/** 项目ID */
|
||||
projectId?:number;
|
||||
projectId?: number;
|
||||
/** 备注 */
|
||||
remark: string;
|
||||
/** 附件 */
|
||||
|
@ -1755,7 +1760,7 @@ declare namespace API {
|
|||
/** 领料单号 */
|
||||
issuanceNumber?: number;
|
||||
/** 项目 */
|
||||
projectId?:number;
|
||||
projectId?: number;
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
/** 附件 */
|
||||
|
|
|
@ -6,3 +6,4 @@ export { useI18n } from './useI18n';
|
|||
export { useOnline } from './useOnline';
|
||||
export { useTime } from './useTime';
|
||||
export { useSortable } from './useSortable';
|
||||
export { useGlobalLoading } from './useGlobalLoading';
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import { createVNode, render, h, onMounted, onUnmounted } from 'vue';
|
||||
import { Spin as ASpin } from 'ant-design-vue';
|
||||
|
||||
export function useGlobalLoading() {
|
||||
let loadingElement: HTMLElement | null = null;
|
||||
|
||||
const showLoading = () => {
|
||||
if (!loadingElement) {
|
||||
loadingElement = document.createElement('div');
|
||||
loadingElement.id = 'global-loading';
|
||||
document.body.appendChild(loadingElement);
|
||||
|
||||
const spinVNode = h(ASpin, { spinning: true });
|
||||
render(spinVNode, loadingElement);
|
||||
}
|
||||
};
|
||||
|
||||
const hideLoading = () => {
|
||||
if (loadingElement) {
|
||||
document.body.removeChild(loadingElement);
|
||||
loadingElement = null;
|
||||
}
|
||||
};
|
||||
|
||||
onUnmounted(hideLoading);
|
||||
|
||||
return { showLoading, hideLoading };
|
||||
}
|
|
@ -34,7 +34,6 @@ export function useFormModal<T extends object = Recordable>() {
|
|||
|
||||
const onSubmit = async (values) => {
|
||||
await modalProps?.onFinish?.(values);
|
||||
// formRef.value?.resetFields();
|
||||
ModalRender.hide();
|
||||
};
|
||||
|
||||
|
|
|
@ -5,3 +5,17 @@
|
|||
@import './transition.less';
|
||||
@import './common.less';
|
||||
@import './antdv.override.less';
|
||||
|
||||
#global-loading {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background: #0004;
|
||||
}
|
||||
|
|
|
@ -52,9 +52,12 @@ service.interceptors.request.use(
|
|||
service.interceptors.response.use(
|
||||
(response: AxiosResponse<BaseResponse>) => {
|
||||
const res = response.data;
|
||||
|
||||
// if the custom code is not 200, it is judged as an error.
|
||||
// 若是文件下载直接跳过解析
|
||||
if (response.request.responseType === 'blob') {
|
||||
return response;
|
||||
}
|
||||
if (res.code !== ResultEnum.SUCCESS) {
|
||||
// if the custom code is not 200, it is judged as an error.
|
||||
$message.error(res.message || UNKNOWN_ERROR);
|
||||
// Illegal token
|
||||
if ([1101, 1105].includes(res.code)) {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
import type { FormSchema } from '@/components/core/schema-form/';
|
||||
|
||||
import Api from '@/api';
|
||||
import { debounce } from 'lodash-es';
|
||||
export const exportSchemas: FormSchema<API.MaterialsInventoryExportParams>[] = [
|
||||
{
|
||||
field: 'projectId',
|
||||
component: 'Select',
|
||||
label: '项目',
|
||||
colProps: {
|
||||
span: 12,
|
||||
},
|
||||
required: true,
|
||||
helpMessage: '如未找到对应项目,请先去项目管理添加项目。',
|
||||
componentProps: ({ formInstance, schema, formModel }) => ({
|
||||
showSearch: true,
|
||||
filterOption: false,
|
||||
fieldNames: {
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
},
|
||||
getPopupContainer: () => document.body,
|
||||
defaultActiveFirstOption: true,
|
||||
onClear: async () => {
|
||||
const newSchema = {
|
||||
field: schema.field,
|
||||
componentProps: {
|
||||
options: [] as LabelValueOptions,
|
||||
},
|
||||
};
|
||||
const options = await getProjectOptions().finally(() => (schema.loading = false));
|
||||
newSchema.componentProps.options = options;
|
||||
formInstance?.updateSchema([newSchema]);
|
||||
},
|
||||
request: () => {
|
||||
return getProjectOptions();
|
||||
},
|
||||
onSearch: debounce(async (keyword) => {
|
||||
schema.loading = true;
|
||||
const newSchema = {
|
||||
field: schema.field,
|
||||
componentProps: {
|
||||
options: [] as LabelValueOptions,
|
||||
},
|
||||
};
|
||||
formInstance?.updateSchema([newSchema]);
|
||||
const options = await getProjectOptions(keyword).finally(() => (schema.loading = false));
|
||||
newSchema.componentProps.options = options;
|
||||
formInstance?.updateSchema([newSchema]);
|
||||
}, 500),
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: '时间',
|
||||
field: 'time',
|
||||
component: 'MonthPicker',
|
||||
required: true,
|
||||
colProps: {
|
||||
span: 12,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const getProjectOptions = async (keyword?: string): Promise<LabelValueOptions> => {
|
||||
const { items: result } = await Api.project.projectList({ pageSize: 100, name: keyword });
|
||||
return (
|
||||
result?.map((item) => ({
|
||||
label: `${item.name}`,
|
||||
value: item.id,
|
||||
})) || []
|
||||
);
|
||||
};
|
|
@ -3,7 +3,7 @@
|
|||
<DynamicTable
|
||||
row-key="id"
|
||||
header-title="原材料出入库记录"
|
||||
title-tooltip=""
|
||||
title-tooltip="要创建入库记录,必须创建入库产品,产品所属公司。"
|
||||
:data-request="Api.materialsInOut.materialsInOutList"
|
||||
:columns="columns"
|
||||
bordered
|
||||
|
@ -20,7 +20,7 @@
|
|||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
:disabled="!$auth('materials_inventory:history_in_out:export')"
|
||||
:disabled="!$auth('app:materials_inventory:export')"
|
||||
@click="exportMI()"
|
||||
>
|
||||
导出原材料盘点表
|
||||
|
@ -41,10 +41,15 @@
|
|||
import Api from '@/api/';
|
||||
import { onMounted, ref, type FunctionalComponent, unref } from 'vue';
|
||||
import { useFormModal, useModal } from '@/hooks/useModal';
|
||||
import { Button, message } from 'ant-design-vue';
|
||||
import { Button } from 'ant-design-vue';
|
||||
import { formSchemas } from './formSchemas';
|
||||
import { exportSchemas } from './exportSchema';
|
||||
import AttachmentManage from '@/components/business/attachment-manage/index.vue';
|
||||
import AttachmentUpload from '@/components/business/attachment-upload/index.vue';
|
||||
import fileDownload from 'js-file-download';
|
||||
import { useGlobalLoading } from '@/hooks';
|
||||
import { waitTime } from '@/utils/common';
|
||||
import dayjs from 'dayjs';
|
||||
defineOptions({
|
||||
name: 'MaterialsInOut',
|
||||
});
|
||||
|
@ -107,10 +112,30 @@
|
|||
const { time } = unref<TableQueryItem>(
|
||||
dynamicTableInstance?.queryFormRef?.formModel as TableQueryItem,
|
||||
);
|
||||
if (!time) {
|
||||
message.warn('请先在查询区选择导出月份时间');
|
||||
|
||||
const [formRef] = await showModal({
|
||||
modalProps: {
|
||||
title: `导出条件选择`,
|
||||
width: '50%',
|
||||
okText: '导出',
|
||||
onFinish: async (values) => {
|
||||
const response = await Api.materialsInventory.materialsInventoryExport(values);
|
||||
const { time } = values;
|
||||
fileDownload(response, `${dayjs(time).format('YYYY年MM月')}.xlsx`);
|
||||
},
|
||||
},
|
||||
formProps: {
|
||||
labelWidth: 100,
|
||||
schemas: exportSchemas,
|
||||
},
|
||||
});
|
||||
|
||||
// auto fill export search fields
|
||||
if (time) {
|
||||
formRef?.setFieldsValue({
|
||||
time,
|
||||
});
|
||||
}
|
||||
console.log('exportMI');
|
||||
};
|
||||
const openAttachmentUploadModal = async (record: TableListItem) => {
|
||||
isUploadPopupVisiable.value = true;
|
||||
|
|
|
@ -147,6 +147,9 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
|||
// minifyInternalExports: false,
|
||||
//TODO fix circular imports
|
||||
manualChunks(id) {
|
||||
if (id.includes('/node_modules/')) {
|
||||
return 'vendor';
|
||||
}
|
||||
if (id.includes('/src/locales/helper.ts')) {
|
||||
return 'vendor';
|
||||
} else if (id.includes('ant-design-vue')) {
|
||||
|
|
Loading…
Reference in New Issue