feat: เพิ่ม crud ของผ type

This commit is contained in:
Net 2024-06-17 17:59:09 +07:00
parent 28777069a1
commit f4df07ea24

View file

@ -13,6 +13,7 @@ import ButtonAddComponent from 'src/components/ButtonAddCompoent.vue';
import BasicInfoProduct from 'src/components/04_product-service/ฺBasicInfoProduct.vue';
import PriceDataComponent from 'src/components/04_product-service/PriceDataComponent.vue';
import ProfileUpload from 'src/components/ProfileUpload.vue';
import TotalProductCardComponent from 'components/04_product-service/TotalProductCardComponent.vue';
import { Status } from 'src/stores/types';
import NoData from 'components/NoData.vue';
@ -23,11 +24,14 @@ import useProductServiceStore from 'src/stores/product-service';
import {
ProductGroup,
ProductGroupCreate,
ProductCreate,
ProductList,
} from 'src/stores/product-service/types';
const productServiceStore = useProductServiceStore();
const {
fetchStatsProductType,
createProductServiceType,
editProductServiceType,
deleteProductServiceType,
@ -38,6 +42,9 @@ const {
createProductService,
editProductService,
deleteProductService,
fetchListProduct,
createProduct,
} = productServiceStore;
import ItemCard from 'src/components/ItemCard.vue';
@ -73,20 +80,35 @@ const profileUrl = ref<string | null>('');
const groupName = ref<string>('งาน MOU');
const dialogProductServiceType = ref<boolean>(false);
const dialogTotalProduct = ref<boolean>(false);
const dialogTotalProduct = ref<boolean>(true);
const productMode = ref<'group' | 'type' | 'service' | 'product'>('group');
const productGroup = ref<ProductGroup[]>();
const productType = ref<ProductGroup[]>();
const product = ref<ProductList[]>();
const productAndServiceTab = ref<string>('all');
const previousValue = ref();
const formData = ref<ProductGroupCreate>({
const formDataGroup = ref<ProductGroupCreate>({
remark: '',
detail: '',
name: '',
code: '',
});
const formDataProduct = ref<ProductCreate>({
productTypeId: '',
remark: '',
serviceCharge: 0,
agentPrice: 0,
price: 0,
process: 0,
detail: '',
name: '',
code: '',
});
const currentId = ref<string>('');
const currentIdType = ref<string>('');
const resultSearchGroup = ref<ProductGroup[]>();
@ -127,6 +149,12 @@ async function searchGroup() {
async function fetchListType() {
const res = await fetchListProductServiceType({
productGroupId: currentId.value,
status:
currentStatus.value === 'All'
? undefined
: currentStatus.value === 'ACTIVE'
? 'ACTIVE'
: 'INACTIVE',
});
if (res) {
@ -135,13 +163,28 @@ async function fetchListType() {
}
async function fetchListGroups() {
const res = await fetchListProductService();
const res = await fetchListProductService({
status:
currentStatus.value === 'All'
? undefined
: currentStatus.value === 'ACTIVE'
? 'ACTIVE'
: 'INACTIVE',
});
if (res) {
productGroup.value = res;
}
}
async function fetchListOfProduct(productTypeId: string) {
const res = await fetchListProduct({ productTypeId });
if (res) {
product.value = res.result;
}
}
async function searchType() {
const res = await await fetchListProductServiceType({
query: inputSearch.value,
@ -156,13 +199,20 @@ async function searchType() {
async function submitType() {
if (drawerInfo.value) {
await editProductServiceType(currentIdType.value, {
...formData.value,
...formDataGroup.value,
productGroupId: currentId.value,
});
drawerInfo.value = false;
} else {
dialogInputForm.value = false;
await createProductServiceType(currentId.value, formData.value);
const res = await createProductServiceType(
currentId.value,
formDataGroup.value,
);
if (res) {
stat.value[1].count = stat.value[1].count + 1;
}
}
await fetchListType();
@ -181,7 +231,7 @@ const itemCard = [
},
];
async function deleteProductById() {
async function deleteProductById(productId?: string) {
dialog({
color: 'negative',
icon: 'mdi-alert',
@ -192,11 +242,14 @@ async function deleteProductById() {
action: async () => {
if (productMode.value === 'type') {
// Product Type
await deleteProductServiceType(currentIdType.value);
await deleteProductServiceType(productId ?? currentIdType.value);
await fetchListType();
} else {
stat.value[1].count = stat.value[1].count - 1;
}
if (productMode.value === 'group') {
// Product Group
const res = await deleteProductService(currentId.value);
const res = await deleteProductService(productId ?? currentId.value);
if (res) {
stat.value[0].count = stat.value[0].count - 1;
}
@ -209,7 +262,7 @@ async function deleteProductById() {
}
function undoProductGroup() {
formData.value = {
formDataGroup.value = {
remark: previousValue.value.remark,
detail: previousValue.value.detail,
name: previousValue.value.name,
@ -218,10 +271,10 @@ function undoProductGroup() {
isEdit.value = false;
}
function assignFormData(data: ProductGroup) {
function assignFormDataGroup(data: ProductGroup) {
previousValue.value = data;
formData.value = {
formDataGroup.value = {
remark: data.remark,
detail: data.detail,
name: data.name,
@ -229,8 +282,22 @@ function assignFormData(data: ProductGroup) {
};
}
function clearForm() {
formData.value = {
function assignFormDataProduct(data: ProductList) {
formDataProduct.value = {
productTypeId: data.productTypeId,
remark: data.remark,
serviceCharge: data.serviceCharge,
agentPrice: data.agentPrice,
price: data.price,
process: data.process,
detail: data.detail,
name: data.name,
code: data.code,
};
}
function clearFormGroup() {
formDataGroup.value = {
remark: '',
detail: '',
name: '',
@ -240,11 +307,35 @@ function clearForm() {
dialogInputForm.value = false;
}
function clearFormProduct() {
formDataProduct.value = {
productTypeId: '',
remark: '',
serviceCharge: 0,
agentPrice: 0,
price: 0,
process: 0,
detail: '',
name: '',
code: '',
};
dialogProduct.value = false;
}
async function submitProduct() {
formDataProduct.value.productTypeId = currentIdType.value;
await createProduct(formDataProduct.value);
dialogProduct.value = false;
await fetchListOfProduct(currentIdType.value);
}
async function submitGroup() {
if (drawerInfo.value) {
await editProductService(currentId.value, formData.value);
await editProductService(currentId.value, formDataGroup.value);
} else {
const res = await createProductService(formData.value);
const res = await createProductService(formDataGroup.value);
if (res) {
stat.value[0].count = stat.value[0].count + 1;
@ -253,12 +344,14 @@ async function submitGroup() {
drawerInfo.value = false;
await fetchListGroups();
clearForm();
clearFormGroup();
}
onMounted(async () => {
const resStatsGroup = await fetchStatsProductGroup();
const resStatsType = await fetchStatsProductType();
stat.value[0].count = resStatsGroup ?? 0;
stat.value[1].count = resStatsType ?? 0;
await fetchListGroups();
});
@ -266,7 +359,11 @@ onMounted(async () => {
watch(productMode, () => (inputSearch.value = ''));
watch(currentStatus, async () => {
await fetchListGroups();
if (productMode.value === 'group') {
await fetchListGroups();
} else {
await fetchListType();
}
});
</script>
@ -283,7 +380,7 @@ watch(currentStatus, async () => {
label-position="left"
@click="
() => {
clearForm();
clearFormGroup();
dialogInputForm = true;
}
"
@ -299,7 +396,7 @@ watch(currentStatus, async () => {
icon="mdi-folder-multiple-plus"
@click="
() => {
clearForm();
clearFormGroup();
dialogInputForm = true;
}
"
@ -328,7 +425,7 @@ watch(currentStatus, async () => {
icon="mdi-folder-multiple-plus"
@click="
() => {
clearForm();
clearFormGroup();
dialogInputForm = true;
}
"
@ -341,7 +438,7 @@ watch(currentStatus, async () => {
</div>
<AppBox
v-if="productGroup?.length === 0"
v-if="stat[0].count === 0"
class="column"
:no-padding="productGroup?.length !== 0"
bordered
@ -362,7 +459,7 @@ watch(currentStatus, async () => {
</div>
</AppBox>
<div v-if="productGroup?.length !== 0">
<div v-if="stat[0].count !== 0">
<div
v-if="productMode === 'group'"
class="text-h6 text-weight-bold q-mb-md"
@ -495,6 +592,7 @@ watch(currentStatus, async () => {
</q-btn>
</div>
</div>
<div class="row q-col-gutter-lg">
<div
:class="`${$q.screen.gt.sm ? 'col-3' : $q.screen.gt.xs ? 'col-6' : 'col-12'}`"
@ -515,19 +613,34 @@ watch(currentStatus, async () => {
:date="new Date(v.updatedAt)"
:status="v.status"
color="var(--purple-11-hsl)"
@view-detail="
@viewCard="
() => {
clearForm();
clearFormGroup();
currentIdType = v.id;
assignFormData(v);
assignFormDataGroup(v);
isEdit = false;
drawerInfo = true;
}
"
@on-click="
@updateCard="
() => {
clearFormGroup();
currentIdType = v.id;
assignFormDataGroup(v);
isEdit = true;
drawerInfo = true;
}
"
@deleteCard="
() => {
deleteProductById(v.id);
}
"
@on-click="
async () => {
currentIdType = v.id;
productMode = 'service';
await fetchListOfProduct(currentIdType);
}
"
/>
@ -538,16 +651,30 @@ watch(currentStatus, async () => {
:date="new Date(v.updatedAt)"
:status="v.status"
color="var(--pink-6-hsl)"
@view-detail="
@viewCard="
() => {
clearForm();
assignFormData(v);
clearFormGroup();
assignFormDataGroup(v);
isEdit = false;
currentId = v.id;
drawerInfo = true;
}
"
@updateCard="
() => {
clearFormGroup();
assignFormDataGroup(v);
isEdit = true;
currentId = v.id;
drawerInfo = true;
}
"
@deleteCard="
() => {
deleteProductById(v.id);
}
"
@on-click="
async () => {
currentId = v.id;
@ -559,6 +686,17 @@ watch(currentStatus, async () => {
/>
</div>
</div>
<div
v-if="
(productMode === 'type' && productType?.length === 0) ||
(productGroup?.length === 0 && productMode === 'group')
"
class="flex justify-center items-center"
style="min-height: 70vh; background-color: var(--surface-2)"
>
<NoData />
</div>
</AppBox>
<AppBox bordered v-else-if="productMode === 'service'" no-padding>
<div class="row justify-between q-px-md">
@ -682,12 +820,36 @@ watch(currentStatus, async () => {
</q-btn>
</div>
</div>
<div
v-if="product && product.length === 0"
class="flex justify-center items-center"
style="min-height: 70vh; background-color: var(--surface-2)"
>
<NoData />
</div>
<div
v-if="product && product.length > 0"
class="flex q-pa-md"
style="
min-height: 70vh;
background-color: var(--surface-2);
grid-template-columns: repeat(4, 1fr);
gap: var(--size-3);
"
>
<div v-for="i in product" :key="i.id">
<TotalProductCardComponent
typeProduct="product"
:title="i.name"
:code="i.code"
:price="i.price"
:process="i.process"
@viewDetail="() => {}"
/>
</div>
</div>
</AppBox>
</div>
</div>
@ -703,9 +865,9 @@ watch(currentStatus, async () => {
<BasicInformation
dense
:isType="productMode === 'type'"
v-model:remark="formData.remark"
v-model:name="formData.name"
v-model:detail="formData.detail"
v-model:remark="formDataGroup.remark"
v-model:name="formDataGroup.name"
v-model:detail="formDataGroup.detail"
/>
</template>
</FormDialog>
@ -727,10 +889,10 @@ watch(currentStatus, async () => {
dense
:isType="productMode === 'type'"
:readonly="!isEdit"
v-model:remark="formData.remark"
v-model:name="formData.name"
v-model:code="formData.code"
v-model:detail="formData.detail"
v-model:remark="formDataGroup.remark"
v-model:name="formDataGroup.name"
v-model:code="formDataGroup.code"
v-model:detail="formDataGroup.detail"
/>
</AppBox>
</template>
@ -796,6 +958,7 @@ watch(currentStatus, async () => {
<TotalProductComponent />
</FormDialog>
<!-- Add Product -->
<FormDialog
v-model:modal="dialogProduct"
noAddress
@ -803,7 +966,7 @@ watch(currentStatus, async () => {
title="เพิ่มสินค้า"
:submit="
() => {
console.log('submit');
submitProduct();
}
"
:close="
@ -823,8 +986,65 @@ watch(currentStatus, async () => {
</template>
<AppBox class="col-10" bordered>
<BasicInfoProduct dense separator />
<PriceDataComponent dense />
<BasicInfoProduct
v-model:detail="formDataProduct.detail"
v-model:remark="formDataProduct.remark"
v-model:name="formDataProduct.name"
v-model:code="formDataProduct.code"
dense
separator
/>
<PriceDataComponent
v-model:price="formDataProduct.price"
v-model:agent-price="formDataProduct.agentPrice"
v-model:service-charge="formDataProduct.serviceCharge"
dense
/>
</AppBox>
</FormDialog>
<!-- edit product -->
<FormDialog
v-model:modal="dialogProduct"
noAddress
noAppBox
title="แก้ไข"
:submit="
() => {
submitProduct();
}
"
:close="
() => {
dialogProduct = false;
}
"
>
<template #prepend>
<ProfileUpload
isProduct
v-model:url-profile="profileUrl"
v-model:status-toggle="statusToggle"
v-model:profile-submit="profileSubmit"
@input-file="inputFile.click()"
/>
</template>
<AppBox class="col-10" bordered>
<BasicInfoProduct
v-model:detail="formDataProduct.detail"
v-model:remark="formDataProduct.remark"
v-model:name="formDataProduct.name"
v-model:code="formDataProduct.code"
dense
separator
/>
<PriceDataComponent
v-model:price="formDataProduct.price"
v-model:agent-price="formDataProduct.agentPrice"
v-model:service-charge="formDataProduct.serviceCharge"
dense
/>
</AppBox>
</FormDialog>
</template>