Subdomain li Tenant sistemi ve Profil resim problemi
This commit is contained in:
parent
4252cbf0f5
commit
10493bd067
12 changed files with 108 additions and 74 deletions
|
|
@ -37,6 +37,19 @@ public class PlatformTenantAppService : TenantAppService, IPlatformTenantAppServ
|
||||||
LocalizationResource = typeof(PlatformResource);
|
LocalizationResource = typeof(PlatformResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Task<TenantDto> GetAsync(Guid id)
|
||||||
|
{
|
||||||
|
return base.GetAsync(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
[AllowAnonymous]
|
||||||
|
public async Task<TenantDto> GetByNameAsync(string name)
|
||||||
|
{
|
||||||
|
return ObjectMapper.Map<Tenant, TenantDto>(
|
||||||
|
await TenantRepository.FindByNameAsync(name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public override Task<PagedResultDto<TenantDto>> GetListAsync(GetTenantsInput input) => base.GetListAsync(input);
|
public override Task<PagedResultDto<TenantDto>> GetListAsync(GetTenantsInput input) => base.GetListAsync(input);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6754,7 +6754,7 @@
|
||||||
"ParentName": null,
|
"ParentName": null,
|
||||||
"DisplayName": "App.ForumManagement",
|
"DisplayName": "App.ForumManagement",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 3
|
"MultiTenancySide": 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"GroupName": "App.Setting",
|
"GroupName": "App.Setting",
|
||||||
|
|
@ -7796,14 +7796,6 @@
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 2
|
"MultiTenancySide": 2
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"GroupName": "App.ForumManagement",
|
|
||||||
"Name": "App.ForumManagement.Publish",
|
|
||||||
"ParentName": "App.ForumManagement",
|
|
||||||
"DisplayName": "Publish",
|
|
||||||
"IsEnabled": true,
|
|
||||||
"MultiTenancySide": 3
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"GroupName": "App.ForumManagement",
|
"GroupName": "App.ForumManagement",
|
||||||
"Name": "App.ForumManagement.Create",
|
"Name": "App.ForumManagement.Create",
|
||||||
|
|
@ -7835,6 +7827,14 @@
|
||||||
"DisplayName": "Update",
|
"DisplayName": "Update",
|
||||||
"IsEnabled": true,
|
"IsEnabled": true,
|
||||||
"MultiTenancySide": 2
|
"MultiTenancySide": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"GroupName": "App.ForumManagement",
|
||||||
|
"Name": "App.ForumManagement.Publish",
|
||||||
|
"ParentName": null,
|
||||||
|
"DisplayName": "Publish",
|
||||||
|
"IsEnabled": true,
|
||||||
|
"MultiTenancySide": 3
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Sectors": [
|
"Sectors": [
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ define(['./workbox-54d0af47'], (function (workbox) { 'use strict';
|
||||||
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
"revision": "3ca0b8505b4bec776b69afdba2768812"
|
||||||
}, {
|
}, {
|
||||||
"url": "index.html",
|
"url": "index.html",
|
||||||
"revision": "0.m83v8d1s4bo"
|
"revision": "0.3kkdvt11rc8"
|
||||||
}], {});
|
}], {});
|
||||||
workbox.cleanupOutdatedCaches();
|
workbox.cleanupOutdatedCaches();
|
||||||
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,12 @@ export const getTenants = (skipCount = 0, maxResultCount = 10) =>
|
||||||
url: `/api/app/platform-tenant?skipCount=${skipCount}&maxResultCount=${maxResultCount}`,
|
url: `/api/app/platform-tenant?skipCount=${skipCount}&maxResultCount=${maxResultCount}`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const getTenantByName = (name: string) =>
|
||||||
|
apiService.fetchData<TenantDto>({
|
||||||
|
method: 'GET',
|
||||||
|
url: `/api/app/platform-tenant/by-name?name=${encodeURIComponent(name)}`,
|
||||||
|
})
|
||||||
|
|
||||||
export const getTenantById = (id: string) =>
|
export const getTenantById = (id: string) =>
|
||||||
apiService.fetchData<TenantDto>({
|
apiService.fetchData<TenantDto>({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,9 @@ authApiService.interceptors.response.use(
|
||||||
)
|
)
|
||||||
|
|
||||||
authApiService.interceptors.request.use(async (config) => {
|
authApiService.interceptors.request.use(async (config) => {
|
||||||
const { tenantId } = store.getState().auth
|
const { currentTenantName } = store.getState().locale
|
||||||
if (tenantId) {
|
if (currentTenantName) {
|
||||||
config.headers['__tenant'] = tenantId
|
config.headers['__tenant'] = currentTenantName
|
||||||
} else {
|
} else {
|
||||||
config.headers.delete('__tenant')
|
config.headers.delete('__tenant')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ class ForumService {
|
||||||
const response = await apiService.fetchData<ForumCategory>({
|
const response = await apiService.fetchData<ForumCategory>({
|
||||||
url: '/api/app/forum/category',
|
url: '/api/app/forum/category',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data,
|
data: {...data},
|
||||||
})
|
})
|
||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +181,7 @@ class ForumService {
|
||||||
const response = await apiService.fetchData<ForumTopic>({
|
const response = await apiService.fetchData<ForumTopic>({
|
||||||
url: '/api/app/forum/topic',
|
url: '/api/app/forum/topic',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data,
|
data: {...data},
|
||||||
})
|
})
|
||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
|
|
@ -288,7 +288,7 @@ class ForumService {
|
||||||
const response = await apiService.fetchData<ForumPost>({
|
const response = await apiService.fetchData<ForumPost>({
|
||||||
url: '/api/app/forum/post',
|
url: '/api/app/forum/post',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data,
|
data: {...data},
|
||||||
})
|
})
|
||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,9 +34,9 @@ platformApiService.interceptors.request.use(async (config) => {
|
||||||
config.headers['Accept-Language'] = cultureName
|
config.headers['Accept-Language'] = cultureName
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tenantId } = state.auth
|
const { currentTenantName } = state.locale
|
||||||
if (tenantId) {
|
if (currentTenantName) {
|
||||||
config.headers['__tenant'] = tenantId
|
config.headers['__tenant'] = currentTenantName
|
||||||
} else {
|
} else {
|
||||||
config.headers.delete('__tenant')
|
config.headers.delete('__tenant')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,10 @@ export interface AuthStoreModel {
|
||||||
name: string
|
name: string
|
||||||
avatar?: string
|
avatar?: string
|
||||||
}
|
}
|
||||||
tenantId?: string
|
tenant?: {
|
||||||
|
tenantId?: string
|
||||||
|
tenantName?: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AuthStoreActions {
|
export interface AuthStoreActions {
|
||||||
|
|
@ -36,7 +39,9 @@ export interface AuthStoreActions {
|
||||||
user: {
|
user: {
|
||||||
setUser: Action<AuthStoreModel['user'], AuthStoreModel['user']>
|
setUser: Action<AuthStoreModel['user'], AuthStoreModel['user']>
|
||||||
}
|
}
|
||||||
setTenantId: Action<AuthStoreModel, string | undefined>
|
tenant: {
|
||||||
|
setTenant: Action<NonNullable<AuthStoreModel['tenant']>, AuthStoreModel['tenant']>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AuthModel = AuthStoreModel & AuthStoreActions
|
export type AuthModel = AuthStoreModel & AuthStoreActions
|
||||||
|
|
@ -52,7 +57,10 @@ export const initialState: AuthStoreModel = {
|
||||||
name: '',
|
name: '',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
},
|
},
|
||||||
tenantId: undefined,
|
tenant: {
|
||||||
|
tenantId: '',
|
||||||
|
tenantName: '',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const authModel: AuthModel = {
|
export const authModel: AuthModel = {
|
||||||
|
|
@ -70,9 +78,10 @@ export const authModel: AuthModel = {
|
||||||
state.user.userName = payload.user.userName
|
state.user.userName = payload.user.userName
|
||||||
state.user.authority = payload.user.authority
|
state.user.authority = payload.user.authority
|
||||||
state.user.email = payload.user.email
|
state.user.email = payload.user.email
|
||||||
state.user.avatar = AVATAR_URL(payload.user.id, state.tenantId)+ `?${dayjs().unix()}`
|
state.user.avatar = AVATAR_URL(payload.user.id, state.tenant?.tenantId) + `?${dayjs().unix()}`
|
||||||
}),
|
}),
|
||||||
signOut: action((state) => ({ ...initialState, tenantId: state.tenantId })),
|
signOut: action(() => ({ ...initialState })),
|
||||||
|
// signOut: action((state) => ({ ...initialState, tenantId: state.tenant?.tenantId })),
|
||||||
onSignInAndOut: thunkOn(
|
onSignInAndOut: thunkOn(
|
||||||
(actions, storeActions) => [storeActions.auth.signIn, storeActions.auth.signOut],
|
(actions, storeActions) => [storeActions.auth.signIn, storeActions.auth.signOut],
|
||||||
async (actions, payload, { getStoreActions }) => {
|
async (actions, payload, { getStoreActions }) => {
|
||||||
|
|
@ -94,8 +103,11 @@ export const authModel: AuthModel = {
|
||||||
state.avatar = payload.avatar
|
state.avatar = payload.avatar
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
tenantId: initialState.tenantId,
|
tenant: {
|
||||||
setTenantId: action((state, payload) => {
|
...initialState.tenant,
|
||||||
state.tenantId = payload
|
setTenant: action((state, payload) => {
|
||||||
}),
|
state.tenantId = payload?.tenantId
|
||||||
|
state.tenantName = payload?.tenantName
|
||||||
|
}),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,19 +6,22 @@ import { Injections, StoreModel } from '.'
|
||||||
export interface LocaleStoreModel {
|
export interface LocaleStoreModel {
|
||||||
currentLang: string
|
currentLang: string
|
||||||
currentUiVersion: string | undefined
|
currentUiVersion: string | undefined
|
||||||
|
currentTenantName?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LocaleStoreActions {
|
export interface LocaleStoreActions {
|
||||||
setLang: Action<LocaleStoreModel, string>
|
setLang: Action<LocaleStoreModel, string>
|
||||||
onSetLang: ThunkOn<LocaleModel, Injections, StoreModel>
|
onSetLang: ThunkOn<LocaleModel, Injections, StoreModel>
|
||||||
setUiVersion: Action<LocaleStoreModel, string | undefined>
|
setUiVersion: Action<LocaleStoreModel, string | undefined>
|
||||||
|
setTenantName: Action<LocaleStoreModel, string | undefined>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LocaleModel = LocaleStoreModel & LocaleStoreActions
|
export type LocaleModel = LocaleStoreModel & LocaleStoreActions
|
||||||
|
|
||||||
const initialState: LocaleStoreModel = {
|
const initialState: LocaleStoreModel = {
|
||||||
currentLang: appConfig.locale,
|
currentLang: appConfig.locale,
|
||||||
currentUiVersion: appConfig.uiVersion
|
currentUiVersion: appConfig.uiVersion,
|
||||||
|
currentTenantName: undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export const localeModel: LocaleModel = {
|
export const localeModel: LocaleModel = {
|
||||||
|
|
@ -36,4 +39,7 @@ export const localeModel: LocaleModel = {
|
||||||
setUiVersion: action((state, payload) => {
|
setUiVersion: action((state, payload) => {
|
||||||
state.currentUiVersion = payload
|
state.currentUiVersion = payload
|
||||||
}),
|
}),
|
||||||
|
setTenantName: action((state, payload) => {
|
||||||
|
state.currentTenantName = payload
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { FormContainer, FormItem } from '@/components/ui/Form'
|
||||||
import Input from '@/components/ui/Input'
|
import Input from '@/components/ui/Input'
|
||||||
import PlatformLoginResultType from '@/constants/login.result.enum'
|
import PlatformLoginResultType from '@/constants/login.result.enum'
|
||||||
import { ROUTES_ENUM } from '@/constants/route.constant'
|
import { ROUTES_ENUM } from '@/constants/route.constant'
|
||||||
|
import { getTenantByName } from '@/proxy/admin/tenant/tenant.service'
|
||||||
import { useStoreActions, useStoreState } from '@/store'
|
import { useStoreActions, useStoreState } from '@/store'
|
||||||
import useAuth from '@/utils/hooks/useAuth'
|
import useAuth from '@/utils/hooks/useAuth'
|
||||||
import { useLocalization } from '@/utils/hooks/useLocalization'
|
import { useLocalization } from '@/utils/hooks/useLocalization'
|
||||||
|
|
@ -43,7 +44,10 @@ const validationSchema = Yup.object().shape({
|
||||||
const Login = () => {
|
const Login = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const isMultiTenant = useStoreState((a) => a.abpConfig.config?.multiTenancy.isEnabled)
|
const isMultiTenant = useStoreState((a) => a.abpConfig.config?.multiTenancy.isEnabled)
|
||||||
const { setTenantId } = useStoreActions((a) => a.auth)
|
const { setTenant } = useStoreActions((a) => a.auth.tenant)
|
||||||
|
|
||||||
|
const tenantName = useStoreState((state) => state.locale.currentTenantName)
|
||||||
|
const { setTenantName } = useStoreActions((actions) => actions.locale)
|
||||||
|
|
||||||
const [message, setMessage] = useState('')
|
const [message, setMessage] = useState('')
|
||||||
const [error, setError] = useTimeOutMessage(300000)
|
const [error, setError] = useTimeOutMessage(300000)
|
||||||
|
|
@ -164,13 +168,36 @@ const Login = () => {
|
||||||
setShowCaptcha(false)
|
setShowCaptcha(false)
|
||||||
setError('')
|
setError('')
|
||||||
setMessage('')
|
setMessage('')
|
||||||
|
|
||||||
|
//Tenant belirlenmişse
|
||||||
|
fetchDataByName(tenantName || '')
|
||||||
}
|
}
|
||||||
|
|
||||||
setSubmitting(false)
|
setSubmitting(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fetchDataByName = async (name: string) => {
|
||||||
|
if (name) {
|
||||||
|
const response = await getTenantByName(name)
|
||||||
|
|
||||||
|
if (response.data) {
|
||||||
|
setTenant({ tenantId: response.data.id, tenantName: response.data.name })
|
||||||
|
} else {
|
||||||
|
setTenant(undefined)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setTenant(undefined)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const subDomainName = getSubdomain()
|
const subDomainName = getSubdomain()
|
||||||
const tenantId = useStoreState((a) => a.auth.tenantId) ?? subDomainName
|
useEffect(() => {
|
||||||
|
if (subDomainName) {
|
||||||
|
setTenantName(subDomainName)
|
||||||
|
fetchDataByName(subDomainName)
|
||||||
|
}
|
||||||
|
}, [subDomainName])
|
||||||
|
|
||||||
const tenantStyle: React.CSSProperties | undefined =
|
const tenantStyle: React.CSSProperties | undefined =
|
||||||
subDomainName && subDomainName !== defaultSubDomain
|
subDomainName && subDomainName !== defaultSubDomain
|
||||||
? {
|
? {
|
||||||
|
|
@ -184,23 +211,6 @@ const Login = () => {
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
|
|
||||||
const { config } = useStoreState((state) => state.abpConfig)
|
|
||||||
const { setLang } = useStoreActions((actions) => actions.locale)
|
|
||||||
const currentCulture = config?.localization?.currentCulture?.cultureName
|
|
||||||
|
|
||||||
const languageList = config?.localization.languages
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isMultiTenant) return
|
|
||||||
|
|
||||||
const subDomainName = getSubdomain()
|
|
||||||
if (subDomainName?.toUpperCase() === defaultSubDomain) {
|
|
||||||
setTenantId('')
|
|
||||||
} else {
|
|
||||||
setTenantId(subDomainName || '')
|
|
||||||
}
|
|
||||||
}, [isMultiTenant])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.div
|
<motion.div
|
||||||
initial={{ opacity: 0, x: 100 }}
|
initial={{ opacity: 0, x: 100 }}
|
||||||
|
|
@ -220,8 +230,8 @@ const Login = () => {
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<Input
|
<Input
|
||||||
placeholder={translate('::Sirket')}
|
placeholder={translate('::Sirket')}
|
||||||
value={tenantId || ''}
|
value={tenantName}
|
||||||
onChange={(e) => setTenantId(e.target.value)}
|
onChange={(e) => setTenantName(e.target.value)}
|
||||||
style={tenantStyle}
|
style={tenantStyle}
|
||||||
aria-hidden={subDomainName && subDomainName !== defaultSubDomain ? 'true' : 'false'}
|
aria-hidden={subDomainName && subDomainName !== defaultSubDomain ? 'true' : 'false'}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ const Profile = () => {
|
||||||
setUser({
|
setUser({
|
||||||
...auth.user,
|
...auth.user,
|
||||||
name: `${resp.data.name} ${resp.data.surname}`.trim(),
|
name: `${resp.data.name} ${resp.data.surname}`.trim(),
|
||||||
avatar: AVATAR_URL(auth.user.id, auth.tenantId) + `?${dayjs().unix()}`,
|
avatar: AVATAR_URL(auth.user.id, auth.tenant.tenantId) + `?${dayjs().unix()}`,
|
||||||
})
|
})
|
||||||
|
|
||||||
toast.push(<Notification title={'Profil güncellendi'} type="success" />, {
|
toast.push(<Notification title={'Profil güncellendi'} type="success" />, {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum'
|
import { ForumCategory, ForumPost, ForumTopic } from '@/proxy/forum/forum'
|
||||||
import { forumService } from '@/services/forumService'
|
import {
|
||||||
|
CreateCategoryRequest,
|
||||||
|
CreatePostRequest,
|
||||||
|
CreateTopicRequest,
|
||||||
|
forumService,
|
||||||
|
} from '@/services/forumService'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
|
|
||||||
export function useForumData() {
|
export function useForumData() {
|
||||||
|
|
@ -56,15 +61,7 @@ export function useForumData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Category operations
|
// Category operations
|
||||||
const createCategory = async (categoryData: {
|
const createCategory = async (categoryData: CreateCategoryRequest) => {
|
||||||
name: string
|
|
||||||
slug: string
|
|
||||||
description: string
|
|
||||||
icon: string
|
|
||||||
displayOrder: number
|
|
||||||
isActive: boolean
|
|
||||||
isLocked: boolean
|
|
||||||
}) => {
|
|
||||||
try {
|
try {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
const newCategory = await forumService.createCategory(categoryData)
|
const newCategory = await forumService.createCategory(categoryData)
|
||||||
|
|
@ -99,7 +96,7 @@ export function useForumData() {
|
||||||
await loadCategories() // refresh after update
|
await loadCategories() // refresh after update
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateCategoryActiveState = async (id: string) => {
|
const updateCategoryActiveState = async (id: string) => {
|
||||||
await forumService.updateCategoryActiveState(id)
|
await forumService.updateCategoryActiveState(id)
|
||||||
await loadCategories() // refresh after update
|
await loadCategories() // refresh after update
|
||||||
}
|
}
|
||||||
|
|
@ -124,13 +121,7 @@ export function useForumData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Topic operations
|
// Topic operations
|
||||||
const createTopic = async (topicData: {
|
const createTopic = async (topicData: CreateTopicRequest) => {
|
||||||
title: string
|
|
||||||
content: string
|
|
||||||
categoryId: string
|
|
||||||
isPinned?: boolean
|
|
||||||
isLocked?: boolean
|
|
||||||
}) => {
|
|
||||||
try {
|
try {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
const newTopic = await forumService.createTopic(topicData)
|
const newTopic = await forumService.createTopic(topicData)
|
||||||
|
|
@ -273,11 +264,7 @@ export function useForumData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post operations
|
// Post operations
|
||||||
const createPost = async (postData: {
|
const createPost = async (postData: CreatePostRequest) => {
|
||||||
topicId: string
|
|
||||||
content: string
|
|
||||||
parentPostId?: string
|
|
||||||
}) => {
|
|
||||||
try {
|
try {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
const newPost = await forumService.createPost(postData)
|
const newPost = await forumService.createPost(postData)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue