mirror of
https://github.com/dreammis/social-auto-upload.git
synced 2026-08-28 17:43:28 +08:00
feat(account-management): add upload and download cookie file buttons
- Add '上传Cookie文件' and '下载Cookie文件' buttons to account management page - Implement frontend functionality for cookie file upload and download - Add backend API endpoints for handling cookie file operations: - /uploadCookie: Handle cookie file upload with validation - /downloadCookie: Handle secure cookie file download - Implement security measures to prevent path traversal attacks - Add proper error handling and user feedback - Maintain existing functionality while adding new features
This commit is contained in:
+121
@@ -476,6 +476,127 @@ def postVideoBatch():
|
||||
"data": None
|
||||
}), 200
|
||||
|
||||
# Cookie文件上传API
|
||||
@app.route('/uploadCookie', methods=['POST'])
|
||||
def upload_cookie():
|
||||
try:
|
||||
if 'file' not in request.files:
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"msg": "没有找到Cookie文件",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
file = request.files['file']
|
||||
if file.filename == '':
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"msg": "Cookie文件名不能为空",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
if not file.filename.endswith('.json'):
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"msg": "Cookie文件必须是JSON格式",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
# 获取账号信息
|
||||
account_id = request.form.get('id')
|
||||
platform = request.form.get('platform')
|
||||
|
||||
if not account_id or not platform:
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"msg": "缺少账号ID或平台信息",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
# 从数据库获取账号的文件路径
|
||||
with sqlite3.connect(Path(BASE_DIR / "db" / "database.db")) as conn:
|
||||
conn.row_factory = sqlite3.Row
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('SELECT filePath FROM user_info WHERE id = ?', (account_id,))
|
||||
result = cursor.fetchone()
|
||||
|
||||
if not result:
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"msg": "账号不存在",
|
||||
"data": None
|
||||
}), 404
|
||||
|
||||
# 保存上传的Cookie文件到对应路径
|
||||
cookie_file_path = Path(BASE_DIR / "cookiesFile" / result['filePath'])
|
||||
cookie_file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
file.save(str(cookie_file_path))
|
||||
|
||||
# 更新数据库中的账号信息(可选,比如更新更新时间)
|
||||
# 这里可以根据需要添加额外的处理逻辑
|
||||
|
||||
return jsonify({
|
||||
"code": 200,
|
||||
"msg": "Cookie文件上传成功",
|
||||
"data": None
|
||||
}), 200
|
||||
|
||||
except Exception as e:
|
||||
print(f"上传Cookie文件时出错: {str(e)}")
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"msg": f"上传Cookie文件失败: {str(e)}",
|
||||
"data": None
|
||||
}), 500
|
||||
|
||||
|
||||
# Cookie文件下载API
|
||||
@app.route('/downloadCookie', methods=['GET'])
|
||||
def download_cookie():
|
||||
try:
|
||||
file_path = request.args.get('filePath')
|
||||
if not file_path:
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"msg": "缺少文件路径参数",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
# 验证文件路径的安全性,防止路径遍历攻击
|
||||
cookie_file_path = Path(BASE_DIR / "cookiesFile" / file_path).resolve()
|
||||
base_path = Path(BASE_DIR / "cookiesFile").resolve()
|
||||
|
||||
if not cookie_file_path.is_relative_to(base_path):
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"msg": "非法文件路径",
|
||||
"data": None
|
||||
}), 400
|
||||
|
||||
if not cookie_file_path.exists():
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"msg": "Cookie文件不存在",
|
||||
"data": None
|
||||
}), 404
|
||||
|
||||
# 返回文件
|
||||
return send_from_directory(
|
||||
directory=str(cookie_file_path.parent),
|
||||
path=cookie_file_path.name,
|
||||
as_attachment=True
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(f"下载Cookie文件时出错: {str(e)}")
|
||||
return jsonify({
|
||||
"code": 500,
|
||||
"msg": f"下载Cookie文件失败: {str(e)}",
|
||||
"data": None
|
||||
}), 500
|
||||
|
||||
|
||||
# 包装函数:在线程中运行异步函数
|
||||
def run_async_function(type,id,status_queue):
|
||||
match type:
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="primary" @click="handleDownloadCookie(scope.row)">下载Cookie文件</el-button>
|
||||
<el-button size="small" type="info" @click="handleUploadCookie(scope.row)">上传Cookie文件</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -120,6 +122,8 @@
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="primary" @click="handleDownloadCookie(scope.row)">下载Cookie文件</el-button>
|
||||
<el-button size="small" type="info" @click="handleUploadCookie(scope.row)">上传Cookie文件</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -183,6 +187,8 @@
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="primary" @click="handleDownloadCookie(scope.row)">下载Cookie文件</el-button>
|
||||
<el-button size="small" type="info" @click="handleUploadCookie(scope.row)">上传Cookie文件</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -246,6 +252,8 @@
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="primary" @click="handleDownloadCookie(scope.row)">下载Cookie文件</el-button>
|
||||
<el-button size="small" type="info" @click="handleUploadCookie(scope.row)">上传Cookie文件</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -309,6 +317,8 @@
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="primary" @click="handleDownloadCookie(scope.row)">下载Cookie文件</el-button>
|
||||
<el-button size="small" type="info" @click="handleUploadCookie(scope.row)">上传Cookie文件</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -547,7 +557,7 @@ const handleDelete = (row) => {
|
||||
try {
|
||||
// 调用API删除账号
|
||||
const response = await accountApi.deleteAccount(row.id)
|
||||
|
||||
|
||||
if (response.code === 200) {
|
||||
// 从状态管理中删除账号
|
||||
accountStore.deleteAccount(row.id)
|
||||
@@ -568,6 +578,77 @@ const handleDelete = (row) => {
|
||||
})
|
||||
}
|
||||
|
||||
// 下载Cookie文件
|
||||
const handleDownloadCookie = (row) => {
|
||||
// 从后端获取Cookie文件
|
||||
const baseUrl = import.meta.env.VITE_API_BASE_URL || 'http://localhost:5409'
|
||||
const downloadUrl = `${baseUrl}/downloadCookie?filePath=${encodeURIComponent(row.filePath)}`
|
||||
|
||||
// 创建一个隐藏的链接来触发下载
|
||||
const link = document.createElement('a')
|
||||
link.href = downloadUrl
|
||||
link.download = `${row.name}_cookie.json`
|
||||
link.target = '_blank'
|
||||
link.style.display = 'none'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
}
|
||||
|
||||
// 上传Cookie文件
|
||||
const handleUploadCookie = (row) => {
|
||||
// 创建一个隐藏的文件输入框
|
||||
const input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
input.accept = '.json'
|
||||
input.style.display = 'none'
|
||||
document.body.appendChild(input)
|
||||
|
||||
input.onchange = async (event) => {
|
||||
const file = event.target.files[0]
|
||||
if (!file) return
|
||||
|
||||
// 检查文件类型
|
||||
if (!file.name.endsWith('.json')) {
|
||||
ElMessage.error('请选择JSON格式的Cookie文件')
|
||||
document.body.removeChild(input)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 创建FormData对象
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('id', row.id)
|
||||
formData.append('platform', row.platform)
|
||||
|
||||
// 发送上传请求
|
||||
const baseUrl = import.meta.env.VITE_API_BASE_URL || 'http://localhost:5409'
|
||||
const response = await fetch(`${baseUrl}/uploadCookie`, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
|
||||
const result = await response.json()
|
||||
|
||||
if (result.code === 200) {
|
||||
ElMessage.success('Cookie文件上传成功')
|
||||
// 刷新账号列表以显示更新
|
||||
fetchAccounts()
|
||||
} else {
|
||||
ElMessage.error(result.msg || 'Cookie文件上传失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('上传Cookie文件失败:', error)
|
||||
ElMessage.error('Cookie文件上传失败')
|
||||
} finally {
|
||||
document.body.removeChild(input)
|
||||
}
|
||||
}
|
||||
|
||||
input.click()
|
||||
}
|
||||
|
||||
// SSE事件源对象
|
||||
let eventSource = null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user