store2
This commit is contained in:
@@ -3,5 +3,10 @@ import useAxios from "@core/utils/useAxios"
|
||||
|
||||
export const setConfiguration = async (obj: Const) => await useAxios.post<Const>(`/admin/get_settings`, obj)
|
||||
|
||||
/** همه تنظیمات — برای خواندن داخلی (is_store، unit و ...) */
|
||||
export const getConfiguration = async () =>
|
||||
await useAxios.get<Array<Const>>(`/admin/get_settings`)
|
||||
|
||||
/** فقط تنظیمات قابل ویرایش — برای صفحه تنظیمات ادمین */
|
||||
export const getEditableConfiguration = async () =>
|
||||
await useAxios.get<Array<Const>>(`/admin/get_settings`, { params: { editable_only: 1 } })
|
||||
@@ -13,6 +13,7 @@ import { setupRoutes } from '@/router'
|
||||
//import { resetRouter } from '@core/router'
|
||||
import { useUserStore } from '@/store/userStore'
|
||||
import { setupPinia } from '@core/plugins/pinia'
|
||||
import { initStoreModeFromSettings } from '@/utils/config'
|
||||
|
||||
const init = async () => {
|
||||
const app = createApp(App)
|
||||
@@ -27,6 +28,7 @@ const init = async () => {
|
||||
const token = getToken()
|
||||
if (token) {
|
||||
await userStore.getMyInfo()
|
||||
await initStoreModeFromSettings()
|
||||
setupRoutes(['*'])
|
||||
//setupRoutes(['project'])
|
||||
/*router.removeRoute('usersMain')
|
||||
|
||||
@@ -41,6 +41,8 @@ export interface Product{
|
||||
file_id?: number
|
||||
file?: File
|
||||
original_image?: File
|
||||
inventory?: number
|
||||
description?: string | null
|
||||
}
|
||||
|
||||
export interface MethodePrices {
|
||||
|
||||
@@ -171,14 +171,16 @@ import type { FormInstance } from 'ant-design-vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import type { Const } from '@/model/configuration'
|
||||
import { loading } from '@/utils'
|
||||
import { getConfiguration, setConfiguration } from '@/api/configuration'
|
||||
import { getEditableConfiguration, setConfiguration } from '@/api/configuration'
|
||||
import SettingValueField from './SettingValueField.vue'
|
||||
import SettingCard from './SettingCard.vue'
|
||||
import { setStoreModeFromSettings } from '@/utils/config'
|
||||
import {
|
||||
SETTING_TYPE_OPTIONS,
|
||||
formatValueForSave,
|
||||
helpText,
|
||||
isSettingVisible,
|
||||
isSwitchOn,
|
||||
resolveSettingFieldType
|
||||
} from './settingTypes'
|
||||
|
||||
@@ -410,7 +412,11 @@ onMounted(() => {
|
||||
async function initConfig() {
|
||||
try {
|
||||
loading.value = true
|
||||
baseData.value = (await getConfiguration()) ?? []
|
||||
baseData.value = (await getEditableConfiguration()) ?? []
|
||||
const storeRow = baseData.value.find((row) => row.key === 'is_store')
|
||||
if (storeRow) {
|
||||
setStoreModeFromSettings(isSwitchOn(storeRow.value))
|
||||
}
|
||||
syncDraftsFromBase()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
@@ -481,6 +487,9 @@ async function saveSettingRow(row: Const, overrides?: { isActive?: boolean }) {
|
||||
row.value = value
|
||||
row.is_active = isActive
|
||||
drafts.value[id] = value
|
||||
if (row.key === 'is_store') {
|
||||
setStoreModeFromSettings(isSwitchOn(value))
|
||||
}
|
||||
savedFlashIds.value.add(id)
|
||||
if (saveTimers.has(id)) clearTimeout(saveTimers.get(id))
|
||||
saveTimers.set(
|
||||
|
||||
@@ -5,7 +5,6 @@ export type SettingFieldType = 'text' | 'number' | 'switch' | 'select' | 'longte
|
||||
|
||||
/** کلیدهای legacy — در پنل نمایش داده نمیشوند (جایگزین: price_provider) */
|
||||
export const HIDDEN_LEGACY_SETTING_KEYS = new Set([
|
||||
'tabanGohar_price',
|
||||
'main_product_price',
|
||||
'montzar_price',
|
||||
'etehadie_api_url',
|
||||
@@ -149,7 +148,7 @@ export function parseSelectOptions(
|
||||
source = source.split('|').pop() || ''
|
||||
}
|
||||
|
||||
const deprecatedOpts = new Set(['taban_gohar', 'etehadie'])
|
||||
const deprecatedOpts = new Set(['etehadie'])
|
||||
const opts = source
|
||||
.split(',')
|
||||
.map((s) => s.trim())
|
||||
|
||||
@@ -194,6 +194,14 @@
|
||||
<a-form-item label="واحد" name="unit" :rules="inputRules()">
|
||||
<BasicSelect v-model:value="form.unit" :items="unitItems" valueName="value" keyName="value" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
v-if="isStore && !isMeltedCategory"
|
||||
label="تعداد موجودی"
|
||||
name="inventory"
|
||||
:rules="inputRules()"
|
||||
>
|
||||
<BasicInput v-model:value="form.inventory" type="number" />
|
||||
</a-form-item>
|
||||
<a-form-item label="هزینه نقدی موقع خرید" name="cash_fee_buy" :rules="inputRules()">
|
||||
<BasicInput v-model:value="form.cash_fee_buy" addon-before="ریال" type="price" />
|
||||
</a-form-item>
|
||||
@@ -249,6 +257,7 @@ import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import BaseCollapse from '@/components/BaseCollapse.vue'
|
||||
import IndexImageUploader from '@/components/ProductUploader/IndexImageUploader.vue'
|
||||
import { getConfiguration } from '@/api/configuration'
|
||||
import { isSwitchOn } from '@/pages/menuPages/configuration/settingTypes'
|
||||
import type { last } from '@/model/price'
|
||||
import type { MethodePrices } from '@/model/product'
|
||||
import { usePrice } from '@core/utils/usePrice'
|
||||
@@ -275,8 +284,11 @@ const props = defineProps<{
|
||||
customLocale: any
|
||||
productIndexImage: any[]
|
||||
editId?: number
|
||||
isStore?: boolean
|
||||
}>()
|
||||
|
||||
const isStore = ref(Boolean(props.isStore))
|
||||
|
||||
const tradeWeightUnit = ref('گرم')
|
||||
const isMeltedCategory = computed(() => isMeltedTradeGroup(props.form.group_type))
|
||||
|
||||
@@ -314,6 +326,11 @@ onMounted(async () => {
|
||||
const rows = await getConfiguration()
|
||||
const unitRow = Array.isArray(rows) ? rows.find((row) => row.key === 'unit') : null
|
||||
tradeWeightUnit.value = resolveTradeWeightUnit(unitRow?.value)
|
||||
|
||||
const storeRow = Array.isArray(rows) ? rows.find((row) => row.key === 'is_store') : null
|
||||
if (storeRow) {
|
||||
isStore.value = isSwitchOn(storeRow.value)
|
||||
}
|
||||
} catch {
|
||||
tradeWeightUnit.value = 'گرم'
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ import {
|
||||
getCustomerTable,
|
||||
setActiveTime
|
||||
} from '@/api/product'
|
||||
import { cols } from '@/pages/menuPages/products/base/hooks/productColumns'
|
||||
import { getProductColumns } from '@/pages/menuPages/products/base/hooks/productColumns'
|
||||
import ProductMobileCardList from '@/pages/menuPages/products/base/components/ProductMobileCardList.vue'
|
||||
import useBaseTable from '@core/components/BaseTable/hooks/useBaseTable'
|
||||
import type { TableInput } from '@core/type/baseTable'
|
||||
@@ -148,7 +148,7 @@ const customLocale = ref({
|
||||
})
|
||||
|
||||
const tblProps = ref<any>({
|
||||
columns: cols,
|
||||
columns: getProductColumns(),
|
||||
api: async (params: TableInput) => {
|
||||
const data = (await getCustomerTable(params)) as any
|
||||
startTime.value = dayjs(data?.auto_open_at, 'HH:mm:ss')
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
import { isStoreApp } from '@/utils/config'
|
||||
|
||||
export const cols: BaseTableColumn[] = [
|
||||
const inventoryColumn: BaseTableColumn = {
|
||||
title: 'موجودی',
|
||||
dataIndex: 'inventory',
|
||||
key: 'inventory',
|
||||
type: 'Number'
|
||||
}
|
||||
|
||||
export function getProductColumns(): BaseTableColumn[] {
|
||||
return [
|
||||
{
|
||||
title: 'ردیف',
|
||||
dataIndex: 'id',
|
||||
@@ -78,6 +87,7 @@ export const cols: BaseTableColumn[] = [
|
||||
key: 'cash_fee_sell',
|
||||
type: 'Number'
|
||||
},
|
||||
...(isStoreApp() ? [inventoryColumn] : []),
|
||||
{
|
||||
title: 'وضعیت محصول',
|
||||
dataIndex: 'active',
|
||||
@@ -102,4 +112,8 @@ export const cols: BaseTableColumn[] = [
|
||||
slot: 'action',
|
||||
filterable: false
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
/** @deprecated از getProductColumns استفاده کنید */
|
||||
export const cols = getProductColumns()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<CustomersStoreView v-if="isStoreApp()" />
|
||||
<div v-else class="h-full min-h-0 min-w-0 overflow-hidden">
|
||||
<div class="h-full min-h-0 min-w-0 overflow-hidden">
|
||||
<tbl ref="table" class="h-full min-h-0 w-full" @edit="edit" @add="add" />
|
||||
<BasicActionSheet
|
||||
v-model:visible="addUserVisible"
|
||||
@@ -34,6 +33,7 @@
|
||||
:productIndexImage="ProductIndexImage"
|
||||
:editId="editId"
|
||||
:meltedPriceOption="meltedPriceOption"
|
||||
:isStore="isStoreApp()"
|
||||
@update:methodOption="methodOption = $event"
|
||||
@update:weightOption="weightOption = $event"
|
||||
@update:meltedPriceOption="meltedPriceOption = $event"
|
||||
@@ -57,7 +57,6 @@ import { cloneDeep } from 'lodash'
|
||||
import dayjs from 'dayjs'
|
||||
import customParseFormat from 'dayjs/plugin/customParseFormat'
|
||||
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||
import CustomersStoreView from '@/pages/menuPages/customers/base/index.vue'
|
||||
import { isStoreApp } from '@/utils/config'
|
||||
import { createProduct, getCustomerById, updateCustomer } from '@/api/product'
|
||||
import { fetchProductImageUrl } from '@/api/file'
|
||||
@@ -326,6 +325,7 @@ function resetData() {
|
||||
order_limit_enabled: false,
|
||||
show_in_assets: false,
|
||||
use_last_price_if_zero: false,
|
||||
inventory: 0,
|
||||
min_order_cash: undefined,
|
||||
max_order_cash: undefined,
|
||||
auto_open_at: dayjs('00:00:00', 'HH:mm:ss'),
|
||||
@@ -375,6 +375,10 @@ async function ok() {
|
||||
}
|
||||
if (weightOption.value === '2') payload.amount = 1
|
||||
|
||||
if (isStoreApp() && !isMeltedTradeGroup(payload.group_type)) {
|
||||
payload.inventory = Math.max(0, Number(payload.inventory ?? 0))
|
||||
}
|
||||
|
||||
payload.auto_open_at = payload.auto_open_at
|
||||
? dayjs(payload.auto_open_at).format('HH:mm:ss')
|
||||
: '00:00:00'
|
||||
|
||||
+29
-8
@@ -1,6 +1,5 @@
|
||||
|
||||
export function getConfigApp(key: string) {
|
||||
const config = window.__APP_CONFIG__ ? window.__APP_CONFIG__.user:{}
|
||||
const config = window.__APP_CONFIG__ ? window.__APP_CONFIG__.user : {}
|
||||
|
||||
if (config) {
|
||||
return config[key]
|
||||
@@ -8,11 +7,33 @@ export function getConfigApp(key: string) {
|
||||
return null
|
||||
}
|
||||
|
||||
let storeModeFromSettings: boolean | null = null
|
||||
|
||||
function isSwitchOn(value: string | undefined | null): boolean {
|
||||
const v = (value ?? '').trim().toLowerCase()
|
||||
return v === 'true' || v === '1' || v === 'yes'
|
||||
}
|
||||
|
||||
export function setStoreModeFromSettings(value: boolean): void {
|
||||
storeModeFromSettings = value
|
||||
}
|
||||
|
||||
/** is_store فقط از API تنظیمات (get_settings) خوانده میشود — نه از get_user */
|
||||
export async function initStoreModeFromSettings(): Promise<boolean> {
|
||||
if (storeModeFromSettings !== null) return storeModeFromSettings
|
||||
|
||||
try {
|
||||
const { getConfiguration } = await import('@/api/configuration')
|
||||
const rows = await getConfiguration()
|
||||
const row = Array.isArray(rows) ? rows.find((item) => item.key === 'is_store') : null
|
||||
storeModeFromSettings = row ? isSwitchOn(row.value) : false
|
||||
} catch {
|
||||
storeModeFromSettings = false
|
||||
}
|
||||
|
||||
return storeModeFromSettings
|
||||
}
|
||||
|
||||
export function isStoreApp(): boolean {
|
||||
const value = getConfigApp('is_store')
|
||||
if (value === true || value === 1) return true
|
||||
if (typeof value === 'string') {
|
||||
return ['true', '1', 'yes'].includes(value.trim().toLowerCase())
|
||||
}
|
||||
return false
|
||||
return storeModeFromSettings === true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user