feat: เพิ่ม crud ของผ type
This commit is contained in:
parent
28777069a1
commit
f4df07ea24
1 changed files with 260 additions and 40 deletions
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue