增加了客户端管理模块
parent
0d1b8c815d
commit
5bdab4a405
|
|
@ -9,6 +9,8 @@ ENV PYTHONPATH=/app
|
||||||
ENV PYTHONUNBUFFERED=1
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
# 使用阿里源
|
# 使用阿里源
|
||||||
|
RUN sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/debian.sources
|
||||||
|
RUN sed -i 's/security.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/debian.sources
|
||||||
|
|
||||||
# 安装系统依赖
|
# 安装系统依赖
|
||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,391 @@
|
||||||
|
from fastapi import APIRouter, HTTPException, Depends
|
||||||
|
from app.models.models import (
|
||||||
|
ClientDownload,
|
||||||
|
CreateClientDownloadRequest,
|
||||||
|
UpdateClientDownloadRequest,
|
||||||
|
ClientDownloadListResponse
|
||||||
|
)
|
||||||
|
from app.core.database import get_db_connection
|
||||||
|
from app.core.auth import get_current_user, get_current_admin_user
|
||||||
|
from app.core.response import create_api_response
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
@router.get("/downloads", response_model=dict)
|
||||||
|
async def get_client_downloads(
|
||||||
|
platform_type: Optional[str] = None,
|
||||||
|
platform_name: Optional[str] = None,
|
||||||
|
is_active: Optional[bool] = None,
|
||||||
|
page: int = 1,
|
||||||
|
size: int = 50
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
获取客户端下载列表(公开接口,所有用户可访问)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with get_db_connection() as conn:
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
|
||||||
|
# 构建查询条件
|
||||||
|
where_clauses = []
|
||||||
|
params = []
|
||||||
|
|
||||||
|
if platform_type:
|
||||||
|
where_clauses.append("platform_type = %s")
|
||||||
|
params.append(platform_type)
|
||||||
|
|
||||||
|
if platform_name:
|
||||||
|
where_clauses.append("platform_name = %s")
|
||||||
|
params.append(platform_name)
|
||||||
|
|
||||||
|
if is_active is not None:
|
||||||
|
where_clauses.append("is_active = %s")
|
||||||
|
params.append(is_active)
|
||||||
|
|
||||||
|
where_clause = " AND ".join(where_clauses) if where_clauses else "1=1"
|
||||||
|
|
||||||
|
# 获取总数
|
||||||
|
count_query = f"SELECT COUNT(*) as total FROM client_downloads WHERE {where_clause}"
|
||||||
|
cursor.execute(count_query, params)
|
||||||
|
total = cursor.fetchone()['total']
|
||||||
|
|
||||||
|
# 获取列表数据
|
||||||
|
offset = (page - 1) * size
|
||||||
|
list_query = f"""
|
||||||
|
SELECT * FROM client_downloads
|
||||||
|
WHERE {where_clause}
|
||||||
|
ORDER BY platform_type, platform_name, version_code DESC
|
||||||
|
LIMIT %s OFFSET %s
|
||||||
|
"""
|
||||||
|
cursor.execute(list_query, params + [size, offset])
|
||||||
|
clients = cursor.fetchall()
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
return create_api_response(
|
||||||
|
code="200",
|
||||||
|
message="获取成功",
|
||||||
|
data={
|
||||||
|
"clients": clients,
|
||||||
|
"total": total,
|
||||||
|
"page": page,
|
||||||
|
"size": size
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return create_api_response(
|
||||||
|
code="500",
|
||||||
|
message=f"获取客户端下载列表失败: {str(e)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/downloads/latest", response_model=dict)
|
||||||
|
async def get_latest_clients():
|
||||||
|
"""
|
||||||
|
获取所有平台的最新版本客户端(公开接口,用于首页下载)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with get_db_connection() as conn:
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
|
||||||
|
query = """
|
||||||
|
SELECT * FROM client_downloads
|
||||||
|
WHERE is_active = TRUE AND is_latest = TRUE
|
||||||
|
ORDER BY platform_type, platform_name
|
||||||
|
"""
|
||||||
|
cursor.execute(query)
|
||||||
|
clients = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
# 按平台类型分组
|
||||||
|
mobile_clients = []
|
||||||
|
desktop_clients = []
|
||||||
|
|
||||||
|
for client in clients:
|
||||||
|
if client['platform_type'] == 'mobile':
|
||||||
|
mobile_clients.append(client)
|
||||||
|
else:
|
||||||
|
desktop_clients.append(client)
|
||||||
|
|
||||||
|
return create_api_response(
|
||||||
|
code="200",
|
||||||
|
message="获取成功",
|
||||||
|
data={
|
||||||
|
"mobile": mobile_clients,
|
||||||
|
"desktop": desktop_clients
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return create_api_response(
|
||||||
|
code="500",
|
||||||
|
message=f"获取最新客户端失败: {str(e)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/downloads/{platform_name}/latest", response_model=dict)
|
||||||
|
async def get_latest_version_by_platform(platform_name: str):
|
||||||
|
"""
|
||||||
|
获取指定平台的最新版本(公开接口,用于客户端版本检查)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with get_db_connection() as conn:
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
|
||||||
|
query = """
|
||||||
|
SELECT * FROM client_downloads
|
||||||
|
WHERE platform_name = %s AND is_active = TRUE AND is_latest = TRUE
|
||||||
|
LIMIT 1
|
||||||
|
"""
|
||||||
|
cursor.execute(query, (platform_name,))
|
||||||
|
client = cursor.fetchone()
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
if not client:
|
||||||
|
return create_api_response(
|
||||||
|
code="404",
|
||||||
|
message=f"未找到平台 {platform_name} 的客户端"
|
||||||
|
)
|
||||||
|
|
||||||
|
return create_api_response(
|
||||||
|
code="200",
|
||||||
|
message="获取成功",
|
||||||
|
data=client
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return create_api_response(
|
||||||
|
code="500",
|
||||||
|
message=f"获取客户端版本失败: {str(e)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/downloads/{id}", response_model=dict)
|
||||||
|
async def get_client_download_by_id(id: int):
|
||||||
|
"""
|
||||||
|
获取指定ID的客户端详情(公开接口)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with get_db_connection() as conn:
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
|
||||||
|
query = "SELECT * FROM client_downloads WHERE id = %s"
|
||||||
|
cursor.execute(query, (id,))
|
||||||
|
client = cursor.fetchone()
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
if not client:
|
||||||
|
return create_api_response(
|
||||||
|
code="404",
|
||||||
|
message="客户端不存在"
|
||||||
|
)
|
||||||
|
|
||||||
|
return create_api_response(
|
||||||
|
code="200",
|
||||||
|
message="获取成功",
|
||||||
|
data=client
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return create_api_response(
|
||||||
|
code="500",
|
||||||
|
message=f"获取客户端详情失败: {str(e)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/downloads", response_model=dict)
|
||||||
|
async def create_client_download(
|
||||||
|
request: CreateClientDownloadRequest,
|
||||||
|
current_user: dict = Depends(get_current_admin_user)
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
创建新的客户端版本(仅管理员)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with get_db_connection() as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# 如果设置为最新版本,先将同平台的其他版本设为非最新
|
||||||
|
if request.is_latest:
|
||||||
|
update_query = """
|
||||||
|
UPDATE client_downloads
|
||||||
|
SET is_latest = FALSE
|
||||||
|
WHERE platform_name = %s
|
||||||
|
"""
|
||||||
|
cursor.execute(update_query, (request.platform_name,))
|
||||||
|
|
||||||
|
# 插入新版本
|
||||||
|
insert_query = """
|
||||||
|
INSERT INTO client_downloads (
|
||||||
|
platform_type, platform_name, version, version_code,
|
||||||
|
download_url, file_size, release_notes, is_active,
|
||||||
|
is_latest, min_system_version, created_by
|
||||||
|
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||||
|
"""
|
||||||
|
cursor.execute(insert_query, (
|
||||||
|
request.platform_type,
|
||||||
|
request.platform_name,
|
||||||
|
request.version,
|
||||||
|
request.version_code,
|
||||||
|
request.download_url,
|
||||||
|
request.file_size,
|
||||||
|
request.release_notes,
|
||||||
|
request.is_active,
|
||||||
|
request.is_latest,
|
||||||
|
request.min_system_version,
|
||||||
|
current_user['user_id']
|
||||||
|
))
|
||||||
|
|
||||||
|
new_id = cursor.lastrowid
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
return create_api_response(
|
||||||
|
code="200",
|
||||||
|
message="客户端版本创建成功",
|
||||||
|
data={"id": new_id}
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return create_api_response(
|
||||||
|
code="500",
|
||||||
|
message=f"创建客户端版本失败: {str(e)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/downloads/{id}", response_model=dict)
|
||||||
|
async def update_client_download(
|
||||||
|
id: int,
|
||||||
|
request: UpdateClientDownloadRequest,
|
||||||
|
current_user: dict = Depends(get_current_admin_user)
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
更新客户端版本信息(仅管理员)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with get_db_connection() as conn:
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
|
||||||
|
# 检查客户端是否存在
|
||||||
|
cursor.execute("SELECT * FROM client_downloads WHERE id = %s", (id,))
|
||||||
|
existing = cursor.fetchone()
|
||||||
|
if not existing:
|
||||||
|
cursor.close()
|
||||||
|
return create_api_response(
|
||||||
|
code="404",
|
||||||
|
message="客户端不存在"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 如果设置为最新版本,先将同平台的其他版本设为非最新
|
||||||
|
if request.is_latest:
|
||||||
|
update_query = """
|
||||||
|
UPDATE client_downloads
|
||||||
|
SET is_latest = FALSE
|
||||||
|
WHERE platform_name = %s AND id != %s
|
||||||
|
"""
|
||||||
|
cursor.execute(update_query, (existing['platform_name'], id))
|
||||||
|
|
||||||
|
# 构建更新语句
|
||||||
|
update_fields = []
|
||||||
|
params = []
|
||||||
|
|
||||||
|
if request.version is not None:
|
||||||
|
update_fields.append("version = %s")
|
||||||
|
params.append(request.version)
|
||||||
|
|
||||||
|
if request.version_code is not None:
|
||||||
|
update_fields.append("version_code = %s")
|
||||||
|
params.append(request.version_code)
|
||||||
|
|
||||||
|
if request.download_url is not None:
|
||||||
|
update_fields.append("download_url = %s")
|
||||||
|
params.append(request.download_url)
|
||||||
|
|
||||||
|
if request.file_size is not None:
|
||||||
|
update_fields.append("file_size = %s")
|
||||||
|
params.append(request.file_size)
|
||||||
|
|
||||||
|
if request.release_notes is not None:
|
||||||
|
update_fields.append("release_notes = %s")
|
||||||
|
params.append(request.release_notes)
|
||||||
|
|
||||||
|
if request.is_active is not None:
|
||||||
|
update_fields.append("is_active = %s")
|
||||||
|
params.append(request.is_active)
|
||||||
|
|
||||||
|
if request.is_latest is not None:
|
||||||
|
update_fields.append("is_latest = %s")
|
||||||
|
params.append(request.is_latest)
|
||||||
|
|
||||||
|
if request.min_system_version is not None:
|
||||||
|
update_fields.append("min_system_version = %s")
|
||||||
|
params.append(request.min_system_version)
|
||||||
|
|
||||||
|
if not update_fields:
|
||||||
|
cursor.close()
|
||||||
|
return create_api_response(
|
||||||
|
code="400",
|
||||||
|
message="没有要更新的字段"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 执行更新
|
||||||
|
update_query = f"""
|
||||||
|
UPDATE client_downloads
|
||||||
|
SET {', '.join(update_fields)}
|
||||||
|
WHERE id = %s
|
||||||
|
"""
|
||||||
|
params.append(id)
|
||||||
|
cursor.execute(update_query, params)
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
return create_api_response(
|
||||||
|
code="200",
|
||||||
|
message="客户端版本更新成功"
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return create_api_response(
|
||||||
|
code="500",
|
||||||
|
message=f"更新客户端版本失败: {str(e)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/downloads/{id}", response_model=dict)
|
||||||
|
async def delete_client_download(
|
||||||
|
id: int,
|
||||||
|
current_user: dict = Depends(get_current_admin_user)
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
删除客户端版本(仅管理员)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with get_db_connection() as conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# 检查是否存在
|
||||||
|
cursor.execute("SELECT * FROM client_downloads WHERE id = %s", (id,))
|
||||||
|
if not cursor.fetchone():
|
||||||
|
cursor.close()
|
||||||
|
return create_api_response(
|
||||||
|
code="404",
|
||||||
|
message="客户端不存在"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 执行删除
|
||||||
|
cursor.execute("DELETE FROM client_downloads WHERE id = %s", (id,))
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
return create_api_response(
|
||||||
|
code="200",
|
||||||
|
message="客户端版本删除成功"
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return create_api_response(
|
||||||
|
code="500",
|
||||||
|
message=f"删除客户端版本失败: {str(e)}"
|
||||||
|
)
|
||||||
|
|
@ -161,3 +161,46 @@ class UpdateKnowledgeBaseRequest(BaseModel):
|
||||||
class KnowledgeBaseListResponse(BaseModel):
|
class KnowledgeBaseListResponse(BaseModel):
|
||||||
kbs: List[KnowledgeBase]
|
kbs: List[KnowledgeBase]
|
||||||
total: int
|
total: int
|
||||||
|
|
||||||
|
# 客户端下载相关模型
|
||||||
|
class ClientDownload(BaseModel):
|
||||||
|
id: int
|
||||||
|
platform_type: str # 'mobile' or 'desktop'
|
||||||
|
platform_name: str # 'ios', 'android', 'windows', 'mac_intel', 'mac_m', 'linux'
|
||||||
|
version: str
|
||||||
|
version_code: int
|
||||||
|
download_url: str
|
||||||
|
file_size: Optional[int] = None
|
||||||
|
release_notes: Optional[str] = None
|
||||||
|
is_active: bool
|
||||||
|
is_latest: bool
|
||||||
|
min_system_version: Optional[str] = None
|
||||||
|
created_at: datetime.datetime
|
||||||
|
updated_at: datetime.datetime
|
||||||
|
created_by: Optional[int] = None
|
||||||
|
|
||||||
|
class CreateClientDownloadRequest(BaseModel):
|
||||||
|
platform_type: str
|
||||||
|
platform_name: str
|
||||||
|
version: str
|
||||||
|
version_code: int
|
||||||
|
download_url: str
|
||||||
|
file_size: Optional[int] = None
|
||||||
|
release_notes: Optional[str] = None
|
||||||
|
is_active: bool = True
|
||||||
|
is_latest: bool = False
|
||||||
|
min_system_version: Optional[str] = None
|
||||||
|
|
||||||
|
class UpdateClientDownloadRequest(BaseModel):
|
||||||
|
version: Optional[str] = None
|
||||||
|
version_code: Optional[int] = None
|
||||||
|
download_url: Optional[str] = None
|
||||||
|
file_size: Optional[int] = None
|
||||||
|
release_notes: Optional[str] = None
|
||||||
|
is_active: Optional[bool] = None
|
||||||
|
is_latest: Optional[bool] = None
|
||||||
|
min_system_version: Optional[str] = None
|
||||||
|
|
||||||
|
class ClientDownloadListResponse(BaseModel):
|
||||||
|
clients: List[ClientDownload]
|
||||||
|
total: int
|
||||||
|
|
|
||||||
3
main.py
3
main.py
|
|
@ -2,7 +2,7 @@ import uvicorn
|
||||||
from fastapi import FastAPI, Request, HTTPException
|
from fastapi import FastAPI, Request, HTTPException
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from app.api.endpoints import auth, users, meetings, tags, admin, tasks, prompts, knowledge_base
|
from app.api.endpoints import auth, users, meetings, tags, admin, tasks, prompts, knowledge_base, client_downloads
|
||||||
from app.core.config import UPLOAD_DIR, API_CONFIG
|
from app.core.config import UPLOAD_DIR, API_CONFIG
|
||||||
from app.api.endpoints.admin import load_system_config
|
from app.api.endpoints.admin import load_system_config
|
||||||
import os
|
import os
|
||||||
|
|
@ -38,6 +38,7 @@ app.include_router(admin.router, prefix="/api", tags=["Admin"])
|
||||||
app.include_router(tasks.router, prefix="/api", tags=["Tasks"])
|
app.include_router(tasks.router, prefix="/api", tags=["Tasks"])
|
||||||
app.include_router(prompts.router, prefix="/api", tags=["Prompts"])
|
app.include_router(prompts.router, prefix="/api", tags=["Prompts"])
|
||||||
app.include_router(knowledge_base.router, prefix="/api", tags=["KnowledgeBase"])
|
app.include_router(knowledge_base.router, prefix="/api", tags=["KnowledgeBase"])
|
||||||
|
app.include_router(client_downloads.router, prefix="/api/clients", tags=["ClientDownloads"])
|
||||||
|
|
||||||
@app.get("/")
|
@app.get("/")
|
||||||
def read_root():
|
def read_root():
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
-- 客户端下载管理表
|
||||||
|
CREATE TABLE IF NOT EXISTS client_downloads (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
|
||||||
|
platform_type ENUM('mobile', 'desktop') NOT NULL COMMENT '平台类型:mobile-移动端, desktop-桌面端',
|
||||||
|
platform_name VARCHAR(50) NOT NULL COMMENT '具体平台:ios, android, windows, mac_intel, mac_m, linux',
|
||||||
|
version VARCHAR(50) NOT NULL COMMENT '版本号,如: 1.0.0',
|
||||||
|
version_code INT NOT NULL DEFAULT 1 COMMENT '版本代码,用于版本比较',
|
||||||
|
download_url TEXT NOT NULL COMMENT '下载链接',
|
||||||
|
file_size BIGINT COMMENT '文件大小(字节)',
|
||||||
|
release_notes TEXT COMMENT '更新说明',
|
||||||
|
is_active BOOLEAN DEFAULT TRUE COMMENT '是否启用',
|
||||||
|
is_latest BOOLEAN DEFAULT FALSE COMMENT '是否为最新版本',
|
||||||
|
min_system_version VARCHAR(50) COMMENT '最低系统版本要求',
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
created_by INT COMMENT '创建人ID',
|
||||||
|
FOREIGN KEY (created_by) REFERENCES users(user_id) ON DELETE SET NULL,
|
||||||
|
INDEX idx_platform (platform_type, platform_name),
|
||||||
|
INDEX idx_version (version_code),
|
||||||
|
INDEX idx_active (is_active, is_latest)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='客户端下载管理表';
|
||||||
|
|
||||||
|
-- 插入初始数据(示例版本)
|
||||||
|
INSERT INTO client_downloads (
|
||||||
|
platform_type,
|
||||||
|
platform_name,
|
||||||
|
version,
|
||||||
|
version_code,
|
||||||
|
download_url,
|
||||||
|
file_size,
|
||||||
|
release_notes,
|
||||||
|
is_active,
|
||||||
|
is_latest,
|
||||||
|
min_system_version,
|
||||||
|
created_by
|
||||||
|
) VALUES
|
||||||
|
-- iOS 客户端
|
||||||
|
(
|
||||||
|
'mobile',
|
||||||
|
'ios',
|
||||||
|
'1.0.0',
|
||||||
|
1000,
|
||||||
|
'https://apps.apple.com/app/imeeting/id123456789',
|
||||||
|
52428800, -- 50MB
|
||||||
|
'初始版本发布
|
||||||
|
- 支持会议录音
|
||||||
|
- 支持实时转录
|
||||||
|
- 支持会议摘要查看',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
'iOS 13.0',
|
||||||
|
1
|
||||||
|
),
|
||||||
|
|
||||||
|
-- Android 客户端
|
||||||
|
(
|
||||||
|
'mobile',
|
||||||
|
'android',
|
||||||
|
'1.0.0',
|
||||||
|
1000,
|
||||||
|
'https://play.google.com/store/apps/details?id=com.imeeting.app',
|
||||||
|
45088768, -- 43MB
|
||||||
|
'初始版本发布
|
||||||
|
- 支持会议录音
|
||||||
|
- 支持实时转录
|
||||||
|
- 支持会议摘要查看',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
'Android 8.0',
|
||||||
|
1
|
||||||
|
),
|
||||||
|
|
||||||
|
-- Windows 客户端
|
||||||
|
(
|
||||||
|
'desktop',
|
||||||
|
'windows',
|
||||||
|
'1.0.0',
|
||||||
|
1000,
|
||||||
|
'https://download.imeeting.com/clients/windows/iMeeting-1.0.0-Setup.exe',
|
||||||
|
104857600, -- 100MB
|
||||||
|
'初始版本发布
|
||||||
|
- 完整的会议管理功能
|
||||||
|
- 高清音频录制
|
||||||
|
- AI智能转录
|
||||||
|
- 知识库管理',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
'Windows 10 (64-bit)',
|
||||||
|
1
|
||||||
|
),
|
||||||
|
|
||||||
|
-- Mac Intel 客户端
|
||||||
|
(
|
||||||
|
'desktop',
|
||||||
|
'mac_intel',
|
||||||
|
'1.0.0',
|
||||||
|
1000,
|
||||||
|
'https://download.imeeting.com/clients/mac/iMeeting-1.0.0-Intel.dmg',
|
||||||
|
94371840, -- 90MB
|
||||||
|
'初始版本发布
|
||||||
|
- 完整的会议管理功能
|
||||||
|
- 高清音频录制
|
||||||
|
- AI智能转录
|
||||||
|
- 知识库管理',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
'macOS 10.15 Catalina',
|
||||||
|
1
|
||||||
|
),
|
||||||
|
|
||||||
|
-- Mac M系列 客户端
|
||||||
|
(
|
||||||
|
'desktop',
|
||||||
|
'mac_m',
|
||||||
|
'1.0.0',
|
||||||
|
1000,
|
||||||
|
'https://download.imeeting.com/clients/mac/iMeeting-1.0.0-AppleSilicon.dmg',
|
||||||
|
83886080, -- 80MB
|
||||||
|
'初始版本发布
|
||||||
|
- 完整的会议管理功能
|
||||||
|
- 高清音频录制
|
||||||
|
- AI智能转录
|
||||||
|
- 知识库管理
|
||||||
|
- 原生支持Apple Silicon',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
'macOS 11.0 Big Sur',
|
||||||
|
1
|
||||||
|
),
|
||||||
|
|
||||||
|
-- Linux 客户端
|
||||||
|
(
|
||||||
|
'desktop',
|
||||||
|
'linux',
|
||||||
|
'1.0.0',
|
||||||
|
1000,
|
||||||
|
'https://download.imeeting.com/clients/linux/iMeeting-1.0.0-x64.AppImage',
|
||||||
|
98566144, -- 94MB
|
||||||
|
'初始版本发布
|
||||||
|
- 完整的会议管理功能
|
||||||
|
- 高清音频录制
|
||||||
|
- AI智能转录
|
||||||
|
- 知识库管理
|
||||||
|
- 支持主流Linux发行版',
|
||||||
|
TRUE,
|
||||||
|
TRUE,
|
||||||
|
'Ubuntu 20.04 / Debian 10 / Fedora 32 或更高版本',
|
||||||
|
1
|
||||||
|
);
|
||||||
Loading…
Reference in New Issue