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' { declare module '@vue/runtime-core' {
export interface GlobalComponents { export interface GlobalComponents {
_index: typeof import('./src/core/components/_sample/_index.vue')['default'] _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'] AAvatar: typeof import('ant-design-vue/es')['Avatar']
ABadge: typeof import('ant-design-vue/es')['Badge'] ABadge: typeof import('ant-design-vue/es')['Badge']
AButton: typeof import('ant-design-vue/es')['Button'] AButton: typeof import('ant-design-vue/es')['Button']
-7
View File
@@ -25,10 +25,3 @@ export const updateBannerConst = async (obj: Const) =>
export const getHeaderBannerConst = async () => export const getHeaderBannerConst = async () =>
await useAxios.get<Const>('/api/const/key/header_banner') 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)
+91 -28
View File
@@ -2,15 +2,34 @@
<div class="capture-sites-page"> <div class="capture-sites-page">
<BasicShowContext title="لیست سایت‌های ری‌گیری"> <BasicShowContext title="لیست سایت‌های ری‌گیری">
<template #extra> <template #extra>
<BaseButton type="primary" size="small" :disabled="loading" @click="openAdd"> <div class="capture-sites-page__toolbar">
<span>افزودن سایت</span> <label v-if="enabledRow" class="capture-sites-page__switch">
<BaseIcon icon="vuesax-linear:add" size="16" /> <span>نمایش سایت‌ها</span>
</BaseButton> <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> </template>
<a-spin :spinning="loading"> <a-spin :spinning="loading">
<a-alert
v-if="!trackingSystemsRow?.id"
type="warning"
show-icon
message="تنظیم tracking_systems در get_settings یافت نشد"
class="mb-4"
/>
<a-empty <a-empty
v-if="!sites.length" v-else-if="!sites.length"
description="هنوز سایتی ثبت نشده" description="هنوز سایتی ثبت نشده"
class="capture-sites-page__empty" 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 BasicShowContext from '@/components/BasicShowContext.vue'
import BasicModal from '@/components/BasicModal.vue' import BasicModal from '@/components/BasicModal.vue'
import type { CaptureSite } from '@/model/captureSite' import type { CaptureSite } from '@/model/captureSite'
import { import type { Const } from '@/model/configuration'
createAddConst, import { getConfiguration, setConfiguration } from '@/api/configuration'
getReygiriSitesConst,
updateReygiriSitesConst,
} from '@/api/consts'
import { inputRules } from '@/utils/inputRules' import { inputRules } from '@/utils/inputRules'
import { import {
REYGIri_SITES_KEY, TRACKING_SYSTEMS_ENABLED_KEY,
normalizeReygiriSitesConst, TRACKING_SYSTEMS_KEY,
buildSettingSavePayload,
findSettingRow,
parseReygiriSitesValue,
parseTrackingSystemsEnabled,
serializeReygiriSites, serializeReygiriSites,
serializeTrackingSystemsEnabled,
} from '@/utils/reygiriSites' } from '@/utils/reygiriSites'
const sites = ref<CaptureSite[]>([]) const sites = ref<CaptureSite[]>([])
const loading = ref(false) const loading = ref(false)
const saving = ref(false) const saving = ref(false)
const savingEnabled = ref(false)
const editorVisible = ref(false) const editorVisible = ref(false)
const editIndex = ref<number | null>(null) 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 formRef = ref<FormInstance>()
const form = ref({ const form = ref({
@@ -148,6 +172,11 @@ function resetForm() {
} }
function openAdd() { function openAdd() {
if (!trackingSystemsRow.value?.id) {
message.error('تنظیم tracking_systems یافت نشد')
return
}
editIndex.value = null editIndex.value = null
resetForm() resetForm()
editorVisible.value = true editorVisible.value = true
@@ -172,20 +201,37 @@ function closeEditor() {
} }
async function persistSites() { async function persistSites() {
const payload = { const row = trackingSystemsRow.value
key: REYGIri_SITES_KEY, if (!row?.id) {
value: serializeReygiriSites(sites.value), message.error('تنظیم tracking_systems یافت نشد')
is_active: true,
description: 'لیست سایت‌های ری‌گیری',
}
if (constId.value) {
await updateReygiriSitesConst({ id: constId.value, ...payload })
return return
} }
const created = await createAddConst(payload) const value = serializeReygiriSites(sites.value)
constId.value = created.id ?? created.const_id ?? null 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() { async function submitForm() {
@@ -210,6 +256,7 @@ async function submitForm() {
closeEditor() closeEditor()
} catch (error) { } catch (error) {
console.error(error) console.error(error)
message.error('خطا در ذخیره سایت')
} finally { } finally {
saving.value = false saving.value = false
} }
@@ -245,10 +292,11 @@ function confirmDelete(index: number) {
async function loadSites() { async function loadSites() {
loading.value = true loading.value = true
try { try {
const res = await getReygiriSitesConst() const rows = (await getConfiguration()) ?? []
const normalized = normalizeReygiriSitesConst(res) trackingSystemsRow.value = findSettingRow(rows, TRACKING_SYSTEMS_KEY) ?? null
constId.value = normalized.constId enabledRow.value = findSettingRow(rows, TRACKING_SYSTEMS_ENABLED_KEY) ?? null
sites.value = normalized.sites sites.value = parseReygiriSitesValue(trackingSystemsRow.value?.value)
enabled.value = parseTrackingSystemsEnabled(enabledRow.value?.value)
} catch (error) { } catch (error) {
console.error('خطا در دریافت سایت‌های ری‌گیری:', error) console.error('خطا در دریافت سایت‌های ری‌گیری:', error)
message.error('خطا در دریافت لیست سایت‌های ری‌گیری') message.error('خطا در دریافت لیست سایت‌های ری‌گیری')
@@ -272,6 +320,21 @@ onMounted(() => {
min-height: 0; 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 { .capture-sites-page__empty {
margin-top: 3rem; 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 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): { export function findSettingRow(rows: Const[], key: string): Const | undefined {
constId: number | null return rows.find((row) => row.key === key)
sites: CaptureSite[] }
} {
const record = Array.isArray(response) ? response[0] : response
if (!record) {
return { constId: null, sites: [] }
}
export function buildSettingSavePayload(row: Const, value: string): Const {
return { return {
constId: record.id ?? record.const_id ?? null, id: row.id,
sites: parseReygiriSitesValue(record.value), 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)
}