feat: complete admin panel and backend admin api migration
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<!--
|
||||
Ported from legacy henza_admin/src/views/manage/wallet.vue — the wallet
|
||||
settings screen. Two tabs, each writing one settings key.
|
||||
|
||||
Legacy quirk preserved: the "تاریخ تولد" tab is declared FIRST in the markup
|
||||
but carries key="2", while "پس از خرید" carries key="1" and is the default
|
||||
active tab — so the visually-second tab opens first.
|
||||
-->
|
||||
<div>
|
||||
<a-card v-if="hasPermission('config.wallet')" title="مدیریت کیف پول">
|
||||
<a-tabs default-active-key="1">
|
||||
<a-tab-pane key="2" tab="تاریخ تولد" force-render>
|
||||
<a-spin :spinning="loading" tip="لطفا کمی تامل کنید">
|
||||
<a-form layout="vertical" @submit.prevent="setWallet2">
|
||||
<div class="grid-2">
|
||||
<a-form-item
|
||||
label="انقضا (روز)"
|
||||
:validate-status="err2.birthday_expire ? 'error' : ''"
|
||||
:help="err2.birthday_expire"
|
||||
>
|
||||
<a-input-number v-model:value="form2.birthday_expire" class="w-full" :min="0" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="میزان (تومان)"
|
||||
:validate-status="err2.birthday_credit ? 'error' : ''"
|
||||
:help="err2.birthday_credit"
|
||||
>
|
||||
<a-input-number v-model:value="form2.birthday_credit" class="w-full" :min="0" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
<a-button type="primary" class="mb-4 mt-4 mr-4" @click="setWallet2">ارسال</a-button>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="1" tab="پس از خرید" force-render>
|
||||
<a-spin :spinning="loading" tip="لطفا کمی تامل کنید">
|
||||
<a-form layout="vertical" @submit.prevent="setWallet1">
|
||||
<div class="grid-2">
|
||||
<a-form-item
|
||||
label="انقضا (روز)"
|
||||
:validate-status="err1.expire ? 'error' : ''"
|
||||
:help="err1.expire"
|
||||
>
|
||||
<a-input-number v-model:value="form1.expire" class="w-full" :min="0" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="درصد"
|
||||
:validate-status="err1.percent ? 'error' : ''"
|
||||
:help="err1.percent"
|
||||
>
|
||||
<a-input-number
|
||||
v-model:value="form1.percent"
|
||||
class="w-full"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:formatter="(v: number | string) => `${v}%`"
|
||||
:parser="(v: string) => v.replace('%', '')"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<a-button type="primary" class="mb-4 mt-4 mr-4" @click="setWallet1">ارسال</a-button>
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { useUsersStore } from '../../stores/users';
|
||||
import api from '../../api/client';
|
||||
|
||||
const users = useUsersStore();
|
||||
const hasPermission = (rid: string) => Boolean(users.hasPermission(rid));
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const form1 = reactive<Record<string, any>>({ expire: undefined, percent: undefined });
|
||||
const form2 = reactive<Record<string, any>>({
|
||||
birthday_expire: undefined,
|
||||
birthday_credit: undefined,
|
||||
});
|
||||
const err1 = reactive<Record<string, string>>({});
|
||||
const err2 = reactive<Record<string, string>>({});
|
||||
|
||||
const REQUIRED = 'لطفا مقدار را وارد کنید';
|
||||
|
||||
async function setWallet1() {
|
||||
Object.keys(err1).forEach((k) => delete err1[k]);
|
||||
if (form1.expire === undefined || form1.expire === null) err1.expire = REQUIRED;
|
||||
if (form1.percent === undefined || form1.percent === null) err1.percent = REQUIRED;
|
||||
if (Object.keys(err1).length) return;
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
await api.post('wallet/config', { expire: form1.expire, percent: form1.percent });
|
||||
message.success('تغییرات ثبت شد');
|
||||
} catch (e: any) {
|
||||
message.error(e?.response?.data?.message ?? 'خطا در ثبت تغییرات');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function setWallet2() {
|
||||
Object.keys(err2).forEach((k) => delete err2[k]);
|
||||
if (form2.birthday_expire === undefined || form2.birthday_expire === null) {
|
||||
err2.birthday_expire = REQUIRED;
|
||||
}
|
||||
if (form2.birthday_credit === undefined || form2.birthday_credit === null) {
|
||||
err2.birthday_credit = REQUIRED;
|
||||
}
|
||||
if (Object.keys(err2).length) return;
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
await api.post('wallet/birthday/config', {
|
||||
birthday_expire: form2.birthday_expire,
|
||||
birthday_credit: form2.birthday_credit,
|
||||
});
|
||||
message.success('تغییرات ثبت شد');
|
||||
} catch (e: any) {
|
||||
message.error(e?.response?.data?.message ?? 'خطا در ثبت تغییرات');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const [c1, c2] = await Promise.all([
|
||||
api.get('wallet/config'),
|
||||
api.get('wallet/birthday/config'),
|
||||
]);
|
||||
Object.assign(form1, c1.data ?? {});
|
||||
Object.assign(form2, c2.data ?? {});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.grid-2 {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
.mb-4 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.mt-4 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user