add reygiri page

This commit is contained in:
2026-07-12 18:11:42 +02:00
parent b2e59464a4
commit 4b59444e7d
4 changed files with 116 additions and 48 deletions
+1
View File
@@ -10,6 +10,7 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
_index: typeof import('./src/core/components/_sample/_index.vue')['default']
AAlert: typeof import('ant-design-vue/es')['Alert']
AAvatar: typeof import('ant-design-vue/es')['Avatar']
ABadge: typeof import('ant-design-vue/es')['Badge']
AButton: typeof import('ant-design-vue/es')['Button']
+1 -8
View File
@@ -24,11 +24,4 @@ export const updateBannerConst = async (obj: Const) =>
await useAxios.put<Const>(`/admin/const/${obj.id}`, obj)
export const getHeaderBannerConst = async () =>
await useAxios.get<Const>('/api/const/key/header_banner')
/** GET /api/const/key/reygiri_sites */
export const getReygiriSitesConst = async () =>
await useAxios.get<Const | Array<Const>>('/api/const/key/reygiri_sites')
export const updateReygiriSitesConst = async (obj: Const) =>
await useAxios.put<Const>(`/admin/const/${obj.id}`, obj)
await useAxios.get<Const>('/api/const/key/header_banner')
+91 -28
View File
@@ -2,15 +2,34 @@
<div class="capture-sites-page">
<BasicShowContext title="لیست سایت‌های ری‌گیری">
<template #extra>
<BaseButton type="primary" size="small" :disabled="loading" @click="openAdd">
<span>افزودن سایت</span>
<BaseIcon icon="vuesax-linear:add" size="16" />
</BaseButton>
<div class="capture-sites-page__toolbar">
<label v-if="enabledRow" class="capture-sites-page__switch">
<span>نمایش سایت‌ها</span>
<a-switch
v-model:checked="enabled"
:loading="savingEnabled"
size="small"
@change="saveEnabled"
/>
</label>
<BaseButton type="primary" size="small" :disabled="loading || !trackingSystemsRow" @click="openAdd">
<span>افزودن سایت</span>
<BaseIcon icon="vuesax-linear:add" size="16" />
</BaseButton>
</div>
</template>
<a-spin :spinning="loading">
<a-alert
v-if="!trackingSystemsRow?.id"
type="warning"
show-icon
message="تنظیم tracking_systems در get_settings یافت نشد"
class="mb-4"
/>
<a-empty
v-if="!sites.length"
v-else-if="!sites.length"
description="هنوز سایتی ثبت نشده"
class="capture-sites-page__empty"
/>
@@ -85,24 +104,29 @@ import Icon from '@core/components/BaseIcon/src/Icon.vue'
import BasicShowContext from '@/components/BasicShowContext.vue'
import BasicModal from '@/components/BasicModal.vue'
import type { CaptureSite } from '@/model/captureSite'
import {
createAddConst,
getReygiriSitesConst,
updateReygiriSitesConst,
} from '@/api/consts'
import type { Const } from '@/model/configuration'
import { getConfiguration, setConfiguration } from '@/api/configuration'
import { inputRules } from '@/utils/inputRules'
import {
REYGIri_SITES_KEY,
normalizeReygiriSitesConst,
TRACKING_SYSTEMS_ENABLED_KEY,
TRACKING_SYSTEMS_KEY,
buildSettingSavePayload,
findSettingRow,
parseReygiriSitesValue,
parseTrackingSystemsEnabled,
serializeReygiriSites,
serializeTrackingSystemsEnabled,
} from '@/utils/reygiriSites'
const sites = ref<CaptureSite[]>([])
const loading = ref(false)
const saving = ref(false)
const savingEnabled = ref(false)
const editorVisible = ref(false)
const editIndex = ref<number | null>(null)
const constId = ref<number | null>(null)
const trackingSystemsRow = ref<Const | null>(null)
const enabledRow = ref<Const | null>(null)
const enabled = ref(true)
const formRef = ref<FormInstance>()
const form = ref({
@@ -148,6 +172,11 @@ function resetForm() {
}
function openAdd() {
if (!trackingSystemsRow.value?.id) {
message.error('تنظیم tracking_systems یافت نشد')
return
}
editIndex.value = null
resetForm()
editorVisible.value = true
@@ -172,20 +201,37 @@ function closeEditor() {
}
async function persistSites() {
const payload = {
key: REYGIri_SITES_KEY,
value: serializeReygiriSites(sites.value),
is_active: true,
description: 'لیست سایت‌های ری‌گیری',
}
if (constId.value) {
await updateReygiriSitesConst({ id: constId.value, ...payload })
const row = trackingSystemsRow.value
if (!row?.id) {
message.error('تنظیم tracking_systems یافت نشد')
return
}
const created = await createAddConst(payload)
constId.value = created.id ?? created.const_id ?? null
const value = serializeReygiriSites(sites.value)
await setConfiguration(buildSettingSavePayload(row, value))
trackingSystemsRow.value = { ...row, value }
}
async function saveEnabled(checked: boolean) {
const row = enabledRow.value
if (!row?.id) {
message.warning('تنظیم tracking_systems_enabled یافت نشد')
return
}
savingEnabled.value = true
try {
const value = serializeTrackingSystemsEnabled(checked)
await setConfiguration(buildSettingSavePayload(row, value))
enabledRow.value = { ...row, value }
message.success('وضعیت نمایش سایت‌ها ذخیره شد')
} catch (error) {
console.error(error)
enabled.value = parseTrackingSystemsEnabled(enabledRow.value?.value)
message.error('خطا در ذخیره وضعیت نمایش')
} finally {
savingEnabled.value = false
}
}
async function submitForm() {
@@ -210,6 +256,7 @@ async function submitForm() {
closeEditor()
} catch (error) {
console.error(error)
message.error('خطا در ذخیره سایت')
} finally {
saving.value = false
}
@@ -245,10 +292,11 @@ function confirmDelete(index: number) {
async function loadSites() {
loading.value = true
try {
const res = await getReygiriSitesConst()
const normalized = normalizeReygiriSitesConst(res)
constId.value = normalized.constId
sites.value = normalized.sites
const rows = (await getConfiguration()) ?? []
trackingSystemsRow.value = findSettingRow(rows, TRACKING_SYSTEMS_KEY) ?? null
enabledRow.value = findSettingRow(rows, TRACKING_SYSTEMS_ENABLED_KEY) ?? null
sites.value = parseReygiriSitesValue(trackingSystemsRow.value?.value)
enabled.value = parseTrackingSystemsEnabled(enabledRow.value?.value)
} catch (error) {
console.error('خطا در دریافت سایت‌های ری‌گیری:', error)
message.error('خطا در دریافت لیست سایت‌های ری‌گیری')
@@ -272,6 +320,21 @@ onMounted(() => {
min-height: 0;
}
.capture-sites-page__toolbar {
display: flex;
align-items: center;
gap: 0.75rem;
}
.capture-sites-page__switch {
display: inline-flex;
align-items: center;
gap: 0.5rem;
margin: 0;
font-size: 0.8125rem;
color: var(--admin-text-secondary);
}
.capture-sites-page__empty {
margin-top: 3rem;
}
+23 -12
View File
@@ -1,20 +1,23 @@
import type { Const } from '@/model/const'
import type { Const } from '@/model/configuration'
import type { CaptureSite } from '@/model/captureSite'
import { isSwitchOn, switchToString } from '@/pages/menuPages/configuration/settingTypes'
export const REYGIri_SITES_KEY = 'reygiri_sites'
export const TRACKING_SYSTEMS_KEY = 'tracking_systems'
export const TRACKING_SYSTEMS_ENABLED_KEY = 'tracking_systems_enabled'
export function normalizeReygiriSitesConst(response: Const | Const[] | null | undefined): {
constId: number | null
sites: CaptureSite[]
} {
const record = Array.isArray(response) ? response[0] : response
if (!record) {
return { constId: null, sites: [] }
}
export function findSettingRow(rows: Const[], key: string): Const | undefined {
return rows.find((row) => row.key === key)
}
export function buildSettingSavePayload(row: Const, value: string): Const {
return {
constId: record.id ?? record.const_id ?? null,
sites: parseReygiriSitesValue(record.value),
id: row.id,
key: row.key,
value,
description: row.description ?? '',
is_active: true,
title_fa: row.title_fa ?? '',
type: row.type ?? 'text',
}
}
@@ -46,3 +49,11 @@ export function serializeReygiriSites(sites: CaptureSite[]): string {
}))
)
}
export function parseTrackingSystemsEnabled(value: string | null | undefined): boolean {
return isSwitchOn(value ?? undefined)
}
export function serializeTrackingSystemsEnabled(enabled: boolean): string {
return switchToString(enabled)
}