feat(settings): catalog keys UI and per-tenant program settings editor
Add/remove keys from the Khanegi versions list (form or JSON), edit values per version, and proxy /get_settings for local work. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -23,6 +23,7 @@ const form = reactive({
|
||||
nameFa: '',
|
||||
nameEn: '',
|
||||
domain: '',
|
||||
domains: [] as string[],
|
||||
avatarUrl: '',
|
||||
appVersion: '1',
|
||||
uiVariant: 'modular' as 'modular' | 'newTheme',
|
||||
@@ -51,6 +52,7 @@ async function load() {
|
||||
if (!isEdit.value) {
|
||||
const q = String(route.query.product || '')
|
||||
form.product = q === 'khanegi' ? 'khanegi' : 'hamkar'
|
||||
form.domains = []
|
||||
createdAt.value = null
|
||||
return
|
||||
}
|
||||
@@ -65,6 +67,7 @@ async function load() {
|
||||
nameFa: data.nameFa,
|
||||
nameEn: data.nameEn || '',
|
||||
domain: data.domain,
|
||||
domains: Array.isArray(data.domains) ? data.domains.map(String) : [],
|
||||
avatarUrl: data.avatarUrl || '',
|
||||
appVersion: data.appVersion || '1',
|
||||
uiVariant: data.uiVariant === 'newTheme' ? 'newTheme' : 'modular',
|
||||
@@ -119,7 +122,10 @@ async function save() {
|
||||
}
|
||||
saving.value = true
|
||||
try {
|
||||
const payload = { ...form }
|
||||
const payload = {
|
||||
...form,
|
||||
domains: form.domains.map((item) => item.trim()).filter(Boolean),
|
||||
}
|
||||
if (!payload.remoteApiToken) {
|
||||
delete (payload as any).remoteApiToken
|
||||
}
|
||||
@@ -153,19 +159,30 @@ onMounted(load)
|
||||
<h1 class="page-title">{{ isEdit ? 'مدیریت نسخه' : 'نسخه فروشی جدید' }}</h1>
|
||||
<p class="page-sub">محصول: {{ productLabel }} · تنظیمات رجیستری برند (/get_user)</p>
|
||||
</div>
|
||||
<a-button
|
||||
v-if="isEdit && form.product === 'khanegi'"
|
||||
type="primary"
|
||||
ghost
|
||||
@click="
|
||||
router.push({
|
||||
name: form.uiVariant === 'newTheme' ? 'version-ui' : 'version-ui-modular',
|
||||
params: { id: route.params.id },
|
||||
})
|
||||
"
|
||||
>
|
||||
ظاهر اپ
|
||||
</a-button>
|
||||
<a-space v-if="isEdit && form.product === 'khanegi'" wrap>
|
||||
<a-button
|
||||
@click="
|
||||
router.push({
|
||||
name: 'version-program-settings',
|
||||
params: { id: route.params.id },
|
||||
})
|
||||
"
|
||||
>
|
||||
تنظیمات برنامه
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
ghost
|
||||
@click="
|
||||
router.push({
|
||||
name: form.uiVariant === 'newTheme' ? 'version-ui' : 'version-ui-modular',
|
||||
params: { id: route.params.id },
|
||||
})
|
||||
"
|
||||
>
|
||||
ظاهر اپ
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
<a-form :model="form" layout="vertical" @finish="save">
|
||||
@@ -189,6 +206,29 @@ onMounted(load)
|
||||
<a-form-item label="دامنه فروشگاه" name="domain" :rules="[{ required: true, message: 'لازم است' }]">
|
||||
<a-input v-model:value="form.domain" size="large" placeholder="example.com" dir="ltr" />
|
||||
</a-form-item>
|
||||
<a-form-item label="دامنهها و IPهای اضافی">
|
||||
<p class="field-hint">
|
||||
برای /get_user. داخل همان محصول (خانگی یا همکار) هر دامنه/IP فقط روی یک نسخه میماند؛
|
||||
اگر از قبل روی نسخه دیگری از همین محصول باشد، از آنجا برداشته و به این نسخه اضافه میشود.
|
||||
خانگی و همکار روی هم اثر ندارند.
|
||||
</p>
|
||||
<div class="alias-list">
|
||||
<div v-for="(_, index) in form.domains" :key="index" class="alias-row">
|
||||
<a-input
|
||||
v-model:value="form.domains[index]"
|
||||
size="large"
|
||||
dir="ltr"
|
||||
placeholder="مثلاً 192.168.1.10 یا shop.example.com"
|
||||
/>
|
||||
<a-button danger @click="form.domains.splice(index, 1)">
|
||||
<DeleteOutlined />
|
||||
</a-button>
|
||||
</div>
|
||||
<a-button @click="form.domains.push('')">
|
||||
<PlusOutlined /> افزودن دامنه / IP
|
||||
</a-button>
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item v-if="isEdit" label="تاریخ ایجاد">
|
||||
<a-input :value="formatIranDateTime(createdAt)" size="large" disabled />
|
||||
</a-form-item>
|
||||
@@ -322,4 +362,19 @@ onMounted(load)
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.alias-list {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.alias-row {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.alias-row :deep(.ant-input) {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user