change configuration & add talabBedehi

This commit is contained in:
2026-05-25 10:49:08 +03:30
parent 5f5d9aef6a
commit 06568c5858
9 changed files with 255 additions and 107 deletions
+6
View File
@@ -1,4 +1,10 @@
export interface TagItem { export interface TagItem {
id: number | undefined id: number | undefined
name: string | undefined name: string | undefined
title_fa?: string
key?: string
value?: string
type?: string
description?: string
is_active: boolean
} }
+4 -1
View File
@@ -19,8 +19,11 @@ export interface SupportLink {
export interface itemConfig { export interface itemConfig {
id: number | string id: number | string
name: string name: string
title_fa?: string
value: string value: string
key: string key: string
type: string type: string
list: [] description?: string
is_active?: boolean
list: string[]
} }
+1
View File
@@ -28,6 +28,7 @@ export interface Charge {
value?: number value?: number
note?: string note?: string
customer_id?: number customer_id?: number
talabBedehi?: boolean
} }
export interface WithdrawStatus { export interface WithdrawStatus {
@@ -1,59 +1,80 @@
<template> <template>
<div class="flex mb-2"> <div class="mb-2 border-1 border-gray-300 border-solid rounded-lg p-3">
<div class="flex flex-col justify-between "> <div>
<div class=" font-bold">{{ item.name }}</div> <div class="flex justify-between">
<div class=" text-xs ">کلید: {{ item.key }}</div> <div class="flex items-center font-bold">
<div>{{ item.title_fa ?? item.name ?? '-' }}</div>
<BaseIcon
@click="ok()"
icon="vuesax-linear:tick-circle"
class="mr-2 items-center cursor-pointer"
color="green"
size="24"
/>
</div>
<a-switch
checked-children="فعال"
un-checked-children="غیرفعال"
v-model:checked="isActive"
@change="ok"
/>
</div>
</div> </div>
<BaseIcon <div class="flex justify-between items-center mt-2">
@click="ok()" <div class="text-xs">کلید: {{ item.key }}</div>
icon="vuesax-linear:tick-circle" <a-switch
class="mr-2 items-center" checked-children="نمایش"
color="green" un-checked-children="عدم نمایش"
size="24" v-model:checked="isVisible"
/> @change="ok"
</div> />
<QuillEditor </div>
<QuillEditor
placeholder="متن" placeholder="متن"
v-model:content="content" v-model:content="content"
toolbar="full" toolbar="full"
theme="snow" theme="snow"
content-type="html" content-type="html"
class="editor-box" class="editor-box mt-2"
/> />
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {loading} from '@/utils' import { loading } from '@/utils'
import {QuillEditor} from '@vueup/vue-quill' import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css' import '@vueup/vue-quill/dist/vue-quill.snow.css'
import {getConfiguration, setConfiguration} from '@/api/configuration' import { setConfiguration } from '@/api/configuration'
import {message} from 'ant-design-vue' import { message } from 'ant-design-vue'
import type { TagItem } from '@/components/BasicTags/model' import type { itemConfig } from '@/model/configuration'
import BasicTextArea from "@/components/BasicTextArea.vue";
interface Prop { interface Prop {
item: TagItem item: itemConfig
} }
const props = defineProps<Prop>() const props = defineProps<Prop>()
const emits = defineEmits(['setVal']) const emits = defineEmits(['setVal'])
const isActive = ref<boolean>(false)
const isVisible = ref<boolean>(false)
function isTruthyFlag(val?: string) {
return val === 'true' || val === '1'
}
async function ok() { async function ok() {
let obj = { const obj = {
id: props.item.id, id: props.item.id,
key: props.item.key, key: props.item.key,
value: content.value, value: content.value,
title_fa:props.item.name, title_fa: props.item.title_fa ?? props.item.name,
type:props.item.type, type: props.item.type,
description: props.item.description, description: isVisible.value ? 'true' : 'false',
is_active: props.item.is_active is_active: isActive.value
} }
try { try {
loading.value = true loading.value = true
await setConfiguration(obj) await setConfiguration(obj)
await getConfiguration()
message.success('تغییر با موفقیت انجام شد') message.success('تغییر با موفقیت انجام شد')
} catch (e) { } catch (e) {
console.error(e) console.error(e)
@@ -68,7 +89,13 @@ const content = computed({
emits('setVal', val) emits('setVal', val)
} }
}) })
onMounted(() => {
isActive.value = props.item.is_active === true
isVisible.value = isTruthyFlag(props.item.description) || props.item.description == null
})
</script> </script>
<style> <style>
.editor-box { .editor-box {
max-height: 40vh; max-height: 40vh;
@@ -1,44 +1,57 @@
<template> <template>
<div class="flex-wrap mb-2 flex justify-between items-center border-1 border-gray-300 border-solid rounded-lg p-3"> <div class="mb-2 justify-between items-center border-1 border-gray-300 border-solid rounded-lg p-3">
<div class="flex flex-col justify-between "> <div>
<div class=" font-bold">{{ item.name }}</div> <div class="flex justify-between">
<div class=" text-xs ">کلید: {{ item.key }}</div> <div>{{ item.title_fa ?? item.name ?? '-' }}</div>
<div>
<a-switch
checked-children="فعال"
un-checked-children="غیرفعال"
v-model:checked="isActive"
@change="ok"
/>
</div>
</div>
</div> </div>
<div class="flex justify-between items-center mt-2">
<div class="flex"> <div class="text-xs items-center">کلید: {{ item.key }}</div>
<a-switch <div class="flex">
checked-children="فعال" <a-switch
un-checked-children="غیرفعال" checked-children="نمایش"
un-checked-children="عدم نمایش"
v-model:checked="value" v-model:checked="value"
@change="ok" @change="ok"
/> />
</div>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {loading} from '@/utils' import { loading } from '@/utils'
import {setConfiguration} from '@/api/configuration' import { setConfiguration } from '@/api/configuration'
import {message} from 'ant-design-vue' import { message } from 'ant-design-vue'
import {onMounted} from 'vue' import { onMounted } from 'vue'
import type {TagItem} from "@/components/BasicTags/model"; import type { TagItem } from '@/components/BasicTags/model'
interface Prop { interface Prop {
item: TagItem item: TagItem
} }
const props = defineProps<Prop>() const props = defineProps<Prop>()
const value = ref<string>('false') const value = ref<boolean>(false)
const isActive = ref<boolean>(false)
async function ok() { async function ok() {
let obj = { let obj = {
id: props.item.id, id: props.item.id,
key: props.item.key, key: props.item.key,
value: `${value.value}`, value: value.value ? 'true' : 'false',
type:props.item.type, type: props.item.type,
title_fa:props.item.name, title_fa: props.item.title_fa ?? props.item.name,
description: props.item.description, description: props.item.description,
is_active: props.item.is_active, is_active: isActive.value
} }
try { try {
loading.value = true loading.value = true
@@ -53,5 +66,6 @@ async function ok() {
onMounted(() => { onMounted(() => {
value.value = props.item.value === 'true' value.value = props.item.value === 'true'
isActive.value = props.item.is_active === true
}) })
</script> </script>
@@ -1,12 +1,49 @@
<template> <template>
<div class="mb-2 justify-between border-1 border-gray-300 border-solid rounded-lg p-3"> <div class="mb-2 justify-between items-center border-1 border-gray-300 border-solid rounded-lg p-3">
<div class="flex mb-2 flex-col justify-between "> <div>
<div class=" font-bold">{{ item.name }}</div> <div class="flex justify-between">
<div class=" text-xs ">کلید: {{ item.key }}</div> <div>{{ item.title_fa ?? item.name ?? '-' }}</div>
</div> <div class="flex justify-between gap-1"> <div>
<BasicSelect class="w-full" v-if="item.list && item.list.length > 0" @change="ok" value-name="value" key-name="lable" v-model:value="value" :items="itemListLocal"/> <a-switch
<BasicInput v-else class="flex-1" type="text" place-holder="مقدار" v-model:value="value" @input="isChanged=true" /> checked-children="فعال"
<div v-if="item.list && item.list.length==0 && isChanged" class="flex items-center " > un-checked-children="غیرفعال"
v-model:checked="isActive"
@change="ok"
/>
</div>
</div>
</div>
<div v-if="!item.list?.length" class="flex justify-between items-center mt-2">
<div class="text-xs">کلید: {{ item.key }}</div>
<div class="flex">
<a-switch
checked-children="نمایش"
un-checked-children="عدم نمایش"
v-model:checked="isVisible"
@change="ok"
/>
</div>
</div>
<div v-else class="text-xs mt-2">کلید: {{ item.key }}</div>
<div class="flex justify-between gap-1 mt-2">
<BasicSelect
v-if="item.list && item.list.length > 0"
class="w-full"
value-name="value"
key-name="lable"
v-model:value="configValue"
:items="itemListLocal"
@change="ok"
/>
<BasicInput
v-else
class="flex-1"
type="text"
place-holder="مقدار"
v-model:value="configValue"
@input="isChanged = true"
/>
<div v-if="item.list && item.list.length === 0 && isChanged" class="flex items-center">
<BaseIcon <BaseIcon
icon="vuesax-linear:tick-circle" icon="vuesax-linear:tick-circle"
class="mr-2 items-center cursor-pointer" class="mr-2 items-center cursor-pointer"
@@ -15,11 +52,11 @@
@click="ok()" @click="ok()"
/> />
<BaseIcon <BaseIcon
icon="vuesax-linear:close-circle" icon="vuesax-linear:close-circle"
class="mr-2 items-center cursor-pointer" class="mr-2 items-center cursor-pointer"
color="red" color="red"
@click="canselFn" @click="cancelFn"
size="24" size="24"
/> />
</div> </div>
</div> </div>
@@ -27,19 +64,21 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import type { Order } from '@/model/order'
import { loading } from '@/utils' import { loading } from '@/utils'
import { setConfiguration } from '@/api/configuration' import { setConfiguration } from '@/api/configuration'
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import type {itemConfig} from "@/model/configuration"; import type { itemConfig } from '@/model/configuration'
interface Prop { interface Prop {
item: itemConfig item: itemConfig
} }
const props = defineProps<Prop>() const props = defineProps<Prop>()
const value = ref<string>('') const configValue = ref<string>('')
const isChanged=ref<boolean>(false) const isActive = ref<boolean>(false)
const isVisible = ref<boolean>(false)
const isChanged = ref<boolean>(false)
const itemListLocal = computed(() => { const itemListLocal = computed(() => {
if (!props.item.list) return [] if (!props.item.list) return []
return props.item.list.map((x) => ({ return props.item.list.map((x) => ({
@@ -47,27 +86,39 @@ const itemListLocal = computed(() => {
value: x value: x
})) }))
}) })
const canselFn=()=>{
value.value = props.item.value
isChanged.value=false
function isTruthyFlag(val?: string) {
return val === 'true' || val === '1'
} }
async function ok() {
let obj = { function cancelFn() {
configValue.value = props.item.value
isChanged.value = false
}
function buildPayload() {
const hasSelectOptions = props.item.list && props.item.list.length > 0
return {
id: props.item.id, id: props.item.id,
key: props.item.key, key: props.item.key,
value: value.value, value: configValue.value,
title_fa:props.item.name, title_fa: props.item.title_fa ?? props.item.name,
type:props.item.type, type: props.item.type,
description: props.item.description, description: hasSelectOptions
is_active: props.item.is_active ? props.item.description
: isVisible.value
? 'true'
: 'false',
is_active: isActive.value
} }
}
async function ok() {
try { try {
loading.value = true loading.value = true
await setConfiguration(obj) await setConfiguration(buildPayload())
message.success('تغییر با موفقیت انجام شد') message.success('تغییر با موفقیت انجام شد')
isChanged.value=false isChanged.value = false
} catch (e) { } catch (e) {
console.error(e) console.error(e)
} finally { } finally {
@@ -76,8 +127,8 @@ async function ok() {
} }
onMounted(() => { onMounted(() => {
console.log(props.item) configValue.value = props.item.value
return value.value = props.item.value isActive.value = props.item.is_active === true
isVisible.value = isTruthyFlag(props.item.description) || props.item.description == null
}) })
</script> </script>
+10 -8
View File
@@ -99,6 +99,7 @@ const form = ref<Const>({
description: '', description: '',
is_active: true is_active: true
}) })
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const typeItems = [ const typeItems = [
@@ -116,9 +117,6 @@ const typeItems = [
} }
] ]
onMounted(() => {
initConfig()
})
const settingsConfig = { const settingsConfig = {
// اطلاعات پایه // اطلاعات پایه
'name_fa': { 'name_fa': {
@@ -261,18 +259,18 @@ async function initConfig() {
loading.value = true loading.value = true
baseData.value = await getConfiguration() baseData.value = await getConfiguration()
items.value = baseData.value?.map((x: Const) => { items.value = baseData.value?.map((x: Const) => {
const title = x?.title_fa ?? (settingsConfig[x.key]?.title ?? x?.key) const title_fa = x?.title_fa || settingsConfig[x.key]?.title || x?.key
return { return {
id: x.id, id: x.id,
name: `${title}`, name: title_fa,
title_fa,
value: x.value, value: x.value,
key: x.key, key: x.key,
type: x.type || 'text', type: x.type || 'text',
description: x.description, description: x.description,
is_active: x.is_active, is_active: x.is_active,
list: settingsConfig[x.key]?.list ?? [] list: settingsConfig[x.key]?.list ?? []
} }
}) })
} catch (e) { } catch (e) {
@@ -288,7 +286,7 @@ const groupedItems = computed(() => {
const type = item.type && result[item.type] ? item.type : 'text' const type = item.type && result[item.type] ? item.type : 'text'
result[type].push(item) result[type].push(item)
}) })
console.log(result) // console.log(result)
return result return result
}) })
@@ -318,7 +316,6 @@ async function ok() {
formRef.value?.validateFields().then(async () => { formRef.value?.validateFields().then(async () => {
try { try {
loading.value = true loading.value = true
console.log(form.value) console.log(form.value)
await setConfiguration(form.value) await setConfiguration(form.value)
await resetData() await resetData()
@@ -331,6 +328,11 @@ async function ok() {
} }
}) })
} }
onMounted(() => {
initConfig()
})
</script> </script>
<style lang="less"></style> <style lang="less"></style>
+29 -7
View File
@@ -216,6 +216,9 @@
@close="showMoneyWalletCharge = false" @close="showMoneyWalletCharge = false"
> >
<a-form :model="formCharge" ref="formChargeRef" autocomplete="off"> <a-form :model="formCharge" ref="formChargeRef" autocomplete="off">
<a-form-item name="talabBedehi">
<a-checkbox v-model:checked="formCharge.talabBedehi">طلب/بدهی</a-checkbox>
</a-form-item>
<a-form-item label="مقدار شارژ " name="value" :rules="inputRules()"> <a-form-item label="مقدار شارژ " name="value" :rules="inputRules()">
<BasicInput addon-before="ریال" v-model:value="formCharge.value" type="price" /> <BasicInput addon-before="ریال" v-model:value="formCharge.value" type="price" />
<div v-show="formCharge.value > 10"> <div v-show="formCharge.value > 10">
@@ -237,6 +240,9 @@
@close="showGoldWalletCharge = false" @close="showGoldWalletCharge = false"
> >
<a-form :model="formCharge" ref="formChargeRef" autocomplete="off"> <a-form :model="formCharge" ref="formChargeRef" autocomplete="off">
<a-form-item name="talabBedehi">
<a-checkbox v-model:checked="formCharge.talabBedehi">طلب/بدهی</a-checkbox>
</a-form-item>
<a-form-item label="مقدار شارژ " name="value" :rules="inputRules()"> <a-form-item label="مقدار شارژ " name="value" :rules="inputRules()">
<BasicInput addon-before="گرم" v-model:value="formCharge.value" type="number" /> <BasicInput addon-before="گرم" v-model:value="formCharge.value" type="number" />
<!-- <div v-show="formCharge.value > 10"> <!-- <div v-show="formCharge.value > 10">
@@ -469,22 +475,39 @@ async function add() {
loading.value = false loading.value = false
} }
function resetFormCharge(customerId: number) {
formCharge.value = {
customer_id: customerId,
value: undefined,
note: undefined,
talabBedehi: false
}
}
function buildChargePayload(): Charge {
return {
value: formCharge.value.value,
note: formCharge.value.note,
customer_id: formCharge.value.customer_id,
talabBedehi: formCharge.value.talabBedehi === true
}
}
async function walletMoneyCharge(val: Customer) { async function walletMoneyCharge(val: Customer) {
resetFormCharge(val.id)
showMoneyWalletCharge.value = true showMoneyWalletCharge.value = true
formCharge.value.customer_id = val.id
} }
async function walletGoldCharge(val: Customer) { async function walletGoldCharge(val: Customer) {
resetFormCharge(val.id)
showGoldWalletCharge.value = true showGoldWalletCharge.value = true
formCharge.value.customer_id = val.id
} }
async function chargeMoneyWallet() { async function chargeMoneyWallet() {
formChargeRef.value?.validateFields().then(async () => { formChargeRef.value?.validateFields().then(async () => {
try { try {
loading.value = true loading.value = true
await chargeWallet(formCharge.value, 'money') await chargeWallet(buildChargePayload(), 'money')
formCharge.value.value = undefined
message.success('افزایش اعتبار با موفقیت انجام شد') message.success('افزایش اعتبار با موفقیت انجام شد')
showMoneyWalletCharge.value = false showMoneyWalletCharge.value = false
} catch (e) { } catch (e) {
@@ -499,10 +522,9 @@ async function chargeGoldWallet() {
formChargeRef.value?.validateFields().then(async () => { formChargeRef.value?.validateFields().then(async () => {
try { try {
loading.value = true loading.value = true
await chargeWallet(formCharge.value, 'gold') await chargeWallet(buildChargePayload(), 'gold')
formCharge.value.value = undefined
message.success('افزایش اعتبار با موفقیت انجام شد') message.success('افزایش اعتبار با موفقیت انجام شد')
showMoneyWalletCharge.value = false showGoldWalletCharge.value = false
} catch (e) { } catch (e) {
console.log(e) console.log(e)
} finally { } finally {
+30 -8
View File
@@ -15,7 +15,7 @@
<component :is="selectedComponent" class="mr-5" />--> <component :is="selectedComponent" class="mr-5" />-->
<!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>--> <!-- <BasicShowContext title="پروژه ها"> <Search /> </BasicShowContext>-->
</div> </div>
<!-- </BasicMainCard>-->n <!-- </BasicMainCard>-->
<BasicModal <BasicModal
v-model:visible="addUserVisible" v-model:visible="addUserVisible"
width="50rem" width="50rem"
@@ -366,6 +366,9 @@
@close="showMoneyWalletCharge = false" @close="showMoneyWalletCharge = false"
> >
<a-form :model="formCharge" ref="formChargeRef" autocomplete="off"> <a-form :model="formCharge" ref="formChargeRef" autocomplete="off">
<a-form-item name="talabBedehi">
<a-checkbox v-model:checked="formCharge.talabBedehi">طلب/بدهی</a-checkbox>
</a-form-item>
<a-form-item label="مقدار شارژ " name="value" :rules="inputRules()"> <a-form-item label="مقدار شارژ " name="value" :rules="inputRules()">
<BasicInput addon-before="ریال" v-model:value="formCharge.value" type="price"/> <BasicInput addon-before="ریال" v-model:value="formCharge.value" type="price"/>
<div v-show="formCharge.value > 10"> <div v-show="formCharge.value > 10">
@@ -386,6 +389,9 @@
@close="showGoldWalletCharge = false" @close="showGoldWalletCharge = false"
> >
<a-form :model="formCharge" ref="formChargeRef" autocomplete="off"> <a-form :model="formCharge" ref="formChargeRef" autocomplete="off">
<a-form-item name="talabBedehi">
<a-checkbox v-model:checked="formCharge.talabBedehi">طلب/بدهی</a-checkbox>
</a-form-item>
<a-form-item label="مقدار شارژ " name="value" :rules="inputRules()"> <a-form-item label="مقدار شارژ " name="value" :rules="inputRules()">
<BasicInput addon-before="گرم" v-model:value="formCharge.value" type="number"/> <BasicInput addon-before="گرم" v-model:value="formCharge.value" type="number"/>
<!-- <div v-show="formCharge.value > 10"> <!-- <div v-show="formCharge.value > 10">
@@ -734,22 +740,39 @@ async function add() {
loading.value = false; loading.value = false;
} }
function resetFormCharge(customerId: number) {
formCharge.value = {
customer_id: customerId,
value: undefined,
note: undefined,
talabBedehi: false
};
}
function buildChargePayload(): Charge {
return {
value: formCharge.value.value,
note: formCharge.value.note,
customer_id: formCharge.value.customer_id,
talabBedehi: formCharge.value.talabBedehi === true
};
}
async function walletMoneyCharge(val: Customer) { async function walletMoneyCharge(val: Customer) {
resetFormCharge(val.id);
showMoneyWalletCharge.value = true; showMoneyWalletCharge.value = true;
formCharge.value.customer_id = val.id;
} }
async function walletGoldCharge(val: Customer) { async function walletGoldCharge(val: Customer) {
resetFormCharge(val.id);
showGoldWalletCharge.value = true; showGoldWalletCharge.value = true;
formCharge.value.customer_id = val.id;
} }
async function chargeMoneyWallet() { async function chargeMoneyWallet() {
formChargeRef.value?.validateFields().then(async () => { formChargeRef.value?.validateFields().then(async () => {
try { try {
loading.value = true; loading.value = true;
await chargeWallet(formCharge.value, "money"); await chargeWallet(buildChargePayload(), "money");
formCharge.value.value = undefined;
message.success("افزایش اعتبار با موفقیت انجام شد"); message.success("افزایش اعتبار با موفقیت انجام شد");
showMoneyWalletCharge.value = false; showMoneyWalletCharge.value = false;
} catch (e) { } catch (e) {
@@ -764,10 +787,9 @@ async function chargeGoldWallet() {
formChargeRef.value?.validateFields().then(async () => { formChargeRef.value?.validateFields().then(async () => {
try { try {
loading.value = true; loading.value = true;
await chargeWallet(formCharge.value, "gold"); await chargeWallet(buildChargePayload(), "gold");
formCharge.value.value = undefined;
message.success("افزایش اعتبار با موفقیت انجام شد"); message.success("افزایش اعتبار با موفقیت انجام شد");
showMoneyWalletCharge.value = false; showGoldWalletCharge.value = false;
} catch (e) { } catch (e) {
console.log(e); console.log(e);
} finally { } finally {