fix project share

main
mula.liu 2026-06-03 17:08:06 +08:00
parent c0a4798fc6
commit 9f707e879e
4 changed files with 60 additions and 90 deletions

View File

@ -4,3 +4,6 @@
## Session 14:59 ## Session 14:59
## Session 16:54

View File

@ -180,6 +180,12 @@
transition: all 0.2s; transition: all 0.2s;
} }
/* 折叠状态下给头像留足空间 */
.ant-layout-sider-collapsed .user-card {
padding: 12px 4px;
justify-content: center;
}
.user-info { .user-info {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -1156,43 +1156,24 @@ function DocumentPage() {
</div> </div>
{hasPassword && ( {hasPassword && (
<div> <Space.Compact style={{ width: '100%' }}>
<Input.Password <Input.Password
placeholder="请输入访问密码" placeholder="请输入访问密码"
value={password} value={password}
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
/> />
<Button <Button type="primary" onClick={handleSavePassword}>
type="primary"
onClick={handleSavePassword}
style={{ marginTop: 8 }}
>
保存密码 保存密码
</Button> </Button>
</div> </Space.Compact>
)} )}
</> </>
) : ( ) : (
<> <>
<div style={{ color: '#8c8c8c', lineHeight: 1.7 }}> <div style={{ color: '#8c8c8c', lineHeight: 1.7 }}>
当前文件尚未创建独立分享文件分享不受项目是否公开影响分享页只包含该文件本身 当前文件尚未创建独立分享
</div> </div>
<div>
<Space>
<span style={{ fontWeight: 500 }}>访问密码保护</span>
<Switch checked={hasPassword} onChange={setHasPassword} />
</Space>
</div>
{hasPassword && (
<Input.Password
placeholder="请输入访问密码"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
)}
<Button type="primary" onClick={handleCreateShare}> <Button type="primary" onClick={handleCreateShare}>
创建文件分享 创建文件分享
</Button> </Button>

View File

@ -146,42 +146,58 @@ function ProjectList({ type = 'my' }) {
editForm.setFieldsValue({ editForm.setFieldsValue({
name: project.name, name: project.name,
description: project.description, description: project.description,
is_public: project.is_public === 1,
}) })
setShareInfo(project.is_public === 1 ? null : { enabled: false, share_url: null, has_password: false, access_pass: null }) setShareInfo(null)
setHasPassword(false) setHasPassword(false)
setPassword('') setPassword('')
setEditModalVisible(true) setEditModalVisible(true)
} }
// // /
const handleUpdateProject = async (values) => { const handlePublicToggle = async (checked) => {
if (!currentProject) return
try { try {
const shouldKeepOpenForShare = currentProject?.is_public !== 1 && values.is_public
const res = await updateProject(currentProject.id, { const res = await updateProject(currentProject.id, {
...values, is_public: checked ? 1 : 0,
is_public: values.is_public ? 1 : 0,
}) })
const updatedProject = res.data || { const updatedProject = res.data || {
...currentProject, ...currentProject,
...values, is_public: checked ? 1 : 0,
is_public: values.is_public ? 1 : 0,
} }
setCurrentProject(updatedProject) setCurrentProject(updatedProject)
message.success('项目更新成功') message.success(checked ? '项目已设为公开' : '项目已设为私有')
await fetchProjects() await fetchProjects()
if (shouldKeepOpenForShare) { if (checked) {
const shareRes = await getProjectShareInfo(currentProject.id) const shareRes = await getProjectShareInfo(currentProject.id)
setShareInfo(shareRes.data) setShareInfo(shareRes.data)
setHasPassword(shareRes.data.has_password) setHasPassword(shareRes.data.has_password)
setPassword(shareRes.data.access_pass || '') setPassword(shareRes.data.access_pass || '')
return } else {
setShareInfo({ enabled: false, share_url: null, has_password: false, access_pass: null })
setHasPassword(false)
setPassword('')
} }
} catch (error) {
console.error('Toggle public error:', error)
message.error('操作失败')
}
}
setShareInfo({ enabled: false, share_url: null, has_password: false, access_pass: null }) //
setHasPassword(false) const handleUpdateProject = async (values) => {
setPassword('') try {
const res = await updateProject(currentProject.id, {
name: values.name,
description: values.description,
})
const updatedProject = res.data || {
...currentProject,
...values,
}
setCurrentProject(updatedProject)
message.success('项目更新成功')
await fetchProjects()
setEditModalVisible(false) setEditModalVisible(false)
editForm.resetFields() editForm.resetFields()
} catch (error) { } catch (error) {
@ -193,9 +209,10 @@ function ProjectList({ type = 'my' }) {
useEffect(() => { useEffect(() => {
if (!editModalVisible || !currentProject) return if (!editModalVisible || !currentProject) return
const isPublic = editForm.getFieldValue('is_public') if (currentProject.is_public !== 1) {
if (!isPublic) {
setShareInfo({ enabled: false, share_url: null, has_password: false, access_pass: null }) setShareInfo({ enabled: false, share_url: null, has_password: false, access_pass: null })
setHasPassword(false)
setPassword('')
return return
} }
@ -209,39 +226,7 @@ function ProjectList({ type = 'my' }) {
console.error('Get project share info error:', error) console.error('Get project share info error:', error)
} }
})() })()
}, [editModalVisible, currentProject, editForm]) }, [editModalVisible, currentProject])
const currentEditPublic = Form.useWatch('is_public', editForm)
const isPublicEnablePending = editModalVisible && currentEditPublic && currentProject?.is_public !== 1
useEffect(() => {
if (!editModalVisible || !currentProject) return
if (!currentEditPublic) {
setShareInfo({ enabled: false, share_url: null, has_password: false, access_pass: null })
setHasPassword(false)
setPassword('')
return
}
if (currentProject.is_public !== 1) {
setShareInfo(null)
setHasPassword(false)
setPassword('')
return
}
;(async () => {
try {
const res = await getProjectShareInfo(currentProject.id)
setShareInfo(res.data)
setHasPassword(res.data.has_password)
setPassword(res.data.access_pass || '')
} catch (error) {
console.error('Refresh project share info error:', error)
}
})()
}, [currentEditPublic, editModalVisible, currentProject, editForm])
const [gitRepos, setGitRepos] = useState([]) const [gitRepos, setGitRepos] = useState([])
const [loadingRepos, setLoadingRepos] = useState(false) const [loadingRepos, setLoadingRepos] = useState(false)
@ -765,25 +750,20 @@ function ProjectList({ type = 'my' }) {
/> />
</Form.Item> </Form.Item>
<Form.Item <Form.Item label="公开项目">
label="公开项目" <Switch
name="is_public" checked={currentProject?.is_public === 1}
valuePropName="checked" onChange={handlePublicToggle}
> />
<Switch />
</Form.Item> </Form.Item>
<Form.Item label="项目公开分享"> <Form.Item label="项目公开分享">
<Space direction="vertical" style={{ width: '100%' }} size="middle"> <Space direction="vertical" style={{ width: '100%' }} size="middle">
{!editForm.getFieldValue('is_public') ? ( {currentProject?.is_public !== 1 ? (
<div style={{ color: '#8c8c8c', lineHeight: 1.7 }}> <div style={{ color: '#8c8c8c', lineHeight: 1.7 }}>
开启公开项目可以生成项目分享链接和配置访问密码 开启公开项目可以生成项目分享链接和访问密码
</div> </div>
) : isPublicEnablePending ? ( ) : shareInfo ? (
<div style={{ color: '#8c8c8c', lineHeight: 1.7 }}>
保存项目后将自动生成项目分享链接
</div>
) : (
<> <>
<Input <Input
value={shareInfo?.share_url ? `${window.location.origin}${shareInfo.share_url}` : '正在生成分享链接...'} value={shareInfo?.share_url ? `${window.location.origin}${shareInfo.share_url}` : '正在生成分享链接...'}
@ -797,19 +777,19 @@ function ProjectList({ type = 'my' }) {
<Switch checked={hasPassword} onChange={handlePasswordToggle} /> <Switch checked={hasPassword} onChange={handlePasswordToggle} />
</Space> </Space>
{hasPassword && ( {hasPassword && (
<div> <Space.Compact style={{ width: '100%' }}>
<Input.Password <Input.Password
placeholder="请输入访问密码" placeholder="请输入访问密码"
value={password} value={password}
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
/> />
<Button type="primary" onClick={handleSavePassword} style={{ marginTop: 8 }}> <Button type="primary" onClick={handleSavePassword}>
保存密码 保存密码
</Button> </Button>
</div> </Space.Compact>
)} )}
</> </>
)} ) : null}
</Space> </Space>
</Form.Item> </Form.Item>