fix some bugs from accounting 3

This commit is contained in:
2026-07-28 21:57:39 +03:30
parent f3a082ef73
commit 2cf4ec1bd9
4 changed files with 85 additions and 6 deletions
+12
View File
@@ -6,6 +6,7 @@ export interface AppNotification {
body: string body: string
severity: 'info' | 'success' | 'warning' | 'danger' severity: 'info' | 'success' | 'warning' | 'danger'
is_active: boolean is_active: boolean
is_system?: boolean
created_by?: number | null created_by?: number | null
created_at?: string created_at?: string
updated_at?: string updated_at?: string
@@ -18,6 +19,17 @@ export interface AppNotification {
customer_ids?: number[] customer_ids?: number[]
} }
export type AppNotificationSourceFilter = 'all' | 'admin' | 'system'
export const APP_NOTIFICATION_SOURCE_TABS: Array<{
value: AppNotificationSourceFilter
label: string
}> = [
{ value: 'all', label: 'همه' },
{ value: 'admin', label: 'اعلان ادمین' },
{ value: 'system', label: 'سیستمی' },
]
export const APP_NOTIFICATION_SEVERITIES = [ export const APP_NOTIFICATION_SEVERITIES = [
{ value: 'info', label: 'اطلاعات (info)' }, { value: 'info', label: 'اطلاعات (info)' },
{ value: 'success', label: 'موفق (success)' }, { value: 'success', label: 'موفق (success)' },
@@ -2,9 +2,23 @@
<div> <div>
<BasicShowContext title="اعلان‌های اپ"> <BasicShowContext title="اعلان‌های اپ">
<template #extra> <template #extra>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2 flex-wrap">
<a-radio-group
v-model:value="sourceFilter"
button-style="solid"
size="small"
@change="onSourceChange"
>
<a-radio-button
v-for="tab in sourceTabs"
:key="tab.value"
:value="tab.value"
>
{{ tab.label }}
</a-radio-button>
</a-radio-group>
<AdminFieldHelp <AdminFieldHelp
text="اعلان را برای همه، گروه (مثلاً کسانی که مدتی نیامده‌اند) یا مشتری تکی بفرستید. کاربران آنلاین از طریق اتصال زنده اپ، بلافاصله بج اعلان را می‌بینند." text="اعلان ادمین را دستی می‌فرستید؛ اعلان سیستمی خودکار برای خرید/فروش/واریز/برداشت ساخته می‌شود. از تب‌ها برای جدا کردن لیست استفاده کنید."
/> />
<BaseButton type="primary" size="small" @click="emits('add')"> <BaseButton type="primary" size="small" @click="emits('add')">
<span>افزودن اعلان</span> <span>افزودن اعلان</span>
@@ -34,7 +48,7 @@
@click="emits('readers', record)" @click="emits('readers', record)"
/> />
</a-tooltip> </a-tooltip>
<a-tooltip placement="bottom"> <a-tooltip v-if="!isSystemRecord(record)" placement="bottom">
<template #title>ویرایش</template> <template #title>ویرایش</template>
<Icon <Icon
icon="vuesax-linear:edit" icon="vuesax-linear:edit"
@@ -69,15 +83,23 @@
</template> </template>
<script lang="tsx" setup> <script lang="tsx" setup>
import { computed, ref } from 'vue'
import type { TableInput } from '@core/type/baseTable' import type { TableInput } from '@core/type/baseTable'
import useBaseTable from '@core/components/BaseTableOld/hooks/useBaseTable' import useBaseTable from '@core/components/BaseTableOld/hooks/useBaseTable'
import Icon from '@core/components/BaseIcon/src/Icon.vue' import Icon from '@core/components/BaseIcon/src/Icon.vue'
import { cols } from '../hooks/appNotificationsColumns' import { cols } from '../hooks/appNotificationsColumns'
import { getAppNotificationsTable } from '@/api/appNotifications' import { getAppNotificationsTable } from '@/api/appNotifications'
import AdminFieldHelp from '@/components/AdminFieldHelp.vue' import AdminFieldHelp from '@/components/AdminFieldHelp.vue'
import {
APP_NOTIFICATION_SOURCE_TABS,
type AppNotificationSourceFilter,
} from '@/model/appNotifications'
const [submit, reload] = useBaseTable() const [submit, reload] = useBaseTable()
const sourceFilter = ref<AppNotificationSourceFilter>('all')
const sourceTabs = APP_NOTIFICATION_SOURCE_TABS
const emits = defineEmits<{ const emits = defineEmits<{
add: [] add: []
edit: [record: Record<string, unknown>] edit: [record: Record<string, unknown>]
@@ -87,9 +109,23 @@ const emits = defineEmits<{
recipients: [record: Record<string, unknown>] recipients: [record: Record<string, unknown>]
}>() }>()
const tblProps = { function isSystemRecord(record: Record<string, unknown>) {
if (typeof record.is_system === 'boolean') return record.is_system
const label = String(record.audience_label || '')
return record.created_by == null && label.startsWith('سیستمی')
}
const tblProps = computed(() => ({
columns: cols, columns: cols,
api: (params: TableInput) => getAppNotificationsTable(params), api: (params: TableInput) =>
getAppNotificationsTable({
...params,
source: sourceFilter.value,
} as TableInput & { source: AppNotificationSourceFilter }),
}))
function onSourceChange() {
reload()
} }
function fetch() { function fetch() {
@@ -28,6 +28,22 @@ const audienceTypeColor: Record<string, string> = {
customers: 'gold', customers: 'gold',
} }
function isSystemRow(record: any): boolean {
if (typeof record?.is_system === 'boolean') return record.is_system
if (record?.created_by == null && String(record?.audience_label || '').startsWith('سیستمی')) {
return true
}
return false
}
function audienceDisplayLabel(record: any): string {
const raw = String(record.audience_label || 'همه کاربران')
if (isSystemRow(record)) {
return raw.replace(/^سیستمی\s*[—\-–]\s*/, '') || raw
}
return raw
}
export const cols: BaseTableColumn[] = [ export const cols: BaseTableColumn[] = [
{ {
title: 'ردیف', title: 'ردیف',
@@ -35,6 +51,17 @@ export const cols: BaseTableColumn[] = [
key: 'id', key: 'id',
customRender: (record: any) => record.index + 1, customRender: (record: any) => record.index + 1,
}, },
{
title: 'منبع',
dataIndex: 'is_system',
key: 'is_system',
width: 110,
customRender: ({ record }) => (
<CustomTag color={isSystemRow(record) ? 'default' : 'geekblue'}>
{isSystemRow(record) ? 'سیستمی' : 'ادمین'}
</CustomTag>
),
},
{ {
title: 'عنوان', title: 'عنوان',
dataIndex: 'title', dataIndex: 'title',
@@ -56,7 +83,7 @@ export const cols: BaseTableColumn[] = [
dataIndex: 'audience_label', dataIndex: 'audience_label',
key: 'audience_label', key: 'audience_label',
customRender: ({ record }) => { customRender: ({ record }) => {
const label = record.audience_label || 'همه کاربران' const label = audienceDisplayLabel(record)
const count = const count =
record.audience_type && record.audience_type !== 'all' record.audience_type && record.audience_type !== 'all'
? ` (${Number(record.recipients_count ?? 0)} نفر)` ? ` (${Number(record.recipients_count ?? 0)} نفر)`
@@ -192,6 +192,10 @@ function openAdd() {
} }
function openEdit(record: AppNotification) { function openEdit(record: AppNotification) {
if (record.is_system) {
message.warning('اعلان سیستمی قابل ویرایش نیست')
return
}
editId.value = record.id editId.value = record.id
form.value = cloneDeep({ form.value = cloneDeep({
title: record.title, title: record.title,