1404/10/28-base

This commit is contained in:
2026-01-18 13:01:46 +03:30
parent f95b0cef95
commit 9d96ae106b
455 changed files with 58164 additions and 0 deletions
+122
View File
@@ -0,0 +1,122 @@
import { tokenName } from '@/themeConfig'
import { ref } from 'vue'
export const loading = ref<boolean>(false)
export const loadingMore = ref<boolean>(false)
const userInfo = ref()
function setToken(token: string | undefined) {
return localStorage.setItem(tokenName, token)
}
function setFingerPrint(val: string | undefined) {
return localStorage.setItem('finger', val)
}
function getToken() {
return localStorage.getItem(tokenName)
}
function getIsActiveFingerprint() {
return localStorage.getItem('finger') === 'true'
}
export async function authenticateWithFingerprint() {
const challenge = new Uint8Array(32)
window.crypto.getRandomValues(challenge)
const createOptions = {
challenge,
rp: { name: 'GOLD.IR' },
user: {
id: Uint8Array.from('user-id', c => c.charCodeAt(0)),
name: 'GOLD.IR',
displayName: 'GOLD.IR'
},
pubKeyCredParams: [{ type: 'public-key', alg: -7 }],
authenticatorSelection: {
authenticatorAttachment: 'platform',
userVerification: 'required'
},
timeout: 60000,
attestation: 'direct'
}
try {
const credential = await navigator.credentials.create({ publicKey: createOptions })
console.log('Credential با موفقیت ایجاد شد!')
const credentialId = btoa(String.fromCharCode(...new Uint8Array(credential.rawId)))
// بازیابی توکن از localStorage
const token = localStorage.getItem('GOLD.IR_app_token')
if (!token) {
console.warn('توکن پیدا نشد، عملیات متوقف شد.')
return false
}
// Success, proceed with login using token
// Perform your login action here
return true
} catch (error) {
const errorMessage = error.name === 'NotAllowedError'
? 'احراز هویت لغو شد یا دسترسی مجاز نبود.'
: 'عملیات ناموفق بود. لطفاً دوباره امتحان کنید.'
console.error(errorMessage, error)
return false
}
}
function removeToken() {
return localStorage.removeItem(tokenName)
}
function removeFingerPrint() {
return localStorage.removeItem('finger')
}
/*const userType = computed(()=>{
console.log('salam',router.currentRoute.value.fullPath)
if (router.currentRoute.value.fullPath.split('/')[1] === 'customer') return 'customer'
else return 'user'
})*/
function URLUserType() {
/* console.log('salam', router.currentRoute.value.fullPath.split('/'))
console.log('salam', router.currentRoute.value.fullPath)*/
/* console.log('salam', location.host.split('.')[0] === 'app')
console.log('salam', location.host)
console.log('salam', location.host.split('.'))*/
if (location.host.split('.')[0] === 'app') return 'single'
else return 'customer'
}
function toFixedDownThreeChar(num: number) {
return Math.floor(num * 1000) / 1000
}
function isIphone() {
const userAgent = navigator.userAgent.toLowerCase()
// const isAndroid = /Android/.test(userAgent);
return /iPhone/.test(userAgent)
}
export {
getToken,
setToken,
removeToken,
URLUserType,
toFixedDownThreeChar,
isIphone,
removeFingerPrint,
getIsActiveFingerprint,
setFingerPrint
}
+245
View File
@@ -0,0 +1,245 @@
/*
export function inputRules(title?: string) {
if (title) {
return [required(title)]
} else {
return [required]
}
}
export function inputLenRules(len: number, title?: string) {
if (title) {
return [
required(title),
lenthValidation(len)
]
} else {
return [
required,
lenthValidation(len)
]
}
}
*/
/*export const persianValidation = computed(() => {
const temp = inputRules()
temp.push({ pattern: /^[A-Za-z]*$/, message: 'فقط حروف انگلیسی مجاز است' })
return temp
})*/
import {computed, ref} from 'vue'
import type {Rule} from 'ant-design-vue/es/form'
import {useWalletStore} from "@/store/walletStore";
export const mobileValidation = (title?: string) => {
return {len: 11, message: `شماره همراه باید 11 رقم باشد`}
}
export const required = (title?: string) => {
if (title) {
return {required: true, message: `پر کردن ${title} الزامی است`}
} else {
return {required: true, message: `پر کردن مورد بالا الزامی است`}
}
}
// function checkCodeMeli(code)
// {
//
// let L=code.length;
// if(L<8 || parseInt(code,10)==0) return false;
// code=('0000'+code).substr(L+4-10);
// if(parseInt(code.substr(3,6),10)==0) return false;
// let c=parseInt(code.substr(9,1),10);
// let s=0;
// for(let i=0;i<9;i++)
// s+=parseInt(code.substr(i,1),10)*(10-i);
// s=s%11;
// return (s<2 && c==s) || (s>=2 && c==(11-s));
//
// }
export const cardNumberValidation = (title?: string) => {
return { len: 16, message: `شماره کارت باید 16 رقم باشد` }
}
const isValidNationalCode = (code) => {
if (code.length !== 10 || /(\d)(\1){9}/.test(code)) return false
let sum = 0,
chars = code.split(''),
lastDigit,
remainder
for (let i = 0; i < 9; i++) sum += +chars[i] * (10 - i)
remainder = sum % 11
lastDigit = remainder < 2 ? remainder : 11 - remainder
return +chars[9] === lastDigit
}
export const requireNationalCode = (code?: string) => {
return {required: true, validator: validateNCode, trigger: 'change'}
}
async function validateNCode(rule: Rule, value: any) {
if (!value) {
return Promise.reject('وارد کردن کد ملی الزامیست')
}
if (isValidNationalCode(value)) return Promise.resolve()
else return Promise.reject('کد ملی وارد شده نامعتبر است')
}
export function inputLenRules(len: number, title?: string) {
if (title) {
return [
{required: true, message: `پر کردن ${title} الزامی است`},
{len: len, message: `تعداد کاراکتر باید ${len} عدد باشد`}
]
} else {
return [
{required: true, message: 'پر کردن مورد بالا الزامی است'},
{len: len, message: `تعداد کاراکتر باید ${len} عدد باشد`}
]
}
}
export const persianValidation = computed(() => {
return {
pattern: /^[A-Za-z]*$/,
message: 'فقط حروف انگلیسی مجاز است'
}
})
export const isValidPersian = () => {
return {
pattern: /^[\u0600-\u06FF\s]+$/,
message: 'فقط حروف فارسی مجاز است'
}
};
export const lengthValidation = (len: number) => {
return {len: len, message: `تعداد کاراکتر باید ${len} عدد باشد`}
}
export const justNumber = () => {
return {
required: true,
type: 'regexp',
pattern: /\d+/g,
message: 'لطفا اطلاعات را به صورت عدد و نقطه وارد کنید'
}
}
const walletCash = useWalletStore()
let priceP = 0
let methodP = 'cash'
let amountP =0
let isBuyP=true
let NumP=0
const checkNumber = async (_rule: Rule, value: number) => {
if (!value) {
return Promise.reject('تعداد محصول را مشخص کنید');
}
if (value % 1 !== 0) {
return Promise.reject('استفاده از اعداد اعشاری مجاز نمی باشد')
}
if (isBuyP){
if (!walletCash?.walletInfo?.cash && methodP == 'cash'){
return Promise.reject('موجودی کیف پول ناکافی است')
}
if (!walletCash?.walletInfo?.gold && methodP == 'gold'){
return Promise.reject('موجودی کیف طلا ناکافی است')
}
if (priceP * value > walletCash?.walletInfo?.cash && methodP == 'cash')
return Promise.reject('موجودی کیف پول ناکافی است')
if (amountP * value > walletCash?.walletInfo?.gold && methodP == 'gold')
return Promise.reject('موجودی کیف طلا ناکافی است')
else
return Promise.resolve();
}else {
if (value > NumP)
return Promise.reject('موجودی محصول ناکافی است')
else
return Promise.resolve();
}
}
export const justNumber2 = (price: number, method?: string , amount?:number ,isBuy?:boolean) => {
priceP = price
methodP = method
amountP=amount
isBuyP=isBuy
return {
required: true,
validator: checkNumber,
trigger: 'change'
}
}
export const justNumber3 = (price: number, Num?:number ,isBuy?:boolean) => {
priceP = price
NumP=Num
isBuyP=isBuy
return {
required: true,
validator: checkNumber,
trigger: 'change'
}
}
export const ruleNumber = () => {
console.log('445455')
return {
required: true,
message: 'لطفا نحوه خرید',
trigger: 'change'
}
}
export const guideTypePassword = ref<{}>({
text: '',
color: ''
})
export const passwordRules = () => {
return [
{
validator: (rule: Rule, value: any) => {
if (value.length < 6) {
return Promise.reject('رمز عبور حداقل 6 رقم')
}
const lengthCriteria = value.length >= 8
const letterCriteria = /[A-Za-z]/.test(value)
const numberCriteria = /\d/.test(value)
const specialCharacterCriteria = /[@$!%*#?&]/.test(value)
const criteriaMet = [
lengthCriteria,
letterCriteria,
numberCriteria,
specialCharacterCriteria
].filter(Boolean).length
if (criteriaMet === 4) {
guideTypePassword.value = {
text: 'سطح : قوی',
color: 'text-green'
}
return Promise.resolve();
} else if (criteriaMet === 3) {
guideTypePassword.value = {
text: 'سطح : متوسط',
color: 'midLevel'
}
return Promise.resolve();
} else {
guideTypePassword.value = {
text: 'سطح : ضعیف',
color: 'week'
}
return Promise.resolve();
}
}
}
]
}
+87
View File
@@ -0,0 +1,87 @@
import {loading} from '@/utils/index'
import {getLastPrice, getPrice} from '@/api/home'
import {ref} from 'vue'
import type {Price} from '@/models/home'
let interval: any
export const price = ref<Price>()
export const lastPrice = ref<Price>()
export const olderPrice = ref<number| undefined>(0)
export async function setIntervalGetAllPrice() {
// console.log('salam')
try {
interval = setInterval(async () => {
await getLastPrices()
await getUpPrice()
}, 10000)
} catch (e) {
console.log(e)
} finally {
loading.value = false
}
}
export async function setIntervalGetLastPrice() {
// console.log('salam')
try {
interval = setInterval(async () => {
await getLastPrices()
// await getUpPrice()
}, 10000)
} catch (e) {
console.log(e)
} finally {
loading.value = false
}
}
export async function getUpPrice() {
try {
// loading.value = true
const data = await getPrice()
// const dataLast = await getLastPrice()
// if (lastPrice.value?.price_last != dataLast.price_last) {
// olderPrice.value = lastPrice.value?.price_last
// }
price.value = data
// lastPrice.value = dataLast
} catch (e) {
console.log(e)
} finally {
// loading.value = false
}
}
export async function getLastPrices() {
try {
// loading.value = true
// const data = await getPrice()
const dataLast = await getLastPrice()
if (lastPrice.value?.price_last != dataLast.price_last) {
olderPrice.value = lastPrice.value?.price_last
}
// price.value = data
lastPrice.value = dataLast
} catch (e) {
console.log(e)
} finally {
// loading.value = false
}
}
export function stopPriceInterval() {
// console.log('stop')
clearInterval(interval);
}
export function percentPriceChanged() {
// console.log(olderPrice.value)
// console.log(lastPrice.value?.price_last)
if (!olderPrice.value)
return 0
return ((lastPrice.value?.price_last-olderPrice.value) *100)/olderPrice.value
}
+178
View File
@@ -0,0 +1,178 @@
import {baseURL} from '@/themeConfig'
import type {AxiosRequestConfig, AxiosResponse} from 'axios'
import axios from 'axios'
import {getToken, removeToken} from "@/utils";
import router from "@/router";
import {get} from 'lodash'
import {message} from "ant-design-vue";
interface Meta {
errorMessage?: 'message' | 'notification' | 'toast' | 'none'
}
interface MyAxiosRequestConfig<D = any> extends AxiosRequestConfig<D> {
meta?: Meta
}
const headers = {
'Content-Type': 'application/json',
Accept: 'application/json',
}
const _axios = axios.create({
baseURL,
headers,
})
_axios.interceptors.request.use(
(config) => {
//console.log('request config', config)
if (config.headers) {
const token = getToken()
if (token) {
//@ts-ignore
config.headers['Authorization'] = 'Bearer ' + token
}
}
return config
},
(error) => {
//console.log('this is error on interceptors.request', error)
Promise.reject(error)
},
)
_axios.interceptors.response.use(
(response) => {
//console.log('this is response')
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
//console.log('this is fulfilled on interceptors.response', response.data)
return response.data
},
async function (error) {
console.log('this is axios error', error)
if (error.response.data && error.response.data.message) {
checkStatus(error.response.data.message, error.response.status, error.config)
}
//console.log('this is error on interceptors.response', error.config.meta)
/* if (error.response && (error.response.status == 401 || error.response.status == 400)) {
//debugger
removeToken()
router.push({ name: 'login' })
}*/
if (error.response && error.response.status == 401) {
///removeToken()
console.log('error')
removeToken()
// router.push({ name: 'login' })
await router.push({name: 'login'})
} else if (error.response && error.response.status == 403) {
message.error('شما دسترسی لازم برای انجام این عملیات را ندارید')
} else if (error.response && error.response.status == 422) {
// message.error(error.response.data?.message)
} else if (error.response) {
message.error('خطا در بارگذاری اطلاعات')
}
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
//const { response, code, message, config } = error || {}
//const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none'
//const msg: string = response?.data?.error?.message ?? ''
//checkStatus(error?.response?.status, msg)
return Promise.reject(error)
})
function checkStatus(msg: string, code: number, config: any) {
//const { code, data, message } = data
const errorMessage = get(config, 'meta.errorMessage', 'message')
/*if (config.meta) {
if (config.meta.message) {
errorMessage = config.meta.message
}
}*/
console.log('this is config', config)
if (errorMessage == 'none') return
switch (errorMessage) {
case 'message':
message.error(msg)
break
default:
message.error(msg)
}
}
const myAxios = {
//AxiosResponse<T>
post<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.post(url, data, config)
},
request<T = any, R = AxiosResponse<T>, D = any>(config: MyAxiosRequestConfig<D>): Promise<R> {
return _axios.request(config)
},
//AxiosResponse<T>
get<T = any, R = T, D = any>(url: string, config?: MyAxiosRequestConfig<D>): Promise<R> {
return _axios.get(url, config)
},
//AxiosResponse<T>
delete<T = any, R = T, D = any>(url: string, config?: MyAxiosRequestConfig<D>): Promise<R> {
return _axios.delete(url, config)
},
//AxiosResponse<T>
head<T = any, R = T, D = any>(url: string, config?: MyAxiosRequestConfig<D>): Promise<R> {
return _axios.head(url, config)
},
//AxiosResponse<T>
options<T = any, R = T, D = any>(url: string, config?: MyAxiosRequestConfig<D>): Promise<R> {
return _axios.options(url, config)
},
//AxiosResponse<T>
put<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.put(url, data, config)
},
//AxiosResponse<T>
patch<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.patch(url, data, config)
},
//AxiosResponse<T>
postForm<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.postForm(url, data, config)
},
//AxiosResponse<T>
putForm<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.putForm(url, data, config)
},
//AxiosResponse<T>
patchForm<T = any, R = T, D = any>(
url: string,
data?: D,
config?: MyAxiosRequestConfig<D>,
): Promise<R> {
return _axios.patchForm(url, data, config)
},
}
export default myAxios
export {_axios}
+8
View File
@@ -0,0 +1,8 @@
export function useCardNumber(val: number) {
const str = val.toString()
return `${str.substring(0,4)}\xa0\xa0\xa0\xa0\xa0\xa0${str.substring(4,8)}\xa0\xa0\xa0\xa0\xa0\xa0${str.substring(8,12)}\xa0\xa0\xa0\xa0\xa0\xa0${str.substring(12,16)}`
}
export function useShabaNumber(val: number) {
const str = val.toString()
return `IR${str.substring(0,4)}\xa0\xa0\xa0${str.substring(4,8)}\xa0\xa0\xa0${str.substring(8,12)}\xa0\xa0\xa0${str.substring(12,16)}\xa0\xa0\xa0${str.substring(16,20)}\xa0\xa0\xa0${str.substring(20,24)}`
}
+127
View File
@@ -0,0 +1,127 @@
import { Modal } from 'ant-design-vue'
import { createVNode } from 'vue'
import { ExclamationCircleOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue/es'
//todo
export async function confirmDeleteItem(
type: string,
id: number,
functionDelete: (id: number) => Promise<any>,
refreshTable: () => void
) {
Modal.confirm({
title: `آیا از حذف ${type} اطمینان دارید؟`,
icon: createVNode(ExclamationCircleOutlined),
okText: 'تایید',
okType: 'danger',
centered: true,
cancelText: 'انصراف',
async onOk() {
// console.log('OK');
// await deleteItem(id)
// loading.value = true
// table?.value?.spinTable(true)
// @ts-ignore
try {
await functionDelete(id)
refreshTable()
console.log('finall')
message.success('با موفقیت حذف شد')
} catch (e) {
console.error(e)
// message.error('خطا در حذف')
}
// setTimeout(Math.random() > 0.5 ? resolve : reject, 1000)
// table?.value?.fetch()
// loading.value = false
// table?.value?.spinTable(false)
},
onCancel() {
console.log('Cancel')
}
})
}
export async function confirmActOnApi(
title: string,
id: number,
functionApi: (id: number) => Promise<any>,
refreshTable: () => void
) {
Modal.confirm({
title: title,
icon: createVNode(ExclamationCircleOutlined),
okText: 'تایید',
okType: 'danger',
centered: true,
cancelText: 'انصراف',
async onOk() {
// console.log('OK');
// await deleteItem(id)
// loading.value = true
// table?.value?.spinTable(true)
// @ts-ignore
try {
await functionApi(id)
refreshTable()
// console.log('finall')
message.success('با موفقیت انجام شد')
} catch (e) {
console.error(e)
// message.error('خطا در حذف')
}
// setTimeout(Math.random() > 0.5 ? resolve : reject, 1000)
// table?.value?.fetch()
// loading.value = false
// table?.value?.spinTable(false)
},
onCancel() {
console.log('Cancel')
}
})
}
export default async function baseConfirm(
title: string,
actionFunction: () => void,
) {
Modal.confirm({
title: title,
icon: createVNode(ExclamationCircleOutlined),
okText: 'تایید',
okType: 'danger',
centered: true,
cancelText: 'انصراف',
async onOk() {
// console.log('OK');
// await deleteItem(id)
// loading.value = true
// table?.value?.spinTable(true)
// @ts-ignore
try {
await actionFunction()
// console.log('finall')
// message.success('با موفقیت انجام شد')
} catch (e) {
console.error(e)
// message.error('خطا در حذف')
}
// setTimeout(Math.random() > 0.5 ? resolve : reject, 1000)
// table?.value?.fetch()
// loading.value = false
// table?.value?.spinTable(false)
},
onCancel() {
console.log('Cancel')
}
})
}
+90
View File
@@ -0,0 +1,90 @@
import { onMounted, ref } from 'vue'
import moment from 'moment'
//sample 00:30 - 1:50 - 00:59
export default function useCountdownTimer(_time = '00:00:30', format = 'HH:mm:ss') {
let interval: number
let startTime = moment(_time, 'HH:mm:ss')
//const isActiveMenu=
const endTime = moment('00:00:00', 'HH:mm:ss')
const time = ref('')
let tempHook: () => void
let tempHookStop: () => void
let tempHookStart: () => void
let tempHookRestart: () => void
function decrement() {
if (startTime > endTime) {
startTime.subtract('1', 'second')
time.value = startTime.format(format)
} else {
clearInterval(interval)
if (tempHook) {
tempHook()
}
}
}
function start() {
if (interval) {
stop()
}
interval = setInterval(decrement, 1000)
if (tempHookStart) {
tempHookStart()
}
}
function stop() {
clearInterval(interval)
if (tempHookStop) {
tempHookStop()
}
}
function onFinish(hook: () => any) {
tempHook = hook
}
function setTime(_time = '00:00:30') {
startTime = moment(_time, 'HH:mm:ss')
time.value = startTime.format(format)
stop()
start()
}
function reset() {
startTime = moment(_time, 'HH:mm:ss')
time.value = startTime.format(format)
stop()
start()
if (tempHookRestart) {
tempHookRestart()
}
}
function onStop(hook: () => any) {
tempHookStop = hook
}
function onStart(hook: () => any) {
tempHookStart = hook
}
function onRestart(hook: () => any) {
tempHookRestart = hook
}
onMounted(() => {
time.value = startTime.format(format)
})
return {
time,
stop,
start,
onFinish,
reset,
setTime,
onRestart,
onStart,
onStop,
}
}
+54
View File
@@ -0,0 +1,54 @@
//@ts-ignore
import moment from 'moment-jalaali'
//@ts-ignore
import fa from 'moment/src/locale/fa'
moment.locale('fa', fa)
moment.loadPersian()
function momentTimeAgo(dataTime: string) {
return moment.utc(dataTime).fromNow()
}
function toJalali(dateTime: string, format = 'jYYYY/jMM/jDD-HH:mm') {
return moment.utc(dateTime).format(format)
}
function toJalaliOutOfUTC(dateTime: string, format = 'jYYYY/jMM/jDD-HH:mm') {
const date = new Date()
date.setHours(3, 30)
return moment.utc(dateTime).format(format)
}
function toJalaliNotime(dateTime: string, format = 'jYYYY/jMM/jDD') {
return moment.utc(dateTime).format(format)
}
function toTime(dateTime: string, format = 'HH:mm:ss') {
return moment.utc(dateTime).format(format)
}
function diffDateByYearMontDay(date: string) {
const a = moment(date)
const b = moment()
const years = a.diff(b, 'year')
b.add(years, 'years')
const months = a.diff(b, 'months')
b.add(months, 'months')
const days = a.diff(b, 'days')
let tempStr = ''
if (years != 0) {
tempStr += years + ' سال'
}
if (months != 0) {
if (tempStr.length > 0) tempStr += ' و '
tempStr += months + ' ماه'
}
if (days != 0) {
if (tempStr.length > 0) tempStr += ' و '
tempStr += days + ' روز'
}
return tempStr
}
export {momentTimeAgo, toJalali, diffDateByYearMontDay, toTime, toJalaliNotime, toJalaliOutOfUTC}
+8
View File
@@ -0,0 +1,8 @@
import { prefixCls } from "@/themeConfig";
export function usePrefix(name = "") {
return {
prefixVar: prefixCls,
prefixCls: `${prefixCls}-${name}`,
};
}
+26
View File
@@ -0,0 +1,26 @@
export function usePrice(price: number, digit = true, unit = 'ریال') {
price= price??0
let _price = price.toString()
if (digit) {
_price = _price.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
return `${_price} ${unit}`
}
export function usePriceWithoutType(price?: number, digit = true, unit = 'ریال') {
let _price = price?.toString()
if (digit) {
_price = _price?.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
return `${_price}`
}
export function useTowDecimal(num: string | number): string | number {
const temp = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)
if (temp && temp.length > 0) return temp[0]
return Math.round(+num * 100) / 100
}
export function useFormat(num: string | number, unit = '') {
return usePrice(Math.abs(+useTowDecimal(num)), true, unit)
}
+147
View File
@@ -0,0 +1,147 @@
import { get } from 'lodash'
import type { Ref } from 'vue'
import type { Product, ProductVariant } from '@/model/product'
import { unref, computed } from 'vue'
// import noImage from '@/assets/img/logo.svg'
import type { UploadedFileInfo } from '@/model/uploadedFileInfo'
export function useProduct(product: Ref<Product> | Product) {
const title = computed(() => {
return get(unref(product), 'title_fa', '')
})
const price = computed<number>(() => {
if (unref(product).price) return unref(product).price as number
return 0
})
const brand = computed(() => {
if (unref(product).brand) return unref(product).brand
return '-'
})
const country = computed(() => {
if (unref(product).country) return unref(product).country
return '-'
})
const gallery = computed(() => {
return get(unref(product), 'gallery', [])
})
const body = computed(() => {
return get(unref(product), 'body', '')
})
const typeUse = computed(() => {
return get(unref(product), 'type_use', '')
})
const pageDesign = computed(() => {
return get(unref(product), 'page_design', '-')
})
const motor = computed(() => {
return get(unref(product), 'page_design', '-')
})
const primaryAttributes = computed(() => {
return [
{ title: 'نوع کاربری', name: typeUse.value },
{ title: 'برند', name: brand.value },
{ title: 'کشور سازنده', name: country.value },
{ title: 'جنس بدنه', name: 'فلزی-آلومینیوم' },
]
})
const moreAttributes = computed(() => {
return [
{ title: 'جنسیت', name: gender.value },
{ title: 'موتور', name: motor.value },
{ title: 'شیشه', name: glass.value },
{ title: 'جنس قاب', name: frame.value },
{ title: 'جنس بند', name: wristlet.value },
{ title: 'نوع قفل بند', name: buckleType.value },
{ title: 'سال ساخت', name: yearCreate.value },
{ title: 'گارانتی', name: warranty.value },
{ title: 'طرح صفحه', name: pageDesign.value },
{ title: 'شکل قاب', name: frameShape.value },
]
})
const frame = computed(() => {
return get(unref(product), 'frame', '-')
})
const warranty = computed(() => {
return unref(product).warranty == 1 ? 'بله' : 'خیر'
})
const buckleType = computed(() => {
return get(unref(product), 'buckle_type', '-')
})
const variants = computed<ProductVariant[]>(() => {
return get(unref(product), 'variants', [])
})
const originalImage = computed<UploadedFileInfo | null>(() => {
//TODO: remove if not find default image
return get(unref(product), 'original_image', null)
})
function variantImage(variant: ProductVariant) {
const temp = variants.value.find((item) => item.id == variant.id)
if (temp && temp.file) {
return temp.file.src
}
return 'GOLD.IR'
}
const collection = computed(() => {
return get(unref(product), 'collection.title', '-')
})
const glass = computed(() => {
return get(unref(product), 'glass', '-')
})
const frameShape = computed(() => {
return get(unref(product), 'frame_shape', '-')
})
const wristlet = computed(() => {
return get(unref(product), 'wristlet', '-')
})
const gender = computed(() => {
return get(unref(product), 'gender_str', '-')
})
const yearCreate = computed(() => {
return get(unref(product), 'year_create', '-')
})
return {
title,
price,
brand,
country,
gallery,
body,
primaryAttributes,
variants,
originalImage,
variantImage,
moreAttributes,
typeUse,
pageDesign,
motor,
collection,
glass,
frameShape,
wristlet,
gender,
warranty,
}
}
View File