1404/10/28-base
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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}
|
||||
@@ -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)}`
|
||||
}
|
||||
@@ -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')
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -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}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { prefixCls } from "@/themeConfig";
|
||||
|
||||
export function usePrefix(name = "") {
|
||||
return {
|
||||
prefixVar: prefixCls,
|
||||
prefixCls: `${prefixCls}-${name}`,
|
||||
};
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user