1404-07-13- created components for form && fixed bugs

This commit is contained in:
MojtabaSoumi 2025-10-05 19:26:21 +03:30
parent 29b7178dcb
commit 5168fec0d7
23 changed files with 1144 additions and 189 deletions

View File

@ -1,5 +1,5 @@
VITE_PROJECT_BASE = pargar
VITE_PROJECT_BASEURL = https://liman.gold/server
VITE_PROJECT_BASEURL_WS = wss://liman.gold
VITE_PROJECT_BASEURL = https://pargar-soft.ir/api
VITE_PROJECT_BASEURL_WS = wss://pargar-soft.ir
VITE_PROJECT_TITLE = پرگار | پنل مشتریان
VITE_PROJECT_LOGO = /logo_desktop.svg

15
components.d.ts vendored
View File

@ -8,22 +8,24 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
AAffix: typeof import('ant-design-vue/es')['Affix']
AAlert: typeof import('ant-design-vue/es')['Alert']
AButton: typeof import('ant-design-vue/es')['Button']
ACard: typeof import('ant-design-vue/es')['Card']
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
ADrawer: typeof import('ant-design-vue/es')['Drawer']
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
AFloatButton: typeof import('ant-design-vue/es')['FloatButton']
AForm: typeof import('ant-design-vue/es')['Form']
AFormItem: typeof import('ant-design-vue/es')['FormItem']
AInput: typeof import('ant-design-vue/es')['Input']
AInputPassword: typeof import('ant-design-vue/es')['InputPassword']
AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AModal: typeof import('ant-design-vue/es')['Modal']
ARadio: typeof import('ant-design-vue/es')['Radio']
ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASpin: typeof import('ant-design-vue/es')['Spin']
ASwitch: typeof import('ant-design-vue/es')['Switch']
ATabPane: typeof import('ant-design-vue/es')['TabPane']
ATabs: typeof import('ant-design-vue/es')['Tabs']
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
BaseDatePicker: typeof import('./src/components/BasicPacks/BaseDatePicker/src/BaseDatePicker.vue')['default']
BaseSwitch: typeof import('./src/components/BasicPacks/BaseSwitch/src/BaseSwitch.vue')['default']
BaseTable: typeof import('./src/components/BasicPacks/BaseTable/src/BaseTable.vue')['default']
@ -33,9 +35,11 @@ declare module 'vue' {
BasicIcon: typeof import('./src/components/BasicPacks/BasicIcon.vue')['default']
BasicInfoItem: typeof import('./src/components/BasicPacks/BasicInfoItem.vue')['default']
BasicInput: typeof import('./src/components/BasicPacks/BasicInput.vue')['default']
BasicInputNew: typeof import('./src/components/BasicInputNew.vue')['default']
BasicModal: typeof import('./src/components/BasicPacks/BasicModal.vue')['default']
BasicPriceInput: typeof import('./src/components/BasicPacks/BasicPriceInput/src/BasicPriceInput.vue')['default']
BasicSelect: typeof import('./src/components/BasicPacks/BasicSelect.vue')['default']
BasicSelectNew: typeof import('./src/components/BasicSelectNew.vue')['default']
BasicTags: typeof import('./src/components/BasicPacks/BasicTags/index.vue')['default']
BasicTextArea: typeof import('./src/components/BasicPacks/BasicTextArea.vue')['default']
BasicToggleTwoItem: typeof import('./src/components/BasicPacks/BasicToggleTwoItem.vue')['default']
@ -45,7 +49,6 @@ declare module 'vue' {
Icon: typeof import('./src/components/Icon.vue')['default']
IconButton: typeof import('./src/components/IconButton.vue')['default']
InfoItem: typeof import('./src/components/InfoItem.vue')['default']
InstallPWA: typeof import('./src/components/InstallPWA.vue')['default']
Menu: typeof import('./src/components/Menu.vue')['default']
MobileNavbar: typeof import('./src/components/MobileNavbar.vue')['default']
Navbar: typeof import('./src/components/Navbar.vue')['default']

View File

@ -20,21 +20,24 @@
</div>
</AAffix>
<RouterView v-slot="{ Component }">
<KeepAlive :include="keepAliveList">
<Component
class="mx-auto px-4"
:is="Component"
/>
<transition name="fade">
<KeepAlive :include="keepAliveList">
<Component
class="mx-auto px-4 overflow-y-scroll h-34rem mt-5rem pt-5rem pb-15"
:is="Component"
/>
</KeepAlive>
</transition>
</KeepAlive>
</RouterView>
<div v-if="router.currentRoute.value.meta.showMenu" class="py-8 absolute bottom-1px" style="justify-self: center">
<div class="container mx-auto">
<div class="menuBorder w-22rem">
<!-- <Menu/>-->
</div>
</div>
</div>
<!-- <div v-if="router.currentRoute.value.meta.showMenu" class="py-8 absolute bottom-1px" style="justify-self: center">-->
<!-- <div class="container mx-auto">-->
<!-- <div class="menuBorder w-22rem">-->
<!--&lt;!&ndash; <Menu/>&ndash;&gt;-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
</div>
</AConfigProvider>
@ -157,7 +160,7 @@ import { update } from 'lodash'
import pkg from '../package.json'
import { useRegisterSW } from 'virtual:pwa-register/vue'
import { onMounted, ref, watch } from 'vue'
import InstallPWA from '@/components/InstallPWA.vue'
// import InstallPWA from '@/components/InstallPWA.vue'
import { useUserStore } from '@/store/user'
import { usePWAStore } from '@/store/usePWAStore'
const versionDialog = ref<boolean>(false)

View File

@ -7,11 +7,11 @@ export const loginWithPass = async (payload: Login) => {
}
export const loginWithSMS = async (payload:Login) => {
return await axios.post<any>('/auth/login', payload)
return await axios.post<any>('/auth/generate-otp', payload)
}
export const registerCustomer = async (obj: User) => await axios.post<User>(`/auth/register`, obj)
export async function verifyToken(id: any,token:string){
return await axios.post<any>('/auth/verify',{provider: "customer",token,id})
export async function verifyToken(phone: any,otp:string){
return await axios.post<any>('/auth/verify-otp',{phone:phone,otp:otp})
}

View File

@ -13,7 +13,7 @@ export const orderTable = async (tbl: TableInput): Promise<TableOutput<Order>> =
}
export const checkOrder = async () => {
return await axios.get<Check>(`/customer/order/check`)
// return await axios.get<Check>(`/customer/order/check`)
}
export const confirmOrderApi = async (id?: number) => {

View File

@ -9,7 +9,7 @@ export const getUsers = async (tbl: TableInput): Promise<TableOutput<User>> => {
}
export const getMe = async () => {
return await axios.get('/customer/me')
return await axios.get('/auth/me')
}
export const updateMe = async (payload: User) => {

View File

@ -1,4 +1,8 @@
.ant-modal-content {
padding: 16px !important;
}
.ant-dropdown .ant-dropdown-menu .ant-dropdown-menu-item-selected{
background-color: rgba(255, 216, 109, 0.43);
color: black;
}

View File

@ -2,7 +2,7 @@ body.pargar {
position: fixed;
top: 0;
bottom: 0;
background: #FFD86DFF;
background: #EAEAEA;
color: rgba(47, 47, 47, 0.8);
overflow: hidden;
}
@ -34,9 +34,9 @@ body.pargar .bottom-yellow-rectangle {
max-width: 425px;
width: 100%;
justify-self: center;
z-index: 1;
z-index: 6;
position: fixed;
top: 48rem;
top: 47rem;
bottom: 0;
right: 0;
left: 0;
@ -107,7 +107,6 @@ body.pargar .navbar{
body.pargar .input-1{
border: 1px solid rgba(85, 85, 85, 0.5);
border-radius: 50px;
z-index: 5;
height: 3rem;
padding: 1rem;
align-items: center;
@ -120,12 +119,21 @@ body.pargar .input-2{
border-bottom-left-radius: 50px;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
z-index: 5;
height: 3rem;
padding: 1rem;
align-items: center;
background: linear-gradient(180deg, rgba(153, 130, 65, 0.02) 0%, rgba(179, 151, 76, 0.03) 25%, rgba(204, 173, 87, 0.05) 50%, rgba(242, 205, 104, 0.07) 87.5%, rgba(255, 216, 109, 0.1) 100%);
}
body.pargar .inputSelect-1{
border: 1px solid rgba(85, 85, 85, 0.5);
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
height: 3rem;
align-items: center;
background: linear-gradient(180deg, rgba(153, 130, 65, 0.02) 0%, rgba(179, 151, 76, 0.03) 25%, rgba(204, 173, 87, 0.05) 50%, rgba(242, 205, 104, 0.07) 87.5%, rgba(255, 216, 109, 0.1) 100%);
}
body.pargar .line-2 {
width: 12px;
@ -208,7 +216,7 @@ body.pargar .orderCard{
body.pargar .ant-input{
border: none;
box-shadow: 0px 4px 20px -4px rgba(0, 0, 0, 0.25);
//box-shadow: 0px 4px 20px -4px rgba(0, 0, 0, 0.25);
}
body.pargar .ant-input-focused{
border: none;
@ -626,14 +634,14 @@ body.pargar .ant-radio-wrapper .ant-radio-checked .ant-radio-inner {
border-color:#E3C27BFF;
}
body.pargar .ant-select-selector, .ant-tooltip-open, .ant-select-selection-item, .ant-select-item .ant-select-item-option {
color: white;
color: black;
}
body.pargar .ant-select:not(.ant-select-customize-input) .ant-select-selector {
position: relative;
background-color: #191919;
//background-color: #191919;
}
body.pargar .ant-select:not(.ant-select-customize-input) .ant-select-selector {
background-color: #191919;
//background-color: #191919;
}
body.pargar .ant-select:not(.ant-select-disabled):not(.ant-select-customize-input):not(.ant-pagination-size-changer):hover .ant-select-selector {
border-color: #E3C27BFF;

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,122 @@
<template>
<div class="col-span-2 flex justify-between relative input-2">
<div class="line-2 absolute"></div>
<div class="w-full">{{props.title}}</div>
<div class="font-bold">
<a-input-password
style="border-radius: 10px"
v-if="isPassword"
v-model:value="localValue"
:addon-after="props.addonAfter"
:addon-before="props.addonBefore"
:disabled="props.disabled"
:placeHolder="props.placeHolder"
:size="props.size"
:type="props.type"
:bordered="false"
class=""
@change="handlerChange"
/>
<a-input
v-else
v-model:value="localValue"
:addon-after="props.addonAfter"
:addon-before="props.addonBefore"
:disabled="props.disabled"
:placeHolder="props.placeHolder"
:size="props.size"
:bordered="false"
:type="props.type === 'price'? 'tel':props.type"
:inputmode="props.inputmode"
:pattern="props.pattern"
class=""
@change="handlerChange"
/>
</div>
</div>
</template>
<script setup lang="ts">
import {usePrice} from "@/composable/usePrice";
import {usePrefix} from "@/composable/usePrefix";
interface Prop {
title?: String
value?: String | Number
size?: String
type?: String
isPassword?: boolean
inputmode?: String
disabled?: boolean
addonAfter?: String
addonBefore?: String
addonBgColor?: String
addonTextColor?: String
placeHolder?: String
}
const localValue = computed({
set(value) {
// console.log(value?.toString().replaceAll(',', ''))
props.type === 'price'
? emits('update:value', value?.toString().replaceAll(',', ''))
: emits('update:value', value)
},
get() {
let a =
props.type === 'price'
? props.value
? usePrice(props.value as number, true, '').trim()
: ''
: props.value
// console.log(props.value)
return a
}
})
const props = withDefaults(defineProps<Prop>(), {
isPassword: false
})
const emits = defineEmits(['update:value', 'onchange'])
const handlerChange = (e: any) => {
// emits('onchange', e.target.value)
props.type === 'price' ? emits('update:value', e.target.value?.toString().replaceAll(',', '')) : emits('update:value', e.target.value)
props.type === 'price' ? emits('onchange', e.target.value?.toString().replaceAll(',', '')) : emits('onchange', e.target.value)
}
//css style
const {prefixCls} = usePrefix('input')
</script>
<style lang="less">
@prefix: ~'@{prefixCls}-input';
.@{prefix} {
/* .ant-input-group-addon:first-child {
!* border: #d9d9d9 1px solid;
border-radius: 0 6px 6px 0;*!
}*/
.ant-input-group {
direction: ltr;
}
.ant-input-group > .ant-input-rtl:first-child,
.ant-input-group-rtl .ant-input-group-addon:first-child {
border-radius: @border-radius-base 0 0 @border-radius-base;
width: 4rem;
}
.ant-input-group > .ant-input:last-child,
.ant-input-group-addon:last-child {
border-radius: 0 @border-radius-base @border-radius-base 0;
}
.ant-input-group-addon {
background-color: v-bind(addonBgColor);
color: v-bind(addonTextColor);
}
}
</style>

View File

@ -0,0 +1,155 @@
<template>
<div class="col-span-2 flex justify-between relative inputSelect-1 pr-4 ">
<div class="line-2 absolute"></div>
<div v-if="props.title" class="w-full">{{ props.title }}</div>
<div class="font-bold w-full ">
<a-dropdown :get-popup-container="trigger => trigger.parentNode">
<template #overlay>
<div class="ml-4">
<a-menu >
<a-menu-item @click="localValue=get(val, props.valueName)" v-for="(val ,i) in items" :key="i">
{{ get(val, props.valueName) }}
</a-menu-item>
</a-menu>
</div>
</template>
<div class="flex ">
<AInput class="text-left font-bold text-4 text-[rgba(47, 47, 47, 0.8)]" v-model:value="localValue" :bordered="false"></AInput>
<div class="border-#55555580 border-1 rounded-full w-12 h-11 flex justify-center items-center">
<basic-icon icon="vuesax-linear:arrow-down" color="#E2B12B" size="20"></basic-icon>
</div>
</div>
</a-dropdown>
<!-- <a-select-->
<!-- class="w-full"-->
<!-- :size="props.size"-->
<!-- v-model:value="localValue"-->
<!-- :disabled="props.disabled"-->
<!-- show-search-->
<!-- :mode="props.mode"-->
<!-- :style="props.style"-->
<!-- :multiple="props.multiple"-->
<!-- :bordered="false"-->
<!-- :default-open="defaultOpen"-->
<!-- @change="handleChange"-->
<!-- :placeholder="props.placeholder"-->
<!-- :allowClear="props.allowClear"-->
<!-- :filter-option="filterOption"-->
<!-- :get-popup-container="trigger => trigger.parentNode"-->
<!-- @focus="(e) => e.preventDefault()"-->
<!-- >-->
<!-- <a-select-option-->
<!-- v-for="(val, i) in props.items"-->
<!-- :key="i"-->
<!-- :label="get(val, props.valueName)"-->
<!-- :value="get(val, props.keyName)"-->
<!-- >-->
<!-- <a-tooltip v-if="props.hasTooltip" placement="left" class="cursor-pointer">-->
<!-- <template #title>-->
<!-- <span>{{ get(val, props.valueName) }}</span>-->
<!-- </template>-->
<!-- <div class="truncate max-w-40">{{ get(val, props.valueName) }}</div>-->
<!-- </a-tooltip>-->
<!-- <div v-else>{{ get(val, props.valueName) }}</div>-->
<!-- </a-select-option>-->
<!-- </a-select>-->
</div>
</div>
</template>
<script setup lang="ts">
import {usePrice} from "@/composable/usePrice";
import {usePrefix} from "@/composable/usePrefix";
import {get} from 'lodash'
import {computed, onMounted} from 'vue'
interface Prop {
title?: string
value?: string | number | boolean | string[] | number[]
valueText?: string | number | boolean | string[] | number[]
style?: string
size?: string
keyName: string
disabled?: boolean
mode?: string
valueName: string
multiple?: boolean
items?: any[]
placeholder?: string
allowClear?: boolean
hasTooltip?: boolean
defaultOpen: boolean
}
const props = withDefaults(defineProps<Prop>(), {allowClear: true, hasTooltip: true})
// console.log('props.items ====>', props.items)
//define emits
const emit = defineEmits(['update:value', 'change', 'update:valueText'])
onMounted(() => {
for (let val in props.items) {
// console.log('new', get(props.items[val], props.valueName))
}
})
const localValue = computed({
get() {
return props.value
},
set(value) {
emit('update:value', value)
}
})
function setValueText(val: any) {
// console.log(val, get(val, props.valueName))
localTextValue.value = get(val, props.valueName)
}
const localTextValue = computed({
get() {
return props.valueText
},
set(value) {
emit('update:valueText', value)
}
})
const filterOption = (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
const handleChange = (e: any) => {
// console.log('e ====>', e)
setValueText(props.items.find((x) => get(x, props.keyName) === e))
emit(
'change',
props.items.find((x) => get(x, props.keyName) === e)
)
}
//css style
const {prefixCls} = usePrefix('select')
</script>
<style lang="less">
@prefix: ~'@{prefixCls}-select';
.@{prefix} {
/* .ant-input-group-addon:first-child {
!* border: #d9d9d9 1px solid;
border-radius: 0 6px 6px 0;*!
}*/
}
</style>

View File

@ -1,34 +1,45 @@
<template>
<div class="flex justify-center mt-2 p-2">
<div
class="flex justify-between items-center navbar"
>
<span class="text-white text-[16px] mr-1rem" style="font-weight: 400; color: rgba(226, 177, 43, 1);">
<div class="relative w-full ">
<div class="bg-[#FFD86D] w-full h-40"></div>
<div class="flex justify-center ">
<div class="flex justify-center flex-col w-92% absolute top-10 rounded-10 z-10 bg-[#EAEAEA] mt-2 p-10 shadow-md ">
<div
class="flex justify-between items-center w-2/3 self-center px-2 border-black border-1 rounded-full "
>
<span class=" text-base font-400 text-[#E2B12B]">
{{ userStore.user?.name }}
</span>
<Icon
icon="vuesax-linear:profile-circle"
size="30"
@click="open = true"
class="p-0.5 icon"
/>
<Icon
icon="vuesax-linear:profile-circle"
size="30"
@click="open = true"
class="p-0.5 icon"
/>
</div>
<div class="flex justify-center">
<img src="@/assets/img/logo_bg_none.png" alt="logo image"/>
</div>
</div>
</div>
</div>
<div>
<ProfileDrawer
v-model:open="open"
/>
</div>
<ProfileDrawer
v-model:open="open"
/>
</template>
<script setup lang="ts">
import { usePrefix } from '@/composable/usePrefix'
import {usePrefix} from '@/composable/usePrefix'
import ProfileDrawer from '@/components/ProfileDrawer.vue'
import { ref } from 'vue'
import { useUserStore } from '@/store/user'
import {ref} from 'vue'
import {useUserStore} from '@/store/user'
import Icon from '@/components/Icon.vue'
const { prefixCls } = usePrefix('header')
const {prefixCls} = usePrefix('header')
const open = ref<boolean>(false)
const userStore = useUserStore()
</script>

View File

@ -1,24 +1,22 @@
export interface Document {
id: number
customer_id: number
amount: number
date_at: string
track_number: string
send_account_number: string
send_bank: string
send_name: string
receive_account_number: string
receive_bank: string
receive_name: string
type: number
sts: number
created_at: string
updated_at: string
deleted_at: string
bank_transaction_id: number
type_str: string
daj: string
transaction: Transaction
document_type: string;
subject: string;
document_number: number;
document_date: string;
convert_ratio: number;
karat: number;
quote_type: string;
quote_value: number;
asset_id: string;
short_name: string|null;
service_type: string;
full_name: string|null;
description: string|null;
unit_id: number;
quantity: number;
profit_percent: number;
wage_percent: number;
commission_percent: number;
}
interface Transaction {

View File

@ -61,11 +61,10 @@ export interface CustomerSetting {
}
export interface Login {
id?: number
mobile: string
phone: string
password?: string
provider: string
type_app: string
token?: string
type?:string
}
export interface Token {

View File

@ -26,19 +26,46 @@ const router = createRouter({
path: '/',
name: 'home',
redirect: (to) => {
return { path: '/products', name: 'products' }
return { path: '/step1', name: 'step1' }
}
// components: () => import('@/views/home/index.vue')
},
{
path: '/products',
name: 'products',
path: '/step1',
name: 'step1',
component: () => import('@/views/products/index.vue'),
meta: {
showMenu: true,
showNavbar: true
}
},
{
path: '/step2',
name: 'step2',
component: () => import('@/views/products/index2.vue'),
meta: {
showMenu: true,
showNavbar: true
}
},
{
path: '/step3',
name: 'step3',
component: () => import('@/views/products/index3.vue'),
meta: {
showMenu: true,
showNavbar: true
}
},
{
path: '/step4',
name: 'step4',
component: () => import('@/views/products/index4.vue'),
meta: {
showMenu: true,
showNavbar: true
}
},
{
path: '/transactions',
name: 'transactions',
@ -192,13 +219,17 @@ const router = createRouter({
router.beforeEach((to, from, next) => {
if (isToken()) {
if (to.name === 'login') {
return next({ name: 'home' })
return next({ name:'step1'})
// return next()
}
return next()
} else {
if (['login', 'notFound', 'register'].includes(to.name as string)) {
return next()
}
// return next()
return next({ name: 'login' })
}
})

40
src/store/document.ts Normal file
View File

@ -0,0 +1,40 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { getMe } from '@/api/user'
import type { User } from '@/model/user'
import { removeToken } from '@/utils'
import router from '@/router'
import type {Document} from "@/model/document";
export const useDocumentStore = defineStore('document', () => {
const document = ref<Document | null>(
{
document_type: "",
subject: "",
document_number: 0,
document_date: "",
convert_ratio: 0,
karat: 0 ,
quote_type: "",
quote_value: 0 ,
asset_id: "" ,
short_name: "" ,
service_type: "" ,
full_name: "" ,
description: "" ,
unit_id: 0 ,
quantity: 0 ,
profit_percent:0,
wage_percent: 0,
commission_percent:0 ,
}
)
return {
document,
}
})

View File

@ -1,6 +1,7 @@
<template>
<div :class="[prefixCls]">
<div class="justify-center absolute right-0 left-0 bottom-0 top-0">
<div class="!h-100vh !mt-0 flex items-center bg-[#FFD86DFF]" :class="[prefixCls]">
<div class=" ">
<AForm :model="model" ref="formRef" layout="vertical">
<div style="border-radius: 15px" class="">
@ -28,21 +29,24 @@
<span>{{ time }}</span>
<span> دیگر </span>
</div>-->
<!-- <BasicButton v-if="enableSendAgainCode" class="continueButton" type="dashed" @click="reSendCode">ارسال مجدد کد تایید</BasicButton>-->
<OtpInput
<!-- <BasicButton v-if="enableSendAgainCode" class="continueButton" type="dashed" @click="reSendCode">ارسال مجدد کد تایید</BasicButton>-->
<div>
<OtpInput
style="direction: ltr"
class=" mobileInput"
class=" mobileInput justify-center"
ref="refOtpInput"
autocomplete="one-time-code"
input-classes="otp-input"
separator=""
value=""
:num-inputs="4"
:num-inputs="5"
:should-auto-focus="true"
:is-input-num="true"
@on-change="handleOnChange"
@on-complete="handleOnComplete"
/>
/>
</div>
<!-- <AInput
type="password"
class="mobileInput"
@ -54,19 +58,23 @@
/>-->
</div>
<div class="bottom-rectangle">
<BasicButton v-if="step === 'mobile'" class="continueButton" icon="vuesax-linear:arrow-right-1" :loading="loading" @click="submitMobileHandler">
دریافت کد
</BasicButton>
<BasicButton v-if="step === 'otp'" class="w-11rem continueButton" icon="vuesax-linear:arrow-right-1" :loading="loading" @click="submitHandler">
ورود
</BasicButton>
</div>
</div>
</AForm>
</div>
</div>
<div class="fixed bottom-0 h-25 text-20px bg-background w-full">
<div class="flex justify-center items-center h-full">
<BasicButton v-if="step === 'mobile'" class="continueButton" icon="vuesax-linear:arrow-right-1" :loading="loading" @click="submitMobileHandler">
دریافت کد
</BasicButton>
<BasicButton v-if="step === 'otp'" class="w-11rem continueButton" icon="vuesax-linear:arrow-right-1" :loading="loading" @click="submitHandler">
ورود
</BasicButton>
</div>
</div>
</template>
<script setup lang="ts">
@ -121,8 +129,7 @@ async function reSendCode() {
enableSendAgainCode.value = false
await loginWithSMS({
mobile: persian2english(model.mobile),
provider: 'customer',
type_app: 'client'
type: 'login',
})
reset()
}
@ -137,8 +144,8 @@ const handleOnComplete = async (value: string) => {
async function submitHandler() {
try {
loading.value = true
const { access_token } = await verifyToken(model.id, persian2english(model.token))
setToken(access_token)
const { token } = await verifyToken(persian2english(model.mobile), persian2english(model.token))
setToken(token)
await userStore.getUserInfo()
await router.push({ name: 'home' })
message.success('با موفقیت وارد شدید.')
@ -156,9 +163,8 @@ async function sendOtpFromPasswordStep() {
refOtpInput.value?.clearInput()
enableSendAgainCode.value = false
const { id } = await loginWithSMS({
mobile: persian2english(model.mobile),
provider: 'customer',
type_app: 'client',
phone: persian2english(model.mobile),
type: 'login',
})
model.id = id
reset()

View File

@ -0,0 +1,49 @@
<template>
<div class="flex gap-2 w-full">
<div class="w-full" @click="handleClick">
<div class="font-semibold flex justify-center w-full">
<div class="input-3 relative">
<transition name="fade">
<div v-show="isChecked" class="line-3 absolute"></div>
</transition>
<slot>{{ label }}</slot>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {computed, inject} from 'vue';
interface Props {
value?: string | number | boolean;
modelValue?: string | number | boolean; // تغییر از model به modelValue
label?: string;
disabled?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
value: '',
modelValue: '',
label: '',
disabled: false
});
// استفاده از نام استاندارد برای v-model
const emit = defineEmits(['update:modelValue', 'change']);
const isChecked = computed(() => {
return modelValue.value === props.value ;
});
const change= inject('change')
const modelValue=inject('modeValue')
const handleClick = () => {
if (props.disabled) return;
console.log('مقدار فعلی:', modelValue.value,2222 ,'مقدار جدید:', props.value);
change(props.value)
emit('update:modelValue', props.value);
emit('change', props.value);
};
</script>

View File

@ -0,0 +1,78 @@
<template>
<!-- <div v-if="items" class="flex gap-2">-->
<!-- <div v-for="item in items" class=" w-full" @click="localValue=item">-->
<!-- <div class=" font-semibold flex justify-center w-full">-->
<!-- <div class="input-3 relative">-->
<!-- <div v-show="localValue==item" class="line-3 absolute"></div>-->
<!-- {{ item }}-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div v-else class="flex gap-2">-->
<!-- <div class=" w-full" @click="localValue=item">-->
<!-- <div class=" font-semibold flex justify-center w-full">-->
<!-- <div class="input-3 relative">-->
<!-- <div v-show="localValue==item" class="line-3 absolute"></div>-->
<!-- {{ item }}-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<div class="flex gap-2">
<slot>
<BasicRadio
v-for="option in options"
:key="option.value"
:value="option.value"
:label="option.label"
:disabled="option.disabled || disabled"
:model-value="modelValue"
@update:modelValue="handleChange"
/>
</slot>
</div>
</template>
<script setup lang="ts">
import BasicRadio from "@/views/products/components/BasicRadio/BasicRadio.vue";
import {provide, ref} from "vue";
interface Option {
value: string | number | boolean;
label: string;
disabled?: boolean;
}
interface Props {
modelValue?: any;
options?: Option[];
disabled?: boolean;
}
const modeValue=ref()
provide('modeValue',modeValue)
const props = withDefaults(defineProps<Props>(), {
modelValue: '',
options: () => [],
disabled: false
});
const emit = defineEmits(['update:modelValue', 'change']);
const handleChange = (value: any) => {
console.log('مقدار جدید در گروه:', value);
modeValue.value=value
emit('update:modelValue', value);
emit('change', value);
};
provide('change',handleChange)
provide('change',handleChange)
</script>
<style scoped lang="less">
</style>

View File

@ -1,33 +1,24 @@
<template>
<div class="" :class="[prefixCls]">
<img style="position: fixed; top: 3rem; justify-self: center" src="@/assets/img/logo.png" alt="logo image"/>
<div class="bottom-yellow-rectangle"></div>
<div class="middle-white-rectangle"></div>
<div class="grid grid-cols-2 gap-3 h-28rem overflow-y-scroll mt-10rem" style="justify-self: center;">
<div class="flex col-span-1 input-1 font-semibold justify-center">سند فروش </div>
<div class="col-span-1 font-semibold flex justify-center">
<div class="input-3 relative">
<div class="line-3 absolute"></div>
سند خرید
</div>
<div class="grid grid-cols-2 gap-3 overflow-x-hidden " style="justify-self: center;">
<div class="col-span-2 ">
<BasicRadioGroup v-model="documentData.document.document_type">
<BasicRadio value="buy" label="سند خرید"/>
<BasicRadio value="sell" label="سند فروش"/>
</BasicRadioGroup>
</div>
<div class="col-span-1 font-semibold flex justify-center">
<div class="input-3 relative">
<div class="line-3 absolute"></div>
سند حسابداری
</div>
<div class="col-span-2 ">
<BasicRadioGroup v-model="documentData.document.document_type">
<BasicRadio value="tax" label="سند سامانه مودیان"/>
<BasicRadio value="accounting" label="سند حسابداری"/>
</BasicRadioGroup>
</div>
<div class="flex col-span-1 input-1 justify-center font-semibold">سند سامانه مودیان </div>
<div class="col-span-2 relative input-2">
<div class="line-2 absolute"></div>
<div class="flex justify-between">
<div class="">مــوضــوع</div>
<div class="font-bold">اصــــلــی</div>
<div class="font-bold">{{ documentData.document?.subject }}</div>
</div>
</div>
@ -36,7 +27,7 @@
<div class="">شـمـــاره</div>
<div class="flex items-center">
<Icon icon="vuesax-linear:arrow-right-1" size="20" class="icon"/>
<div class="mx-4 font-bold">2</div>
<div class="mx-4 font-bold">{{ documentData.document?.document_number }}</div>
<Icon icon="vuesax-linear:arrow-left-1" size="20" class="icon"/>
</div>
</div>
@ -45,22 +36,19 @@
<div class="line-2 absolute"></div>
<div class="">تـاریـــخ</div>
<div class="flex items-center">
<div>1404/05/06</div>
<div>{{toJalali(documentData.document?.document_date)}}</div>
</div>
</div>
<div class="col-span-2 flex justify-between relative input-2">
<div class="line-2 absolute"></div>
<div class="">عیار تبدیل مثقال/گرم</div>
<div class="font-bold">18</div>
</div>
<div class="col-span-2 flex justify-between relative input-2">
<div class="line-2 absolute"></div>
<div class="">عیار</div>
<div class="font-bold">750</div>
</div>
<!-- <div class="col-span-2 flex justify-between relative input-2">-->
<!-- <div class="line-2 absolute"></div>-->
<!-- <div class="">عیار</div>-->
<!-- <div class="font-bold">750</div>-->
<!-- </div>-->
<BasicSelectNew title="عیار تبدیل مثقال/گرم" :items="ayarList" value-name="val" key-name="val"
v-model:value="documentData.document.convert_ratio"></BasicSelectNew>
<BasicSelectNew title="عیار" :items="ayarList" value-name="val" key-name="val"
v-model:value="documentData.document.karat"></BasicSelectNew>
<div class="col-span-2 flex items-center justify-center gap-2">
<span class="dot-line">
<span class="line-1"></span>
@ -72,14 +60,34 @@
<span class="line-1"></span>
</span>
</div>
<div class="col-span-2 ">
<BasicRadioGroup v-model="documentData.document.quote_type">
<BasicRadio value="gram" label="مظنه گرمی"/>
<BasicRadio value="mesghal" label="مظنه مثقالی"/>
</BasicRadioGroup>
</div>
<div class="flex col-span-1 input-1 justify-center">مظنه گرمی</div>
<div class="flex col-span-1 input-1 justify-center">مظنه مثقالی</div>
<div class="col-span-2 flex justify-between relative input-2">
<div class="line-2 absolute"></div>
<div class="">عیار</div>
<div class="font-bold">750</div>
<BasicInputNew v-model:value="documentData.document.quote_value" title="ریال"></BasicInputNew>
</div>
<div class="bottom-yellow-rectangle">
<div class="flex justify-between items-center mx-4 my-2 ">
<div class="col-span-2 flex justify-center w-1/2">
<AButton class="rounded-full bg-[#EAEAEA] border-1 h-12 w-full " :loading="loading"
@click="router.push({name:'step2'})">
<div class="flex justify-between ">
<div>
<Icon icon="vuesax-linear:arrow-right-1" color="#E2B12B"/>
</div>
<div class="w-full font-700"> ادامه</div>
</div>
</AButton>
</div>
<div>1/4 مرحله تکمیل شده</div>
</div>
</div>
@ -87,52 +95,63 @@
</template>
<script setup lang="ts">
import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import { usePrefix } from '@/composable/usePrefix'
import {nextTick, onMounted, onUnmounted, ref, watch} from 'vue'
import {usePrefix} from '@/composable/usePrefix'
import ProductCard from '@/components/ProductCard.vue'
import type { ProductShow } from '@/model/product'
import type {ProductShow} from '@/model/product'
import BuySell from '@/views/products/components/BuySell.vue'
import { useWindowSize } from '@vueuse/core'
import { loading } from '@/utils'
import type { TableEngineInput, TableOutput } from '@/model/table'
import { useUserStore } from '@/store/user'
import { getPrices,fillItemsCredit, mainProductList, setIntervalGetPrice, stopPriceInterval } from '@/utils/price'
import { getMessages } from '@/api/message'
import {useWindowSize} from '@vueuse/core'
import {loading} from '@/utils'
import type {TableEngineInput, TableOutput} from '@/model/table'
import {useUserStore} from '@/store/user'
import {getPrices, fillItemsCredit, mainProductList, setIntervalGetPrice, stopPriceInterval} from '@/utils/price'
import {getMessages} from '@/api/message'
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
import Icon from '@/components/Icon.vue'
import BasicInputNew from "@/components/BasicInputNew.vue";
import BasicSelectNew from "@/components/BasicSelectNew.vue";
import BasicSelect from "@/components/BasicPacks/BasicSelect.vue";
import BasicRadio from "@/views/products/components/BasicRadio/BasicRadio.vue";
import BasicRadioGroup from "@/views/products/components/BasicRadio/BasicRadioGroup.vue";
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
import router from "@/router";
import type {Document} from "@/model/document";
import {useDocumentStore} from "@/store/document";
import {toJalali} from "@/utils/useDateTime";
const { prefixCls } = usePrefix('products')
const {prefixCls} = usePrefix('products')
const open = ref<boolean>(false)
const transactionType = ref<string>('')
const { width } = useWindowSize()
const {width} = useWindowSize()
const data = ref<ProductShow>()
const userStore = useUserStore()
const messages = ref<Message[]>([])
const pagination = ref<TableEngineInput>({ filters: [], limit: 1000, page: 0 })
const tableOutput = ref<TableOutput<Message> | null>(null)
async function initNotification() {
try {
loading.value = true
// messages.value = await getMessages()
tableOutput.value = await getMessages(pagination.value)
messages.value.push(...tableOutput.value.rows)
} catch (e) {
console.log(e)
} finally {
loading.value = false
}
}
const typeDocument = ref<string>('apple')
const documentData = useDocumentStore()
const ayarList = ref([{val: '0'}, {val: '10'}, {val: '18'}])
// async function initNotification() {
// try {
// loading.value = true
// // messages.value = await getMessages()
// tableOutput.value = await getMessages(pagination.value)
// messages.value.push(...tableOutput.value.rows)
// } catch (e) {
// console.log(e)
// } finally {
// loading.value = false
// }
// }
onMounted(async () => {
// initTable()
console.log(documentData.document)
try {
loading.value = true
await initNotification()
// await initNotification()
await nextTick(async () => {
await fillItemsCredit()
await getPrices()
if (!userStore.priceStarted) await setIntervalGetPrice()
// await fillItemsCredit()
// await getPrices()
// if (!userStore.priceStarted) await setIntervalGetPrice()
})
} catch (e) {
console.log(e)
@ -141,22 +160,23 @@ onMounted(async () => {
}
})
onUnmounted(() => {
stopPriceInterval()
// stopPriceInterval()
})
function alertType(val) {
switch (val) {
case 1: return 'error'
case 2: return 'warning'
case 3: return 'info'
case 4: return 'success'
case 1:
return 'error'
case 2:
return 'warning'
case 3:
return 'info'
case 4:
return 'success'
}
}
const openHandler = (type: string, item: ProductShow) => {
data.value = item
// console.log(data)
transactionType.value = type
open.value = true
}
watch(mainProductList, () => {
if (open.value) {
data.value = mainProductList.value?.find(x => x.product_id === data.value?.product_id)

View File

@ -0,0 +1,132 @@
<template>
<div class="" :class="[prefixCls]">
<div class="grid grid-cols-2 gap-3 overflow-x-hidden " style="justify-self: center;">
<BasicSelectNew title="شناسه دارایی" :items="ayarList" value-name="val" key-name="val"
v-model:value="typeDocument"></BasicSelectNew>
<BasicSelectNew title="نام مختصر کالا" :items="ayarList" value-name="val" key-name="val"
v-model:value="typeDocument"></BasicSelectNew>
<BasicSelectNew title="کد کالا یا خدمت" :items="ayarList" value-name="val" key-name="val"
v-model:value="typeDocument"></BasicSelectNew>
<div class="col-span-2 flex items-center justify-center gap-2">
<span class="dot-line">
<span class="line-1"></span>
<span class="dot"></span>
</span>
<div class="text-14px">نام کالا یا خدمت را وارد کنید</div>
<span class="dot-line">
<span class="dot"></span>
<span class="line-1"></span>
</span>
</div>
<BasicSelectNew :items="ayarList" value-name="val" key-name="val"
v-model:value="typeDocument"></BasicSelectNew>
<BasicSelectNew title=ارکد1" :items="ayarList" value-name="val" key-name="val"
v-model:value="typeDocument"></BasicSelectNew>
<div class="col-span-2 flex justify-center">
<AButton class="rounded-full bg-[#EAEAEA] border-1 border-[#E2B12B] h-12 w-1/2 "
@click="router.push({name:'step1'})">
<div class="flex justify-between ">
<div class="w-full font-700"> بازگشت</div>
<div>
<Icon icon="vuesax-linear:arrow-left-1" color="#E2B12B"/>
</div>
</div>
</AButton>
</div>
</div>
<div class="bottom-yellow-rectangle">
<div class="flex justify-between items-center mx-4 my-2">
<div class="col-span-2 flex justify-center w-1/2">
<AButton class="rounded-full bg-[#EAEAEA] border-1 h-12 w-full " :loading="loading"
@click="router.push({name:'step3'})">
<div class="flex justify-between ">
<div>
<Icon icon="vuesax-linear:arrow-right-1" color="#E2B12B"/>
</div>
<div class="w-full font-700"> ادامه</div>
</div>
</AButton>
</div>
<div>2/4 مرحله تکمیل شده</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {nextTick, onMounted, onUnmounted, ref, watch} from 'vue'
import {usePrefix} from '@/composable/usePrefix'
import ProductCard from '@/components/ProductCard.vue'
import type {ProductShow} from '@/model/product'
import BuySell from '@/views/products/components/BuySell.vue'
import {useWindowSize} from '@vueuse/core'
import {loading} from '@/utils'
import type {TableEngineInput, TableOutput} from '@/model/table'
import {useUserStore} from '@/store/user'
import {getPrices, fillItemsCredit, mainProductList, setIntervalGetPrice, stopPriceInterval} from '@/utils/price'
import {getMessages} from '@/api/message'
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
import Icon from '@/components/Icon.vue'
import BasicInputNew from "@/components/BasicInputNew.vue";
import BasicSelectNew from "@/components/BasicSelectNew.vue";
import BasicSelect from "@/components/BasicPacks/BasicSelect.vue";
import BasicRadio from "@/views/products/components/BasicRadio/BasicRadio.vue";
import BasicRadioGroup from "@/views/products/components/BasicRadio/BasicRadioGroup.vue";
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
import router from "@/router";
const {prefixCls} = usePrefix('products')
const typeDocument = ref<string>('apple')
const ayarList = ref([{val: '0'}, {val: '10'}, {val: '18'}])
onMounted(async () => {
// initTable()
try {
loading.value = true
await nextTick(async () => {
})
} catch (e) {
console.log(e)
} finally {
loading.value = false
}
})
onUnmounted(() => {
})
function alertType(val) {
switch (val) {
case 1:
return 'error'
case 2:
return 'warning'
case 3:
return 'info'
case 4:
return 'success'
}
}
</script>
<style scoped lang="less">
@prefix: ~'@{prefixCls}-products';
.@{prefix} {
}
</style>

View File

@ -0,0 +1,157 @@
<template>
<div class="" :class="[prefixCls]">
<div class="grid grid-cols-2 gap-3 overflow-x-hidden " style="justify-self: center;">
<BasicInputNew title="وزن / تعداد"></BasicInputNew>
<div class="col-span-2 flex gap-2 justify-between">
<BasicInputNew class="flex-1" title="مبلغ / درصد سود"></BasicInputNew>
<div class="flex gap-2 items-center">
<div class="text-sm">کل لحاظ شود</div>
<div class=" w-5 h-5 rounded-full bg-[#EAEAEA] border-5 border-#55555580"></div>
</div>
</div>
<div class="col-span-2 flex gap-2 justify-between">
<BasicInputNew class="flex-1" title="مبلغ / درصد اجرت"></BasicInputNew>
<div class="flex gap-2 items-center">
<div class="text-sm">کل لحاظ شود</div>
<div class=" w-5 h-5 rounded-full bg-[#EAEAEA] border-5 border-#55555580"></div>
</div>
</div>
<div class="col-span-2 flex gap-2 justify-between">
<BasicInputNew class="flex-1" title="حق العمل"></BasicInputNew>
<div class="flex gap-2 items-center">
<div class="text-sm">کل لحاظ شود</div>
<div class=" w-5 h-5 rounded-full bg-[#EAEAEA] border-5 border-#55555580"></div>
</div>
</div>
<div class="flex col-span-2 gap-2">
<div class=" w-full flex justify-center">
<AButton class="rounded-full bg-[#FFC42033] border-1 border-[#E2B12B] h-12 w-full "
@click="router.push({name:'step2'})">
<div class="flex justify-between ">
<div class="w-full font-700"> اضافه اقلام</div>
</div>
</AButton>
</div>
<div class=" w-full flex justify-center">
<AButton class="rounded-full bg-[#FFC42033] border-1 border-[#E2B12B] h-12 w-full "
@click="router.push({name:'step2'})">
<div class="flex justify-between ">
<div class="w-full font-700"> کالای بعدی</div>
</div>
</AButton>
</div>
</div>
<div class="col-span-2 flex justify-center">
<AButton class="rounded-full bg-[#EAEAEA] border-1 border-[#E2B12B] h-12 w-1/2 "
@click="router.push({name:'step2'})">
<div class="flex justify-between ">
<div class="w-full font-700"> بازگشت</div>
<div>
<Icon icon="vuesax-linear:arrow-left-1" color="#E2B12B"/>
</div>
</div>
</AButton>
</div>
</div>
<div class="bottom-yellow-rectangle">
<div class="flex justify-between items-center mx-4 my-2">
<div class="col-span-2 flex justify-center w-1/2">
<AButton class="rounded-full bg-[#EAEAEA] border-1 h-12 w-full " :loading="loading"
@click="router.push({name:'step4'})">
<div class="flex justify-between ">
<div>
<Icon icon="vuesax-linear:arrow-right-1" color="#E2B12B"/>
</div>
<div class="w-full font-700"> ادامه</div>
</div>
</AButton>
</div>
<div>3/4 مرحله تکمیل شده</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {nextTick, onMounted, onUnmounted, ref, watch} from 'vue'
import {usePrefix} from '@/composable/usePrefix'
import ProductCard from '@/components/ProductCard.vue'
import type {ProductShow} from '@/model/product'
import BuySell from '@/views/products/components/BuySell.vue'
import {useWindowSize} from '@vueuse/core'
import {loading} from '@/utils'
import type {TableEngineInput, TableOutput} from '@/model/table'
import {useUserStore} from '@/store/user'
import {getPrices, fillItemsCredit, mainProductList, setIntervalGetPrice, stopPriceInterval} from '@/utils/price'
import {getMessages} from '@/api/message'
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
import Icon from '@/components/Icon.vue'
import BasicInputNew from "@/components/BasicInputNew.vue";
import BasicSelectNew from "@/components/BasicSelectNew.vue";
import BasicSelect from "@/components/BasicPacks/BasicSelect.vue";
import BasicRadio from "@/views/products/components/BasicRadio/BasicRadio.vue";
import BasicRadioGroup from "@/views/products/components/BasicRadio/BasicRadioGroup.vue";
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
import router from "@/router";
const {prefixCls} = usePrefix('products')
onMounted(async () => {
// initTable()
try {
loading.value = true
await nextTick(async () => {
})
} catch (e) {
console.log(e)
} finally {
loading.value = false
}
})
onUnmounted(() => {
})
function alertType(val) {
switch (val) {
case 1:
return 'error'
case 2:
return 'warning'
case 3:
return 'info'
case 4:
return 'success'
}
}
</script>
<style scoped lang="less">
@prefix: ~'@{prefixCls}-products';
.@{prefix} {
}
</style>

View File

@ -0,0 +1,139 @@
<template>
<div class="" :class="[prefixCls]">
<div class="grid grid-cols-2 gap-3 overflow-x-hidden w-full " style="justify-self: center;">
<div class="col-span-2 flex items-center justify-center gap-2">
<span class="dot-line">
<span class="line-1"></span>
<span class="dot"></span>
</span>
<div class="text-14px">مشاهده فاکتور</div>
<span class="dot-line">
<span class="dot"></span>
<span class="line-1"></span>
</span>
</div>
<div class="col-span-2 border-1 rounded-3xl text-sm border-[#E2B12B] mx-2 p-4 ">
<div class="w-full">
<div class="flex justify-between">
<div>ردیف:</div>
<div>1</div>
</div>
<div class="flex justify-between">
<div>شرح کالا</div>
<div>آویز گردنبند زیورآلات ساخته شده</div>
</div>
<div class="flex justify-between">
<div>وزن:</div>
<div>2.5</div>
</div>
<div class="flex justify-between">
<div>مبلغ کل:</div>
<div>20,500,000</div>
</div>
<div class=" flex items-center justify-center gap-2">
<span class="dot-line">
<span class="line-1"></span>
<span class="dot"></span>
</span>
<span class="dot-line">
<span class="dot"></span>
<span class="line-1"></span>
</span>
</div>
</div>
</div>
<div class="flex col-span-2 gap-2">
</div>
<div class="col-span-2 flex justify-center">
<AButton class="rounded-full bg-[#EAEAEA] border-1 border-[#E2B12B] h-12 w-1/2 "
@click="router.push({name:'step3'})">
<div class="flex justify-between ">
<div class="w-full font-700"> بازگشت</div>
<div>
<Icon icon="vuesax-linear:arrow-left-1" color="#E2B12B"/>
</div>
</div>
</AButton>
</div>
</div>
<div class="bottom-yellow-rectangle">
<div class="flex justify-center items-center mx-4 my-2">
<div>4/4 مرحله تکمیل شده</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {nextTick, onMounted, onUnmounted, ref, watch} from 'vue'
import {usePrefix} from '@/composable/usePrefix'
import ProductCard from '@/components/ProductCard.vue'
import type {ProductShow} from '@/model/product'
import BuySell from '@/views/products/components/BuySell.vue'
import {useWindowSize} from '@vueuse/core'
import {loading} from '@/utils'
import type {TableEngineInput, TableOutput} from '@/model/table'
import {useUserStore} from '@/store/user'
import {getPrices, fillItemsCredit, mainProductList, setIntervalGetPrice, stopPriceInterval} from '@/utils/price'
import {getMessages} from '@/api/message'
import BasicActionSheet from '@/components/BasicPacks/BasicActionSheet.vue'
import Icon from '@/components/Icon.vue'
import BasicInputNew from "@/components/BasicInputNew.vue";
import BasicSelectNew from "@/components/BasicSelectNew.vue";
import BasicSelect from "@/components/BasicPacks/BasicSelect.vue";
import BasicRadio from "@/views/products/components/BasicRadio/BasicRadio.vue";
import BasicRadioGroup from "@/views/products/components/BasicRadio/BasicRadioGroup.vue";
import BasicButton from "@/components/BasicPacks/BasicButton.vue";
import router from "@/router";
const {prefixCls} = usePrefix('products')
onMounted(async () => {
// initTable()
try {
loading.value = true
await nextTick(async () => {
})
} catch (e) {
console.log(e)
} finally {
loading.value = false
}
})
onUnmounted(() => {
})
function alertType(val) {
switch (val) {
case 1:
return 'error'
case 2:
return 'warning'
case 3:
return 'info'
case 4:
return 'success'
}
}
</script>
<style scoped lang="less">
@prefix: ~'@{prefixCls}-products';
.@{prefix} {
}
</style>