feat: import prodect from file
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 6s
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 6s
This commit is contained in:
parent
74291c0552
commit
8d8ad40de1
3 changed files with 70 additions and 6 deletions
|
|
@ -1,8 +1,10 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
import MainButton from './MainButton.vue';
|
import MainButton from './MainButton.vue';
|
||||||
|
|
||||||
defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'click', v: MouseEvent): void;
|
(e: 'click', v: MouseEvent): void;
|
||||||
|
(e: 'fileSelected', v: File[]): void;
|
||||||
}>();
|
}>();
|
||||||
defineProps<{
|
defineProps<{
|
||||||
iconOnly?: boolean;
|
iconOnly?: boolean;
|
||||||
|
|
@ -10,15 +12,29 @@ defineProps<{
|
||||||
outlined?: boolean;
|
outlined?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
dark?: boolean;
|
dark?: boolean;
|
||||||
|
importFile?: boolean;
|
||||||
|
|
||||||
label?: string;
|
label?: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const inputRef = ref<HTMLInputElement | null>(null);
|
||||||
|
|
||||||
|
function triggerFileInput() {
|
||||||
|
inputRef.value?.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleFileChange(event: Event) {
|
||||||
|
const files = (event.target as HTMLInputElement).files;
|
||||||
|
if (files && files.length > 0) {
|
||||||
|
emit('fileSelected', Array.from(files));
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MainButton
|
<MainButton
|
||||||
@click="(e) => $emit('click', e)"
|
@click="(e) => (importFile ? triggerFileInput() : $emit('click', e))"
|
||||||
v-bind="{ ...$props, ...$attrs }"
|
v-bind="{ ...$props, ...$attrs }"
|
||||||
:icon="icon || 'mdi-import'"
|
:icon="icon || 'mdi-import'"
|
||||||
color="var(--info-bg)"
|
color="var(--info-bg)"
|
||||||
|
|
@ -26,4 +42,13 @@ defineProps<{
|
||||||
>
|
>
|
||||||
{{ label || $t('general.import') }}
|
{{ label || $t('general.import') }}
|
||||||
</MainButton>
|
</MainButton>
|
||||||
|
|
||||||
|
<input
|
||||||
|
ref="inputRef"
|
||||||
|
type="file"
|
||||||
|
@change="(e) => handleFileChange(e)"
|
||||||
|
hidden
|
||||||
|
accept=".xls, .xlsx , .csv"
|
||||||
|
multiple
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import {
|
||||||
UndoButton,
|
UndoButton,
|
||||||
ToggleButton,
|
ToggleButton,
|
||||||
PasteButton,
|
PasteButton,
|
||||||
|
ImportButton,
|
||||||
} from 'components/button';
|
} from 'components/button';
|
||||||
import TableProduct from 'src/components/04_product-service/TableProduct.vue';
|
import TableProduct from 'src/components/04_product-service/TableProduct.vue';
|
||||||
import PaginationPageSize from 'src/components/PaginationPageSize.vue';
|
import PaginationPageSize from 'src/components/PaginationPageSize.vue';
|
||||||
|
|
@ -99,6 +100,8 @@ const {
|
||||||
createWork,
|
createWork,
|
||||||
editWork,
|
editWork,
|
||||||
deleteWork,
|
deleteWork,
|
||||||
|
|
||||||
|
importProduct,
|
||||||
} = productServiceStore;
|
} = productServiceStore;
|
||||||
|
|
||||||
const currentCopy = ref<{
|
const currentCopy = ref<{
|
||||||
|
|
@ -107,6 +110,7 @@ const currentCopy = ref<{
|
||||||
}>();
|
}>();
|
||||||
const { workNameItems } = storeToRefs(productServiceStore);
|
const { workNameItems } = storeToRefs(productServiceStore);
|
||||||
const allStat = ref<{ mode: string; count: number }[]>([]);
|
const allStat = ref<{ mode: string; count: number }[]>([]);
|
||||||
|
|
||||||
const stat = ref<
|
const stat = ref<
|
||||||
{
|
{
|
||||||
icon: string;
|
icon: string;
|
||||||
|
|
@ -2262,7 +2266,6 @@ watch(
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
></q-select>
|
></q-select>
|
||||||
|
|
||||||
<q-select
|
<q-select
|
||||||
v-if="modeView === false"
|
v-if="modeView === false"
|
||||||
id="select-field"
|
id="select-field"
|
||||||
|
|
@ -2285,7 +2288,6 @@ watch(
|
||||||
multiple
|
multiple
|
||||||
dense
|
dense
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-btn-toggle
|
<q-btn-toggle
|
||||||
v-model="modeView"
|
v-model="modeView"
|
||||||
id="btn-mode"
|
id="btn-mode"
|
||||||
|
|
@ -2760,6 +2762,26 @@ watch(
|
||||||
</AdvanceSearch>
|
</AdvanceSearch>
|
||||||
</template>
|
</template>
|
||||||
</q-input>
|
</q-input>
|
||||||
|
<div
|
||||||
|
class="flex q-mr-auto q-pl-sm"
|
||||||
|
v-if="productAndServiceTab === 'product'"
|
||||||
|
>
|
||||||
|
<input ref="fileImport" type="file" hidden />
|
||||||
|
<ImportButton
|
||||||
|
type="file"
|
||||||
|
import-file
|
||||||
|
icon-only
|
||||||
|
@file-selected="
|
||||||
|
(file) => {
|
||||||
|
importProduct(
|
||||||
|
currentIdGroup,
|
||||||
|
file,
|
||||||
|
async () => await fetchListOfProduct(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row col-md-6" style="white-space: nowrap">
|
<div class="row col-md-6" style="white-space: nowrap">
|
||||||
<q-select
|
<q-select
|
||||||
|
|
@ -2785,7 +2807,6 @@ watch(
|
||||||
]"
|
]"
|
||||||
@update:model-value="fetchStatus()"
|
@update:model-value="fetchStatus()"
|
||||||
></q-select>
|
></q-select>
|
||||||
|
|
||||||
<q-select
|
<q-select
|
||||||
v-if="modeView === false"
|
v-if="modeView === false"
|
||||||
:hide-dropdown-icon="$q.screen.lt.sm"
|
:hide-dropdown-icon="$q.screen.lt.sm"
|
||||||
|
|
@ -2820,7 +2841,6 @@ watch(
|
||||||
multiple
|
multiple
|
||||||
dense
|
dense
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-btn-toggle
|
<q-btn-toggle
|
||||||
v-model="modeView"
|
v-model="modeView"
|
||||||
id="btn-mode"
|
id="btn-mode"
|
||||||
|
|
|
||||||
|
|
@ -194,6 +194,23 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function importProduct(
|
||||||
|
productGroupId: string,
|
||||||
|
files: File[],
|
||||||
|
fetch: (...args: unknown[]) => void,
|
||||||
|
) {
|
||||||
|
const importTasks = files.map((f) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', f);
|
||||||
|
return api.post('/product/import-product', formData, {
|
||||||
|
params: { productGroupId },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all(importTasks);
|
||||||
|
fetch?.();
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchListProductById(productId: string) {
|
async function fetchListProductById(productId: string) {
|
||||||
const res = await api.get<Product>(`/product/${productId}`);
|
const res = await api.get<Product>(`/product/${productId}`);
|
||||||
|
|
||||||
|
|
@ -549,6 +566,8 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
fetchImageListById,
|
fetchImageListById,
|
||||||
addImageList,
|
addImageList,
|
||||||
deleteImageByName,
|
deleteImageByName,
|
||||||
|
|
||||||
|
importProduct,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue