Commit d252d47f authored by Tình Trương's avatar Tình Trương

update customer

parent 1f95e656
import { defineComponent } from 'vue';
import { i18n } from 'src/boot/i18n';
import { isEmail } from '../../../boot/functions';
import { isMobilePhone } from '../../../boot/functions';
export default defineComponent({
props: {
showDialog: {
type: Boolean,
required: true,
},
ratingsOptions: {type: Array, required: true},
businessTypeOptions: {type: Array, required: true},
tenĐN: { type: String, required: true },
customerName: { type: String, required: true },
businessName: { type: String, required: true },
taxCode: { type: Number, required: true },
email: { type: String, required: true },
ratings: { type: String, required: true },
address: { type: String, required: true },
businessType: { type: String, required: true },
representative: { type: String, required: true },
position: { type: String, required: true },
phone: { type: String, required: true },
status: { type: Boolean, required: true },
},
setup() {
const tenĐNRules = [
(val?: string) =>
(val && val.trim().length) ||
i18n.global.t('customer.validateMessages.requireTenĐN'),
];
const customerNameRules = [
(val?: string) =>
(val && val.trim().length) ||
i18n.global.t('customer.validateMessages.requireCustomerName'),
];
const businessNameRules = [
(val?: string) =>
(val && val.trim().length) ||
i18n.global.t('customer.validateMessages.requireBusinessName'),
];
const taxCodeRules = [
(val?: number) =>
val !== undefined ||
i18n.global.t('customer.validateMessages.requireTaxCode'),
];
const phoneRules = [
(val?: string) =>
(val && val.trim().length) ||
i18n.global.t('customer.validateMessages.requirePhone'),
(val: string) =>
isMobilePhone(val) ||
i18n.global.t('customer.validateMessages.isPhone'),
];
const emailRules = [
(val?: string) =>
(val && val.trim().length) ||
i18n.global.t('customer.validateMessages.requireEmail'),
(val: string) =>
isEmail(val) || i18n.global.t('customer.validateMessages.isEmail'),
];
const addressRules = [
(val?: string) =>
(val && val.trim().length) ||
i18n.global.t('customer.validateMessages.requireAddress'),
];
const businessTypeRules = [
(val?: number) =>
val !== undefined ||
i18n.global.t('customer.validateMessages.requireBusinessType'),
];
const ratingsRules = [
(val?: number) =>
val !== undefined ||
i18n.global.t('customer.validateMessages.requireRatings'),
];
const representativeRules = [
(val?: string) =>
(val && val.trim().length) ||
i18n.global.t('customer.validateMessages.requireRepresentative'),
];
const positionRules = [
(val?: string) =>
(val && val.trim().length) ||
i18n.global.t('customer.validateMessages.requiredPosition'),
];
return {
tenĐNRules,
customerNameRules,
businessNameRules,
taxCodeRules,
emailRules,
ratingsRules,
addressRules,
businessTypeRules,
representativeRules,
positionRules,
phoneRules,
};
},
emits: [
'update:showDialog',
'click:CloseBtn',
'update:tenĐN',
'update:customerName',
'update:businessName',
'update:taxCode',
'update:email',
'update:ratings',
'update:address',
'update:businessType',
'update:representative',
'update:position',
'update:phone',
'update:status',
'addNewCustomer',
],
});
<template>
<q-dialog
persistent
:model-value="showDialog"
@update:model-value="$emit('update:showDialog', $event)"
>
<q-card style="min-width: 900px" bordered>
<q-form greedy @submit.prevent="$emit('addNewCustomer')">
<q-card-section>
<q-item>
<q-item-section>
<q-item-label class="text-h6 text-weight-regular">{{
$t('customer.dialogLabel.title.addCustomer')
}}</q-item-label>
</q-item-section>
</q-item>
</q-card-section>
<q-separator />
<q-card-section>
<div class="row q-col-gutter-sm">
<div class="col-6">
<q-input
:model-value="tenĐN"
@update:model-value="$emit('update:tenĐN', $event)"
:label="$t('customer.dialogLabel.fieldLabels.tenĐN')"
:rules="tenĐNRules"
hide-bottom-space
type="text"
class="q-my-sm"
outlined
clearable
></q-input>
<q-input
:model-value="customerName"
@update:model-value="$emit('update:customerName', $event)"
:label="$t('customer.dialogLabel.fieldLabels.customerName')"
type="text"
class="q-my-sm"
outlined
:rules="customerNameRules"
hide-bottom-space
clearable
></q-input>
<q-input
:model-value="businessName"
@update:model-value="$emit('update:businessName', $event)"
:label="$t('customer.dialogLabel.fieldLabels.businessName')"
type="text"
class="q-my-sm"
outlined
:rules="businessNameRules"
hide-bottom-space
clearable
></q-input>
<q-input
:model-value="taxCode"
@update:model-value="$emit('update:taxCode', $event)"
:label="$t('customer.dialogLabel.fieldLabels.taxCode')"
type="number"
class="q-my-sm"
outlined
:rules="taxCodeRules"
hide-bottom-space
clearable
></q-input>
<q-input
:model-value="email"
@update:model-value="$emit('update:email', $event)"
:label="$t('customer.dialogLabel.fieldLabels.email')"
type="text"
class="q-my-sm"
outlined
:rules="emailRules"
hide-bottom-space
clearable
></q-input>
<q-select
:model-value="ratings"
@update:model-value="$emit('update:ratings', $event)"
:label="$t('customer.dialogLabel.fieldLabels.ratings')"
:options="ratingsOptions"
:rules="ratingsRules"
emit-value
map-options
option-value="id"
option-label="text"
type="text"
class="q-my-sm"
outlined
hide-bottom-space
clearable
></q-select>
</div>
<div class="col-6">
<q-input
:model-value="address"
@update:model-value="$emit('update:address', $event)"
:label="$t('customer.dialogLabel.fieldLabels.address')"
type="text"
class="q-my-sm"
:rules="addressRules"
outlined
hide-bottom-space
clearable
></q-input>
<q-select
:model-value="businessType"
@update:model-value="$emit('update:businessType', $event)"
:label="$t('customer.dialogLabel.fieldLabels.businessType')"
:options="businessTypeOptions"
:rules="businessTypeRules"
emit-value
map-options
option-value="id"
option-label="text"
type="text"
class="q-my-sm"
outlined
hide-bottom-space
clearable
></q-select>
<q-input
:model-value="representative"
emit-value
@update:model-value="$emit('update:representative', $event)"
:label="$t('customer.dialogLabel.fieldLabels.representative')"
class="q-my-sm"
type="text"
outlined
:rules="representativeRules"
hide-bottom-space
clearable
></q-input>
<q-input
:model-value="position"
emit-value
@update:model-value="$emit('update:position', $event)"
:label="$t('customer.dialogLabel.fieldLabels.position')"
class="q-my-sm"
type="text"
outlined
:rules="positionRules"
hide-bottom-space
clearable
></q-input>
<q-input
:model-value="phone"
emit-value
@update:model-value="$emit('update:phone', $event)"
:label="$t('customer.dialogLabel.fieldLabels.phone')"
class="q-my-sm"
type="number"
:rules="phoneRules"
outlined
hide-bottom-space
clearable
></q-input>
<div style="padding-top: 13px; padding-left: 12px">
<span class="text-body1">{{
$t('customer.dialogLabel.fieldLabels.status')
}}</span
><q-toggle
:model-value="status"
@update:model-value="$emit('update:status', $event)"
/>
</div>
</div>
</div>
</q-card-section>
<q-card-actions align="right">
<q-btn
color="black"
no-caps
style="width: 90px"
:label="$t('customer.crudActions.cancel')"
@click="$emit('click:CloseBtn')"
/>
<q-btn
type="submit"
color="primary"
no-caps
style="width: 90px"
:label="$t('customer.crudActions.save')"
/>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>
<script lang="ts" src="./AddNewCustomerDialog.ts"></script>
<template>
<div>My component</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
// name: 'ComponentName'
})
</script>
......@@ -145,6 +145,84 @@ export default {
action: 'Chức năng',
},
},
// khách hàng
customer: {
title: 'Danh sách khách hàng',
tableColumnsCustomer: {
stt: 'STT',
customerCode: 'Mã khách hàng',
tenĐN: 'Tên ĐN',
fullName: 'Họ tên',
businessName: 'Tên doanh nghiệp',
taxCode: 'Mã số thuế',
email: 'Email',
ratings: 'Xếp hạng',
status: 'Trạng thái',
action: 'Chức năng',
},
statusLabel: {
active: 'Đang hoạt động',
inactive: 'Ngừng hoạt động',
},
dialogLabel: {
title: {
addCustomer: 'Thêm mới khách hàng',
updateCustomer: 'Cập nhật người dùng',
},
fieldLabels: {
tenĐN: 'Tên ĐN *',
customerName: 'Họ tên *',
businessName: 'Tên doanh nghiệp *',
taxCode: 'Mã số thuế *',
email: 'Email *',
ratings: 'Xếp hạng *',
address: 'Địa chỉ *',
businessType: 'Loại doanh nghiệp *',
representative: 'Đại diện *',
position: 'Chức vụ *',
phone: 'Số điện thoại *',
status: 'Trạng thái',
},
},
toolTipMessage: {
updateCustomerInfo: 'Cập nhật',
informationCustomer: 'Thông tin',
},
crudActions: {
save: 'Lưu',
cancel: 'Đóng',
},
validateMessages: {
requireTenĐN: 'Vui lòng nhập Tên ĐH',
requireCustomerName: 'Vui lòng nhập Họ tên',
requireBusinessName: 'Vui lòng nhập Tên Doanh nghiệp',
requireTaxCode: 'Vui lòng nhập Mã số thuế',
requireEmail: 'Vui lòng nhập Email',
isEmail: 'Email không hợp lệ',
requirePhone: 'Vui lòng nhập số điện thoại',
isPhone: 'Số điện thoại không hợp lệ',
requireAddress: 'Vui lòng nhập địa chỉ',
requireBusinessType: 'Vui lòng nhập Loại doanh nghiệp',
requireRatings: 'Vui lòng nhập xếp hạng',
requireRepresentative: 'Vui lòng nhập giới tính',
requiredPosition: 'Vui lòng nhập chức vụ',
},
// confirmActionsTitle: {
// confirmDeleteUserTitle: 'Xác nhận',
// confirmDeleteUserCancelBtnLabel: 'Huỷ',
// confirmDeleteUserContent: 'Bạn có chắc muốn xoá tài khoản',
// confirmResetPasswordContent:
// 'Bạn có muốn reset mật khẩu của người dùng này không',
// },
// actionMessages: {
// addNewUserAccess: 'Thêm tài khoản thành công',
// deleteUserAccess: 'Xoá tài khoản thành công',
// updateUserAccess: 'Cập nhật thông tin tài khoản thành công',
// resetPasswordAccess: 'Reset mật khẩu thành công',
// },
},
artist: {
tableColumnsArtist: {
artistName: 'Tên nghệ sỹ',
......
import { i18n } from 'src/boot/i18n';
import { defineComponent, onMounted, ref, Ref } from 'vue';
import Pagination from 'components/pagination/index.vue';
import AddNewCustomerDialogComponent from '../../components/customer/add-new-customer-dialog/index.vue';
export type ArtistInfoType = {
id: number;
tenĐN: string | null;
customerName: string | null;
businessName: string | null;
taxCode: number;
email: string | null;
ratings: string | null;
address: string | null;
businessType: string | null;
representative: string | null;
position: string | null;
phone: string | null;
status: number;
};
export default defineComponent({
components: {
AddNewCustomerDialogComponent,
Pagination,
},
setup() {
const dataTest = ref([]);
const userTableColumnsCustomer = [
{
name: 'stt',
field: 'stt',
required: true,
label: i18n.global.t('customer.tableColumnsCustomer.stt'),
align: 'center',
sortable: false,
},
{
name: 'customerCode',
field: 'customerCode',
required: true,
label: i18n.global.t('customer.tableColumnsCustomer.customerCode'),
align: 'left',
headerStyle: 'text-align: center !important;',
sortable: false,
},
{
name: 'tenĐN',
field: 'tenĐN',
required: true,
label: i18n.global.t('customer.tableColumnsCustomer.tenĐN'),
headerStyle: 'text-align: center !important;',
align: 'left',
sortable: false,
},
{
name: 'fullName',
field: 'fullName',
required: true,
label: i18n.global.t('customer.tableColumnsCustomer.fullName'),
headerStyle: 'text-align: center !important;',
align: 'left',
sortable: false,
},
{
name: 'businessName',
field: 'businessName',
required: true,
label: i18n.global.t('customer.tableColumnsCustomer.businessName'),
headerStyle: 'text-align: center !important;',
align: 'left',
sortable: false,
},
{
name: 'taxCode',
field: 'taxCode',
required: true,
label: i18n.global.t('customer.tableColumnsCustomer.taxCode'),
headerStyle: 'text-align: center !important;',
align: 'left',
sortable: false,
},
{
name: 'email',
field: 'email',
required: true,
label: i18n.global.t('customer.tableColumnsCustomer.email'),
headerStyle: 'text-align: center !important;',
align: 'left',
sortable: false,
},
{
name: 'ratings',
field: 'ratings',
required: true,
label: i18n.global.t('customer.tableColumnsCustomer.ratings'),
headerStyle: 'text-align: center !important;',
align: 'left',
sortable: false,
},
{
name: 'status',
field: 'status',
required: true,
label: i18n.global.t('customer.tableColumnsCustomer.status'),
align: 'center',
sortable: false,
},
{
name: 'action',
field: 'action',
required: true,
label: i18n.global.t('customer.tableColumnsCustomer.action'),
align: 'center',
sortable: false,
},
];
const userTableRowsCustomer: Ref<unknown[]> = ref([]);
const showDialog = ref(false);
const pageIndex = ref(1);
const pageSize = ref(20);
const totalPage = ref(10);
const id: Ref<number> = ref(0);
const businessName: Ref<string | undefined> = ref();
const taxCode: Ref<number | undefined> = ref();
const tenĐN: Ref<string | undefined> = ref();
const email: Ref<string | undefined> = ref();
const address: Ref<string | undefined> = ref();
const customerName: Ref<string | undefined> = ref();
const ratings: Ref<number | undefined> = ref();
const ratingsOptions = ref([
{ id: 1, text: 'VIP_1' },
{ id: 2, text: 'VIP_2' },
{ id: 3, text: 'VIP_3' },
]);
const businessType: Ref<number | undefined> = ref();
const businessTypeOptions = ref([
{ id: 1, text: 'Doanh nghiệp A' },
{ id: 2, text: 'Doanh nghiệp B' },
{ id: 3, text: 'Doanh nghiệp C' },
]);
const representative: Ref<string | undefined> = ref();
const position: Ref<string | undefined> = ref();
const phone: Ref<string | undefined> = ref();
const status: Ref<boolean | number> = ref(true);
const ratingOptions = ref([
{ id: 1, text: 'VIP_1' },
{ id: 2, text: 'VIP_2' },
]);
const ratingSelected: Ref<number | undefined> = ref();
const getListCustomer = () => {
// const response = (await api({
// url: API_PATHS.getListArtist,
// method: 'GET',
// params: {
// pageIndex: pageIndex.value,
// pageSize: pageSize.value,
// },
// })) as AxiosResponse<BaseResponseBody<unknown>>;
const fakeData: unknown[] = [
{
id: 1,
stt: 1,
customerCode: '0001',
tenĐN: 'DuongNA01',
fullName: 'Nguyễn Tùng Dương',
businessName: 'TNHH Hà Đông',
taxCode: '1234567890',
email: 'info@hadong.vn',
ratings: 'VIP_1',
status: 1,
},
{
id: 2,
stt: 2,
customerCode: '0001',
tenĐN: 'DuongNA01',
fullName: 'Nguyễn Tùng Dương',
businessName: 'TNHH Hà Đông',
taxCode: '1234567890',
email: 'info@hadong.vn',
ratings: 'VIP_1',
status: 0,
},
];
userTableRowsCustomer.value = fakeData;
};
const filterListCustomer = () => {
// const response = (await api({
// url: API_PATHS.filterListArtist,
// method: 'GET',
// params: {
// unitName: fullNameKeyword.value,
// fieldName: fieldSelected.value,
// },
// })) as AxiosResponse<BaseResponseBody<unknown>>;
// userTableRowsArtist.value = userTableRowsArtist.value.filter((item: unknown) => item.fullName = fullNameKeyword)
};
const changePageSize = () => {
pageIndex.value = 1;
void getListCustomer();
};
const openAddCustomerDialog = () => {
showDialog.value = true;
tenĐN.value = '';
customerName.value = '';
businessName.value = '';
taxCode.value = undefined;
email.value = '';
ratings.value = undefined;
address.value = '';
businessType.value = undefined;
representative.value = '';
position.value = '';
phone.value = '';
};
const addNewCustomer = () => {
try {
} catch (error) {
}
};
onMounted(() => {
void getListCustomer();
});
return {
openAddCustomerDialog,
addNewCustomer,
showDialog,
id,
tenĐN,
customerName,
businessName,
taxCode,
email,
ratings,
ratingsOptions,
address,
businessType,
businessTypeOptions,
representative,
position,
phone,
status,
userTableColumnsCustomer,
userTableRowsCustomer,
getListCustomer,
pageIndex,
pageSize,
filterListCustomer,
dataTest,
totalPage,
changePageSize,
ratingSelected,
ratingOptions,
};
},
});
<template>
<div class="row q-col-gutter-sm flex-center q-mt-sm">
<q-space></q-space>
<div class="col-2">
<q-input
v-model="businessName"
dense
outlined
:label="$t('customer.tableColumnsCustomer.businessName')"
clearable
></q-input>
</div>
<div class="col-2">
<q-input
v-model="taxCode"
dense
outlined
:label="$t('customer.tableColumnsCustomer.taxCode')"
clearable
></q-input>
</div>
<div class="col-2" dense outlined>
<q-select
v-model="ratingSelected"
:options="ratingOptions"
option-label="text"
option-value="id"
dense
outlined
label="Xếp hạng"
clearable
></q-select>
</div>
<div class="col-auto">
<q-btn
color="primary"
no-caps
:label="$t('crudActions.search')"
@click="filterListCustomer"
>
</q-btn>
</div>
<div class="col-auto">
<q-btn
color="primary"
no-caps
:label="$t('crudActions.add')"
@click="openAddCustomerDialog"
>
</q-btn>
</div>
<div class="col-12 q-mt-sm">
<q-table
:rows="userTableRowsCustomer"
:columns="userTableColumnsCustomer"
:no-data-label="$t('emptyData')"
row-key="name"
separator="cell"
hide-pagination
>
<template v-slot:body-cell-action>
<q-td style="padding: 0" class="flex flex-center">
<q-btn flat round color="primary" icon="mdi-information-outline">
<q-tooltip :offset="[20, 10]">{{
$t('customer.toolTipMessage.informationCustomer')
}}</q-tooltip>
</q-btn>
<q-btn flat round color="primary" icon="mdi-account-edit-outline">
<q-tooltip :offset="[20, 10]">{{
$t('customer.toolTipMessage.updateCustomerInfo')
}}</q-tooltip>
</q-btn>
</q-td>
</template>
<template v-slot:body-cell-status="rowData">
<q-td>
<div align="center">
<q-chip
:color="rowData.value ? 'positive' : 'orange'"
text-color="white"
size="sm"
>
{{
rowData.value
? $t('customer.statusLabel.active')
: $t('customer.statusLabel.inactive')
}}
</q-chip>
</div>
</q-td>
</template>
</q-table>
<div class="col-12 q-mt-sm">
<Pagination
v-model:currentPage="pageIndex"
v-model:pageSize="pageSize"
:totalPage="totalPage"
@update:pageSize="changePageSize"
@update:currentPage="getListCustomer"
/>
<AddNewCustomerDialogComponent
v-model:show-dialog="showDialog"
v-model:tendn="tenĐN"
v-model:customer-name="customerName"
v-model:business-name="businessName"
v-model:tax-code="taxCode"
v-model:email="email"
v-model:ratings="ratings"
v-model:address="address"
v-model:business-type="businessType"
v-model:representative="representative"
v-model:position="position"
v-model:phone="phone"
v-model:status="status"
:ratings-options="ratingsOptions"
:business-type-options="businessTypeOptions"
@click:CloseBtn="showDialog = false"
@addNewCustomer="addNewCustomer"
></AddNewCustomerDialogComponent>
</div>
</div>
</div>
</template>
<script lang="ts" src="./customer.ts"></script>
......@@ -8,6 +8,7 @@ export enum Pages {
managingUnit = 'don-vi-chu-quan',
artist = 'nghe-sy',
informationArtist = 'cap-nhat-thong-tin-nghe-sy',
customer = 'khach-hang',
}
const routes: RouteRecordRaw[] = [
......@@ -50,6 +51,11 @@ const routes: RouteRecordRaw[] = [
component: () => import('pages/cap-nhat-thong-tin-nghe-sy/index.vue'),
name: Pages.informationArtist,
},
{
path: '/khach-hang',
component: () => import('pages/khach-hang/index.vue'),
name: Pages.customer,
},
],
},
......
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