diff --git a/.gitignore b/.gitignore
index 73b8e09..7ae43d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,4 +34,5 @@ Thumbs.db
*.asar
-data/
\ No newline at end of file
+data/
+service/
\ No newline at end of file
diff --git a/README.md b/README.md
index bca3842..809a1e4 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
- 轻松管理 PHP、MySQL、Nginx、Redis 等服务,告别繁琐的手动配置
+ 轻松管理 PHP、MySQL、Nginx、Redis、Node.js、Python 等服务,告别繁琐的手动配置
@@ -26,11 +26,35 @@
 |
-  |
+  |
- | 仪表盘 |
- PHP 版本管理 |
+ 🏠 仪表盘 |
+ 🐘 PHP 版本管理 |
+
+
+  |
+  |
+
+
+ | 🐬 MySQL 管理 |
+ 🌐 Nginx 管理 |
+
+
+  |
+  |
+
+
+ | 🔴 Redis 管理 |
+ 💚 Node.js 管理 |
+
+
+  |
+  |
+
+
+ | 🐍 Python 管理 |
+ ⚙️ 设置 |
@@ -42,39 +66,72 @@
| ---------- | ---------------------------------------------------------- |
| 多版本管理 | 支持同时安装 PHP 8.1、8.2、8.3、8.4、8.5 等多个版本 |
| 一键切换 | 点击即可切换 PHP 版本,自动配置系统环境变量 |
-| 扩展管理 | 可视化管理 PHP 扩展,一键启用/禁用 |
+| 扩展管理 | 可视化管理 PHP 扩展,支持在线安装(从 PECL) |
| 配置编辑 | 在线编辑 php.ini,无需手动查找配置文件 |
| 自动配置 | 安装时自动启用常用扩展(curl、gd、mbstring、pdo_mysql 等) |
+| Composer | 集成 Composer 管理,支持镜像源切换(阿里云、腾讯云等) |
+| 下载源 | 从 [windows.php.net](https://windows.php.net) 官方下载 |
### 🐬 MySQL 管理
-| 功能 | 说明 |
-| ---------- | -------------------------------- |
-| 版本支持 | 支持 MySQL 5.7.x 和 8.0.x 系列 |
-| 服务控制 | 启动、停止、重启 MySQL 服务 |
-| 密码管理 | 一键修改 root 密码 |
-| 配置编辑 | 在线编辑 my.ini 配置文件 |
-| 自动初始化 | 安装时自动初始化数据库,开箱即用 |
+| 功能 | 说明 |
+| ---------- | -------------------------------------------------------------------- |
+| 版本支持 | 支持 MySQL 5.7.x 和 8.0.x 系列 |
+| 服务控制 | 启动、停止、重启 MySQL 服务 |
+| 密码管理 | 一键修改 root 密码 |
+| 配置编辑 | 在线编辑 my.ini 配置文件 |
+| 自动初始化 | 安装时自动初始化数据库,开箱即用 |
+| 下载源 | 从[阿里云镜像站](https://mirrors.aliyun.com/mysql/)下载,速度更快 |
### 🌐 Nginx 管理
-| 功能 | 说明 |
-| ------------ | ------------------------------------ |
-| 版本管理 | 支持多个 Nginx 版本,可随时切换 |
-| 服务控制 | 启动、停止、重启、热重载配置 |
-| 站点管理 | 可视化添加、删除、启用、禁用虚拟主机 |
-| Laravel 支持 | 自动生成 Laravel 项目的伪静态配置 |
-| SSL 证书 | 支持申请 Let's Encrypt 免费 SSL 证书 |
-| 配置编辑 | 在线编辑 nginx.conf 主配置文件 |
+| 功能 | 说明 |
+| ------------ | --------------------------------------------- |
+| 版本管理 | 支持多个 Nginx 版本,可随时切换 |
+| 服务控制 | 启动、停止、重启、热重载配置 |
+| 站点管理 | 可视化添加、删除、启用、禁用虚拟主机 |
+| Laravel 支持 | 自动生成 Laravel 项目的伪静态配置 |
+| SSL 证书 | 支持申请 Let's Encrypt 免费 SSL 证书 |
+| 配置编辑 | 在线编辑 nginx.conf 主配置文件 |
+| 下载源 | 从 [nginx.org](https://nginx.org) 官方下载 |
### 🔴 Redis 管理
-| 功能 | 说明 |
-| ------------ | -------------------------------- |
-| Windows 版本 | 使用 Windows 原生编译版 Redis |
-| 服务控制 | 启动、停止、重启 Redis 服务 |
-| 状态监控 | 实时查看运行状态、内存使用情况 |
-| 配置编辑 | 在线编辑 redis.windows.conf 配置 |
+| 功能 | 说明 |
+| ------------ | -------------------------------------------------------------------------- |
+| Windows 版本 | 使用 Windows 原生编译版 Redis |
+| 服务控制 | 启动、停止、重启 Redis 服务 |
+| 状态监控 | 实时查看运行状态、内存使用情况 |
+| 配置编辑 | 在线编辑 redis.windows.conf 配置 |
+| 下载源 | 从 [GitHub (redis-windows)](https://github.com/redis-windows/redis-windows) 下载 |
+
+### 💚 Node.js 管理
+
+| 功能 | 说明 |
+| ---------- | -------------------------------------------------------- |
+| 多版本管理 | 支持同时安装多个 Node.js 版本 |
+| LTS 支持 | 显示 LTS 版本和 Current 版本标识 |
+| npm 集成 | 自动显示对应的 npm 版本 |
+| 一键切换 | 快速切换默认 Node.js 版本,自动配置环境变量 |
+| 下载源 | 从 [nodejs.org](https://nodejs.org) 官方下载 |
+
+### 🐍 Python 管理
+
+| 功能 | 说明 |
+| ---------- | -------------------------------------------------------- |
+| 嵌入式版本 | 使用免安装的嵌入式版本,不影响系统环境 |
+| pip 集成 | 自动配置 pip,支持安装 Python 包 |
+| 多版本管理 | 支持同时安装多个 Python 版本 |
+| 一键切换 | 快速切换默认 Python 版本 |
+| 下载源 | 从 [python.org](https://www.python.org) 官方下载 |
+
+### 🔧 Git 管理
+
+| 功能 | 说明 |
+| ---------- | ------------------------------ |
+| 版本管理 | 一键安装/卸载 Git for Windows |
+| 配置管理 | 可视化配置用户名、邮箱等信息 |
+| 环境变量 | 自动配置系统 PATH |
### 🌍 站点管理
@@ -89,6 +146,8 @@
- 📋 **Hosts 管理** - 可视化管理系统 hosts 文件
- 🌙 **深色/浅色主题** - 支持主题切换
- 📊 **服务状态监控** - 实时显示各服务运行状态
+- ⏳ **加载状态提示** - 版本列表加载时显示 Loading 状态
+- 📥 **下载源说明** - 清晰显示各软件的下载来源
## 🛠️ 技术栈
@@ -146,6 +205,9 @@ phper/
│ ├── MysqlManager.ts # MySQL 服务管理器
│ ├── NginxManager.ts # Nginx 服务管理器
│ ├── RedisManager.ts # Redis 服务管理器
+│ ├── NodeManager.ts # Node.js 版本管理器
+│ ├── PythonManager.ts # Python 版本管理器
+│ ├── GitManager.ts # Git 管理器
│ ├── ServiceManager.ts # 开机自启服务管理器
│ └── HostsManager.ts # Hosts 文件管理器
│
@@ -163,6 +225,9 @@ phper/
│ ├── MysqlManager.vue # MySQL 管理
│ ├── NginxManager.vue # Nginx 管理
│ ├── RedisManager.vue # Redis 管理
+│ ├── NodeManager.vue # Node.js 管理
+│ ├── PythonManager.vue # Python 管理
+│ ├── GitManager.vue # Git 管理
│ ├── SitesManager.vue # 站点管理
│ ├── HostsManager.vue # Hosts 管理
│ └── Settings.vue # 设置
@@ -246,10 +311,15 @@ A: 进入对应服务管理页面,先停止服务,然后点击"卸载"按钮
## 🔗 相关资源
-- [PHP for Windows](https://windows.php.net/download/) - PHP Windows 官方下载
-- [MySQL Downloads](https://dev.mysql.com/downloads/) - MySQL 官方下载
-- [Nginx](https://nginx.org/) - Nginx 官方网站
-- [Redis for Windows](https://github.com/redis-windows/redis-windows) - Windows 版 Redis
+| 软件 | 下载源 |
+| ------- | ---------------------------------------------------------------------- |
+| PHP | [windows.php.net](https://windows.php.net/download/) - 官方 Windows 版 |
+| MySQL | [阿里云镜像](https://mirrors.aliyun.com/mysql/) - 国内高速下载 |
+| Nginx | [nginx.org](https://nginx.org/en/download.html) - 官方 Windows 版 |
+| Redis | [GitHub redis-windows](https://github.com/redis-windows/redis-windows) |
+| Node.js | [nodejs.org](https://nodejs.org/en/download/) - 官方下载 |
+| Python | [python.org](https://www.python.org/downloads/windows/) - 嵌入式版本 |
+| Git | [git-scm.com](https://git-scm.com/download/win) - 官方 Windows 版 |
## 📄 开源协议
diff --git a/docs/dashboard.png b/docs/dashboard.png
new file mode 100644
index 0000000..1ecacf7
Binary files /dev/null and b/docs/dashboard.png differ
diff --git a/docs/mysql.png b/docs/mysql.png
new file mode 100644
index 0000000..2a5d115
Binary files /dev/null and b/docs/mysql.png differ
diff --git a/docs/nginx.png b/docs/nginx.png
new file mode 100644
index 0000000..3fd2b13
Binary files /dev/null and b/docs/nginx.png differ
diff --git a/docs/nodejs.png b/docs/nodejs.png
new file mode 100644
index 0000000..71c0890
Binary files /dev/null and b/docs/nodejs.png differ
diff --git a/docs/php.png b/docs/php.png
new file mode 100644
index 0000000..6d4c7bb
Binary files /dev/null and b/docs/php.png differ
diff --git a/docs/python.png b/docs/python.png
new file mode 100644
index 0000000..f8df66c
Binary files /dev/null and b/docs/python.png differ
diff --git a/docs/redis.png b/docs/redis.png
new file mode 100644
index 0000000..78006f9
Binary files /dev/null and b/docs/redis.png differ
diff --git a/docs/setting.png b/docs/setting.png
new file mode 100644
index 0000000..5b88e16
Binary files /dev/null and b/docs/setting.png differ
diff --git a/electron/services/ConfigStore.ts b/electron/services/ConfigStore.ts
index b2329ba..b914514 100644
--- a/electron/services/ConfigStore.ts
+++ b/electron/services/ConfigStore.ts
@@ -9,7 +9,9 @@ interface ConfigSchema {
mysqlVersions: string[];
nginxVersions: string[];
redisVersions: string[];
+ nodeVersions: string[];
activePhpVersion: string;
+ activeNodeVersion: string;
autoStart: {
nginx: boolean;
mysql: boolean;
@@ -63,7 +65,9 @@ export class ConfigStore {
mysqlVersions: [],
nginxVersions: [],
redisVersions: [],
+ nodeVersions: [],
activePhpVersion: "",
+ activeNodeVersion: "",
autoStart: {
nginx: false,
mysql: false,
diff --git a/electron/services/NginxManager.ts b/electron/services/NginxManager.ts
index 53b8c0c..ce865bc 100644
--- a/electron/services/NginxManager.ts
+++ b/electron/services/NginxManager.ts
@@ -28,6 +28,8 @@ interface NginxStatus {
export class NginxManager {
private configStore: ConfigStore
+ private versionCache: { versions: AvailableNginxVersion[]; timestamp: number } | null = null
+ private readonly CACHE_TTL = 5 * 60 * 1000 // 5分钟缓存
constructor(configStore: ConfigStore) {
this.configStore = configStore
@@ -88,9 +90,109 @@ export class NginxManager {
/**
* 获取可用的 Nginx 版本列表
+ * 动态从 nginx.org 获取
*/
async getAvailableVersions(): Promise {
- const versions: AvailableNginxVersion[] = [
+ // 检查缓存
+ if (this.versionCache && (Date.now() - this.versionCache.timestamp) < this.CACHE_TTL) {
+ console.log('使用缓存的 Nginx 版本列表')
+ return this.versionCache.versions
+ }
+
+ let versions: AvailableNginxVersion[] = []
+
+ try {
+ console.log('从 nginx.org 获取版本列表...')
+ versions = await this.fetchNginxVersions()
+ console.log(`从 nginx.org 获取到 ${versions.length} 个 Nginx 版本`)
+ } catch (error: any) {
+ console.error('从 nginx.org 获取 Nginx 版本失败:', error.message)
+ }
+
+ // 如果获取失败或为空,使用备用列表
+ if (versions.length === 0) {
+ console.log('使用备用 Nginx 版本列表')
+ versions = this.getFallbackVersions()
+ }
+
+ // 更新缓存
+ this.versionCache = { versions, timestamp: Date.now() }
+
+ return versions
+ }
+
+ /**
+ * 从 nginx.org 下载页面获取版本列表
+ */
+ private async fetchNginxVersions(): Promise {
+ return new Promise((resolve, reject) => {
+ const options = {
+ hostname: 'nginx.org',
+ path: '/download/',
+ method: 'GET',
+ headers: {
+ 'User-Agent': 'PHPer-Dev-Manager'
+ },
+ timeout: 15000
+ }
+
+ const request = http.request(options, (response) => {
+ let data = ''
+ response.on('data', chunk => data += chunk)
+ response.on('end', () => {
+ try {
+ const versions: AvailableNginxVersion[] = []
+ // 解析 HTML 页面中的 Windows 版本链接
+ // 格式: nginx-1.27.3.zip
+ const regex = /href="\/download\/nginx-(\d+\.\d+\.\d+)\.zip"/g
+ let match
+ const seen = new Set()
+
+ while ((match = regex.exec(data)) !== null) {
+ const version = match[1]
+ if (!seen.has(version)) {
+ seen.add(version)
+ versions.push({
+ version,
+ downloadUrl: `https://nginx.org/download/nginx-${version}.zip`
+ })
+ }
+ }
+
+ // 按版本号排序(降序)
+ versions.sort((a, b) => {
+ const aParts = a.version.split('.').map(Number)
+ const bParts = b.version.split('.').map(Number)
+ for (let i = 0; i < 3; i++) {
+ if (aParts[i] !== bParts[i]) {
+ return bParts[i] - aParts[i]
+ }
+ }
+ return 0
+ })
+
+ // 只返回前 10 个版本
+ resolve(versions.slice(0, 10))
+ } catch (e) {
+ reject(e)
+ }
+ })
+ })
+
+ request.on('error', reject)
+ request.on('timeout', () => {
+ request.destroy()
+ reject(new Error('请求超时'))
+ })
+ request.end()
+ })
+ }
+
+ /**
+ * 备用版本列表
+ */
+ private getFallbackVersions(): AvailableNginxVersion[] {
+ return [
{
version: '1.27.3',
downloadUrl: 'https://nginx.org/download/nginx-1.27.3.zip'
@@ -108,8 +210,6 @@ export class NginxManager {
downloadUrl: 'https://nginx.org/download/nginx-1.24.0.zip'
}
]
-
- return versions
}
/**
diff --git a/electron/services/PythonManager.ts b/electron/services/PythonManager.ts
index f0e363f..bc3dff7 100644
--- a/electron/services/PythonManager.ts
+++ b/electron/services/PythonManager.ts
@@ -24,6 +24,8 @@ interface AvailablePythonVersion {
export class PythonManager {
private configStore: ConfigStore
+ private versionCache: { versions: AvailablePythonVersion[]; timestamp: number } | null = null
+ private readonly CACHE_TTL = 5 * 60 * 1000 // 5分钟缓存
constructor(configStore: ConfigStore) {
this.configStore = configStore
@@ -56,7 +58,7 @@ export class PythonManager {
}
const dirs = readdirSync(pythonBasePath, { withFileTypes: true })
-
+
for (const dir of dirs) {
if (dir.isDirectory() && dir.name.startsWith('python-')) {
const version = dir.name.replace('python-', '')
@@ -78,12 +80,131 @@ export class PythonManager {
/**
* 获取可用的 Python 版本列表
- * 使用 Python 嵌入式版本(免安装)
+ * 动态从 python.org 获取 Windows 嵌入式版本
*/
async getAvailableVersions(): Promise {
- // Python 嵌入式版本下载地址
- // https://www.python.org/downloads/windows/
- const versions: AvailablePythonVersion[] = [
+ // 检查缓存
+ if (this.versionCache && (Date.now() - this.versionCache.timestamp) < this.CACHE_TTL) {
+ console.log('使用缓存的 Python 版本列表')
+ // 过滤掉已安装的版本
+ const installed = await this.getInstalledVersions()
+ const installedVersions = installed.map(v => v.version)
+ return this.versionCache.versions.filter(v => !installedVersions.includes(v.version))
+ }
+
+ let versions: AvailablePythonVersion[] = []
+
+ try {
+ console.log('从 python.org 获取版本列表...')
+ versions = await this.fetchPythonVersions()
+ console.log(`从 python.org 获取到 ${versions.length} 个 Python 版本`)
+ } catch (error: any) {
+ console.error('从 python.org 获取 Python 版本失败:', error.message)
+ }
+
+ // 如果获取失败或为空,使用备用列表
+ if (versions.length === 0) {
+ console.log('使用备用 Python 版本列表')
+ versions = this.getFallbackVersions()
+ }
+
+ // 更新缓存
+ this.versionCache = { versions, timestamp: Date.now() }
+
+ // 过滤掉已安装的版本
+ const installed = await this.getInstalledVersions()
+ const installedVersions = installed.map(v => v.version)
+
+ return versions.filter(v => !installedVersions.includes(v.version))
+ }
+
+ /**
+ * 从 python.org API 获取版本列表
+ */
+ private async fetchPythonVersions(): Promise {
+ return new Promise((resolve, reject) => {
+ const options = {
+ hostname: 'www.python.org',
+ path: '/api/v2/downloads/release/?is_published=true&pre_release=false&page_size=50',
+ method: 'GET',
+ headers: {
+ 'User-Agent': 'PHPer-Dev-Manager',
+ 'Accept': 'application/json'
+ },
+ timeout: 15000
+ }
+
+ const request = https.request(options, (response) => {
+ let data = ''
+ response.on('data', chunk => data += chunk)
+ response.on('end', () => {
+ try {
+ const json = JSON.parse(data)
+ const versions: AvailablePythonVersion[] = []
+ const seen = new Set()
+
+ if (json.results && Array.isArray(json.results)) {
+ for (const release of json.results) {
+ // 解析版本号,如 "Python 3.13.1"
+ const match = release.name?.match(/Python (\d+\.\d+\.\d+)/)
+ if (match) {
+ const version = match[1]
+ // 只获取 Python 3.8+ 版本
+ const majorMinor = version.split('.').slice(0, 2).map(Number)
+ if (majorMinor[0] >= 3 && majorMinor[1] >= 8 && !seen.has(version)) {
+ seen.add(version)
+ versions.push({
+ version,
+ downloadUrl: `https://www.python.org/ftp/python/${version}/python-${version}-embed-amd64.zip`,
+ type: 'embed'
+ })
+ }
+ }
+ }
+ }
+
+ // 按版本号排序(降序)
+ versions.sort((a, b) => {
+ const aParts = a.version.split('.').map(Number)
+ const bParts = b.version.split('.').map(Number)
+ for (let i = 0; i < 3; i++) {
+ if (aParts[i] !== bParts[i]) {
+ return bParts[i] - aParts[i]
+ }
+ }
+ return 0
+ })
+
+ // 每个主版本只保留最新的一个
+ const latestByMajorMinor = new Map()
+ for (const v of versions) {
+ const majorMinor = v.version.split('.').slice(0, 2).join('.')
+ if (!latestByMajorMinor.has(majorMinor)) {
+ latestByMajorMinor.set(majorMinor, v)
+ }
+ }
+
+ resolve(Array.from(latestByMajorMinor.values()))
+ } catch (e) {
+ reject(e)
+ }
+ })
+ })
+
+ request.on('error', reject)
+ request.on('timeout', () => {
+ request.destroy()
+ reject(new Error('请求超时'))
+ })
+ request.end()
+ })
+ }
+
+ /**
+ * 备用版本列表
+ */
+ private getFallbackVersions(): AvailablePythonVersion[] {
+ return [
{
version: '3.13.1',
downloadUrl: 'https://www.python.org/ftp/python/3.13.1/python-3.13.1-embed-amd64.zip',
@@ -110,12 +231,6 @@ export class PythonManager {
type: 'embed'
}
]
-
- // 过滤掉已安装的版本
- const installed = await this.getInstalledVersions()
- const installedVersions = installed.map(v => v.version)
-
- return versions.filter(v => !installedVersions.includes(v.version))
}
/**
@@ -324,7 +439,7 @@ export class PythonManager {
// 修改 python*._pth 文件以启用 pip
const majorMinor = version.split('.').slice(0, 2).join('')
const pthFile = join(pythonPath, `python${majorMinor}._pth`)
-
+
if (existsSync(pthFile)) {
const { readFileSync } = require('fs')
let content = readFileSync(pthFile, 'utf-8')
diff --git a/src/views/Dashboard.vue b/src/views/Dashboard.vue
index ad3e2e9..3a4a3a8 100644
--- a/src/views/Dashboard.vue
+++ b/src/views/Dashboard.vue
@@ -376,8 +376,6 @@ const startService = async (service: Service) => {
} else {
ElMessage.error(result?.message || '启动失败')
}
- // 同步刷新全局状态
- await store.refreshServiceStatus()
} catch (error: any) {
ElMessage.error(error.message)
} finally {
@@ -396,8 +394,6 @@ const startPhpCgi = async (service: Service) => {
} else {
ElMessage.error(result?.message || '启动失败')
}
- // 同步刷新全局状态
- await store.refreshServiceStatus()
} catch (error: any) {
ElMessage.error(error.message)
} finally {
@@ -426,8 +422,6 @@ const stopService = async (service: Service) => {
} else {
ElMessage.error(result?.message || '停止失败')
}
- // 同步刷新全局状态
- await store.refreshServiceStatus()
} catch (error: any) {
ElMessage.error(error.message)
} finally {
@@ -446,8 +440,6 @@ const stopPhpCgi = async (service: Service) => {
} else {
ElMessage.error(result?.message || '停止失败')
}
- // 同步刷新全局状态
- await store.refreshServiceStatus()
} catch (error: any) {
ElMessage.error(error.message)
} finally {
@@ -475,8 +467,6 @@ const restartService = async (service: Service) => {
} else {
ElMessage.error(result?.message || '重启失败')
}
- // 同步刷新全局状态
- await store.refreshServiceStatus()
} catch (error: any) {
ElMessage.error(error.message)
} finally {
@@ -498,8 +488,6 @@ const restartPhpCgi = async (service: Service) => {
} else {
ElMessage.error(result?.message || '重启失败')
}
- // 同步刷新全局状态
- await store.refreshServiceStatus()
} catch (error: any) {
ElMessage.error(error.message)
} finally {
@@ -513,8 +501,8 @@ const startAllPhpCgi = async () => {
const result = await window.electronAPI?.service.startAllPhpCgi()
if (result?.success) {
ElMessage.success('全部 PHP-CGI 已启动')
- // 刷新全局状态
- await store.refreshServiceStatus()
+ // 更新所有 PHP-CGI 状态为运行中
+ store.serviceStatus.phpCgi.forEach(p => p.running = true)
} else {
ElMessage.error(result?.message || '启动失败')
}
@@ -529,8 +517,8 @@ const stopAllPhpCgi = async () => {
const result = await window.electronAPI?.service.stopAllPhpCgi()
if (result?.success) {
ElMessage.success('全部 PHP-CGI 已停止')
- // 刷新全局状态
- await store.refreshServiceStatus()
+ // 更新所有 PHP-CGI 状态为已停止
+ store.serviceStatus.phpCgi.forEach(p => p.running = false)
} else {
ElMessage.error(result?.message || '停止失败')
}
@@ -581,11 +569,9 @@ const setActiveNode = async (version: string) => {
}
}
-onMounted(() => {
- // 如果 store 未初始化,则刷新
- if (!store.lastUpdated) {
- store.refreshAll()
- }
+onMounted(async () => {
+ // 总是刷新数据以确保数据最新
+ await store.refreshAll()
})
diff --git a/src/views/MysqlManager.vue b/src/views/MysqlManager.vue
index c94c197..199a8d2 100644
--- a/src/views/MysqlManager.vue
+++ b/src/views/MysqlManager.vue
@@ -113,11 +113,19 @@
>
- 安装说明
+
+ 下载源说明
- MySQL 将从阿里云镜像站下载,安装后自动设置 root 密码为 123456。
+ MySQL 将从 阿里云镜像站 下载,速度较快。安装后 root 密码默认为 123456。
-
+
+
+ 正在获取可用版本列表...
+
+
+ 暂无可用版本
+
+
+