diff --git a/code/allapp/allapp-go/api/handler/space/index.go b/code/allapp/allapp-go/api/handler/space/index.go
index 5c6b9f30..8cbcd1fd 100644
--- a/code/allapp/allapp-go/api/handler/space/index.go
+++ b/code/allapp/allapp-go/api/handler/space/index.go
@@ -183,6 +183,38 @@ func DissolveSpace(c fiber.Ctx) error {
return responsex.OK(c, "空间已成功解散")
}
+// ExitSpace 退出空间
+func ExitSpace(c fiber.Ctx) error {
+ dto := new(types.ExitSpaceDTO)
+ if err := requestx.BindAndValidate(c, dto); err != nil {
+ return err
+ }
+
+ userId, err := middleware.GetUserID(c)
+ if err != nil {
+ return err
+ }
+
+ spaceId := dto.SpaceId
+
+ _, err = db.Queries.GetSpaceById(c.Context(), spaceId)
+ if err != nil {
+ if errorx.IsNotFound(err) {
+ return responsex.Error(c, "空间不存在或已解散")
+ }
+ return err
+ }
+
+ if err := db.Queries.UpdateSpaceMemberExit(c.Context(), repo.UpdateSpaceMemberExitParams{
+ SpaceID: spaceId,
+ UserID: userId,
+ }); err != nil {
+ return err
+ }
+
+ return responsex.OK(c, "空间已成功退出")
+}
+
// UpdateMemberName 更新群成员名称
func UpdateMemberName(c fiber.Ctx) error {
dto := new(types.UpdateMemberNameDTO)
@@ -257,6 +289,7 @@ func UpdateSpaceDefault(c fiber.Ctx) error {
return responsex.OK(c, "更新成功")
}
+// UpdateSpaceName 更新空间名称
func UpdateSpaceName(c fiber.Ctx) error {
dto := new(types.UpdateSpaceNameDTO)
if err := requestx.BindAndValidate(c, dto); err != nil {
@@ -295,6 +328,7 @@ func UpdateSpaceName(c fiber.Ctx) error {
return responsex.OK(c, "更新成功")
}
+// GetSpaceSettings 获取空间配置信息
func GetSpaceSettings(c fiber.Ctx) error {
dto := new(types.GetSpaceSettingDTO)
if err := requestx.BindAndValidate(c, dto); err != nil {
@@ -329,6 +363,7 @@ func GetSpaceSettings(c fiber.Ctx) error {
vo.MemberCount = row.MemberCount
vo.OwnerId = row.OwnerID
vo.SortNumber = row.SortNumber
+ vo.InviteCode = row.InviteCode
return responsex.OK(c, vo)
}
diff --git a/code/allapp/allapp-go/api/router/router.go b/code/allapp/allapp-go/api/router/router.go
index da2c6d69..61b7e9b0 100644
--- a/code/allapp/allapp-go/api/router/router.go
+++ b/code/allapp/allapp-go/api/router/router.go
@@ -30,6 +30,7 @@ func SetupRouters(app *fiber.App) {
spaceRouter.Post("/member/default", space.UpdateSpaceDefault)
spaceRouter.Post("/member/name", space.UpdateMemberName)
spaceRouter.Post("/member/sortNumber", space.UpdateSpaceSortNumber)
+ spaceRouter.Post("/member/exit", space.ExitSpace)
// authGroup.Get("/user/profile", user.GetProfile)
// spaceGroup.Get("/space/info", space.GetInfo)
diff --git a/code/allapp/allapp-go/api/types/space.go b/code/allapp/allapp-go/api/types/space.go
index 666f24b6..fdc07d23 100644
--- a/code/allapp/allapp-go/api/types/space.go
+++ b/code/allapp/allapp-go/api/types/space.go
@@ -21,6 +21,7 @@ type UserSpace struct {
IsDefault int16 `json:"is_default"`
MemberName string `json:"member_name"`
SortNumber int32 `json:"sort_number"`
+ InviteCode string `json:"invite_code"`
}
type ListSpacesVO struct {
@@ -31,6 +32,10 @@ type DissolveSpaceDTO struct {
SpaceId int64 `json:"space_id" validate:"required"`
}
+type ExitSpaceDTO struct {
+ SpaceId int64 `json:"space_id" validate:"required"`
+}
+
type UpdateMemberNameDTO struct {
SpaceId int64 `json:"space_id" validate:"required"`
MemberName string `json:"member_name" validate:"required"`
diff --git a/code/allapp/allapp-go/db/queries/space.sql b/code/allapp/allapp-go/db/queries/space.sql
index 08466b49..0ae0731d 100644
--- a/code/allapp/allapp-go/db/queries/space.sql
+++ b/code/allapp/allapp-go/db/queries/space.sql
@@ -39,7 +39,7 @@ FROM space s
GROUP BY space_id
) mc
ON s.id = mc.space_id
-WHERE sm.user_id = $1
+WHERE sm.user_id = $1 AND s.status != 2 AND sm.status != 2
ORDER BY sm.is_default DESC, sm.sort_number ASC;
-- name: GetSpaceByUserIdAndSpaceId :one
@@ -51,7 +51,8 @@ SELECT
COALESCE(mc.member_count, 0) AS member_count,
sm.is_default,
sm.member_name,
- sm.sort_number
+ sm.sort_number,
+ s.invite_code
FROM space s
JOIN space_member sm
ON s.id = sm.space_id
@@ -61,7 +62,7 @@ FROM space s
GROUP BY space_id
) mc
ON s.id = mc.space_id
-WHERE sm.user_id = $1 AND s.id = $2
+WHERE sm.user_id = $1 AND s.id = $2 AND s.status != 2 AND sm.status != 2
ORDER BY sm.is_default DESC, sm.sort_number ASC;
-- name: UpdateSpaceName :exec
diff --git a/code/allapp/allapp-go/db/queries/space_member.sql b/code/allapp/allapp-go/db/queries/space_member.sql
index ff3b0693..258e0bf9 100644
--- a/code/allapp/allapp-go/db/queries/space_member.sql
+++ b/code/allapp/allapp-go/db/queries/space_member.sql
@@ -38,4 +38,11 @@ WHERE user_id = $2
UPDATE space_member
SET sort_number = $1
WHERE user_id = $2
- AND space_id = $3;
\ No newline at end of file
+ AND space_id = $3;
+
+-- 退出空间
+-- name: UpdateSpaceMemberExit :exec
+UPDATE space_member
+SET status = 2 AND exit_time = NOW()
+WHERE space_id = $1
+ AND user_id = $2;
\ No newline at end of file
diff --git a/code/allapp/allapp-go/db/repo/space.sql.go b/code/allapp/allapp-go/db/repo/space.sql.go
index cd07e10a..4c9cbed8 100644
--- a/code/allapp/allapp-go/db/repo/space.sql.go
+++ b/code/allapp/allapp-go/db/repo/space.sql.go
@@ -75,7 +75,8 @@ SELECT
COALESCE(mc.member_count, 0) AS member_count,
sm.is_default,
sm.member_name,
- sm.sort_number
+ sm.sort_number,
+ s.invite_code
FROM space s
JOIN space_member sm
ON s.id = sm.space_id
@@ -85,7 +86,7 @@ FROM space s
GROUP BY space_id
) mc
ON s.id = mc.space_id
-WHERE sm.user_id = $1 AND s.id = $2
+WHERE sm.user_id = $1 AND s.id = $2 AND s.status != 2 AND sm.status != 2
ORDER BY sm.is_default DESC, sm.sort_number ASC
`
@@ -103,6 +104,7 @@ type GetSpaceByUserIdAndSpaceIdRow struct {
IsDefault int16
MemberName string
SortNumber int32
+ InviteCode string
}
func (q *Queries) GetSpaceByUserIdAndSpaceId(ctx context.Context, arg GetSpaceByUserIdAndSpaceIdParams) (GetSpaceByUserIdAndSpaceIdRow, error) {
@@ -117,6 +119,7 @@ func (q *Queries) GetSpaceByUserIdAndSpaceId(ctx context.Context, arg GetSpaceBy
&i.IsDefault,
&i.MemberName,
&i.SortNumber,
+ &i.InviteCode,
)
return i, err
}
@@ -164,7 +167,7 @@ FROM space s
GROUP BY space_id
) mc
ON s.id = mc.space_id
-WHERE sm.user_id = $1
+WHERE sm.user_id = $1 AND s.status != 2 AND sm.status != 2
ORDER BY sm.is_default DESC, sm.sort_number ASC
`
diff --git a/code/allapp/allapp-go/db/repo/space_member.sql.go b/code/allapp/allapp-go/db/repo/space_member.sql.go
index 680476f8..3eccdd99 100644
--- a/code/allapp/allapp-go/db/repo/space_member.sql.go
+++ b/code/allapp/allapp-go/db/repo/space_member.sql.go
@@ -108,6 +108,24 @@ func (q *Queries) UpdateSpaceIsDefault(ctx context.Context, arg UpdateSpaceIsDef
return err
}
+const updateSpaceMemberExit = `-- name: UpdateSpaceMemberExit :exec
+UPDATE space_member
+SET status = 2 AND exit_time = NOW()
+WHERE space_id = $1
+ AND user_id = $2
+`
+
+type UpdateSpaceMemberExitParams struct {
+ SpaceID int64
+ UserID int64
+}
+
+// 退出空间
+func (q *Queries) UpdateSpaceMemberExit(ctx context.Context, arg UpdateSpaceMemberExitParams) error {
+ _, err := q.db.Exec(ctx, updateSpaceMemberExit, arg.SpaceID, arg.UserID)
+ return err
+}
+
const updateSpaceMemberName = `-- name: UpdateSpaceMemberName :exec
UPDATE space_member SET member_name = $1
WHERE space_id = $2 AND user_id = $3
diff --git a/code/allapp/allapp-rn/src/app/space/manage/sub-page/invite/index.tsx b/code/allapp/allapp-rn/src/app/space/manage/sub-page/invite/index.tsx
new file mode 100644
index 00000000..5981ba3c
--- /dev/null
+++ b/code/allapp/allapp-rn/src/app/space/manage/sub-page/invite/index.tsx
@@ -0,0 +1,96 @@
+import * as Clipboard from 'expo-clipboard'
+import { useLocalSearchParams } from 'expo-router'
+import { useEffect, useState } from 'react'
+import {
+ Modal,
+ Pressable,
+ Text,
+ TouchableOpacity,
+ View,
+} from 'react-native'
+import QRCode from 'react-native-qrcode-svg'
+import { toast } from 'sonner-native'
+import { AButton, ADivider, LucideIcon } from '@/components/common/ao'
+import CustomHeader from '@/components/custom/Header'
+
+export default function Invite() {
+ const params = useLocalSearchParams<{ invite_code: string }>()
+ const { invite_code } = params
+
+ const [qrcode, setQrcode] = useState('space:')
+
+ const [previewVisible, setPreviewVisible] = useState(false)
+
+ async function copyInviteCode() {
+ await Clipboard.setStringAsync(invite_code)
+ toast.success('邀请码已复制')
+ }
+
+ useEffect(() => {
+ setQrcode(`space:${invite_code}`)
+ console.log(`space:${invite_code}`)
+ }, [invite_code])
+
+ return (
+
+
+
+
+
+ {/* 邀请码卡片 */}
+
+
+ 复制邀请码邀请家庭成员加入
+
+
+
+ {invite_code}
+
+
+
+ }
+ >
+ 复制邀请码
+
+
+
+
+
+
+
+ {/* 二维码卡片 */}
+ setPreviewVisible(true)}
+ className="bg-white rounded-2xl py-8 items-center"
+ >
+
+
+
+
+
+ {/* 全屏预览(无动画) */}
+
+ setPreviewVisible(false)}
+ className="flex-1 bg-white items-center justify-center"
+ >
+
+
+
+
+ )
+}
diff --git a/code/allapp/allapp-rn/src/app/space/manage/sub-page/member-manage/index.tsx b/code/allapp/allapp-rn/src/app/space/manage/sub-page/member-manage/index.tsx
new file mode 100644
index 00000000..48587626
--- /dev/null
+++ b/code/allapp/allapp-rn/src/app/space/manage/sub-page/member-manage/index.tsx
@@ -0,0 +1,10 @@
+import { View } from 'react-native'
+import CustomHeader from '@/components/custom/Header'
+
+export default function () {
+ return (
+
+
+
+ )
+}
diff --git a/code/allapp/allapp-rn/src/app/space/manage/sub-page/settings/index.tsx b/code/allapp/allapp-rn/src/app/space/manage/sub-page/settings/index.tsx
index c9078c30..49f6632f 100644
--- a/code/allapp/allapp-rn/src/app/space/manage/sub-page/settings/index.tsx
+++ b/code/allapp/allapp-rn/src/app/space/manage/sub-page/settings/index.tsx
@@ -14,7 +14,7 @@ import {
ActionsheetDragIndicator,
ActionsheetDragIndicatorWrapper,
} from '@/components/ui/actionsheet'
-import { dissolveSpaceApi, getSpaceSettingsApi, updateSpaceDefaultApi, updateSpaceMemberNameApi, updateSpaceNameApi } from '@/request/api/space'
+import { dissolveSpaceApi, exitSpaceApi, getSpaceSettingsApi, updateSpaceDefaultApi, updateSpaceMemberNameApi, updateSpaceNameApi } from '@/request/api/space'
import { useUserStore } from '@/store/user'
interface ItemProps {
@@ -65,6 +65,8 @@ export default function Settings() {
const { spaceId } = params
const [space, setSpace] = useState(null)
+ // 是否自己的空间
+ const [isOwner, setIsOwner] = useState(false)
// 空间名称
const [showName, setShowName] = useState(false)
@@ -114,6 +116,15 @@ export default function Settings() {
}
}, [spaceId])
+ useEffect(() => {
+ if (space) {
+ setIsOwner(space.owner_id === userStore.userInfo.id)
+ }
+ else {
+ setIsOwner(false)
+ }
+ }, [space])
+
return (
@@ -124,13 +135,14 @@ export default function Settings() {
)
: (
+
常用设置
{
- space?.owner_id === userStore.userInfo.id && (
+ isOwner && (
+
+ 分享
+
+
+
+ - {
+ router.navigate({
+ pathname: '/space/manage/sub-page/invite',
+ params: {
+ invite_code: space.invite_code,
+ },
+ })
+ }}
+ />
+
+
其它操作
-
+ {
+ isOwner && (
+
+ )
+ }
- {
setShowDissolve(true)
@@ -397,7 +432,7 @@ export default function Settings() {
{/* 解散 */}
{
setShowDissolve(false)
@@ -411,18 +446,34 @@ export default function Settings() {
return
}
- await dissolveSpaceApi({
- space_id: space.space_id,
- }).then((res) => {
- if (res.isSuccess) {
- setShowDissolve(false)
- toast.success('解散成功')
+ if (isOwner) {
+ await dissolveSpaceApi({
+ space_id: space.space_id,
+ }).then((res) => {
+ if (res.isSuccess) {
+ setShowDissolve(false)
+ toast.success('已解散该空间')
- setTimeout(() => {
- router.back()
- }, 300)
- }
- })
+ setTimeout(() => {
+ router.back()
+ }, 300)
+ }
+ })
+ }
+ else {
+ await exitSpaceApi({
+ space_id: space.space_id,
+ }).then((res) => {
+ if (res.isSuccess) {
+ setShowDissolve(false)
+ toast.success('已退出该空间')
+
+ setTimeout(() => {
+ router.back()
+ }, 300)
+ }
+ })
+ }
}}
/>
diff --git a/code/allapp/allapp-rn/src/request/api/space/index.ts b/code/allapp/allapp-rn/src/request/api/space/index.ts
index f8a697ba..3313e245 100644
--- a/code/allapp/allapp-rn/src/request/api/space/index.ts
+++ b/code/allapp/allapp-rn/src/request/api/space/index.ts
@@ -2,9 +2,7 @@ import type {
CreateSpaceParams,
CreateSpaceResult,
DissolveSpaceParams,
- DissolveSpaceResult,
ExitSpaceParams,
- ExitSpaceResult,
GetSpaceSettingsParams,
JoinSpaceParams,
JoinSpaceResult,
@@ -60,21 +58,21 @@ export function getSpaceSettingsApi(params: GetSpaceSettingsParams) {
return alovaInstance.Post>(`${API_PREFIX}/settings`, params)
}
+// 解散空间
+export function dissolveSpaceApi(params: DissolveSpaceParams) {
+ return alovaInstance.Post>(`${API_PREFIX}/dissolve`, params)
+}
+
+// 退出空间
+export function exitSpaceApi(params: ExitSpaceParams) {
+ return alovaInstance.Post>(`${API_PREFIX}/member/exit`, params)
+}
+
// Join Space API
export function joinSpaceApi(params: JoinSpaceParams) {
return alovaInstance.Post>(`${API_PREFIX}/join`, params)
}
-// Dissolve Space API
-export function dissolveSpaceApi(params: DissolveSpaceParams) {
- return alovaInstance.Post>(`${API_PREFIX}/dissolve`, params)
-}
-
-// Exit Space API
-export function exitSpaceApi(params: ExitSpaceParams) {
- return alovaInstance.Post>(`${API_PREFIX}/exit`, params)
-}
-
// Remove Space User API
export function removeSpaceMemberApi(params: RemoveSpaceMemberParams) {
return alovaInstance.Post>(`${API_PREFIX}/remove`, params)
diff --git a/code/allapp/allapp-rn/src/request/index.ts b/code/allapp/allapp-rn/src/request/index.ts
index f12e2875..d52bee1f 100644
--- a/code/allapp/allapp-rn/src/request/index.ts
+++ b/code/allapp/allapp-rn/src/request/index.ts
@@ -28,8 +28,8 @@ function isWhiteListed(url: string) {
}
const alovaInstance = createAlova({
- // baseURL: 'http://192.168.5.6:8086/app',
- baseURL: 'http://192.168.1.137:8086/app',
+ baseURL: 'http://192.168.5.6:8086/app',
+ // baseURL: 'http://192.168.1.137:8086/app',
requestAdapter: axiosRequestAdapter(),
timeout: 5000,
cacheFor: null,
diff --git a/code/allapp/allapp-rn/src/types/space/index.ts b/code/allapp/allapp-rn/src/types/space/index.ts
index 4e0c0673..fea0657c 100644
--- a/code/allapp/allapp-rn/src/types/space/index.ts
+++ b/code/allapp/allapp-rn/src/types/space/index.ts
@@ -8,6 +8,8 @@ export interface UserSpace {
member_name: string
sort_number: number
+
+ invite_code: string
}
// 创建空间
@@ -31,9 +33,11 @@ export interface ListUserSpacesResult {
export interface DissolveSpaceParams {
space_id: number
}
-export interface DissolveSpaceResult {
-}
+// 退出空间
+export interface ExitSpaceParams {
+ space_id: number
+}
// 更新空间名称
export interface UpdateSpaceNameParams {
space_id: number
@@ -74,13 +78,6 @@ export interface JoinSpaceResult {
space_name: string
}
-// 退出空间
-export interface ExitSpaceParams {
- space_id: number
-}
-export interface ExitSpaceResult {
-}
-
// 踢出用户
export interface RemoveSpaceMemberParams {
space_id: number