update

parent 1c90e72f
...@@ -128,4 +128,6 @@ export enum API_PATHS { ...@@ -128,4 +128,6 @@ export enum API_PATHS {
getListRegister = 'artist/getListRegister', getListRegister = 'artist/getListRegister',
accountArtistBrowsing = 'customer/accountArtistBrowsing', accountArtistBrowsing = 'customer/accountArtistBrowsing',
detailRegisterArtist = 'artist/detailRegister', detailRegisterArtist = 'artist/detailRegister',
listBookingNotApproval = 'booking/notApproval',
bookingBrowsing = 'booking/bookingBrowsing'
} }
<template>
<q-dialog persistent :model-value="openDialogRefusedBrowser">
<q-card style="min-width: 900px" bordered>
<q-form greedy @submit.prevent="confirmRefusedCustomer">
<q-card-section style="padding-bottom: 10px">
<q-item style="padding-left: 10px">
<q-item-section>
<q-item-label class="text-h6 text-weight-regular"
>Lý do</q-item-label
>
</q-item-section>
</q-item>
</q-card-section>
<q-card-section style="padding-top: 0px">
<q-input
outlined
hide-bottom-space
:rules="contentRules"
v-model="content"
label="Nội dung"
type="textarea"
/>
</q-card-section>
<q-card-actions align="right">
<q-btn
color="grey"
no-caps
style="width: 90px"
label="Hủy"
@click="$emit('click:CloseBtn')"
/>
<q-btn
type="submit"
color="primary"
no-caps
style="width: 90px"
label="Ok"
/>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>
<script lang="ts">
import { defineComponent, PropType, Ref, ref, watch } from 'vue';
import { Dialog, Notify } from 'quasar';
import { API_PATHS, config } from 'src/assets/configurations.example';
import { AxiosResponse } from 'axios';
import { api, BaseResponseBody } from 'src/boot/axios';
import { emit } from 'cluster';
export default defineComponent({
props: {
openDialogRefusedBrowser: {
type: Boolean,
required: true,
},
id: {
type: Number,
required: true,
},
},
setup(props, context) {
watch(
() => props.openDialogRefusedBrowser,
(value) => {
if (value) {
content.value = null;
}
}
);
const content: Ref<string | null> = ref(null);
const contentRules = [
(val?: string) => (val && val.trim().length) || 'Vui lòng nhập nội dung',
];
const confirmRefusedCustomer = async () => {
try {
const browserResult = (await api({
url: API_PATHS.bookingBrowsing,
method: 'POST',
data: {
id: props.id,
approvalStatus: 2,
reason: content.value,
},
})) as AxiosResponse<BaseResponseBody<unknown>>;
if (browserResult.data.error.code === config.API_RES_CODE.OK.code) {
Notify.create({
type: 'positive',
message: 'Từ chối duyệt thành công',
actions: [{ icon: 'close', color: 'white' }],
});
context.emit('editReCustomer');
context.emit('click:CloseBtn');
}
} catch (error) {}
};
return {
contentRules,
content,
confirmRefusedCustomer,
};
},
emits: ['click:CloseBtn', 'editReCustomer'],
});
</script>
<template> <template>
<div>
<q-dialog
persistent
:model-value="showDialogUpdate"
@update:model-value="$emit('update:showDialogUpdate', $event)"
>
<q-card style="min-width: 900px" bordered>
<q-form greedy @submit.prevent="confirmEditCustomer">
<q-card-section>
<q-item>
<q-item-section>
<q-item-label class="text-h6 text-weight-regular"
>Duyệt thông tin khách hàng</q-item-label
>
</q-item-section>
</q-item>
</q-card-section>
<q-separator />
<div> <q-card-section>
<q-dialog <div class="row q-col-gutter-sm">
persistent <div class="col-6">
:model-value="showDialogUpdate" <q-input
@update:model-value="$emit('update:showDialogUpdate', $event)" v-model="userName"
> :label="$t('customer.dialogLabel.fieldLabels.userName')"
<q-card style="min-width: 900px" bordered> :rules="userNameRules"
<q-form greedy @submit.prevent="confirmEditCustomer"> hide-bottom-space
<q-card-section> type="text"
<q-item> class="q-my-sm"
<q-item-section> outlined
<q-item-label class="text-h6 text-weight-regular">Duyệt thông tin khách hàng</q-item-label> readonly
</q-item-section> ></q-input>
</q-item> <q-input
</q-card-section> v-model="password"
<q-separator /> :label="$t('customer.dialogLabel.fieldLabels.password')"
:rules="passwordRules"
<q-card-section> outlined
<div class="row q-col-gutter-sm"> :type="isPwd ? 'password' : 'text'"
<div class="col-6"> class="q-my-sm"
<q-input autocomplete="new-password"
v-model="userName" hide-bottom-space
:label="$t('customer.dialogLabel.fieldLabels.userName')" >
:rules="userNameRules" <template v-slot:append>
hide-bottom-space <q-icon
type="text" :name="isPwd ? 'visibility_off' : 'visibility'"
class="q-my-sm" class="cursor-pointer"
outlined @click="isPwd = !isPwd"
readonly /> </template
></q-input> ></q-input>
<q-input <!-- <q-input
v-model="password"
:label="$t('customer.dialogLabel.fieldLabels.password')"
:rules="passwordRules"
outlined
:type="isPwd ? 'password' : 'text'"
class="q-my-sm"
autocomplete="new-password"
hide-bottom-space
>
<template v-slot:append>
<q-icon
:name="isPwd ? 'visibility_off' : 'visibility'"
class="cursor-pointer"
@click="isPwd = !isPwd"
/> </template
></q-input>
<q-input
v-model="code" v-model="code"
label="Mã khách hàng" label="Mã khách hàng"
...@@ -56,8 +57,8 @@ ...@@ -56,8 +57,8 @@
class="q-my-sm" class="q-my-sm"
outlined outlined
readonly readonly
></q-input> ></q-input> -->
<q-input <!-- <q-input
v-model="fullName" v-model="fullName"
:label="$t('customer.dialogLabel.fieldLabels.customerName')" :label="$t('customer.dialogLabel.fieldLabels.customerName')"
type="text" type="text"
...@@ -65,132 +66,132 @@ ...@@ -65,132 +66,132 @@
outlined outlined
:rules="customerNameRules" :rules="customerNameRules"
hide-bottom-space hide-bottom-space
></q-input> ></q-input> -->
<q-input <q-input
v-model="companyName" v-model="companyName"
:label="$t('customer.dialogLabel.fieldLabels.businessName')" :label="$t('customer.dialogLabel.fieldLabels.businessName')"
type="text" type="text"
class="q-my-sm" class="q-my-sm"
outlined outlined
:rules="businessNameRules" :rules="businessNameRules"
hide-bottom-space hide-bottom-space
></q-input> ></q-input>
<q-input <q-input
v-model="taxCode" v-model="taxCode"
label="Mã số thuế" label="Mã số thuế"
type="text" type="text"
class="q-my-sm" class="q-my-sm"
outlined outlined
hide-bottom-space
hide-bottom-space ></q-input>
></q-input> <q-input
<q-input v-model="address"
v-model="address" :label="$t('customer.dialogLabel.fieldLabels.address')"
:label="$t('customer.dialogLabel.fieldLabels.address')" type="text"
type="text" class="q-my-sm"
class="q-my-sm" :rules="addressRules"
:rules="addressRules" outlined
outlined hide-bottom-space
hide-bottom-space ></q-input>
></q-input> </div>
</div> <div class="col-6">
<div class="col-6"> <q-input
<q-input v-model="email"
v-model="email" :label="$t('customer.dialogLabel.fieldLabels.email')"
:label="$t('customer.dialogLabel.fieldLabels.email')" type="text"
type="text" class="q-my-sm"
class="q-my-sm" outlined
outlined :rules="emailRules"
:rules="emailRules" hide-bottom-space
hide-bottom-space ></q-input>
></q-input> <q-input
<q-input v-model="type"
v-model="type" label="Loại doanh nghiệp"
label="Loại doanh nghiệp" emit-value
map-options
emit-value option-value="id"
map-options option-label="text"
option-value="id" class="q-my-sm"
option-label="text" outlined
class="q-my-sm" hide-bottom-space
outlined ></q-input>
hide-bottom-space <q-select
></q-input> v-model="level"
<q-select :label="$t('customer.dialogLabel.fieldLabels.ratings')"
v-model="level" :options="levelOptions"
:label="$t('customer.dialogLabel.fieldLabels.ratings')" :rules="levelRules"
:options="levelOptions" map-options
:rules="levelRules" option-value="id"
map-options option-label="name"
option-value="id" type="text"
option-label="name" class="q-my-sm"
type="text" outlined
class="q-my-sm" clearable
outlined hide-bottom-space
clearable ></q-select>
hide-bottom-space
></q-select>
<q-input <q-input
v-model="representative" v-model="representative"
:label="$t('customer.dialogLabel.fieldLabels.representative')" :label="$t('customer.dialogLabel.fieldLabels.representative')"
class="q-my-sm" class="q-my-sm"
type="text" type="text"
outlined outlined
:rules="representativeRules" :rules="representativeRules"
hide-bottom-space hide-bottom-space
></q-input> ></q-input>
<q-input <q-input
v-model="position" v-model="position"
:label="$t('customer.dialogLabel.fieldLabels.position')" :label="$t('customer.dialogLabel.fieldLabels.position')"
class="q-my-sm" class="q-my-sm"
type="text" type="text"
outlined outlined
:rules="positionRules" :rules="positionRules"
hide-bottom-space hide-bottom-space
></q-input> ></q-input>
<q-input <q-input
v-model="phone" v-model="phone"
:label="$t('customer.dialogLabel.fieldLabels.phone')" :label="$t('customer.dialogLabel.fieldLabels.phone')"
class="q-my-sm" class="q-my-sm"
mask="##########" mask="##########"
:rules="phoneRules" :rules="phoneRules"
outlined outlined
hide-bottom-space hide-bottom-space
></q-input> ></q-input>
<div style="padding-top: 13px; padding-left: 12px"> <div style="padding-top: 13px; padding-left: 12px">
<span class="text-body1">{{ <span class="text-body1">{{
$t('customer.dialogLabel.fieldLabels.status') $t('customer.dialogLabel.fieldLabels.status')
}}</span }}</span
><q-toggle :true-value="1" :false-value="2" v-model="status" /> ><q-toggle
:true-value="1"
:false-value="2"
v-model="status"
/>
</div>
</div> </div>
</div> </div>
</div> </q-card-section>
</q-card-section> <q-card-actions align="right">
<q-card-actions align="right"> <q-btn
<q-btn color="grey"
color="grey" no-caps
no-caps style="width: 90px"
style="width: 90px" :label="$t('customer.crudActions.cancel')"
:label="$t('customer.crudActions.cancel')" @click="$emit('click:CloseBtn')"
@click="$emit('click:CloseBtn')" />
/> <q-btn
<q-btn type="submit"
type="submit" color="primary"
color="primary" no-caps
no-caps style="width: 90px"
style="width: 90px" :label="$t('customer.crudActions.save')"
:label="$t('customer.crudActions.save')" />
/> </q-card-actions>
</q-card-actions> </q-form>
</q-form> </q-card>
</q-card> </q-dialog>
</q-dialog> </div>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, PropType, Ref, ref, watch } from 'vue'; import { defineComponent, PropType, Ref, ref, watch } from 'vue';
import { i18n } from 'src/boot/i18n'; import { i18n } from 'src/boot/i18n';
...@@ -198,7 +199,7 @@ import { isEmail } from '../../boot/functions'; ...@@ -198,7 +199,7 @@ import { isEmail } from '../../boot/functions';
import { isMobilePhone } from '../../boot/functions'; import { isMobilePhone } from '../../boot/functions';
import { CustomerLevelType, CustomerType } from 'src/assets/type'; import { CustomerLevelType, CustomerType } from 'src/assets/type';
export default defineComponent({ export default defineComponent({
props: { props: {
showDialogUpdate: { showDialogUpdate: {
type: Boolean, type: Boolean,
required: true, required: true,
...@@ -208,9 +209,9 @@ export default defineComponent({ ...@@ -208,9 +209,9 @@ export default defineComponent({
required: true, required: true,
}, },
customerInfo: { type: Object as PropType<CustomerType>, required: true }, customerInfo: { type: Object as PropType<CustomerType>, required: true },
}, },
setup(props, context) { setup(props, context) {
watch( watch(
() => props.showDialogUpdate, () => props.showDialogUpdate,
(value) => { (value) => {
...@@ -242,7 +243,7 @@ export default defineComponent({ ...@@ -242,7 +243,7 @@ export default defineComponent({
userName: userName.value, userName: userName.value,
fullName: fullName.value, fullName: fullName.value,
companyName: companyName.value, companyName: companyName.value,
taxCode: taxCode.value, taxCode: taxCode.value,
email: email.value, email: email.value,
status: status.value, status: status.value,
...@@ -253,7 +254,6 @@ export default defineComponent({ ...@@ -253,7 +254,6 @@ export default defineComponent({
representative: representative.value, representative: representative.value,
position: position.value, position: position.value,
level: level.value, level: level.value,
}); });
}; };
const getData = () => { const getData = () => {
...@@ -349,12 +349,12 @@ export default defineComponent({ ...@@ -349,12 +349,12 @@ export default defineComponent({
customerNameRules, customerNameRules,
businessNameRules, businessNameRules,
passwordRules, passwordRules,
// codeRules, // codeRules,
// taxCodeRules, // taxCodeRules,
emailRules, emailRules,
levelRules, levelRules,
addressRules, addressRules,
// businessTypeRules, // businessTypeRules,
representativeRules, representativeRules,
positionRules, positionRules,
phoneRules, phoneRules,
...@@ -376,5 +376,5 @@ export default defineComponent({ ...@@ -376,5 +376,5 @@ export default defineComponent({
id, id,
}; };
}, },
}) });
</script> </script>
\ No newline at end of file
...@@ -56,7 +56,7 @@ export default defineComponent({ ...@@ -56,7 +56,7 @@ export default defineComponent({
type: Boolean, type: Boolean,
required: true, required: true,
}, },
customerId: { id: {
type: Number, type: Number,
required: true, required: true,
}, },
...@@ -78,11 +78,11 @@ export default defineComponent({ ...@@ -78,11 +78,11 @@ export default defineComponent({
const confirmRefusedCustomer = async () => { const confirmRefusedCustomer = async () => {
try { try {
const browserResult = (await api({ const browserResult = (await api({
url: API_PATHS.customerNotBrowsing, url: API_PATHS.bookingBrowsing,
method: 'POST', method: 'POST',
data: { data: {
id: props.customerId, id: props.id,
isCustomer: 1,
approvalStatus: 2, approvalStatus: 2,
reason: content.value, reason: content.value,
}, },
......
<template>
<div class="row q-col-gutter-sm flex-center q-mt-sm">
<!-- <div class="col-auto text-h6 text-weight-regular flex flex-center q-mr-md">
{{ $t('listBooking.title') }}
<q-separator vertical spaced />
</div> -->
<q-space></q-space>
<div class="col-2 sreach">
<q-select
v-model="sreachArtist"
:options="artistOptions"
option-label="artistName"
option-value="id"
dense
outlined
:label="$t('listBooking.titleColumnsTable.artistName')"
clearable
></q-select>
</div>
<div class="col-2 sreach">
<q-select
v-model="sreachUserName"
:options="customerOptions"
option-label="fullName"
option-value="id"
dense
outlined
:label="$t('listBooking.titleColumnsTable.userName')"
clearable
></q-select>
</div>
<div class="col-2 sreach">
<q-select
v-model="sreachStatus"
:options="ListStatusBooking"
option-label="name"
option-value="id"
dense
outlined
:label="$t('listBooking.titleColumnsTable.status')"
clearable
></q-select>
</div>
<div class="col-2 sreach">
<q-select
v-model="sreachPerformStatus"
:options="ListPerformStatus"
option-label="name"
option-value="id"
dense
outlined
:label="$t('listBooking.titleColumnsTable.performStatus')"
clearable
></q-select>
</div>
<div class="col-2 sreach">
<q-input
v-model="date[0]"
:label="$t('listBooking.titleColumnsTable.fromTime')"
readonly
dense
outlined
>
<template v-slot:append>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy
ref="qDateProxy"
transition-show="scale"
transition-hide="scale"
>
<q-date v-model="date[0]" mask="DD/MM/YYYY" no-unset>
<div class="row items-center justify-end">
<q-btn
v-close-popup
:label="$t('listBooking.crudActions.cancel')"
color="primary"
flat
></q-btn>
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</div>
<div class="col-2 sreach">
<q-input
v-model="date[1]"
:label="$t('listBooking.titleColumnsTable.toTime')"
readonly
dense
outlined
>
<template v-slot:append>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy
ref="qDateProxy"
transition-show="scale"
transition-hide="scale"
>
<q-date v-model="date[1]" mask="DD/MM/YYYY" no-unset>
<div class="row items-center justify-end">
<q-btn
v-close-popup
:label="$t('listBooking.crudActions.cancel')"
color="primary"
flat
></q-btn>
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</div>
<div class="col-auto">
<q-btn
class="q-mr-sm"
color="primary"
no-caps
@click="getListBooking"
:label="$t('crudActions.search')"
style="width: 100px"
>
</q-btn>
</div>
<div class="col-12 q-mt-sm">
<q-table
:rows="listBooking"
:columns="tableColumns"
:no-data-label="$t('emptyData')"
row-key="name"
separator="cell"
:rows-per-page-label="$t('recordPerPage')"
:pagination="{
rowsPerPage: 0,
}"
wrap-cells
hide-pagination
class="sticky-header-table"
>
<template v-slot:body-cell-action="rowData">
<q-td style="padding: 0; text-align: center">
<q-btn
flat
round
color="primary"
icon="mdi-check-circle-outline"
@click="confirmDeleteCustomer(rowData.row.id)"
>
<q-tooltip :offset="[20, 10]">Duyệt</q-tooltip>
</q-btn>
<q-btn
v-if="rowData.row.approvalStatus === 0"
flat
round
size="1em"
color="primary"
icon="mdi-block-helper"
@click="confirmRefusedBrowserCustomer(rowData.row.id)"
>
<q-tooltip>Từ chối</q-tooltip>
</q-btn>
<q-btn
flat
round
color="primary"
icon="mdi-information-outline"
@click="detail(rowData.row.id)"
>
<q-tooltip :offset="[10, 10]">{{
$t('listBooking.toolTipMessage')
}}</q-tooltip>
</q-btn>
</q-td>
</template>
<template v-slot:body-cell-stt="item">
<q-td :item="item" style="text-align: center">
{{ 1 + item.rowIndex + pageSize * (pageIndex - 1) }}
</q-td>
</template>
<template v-slot:body-cell-status="item">
<q-td align="center">
<template v-for="(data, idx) in ListStatusBooking">
<q-chip
v-if="item.row.status === data.id"
:key="`status-${idx}-${item}`"
size="sm"
label
:color="data.color"
>{{ data.name }}</q-chip
>
</template>
</q-td>
</template>
<template v-slot:body-cell-approvalStatus="rowData">
<q-td>
<div align="center">
<q-chip
v-if="rowData.value === 0"
color="orange"
text-color="white"
size="sm"
>
Chưa duyệt
</q-chip>
<q-chip
v-if="rowData.value === 2"
color="red"
text-color="white"
size="sm"
>
Từ chối duyệt
</q-chip>
</div>
</q-td>
</template>
<template v-slot:body-cell-performStatus="item">
<q-td align="center">
<template v-for="(data, idx) in ListPerformStatus">
<q-chip
v-if="item.row.performStatus === data.id"
:key="`performStatus-${idx}-${item}`"
size="sm"
label
:color="data.color"
>{{ data.name }}</q-chip
>
</template>
</q-td>
</template>
<template v-slot:body-cell-content="item">
<td>
<div class="ellipsis-3-lines">
{{ !item.row.content ? '' : item.row.content }}
<q-tooltip :offset="[10, 10]" max-width="35%">{{
!item.row.content ? '' : item.row.content
}}</q-tooltip>
</div>
</td>
</template>
</q-table>
</div>
<div class="col-12 q-mt-sm">
<Pagination
v-model:currentPage="pageIndex"
v-model:pageSize="pageSize"
:totalPage="totalPage"
@update:pageSize="changePageSize"
@update:currentPage="getListBooking"
/>
<detailBooking
v-model:show-dialog="showDialog"
:detail-info-booking="detailInfoBooking"
@click:CloseBtn="showDialog = false"
></detailBooking>
<RefusedBrowser
:id="idBooking"
v-model:open-dialog-refused-browser="openDialogRefusedBrowser"
@click:CloseBtn="openDialogRefusedBrowser = false"
@editReCustomer="getListBooking"
>
</RefusedBrowser>
</div>
</div>
</template>
<script lang="ts">
import { api, BaseResponseBody } from 'src/boot/axios';
import { config, API_PATHS } from 'src/assets/configurations.example';
import RefusedBrowser from '../../components/booking/openDialogRefusedBrowser.vue';
import { AxiosResponse } from 'axios';
import { i18n } from 'src/boot/i18n';
import { defineComponent, onMounted, Ref, ref } from 'vue';
import Pagination from 'components/pagination/index.vue';
import {
PaginationResponse,
ListBooking,
ListArrayArtist,
ListArrayCust,
} from 'src/assets/type';
import detailBooking from '../../components/detailBooking/index.vue';
import { Dialog, Notify } from 'quasar';
import moment from 'moment';
export default defineComponent({
components: {
detailBooking,
Pagination,
RefusedBrowser,
},
setup() {
const tableColumns = [
{
name: 'stt',
field: 'stt',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.stt'),
headerStyle: 'text-align: center !important; width: 4%',
align: 'center',
sortable: false,
},
{
name: 'bookingCode',
field: 'bookingCode',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.bookingCode'),
headerStyle: 'text-align: center !important; width: 4%',
align: 'center',
sortable: false,
},
{
name: 'artistName',
field: 'artistName',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.artistName'),
align: 'left',
headerStyle: 'text-align: center !important; width: 9%',
sortable: false,
},
{
name: 'userName',
field: 'userName',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.userName'),
headerStyle: 'text-align: center !important; width: 9%',
align: 'left',
sortable: false,
},
{
name: 'address',
field: 'address',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.address'),
headerStyle: 'text-align: center !important; width: 13%',
align: 'left',
sortable: false,
},
// {
// name: 'content',
// field: 'content',
// required: true,
// label: i18n.global.t('listBooking.titleColumnsTable.content'),
// headerStyle: 'text-align: center !important; width: 13%',
// align: 'left',
// sortable: false,
// },
{
name: 'fromTime',
field: 'fromTime',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.fromTime'),
headerStyle: 'text-align: center !important; width: 9%',
align: 'left',
sortable: false,
},
{
name: 'toTime',
field: 'toTime',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.toTime'),
headerStyle: 'text-align: center !important; width: 9%',
align: 'left',
sortable: false,
},
{
name: 'fee',
field: 'fee',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.fee'),
headerStyle: 'text-align: center !important; width: 9%',
align: 'left',
sortable: false,
},
// {
// name: 'favoriteScore',
// field: 'favoriteScore',
// required: true,
// label: i18n.global.t('listBooking.titleColumnsTable.favoriteScore'),
// headerStyle: 'text-align: center !important; width: 7%',
// align: 'center',
// sortable: false,
// },
{
name: 'status',
field: 'status',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.status'),
headerStyle: 'text-align: center !important; width: 8%',
align: 'center',
sortable: false,
},
{
name: 'performStatus',
field: 'performStatus',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.performStatus'),
headerStyle: 'text-align: center !important; width: 8%',
align: 'center',
sortable: false,
},
{
name: 'approvalStatus',
field: 'approvalStatus',
required: true,
label: 'T.T Duyệt',
headerStyle: 'text-align: center !important; width: 10%',
align: 'center',
sortable: false,
},
{
name: 'action',
field: 'action',
required: true,
label: i18n.global.t('listBooking.titleColumnsTable.action'),
headerStyle: 'text-align: center !important; width: 13%',
align: 'center',
sortable: false,
},
];
const ListStatusBooking = ref([
{ id: 0, name: 'Chờ nhận', color: 'secondary' },
{ id: 1, name: 'Đã nhận', color: 'info' },
{ id: 2, name: 'Từ chối', color: 'warning' },
]);
const ListPerformStatus = ref([
{ id: 0, name: 'Chờ nhận', color: 'secondary' },
{ id: 1, name: 'Đã thực hiện', color: 'info' },
{ id: 2, name: 'Chưa thực hiện', color: 'warning' },
{ id: 3, name: 'Hoãn lịch', color: 'warning' },
{ id: 4, name: 'Hủy lịch', color: 'warning' },
{ id: 5, name: 'Thay đổi lịch', color: 'secondary' },
]);
const showDialog = ref(false);
const openDialogRefusedBrowser = ref(false);
const idBooking: Ref<number | null> = ref(null);
const detailInfoBooking: Ref<ListBooking | null> = ref(null);
const listBooking: Ref<unknown[]> = ref([]);
const pageIndex = ref(1);
const pageSize = ref(20);
const totalPage = ref(1);
const sreachArtist: Ref<ListArrayArtist | null> = ref(null);
const sreachUserName: Ref<ListArrayArtist | null> = ref(null);
const sreachStatus: Ref<
{ id: number; name: string; color: string } | undefined
> = ref(undefined);
const sreachPerformStatus: Ref<
{ id: number; name: string; color: string } | undefined
> = ref(undefined);
const changePageSize = () => {
pageIndex.value = 1;
void getListBooking();
};
const confirmRefusedBrowserCustomer = (id: number) => {
idBooking.value = id;
openDialogRefusedBrowser.value = true;
};
const confirmDeleteCustomer = (id: number) => {
Dialog.create({
title: i18n.global.t(
'customer.confirmActionsTitle.confirmDeleteUserTitle'
),
message: i18n.global.t('Bạn có chắc muốn duyệt booking này không?'),
cancel: i18n.global.t(
'customer.confirmActionsTitle.confirmDeleteUserCancelBtnLabel'
),
color: 'negative',
}).onOk(() => {
void deleteCustomer(id);
});
};
const deleteCustomer = async (id: number) => {
try {
const deleteResult = (await api({
url: API_PATHS.bookingBrowsing,
method: 'POST',
data: {
id: id,
approvalStatus: 1,
reason: null,
},
})) as AxiosResponse<BaseResponseBody<unknown>>;
if (deleteResult.data.error.code === config.API_RES_CODE.OK.code) {
Notify.create({
type: 'positive',
message: i18n.global.t('customer.actionMessages.deleteUserAccess'),
actions: [{ icon: 'close', color: 'white' }],
});
void getListBooking();
}
} catch (error) {}
};
const date = ref([
moment(new Date()).format('DD/MM/YYYY'),
moment(new Date()).add(7, 'days').format('DD/MM/YYYY'),
]);
const changeTime = () => {
const startTime = Number(
moment(date.value[0], 'DD/MM/YYYY').format('YYYYMMDD')
);
const endTime = Number(
moment(date.value[1], 'DD/MM/YYYY').format('YYYYMMDD')
);
if (startTime > endTime) {
date.value = [date.value[1], date.value[0]];
}
};
const artistOptions: Ref<ListArrayArtist[] | null> = ref([]);
const customerOptions: Ref<ListArrayCust[] | null> = ref([]);
const getArrayArtist = async () => {
const response = (await api({
url: API_PATHS.getArrayArtist,
method: 'GET',
params: {},
})) as AxiosResponse<BaseResponseBody<ListArrayArtist[]>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
artistOptions.value = response.data.data;
}
};
const getArrayCust = async () => {
const response = (await api({
url: API_PATHS.getArrayCust,
method: 'GET',
params: {},
})) as AxiosResponse<BaseResponseBody<ListArrayCust[]>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
customerOptions.value = response.data.data;
}
};
const getListBooking = async () => {
try {
const response = (await api({
url: API_PATHS.listBookingNotApproval,
method: 'GET',
params: {
pageIndex: pageIndex.value,
pageSize: pageSize.value,
artistId: sreachArtist.value?.id,
custId: sreachUserName.value?.id,
status: sreachStatus.value?.id,
performStatus: sreachPerformStatus.value?.id,
fromTime: moment(date.value[0], 'DD/MM/YYYY').format('DD/MM/YYYY'),
toTime: moment(date.value[1], 'DD/MM/YYYY').format('DD/MM/YYYY'),
},
})) as AxiosResponse<BaseResponseBody<PaginationResponse<ListBooking>>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
listBooking.value = response.data.data.data;
totalPage.value = response.data.data.totalPages;
}
} catch (error) {}
};
const getDetail = async (id: number) => {
try {
const response = (await api({
url: API_PATHS.getBookingDetail,
method: 'GET',
params: {
id: id,
},
})) as AxiosResponse<BaseResponseBody<ListBooking>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
detailInfoBooking.value = response.data.data;
showDialog.value = true;
}
} catch (error) {}
};
const detail = (id: number) => {
void getDetail(id);
};
// const filterOrganizational = (
// val: string, update: (fn : () => void) => void
// ) => {
// if (!val) {
// update(() => {
// organizationalList.value = [...filterArrayOrganizational.value];
// });
// return;
// } else {
// update(() => {
// const needle = val.toLowerCase();
// organizationalList.value = filterArrayOrganizational.value.filter(
// (item: { id: number; name: string }) =>
// item.name.toLowerCase().indexOf(needle) > -1
// );
// });
// }
// };
onMounted(() => {
void getListBooking();
void getArrayArtist();
void getArrayCust();
});
return {
date,
idBooking,
openDialogRefusedBrowser,
changeTime,
customerOptions,
artistOptions,
detailInfoBooking,
showDialog,
detail,
sreachArtist,
sreachUserName,
listBooking,
tableColumns,
pageIndex,
pageSize,
totalPage,
changePageSize,
getListBooking,
ListStatusBooking,
ListPerformStatus,
sreachStatus,
sreachPerformStatus,
confirmDeleteCustomer,
confirmRefusedBrowserCustomer,
};
},
});
</script>
<style lang="scss" scoped>
.sreach {
width: 14rem;
}
</style>
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
$t('customer.toolTipMessage.updateCustomerInfo') $t('customer.toolTipMessage.updateCustomerInfo')
}}</q-tooltip> }}</q-tooltip>
</q-btn> --> </q-btn> -->
<q-btn <q-btn
flat flat
round round
color="primary" color="primary"
...@@ -98,7 +98,7 @@ ...@@ -98,7 +98,7 @@
> >
<q-tooltip :offset="[20, 10]">Duyệt</q-tooltip> <q-tooltip :offset="[20, 10]">Duyệt</q-tooltip>
</q-btn> </q-btn>
<q-btn <q-btn
v-if="rowData.row.approvalStatus === 0" v-if="rowData.row.approvalStatus === 0"
flat flat
round round
...@@ -107,7 +107,7 @@ ...@@ -107,7 +107,7 @@
icon="mdi-block-helper" icon="mdi-block-helper"
@click="confirmRefusedBrowserCustomer(rowData.row.id)" @click="confirmRefusedBrowserCustomer(rowData.row.id)"
> >
<q-tooltip >Từ chối</q-tooltip> <q-tooltip>Từ chối</q-tooltip>
</q-btn> </q-btn>
<!-- <q-btn <!-- <q-btn
flat flat
...@@ -143,23 +143,23 @@ ...@@ -143,23 +143,23 @@
<template v-slot:body-cell-approvalStatus="rowData"> <template v-slot:body-cell-approvalStatus="rowData">
<q-td> <q-td>
<div align="center"> <div align="center">
<q-chip <q-chip
v-if="rowData.value === 0" v-if="rowData.value === 0"
color='orange' color="orange"
text-color="white" text-color="white"
size="sm" size="sm"
> >
Chưa duyệt Chưa duyệt
</q-chip> </q-chip>
<q-chip <q-chip
v-if="rowData.value === 2" v-if="rowData.value === 2"
color="red" color="red"
text-color="white" text-color="white"
size="sm" size="sm"
> >
Từ chối duyệt Từ chối duyệt
</q-chip> </q-chip>
</div> </div>
</q-td> </q-td>
</template> </template>
...@@ -189,14 +189,13 @@ ...@@ -189,14 +189,13 @@
@editCustomer="updateCustomer" @editCustomer="updateCustomer"
></UpdateNewCustomerDialogComponent> ></UpdateNewCustomerDialogComponent>
<RefusedBrowserCustomer <RefusedBrowserCustomer
:customer-id="customerId" :customer-id="customerId"
v-model:open-dialog-refused-browser="openDialogRefusedBrowser" v-model:open-dialog-refused-browser="openDialogRefusedBrowser"
@click:CloseBtn="openDialogRefusedBrowser = false" @click:CloseBtn="openDialogRefusedBrowser = false"
@editReCustomer="getListCustomers" @editReCustomer="getListCustomers"
> >
</RefusedBrowserCustomer> </RefusedBrowserCustomer>
</div> </div>
</div> </div>
</div> </div>
...@@ -208,7 +207,7 @@ import { defineComponent, onMounted, Ref, ref } from 'vue'; ...@@ -208,7 +207,7 @@ import { defineComponent, onMounted, Ref, ref } from 'vue';
import Pagination from 'components/pagination/index.vue'; import Pagination from 'components/pagination/index.vue';
// import AddNewCustomerDialogComponent from '../../components/customer/add-new-customer-dialog/index.vue'; // import AddNewCustomerDialogComponent from '../../components/customer/add-new-customer-dialog/index.vue';
import UpdateNewCustomerDialogComponent from '../../components/customer/browser-new-customer-dialog.vue'; import UpdateNewCustomerDialogComponent from '../../components/customer/browser-new-customer-dialog.vue';
import RefusedBrowserCustomer from '../../components/customer/openDialogRefusedBrowser.vue' import RefusedBrowserCustomer from '../../components/customer/openDialogRefusedBrowser.vue';
import { API_PATHS, config } from 'src/assets/configurations.example'; import { API_PATHS, config } from 'src/assets/configurations.example';
import { AxiosResponse } from 'axios'; import { AxiosResponse } from 'axios';
import { api, BaseResponseBody } from 'src/boot/axios'; import { api, BaseResponseBody } from 'src/boot/axios';
...@@ -307,11 +306,11 @@ export default defineComponent({ ...@@ -307,11 +306,11 @@ export default defineComponent({
align: 'center', align: 'center',
sortable: false, sortable: false,
}, },
{ {
name: 'approvalStatus', name: 'approvalStatus',
field: 'approvalStatus', field: 'approvalStatus',
required: true, required: true,
label: 'T.thái duyệt', label: 'T.T Duyệt',
align: 'center', align: 'center',
sortable: false, sortable: false,
}, },
...@@ -399,11 +398,10 @@ export default defineComponent({ ...@@ -399,11 +398,10 @@ export default defineComponent({
// }); // });
// }; // };
const confirmRefusedBrowserCustomer = (id:number) => { const confirmRefusedBrowserCustomer = (id: number) => {
customerId.value = id customerId.value = id;
openDialogRefusedBrowser.value = true openDialogRefusedBrowser.value = true;
} };
// const deleteCustomer = async (id: number) => { // const deleteCustomer = async (id: number) => {
// try { // try {
...@@ -539,12 +537,12 @@ export default defineComponent({ ...@@ -539,12 +537,12 @@ export default defineComponent({
void getCustomerLevelOptions(); void getCustomerLevelOptions();
}); });
return { return {
// openUpdateCustomerDialog, // openUpdateCustomerDialog,
updateCustomer, updateCustomer,
// openAddCustomerDialog, // openAddCustomerDialog,
// addCustomer, // addCustomer,
showDialogUpdate, showDialogUpdate,
// showDialog, // showDialog,
openDialogRefusedBrowser, openDialogRefusedBrowser,
id, id,
userName, userName,
...@@ -574,11 +572,11 @@ export default defineComponent({ ...@@ -574,11 +572,11 @@ export default defineComponent({
totalPage, totalPage,
changePageSize, changePageSize,
getCustomerLevelOptions, getCustomerLevelOptions,
// confirmDeleteCustomer, // confirmDeleteCustomer,
confirmBrowserCustomer, confirmBrowserCustomer,
customerInfo, customerInfo,
customerId, customerId,
confirmRefusedBrowserCustomer confirmRefusedBrowserCustomer,
}; };
}, },
}); });
......
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
$t('customer.toolTipMessage.updateCustomerInfo') $t('customer.toolTipMessage.updateCustomerInfo')
}}</q-tooltip> }}</q-tooltip>
</q-btn> </q-btn>
<!-- <q-btn <!-- <q-btn
flat flat
round round
color="primary" color="primary"
...@@ -98,7 +98,7 @@ ...@@ -98,7 +98,7 @@
> >
<q-tooltip :offset="[20, 10]">Duyệt tài khoản</q-tooltip> <q-tooltip :offset="[20, 10]">Duyệt tài khoản</q-tooltip>
</q-btn> --> </q-btn> -->
<!-- <q-btn <!-- <q-btn
flat flat
round round
color="primary" color="primary"
...@@ -137,7 +137,20 @@ ...@@ -137,7 +137,20 @@
</div> </div>
</q-td> </q-td>
</template> </template>
<template v-slot:body-cell-approvalStatus="rowData">
<q-td>
<div align="center">
<q-chip
v-if="rowData.value === 1"
color="positive"
text-color="white"
size="sm"
>
Duyệt
</q-chip>
</div>
</q-td>
</template>
<!-- <template v-slot:body-cell-approvalStatus="rowData"> <!-- <template v-slot:body-cell-approvalStatus="rowData">
<q-td> <q-td>
<div align="center"> <div align="center">
...@@ -188,7 +201,6 @@ ...@@ -188,7 +201,6 @@
@editReCustomer="getListCustomers" @editReCustomer="getListCustomers"
> >
</RefusedBrowserCustomer> --> </RefusedBrowserCustomer> -->
</div> </div>
</div> </div>
</div> </div>
...@@ -299,7 +311,7 @@ export default defineComponent({ ...@@ -299,7 +311,7 @@ export default defineComponent({
align: 'center', align: 'center',
sortable: false, sortable: false,
}, },
{ {
name: 'approvalStatus', name: 'approvalStatus',
field: 'approvalStatus', field: 'approvalStatus',
required: true, required: true,
...@@ -391,8 +403,8 @@ export default defineComponent({ ...@@ -391,8 +403,8 @@ export default defineComponent({
void deleteCustomer(id); void deleteCustomer(id);
}); });
}; };
const confirmBrowserCustomer = (id: number) => { const confirmBrowserCustomer = (id: number) => {
Dialog.create({ Dialog.create({
title: i18n.global.t( title: i18n.global.t(
'customer.confirmActionsTitle.confirmDeleteUserTitle' 'customer.confirmActionsTitle.confirmDeleteUserTitle'
), ),
...@@ -400,29 +412,29 @@ export default defineComponent({ ...@@ -400,29 +412,29 @@ export default defineComponent({
// i18n.global.t( // i18n.global.t(
// 'customer.confirmActionsTitle.confirmDeleteUserContent' // 'customer.confirmActionsTitle.confirmDeleteUserContent'
// ), // ),
cancel: i18n.global.t( cancel: i18n.global.t(
'customer.confirmActionsTitle.confirmDeleteUserCancelBtnLabel' 'customer.confirmActionsTitle.confirmDeleteUserCancelBtnLabel'
), ),
color: 'secondary', color: 'secondary',
}).onOk(() => { }).onOk(() => {
// void deleteCustomer(id); // void deleteCustomer(id);
void browserCustomer(id); void browserCustomer(id);
}); });
}; };
const confirmRefusedBrowserCustomer = (id:number) => { const confirmRefusedBrowserCustomer = (id: number) => {
customerId.value = id customerId.value = id;
openDialogRefusedBrowser.value = true openDialogRefusedBrowser.value = true;
} };
const browserCustomer = async (id:number) => { const browserCustomer = async (id: number) => {
try { try {
const browserResult = (await api({ const browserResult = (await api({
url: API_PATHS.browserCustomer, url: API_PATHS.browserCustomer,
method: 'POST', method: 'POST',
data: { data: {
id: id, id: id,
isCustomer: 1, isCustomer: 1,
approvalStatus:1 approvalStatus: 1,
}, },
})) as AxiosResponse<BaseResponseBody<unknown>>; })) as AxiosResponse<BaseResponseBody<unknown>>;
...@@ -433,11 +445,9 @@ export default defineComponent({ ...@@ -433,11 +445,9 @@ export default defineComponent({
actions: [{ icon: 'close', color: 'white' }], actions: [{ icon: 'close', color: 'white' }],
}); });
void getListCustomers(); void getListCustomers();
} }
} catch (error) { } catch (error) {}
};
}
}
const deleteCustomer = async (id: number) => { const deleteCustomer = async (id: number) => {
try { try {
...@@ -612,7 +622,7 @@ export default defineComponent({ ...@@ -612,7 +622,7 @@ export default defineComponent({
confirmBrowserCustomer, confirmBrowserCustomer,
customerInfo, customerInfo,
customerId, customerId,
confirmRefusedBrowserCustomer confirmRefusedBrowserCustomer,
}; };
}, },
}); });
......
...@@ -374,7 +374,7 @@ export default defineComponent({ ...@@ -374,7 +374,7 @@ export default defineComponent({
name: 'approvalStatus', name: 'approvalStatus',
field: 'approvalStatus', field: 'approvalStatus',
required: true, required: true,
label: 'T.Thái chờ duyệt', label: 'T.T Duyệt',
headerStyle: 'text-align: center !important;', headerStyle: 'text-align: center !important;',
align: 'center', align: 'center',
sortable: false, sortable: false,
......
...@@ -22,6 +22,7 @@ export enum Pages { ...@@ -22,6 +22,7 @@ export enum Pages {
infoVAB = 'thong-tin-chung', infoVAB = 'thong-tin-chung',
menu = 'menu', menu = 'menu',
listBooking = 'danh-sach-booking', listBooking = 'danh-sach-booking',
listBookingBrowsing = 'danh-sach-booking-cho-duyet',
work = 'cong-viec', work = 'cong-viec',
configSystem = 'cau-hinh-trang-tinh', configSystem = 'cau-hinh-trang-tinh',
news = 'cau-hinh-tin-tuc', news = 'cau-hinh-tin-tuc',
...@@ -134,6 +135,11 @@ const routes: RouteRecordRaw[] = [ ...@@ -134,6 +135,11 @@ const routes: RouteRecordRaw[] = [
component: () => import('pages/danh-sach-booking/index.vue'), component: () => import('pages/danh-sach-booking/index.vue'),
name: Pages.listBooking, name: Pages.listBooking,
}, },
{
path: 'danh-sach-booking-cho-duyet',
component: () => import('pages/danh-sach-booking-cho-duyet/index.vue'),
name: Pages.listBookingBrowsing,
},
{ {
path: 'cong-viec', path: 'cong-viec',
component: () => import('pages/cong-viec/index.vue'), component: () => import('pages/cong-viec/index.vue'),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment