import { createApi } from "@reduxjs/toolkit/query/react"; import BASE_URL, { ContentTypes, IS_OFFICIAL_DEMO, PAYMENT_URL_PREFIX } from "../config"; import { updateInfo } from "../slices/server"; import baseQuery from "./base.query"; import { RootState } from "../store"; import { User } from "../../types/user"; import { FirebaseConfig, GoogleAuthConfig, LoginConfig, Server, TestEmailDTO, CreateAdminDTO, SMTPConfig, AgoraConfig, GithubAuthConfig, LicenseResponse, RenewLicense, RenewLicenseResponse, AgoraTokenResponse, AgoraVoicingListResponse } from "../../types/server"; import { Channel } from "../../types/channel"; import { ContentTypeKey } from "../../types/message"; import { upsertVoiceList } from "../slices/voice"; const defaultExpireDuration = 2 * 24 * 60 * 60; export const serverApi = createApi({ reducerPath: "serverApi", baseQuery, endpoints: (builder) => ({ getServer: builder.query({ query: () => ({ url: `admin/system/organization` }), async onQueryStarted(data, { dispatch, queryFulfilled }) { try { const { data: server } = await queryFulfilled; const logo = `${BASE_URL}/resource/organization/logo?t=${+new Date()}`; dispatch(updateInfo({ ...server, logo })); } catch { console.error("get server info error"); } } }), getThirdPartySecret: builder.query({ query: () => ({ url: `/admin/system/third_party_secret`, responseHandler: "text" }), keepUnusedDataFor: 0 }), updateThirdPartySecret: builder.mutation({ query: () => ({ url: `/admin/system/third_party_secret`, method: "POST", responseHandler: "text" }) }), getServerVersion: builder.query({ query: () => ({ headers: { accept: "text/plain" }, url: `/admin/system/version`, responseHandler: "text" }) }), getFirebaseConfig: builder.query({ query: () => ({ url: `admin/fcm/config` }) }), getGoogleAuthConfig: builder.query({ query: () => ({ url: `admin/google_auth/config` }) }), updateGoogleAuthConfig: builder.mutation({ query: (data) => ({ url: `admin/google_auth/config`, method: "POST", body: data }) }), getGithubAuthConfig: builder.query({ query: () => ({ url: `admin/github_auth/config` }) }), updateGithubAuthConfig: builder.mutation({ query: (data) => ({ url: `admin/github_auth/config`, method: "POST", body: data }) }), sendTestEmail: builder.mutation({ query: (data) => ({ url: `/admin/system/send_mail`, method: "POST", body: data }) }), updateFirebaseConfig: builder.mutation({ query: (data) => ({ url: `admin/fcm/config`, method: "POST", body: data }) }), getAgoraConfig: builder.query({ query: () => ({ url: `admin/agora/config` }) }), updateAgoraConfig: builder.mutation({ query: (data) => ({ url: `admin/agora/config`, method: "POST", body: data }) }), getAgoraToken: builder.query({ query: (id) => ({ url: `group/${id}/agora_token`, }) }), // tmp API getAgoraVoicingList: builder.query({ query: ({ appid, key, secret }) => ({ headers: { Authorization: `Basic ${btoa(`${key}:${secret}`)}` }, url: `https://api.agora.io/dev/v1/channel/${appid}`, }), async onQueryStarted(data, { dispatch, queryFulfilled }) { try { const { data: resp } = await queryFulfilled; const { success } = resp; if (success) { const arr = resp.data.channels.map(data => { const [id] = data.channel_name.split(":").slice(-1); const count = data.user_count; return { id: +id, context: "channel" as const, memberCount: count }; }); dispatch(upsertVoiceList(arr)); } } catch { console.error("get voice list error"); } } }), getSMTPConfig: builder.query({ query: () => ({ url: `admin/smtp/config` }) }), getSMTPStatus: builder.query({ query: () => ({ url: `/admin/smtp/enabled` }) }), updateSMTPConfig: builder.mutation({ query: (data) => ({ url: `admin/smtp/config`, method: "POST", body: data }) }), getLoginConfig: builder.query({ query: () => ({ url: `admin/login/config` }) }), updateLoginConfig: builder.mutation>({ query: (data) => ({ url: `admin/login/config`, method: "POST", body: data }) }), updateLogo: builder.mutation({ query: (data) => ({ headers: { "content-type": "image/png" }, url: `admin/system/organization/logo`, method: "POST", body: data }), async onQueryStarted(data, { dispatch, queryFulfilled }) { try { await queryFulfilled; dispatch( updateInfo({ logo: `${BASE_URL}/resource/organization/logo?t=${+new Date()}` }) ); } catch { console.error("update server logo error"); } } }), createInviteLink: builder.query({ query: (expired_in = defaultExpireDuration) => ({ headers: { "content-type": "text/plain", accept: "text/plain" }, url: `/admin/system/create_invite_link?expired_in=${expired_in}`, responseHandler: "text" }), transformResponse: (link: string) => { // 确保http开头 const _link = link.startsWith("http") ? link : `http://${link}`; // 替换掉域名 const invite = new URL(_link); return `${location.origin}${invite.pathname}${invite.search}${invite.hash}`; } }), updateServer: builder.mutation({ query: (data) => ({ url: "admin/system/organization", method: "POST", body: data }), async onQueryStarted(data, { dispatch, queryFulfilled, getState }) { const rootStore = getState() as RootState; const { name: prevName, description: prevDesc } = rootStore.server; dispatch(updateInfo(data)); try { await queryFulfilled; } catch { dispatch(updateInfo({ name: prevName, description: prevDesc })); } } }), createAdmin: builder.mutation({ query: (data) => ({ url: "/admin/system/create_admin", method: "POST", body: data }) }), getFrontendUrl: builder.query({ query: () => ({ url: `/admin/system/frontend_url`, responseHandler: "text" }) }), updateFrontendUrl: builder.mutation({ query: (url) => ({ url: `/admin/system/update_frontend_url`, method: "POST", headers: { "content-type": 'text/plain', }, body: url }) }), getLicense: builder.query({ query: () => ({ url: `/license` }), async onQueryStarted(data, { dispatch, queryFulfilled, getState }) { // vocechat官方demo 则忽略 if (IS_OFFICIAL_DEMO) return; const rootStore = getState() as RootState; const { upgraded: prevValue } = rootStore.server; try { const { data: { user_limit } } = await queryFulfilled; const currValue = user_limit > 20; if (prevValue !== currValue) { dispatch(updateInfo({ upgraded: currValue })); } } catch { console.error("update license upgraded status failed "); } } }), getLicensePaymentUrl: builder.mutation({ query: (data) => ({ url: `${PAYMENT_URL_PREFIX}/vocechat/payment/create`, method: "POST", body: data }) }), getGeneratedLicense: builder.query<{ license: string }, string>({ query: (session_id) => ({ url: `${PAYMENT_URL_PREFIX}/vocechat/licenses/${session_id}` }) }), checkLicense: builder.mutation({ query: (license) => ({ url: "/license/check", method: "POST", body: { license } }) }), upsertLicense: builder.mutation({ query: (license) => ({ url: "/license", method: "PUT", body: { license } }) }), getBotRelatedChannels: builder.query({ query: ({ api_key, public_only = false }) => ({ url: public_only ? `/bot?public_only=${public_only}` : `/bot`, headers: { "x-api-key": api_key }, }) }), sendMessageByBot: builder.mutation({ query: ({ uid, cid, api_key, type = "text", properties, content }) => ({ headers: { "x-api-key": api_key, "content-type": ContentTypes[type], "X-Properties": properties ? btoa(unescape(encodeURIComponent(JSON.stringify(properties)))) : "" }, url: cid ? `/bot/send_to_group/${cid}` : `/bot/send_to_user/${uid}`, method: "POST", body: content }) }), }) }); export const { useGetServerVersionQuery, useGetGithubAuthConfigQuery, useUpdateGithubAuthConfigMutation, useGetGoogleAuthConfigQuery, useUpdateGoogleAuthConfigMutation, useGetSMTPStatusQuery, useSendTestEmailMutation, useUpdateFirebaseConfigMutation, useLazyGetFirebaseConfigQuery, useLazyGetAgoraConfigQuery, useLazyGetSMTPConfigQuery, useLazyGetLoginConfigQuery, useGetLoginConfigQuery, useUpdateLoginConfigMutation, useGetSMTPConfigQuery, useUpdateSMTPConfigMutation, useUpdateAgoraConfigMutation, useGetServerQuery, useLazyGetServerQuery, useUpdateServerMutation, useUpdateLogoMutation, useCreateInviteLinkQuery, useLazyCreateInviteLinkQuery, useGetThirdPartySecretQuery, useUpdateThirdPartySecretMutation, useCreateAdminMutation, useUpsertLicenseMutation, useCheckLicenseMutation, useGetLicenseQuery, useGetLicensePaymentUrlMutation, useLazyGetGeneratedLicenseQuery, useLazyGetBotRelatedChannelsQuery, useSendMessageByBotMutation, useUpdateFrontendUrlMutation, useGetFrontendUrlQuery, useLazyGetAgoraTokenQuery, useGetAgoraConfigQuery, useGetAgoraVoicingListQuery } = serverApi;