feat: 下载文件功能,全局loading组件封装,导出盘点表初步
This commit is contained in:
parent
7c6ead4c66
commit
963ad25032
|
@ -47,6 +47,7 @@
|
||||||
"dayjs": "~1.11.10",
|
"dayjs": "~1.11.10",
|
||||||
"echarts": "^5.5.0",
|
"echarts": "^5.5.0",
|
||||||
"file-saver": "~2.0.5",
|
"file-saver": "~2.0.5",
|
||||||
|
"js-file-download": "^0.4.12",
|
||||||
"lodash-es": "~4.17.21",
|
"lodash-es": "~4.17.21",
|
||||||
"mitt": "~3.0.1",
|
"mitt": "~3.0.1",
|
||||||
"nprogress": "~1.0.0-1",
|
"nprogress": "~1.0.0-1",
|
||||||
|
@ -78,13 +79,12 @@
|
||||||
"@vitejs/plugin-vue": "~5.0.4",
|
"@vitejs/plugin-vue": "~5.0.4",
|
||||||
"@vitejs/plugin-vue-jsx": "~3.1.0",
|
"@vitejs/plugin-vue-jsx": "~3.1.0",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.5.1",
|
||||||
"commitizen": "~4.3.0",
|
|
||||||
"cliui": "^8.0.1",
|
"cliui": "^8.0.1",
|
||||||
"cz-customizable": "^7.0.0",
|
"commitizen": "~4.3.0",
|
||||||
"conventional-changelog-cli": "~4.1.0",
|
"conventional-changelog-cli": "~4.1.0",
|
||||||
"standard-version": "^9.5.0",
|
|
||||||
"core-js": "^3.36.0",
|
"core-js": "^3.36.0",
|
||||||
"cross-env": "~7.0.3",
|
"cross-env": "~7.0.3",
|
||||||
|
"cz-customizable": "^7.0.0",
|
||||||
"eslint": "~8.57.0",
|
"eslint": "~8.57.0",
|
||||||
"eslint-config-prettier": "~9.1.0",
|
"eslint-config-prettier": "~9.1.0",
|
||||||
"eslint-define-config": "~2.1.0",
|
"eslint-define-config": "~2.1.0",
|
||||||
|
@ -103,6 +103,7 @@
|
||||||
"prettier": "~3.2.5",
|
"prettier": "~3.2.5",
|
||||||
"pretty-quick": "~4.0.0",
|
"pretty-quick": "~4.0.0",
|
||||||
"rimraf": "~5.0.5",
|
"rimraf": "~5.0.5",
|
||||||
|
"standard-version": "^9.5.0",
|
||||||
"stylelint": "~16.2.1",
|
"stylelint": "~16.2.1",
|
||||||
"stylelint-config-property-sort-order-smacss": "^10.0.0",
|
"stylelint-config-property-sort-order-smacss": "^10.0.0",
|
||||||
"stylelint-config-recommended": "~14.0.0",
|
"stylelint-config-recommended": "~14.0.0",
|
||||||
|
|
|
@ -32,6 +32,9 @@ dependencies:
|
||||||
file-saver:
|
file-saver:
|
||||||
specifier: ~2.0.5
|
specifier: ~2.0.5
|
||||||
version: 2.0.5
|
version: 2.0.5
|
||||||
|
js-file-download:
|
||||||
|
specifier: ^0.4.12
|
||||||
|
version: 0.4.12
|
||||||
lodash-es:
|
lodash-es:
|
||||||
specifier: ~4.17.21
|
specifier: ~4.17.21
|
||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
|
@ -7727,6 +7730,10 @@ packages:
|
||||||
resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==}
|
resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/js-file-download@0.4.12:
|
||||||
|
resolution: {integrity: sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/js-tokens@4.0.0:
|
/js-tokens@4.0.0:
|
||||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
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 */
|
/** 新增原材料盘点 POST /api/materials-inventory */
|
||||||
export async function materialsInventoryCreate(
|
export async function materialsInventoryCreate(
|
||||||
body: API.MaterialsInventoryDto,
|
body: API.MaterialsInventoryDto,
|
||||||
|
|
|
@ -1361,6 +1361,11 @@ declare namespace API {
|
||||||
id: number;
|
id: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type MaterialsInventoryExportParams = {
|
||||||
|
time: string;
|
||||||
|
projectId: number;
|
||||||
|
};
|
||||||
|
|
||||||
type MaterialsInventoryInfoParams = {
|
type MaterialsInventoryInfoParams = {
|
||||||
id: number;
|
id: number;
|
||||||
};
|
};
|
||||||
|
@ -1667,7 +1672,7 @@ declare namespace API {
|
||||||
time?: string;
|
time?: string;
|
||||||
inventoryNumber?: string;
|
inventoryNumber?: string;
|
||||||
isCreateOut?: boolean;
|
isCreateOut?: boolean;
|
||||||
project?:string;
|
project?: string;
|
||||||
field?: string;
|
field?: string;
|
||||||
order?: 'ASC' | 'DESC';
|
order?: 'ASC' | 'DESC';
|
||||||
_t?: number;
|
_t?: number;
|
||||||
|
@ -1701,7 +1706,7 @@ declare namespace API {
|
||||||
/** 项目 */
|
/** 项目 */
|
||||||
project: ProjectEntity;
|
project: ProjectEntity;
|
||||||
/** 项目ID */
|
/** 项目ID */
|
||||||
projectId?:number;
|
projectId?: number;
|
||||||
/** 备注 */
|
/** 备注 */
|
||||||
remark: string;
|
remark: string;
|
||||||
/** 附件 */
|
/** 附件 */
|
||||||
|
@ -1755,7 +1760,7 @@ declare namespace API {
|
||||||
/** 领料单号 */
|
/** 领料单号 */
|
||||||
issuanceNumber?: number;
|
issuanceNumber?: number;
|
||||||
/** 项目 */
|
/** 项目 */
|
||||||
projectId?:number;
|
projectId?: number;
|
||||||
/** 备注 */
|
/** 备注 */
|
||||||
remark?: string;
|
remark?: string;
|
||||||
/** 附件 */
|
/** 附件 */
|
||||||
|
|
|
@ -6,3 +6,4 @@ export { useI18n } from './useI18n';
|
||||||
export { useOnline } from './useOnline';
|
export { useOnline } from './useOnline';
|
||||||
export { useTime } from './useTime';
|
export { useTime } from './useTime';
|
||||||
export { useSortable } from './useSortable';
|
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) => {
|
const onSubmit = async (values) => {
|
||||||
await modalProps?.onFinish?.(values);
|
await modalProps?.onFinish?.(values);
|
||||||
// formRef.value?.resetFields();
|
|
||||||
ModalRender.hide();
|
ModalRender.hide();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,3 +5,17 @@
|
||||||
@import './transition.less';
|
@import './transition.less';
|
||||||
@import './common.less';
|
@import './common.less';
|
||||||
@import './antdv.override.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(
|
service.interceptors.response.use(
|
||||||
(response: AxiosResponse<BaseResponse>) => {
|
(response: AxiosResponse<BaseResponse>) => {
|
||||||
const res = response.data;
|
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 (res.code !== ResultEnum.SUCCESS) {
|
||||||
|
// if the custom code is not 200, it is judged as an error.
|
||||||
$message.error(res.message || UNKNOWN_ERROR);
|
$message.error(res.message || UNKNOWN_ERROR);
|
||||||
// Illegal token
|
// Illegal token
|
||||||
if ([1101, 1105].includes(res.code)) {
|
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
|
<DynamicTable
|
||||||
row-key="id"
|
row-key="id"
|
||||||
header-title="原材料出入库记录"
|
header-title="原材料出入库记录"
|
||||||
title-tooltip=""
|
title-tooltip="要创建入库记录,必须创建入库产品,产品所属公司。"
|
||||||
:data-request="Api.materialsInOut.materialsInOutList"
|
:data-request="Api.materialsInOut.materialsInOutList"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
bordered
|
bordered
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button
|
<a-button
|
||||||
type="primary"
|
type="primary"
|
||||||
:disabled="!$auth('materials_inventory:history_in_out:export')"
|
:disabled="!$auth('app:materials_inventory:export')"
|
||||||
@click="exportMI()"
|
@click="exportMI()"
|
||||||
>
|
>
|
||||||
导出原材料盘点表
|
导出原材料盘点表
|
||||||
|
@ -41,10 +41,15 @@
|
||||||
import Api from '@/api/';
|
import Api from '@/api/';
|
||||||
import { onMounted, ref, type FunctionalComponent, unref } from 'vue';
|
import { onMounted, ref, type FunctionalComponent, unref } from 'vue';
|
||||||
import { useFormModal, useModal } from '@/hooks/useModal';
|
import { useFormModal, useModal } from '@/hooks/useModal';
|
||||||
import { Button, message } from 'ant-design-vue';
|
import { Button } from 'ant-design-vue';
|
||||||
import { formSchemas } from './formSchemas';
|
import { formSchemas } from './formSchemas';
|
||||||
|
import { exportSchemas } from './exportSchema';
|
||||||
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 fileDownload from 'js-file-download';
|
||||||
|
import { useGlobalLoading } from '@/hooks';
|
||||||
|
import { waitTime } from '@/utils/common';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'MaterialsInOut',
|
name: 'MaterialsInOut',
|
||||||
});
|
});
|
||||||
|
@ -107,10 +112,30 @@
|
||||||
const { time } = unref<TableQueryItem>(
|
const { time } = unref<TableQueryItem>(
|
||||||
dynamicTableInstance?.queryFormRef?.formModel as 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) => {
|
const openAttachmentUploadModal = async (record: TableListItem) => {
|
||||||
isUploadPopupVisiable.value = true;
|
isUploadPopupVisiable.value = true;
|
||||||
|
|
|
@ -147,6 +147,9 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
||||||
// minifyInternalExports: false,
|
// minifyInternalExports: false,
|
||||||
//TODO fix circular imports
|
//TODO fix circular imports
|
||||||
manualChunks(id) {
|
manualChunks(id) {
|
||||||
|
if (id.includes('/node_modules/')) {
|
||||||
|
return 'vendor';
|
||||||
|
}
|
||||||
if (id.includes('/src/locales/helper.ts')) {
|
if (id.includes('/src/locales/helper.ts')) {
|
||||||
return 'vendor';
|
return 'vendor';
|
||||||
} else if (id.includes('ant-design-vue')) {
|
} else if (id.includes('ant-design-vue')) {
|
||||||
|
|
Loading…
Reference in New Issue