update

parent 2c1fc2ab
......@@ -88,6 +88,28 @@
:rules="statusRules"
hide-bottom-space
></q-select>
<!-- <q-select
v-model="homeStatus"
emit-value
label="Nổi bật ở trang chủ"
class="q-my-sm"
:options="statusHomeOptions"
option-value="id"
option-label="name"
outlined
map-options
hide-bottom-space
></q-select> -->
<!-- <div class="q-pt-sm">
<span class="text-body1">Nổi bật ở trang chủ</span
><q-toggle
:model-value="homeStatus"
:true-value="1"
:false-value="2"
/>
</div> -->
</div>
</div>
</q-card-section>
......
......@@ -29,10 +29,15 @@ export default defineComponent({
const urlFileLocal: Ref<string> = ref('');
const imageAPI: Ref<string | null> = ref(null);
const status: Ref<number> = ref(2);
// const homeStatus: Ref<number> = ref(0);
const statusOptions = ref([
{ id: 1, name: 'Sản phẩm khác' },
{ id: 2, name: 'Sản phẩm nổi bật' },
]);
// const statusHomeOptions = ref([
// { id: 0, name: 'Hiển thị' },
// { id: 1, name: 'Ẩn' },
// ])
const id: Ref<number | null> = ref(null);
const uploadAvatar = (value: FileList) => {
urlFileLocal.value = URL.createObjectURL(value[0]);
......@@ -49,6 +54,7 @@ export default defineComponent({
code.value = props.dataUpdate?.code as string;
embeddedUrl.value = props.dataUpdate?.embeddedUrl as string;
status.value = props.dataUpdate?.status as number;
// homeStatus.value = props.dataUpdate?.status as number
urlFileLocal.value = props.dataUpdate?.imageUrl as string;
if (props.dataUpdate?.file) {
imageAPI.value = null;
......@@ -67,6 +73,7 @@ export default defineComponent({
embeddedUrl.value = '';
urlFileLocal.value = '';
status.value = 2;
// homeStatus.value = 0
};
const SubbmitDataUpdate = () => {
context.emit('click:CloseBtnUpdateHotProduct');
......@@ -75,6 +82,7 @@ export default defineComponent({
name: name.value,
code: code.value,
status: status.value,
// isFeaturedOnHomepage: homeStatus.value,
embeddedUrl: embeddedUrl.value,
imageUrl: urlFileLocal.value,
id: id.value,
......@@ -131,6 +139,8 @@ export default defineComponent({
url_embed,
statusRules,
statusOptions,
// statusHomeOptions,
// homeStatus,
id,
configImg,
imageAPI,
......
......@@ -4,6 +4,7 @@ import Pagination from 'components/pagination/index.vue';
import { ProductType } from 'src/assets/type';
import { HotProductStatus } from 'src/assets/enums';
import { config } from 'src/assets/configurations.example';
import { Dialog, Notify } from 'quasar';
export default defineComponent({
components: {
Pagination,
......@@ -13,6 +14,7 @@ export default defineComponent({
// DataInsertHotProduct: { type: Object, requied: false }
},
setup(_, context) {
const configImg = config;
const userTableColumnsHotProduct = [
{
......@@ -61,6 +63,16 @@ export default defineComponent({
align: 'center',
sortable: false,
},
{
name: 'isFeaturedOnHomepage',
field: 'isFeaturedOnHomepage',
required: true,
label: 'Nổi bật ở trang chủ',
align: 'center',
sortable: false,
},
{
name: 'action',
field: 'action',
......@@ -75,6 +87,7 @@ export default defineComponent({
const pageIndex = ref(1);
const pageSize = ref(20);
const totalPage = ref(10);
const updateProduct = (item: { row: ProductType }) => {
context.emit('setDataUpdate', {
code: item.row.code,
......@@ -86,7 +99,37 @@ export default defineComponent({
file: item.row.file,
});
context.emit('click:openUpdateHotProduct');
};
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const showHiden = (index: any) => {
Dialog.create({
title: i18n.global.t(
'managingUnit.confirmActionsTitle.confirmDeleteManagingUnitsTitle'
),
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
message: index.isFeaturedOnHomepage === 1 ? 'Bạn có chắc chắn muốn ẩn ở trang chủ không?' : 'Bạn có chắc chắn muốn hiển thị ở trang chủ không?',
cancel: i18n.global.t(
'managingUnit.confirmActionsTitle.confirmDeleteManagingUnitsCancelBtnLabel'
),
color: 'negative',
}).onOk(() => {
context.emit('click:updateStatusHot');
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
console.log(index.id,'index')
Notify.create({
type: 'positive',
message: 'Thay đổi trạng thái thành công',
actions: [{ icon: 'close', color: 'white' }],
});
});
}
const clickAdd = () => {
context.emit('click:addHotProduct');
};
......@@ -104,7 +147,9 @@ export default defineComponent({
deleteRow,
clickAdd,
updateProduct,
showHiden,
HotProductStatus,
};
},
emits: [
......@@ -113,5 +158,6 @@ export default defineComponent({
'deleteRow',
'click:openUpdateHotProduct',
'setDataUpdate',
'click:updateStatusHot'
],
});
......@@ -50,6 +50,20 @@
</div>
</q-td>
</template>
<template v-slot:body-cell-isFeaturedOnHomepage="rowData">
<q-td>
<div v-if="rowData.value === 1" align="center">
<q-chip color=" positive" text-color="white" size="sm">
Hiển thị
</q-chip>
</div>
<div v-if="rowData.value === 0" align="center">
<q-chip color="primary" text-color="white" size="sm"> Ẩn </q-chip>
</div>
</q-td>
</template>
<template v-slot:body-cell-STT="item">
<q-td :item="item" style="text-align: center">
{{ 1 + item.rowIndex + pageSize * (pageIndex - 1) }}
......@@ -59,6 +73,19 @@
<template v-slot:body-cell-action="item">
<q-td style="padding: 0; height: 100%">
<div align="center">
<q-btn
flat
round
color="primary"
:icon="
item.row.isFeaturedOnHomepage === 0
? 'mdi-eye-off-outline'
: 'mdi-eye-outline'
"
@click="showHiden(item.row)"
>
<q-tooltip> Nổi bật ở trang chủ </q-tooltip>
</q-btn>
<q-btn
flat
round
......
......@@ -75,11 +75,7 @@ export default defineComponent({
(val && val.trim().length) ||
i18n.global.t('userPage.validateMessages.requireUnit'),
];
const sexRules = [
(val?: number) =>
val !== undefined ||
i18n.global.t('userPage.validateMessages.requireSex'),
];
const groupRules = [
(val?: Array<unknown>) =>
val?.length || i18n.global.t('userPage.validateMessages.requiredGroup'),
......@@ -94,7 +90,7 @@ export default defineComponent({
mobileNumberRules,
addressRules,
unitRules,
sexRules,
groupRules,
birthdayRules,
};
......
......@@ -119,7 +119,6 @@
option-label="text"
outlined
map-options
:rules="sexRules"
hide-bottom-space
></q-select>
<q-input
......
......@@ -97,7 +97,7 @@ export default {
address: 'Địa chỉ',
phoneNumber: 'Số máy bàn',
unit: 'Đơn vị phòng ban',
sex: 'Giới tính *',
sex: 'Giới tính',
birthday: 'Ngày sinh',
group: 'Thuộc nhóm *',
scheduleAccess: 'Lịch truy cập',
......
......@@ -136,6 +136,7 @@
@click:addHotProduct="openAddHotProduct = true"
@click:openUpdateHotProduct="openUpdateHotProduct = true"
@setDataUpdate="SetProduct($event)"
@click:update-status-hot="getInformationArtist"
></HotProduct>
</q-tab-panel>
</q-tab-panels>
......@@ -179,6 +180,7 @@
@UpdateData="UpdateData($event)"
@click:CloseBtnUpdateHotProduct="openUpdateHotProduct = false"
v-model:open-update-hot-product="openUpdateHotProduct"
></UpdateHotProduct>
<AddStory
@insertData="addStory"
......
......@@ -345,6 +345,7 @@ export default defineComponent({
// }
// );
const getInformationArtist = async () => {
const response = (await api({
url: API_PATHS.getDetailArtist,
......@@ -1054,6 +1055,7 @@ export default defineComponent({
confirmDeleteRow,
updateInformationArtist,
openUpdateHotProduct,
SetProduct,
DataUpdateHotProduct,
UpdateData,
......
<template>
<q-page class="row items-center justify-evenly">
<!-- <q-btn color="primary" @click="$store.dispatch('authentication/logOut')"
>Logout</q-btn
> -->
</q-page>
<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">
Danh sách sản phẩm nổi bật
<q-separator vertical spaced />
</div>
<q-space></q-space>
<div class="col-12 q-mt-sm">
<q-table
:rows="bannerTableRows"
:columns="bannerTableColumns"
row-key="id"
separator="cell"
wrap-cells
:no-data-label="$t('emptyData')"
:rows-per-page-label="$t('recordPerPage')"
:pagination="{
rowsPerPage: 0,
}"
hide-pagination
class="sticky-header-table"
>
<template v-slot:body-cell-action="item">
<q-td style="padding: 0; text-align: center">
<q-btn
flat
round
color="primary"
icon="mdi-delete-outline"
@click="confirmDeleteBanner(item.row.id)"
>
<q-tooltip :offset="[20, 10]">Xóa</q-tooltip>
</q-btn>
</q-td>
</template>
<template v-slot:body-cell-imageUrl="image">
<q-td style="padding: auto; height: 100%; text-align: center">
<q-img
style="width: 18rem; height: 6rem"
:src="configImg.API_IMAGE_ENDPOINT + image.row.imageUrl"
></q-img>
</q-td>
</template>
<template v-slot:body-cell-artistName="item">
<q-td style="padding: auto; height: 100%; text-align: center">
{{ item.row.artistName.artistName }}
</q-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="configHomeProduct"
/>
</div>
<!-- <AddUpdateBannerDialog
v-model:isOpened="addBannerDialogIsOpened"
v-model:name="name"
v-model:image="image"
v-model:numIndex="numIndex"
v-model:status="status"
@SetAvatar="setAvatar($event)"
@deleteAvatar="deleteAvatar"
isUpdate
@saveBannerInfo="addBanner"
/> -->
</div>
</template>
<script lang="ts">
import { i18n } from 'src/boot/i18n';
import { defineComponent, onMounted, ref, Ref } from 'vue';
import { AxiosResponse } from 'axios';
import Pagination from 'components/pagination/index.vue';
import { api, BaseResponseBody } from 'src/boot/axios';
import {
PaginationResponse,
FileUploadType,
ListBannerConfig,
DetailBannerConfig,
AddBannerConfig,
} from 'src/assets/type';
import { config, API_PATHS } from 'src/assets/configurations.example';
import { BannerStatus } from 'src/assets/enums';
// import AddUpdateBannerDialog from 'components/add-update-banner/index.vue';
import { Dialog, Notify } from 'quasar';
export type AvatarType = {
file?: File;
url?: string | null;
};
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'PageIndex',
components: {
Pagination,
// AddUpdateBannerDialog,
},
setup() {
const bannerTableColumns = [
{
name: 'name',
field: 'name',
required: true,
label: 'Tên sản phẩm',
headerStyle: 'text-align: center !important; width: 10%',
align: 'left',
sortable: false,
},
{
name: 'code',
field: 'code',
required: true,
label: 'Mã sản phẩm',
align: 'center',
headerStyle: 'width: 10%',
sortable: false,
},
{
name: 'artistName',
field: 'artistName',
required: true,
label: 'Tên nghệ sỹ',
align: 'center',
headerStyle: 'width: 10%',
sortable: false,
},
{
name: 'embeddedUrl',
field: 'embeddedUrl',
required: true,
label: i18n.global.t('artist.hotProduct.tableColumnsProduct.urlEmbed'),
headerStyle: 'text-align: center !important; width: 25%',
align: 'left',
sortable: false,
},
{
name: 'imageUrl',
field: 'imageUrl',
required: true,
label: i18n.global.t(
'artist.hotProduct.tableColumnsProduct.productImage'
),
align: 'center',
sortable: false,
headerStyle:'width: 25%'
},
{
name: 'action',
field: 'action',
required: true,
label: i18n.global.t('artist.bankAccount.tableColumnsBank.action'),
align: 'center',
sortable: false,
headerStyle:'width: 5%'
},
];
const pageIndex = ref(1);
const pageSize = ref(20);
const totalPage = ref(1);
const changePageSize = () => {
pageIndex.value = 1;
void configHomeProduct();
};
const bannerTableRows: Ref<unknown[]> = ref([]);
const addBannerDialogIsOpened = ref(false);
const name = ref('');
const image: Ref<string | null> = ref(null);
const numIndex: Ref<number | undefined> = ref(undefined);
const status: Ref<number> = ref(BannerStatus.active);
const bannerId: Ref<number | undefined> = ref(undefined);
const nameBanner = ref('');
const avatarFile: Ref<File | null> = ref(null);
const avatarUploaded: Ref<string> = ref('');
const imageChange: Ref<string> = ref('');
//gọi api ds
const configHomeProduct = async () => {
const response = (await api({
url: API_PATHS.configHomeProduct,
method: 'GET',
params: {
pageIndex: pageIndex.value,
pageSize: pageSize.value,
name: nameBanner.value,
},
})) as AxiosResponse<
BaseResponseBody<PaginationResponse<ListBannerConfig[]>>
>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
bannerTableRows.value = response.data.data.data;
totalPage.value = response.data.data.totalPages;
}
};
const confirmDeleteBanner = (id: number) => {
Dialog.create({
title: i18n.global.t(
'banner.confirmActionsTitle.confirmDeleteBannerTitle'
),
message: 'Bạn chắc chắn muốn xóa sản phẩm này khỏi danh sách nổi bật không?',
cancel: i18n.global.t(
'banner.confirmActionsTitle.confirmDeleteBannerCancelBtnLabel'
),
color: 'negative',
}).onOk(() => {
void deleteBanner(id);
});
};
//gói api xóa
const deleteBanner = async (id: number) => {
try {
const deleteResult = (await api({
url: API_PATHS.deleteBanner,
method: 'GET',
params: {
id: id,
},
})) as AxiosResponse<BaseResponseBody<unknown>>;
if (deleteResult.data.error.code === config.API_RES_CODE.OK.code) {
Notify.create({
type: 'positive',
message: i18n.global.t('banner.actionMessages.deleteBannerAccess'),
});
void configHomeProduct();
}
} catch (error) {}
};
const openAddBannerDialog = () => {
name.value = '';
numIndex.value = undefined;
image.value = null;
status.value = BannerStatus.active;
addBannerDialogIsOpened.value = true;
};
//gọi api add
const addBanner = async () => {
avatarUploaded.value = await callApiUploadAvatar(
avatarFile.value as File
);
const data = {
name: name.value,
image: avatarUploaded.value,
numIndex: numIndex.value,
status: status.value,
};
const response = (await api({
url: API_PATHS.addBanner,
method: 'POST',
data,
})) as AxiosResponse<BaseResponseBody<AddBannerConfig[]>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
addBannerDialogIsOpened.value = false;
Notify.create({
type: 'positive',
message: i18n.global.t('banner.actionMessages.addNewBannerAccess'),
actions: [{ icon: 'close', color: 'white' }],
});
void configHomeProduct();
}
};
//gọi api detail
const getDetailBanner = async (id: number) => {
try {
const response = (await api({
url: API_PATHS.getDetailBanner,
method: 'GET',
params: {
id: id,
},
})) as AxiosResponse<BaseResponseBody<DetailBannerConfig>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
bannerId.value = response.data.data.id;
name.value = response.data.data.name;
numIndex.value = response.data.data.numIndex;
status.value = response.data.data.status;
image.value = config.API_IMAGE_ENDPOINT + response.data.data.image;
imageChange.value = response.data.data.image;
}
} catch (error) {}
};
const setAvatar = (value: { file?: File; url?: string }) => {
avatarFile.value = value.file as File;
image.value = value.url as string;
};
const callApiUploadAvatar = async (file: File) => {
try {
const bodyFormData = new FormData();
bodyFormData.append('file', file);
const response = (await api({
headers: { 'Content-Type': 'multipart/form-data' },
// url: 'https://cms.vab.vn/file/upload/', // pro
url: config.API_IMAGE_ENDPOINT, // pro
// url: 'http://103.147.34.20:10705/file/upload/', // test
method: 'POST',
data: bodyFormData,
})) as AxiosResponse<BaseResponseBody<FileUploadType>>;
if (response.data.error.code === config.API_RES_CODE.OK.code) {
return response.data.data.fileName;
} else {
return '';
}
} catch (error) {
return '';
}
};
const deleteAvatar = () => {
image.value = null;
};
const configImg = config;
onMounted(() => {
void configHomeProduct();
});
return {
addBannerDialogIsOpened,
bannerTableColumns,
bannerTableRows,
configHomeProduct,
pageIndex,
pageSize,
totalPage,
changePageSize,
BannerStatus,
openAddBannerDialog,
name,
status,
addBanner,
confirmDeleteBanner,
deleteBanner,
getDetailBanner,
nameBanner,
image,
numIndex,
setAvatar,
callApiUploadAvatar,
deleteAvatar,
configImg,
avatarUploaded,
bannerId,
};
},
});
</script>
......@@ -97,11 +97,11 @@ export default defineComponent({
const userName = ref('');
const password = ref('');
const fullName = ref('');
const birthday: Ref<string | undefined> = ref();
const birthday: Ref<string | null> = ref(null);
const email = ref('');
const phoneNumber = ref('');
const mobileNumber = ref('');
const sex: Ref<number | undefined> = ref();
const sex: Ref<number | null> = ref(null);
const sexOptions = ref([
{ id: 1, text: 'Nam' },
{ id: 2, text: 'Nữ' },
......@@ -157,18 +157,19 @@ export default defineComponent({
userName.value = '';
password.value = '';
fullName.value = '';
birthday.value = '';
birthday.value = null;
email.value = '';
phoneNumber.value = '';
mobileNumber.value = '';
sex.value = undefined;
sex.value = null;
address.value = '';
unit.value = null;
status.value = true;
group.value = [];
};
const addNewUser = async () => {
const addNewUser = async () => {
try {
const groups: { id: number }[] = [];
group.value.map((item) => {
......@@ -183,11 +184,11 @@ export default defineComponent({
password: password.value,
fullName: fullName.value.trim(),
birthday:
birthday.value === '' ? '' : moment(birthday.value, 'DD/MM/YYYY').format('DD/MM/YYYY 00:00:00'),
birthday.value === null ? null : moment(birthday.value, 'DD/MM/YYYY').format('DD/MM/YYYY 00:00:00'),
email: email.value.trim(),
phoneNumber: phoneNumber.value.trim(),
mobileNumber: mobileNumber.value.trim(),
sex: sex.value,
sex: sex.value === null ? null : sex.value ,
address: address.value?.trim(),
unit: unit.value?.trim(),
status: status.value ? 1 : 0,
......@@ -319,20 +320,21 @@ export default defineComponent({
'DD/MM/YYYY HH:mm:ss'
).format('DD/MM/YYYY');
} else {
birthday.value = '';
birthday.value = null;
}
email.value = userInfo.email as string;
fullName.value = userInfo.fullName as string;
mobileNumber.value = userInfo.mobileNumber as string;
phoneNumber.value = userInfo.phoneNumber as string;
if (userInfo.sex !== 0) {
if (userInfo.sex !== null ) {
sex.value = userInfo.sex;
} else {
sex.value = 1;
sex.value = null;
}
status.value = userInfo.status ? true : false;
unit.value = userInfo.unit;
userName.value = userInfo.userName;
password.value = userInfo.password
}
} catch (error) {}
};
......@@ -350,11 +352,11 @@ export default defineComponent({
fullName: fullName.value.trim(),
birthday:
birthday.value === '' ? '' : moment(birthday.value, 'DD/MM/YYYY').format('DD/MM/YYYY 00:00:00'),
birthday.value === null ? null : moment(birthday.value, 'DD/MM/YYYY').format('DD/MM/YYYY 00:00:00'),
email: email.value.trim(),
phoneNumber: phoneNumber.value.trim(),
mobileNumber: mobileNumber.value.trim(),
sex: sex.value,
sex: sex.value === null ? null : sex.value ,
address: address.value?.trim(),
unit: unit.value?.trim(),
status: status.value ? 1 : 0,
......
......@@ -192,6 +192,8 @@
@UpdateData="UpdateData($event)"
@click:CloseBtnUpdateHotProduct="openUpdateHotProduct = false"
v-model:open-update-hot-product="openUpdateHotProduct"
></UpdateHotProduct>
<AddStory
@insertData="addStory"
......
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