Show accounting adjust notes on transactions and polish input/lottie boot.
Transaction detail surfaces note text for adjustments; Persian digit input and local Lottie preload are included. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
{"nm":"Pre-comp 1","ddd":0,"h":1200,"w":1200,"meta":{"g":"LottieFiles AE 0.1.21"},"layers":[{"ty":4,"nm":"arrow down Outlines","sr":1,"st":0,"op":1020,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":0,"k":[46.875,46.875,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[600,528,0],"t":0,"ti":[0,0,0],"to":[0,-15.333,0]},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[600,436,0],"t":13,"ti":[0,-15.333,0],"to":[0,0,0]},{"s":[600,528,0],"t":27}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Group 1","ix":1,"cix":2,"np":4,"it":[{"ty":"sh","bm":0,"hd":false,"mn":"ADBE Vector Shape - Group","nm":"Path 1","ix":1,"d":1,"ks":{"a":0,"k":{"c":true,"i":[[7.831,7.793],[7.792,-7.828],[0,0],[0,0],[11.045,0],[0,-11.046],[0,0],[0,0],[7.829,-7.792],[-7.791,-7.829],[0,0],[-0.005,-0.006],[-7.819,7.833],[-0.005,0.006],[0,0]],"o":[[-7.829,-7.792],[0,0],[0,0],[0,-11.046],[-11.046,0],[0,0],[0,0],[-7.792,-7.828],[-7.83,7.793],[0,0],[0.006,0.007],[7.792,7.809],[0.006,-0.007],[0,0],[7.79,-7.828]],"v":[[118.109,117.328],[89.825,117.394],[20.001,187.557],[20.001,-236],[0.001,-256],[-19.999,-236],[-19.999,187.557],[-89.824,117.393],[-118.107,117.327],[-118.175,145.612],[-14.175,250.116],[-14.157,250.134],[14.158,250.135],[14.176,250.117],[118.176,145.613]]},"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[0.1608,0.1608,0.3843],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[255.999,256],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":1},{"ty":4,"nm":"Shape Layer 1","sr":1,"st":0,"op":1020,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[141,141,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":1,"k":[{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[622.56,380.04,0],"t":0,"ti":[0,0,0],"to":[0,-15.333,0]},{"o":{"x":0.333,"y":0},"i":{"x":0.667,"y":1},"s":[622.56,288.04,0],"t":13,"ti":[0,-15.333,0],"to":[0,0,0]},{"s":[622.56,380.04,0],"t":27}],"ix":2,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":100,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[144,144],"ix":2}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[1,1,1],"ix":4},"r":1,"o":{"a":0,"k":100,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[-16,156],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":2}],"v":"5.5.7","fr":30,"op":1020,"ip":0,"assets":[]}
|
||||
File diff suppressed because one or more lines are too long
@@ -93,6 +93,13 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 500px) {
|
||||
.login-vip-page__body{
|
||||
height: 20vh !important;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
|
||||
@@ -42,7 +42,6 @@ import {
|
||||
normalizeDecimalInput,
|
||||
persianToEnglishDigits,
|
||||
shouldNormalizeDecimalSeparators,
|
||||
shouldNormalizeInputDigits,
|
||||
} from '@/utils/persianDigits';
|
||||
|
||||
//Props
|
||||
@@ -93,11 +92,7 @@ function normalizeValue(value: unknown) {
|
||||
})
|
||||
}
|
||||
|
||||
let normalized = String(value)
|
||||
if (shouldNormalizeInputDigits(props)) {
|
||||
normalized = persianToEnglishDigits(normalized)
|
||||
}
|
||||
return normalized
|
||||
return persianToEnglishDigits(String(value))
|
||||
}
|
||||
|
||||
const handlerChange = (e: Event | string) => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import './assets/css/main.less'
|
||||
import 'virtual:uno.css'
|
||||
|
||||
import { initPwaInstallCapture } from '@/modules/pwa/manifest'
|
||||
import { preloadLottieAssets } from '@/utils/lottieAssets'
|
||||
import { bootstrapApp } from '@/app/bootstrap'
|
||||
|
||||
export {
|
||||
@@ -15,4 +16,5 @@ export {
|
||||
import '@unocss/reset/tailwind-compat.css'
|
||||
|
||||
initPwaInstallCapture()
|
||||
void preloadLottieAssets()
|
||||
bootstrapApp()
|
||||
|
||||
@@ -13,7 +13,7 @@ export interface Transaction {
|
||||
unit: string
|
||||
hash?: string
|
||||
id?: number
|
||||
note?: null
|
||||
note?: string | null
|
||||
title: string
|
||||
order_id?: number
|
||||
transaction_type?: string
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/** Lottieهای لوکال (`public/lottie`) — پیشدانلود تا مودال/لیست خالی نماند */
|
||||
|
||||
const LOTTIE_FILES = {
|
||||
logoutConfirm: 'lottie/logoutConfirm.json',
|
||||
emptyList: 'lottie/emptyList.json',
|
||||
goldBars: 'lottie/goldBars.json',
|
||||
} as const
|
||||
|
||||
export type LottieAssetKey = keyof typeof LOTTIE_FILES
|
||||
|
||||
const cache = new Map<LottieAssetKey, string>()
|
||||
|
||||
export function lottieSrc(key: LottieAssetKey): string {
|
||||
const base = import.meta.env.BASE_URL || '/'
|
||||
const path = `${base}${LOTTIE_FILES[key]}`
|
||||
return path.replace(/([^:]\/)\/+/g, '$1')
|
||||
}
|
||||
|
||||
export function getLottieData(key: LottieAssetKey): string | undefined {
|
||||
return cache.get(key)
|
||||
}
|
||||
|
||||
export async function preloadLottieAssets(): Promise<void> {
|
||||
const keys = Object.keys(LOTTIE_FILES) as LottieAssetKey[]
|
||||
await Promise.all(
|
||||
keys.map(async (key) => {
|
||||
if (cache.has(key)) return
|
||||
try {
|
||||
const res = await fetch(lottieSrc(key))
|
||||
if (!res.ok) return
|
||||
cache.set(key, await res.text())
|
||||
} catch {
|
||||
/* شبکه/آفلاین — بعداً از src لوکال میخواند */
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -56,19 +56,13 @@ export function parseDecimalInput(
|
||||
return Number(normalized)
|
||||
}
|
||||
|
||||
export function shouldNormalizeInputDigits(options: {
|
||||
export function shouldNormalizeInputDigits(_options?: {
|
||||
isPassword?: boolean
|
||||
type?: string
|
||||
inputmode?: string
|
||||
}): boolean {
|
||||
if (options.isPassword) {
|
||||
return false
|
||||
}
|
||||
if (options.type === 'price' || options.type === 'number') {
|
||||
return true
|
||||
}
|
||||
const mode = String(options.inputmode ?? '').trim().toLowerCase()
|
||||
return mode === 'numeric' || mode === 'decimal' || mode === 'number'
|
||||
// همیشه ارقام فارسی/عربی → انگلیسی (لاگین، گرم، تعداد، مظنه، …)
|
||||
return true
|
||||
}
|
||||
|
||||
/** فیلدهای وزن/مبلغ/عدد اعشاری که باید `/` را ممیز بگیرند */
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<DotLottieVue
|
||||
class="w-11rem h-11rem"
|
||||
autoplay
|
||||
src="https://lottie.host/129cf3a1-df84-4758-a856-58c133ae6013/R5RqclXA8G.json"
|
||||
v-bind="lottieBind"
|
||||
/>
|
||||
<div class="p-5 text-sm">آیا از خروج خود اطمینان دارید؟</div>
|
||||
</div>
|
||||
@@ -23,7 +23,8 @@
|
||||
<script setup lang="ts">
|
||||
import DialogVant from '@/components/DialogVant.vue'
|
||||
import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
|
||||
import {computed} from "vue";
|
||||
import {computed, ref, watch} from 'vue'
|
||||
import {getLottieData, lottieSrc, preloadLottieAssets} from '@/utils/lottieAssets'
|
||||
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
@@ -34,8 +35,29 @@ const emit = defineEmits<{
|
||||
confirm: []
|
||||
}>()
|
||||
|
||||
const cachedData = ref(getLottieData('logoutConfirm'))
|
||||
|
||||
const lottieBind = computed(() => {
|
||||
if (cachedData.value) return {data: cachedData.value}
|
||||
return {src: lottieSrc('logoutConfirm')}
|
||||
})
|
||||
|
||||
async function ensureLottie() {
|
||||
if (cachedData.value) return
|
||||
await preloadLottieAssets()
|
||||
cachedData.value = getLottieData('logoutConfirm')
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.show,
|
||||
(open) => {
|
||||
if (open) void ensureLottie()
|
||||
},
|
||||
{immediate: true},
|
||||
)
|
||||
|
||||
const visible = computed({
|
||||
get: () => props.show,
|
||||
set: (val) => emit('update:show', val)
|
||||
})
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -347,7 +347,7 @@
|
||||
<DotLottieVue
|
||||
class="w-11rem h-11rem"
|
||||
autoplay
|
||||
src="https://lottie.host/129cf3a1-df84-4758-a856-58c133ae6013/R5RqclXA8G.json"
|
||||
src="/lottie/logoutConfirm.json"
|
||||
/>
|
||||
<div class="p-5 text-sm">آیا از خروج خود اطمینان دارید؟</div>
|
||||
</div>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
class="w-5rem h-5rem mt-[-1.6rem] ml-[-2rem]"
|
||||
autoplay
|
||||
loop
|
||||
src="https://lottie.host/3d46ebb3-a580-41eb-ade7-b8829c32b071/PJPuSKbpze.json"
|
||||
src="/lottie/goldBars.json"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -315,7 +315,7 @@
|
||||
<DotLottieVue
|
||||
class="w-11rem h-11rem"
|
||||
autoplay
|
||||
src="https://lottie.host/129cf3a1-df84-4758-a856-58c133ae6013/R5RqclXA8G.json"
|
||||
src="/lottie/logoutConfirm.json"
|
||||
/>
|
||||
<div class="p-5 text-sm">آیا از خروج خود اطمینان دارید؟</div>
|
||||
</div>
|
||||
|
||||
@@ -115,6 +115,10 @@
|
||||
<div :class="variant === 'desktop' ? 'dtxn-detail__label' : 'text-primary'">مهلت ارسال فیش:</div>
|
||||
<div :class="variant === 'desktop' ? 'dtxn-detail__value' : ''">{{ item.eaj }}</div>
|
||||
</div>
|
||||
<div v-if="item.note" :class="variant === 'desktop' ? 'dtxn-detail__row' : 'flex justify-between mb-3'">
|
||||
<div :class="variant === 'desktop' ? 'dtxn-detail__label' : 'text-primary'">توضیحات سند:</div>
|
||||
<div :class="variant === 'desktop' ? 'dtxn-detail__value' : ''">{{ item.note }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<DotLottieVue
|
||||
class="w-44 h-44"
|
||||
autoplay
|
||||
src="https://lottie.host/51d3315a-cf88-4c18-bb4d-a31511fd4325/KjSBzcMbi6.json"
|
||||
src="/lottie/emptyList.json"
|
||||
/>
|
||||
<p class="dtxn-empty__text">{{ emptyText }}</p>
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<DotLottieVue
|
||||
class="w-11rem h-11rem"
|
||||
autoplay
|
||||
src="https://lottie.host/51d3315a-cf88-4c18-bb4d-a31511fd4325/KjSBzcMbi6.json"
|
||||
src="/lottie/emptyList.json"
|
||||
/>
|
||||
<div class="font-bold">{{ emptyText }}</div>
|
||||
</div>
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
import { mobileValidation, required } from '@/utils/inputRules'
|
||||
// import type {UserMobile} from "@/models/login";
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import { persianToEnglishDigits } from '@/utils/persianDigits'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import InstallButton from '@/components/InstallButton.vue'
|
||||
import { authenticateWithFingerprint, getToken, loading, removeToken, setToken, URLUserType } from '@/utils'
|
||||
@@ -219,12 +220,12 @@ function useStyle() {
|
||||
}
|
||||
|
||||
function handleOnChange(value: string) {
|
||||
userFormState.token = value
|
||||
userFormState.token = persianToEnglishDigits(String(value ?? ''))
|
||||
// formRef.value?.validateFields()
|
||||
}
|
||||
|
||||
async function handleOnComplete(value: string) {
|
||||
userFormState.token = value
|
||||
userFormState.token = persianToEnglishDigits(String(value ?? ''))
|
||||
phoneVerification()
|
||||
}
|
||||
|
||||
@@ -457,6 +458,7 @@ const getcode=()=>{
|
||||
import { mobileValidation, required } from '@/utils/inputRules'
|
||||
// import type {UserMobile} from "@/models/login";
|
||||
import BasicInput from '@/components/BasicPacks/BasicInput.vue'
|
||||
import { persianToEnglishDigits } from '@/utils/persianDigits'
|
||||
import BasicButton from '@/components/BasicPacks/BasicButton.vue'
|
||||
import {
|
||||
authenticateWithFingerprint,
|
||||
@@ -558,12 +560,12 @@ function useStyle() {
|
||||
}
|
||||
|
||||
function handleOnChange(value: string) {
|
||||
userFormState.token = value
|
||||
userFormState.token = persianToEnglishDigits(String(value ?? ''))
|
||||
// formRef.value?.validateFields()
|
||||
}
|
||||
|
||||
async function handleOnComplete(value: string) {
|
||||
userFormState.token = value
|
||||
userFormState.token = persianToEnglishDigits(String(value ?? ''))
|
||||
phoneVerification()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user