create upload image

parent 32dc7933
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
"axios": "^0.21.1", "axios": "^0.21.1",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"http-status-codes": "^2.1.4", "http-status-codes": "^2.1.4",
"moment": "^2.29.1",
"quasar": "^2.0.0-beta.1", "quasar": "^2.0.0-beta.1",
"secure-ls": "^1.2.6", "secure-ls": "^1.2.6",
"vue": "^3.0.11", "vue": "^3.0.11",
...@@ -11148,7 +11149,6 @@ ...@@ -11148,7 +11149,6 @@
"version": "2.29.1", "version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
"dev": true,
"engines": { "engines": {
"node": "*" "node": "*"
} }
...@@ -31957,8 +31957,7 @@ ...@@ -31957,8 +31957,7 @@
"moment": { "moment": {
"version": "2.29.1", "version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
"dev": true
}, },
"move-concurrently": { "move-concurrently": {
"version": "1.0.1", "version": "1.0.1",
...@@ -94,7 +94,9 @@ export type BannerType = { ...@@ -94,7 +94,9 @@ export type BannerType = {
bannerUrl: string; bannerUrl: string;
id: number; id: number;
numIndex: number; numIndex: number;
status: 1; status: number;
url?: string;
file?: File;
}; };
export type SchedulesType = { export type SchedulesType = {
......
import { defineComponent, PropType, ref } from 'vue'; import { defineComponent, PropType, ref, watch } from 'vue';
import { i18n } from 'src/boot/i18n'; import { i18n } from 'src/boot/i18n';
import { BannerType, StoriesType } from 'src/assets/type'; import { BannerType, StoriesType } from 'src/assets/type';
import UploadImage from 'components/upload-image/index.vue';
import { Dialog } from 'quasar';
export default defineComponent({ export default defineComponent({
components: { UploadImage },
props: { props: {
account: { type: String, required: true }, account: { type: String, required: true },
banners: { type: Array as PropType<BannerType[]>, required: true }, banners: { type: Array as PropType<BannerType[]>, required: true },
shortDescription: { type: Array, required: true }, shortDescription: { type: Array, required: true },
socialEmbedded: { type: Array, required: true }, socialEmbedded: { type: Array, required: true },
stories: { type: Array as PropType<StoriesType[]>, required: true }, stories: { type: Array as PropType<StoriesType[]>, required: true },
formatSchedules: { type: Array as PropType<string[]>, required: true },
}, },
setup() { setup(props, context) {
watch(
() => props.banners.length,
(value) => {
slide.value = value - 1;
}
);
const slide = ref(1); const slide = ref(1);
const slideStory = ref(0);
const editor = ref('Customize it.'); const editor = ref('Customize it.');
const accountRules = [ const accountRules = [
(val?: string) => (val?: string) =>
...@@ -20,7 +32,43 @@ export default defineComponent({ ...@@ -20,7 +32,43 @@ export default defineComponent({
'artist.artistInformation.validateMessages.requireFullName' 'artist.artistInformation.validateMessages.requireFullName'
), ),
]; ];
return { slide, editor, accountRules }; const uploadBanner = (value: FileList) => {
context.emit('selectedFile', encodeImageFileAsURL(value[0]));
};
const encodeImageFileAsURL = (file: File) => {
return { url: URL.createObjectURL(file), file: file };
};
const deleteImage = (index: number) => {
Dialog.create({
title: i18n.global.t(
'managingUnit.confirmActionsTitle.confirmDeleteManagingUnitsTitle'
),
message: i18n.global.t(
'managingUnit.confirmActionsTitle.confirmDeleteManagingUnitsContent'
),
cancel: i18n.global.t(
'managingUnit.confirmActionsTitle.confirmDeleteManagingUnitsCancelBtnLabel'
),
color: 'negative',
}).onOk(() => {
context.emit('deleteBanner', index);
});
};
return {
slide,
slideStory,
editor,
accountRules,
uploadBanner,
deleteImage,
};
}, },
emits: ['update:account', 'update:shortDescription'], emits: [
'update:account',
'update:shortDescription',
'update:content',
'update:formatSchedules',
'selectedFile',
'deleteBanner',
],
}); });
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div class="row q-col-gutter-sm"> <div class="row q-col-gutter-sm">
<div class="col-12 text-uppercase text-weight-medium">Tài khoản VAB</div> <div class="col-12 text-uppercase text-weight-medium">Tài khoản VAB</div>
<br /> <br />
<div class="col-2 flex flex-center justify-start"> <div class="col-auto flex flex-center justify-start">
<div>Tên đăng nhập</div> <div>Tên đăng nhập</div>
</div> </div>
<div class="col-2 flex flex-center"> <div class="col-2 flex flex-center">
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
@update:model-value="$emit('update:account', $event)" @update:model-value="$emit('update:account', $event)"
:rules="accountRules" :rules="accountRules"
dense dense
readonly
hide-bottom-space hide-bottom-space
outlined outlined
></q-input> ></q-input>
...@@ -26,6 +27,8 @@ ...@@ -26,6 +27,8 @@
<div class="col-4"> <div class="col-4">
<q-carousel <q-carousel
v-model="slide" v-model="slide"
:key="banners.length"
v-if="banners.length"
animated animated
arrows arrows
navigation navigation
...@@ -35,11 +38,30 @@ ...@@ -35,11 +38,30 @@
<q-carousel-slide <q-carousel-slide
v-for="(bannerInfo, bannerIdx) in banners" v-for="(bannerInfo, bannerIdx) in banners"
:key="bannerIdx" :key="bannerIdx"
:name="bannerInfo.id" :name="bannerIdx"
img-src="https://kenh14cdn.com/203336854389633024/2020/12/31/photo-1-16094117624341764656274.jpg" :img-src="bannerInfo.bannerUrl || bannerInfo.url"
/> >
<template v-slot:default>
<div align="right">
<q-icon
color="red"
name="mdi-close-circle"
size="24px"
@click="deleteImage(bannerIdx)"
></q-icon>
</div>
</template>
</q-carousel-slide>
</q-carousel> </q-carousel>
<UploadImage v-else @selectedFile="uploadBanner"></UploadImage>
<UploadImage
class="q-mt-xs"
v-if="banners.length"
:isBtn="true"
@selectedFile="uploadBanner"
></UploadImage>
</div> </div>
<div class="col-8"> <div class="col-8">
<q-editor <q-editor
:model-value="shortDescription" :model-value="shortDescription"
...@@ -48,7 +70,7 @@ ...@@ -48,7 +70,7 @@
toolbar-text-color="white" toolbar-text-color="white"
toolbar-toggle-color="yellow-8" toolbar-toggle-color="yellow-8"
toolbar-bg="primary" toolbar-bg="primary"
height="266px" style="height: 100%"
:toolbar="[ :toolbar="[
['token'], ['token'],
['bold', 'italic', 'underline'], ['bold', 'italic', 'underline'],
...@@ -66,30 +88,50 @@ ...@@ -66,30 +88,50 @@
</div> </div>
</div> </div>
<div class="col-12 q-mt-md"> <div class="col-12 q-mt-md">
<div class="row" align="center" justify="center"> <div class="row q-col-gutter-lg" align="center" justify="center">
<div class="col-3"> <div class="col-4">
<div class="text-h6 text-weight-regular">Nổi bật(Embed)</div> <div class="text-h6 text-weight-regular">Nổi bật(Embed)</div>
<q-card class="my-card q-mt-sm" style="height: 300px"> <q-card class="my-card q-mt-sm" style="height: 300px">
<img style="height: 100%" :src="socialEmbedded" /> <!-- <img style="height: 100%" :src="socialEmbedded" /> -->
<iframe
style="height: 100%; width: 100%"
:src="socialEmbedded"
frameborder="0"
></iframe>
</q-card> </q-card>
</div> </div>
<q-space></q-space>
<div class="col-3"> <div class="col-4">
<div class="text-h6 text-weight-regular">Story</div> <div class="text-h6 text-weight-regular">Story</div>
<q-card class="my-card q-mt-sm" style="height: 300px"> <q-carousel v-model="slideStory" animated arrows navigation infinite>
<img <q-carousel-slide
v-if="stories[0].imageUrl !== null" v-for="(story, storyIdx) in stories"
style="height: 70%" :key="storyIdx"
:src="stories[0].imageUrl" :name="storyIdx"
/> class="q-pt-sm"
<div class="text-subtitle2">{{ stories[0].content }}</div> >
<q-card class="my-card">
<q-img fit="contain" :src="story.imageUrl" />
<q-input
type="textarea"
:model-value="story.content"
@update:model-value="$emit('update:content', $event)"
></q-input>
</q-card> </q-card>
</q-carousel-slide>
</q-carousel>
</div> </div>
<q-space></q-space> <div class="col-4">
<div class="col-3 q-mr-md">
<div class="text-h6 text-weight-regular">Lịch</div> <div class="text-h6 text-weight-regular">Lịch</div>
<q-date class="q-mt-sm" event-color="orange" /> <q-date
style="width: 100%"
:model-value="formatSchedules"
@update:model-value="$emit('update:formatSchedules', $event)"
multiple
readonly
class="q-mt-sm"
event-color="orange"
/>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -13,6 +13,7 @@ export default defineComponent({ ...@@ -13,6 +13,7 @@ export default defineComponent({
setup() { setup() {
const userTableColumnsBankAccount = [ const userTableColumnsBankAccount = [
{ {
name: 'STT',
required: true, required: true,
label: 'STT', label: 'STT',
align: 'center', align: 'center',
...@@ -111,5 +112,5 @@ export default defineComponent({ ...@@ -111,5 +112,5 @@ export default defineComponent({
changePageSize, changePageSize,
}; };
}, },
emits: ['click:addBankBtn'], emits: ['click:addBankBtn', 'confirmDeleteAccBank'],
}); });
...@@ -68,6 +68,8 @@ ...@@ -68,6 +68,8 @@
<!-- :label="$t('artist.dialogLabel.fieldLabels.isDefault')" --> <!-- :label="$t('artist.dialogLabel.fieldLabels.isDefault')" -->
<q-checkbox <q-checkbox
:model-value="isDefault" :model-value="isDefault"
:true-value="1"
:false-value="2"
@update:model-value="$emit('update:isDefault', $event)" @update:model-value="$emit('update:isDefault', $event)"
/> />
</div> </div>
......
...@@ -23,17 +23,35 @@ ...@@ -23,17 +23,35 @@
<template v-slot:body-cell-isDefault="rowData"> <template v-slot:body-cell-isDefault="rowData">
<q-td> <q-td>
<div align="center"> <div align="center">
<q-checkbox v-model="rowData.value" /> <q-checkbox
:true-value="1"
:false-value="2"
v-model="rowData.value"
/>
</div> </div>
</q-td> </q-td>
</template> </template>
<template v-slot:body-cell-action> <template v-slot:body-cell-action="item">
<q-td style="padding: 0" class="flex flex-center"> <q-td style="padding: 0; height: 100%">
<q-btn flat round color="primary" icon="mdi-information-outline"> <div align="center">
<q-btn
flat
round
color="primary"
icon="mdi-delete-outline"
@click="$emit('confirmDeleteAccBank', item)"
>
</q-btn> </q-btn>
<q-btn flat round color="primary" icon="mdi-minus-circle-outline"> <q-btn flat round color="primary" icon="mdi-circle-edit-outline">
</q-btn> </q-btn>
<q-btn flat round color="primary" icon="mdi-lock-outline"> </q-btn> </div>
</q-td>
</template>
<template v-slot:body-cell-STT="item">
<q-td style="padding: 0; height: 100%">
<div align="center">
{{ item.rowIndex + 1 }}
</div>
</q-td> </q-td>
</template> </template>
</q-table> </q-table>
......
import { defineComponent, ref } from 'vue';
export default defineComponent({
// name: 'ComponentName'
props: {
isBtn: {
type: Boolean,
default: false,
},
},
setup() {
const upload = ref(null);
const uploadBanner = () => {
// eslint-disable-next-line
// @ts-ignore
// eslint-disable-next-line
upload.value?.click();
};
return { uploadBanner, upload };
},
});
<template>
<q-card
@click="uploadBanner"
:class="{
'full-height full-width flex flex-center': !isBtn,
}"
bordered
>
<div
align="center"
:class="{
'flex flex-center q-py-xs': isBtn,
}"
>
<q-icon
name="mdi-plus-circle-outline"
:size="isBtn ? 'sm' : 'xl'"
></q-icon>
<div class="q-mt-xs">{{ $t('uploadImage.uploadBanner') }}</div>
</div>
<input
ref="upload"
hidden
type="file"
accept="image/png, image/jpeg"
@change="$emit('selectedFile', $event.target.files)"
/>
</q-card>
</template>
<script lang="ts" src="./UploadImage.ts"></script>
...@@ -450,4 +450,7 @@ export default { ...@@ -450,4 +450,7 @@ export default {
}, },
}, },
recordPerPage: 'Số bản ghi', recordPerPage: 'Số bản ghi',
uploadImage: {
uploadBanner: 'Tải lên Banner',
},
}; };
...@@ -65,6 +65,10 @@ ...@@ -65,6 +65,10 @@
<VabAccount <VabAccount
v-model:account="account" v-model:account="account"
v-model:short-description="shortDescription" v-model:short-description="shortDescription"
v-model:content="stories[0].content"
v-model:format-schedules="formatSchedules"
@selectedFile="selectedFile"
@deleteBanner="banners.splice($event, 1)"
:social-embedded="socialEmbedded" :social-embedded="socialEmbedded"
:banners="banners" :banners="banners"
:stories="stories" :stories="stories"
...@@ -73,6 +77,7 @@ ...@@ -73,6 +77,7 @@
<q-tab-panel name="bankAccount"> <q-tab-panel name="bankAccount">
<BankAccount <BankAccount
:bank-accounts="bankAccounts" :bank-accounts="bankAccounts"
@confirmDeleteAccBank="confirmDeleteAccBank"
@click:addBankBtn="isOpenAddAccountBankDialog = true" @click:addBankBtn="isOpenAddAccountBankDialog = true"
></BankAccount> ></BankAccount>
</q-tab-panel> </q-tab-panel>
......
...@@ -8,6 +8,7 @@ import { api, BaseResponseBody } from 'src/boot/axios'; ...@@ -8,6 +8,7 @@ import { api, BaseResponseBody } from 'src/boot/axios';
import { API_PATHS, config } from 'src/assets/configurations'; import { API_PATHS, config } from 'src/assets/configurations';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { AxiosResponse } from 'axios'; import { AxiosResponse } from 'axios';
import moment from 'moment';
import { import {
ArtistInfoType, ArtistInfoType,
FieldType, FieldType,
...@@ -19,6 +20,7 @@ import { ...@@ -19,6 +20,7 @@ import {
ProductType, ProductType,
BannerType, BannerType,
StoriesType, StoriesType,
SchedulesType,
} from 'src/assets/type'; } from 'src/assets/type';
export default defineComponent({ export default defineComponent({
...@@ -99,6 +101,8 @@ export default defineComponent({ ...@@ -99,6 +101,8 @@ export default defineComponent({
const shortDescription: Ref<string | null> = ref(''); const shortDescription: Ref<string | null> = ref('');
const socialEmbedded: Ref<string | null> = ref(''); const socialEmbedded: Ref<string | null> = ref('');
const stories: Ref<StoriesType[]> = ref([]); const stories: Ref<StoriesType[]> = ref([]);
const schedules: Ref<SchedulesType[]> = ref([]);
const formatSchedules: Ref<string[]> = ref([]);
const route = useRoute(); const route = useRoute();
//state accountBank //state accountBank
...@@ -107,7 +111,7 @@ export default defineComponent({ ...@@ -107,7 +111,7 @@ export default defineComponent({
const cardNumber: Ref<string | null | undefined> = ref(); const cardNumber: Ref<string | null | undefined> = ref();
const bankName: Ref<string | null | undefined> = ref(); const bankName: Ref<string | null | undefined> = ref();
const cardType: Ref<number | undefined> = ref(); const cardType: Ref<number | undefined> = ref();
const isDefault: Ref<number | undefined> = ref(); const isDefault: Ref<number | undefined> = ref(1);
const getInformationArtist = async () => { const getInformationArtist = async () => {
const response = (await api({ const response = (await api({
...@@ -122,7 +126,10 @@ export default defineComponent({ ...@@ -122,7 +126,10 @@ export default defineComponent({
artistCode.value = ArtistInformation.artistCode; artistCode.value = ArtistInformation.artistCode;
fullName.value = ArtistInformation.fullName; fullName.value = ArtistInformation.fullName;
artistName.value = ArtistInformation.artistName; artistName.value = ArtistInformation.artistName;
birthday.value = ArtistInformation.birthday; birthday.value = moment(
ArtistInformation.birthday,
'DD/MM/YYYY HH:mm:ss'
).format('YYYY-MM-DD');
address.value = ArtistInformation.address; address.value = ArtistInformation.address;
status.value = ArtistInformation.status; status.value = ArtistInformation.status;
phoneNumber.value = ArtistInformation.phoneNumber; phoneNumber.value = ArtistInformation.phoneNumber;
...@@ -139,11 +146,20 @@ export default defineComponent({ ...@@ -139,11 +146,20 @@ export default defineComponent({
fields.value = ArtistInformation.fields; fields.value = ArtistInformation.fields;
bankAccounts.value = ArtistInformation.bankAccounts; bankAccounts.value = ArtistInformation.bankAccounts;
products.value = ArtistInformation.products; products.value = ArtistInformation.products;
banners.value = ArtistInformation.banners; banners.value = ArtistInformation.banners || [];
socialEmbedded.value = ArtistInformation.socialEmbedded; socialEmbedded.value = ArtistInformation.socialEmbedded;
stories.value = ArtistInformation.stories; stories.value = ArtistInformation.stories;
}; schedules.value = ArtistInformation.schedules;
for (let index = 0; index < schedules.value.length; index++) {
const element = schedules.value[index];
formatSchedules.value.push(
moment(element.scheduleTime, 'DD/MM/YYYY HH:mm:ss').format(
'YYYY/MM/DD'
)
);
}
};
const getFieldOptions = async () => { const getFieldOptions = async () => {
const response = (await api({ const response = (await api({
url: API_PATHS.getFieldOptions, url: API_PATHS.getFieldOptions,
...@@ -196,7 +212,6 @@ export default defineComponent({ ...@@ -196,7 +212,6 @@ export default defineComponent({
workOptions.value = response.data.data; workOptions.value = response.data.data;
} }
}; };
const addAccBank = () => { const addAccBank = () => {
const newAccount = { const newAccount = {
accountNumber: accountNumber.value, accountNumber: accountNumber.value,
...@@ -208,6 +223,15 @@ export default defineComponent({ ...@@ -208,6 +223,15 @@ export default defineComponent({
bankAccounts.value.push(newAccount as BankAccountType); bankAccounts.value.push(newAccount as BankAccountType);
isOpenAddAccountBankDialog.value = false; isOpenAddAccountBankDialog.value = false;
}; };
const confirmDeleteAccBank = (value: number) => {
console.log(value, 'valueeee');
};
const selectedFile = (value: BannerType) => {
banners.value.push(value);
console.log(banners.value);
};
onMounted(() => { onMounted(() => {
void getInformationArtist(); void getInformationArtist();
void getFieldOptions(); void getFieldOptions();
...@@ -265,6 +289,10 @@ export default defineComponent({ ...@@ -265,6 +289,10 @@ export default defineComponent({
cardType, cardType,
isDefault, isDefault,
addAccBank, addAccBank,
schedules,
formatSchedules,
confirmDeleteAccBank,
selectedFile,
}; };
}, },
}); });
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
hide-pagination hide-pagination
> >
<template v-slot:body-cell-avatar="avatar"> <template v-slot:body-cell-avatar="avatar">
<q-td style="padding: 0" class="flex flex-center"> <q-td style="padding: 0; height: 100%" class="flex flex-center">
<q-img <q-img
style="width: 7rem" style="width: 7rem"
fit="contain" fit="contain"
......
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