refactor(04): service new img dialog
This commit is contained in:
parent
f1168c781f
commit
21ac39d538
4 changed files with 296 additions and 92 deletions
|
|
@ -146,7 +146,7 @@ withDefaults(
|
||||||
style="background-color: transparent"
|
style="background-color: transparent"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
:src="
|
:src="
|
||||||
`${baseUrl}/${data?.type === 'service' ? 'service' : 'product'}/${data?.id}/image`.concat(
|
`${baseUrl}/${data?.type}/${data?.id}/image/${data?.selectedImage}`.concat(
|
||||||
noTimeImg ? '' : `?ts=${Date.now()}`,
|
noTimeImg ? '' : `?ts=${Date.now()}`,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
|
|
|
||||||
|
|
@ -490,6 +490,15 @@ const branchOption = ref<{ id: string; name: string }[]>([]);
|
||||||
|
|
||||||
const currentStatus = ref<Status | 'All'>('All');
|
const currentStatus = ref<Status | 'All'>('All');
|
||||||
|
|
||||||
|
// img
|
||||||
|
const isImageEdit = ref<boolean>(false);
|
||||||
|
const refreshImageState = ref(false);
|
||||||
|
const imageList = ref<{ selectedImage: string; list: string[] }>();
|
||||||
|
const onCreateImageList = ref<{
|
||||||
|
selectedImage: string;
|
||||||
|
list: { url: string; imgFile: File | null; name: string }[];
|
||||||
|
}>({ selectedImage: '', list: [] });
|
||||||
|
|
||||||
async function searchProduct(isAdd: boolean = true) {
|
async function searchProduct(isAdd: boolean = true) {
|
||||||
const res = await fetchListProduct({
|
const res = await fetchListProduct({
|
||||||
query: inputSearchProductAndService.value,
|
query: inputSearchProductAndService.value,
|
||||||
|
|
@ -869,9 +878,10 @@ async function assignFormDataProductService(id: string) {
|
||||||
const res = await fetchListServiceById(id);
|
const res = await fetchListServiceById(id);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
await fetchImageList(res.id, res.selectedImage || '', 'service');
|
||||||
serviceTab.value = 1;
|
serviceTab.value = 1;
|
||||||
statusToggle.value = res.status === 'INACTIVE' ? false : true;
|
statusToggle.value = res.status === 'INACTIVE' ? false : true;
|
||||||
profileUrl.value = res.imageUrl;
|
profileUrl.value = `${baseUrl.value}/service/${res.id}/image/${res.selectedImage}`;
|
||||||
profileSubmit.value = true;
|
profileSubmit.value = true;
|
||||||
|
|
||||||
currentService.value = JSON.parse(JSON.stringify(res));
|
currentService.value = JSON.parse(JSON.stringify(res));
|
||||||
|
|
@ -884,6 +894,7 @@ async function assignFormDataProductService(id: string) {
|
||||||
work: [],
|
work: [],
|
||||||
status: res.status,
|
status: res.status,
|
||||||
productGroupId: res.productGroupId,
|
productGroupId: res.productGroupId,
|
||||||
|
selectedImage: res.selectedImage,
|
||||||
};
|
};
|
||||||
|
|
||||||
formDataProductService.value = { ...prevService.value };
|
formDataProductService.value = { ...prevService.value };
|
||||||
|
|
@ -932,12 +943,13 @@ const prevProduct = ref<ProductCreate>({
|
||||||
image: undefined,
|
image: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
function assignFormDataProduct(data: ProductList) {
|
async function assignFormDataProduct(data: ProductList) {
|
||||||
productTab.value = 1;
|
productTab.value = 1;
|
||||||
statusToggle.value = data.status === 'INACTIVE' ? false : true;
|
statusToggle.value = data.status === 'INACTIVE' ? false : true;
|
||||||
profileUrl.value = `${baseUrl.value}/product/${data?.id}/image`;
|
profileUrl.value = `${baseUrl.value}/product/${data?.id}/image/${data?.selectedImage}`;
|
||||||
|
|
||||||
profileSubmit.value = true;
|
await fetchImageList(data.id, data.selectedImage || '', 'product');
|
||||||
|
// profileSubmit.value = true;
|
||||||
|
|
||||||
prevProduct.value = {
|
prevProduct.value = {
|
||||||
productGroupId: data.productGroupId,
|
productGroupId: data.productGroupId,
|
||||||
|
|
@ -953,8 +965,8 @@ function assignFormDataProduct(data: ProductList) {
|
||||||
status: data.status,
|
status: data.status,
|
||||||
expenseType: data.expenseType,
|
expenseType: data.expenseType,
|
||||||
vatIncluded: data.vatIncluded,
|
vatIncluded: data.vatIncluded,
|
||||||
|
selectedImage: data.selectedImage,
|
||||||
};
|
};
|
||||||
|
|
||||||
formDataProduct.value = { ...prevProduct.value };
|
formDataProduct.value = { ...prevProduct.value };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1028,7 +1040,7 @@ function assignFormDataProductServiceCreate() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitService() {
|
async function submitService(notClose = false) {
|
||||||
assignFormDataProductServiceCreate();
|
assignFormDataProductServiceCreate();
|
||||||
formDataProductService.value.productGroupId = currentIdGrop.value;
|
formDataProductService.value.productGroupId = currentIdGrop.value;
|
||||||
|
|
||||||
|
|
@ -1045,7 +1057,10 @@ async function submitService() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await createService(formDataProductService.value);
|
const res = await createService(
|
||||||
|
formDataProductService.value,
|
||||||
|
onCreateImageList.value,
|
||||||
|
);
|
||||||
if (res) {
|
if (res) {
|
||||||
allStat.value[1].count = allStat.value[1].count + 1;
|
allStat.value[1].count = allStat.value[1].count + 1;
|
||||||
stat.value[1].count = stat.value[1].count + 1;
|
stat.value[1].count = stat.value[1].count + 1;
|
||||||
|
|
@ -1063,15 +1078,16 @@ async function submitService() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!notClose) clearFormService();
|
||||||
|
|
||||||
if (productAndServiceTab.value === 'service') {
|
if (productAndServiceTab.value === 'service') {
|
||||||
await fetchListOfService();
|
await fetchListOfService();
|
||||||
}
|
}
|
||||||
|
|
||||||
flowStore.rotate();
|
flowStore.rotate();
|
||||||
clearFormService();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitProduct() {
|
async function submitProduct(notClose = false) {
|
||||||
formDataProduct.value.productGroupId = currentIdGrop.value;
|
formDataProduct.value.productGroupId = currentIdGrop.value;
|
||||||
if (profileFileImg.value) {
|
if (profileFileImg.value) {
|
||||||
formDataProduct.value.image = profileFileImg.value;
|
formDataProduct.value.image = profileFileImg.value;
|
||||||
|
|
@ -1085,7 +1101,10 @@ async function submitProduct() {
|
||||||
productTab.value = 1;
|
productTab.value = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const res = await createProduct(formDataProduct.value);
|
const res = await createProduct(
|
||||||
|
formDataProduct.value,
|
||||||
|
onCreateImageList.value,
|
||||||
|
);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
allStat.value[2].count = allStat.value[2].count + 1;
|
allStat.value[2].count = allStat.value[2].count + 1;
|
||||||
|
|
@ -1102,7 +1121,7 @@ async function submitProduct() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
totalProduct.value = totalProduct.value + 1;
|
totalProduct.value = totalProduct.value + 1;
|
||||||
clearFormProduct();
|
if (!notClose) clearFormProduct();
|
||||||
|
|
||||||
if (productAndServiceTab.value === 'product') {
|
if (productAndServiceTab.value === 'product') {
|
||||||
await fetchListOfProduct();
|
await fetchListOfProduct();
|
||||||
|
|
@ -1234,12 +1253,14 @@ async function alternativeFetch() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneData() {
|
function cloneServiceData() {
|
||||||
if (!currentService.value) return;
|
if (!currentService.value) return;
|
||||||
|
const currentSelectedImage = formDataProductService.value.selectedImage;
|
||||||
formDataProductService.value = {
|
formDataProductService.value = {
|
||||||
...prevService.value,
|
...prevService.value,
|
||||||
attributes: JSON.parse(JSON.stringify(currentService.value.attributes)),
|
attributes: JSON.parse(JSON.stringify(currentService.value.attributes)),
|
||||||
};
|
};
|
||||||
|
formDataProductService.value.selectedImage = currentSelectedImage;
|
||||||
|
|
||||||
workItems.value = currentService.value.work.map((item) => {
|
workItems.value = currentService.value.work.map((item) => {
|
||||||
return {
|
return {
|
||||||
|
|
@ -1317,6 +1338,19 @@ function handleHold(node: ProductGroup & { type: string }) {
|
||||||
currentNode.value = node;
|
currentNode.value = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchImageList(
|
||||||
|
id: string,
|
||||||
|
selectedName: string,
|
||||||
|
type: 'product' | 'service',
|
||||||
|
) {
|
||||||
|
const res = await productServiceStore.fetchImageListById(id, type);
|
||||||
|
imageList.value = {
|
||||||
|
selectedImage: selectedName,
|
||||||
|
list: res.map((n: string) => `${type}/${id}/image/${n}`),
|
||||||
|
};
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
utilsStore.currentTitle.title = 'productService.title';
|
utilsStore.currentTitle.title = 'productService.title';
|
||||||
utilsStore.currentTitle.path = [
|
utilsStore.currentTitle.path = [
|
||||||
|
|
@ -1442,6 +1476,13 @@ watch(productMode, async () => {
|
||||||
await calculateStats({ type: 'product' });
|
await calculateStats({ type: 'product' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => profileFileImg.value,
|
||||||
|
() => {
|
||||||
|
if (profileFileImg.value !== null) isImageEdit.value = true;
|
||||||
|
},
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -2430,9 +2471,7 @@ watch(productMode, async () => {
|
||||||
<q-img
|
<q-img
|
||||||
class="text-center"
|
class="text-center"
|
||||||
:ratio="1"
|
:ratio="1"
|
||||||
:src="`
|
:src="`${baseUrl}/${productAndServiceTab}/${props.row.id}/image/${props.row.selectedImage}`"
|
||||||
${props.row.imageUrl ?? null}
|
|
||||||
`"
|
|
||||||
>
|
>
|
||||||
<template #error>
|
<template #error>
|
||||||
<q-icon
|
<q-icon
|
||||||
|
|
@ -3336,6 +3375,7 @@ watch(productMode, async () => {
|
||||||
:close="
|
:close="
|
||||||
() => {
|
() => {
|
||||||
dialogProduct = false;
|
dialogProduct = false;
|
||||||
|
onCreateImageList = { selectedImage: '', list: [] };
|
||||||
flowStore.rotate();
|
flowStore.rotate();
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
|
@ -3356,8 +3396,13 @@ watch(productMode, async () => {
|
||||||
bgColor: 'var(--surface-1)',
|
bgColor: 'var(--surface-1)',
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
@view="imageDialog = true"
|
@view="
|
||||||
@edit="refImageUpload && refImageUpload.browse()"
|
() => {
|
||||||
|
imageDialog = true;
|
||||||
|
isImageEdit = false;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@edit="imageDialog = isImageEdit = true"
|
||||||
v-model:toggle-status="formDataProduct.status"
|
v-model:toggle-status="formDataProduct.status"
|
||||||
@update:toggle-status="
|
@update:toggle-status="
|
||||||
() => {
|
() => {
|
||||||
|
|
@ -3449,15 +3494,6 @@ watch(productMode, async () => {
|
||||||
v-model:modal="dialogProductEdit"
|
v-model:modal="dialogProductEdit"
|
||||||
noAddress
|
noAddress
|
||||||
:title="$t('productService.product.title')"
|
:title="$t('productService.product.title')"
|
||||||
:editData="() => (infoProductEdit = true)"
|
|
||||||
:undo="
|
|
||||||
() => {
|
|
||||||
formDataProduct = { ...prevProduct };
|
|
||||||
infoProductEdit = false;
|
|
||||||
flowStore.rotate();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:deleteData="() => deleteProductConfirm()"
|
|
||||||
:submit="() => submitProduct()"
|
:submit="() => submitProduct()"
|
||||||
:close="
|
:close="
|
||||||
() => {
|
() => {
|
||||||
|
|
@ -3478,9 +3514,12 @@ watch(productMode, async () => {
|
||||||
icon="mdi-shopping-outline"
|
icon="mdi-shopping-outline"
|
||||||
fallbackImg="/images/product-avatar.png"
|
fallbackImg="/images/product-avatar.png"
|
||||||
color="var(--teal-10)"
|
color="var(--teal-10)"
|
||||||
:readonly="!infoProductEdit"
|
|
||||||
:toggleTitle="$t('status.title')"
|
:toggleTitle="$t('status.title')"
|
||||||
:img="profileUrl || '/images/product-avatar.png'"
|
:img="
|
||||||
|
`${baseUrl}/product/${currentIdProduct}/image/${formDataProduct.selectedImage}`.concat(
|
||||||
|
refreshImageState ? `?ts=${Date.now()}` : '',
|
||||||
|
) || '/images/product-avatar.png'
|
||||||
|
"
|
||||||
fallbackCover="/images/product-banner.png"
|
fallbackCover="/images/product-banner.png"
|
||||||
:bgColor="`hsla(var(--teal-${$q.dark.isActive ? '8' : '10'}-hsl)/0.15)`"
|
:bgColor="`hsla(var(--teal-${$q.dark.isActive ? '8' : '10'}-hsl)/0.15)`"
|
||||||
:menu="[
|
:menu="[
|
||||||
|
|
@ -3491,8 +3530,13 @@ watch(productMode, async () => {
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
v-model:toggle-status="formDataProduct.status"
|
v-model:toggle-status="formDataProduct.status"
|
||||||
@view="imageDialog = true"
|
@view="
|
||||||
@edit="refImageUpload && refImageUpload.browse()"
|
() => {
|
||||||
|
imageDialog = true;
|
||||||
|
isImageEdit = false;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@edit="imageDialog = isImageEdit = true"
|
||||||
@update:toggle-status="
|
@update:toggle-status="
|
||||||
async () => {
|
async () => {
|
||||||
if (formDataProduct.status)
|
if (formDataProduct.status)
|
||||||
|
|
@ -3639,6 +3683,7 @@ watch(productMode, async () => {
|
||||||
() => {
|
() => {
|
||||||
clearFormService();
|
clearFormService();
|
||||||
dialogService = false;
|
dialogService = false;
|
||||||
|
onCreateImageList = { selectedImage: '', list: [] };
|
||||||
flowStore.rotate();
|
flowStore.rotate();
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
|
@ -3664,8 +3709,13 @@ watch(productMode, async () => {
|
||||||
bgColor: 'var(--surface-1)',
|
bgColor: 'var(--surface-1)',
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
@view="imageDialog = true"
|
@view="
|
||||||
@edit="refImageUpload && refImageUpload.browse()"
|
() => {
|
||||||
|
imageDialog = true;
|
||||||
|
isImageEdit = false;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@edit="imageDialog = isImageEdit = true"
|
||||||
v-model:toggle-status="formDataProductService.status"
|
v-model:toggle-status="formDataProductService.status"
|
||||||
@update:toggle-status="
|
@update:toggle-status="
|
||||||
() => {
|
() => {
|
||||||
|
|
@ -3879,20 +3929,6 @@ watch(productMode, async () => {
|
||||||
dialogServiceEdit = false;
|
dialogServiceEdit = false;
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
:edit-data="
|
|
||||||
() => {
|
|
||||||
infoServiceEdit = true;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:undo="
|
|
||||||
() => {
|
|
||||||
infoServiceEdit = false;
|
|
||||||
cloneData();
|
|
||||||
statusToggle = prevService.status === 'INACTIVE' ? false : true;
|
|
||||||
flowStore.rotate();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
:delete-data="() => deleteServiceConfirm()"
|
|
||||||
>
|
>
|
||||||
<div class="q-mx-lg q-mt-lg">
|
<div class="q-mx-lg q-mt-lg">
|
||||||
<ProfileBanner
|
<ProfileBanner
|
||||||
|
|
@ -3901,9 +3937,13 @@ watch(productMode, async () => {
|
||||||
:title="formDataProductService.name"
|
:title="formDataProductService.name"
|
||||||
:caption="formDataProductService.code"
|
:caption="formDataProductService.code"
|
||||||
:active="formDataProductService.status !== 'INACTIVE'"
|
:active="formDataProductService.status !== 'INACTIVE'"
|
||||||
:readonly="!infoServiceEdit"
|
|
||||||
:toggleTitle="$t('status.title')"
|
:toggleTitle="$t('status.title')"
|
||||||
:img="profileUrl || '/images/service-avatar.png'"
|
:img="
|
||||||
|
`${baseUrl}/service/${currentIdService}/image/${formDataProductService.selectedImage}`.concat(
|
||||||
|
refreshImageState ? `?ts=${Date.now()}` : '',
|
||||||
|
) || '/images/service-avatar.png'
|
||||||
|
"
|
||||||
|
fallbackImg="/images/service-avatar.png"
|
||||||
fallbackCover="/images/service-banner.png"
|
fallbackCover="/images/service-banner.png"
|
||||||
:bgColor="`hsla(var(--orange-${$q.dark.isActive ? '6' : '5'}-hsl)/0.15)`"
|
:bgColor="`hsla(var(--orange-${$q.dark.isActive ? '6' : '5'}-hsl)/0.15)`"
|
||||||
:menu="[
|
:menu="[
|
||||||
|
|
@ -3919,8 +3959,13 @@ watch(productMode, async () => {
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
v-model:toggle-status="formDataProductService.status"
|
v-model:toggle-status="formDataProductService.status"
|
||||||
@view="imageDialog = true"
|
@view="
|
||||||
@edit="refImageUpload && refImageUpload.browse()"
|
() => {
|
||||||
|
imageDialog = true;
|
||||||
|
isImageEdit = false;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@edit="imageDialog = isImageEdit = true"
|
||||||
@update:toggle-status="
|
@update:toggle-status="
|
||||||
async () => {
|
async () => {
|
||||||
if (formDataProductService.status)
|
if (formDataProductService.status)
|
||||||
|
|
@ -3965,7 +4010,7 @@ watch(productMode, async () => {
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
infoServiceEdit = false;
|
infoServiceEdit = false;
|
||||||
cloneData();
|
cloneServiceData();
|
||||||
statusToggle = prevService.status === 'INACTIVE' ? false : true;
|
statusToggle = prevService.status === 'INACTIVE' ? false : true;
|
||||||
flowStore.rotate();
|
flowStore.rotate();
|
||||||
}
|
}
|
||||||
|
|
@ -4225,10 +4270,91 @@ watch(productMode, async () => {
|
||||||
v-model:dialogState="imageDialog"
|
v-model:dialogState="imageDialog"
|
||||||
v-model:file="profileFileImg"
|
v-model:file="profileFileImg"
|
||||||
v-model:image-url="profileUrl as string"
|
v-model:image-url="profileUrl as string"
|
||||||
:hidden-footer="!profileUrl && !dialogService && !dialogProduct"
|
v-model:data-list="imageList"
|
||||||
clearButton
|
v-model:on-create-data-list="onCreateImageList"
|
||||||
|
:hidden-footer="!isImageEdit"
|
||||||
|
:on-create="dialogProduct || dialogService"
|
||||||
:change-disabled="!actionDisplay"
|
:change-disabled="!actionDisplay"
|
||||||
|
@add-image="
|
||||||
|
async (v) => {
|
||||||
|
if (!v) return;
|
||||||
|
if (!currentIdProduct) return;
|
||||||
|
const res = await productServiceStore.addImageList(
|
||||||
|
v,
|
||||||
|
currentIdProduct,
|
||||||
|
Date.now(),
|
||||||
|
dialogProductEdit ? 'product' : 'service',
|
||||||
|
);
|
||||||
|
await fetchImageList(
|
||||||
|
currentIdProduct,
|
||||||
|
res,
|
||||||
|
dialogProductEdit ? 'product' : 'service',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@remove-image="
|
||||||
|
async (v) => {
|
||||||
|
if (!v) return;
|
||||||
|
if (!currentIdProduct && !currentIdService) return;
|
||||||
|
|
||||||
|
const name = v.split('/').pop() || '';
|
||||||
|
const type = dialogProductEdit ? 'product' : 'service';
|
||||||
|
await productServiceStore.deleteImageByName(
|
||||||
|
dialogProductEdit ? currentIdProduct : currentIdService,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
);
|
||||||
|
await fetchImageList(
|
||||||
|
dialogProductEdit ? currentIdProduct : currentIdService,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@submit="
|
||||||
|
async (v) => {
|
||||||
|
if (dialogProduct || dialogService) {
|
||||||
|
profileUrl = v;
|
||||||
|
imageDialog = false;
|
||||||
|
} else {
|
||||||
|
const type = dialogProductEdit ? 'product' : 'service';
|
||||||
|
const id = dialogProductEdit ? currentIdProduct : currentIdService;
|
||||||
|
refreshImageState = true;
|
||||||
|
type === 'product'
|
||||||
|
? (formDataProduct.selectedImage = v)
|
||||||
|
: (formDataProductService.selectedImage = v);
|
||||||
|
imageList ? (imageList.selectedImage = v) : '';
|
||||||
|
profileUrl = `${baseUrl}/${type}/${id}/image/${v}`;
|
||||||
|
if (type === 'product') {
|
||||||
|
const { selectedImage, ...data } = prevProduct;
|
||||||
|
formDataProduct = {
|
||||||
|
selectedImage: formDataProduct.selectedImage,
|
||||||
|
...data,
|
||||||
|
};
|
||||||
|
await submitProduct(true);
|
||||||
|
} else {
|
||||||
|
cloneServiceData();
|
||||||
|
await submitService(true);
|
||||||
|
}
|
||||||
|
imageDialog = false;
|
||||||
|
refreshImageState = false;
|
||||||
|
infoProductEdit = false;
|
||||||
|
infoServiceEdit = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
>
|
>
|
||||||
|
<template #title>
|
||||||
|
<span
|
||||||
|
v-if="!dialogProduct || !dialogService"
|
||||||
|
class="justify-center flex text-bold"
|
||||||
|
>
|
||||||
|
{{ $t('general.image') }}
|
||||||
|
{{
|
||||||
|
dialogProductEdit ? formDataProduct.name : formDataProductService.name
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="full-height full-width" style="background: var(--surface-1)">
|
<div class="full-height full-width" style="background: var(--surface-1)">
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -185,22 +185,32 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createProduct(data: ProductCreate) {
|
async function createProduct(
|
||||||
|
data: ProductCreate,
|
||||||
|
imgList: {
|
||||||
|
selectedImage: string;
|
||||||
|
list: { url: string; imgFile: File | null; name: string }[];
|
||||||
|
},
|
||||||
|
) {
|
||||||
const { image, status, ...payload } = data;
|
const { image, status, ...payload } = data;
|
||||||
|
|
||||||
const res = await api.post<ProductCreate & { imageUploadUrl: string }>(
|
const res = await api.post<ProductCreate>('/product', {
|
||||||
'/product',
|
...payload,
|
||||||
{
|
selectedImage: imgList.selectedImage || '',
|
||||||
...payload,
|
});
|
||||||
},
|
|
||||||
);
|
if (imgList.list.length > 0 && res.data.id) {
|
||||||
image &&
|
for (let index = 0; index < imgList.list.length; index++) {
|
||||||
(await axios
|
const imgFile = imgList.list[index].imgFile;
|
||||||
.put(res.data.imageUploadUrl, image, {
|
if (imgFile)
|
||||||
headers: { 'Content-Type': image.type },
|
await addImageList(
|
||||||
onUploadProgress: (e) => console.log(e),
|
imgFile,
|
||||||
})
|
res.data.id,
|
||||||
.catch((e) => console.error(e)));
|
imgList.list[index].name,
|
||||||
|
'product',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!res) return false;
|
if (!res) return false;
|
||||||
|
|
||||||
|
|
@ -234,14 +244,6 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
image &&
|
|
||||||
(await axios
|
|
||||||
.put(res.data.imageUploadUrl, image, {
|
|
||||||
headers: { 'Content-Type': image.type },
|
|
||||||
onUploadProgress: (e) => console.log(e),
|
|
||||||
})
|
|
||||||
.catch((e) => console.error(e)));
|
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
return res.data;
|
return res.data;
|
||||||
}
|
}
|
||||||
|
|
@ -314,23 +316,35 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createService(data: ServiceCreate) {
|
async function createService(
|
||||||
|
data: ServiceCreate,
|
||||||
|
imgList: {
|
||||||
|
selectedImage: string;
|
||||||
|
list: { url: string; imgFile: File | null; name: string }[];
|
||||||
|
},
|
||||||
|
) {
|
||||||
const { image, status, ...payload } = data;
|
const { image, status, ...payload } = data;
|
||||||
|
|
||||||
const res = await api.post<ServiceCreate & { imageUploadUrl: string }>(
|
const res = await api.post<ServiceCreate & { imageUploadUrl: string }>(
|
||||||
'/service',
|
'/service',
|
||||||
{
|
{
|
||||||
...payload,
|
...payload,
|
||||||
|
selectedImage: imgList.selectedImage || '',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
image &&
|
if (imgList.list.length > 0 && res.data.id) {
|
||||||
(await axios
|
for (let index = 0; index < imgList.list.length; index++) {
|
||||||
.put(res.data.imageUploadUrl, image, {
|
const imgFile = imgList.list[index].imgFile;
|
||||||
headers: { 'Content-Type': image.type },
|
if (imgFile)
|
||||||
onUploadProgress: (e) => console.log(e),
|
await addImageList(
|
||||||
})
|
imgFile,
|
||||||
.catch((e) => console.error(e)));
|
res.data.id,
|
||||||
|
imgList.list[index].name,
|
||||||
|
'service',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!res) return false;
|
if (!res) return false;
|
||||||
|
|
||||||
|
|
@ -397,14 +411,6 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
image &&
|
|
||||||
(await axios
|
|
||||||
.put(res.data.imageUploadUrl, image, {
|
|
||||||
headers: { 'Content-Type': image.type },
|
|
||||||
onUploadProgress: (e) => console.log(e),
|
|
||||||
})
|
|
||||||
.catch((e) => console.error(e)));
|
|
||||||
|
|
||||||
if (!res) return false;
|
if (!res) return false;
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
|
|
@ -554,6 +560,67 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchImageListById(
|
||||||
|
id: string,
|
||||||
|
type: 'product' | 'service',
|
||||||
|
flow?: {
|
||||||
|
sessionId?: string;
|
||||||
|
refTransactionId?: string;
|
||||||
|
transactionId?: string;
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
const res = await api.get(`/${type}/${id}/image`, {
|
||||||
|
headers: {
|
||||||
|
'X-Session-Id': flow?.sessionId,
|
||||||
|
'X-Rtid': flow?.refTransactionId || flowStore.rtid,
|
||||||
|
'X-Tid': flow?.transactionId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res) return false;
|
||||||
|
if (res.status === 200) return res.data;
|
||||||
|
if (res.status === 204) return null;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addImageList(
|
||||||
|
file: File,
|
||||||
|
userId: string,
|
||||||
|
name: string,
|
||||||
|
type: 'product' | 'service',
|
||||||
|
) {
|
||||||
|
await api
|
||||||
|
.put(`/${type}/${userId}/image/${name}`, file, {
|
||||||
|
headers: { 'Content-Type': file.type },
|
||||||
|
onUploadProgress: (e) => console.log(e),
|
||||||
|
})
|
||||||
|
.catch((e) => console.error(e));
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteImageByName(
|
||||||
|
id: string,
|
||||||
|
name: string,
|
||||||
|
type: 'product' | 'service',
|
||||||
|
flow?: {
|
||||||
|
sessionId?: string;
|
||||||
|
refTransactionId?: string;
|
||||||
|
transactionId?: string;
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
const res = await api.delete(`/${type}/${id}/image/${name}`, {
|
||||||
|
headers: {
|
||||||
|
'X-Session-Id': flow?.sessionId,
|
||||||
|
'X-Rtid': flow?.refTransactionId || flowStore.rtid,
|
||||||
|
'X-Tid': flow?.transactionId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res) return false;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
workNameItems,
|
workNameItems,
|
||||||
|
|
||||||
|
|
@ -587,6 +654,10 @@ const useProductServiceStore = defineStore('api-product-service', () => {
|
||||||
fetchListProductByIdWork,
|
fetchListProductByIdWork,
|
||||||
|
|
||||||
fetchListOfWork,
|
fetchListOfWork,
|
||||||
|
|
||||||
|
fetchImageListById,
|
||||||
|
addImageList,
|
||||||
|
deleteImageByName,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ export interface TreeProduct {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Service {
|
export interface Service {
|
||||||
|
selectedImage?: string;
|
||||||
productGroupId: string;
|
productGroupId: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
updatedBy: UpdatedBy;
|
updatedBy: UpdatedBy;
|
||||||
|
|
@ -47,6 +48,7 @@ export interface Work {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ServiceCreate {
|
export interface ServiceCreate {
|
||||||
|
id?: string;
|
||||||
work: {
|
work: {
|
||||||
attributes: Attributes;
|
attributes: Attributes;
|
||||||
productId: string[];
|
productId: string[];
|
||||||
|
|
@ -59,6 +61,7 @@ export interface ServiceCreate {
|
||||||
image?: File;
|
image?: File;
|
||||||
status?: Status;
|
status?: Status;
|
||||||
productGroupId: string;
|
productGroupId: string;
|
||||||
|
selectedImage?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Attributes {
|
export interface Attributes {
|
||||||
|
|
@ -131,6 +134,7 @@ export interface WorkItems {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductList {
|
export interface ProductList {
|
||||||
|
selectedImage?: string;
|
||||||
expenseType: string;
|
expenseType: string;
|
||||||
vatIncluded: boolean;
|
vatIncluded: boolean;
|
||||||
remark: string;
|
remark: string;
|
||||||
|
|
@ -152,6 +156,8 @@ export interface ProductList {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductCreate {
|
export interface ProductCreate {
|
||||||
|
id?: string;
|
||||||
|
selectedImage?: string;
|
||||||
expenseType: string;
|
expenseType: string;
|
||||||
vatIncluded: boolean;
|
vatIncluded: boolean;
|
||||||
productGroupId: string;
|
productGroupId: string;
|
||||||
|
|
@ -168,6 +174,7 @@ export interface ProductCreate {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProductUpdate {
|
export interface ProductUpdate {
|
||||||
|
selectedImage?: string;
|
||||||
productGroupId: string;
|
productGroupId: string;
|
||||||
remark: string;
|
remark: string;
|
||||||
serviceCharge: number;
|
serviceCharge: number;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue