change prices &...
This commit is contained in:
Vendored
+2
@@ -25,6 +25,7 @@ declare module 'vue' {
|
||||
ATag: typeof import('ant-design-vue/es')['Tag']
|
||||
ATextarea: typeof import('ant-design-vue/es')['Textarea']
|
||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||
AUpload: typeof import('ant-design-vue/es')['Upload']
|
||||
BaseDatePicker: typeof import('./src/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue')['default']
|
||||
Basic: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/basic.vue')['default']
|
||||
BasicActionSheet: typeof import('./src/components/BasicPacks/BasicActionSheet.vue')['default']
|
||||
@@ -54,6 +55,7 @@ declare module 'vue' {
|
||||
ListAnim: typeof import('./src/components/ListAnim.vue')['default']
|
||||
Mode: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/mode.vue')['default']
|
||||
PresettedRanges: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/presetted-ranges.vue')['default']
|
||||
ProfileAvatarUpload: typeof import('./src/components/ProfileAvatarUpload.vue')['default']
|
||||
RangePicker: typeof import('./src/components/BasicPacks/BaseDatePicker/src/datePick/demo/range-picker.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import useAxios from '@/utils/useAxios'
|
||||
|
||||
export interface AvatarUploadResponse {
|
||||
id: number
|
||||
src?: string
|
||||
full_src?: string
|
||||
title?: string
|
||||
}
|
||||
|
||||
/** POST multipart — expects backend route POST /customer/avatar */
|
||||
export const uploadAvatar = async (file: File) => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
return useAxios.postForm<AvatarUploadResponse>('/customer/avatar', formData)
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div class="flex flex-col items-center gap-2">
|
||||
<div class="relative">
|
||||
<div
|
||||
class="w-24 h-24 rounded-full overflow-hidden border-2 border-gray-200 bg-gray-100 flex items-center justify-center"
|
||||
>
|
||||
<img
|
||||
v-if="previewUrl"
|
||||
:src="previewUrl"
|
||||
alt="عکس پروفایل"
|
||||
class="w-full h-full object-cover"
|
||||
/>
|
||||
<BasicIcon v-else icon="vuesax-linear:user" size="40" color="#9CA3AF" />
|
||||
</div>
|
||||
<button
|
||||
v-if="previewUrl && !uploading"
|
||||
type="button"
|
||||
class="absolute bottom-0 left-0 z-10 p-1 rounded-full bg-white shadow"
|
||||
aria-label="حذف عکس"
|
||||
@click.stop="onRemove"
|
||||
>
|
||||
<BasicIcon icon="vuesax-linear:trash" class="text-red-600" size="18" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<a-upload
|
||||
name="file"
|
||||
:show-upload-list="false"
|
||||
accept="image/jpeg,image/png,image/webp,image/gif"
|
||||
:disabled="uploading"
|
||||
:before-upload="beforeUpload"
|
||||
:custom-request="customRequest"
|
||||
>
|
||||
<BasicButton size="small" type="default" :disabled="uploading">
|
||||
<a-spin v-if="uploading" size="small" class="ml-1" />
|
||||
{{ previewUrl ? 'تغییر عکس' : 'انتخاب عکس پروفایل' }}
|
||||
</BasicButton>
|
||||
</a-upload>
|
||||
<p class="text-xs text-gray-500 text-center">فرمت jpg، png یا webp — حداکثر ۲ مگابایت</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import { message, Upload } from 'ant-design-vue'
|
||||
import type { UploadProps } from 'ant-design-vue'
|
||||
|
||||
type UploadRequestOption = Parameters<NonNullable<UploadProps['customRequest']>>[0]
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import BasicIcon from '@/components/BasicPacks/BasicIcon.vue'
|
||||
import { uploadAvatar } from '@/api/avatar'
|
||||
import { getFileUrl } from '@/utils/file'
|
||||
|
||||
const props = defineProps<{
|
||||
imageUrl?: string | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'uploaded', payload: { id: number; url: string }): void
|
||||
(e: 'removed'): void
|
||||
}>()
|
||||
|
||||
const previewUrl = ref<string | null>(null)
|
||||
const uploading = ref(false)
|
||||
|
||||
watch(
|
||||
() => props.imageUrl,
|
||||
(url) => {
|
||||
previewUrl.value = url || null
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
function beforeUpload(file: File) {
|
||||
if (!file.type.startsWith('image/')) {
|
||||
message.error('فقط فایل تصویری مجاز است')
|
||||
return Upload.LIST_IGNORE
|
||||
}
|
||||
if (file.size / 1024 / 1024 > 2) {
|
||||
message.error('حجم تصویر نباید بیشتر از ۲ مگابایت باشد')
|
||||
return Upload.LIST_IGNORE
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
async function customRequest(options: UploadRequestOption) {
|
||||
const file = options.file as File
|
||||
uploading.value = true
|
||||
const localPreview = URL.createObjectURL(file)
|
||||
previewUrl.value = localPreview
|
||||
|
||||
try {
|
||||
const res = await uploadAvatar(file)
|
||||
const url = res.full_src || getFileUrl(res) || localPreview
|
||||
previewUrl.value = url
|
||||
if (res.id != null) {
|
||||
emit('uploaded', { id: res.id, url })
|
||||
message.success('عکس پروفایل آپلود شد')
|
||||
options.onSuccess?.(res)
|
||||
} else {
|
||||
throw new Error('invalid response')
|
||||
}
|
||||
} catch {
|
||||
previewUrl.value = props.imageUrl || null
|
||||
message.error('آپلود عکس انجام نشد. (احتمالاً API سرور هنوز آماده نیست)')
|
||||
options.onError?.(new Error('upload failed'))
|
||||
} finally {
|
||||
uploading.value = false
|
||||
if (localPreview.startsWith('blob:')) {
|
||||
URL.revokeObjectURL(localPreview)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onRemove() {
|
||||
previewUrl.value = null
|
||||
emit('removed')
|
||||
}
|
||||
</script>
|
||||
@@ -15,6 +15,7 @@ export interface Series {
|
||||
export interface Price {
|
||||
sell: number
|
||||
buy: number
|
||||
price: number
|
||||
price_last: number
|
||||
goldir:number
|
||||
}
|
||||
+5
-1
@@ -19,7 +19,11 @@ export interface User {
|
||||
name: string;
|
||||
active: boolean;
|
||||
mobile: string;
|
||||
avatar_id?: any;
|
||||
avatar_id?: number | null;
|
||||
avatar_url?: string | null;
|
||||
full_src?: string | null;
|
||||
avatar?: { id?: number; src?: string; full_src?: string; url?: string };
|
||||
file?: { id?: number; src?: string; full_src?: string; url?: string };
|
||||
last_seen_at: string;
|
||||
default_address_id?: any;
|
||||
sts?: any;
|
||||
|
||||
+2
-2
@@ -10,8 +10,8 @@ const projectName = getConfigApp('name')
|
||||
|
||||
export const baseURL: string = projectBase
|
||||
// export const baseURL: string = 'https://api-gholaktala.z23.ir/'
|
||||
// const baseUploadURL: string = '/site/file'
|
||||
// const uploadURL: string = baseURL + baseUploadURL
|
||||
/** Customer profile image upload (backend: POST /customer/avatar) */
|
||||
export const avatarUploadURL: string = `${projectBase.replace(/\/$/, '')}/customer/avatar`
|
||||
// const baseURLStorage: string = baseURL + '/v1'
|
||||
const prefixCls: string = 'noname'
|
||||
// const version: string = pkg.version
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { baseURL } from '@/themeConfig'
|
||||
import type { User } from '@/models/login'
|
||||
|
||||
export interface ProductFile {
|
||||
id?: number
|
||||
url?: string | null
|
||||
src?: string
|
||||
full_src?: string
|
||||
}
|
||||
|
||||
export function getFileUrl(file?: ProductFile | null): string | null {
|
||||
if (!file) return null
|
||||
if (file.full_src) return file.full_src
|
||||
if (file.url) return file.url
|
||||
if (!file.src) return null
|
||||
if (/^https?:\/\//i.test(file.src)) return file.src
|
||||
@@ -15,3 +18,12 @@ export function getFileUrl(file?: ProductFile | null): string | null {
|
||||
const path = file.src.replace(/^\//, '')
|
||||
return `${base}/${path}`
|
||||
}
|
||||
|
||||
/** Resolve profile avatar URL from GET /customer/me payload */
|
||||
export function getUserAvatarUrl(user?: User | null): string | null {
|
||||
if (!user) return null
|
||||
if (typeof user.avatar_url === 'string' && user.avatar_url) return user.avatar_url
|
||||
if (typeof user.full_src === 'string' && user.full_src) return user.full_src
|
||||
const nested = user.avatar || user.file
|
||||
return getFileUrl(nested as ProductFile | undefined)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="config.config.name === 'garoosi'" class="wrap-fix bottom-0 px-10 pb-3rem flex gap-2 bg-white">
|
||||
<a class="w-full" href="tel:09306612518">
|
||||
<a class="w-full" href="tel:09031265925">
|
||||
<BasicButton class="w-full" type="primary">تماس با پشتیبانی</BasicButton>
|
||||
</a>
|
||||
<a href="https://ble.ir/garoosigallery">
|
||||
|
||||
@@ -308,8 +308,17 @@ const finalPrice = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const payablePrice = computed(() => finalPrice.value)
|
||||
const equivalentPrice = computed(() => usePriceWithoutType(((isBuy ? price.value?.buy ?? 0 : price.value?.sell ?? 0) * (parseFloat(((form.value?.goldValue ?? 0) * 0.01).toFixed(4))) ).toFixed(0)) )
|
||||
const payablePrice = computed(() =>
|
||||
isBuy.value ? finalPrice.value + feeInRial.value : finalPrice.value - feeInRial.value
|
||||
)
|
||||
const feeInGrams = computed(() =>
|
||||
parseFloat(((form.value?.goldValue ?? 0) * 0.01).toFixed(4))
|
||||
)
|
||||
const unitPrice = computed(() =>
|
||||
(props?.ProductItem?.price_profit ?? 0) + (props?.ProductItem?.price ?? 0)
|
||||
)
|
||||
const feeInRial = computed(() => unitPrice.value * feeInGrams.value)
|
||||
const equivalentPrice = computed(() => usePriceWithoutType(feeInRial.value.toFixed(0)))
|
||||
|
||||
const disableTransaction = computed(() =>
|
||||
loading.value ||
|
||||
@@ -506,6 +515,28 @@ const limitedPrice = computed(() => {
|
||||
}
|
||||
}
|
||||
}*/
|
||||
function syncFormWithLatestPrice() {
|
||||
if (!price.value) return
|
||||
|
||||
const goldValue = form.value.goldValue
|
||||
if (goldValue !== undefined && goldValue !== null && goldValue !== '' && !isNaN(Number(goldValue))) {
|
||||
calculateCash(Number(goldValue))
|
||||
return
|
||||
}
|
||||
|
||||
const goldCash = form.value.goldCash
|
||||
if (goldCash !== undefined && goldCash !== null && goldCash !== '' && !isNaN(Number(goldCash))) {
|
||||
calculateGold(Number(goldCash))
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [basePriceValue.value, isBuy.value],
|
||||
() => {
|
||||
syncFormWithLatestPrice()
|
||||
}
|
||||
)
|
||||
|
||||
function calculateCash(val: number) {
|
||||
priceErrorVisible.value = false
|
||||
if (price.value) {
|
||||
@@ -597,10 +628,10 @@ const formatter = (value: number) => {
|
||||
const price = computed((): Price => <Price>lastPrice.value ?? 0)
|
||||
|
||||
const goldPriceValue = computed(() => {
|
||||
if (!price.value) return 0
|
||||
return isBuy.value
|
||||
? (price.value.buy ?? 0)
|
||||
: (price.value.sell ?? 0)
|
||||
if (!lastPrice.value?.price) return 0
|
||||
return isBuy.value
|
||||
? (lastPrice.value.buy ?? 0)
|
||||
: (lastPrice.value.sell ?? 0)
|
||||
})
|
||||
|
||||
async function initPrice() {
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
</div>
|
||||
|
||||
<div v-if="config.config.name === 'garoosi'" class="wrap-fix bottom-0 px-10 py-6 flex gap-2 bg-white">
|
||||
<a class="w-full" href="tel:09306612518">
|
||||
<a class="w-full" href="tel:09031265925">
|
||||
<BasicButton class="w-full" type="primary">تماس با پشتیبانی</BasicButton>
|
||||
</a>
|
||||
<a href="https://ble.ir/garoosigallery">
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
<div class="flex justify-between mt-3">
|
||||
<div>کارمزد:</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="font-bold text-xl">{{ parseFloat(((form.goldValue ?? 0) * (Number(feeAmount))).toFixed(4)) }}</div>
|
||||
<div class="font-bold text-xl">{{ feeInGrams }}</div>
|
||||
<div class="text-xs mr-1">گرم</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -274,10 +274,18 @@ const sellPagination = ref<TableEngineInput>({
|
||||
}], limit: 6, page: 0
|
||||
})
|
||||
|
||||
const finalPrice = computed(() => (form.value?.goldValue * (isBuy.value ? price.value?.buy ?? 0 : price.value?.sell ?? 0)))
|
||||
// const payablePrice = computed(() => finalPrice.value + finalPrice.value * 0.007)
|
||||
const payablePrice = computed(() => finalPrice.value)
|
||||
const equivalentPrice = computed(() => usePriceWithoutType(((isBuy ? price.value?.buy ?? 0 : price.value?.sell ?? 0) * (parseFloat(((form.value?.goldValue ?? 0) * 0.01).toFixed(4))) ).toFixed(0)) )
|
||||
const unitPrice = computed(() =>
|
||||
isBuy.value ? price.value?.buy ?? 0 : price.value?.sell ?? 0
|
||||
)
|
||||
const feeInGrams = computed(() =>
|
||||
parseFloat(((form.value?.goldValue ?? 0) * Number(feeAmount.value)).toFixed(4))
|
||||
)
|
||||
const finalPrice = computed(() => (form.value?.goldValue ?? 0) * unitPrice.value)
|
||||
const feeInRial = computed(() => unitPrice.value * feeInGrams.value)
|
||||
const equivalentPrice = computed(() => usePriceWithoutType(feeInRial.value.toFixed(0)))
|
||||
const payablePrice = computed(() =>
|
||||
isBuy.value ? finalPrice.value + feeInRial.value : finalPrice.value - feeInRial.value
|
||||
)
|
||||
|
||||
const disableTransaction = computed(() =>
|
||||
loading.value ||
|
||||
@@ -472,6 +480,28 @@ const limitedPrice = computed(() => {
|
||||
return walletStore?.limitedPrice[0]
|
||||
})
|
||||
|
||||
function syncFormWithLatestPrice() {
|
||||
if (!price.value) return
|
||||
|
||||
const goldValue = form.value.goldValue
|
||||
if (goldValue !== undefined && goldValue !== null && goldValue !== '' && !isNaN(Number(goldValue))) {
|
||||
calculateCash(Number(goldValue))
|
||||
return
|
||||
}
|
||||
|
||||
const goldCash = form.value.goldCash
|
||||
if (goldCash !== undefined && goldCash !== null && goldCash !== '' && !isNaN(Number(goldCash))) {
|
||||
calculateGold(Number(goldCash))
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => [lastPrice.value?.buy, lastPrice.value?.sell, isBuy.value],
|
||||
() => {
|
||||
syncFormWithLatestPrice()
|
||||
}
|
||||
)
|
||||
|
||||
function calculateCash(val: number) {
|
||||
priceErrorVisible.value = false
|
||||
// console.log(val)
|
||||
@@ -556,7 +586,8 @@ const formatter = (value: number) => {
|
||||
const price = computed((): Price => <Price>lastPrice.value ?? 0)
|
||||
|
||||
const goldPriceValue = computed(() => {
|
||||
if (!price.value) return 0
|
||||
// if (!price.value) return 0
|
||||
if (!lastPrice.value?.price) return 0
|
||||
return isBuy.value
|
||||
? (price.value.buy ?? 0)
|
||||
: (price.value.sell ?? 0)
|
||||
|
||||
@@ -66,7 +66,7 @@ const chartOptions = computed(() => {
|
||||
tickAmount: 8,
|
||||
show: false,
|
||||
labels: {
|
||||
formatter: (val: number) => toPersianNumber(usePrice(val)),
|
||||
formatter: (val: number) => toPersianNumber(usePrice(val, true, 'ه.ریال')),
|
||||
style: { fontSize: '13px', fontFamily }
|
||||
}
|
||||
},
|
||||
@@ -87,7 +87,7 @@ const chartOptions = computed(() => {
|
||||
})}`
|
||||
}
|
||||
},
|
||||
formatter: (val: number) => toPersianNumber(usePrice(val)),
|
||||
formatter: (val: number) => toPersianNumber(usePrice(val, true, 'ه.ریال')),
|
||||
style: { fontFamily }
|
||||
},
|
||||
colors: [config.config.color],
|
||||
|
||||
@@ -652,6 +652,24 @@ onMounted(async () => {
|
||||
})
|
||||
|
||||
async function initPrice() {
|
||||
try {
|
||||
// chartLoading.value = true
|
||||
await getLastPrices()
|
||||
// await setIntervalGetPrice()
|
||||
loading.value = true
|
||||
price.value = lastPrice.value
|
||||
/*props.ProductItem.price = lastPrice.value?.buy * props.ProductItem?.amount
|
||||
props.ProductItem.sellPrice = lastPrice.value?.sell * props.ProductItem?.amount*/
|
||||
props.ProductItem.price = lastPrice?.value?.price? (lastPrice?.value?.price + props.ProductItem?.cash_fee_buy) * props.ProductItem?.amount: 0
|
||||
props.ProductItem.sellPrice = lastPrice?.value?.price? (lastPrice?.value?.price - props.ProductItem?.percent_fee_sell) * props.ProductItem?.amount:0
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
// chartLoading.value = false
|
||||
}
|
||||
}
|
||||
/*async function initPrice() {
|
||||
try {
|
||||
// chartLoading.value = true
|
||||
await getLastPrices()
|
||||
@@ -666,7 +684,7 @@ async function initPrice() {
|
||||
loading.value = false
|
||||
// chartLoading.value = false
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// onMounted(() => {
|
||||
// initPrice()
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="config.config.name === 'garoosi'" class="wrap-fix bottom-0 px-10 pb-3rem flex gap-2 bg-white">
|
||||
<a class="w-full" href="tel:09306612518">
|
||||
<a class="w-full" href="tel:09031265925">
|
||||
<BasicButton class="w-full" type="primary">تماس با پشتیبانی</BasicButton>
|
||||
</a>
|
||||
<a href="https://ble.ir/garoosigallery">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<!-- <img :src="permission1" alt="" class="w-full">-->
|
||||
<div class="mt-5 text-xs"></div>
|
||||
<div v-if="config.config.name === 'garoosi'" class="wrap-fix bottom-0 px-10 pb-3rem flex gap-2 bg-white">
|
||||
<a class="w-full" href="tel:09306612518">
|
||||
<a class="w-full" href="tel:09031265925">
|
||||
<BasicButton class="w-full" type="primary">تماس با پشتیبانی</BasicButton>
|
||||
</a>
|
||||
<a href="https://ble.ir/garoosigallery">
|
||||
|
||||
@@ -14,6 +14,17 @@
|
||||
<div
|
||||
class="border-gray-200 border-1 rounded-xl p-5 trans flex flex-col items-center mx-5 z-1000 relative bg-white shadow-lg"
|
||||
>
|
||||
<!-- <div
|
||||
class="w-20 h-20 rounded-full overflow-hidden border-2 border-gray-200 bg-gray-100 flex items-center justify-center mb-3"
|
||||
>
|
||||
<img
|
||||
v-if="profileAvatarUrl"
|
||||
:src="profileAvatarUrl"
|
||||
alt="عکس پروفایل"
|
||||
class="w-full h-full object-cover"
|
||||
/>
|
||||
<BasicIcon v-else icon="vuesax-linear:user" size="36" color="#9CA3AF" />
|
||||
</div>-->
|
||||
<div class="text-primary font-bold w-full text-center flex justify-between">
|
||||
نام و نام خانوادگی:
|
||||
<div class="mr-2">{{ userStore.userInfo?.name }}</div>
|
||||
@@ -189,6 +200,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="h60vh overflow-y-auto pb20">
|
||||
<!-- <ProfileAvatarUpload
|
||||
:image-url="editAvatarUrl"
|
||||
class="mb-4"
|
||||
@uploaded="onAvatarUploaded"
|
||||
@removed="onAvatarRemoved"
|
||||
/>-->
|
||||
<a-form ref="formRef" :model="userFormState" class="!mt-5" name="basic" @finish="ok">
|
||||
<a-form-item :rules="[isValidPersian()]" label="نام" name="fname">
|
||||
<BasicInput v-model:value="userFormState.fname" />
|
||||
@@ -266,7 +283,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, reactive, ref, computed } from 'vue'
|
||||
import { onMounted, ref, computed, watch } from 'vue'
|
||||
import img from '@/assets/img/user_ly1.svg'
|
||||
import gr_bottom from './assets/img/gr_bottom_white.svg'
|
||||
import { loading } from '@/utils'
|
||||
@@ -289,6 +306,8 @@ import { message } from 'ant-design-vue'
|
||||
import { updateMe, updatePass } from '@/api/me'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import BaseDatePicker from '@/components/BasicPacks/BaseDatePicker'
|
||||
import ProfileAvatarUpload from '@/components/ProfileAvatarUpload.vue'
|
||||
import { getUserAvatarUrl } from '@/utils/file'
|
||||
import { useConfigStore } from '@/store/configStore'
|
||||
import { getConfigApp, getReferralShareText, getReferralShareTitle } from '../../../utils/config'
|
||||
|
||||
@@ -311,11 +330,39 @@ const nameProject = useConfigStore().config.name_fa
|
||||
// const editPassVisible = ref<boolean>(false)
|
||||
const editPassVisible = ref<boolean>(false)
|
||||
const editPasswordVisible = ref<boolean>(false)
|
||||
const localAvatarUrl = ref<string | null>(null)
|
||||
|
||||
const profileAvatarUrl = computed(() => localAvatarUrl.value || getUserAvatarUrl(userStore.userInfo))
|
||||
|
||||
const editAvatarUrl = computed(() => localAvatarUrl.value || getUserAvatarUrl(userFormState.value))
|
||||
|
||||
function setForm() {
|
||||
userFormState.value = userStore.userInfo
|
||||
userFormState.value = { ...userStore.userInfo } as User
|
||||
localAvatarUrl.value = getUserAvatarUrl(userStore.userInfo)
|
||||
}
|
||||
|
||||
function onAvatarUploaded({ id, url }: { id: number; url: string }) {
|
||||
userFormState.value.avatar_id = id
|
||||
localAvatarUrl.value = url
|
||||
if (userStore.userInfo) {
|
||||
userStore.userInfo.avatar_id = id
|
||||
userStore.userInfo.avatar_url = url
|
||||
}
|
||||
}
|
||||
|
||||
function onAvatarRemoved() {
|
||||
userFormState.value.avatar_id = null
|
||||
localAvatarUrl.value = null
|
||||
if (userStore.userInfo) {
|
||||
userStore.userInfo.avatar_id = null
|
||||
userStore.userInfo.avatar_url = null
|
||||
}
|
||||
}
|
||||
|
||||
watch(editPassVisible, (open) => {
|
||||
if (open) setForm()
|
||||
})
|
||||
|
||||
function copyCode() {
|
||||
// nextTick(() => {
|
||||
const val = userStore.userInfo?.referral_id
|
||||
@@ -386,9 +433,9 @@ function ok() {
|
||||
loading.value = true
|
||||
await updateMe(userFormState.value)
|
||||
await userStore.getMyInfo()
|
||||
localAvatarUrl.value = getUserAvatarUrl(userStore.userInfo)
|
||||
editPassVisible.value = false
|
||||
message.success('اطلاعات شما با موفقیت به روز رسانی شد')
|
||||
location.reload()
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user