-
{{ I18nT('host.OnlineDomain') }}
+
+
+
+
+
+ {{ I18nT('host.CloudflareTunnel.TunnelRule') }}
+
+
+
+
+
+
+
+ {{ scope.row.subdomain }}.{{ scope.row.zoneName }}
+
+
+ {{ scope.row.subdomain }}.{{ scope.row.zoneName }}
+
+
+
+
+
+
+ {{
+ scope.row.localService
+ }}
+
+
+ {{ scope.row.localService }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ I18nT('base.edit') }}
+
+
+
+
+
+
+
+ {{ I18nT('base.del') }}
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- {{ scope.row.subdomain }}.{{ scope.row.zoneName }}
-
-
- {{ scope.row.subdomain }}.{{ scope.row.zoneName }}
-
-
+ {{ scope.row.apiToken }}
-
+
-
- {{
- scope.row.localService
- }}
-
-
- {{ scope.row.localService }}
-
+ {{ scope.row.tunnelName }}
@@ -84,34 +158,43 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ I18nT('base.edit') }}
+
+
+
+
+
+
+
+ {{ I18nT('base.info') }}
+
+
+
+
+
+
+
+ {{ I18nT('base.del') }}
+
+
+
+
+
+
+
@@ -124,10 +207,24 @@
import { Setup } from './setup'
import { AppStore } from '@/store/app'
import { CloudflareTunnel } from '@/core/CloudflareTunnel/CloudflareTunnel'
+ import { CloudflareTunnelDnsRecord } from '@/core/CloudflareTunnel/type'
const appStore = AppStore()
- const { add, edit, del, info, list, openOutUrl, openLocalUrl, groupTrunOn } = Setup()
+ const {
+ add,
+ edit,
+ del,
+ info,
+ list,
+ openOutUrl,
+ openLocalUrl,
+ groupTrunOn,
+ copy,
+ editDNS,
+ delDNS,
+ addDNS
+ } = Setup()
const action = (item: CloudflareTunnel, index: number, flag: string) => {
switch (flag) {
@@ -142,4 +239,27 @@
break
}
}
+
+ const dnsAction = (
+ item: CloudflareTunnel,
+ dns: CloudflareTunnelDnsRecord,
+ index: number,
+ flag: string
+ ) => {
+ switch (flag) {
+ case 'edit':
+ editDNS(item, dns, index)
+ break
+ case 'del':
+ delDNS(item, dns, index)
+ break
+ }
+ }
+
diff --git a/src/render/components/CloudflareTunnel/add.vue b/src/render/components/CloudflareTunnel/add.vue
index 17379c94a..61351529e 100644
--- a/src/render/components/CloudflareTunnel/add.vue
+++ b/src/render/components/CloudflareTunnel/add.vue
@@ -4,6 +4,8 @@
:title="'Cloudflare Tunnel' + ' ' + I18nT('base.add')"
class="el-dialog-content-flex-1 h-[75%] dark:bg-[#1d2033]"
width="600px"
+ :close-on-click-modal="false"
+ :close-on-press-escape="false"
@closed="closedFn"
>
@@ -51,10 +53,14 @@
@@ -73,6 +79,7 @@
import { reactiveBind, uuid } from '@/util/Index'
import CloudflareTunnelStore from '@/core/CloudflareTunnel/CloudflareTunnelStore'
import { BrewStore } from '@/store/brew'
+ import { MessageError } from '@/util/Element'
const brewStore = BrewStore()
@@ -80,6 +87,8 @@
const formRef = ref()
+ const loading = ref(false)
+
const zones = ref
([])
const form = ref({
@@ -189,7 +198,11 @@
return ''
}
const domain = `${form.value.subdomain}.${form.value.zoneName}`
- const all = CloudflareTunnelStore.items.map((item) => `${item.subdomain}.${item.zoneName}`)
+ const all = CloudflareTunnelStore.items
+ .map((item) => {
+ return item.dns.map((d) => `${d.subdomain}.${d.zoneName}`)
+ })
+ .flat()
if (all.includes(domain)) {
return I18nT('host.CloudflareTunnel.OnlineDomainExistsTips')
}
@@ -201,11 +214,39 @@
}
const doSubmit = async () => {
- const item = reactiveBind(new CloudflareTunnel(form.value))
+ if (loading.value) {
+ return
+ }
+ loading.value = true
+ const obj: any = {
+ apiToken: form.value.apiToken,
+ cloudflaredBin: form.value.cloudflaredBin,
+ accountId: form.value.accountId,
+
+ dns: [
+ {
+ id: uuid(),
+ subdomain: form.value.subdomain,
+ localService: form.value.localService,
+ zoneId: form.value.zoneId,
+ zoneName: form.value.zoneName
+ }
+ ]
+ }
+ const item = reactiveBind(new CloudflareTunnel(obj))
item.id = uuid()
- CloudflareTunnelStore.items.unshift(item)
- CloudflareTunnelStore.save()
- onCancel()
+ item
+ .fetchTunnel()
+ .then(() => {
+ CloudflareTunnelStore.items.unshift(item)
+ CloudflareTunnelStore.save()
+ loading.value = false
+ onCancel()
+ })
+ .catch((error) => {
+ MessageError(I18nT('host.CloudflareTunnel.TunnelInitFailTips', { error }))
+ loading.value = false
+ })
}
defineExpose({
diff --git a/src/render/components/CloudflareTunnel/addDNS.vue b/src/render/components/CloudflareTunnel/addDNS.vue
new file mode 100644
index 000000000..c94862e73
--- /dev/null
+++ b/src/render/components/CloudflareTunnel/addDNS.vue
@@ -0,0 +1,209 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/render/components/CloudflareTunnel/edit.vue b/src/render/components/CloudflareTunnel/edit.vue
index c6c98e449..b6b86de85 100644
--- a/src/render/components/CloudflareTunnel/edit.vue
+++ b/src/render/components/CloudflareTunnel/edit.vue
@@ -2,12 +2,16 @@
+
+
+
+
@@ -15,38 +19,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -61,14 +33,9 @@
diff --git a/src/render/components/CloudflareTunnel/setup.ts b/src/render/components/CloudflareTunnel/setup.ts
index 9aa1050da..0f224fa12 100644
--- a/src/render/components/CloudflareTunnel/setup.ts
+++ b/src/render/components/CloudflareTunnel/setup.ts
@@ -3,7 +3,11 @@ import { computed, reactive } from 'vue'
import CloudflareTunnelStore from '@/core/CloudflareTunnel/CloudflareTunnelStore'
import { AppStore } from '@/store/app'
import { AsyncComponentShow } from '@/util/AsyncComponent'
-import type { ZoneType } from '@/core/CloudflareTunnel/type'
+import { CloudflareTunnelDnsRecord, ZoneType } from '@/core/CloudflareTunnel/type'
+import Base from '@/core/Base'
+import { I18nT } from '@lang/index'
+import { clipboard } from '@/util/NodeFn'
+import { MessageSuccess } from '@/util/Element'
export const ZoneDict: Record = reactive({})
@@ -30,13 +34,21 @@ export const Setup = () => {
function edit(item: CloudflareTunnel) {
AsyncComponentShow(EditVM, {
- item
+ item: JSON.parse(JSON.stringify(item))
}).then()
}
function info(item: CloudflareTunnel) {}
- function del(item: CloudflareTunnel, index: number) {}
+ function del(item: CloudflareTunnel, index: number) {
+ Base._Confirm(I18nT('base.areYouSure'), undefined, {
+ customClass: 'confirm-del',
+ type: 'warning'
+ }).then(() => {
+ CloudflareTunnelStore.items.splice(index, 1)
+ CloudflareTunnelStore.save()
+ })
+ }
const openOutUrl = (item: CloudflareTunnel) => {}
@@ -55,6 +67,49 @@ export const Setup = () => {
appStore.saveConfig().then().catch()
}
+ const copy = (str: string) => {
+ clipboard.writeText(str).then(() => {
+ MessageSuccess(I18nT('base.copySuccess'))
+ })
+ }
+
+ let EditDNSVM: any
+ import('./editDNS.vue').then((res) => {
+ EditDNSVM = res.default
+ })
+
+ const editDNS = (item: CloudflareTunnel, dns: CloudflareTunnelDnsRecord, index: number) => {
+ AsyncComponentShow(EditDNSVM, {
+ item: JSON.parse(JSON.stringify(item)),
+ dns: JSON.parse(JSON.stringify(dns)),
+ index
+ }).then()
+ }
+
+ const delDNS = (item: CloudflareTunnel, dns: CloudflareTunnelDnsRecord, index: number) => {
+ Base._Confirm(I18nT('base.areYouSure'), undefined, {
+ customClass: 'confirm-del',
+ type: 'warning'
+ }).then(() => {
+ const find = CloudflareTunnelStore.items.find((i) => i.id === item.id)
+ if (find) {
+ find.dns.splice(index, 1)
+ }
+ CloudflareTunnelStore.save()
+ })
+ }
+
+ let AddDNSVM: any
+ import('./addDNS.vue').then((res) => {
+ AddDNSVM = res.default
+ })
+
+ function addDNS(item: CloudflareTunnel) {
+ AsyncComponentShow(AddDNSVM, {
+ item: JSON.parse(JSON.stringify(item))
+ }).then()
+ }
+
return {
add,
edit,
@@ -63,6 +118,10 @@ export const Setup = () => {
list,
openOutUrl,
openLocalUrl,
- groupTrunOn
+ groupTrunOn,
+ copy,
+ editDNS,
+ delDNS,
+ addDNS
}
}
diff --git a/src/render/core/CloudflareTunnel/CloudflareTunnel.ts b/src/render/core/CloudflareTunnel/CloudflareTunnel.ts
index 88d05f5b4..833ef20c7 100644
--- a/src/render/core/CloudflareTunnel/CloudflareTunnel.ts
+++ b/src/render/core/CloudflareTunnel/CloudflareTunnel.ts
@@ -1,11 +1,13 @@
import IPC from '@/util/IPC'
-import { CloudflareTunnelDnsRecord, ZoneType } from '@/core/CloudflareTunnel/type'
+import { CloudflareTunnelDnsRecord } from '@/core/CloudflareTunnel/type'
import { I18nT } from '@lang/index'
import { MessageError } from '@/util/Element'
+import { md5 } from '@/util/Index'
export class CloudflareTunnel {
id: string = ''
apiToken: string = ''
+ tunnelName: string = ''
tunnelId: string = ''
tunnelToken: string = ''
cloudflaredBin: string = ''
@@ -22,17 +24,25 @@ export class CloudflareTunnel {
this.pid = ''
this.run = false
this.running = false
+ if (this.apiToken && !this.tunnelName) {
+ this.tunnelName = `FlyEnv-Tunnel-${md5(this.apiToken).substring(0, 12)}`
+ }
}
- /**
- * 获取所有的Zone
- */
- fetchAllZone(): Promise {
- return new Promise((resolve) => {
- IPC.send('app-fork:cloudflare-tunnel', 'fetchAllZone').then((key: string, res: any) => {
- IPC.off(key)
- resolve(res?.data ?? [])
- })
+ fetchTunnel(): Promise {
+ return new Promise((resolve, reject) => {
+ IPC.send('app-fork:cloudflare-tunnel', 'fetchTunnel', JSON.parse(JSON.stringify(this))).then(
+ (key: string, res: any) => {
+ IPC.off(key)
+ if (res?.data?.tunnelId && res?.data?.tunnelToken) {
+ this.tunnelId = res?.data?.tunnelToken
+ this.tunnelToken = res?.data?.tunnelToken
+ this.tunnelName = res?.data?.tunnelName
+ resolve(true)
+ }
+ reject(new Error(res?.msg ?? I18nT('base.fail')))
+ }
+ )
})
}
diff --git a/src/render/core/CloudflareTunnel/type.ts b/src/render/core/CloudflareTunnel/type.ts
index c89077b3d..b4c002c98 100644
--- a/src/render/core/CloudflareTunnel/type.ts
+++ b/src/render/core/CloudflareTunnel/type.ts
@@ -8,6 +8,7 @@ export type ZoneType = {
}
export type CloudflareTunnelDnsRecord = {
+ id: string
subdomain: string
localService: string
zoneId: string
From 0bc3750af7490e6fefdbb8914eb2cb9c62670349 Mon Sep 17 00:00:00 2001
From: KietNT <113796420+TanNhatCMS@users.noreply.github.com>
Date: Sun, 1 Mar 2026 20:50:18 +0700
Subject: [PATCH 08/16] =?UTF-8?q?=E2=9C=A8=20feat(lang):=20update=20Vietna?=
=?UTF-8?q?mese=20translations?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit updates Vietnamese translations for various strings across multiple files, improving the localization of the application.
---
src/lang/vi/nodejs.json | 2 +-
src/lang/vi/php.json | 50 +++++++++++++++++++--------------------
src/lang/vi/service.json | 26 ++++++++++----------
src/lang/vi/toolType.json | 2 +-
src/lang/vi/update.json | 4 ++--
src/lang/vi/util.json | 28 +++++++++++-----------
6 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/src/lang/vi/nodejs.json b/src/lang/vi/nodejs.json
index e5d50fb16..7343bd074 100644
--- a/src/lang/vi/nodejs.json
+++ b/src/lang/vi/nodejs.json
@@ -7,7 +7,7 @@
"updatePackageJsonFile": "Cập nhật tệp package.json",
"updatePackageJsonFileTips": "Hành động này sẽ thay đổi tệp package.json. Bạn có chắc chắn muốn cập nhật không?",
"copyDirPath": "Sao chép đường dẫn thư mục dự án",
- "openIN": "Mở bằng",
+ "openIN": "Mở trong",
"VSCode": "Visual Studio Code",
"PhpStorm": "PhpStorm",
"WebStorm": "WebStorm",
diff --git a/src/lang/vi/php.json b/src/lang/vi/php.json
index 45157e53d..b738abfb2 100644
--- a/src/lang/vi/php.json
+++ b/src/lang/vi/php.json
@@ -1,39 +1,39 @@
{
"phpiniNotFound": "Không tìm thấy tệp php.ini",
- "editPhpIni": "Chỉnh sửa php.ini",
- "phpExtensions": "Phần mở rộng PHP",
+ "editPhpIni": "Sửa php.ini",
+ "phpExtensions": "Tiện ích mở rộng PHP",
"copyConfTemplate": "Sao chép mẫu cấu hình",
- "extensionCopySuccess": "Liên kết mở rộng đã được sao chép vào bảng tạm",
- "xdebugConfCopySuccess": "Mẫu cấu hình xdebug đã được sao chép vào bảng tạm",
+ "extensionCopySuccess": "Đã sao chép liên kết tiện ích mở rộng vào khay nhớ tạm",
+ "xdebugConfCopySuccess": "Đã sao chép mẫu cấu hình xdebug vào khay nhớ tạm",
"fpmLog": "Nhật ký FPM",
- "extensions": "Phần mở rộng",
- "extension": "Phần mở rộng",
- "obfuscatorPhpVersion": "Làm rối với phiên bản PHP",
- "obfuscatorSrc": "Tệp hoặc thư mục PHP cần làm rối",
- "obfuscatorDesc": "Lưu tệp hoặc thư mục mà không sao chép lại tệp hoặc thư mục gốc",
+ "extensions": "Tiện ích mở rộng",
+ "extension": "Tiện ích mở rộng",
+ "obfuscatorPhpVersion": "Làm rối mã (Obfuscate) bằng phiên bản PHP",
+ "obfuscatorSrc": "Tệp hoặc thư mục PHP cần làm rối mã",
+ "obfuscatorDesc": "Lưu tệp hoặc thư mục, không được trùng với tệp hoặc thư mục gốc",
"obfuscatorConfig": "Cài đặt nâng cao",
- "quickStart": "Khởi động nhanh",
+ "quickStart": "Khởi động nhóm",
"display_errors": "Có xuất thông tin lỗi chi tiết hay không",
- "short_open_tag": "Hỗ trợ short tag",
- "file_uploads": "Có cho phép tải lên tệp hay không",
+ "short_open_tag": "Hỗ trợ thẻ ngắn (short tag)",
+ "file_uploads": "Có cho phép tải tệp lên hay không",
"fix_pathinfo": "Có bật pathinfo hay không",
- "max_execution_time": "Thời gian chạy tối đa của script",
- "max_input_time": "Thời gian nhập tối đa",
- "memory_limit": "Giới hạn bộ nhớ cho script",
+ "max_execution_time": "Thời gian chạy script tối đa",
+ "max_input_time": "Thời gian nhập (input) tối đa",
+ "memory_limit": "Giới hạn bộ nhớ của script",
"post_max_size": "Kích thước tối đa của dữ liệu POST",
- "upload_max_filesize": "Kích thước tối đa cho phép khi tải lên tệp",
- "max_file_uploads": "Số lượng tệp tối đa cho phép tải lên cùng lúc",
- "default_socket_timeout": "Thời gian chờ socket",
- "error_reporting": "Mức báo cáo lỗi",
+ "upload_max_filesize": "Kích thước tối đa cho phép khi tải tệp lên",
+ "max_file_uploads": "Số lượng tệp tối đa được phép tải lên đồng thời",
+ "default_socket_timeout": "Thời gian chờ (timeout) của socket",
+ "error_reporting": "Mức độ báo cáo lỗi",
"timezone": "Múi giờ",
- "loadedExtensions": "Các phần mở rộng đã tải",
+ "loadedExtensions": "Các tiện ích mở rộng đã tải",
"log_errors": "Bật ghi nhật ký lỗi",
"error_log_dir": "Chỉ định đường dẫn tệp nhật ký lỗi PHP",
"disableFunction": {
- "title": "Disable Functions",
- "function": "Function",
- "emptyFunction": "Please enter function name",
- "sameName": "Function already exists",
- "invalidName": "Invalid function name. Function name can only contain letters, numbers, and underscores"
+ "title": "Vô hiệu hóa hàm",
+ "function": "Hàm",
+ "emptyFunction": "Vui lòng nhập tên hàm",
+ "sameName": "Hàm đã tồn tại",
+ "invalidName": "Tên hàm không hợp lệ. Tên hàm chỉ có thể chứa chữ cái, số và dấu gạch dưới"
}
}
diff --git a/src/lang/vi/service.json b/src/lang/vi/service.json
index 5a1008ddc..2d62c1fbe 100644
--- a/src/lang/vi/service.json
+++ b/src/lang/vi/service.json
@@ -1,22 +1,22 @@
{
- "setaliase": "Đặt bí danh",
- "env": "Môi trường",
- "alias": "Bí danh",
+ "setaliase": "Thiết lập bí danh (Alias)",
+ "env": "Môi trường (Env)",
+ "alias": "Bí danh (Alias)",
"envTips": "Đường dẫn đã được thêm vào biến môi trường chưa",
- "aliasTips": "Bí danh sử dụng trong terminal",
+ "aliasTips": "Bí danh được sử dụng trong terminal",
"useSysPHP": "Sử dụng phiên bản PHP mặc định",
- "setByApp": "Biến môi trường được thiết lập bởi FlyEnv",
- "setByNoApp": "Biến môi trường không được thiết lập bởi FlyEnv",
- "ftpdNeedPasswordToStart": "Pure-FTPd cần quyền sudo để khởi động. Vui lòng nhập mật khẩu người dùng của bạn. Mật khẩu sẽ được dùng cho việc tự động điền sau này. Hoặc bạn có thể nhấp vào nút bên dưới để nhập thủ công trong terminal, nhưng thông báo này có thể xuất hiện lại.",
+ "setByApp": "Các biến môi trường được thiết lập bởi FlyEnv",
+ "setByNoApp": "Các biến môi trường không được thiết lập bởi FlyEnv",
+ "ftpdNeedPasswordToStart": "Pure-FTPd yêu cầu quyền sudo để khởi động. Vui lòng nhập mật khẩu người dùng của bạn. Mật khẩu sẽ được lưu để tự động điền sau này. Hoặc bạn có thể nhấp vào nút bên dưới để nhập thủ công trong terminal, nhưng thông báo này có thể xuất hiện lại.",
"bundleinVersionDelTips": "Phiên bản này là phiên bản tích hợp sẵn, xác nhận không hiển thị nữa?",
- "customDirVersionDelTips": "Phiên bản này là phiên bản đường dẫn tùy chỉnh, xác nhận không hiển thị nữa?",
+ "customDirVersionDelTips": "Phiên bản này là phiên bản có đường dẫn tùy chỉnh, xác nhận không hiển thị nữa?",
"ErrorTips": {
"VCRuntime": {
- "title": "Your system is missing the Visual C++ Redistributable (DLLs) required to run this version. Please click the link below to download and install the VC Runtime from Microsoft's official website.",
- "versionRelation": "Version Compatibility Reference:",
- "software": "Software",
- "versionRange": "Version Range",
- "msvsVersion": "MSVC Version"
+ "title": "Hệ thống của bạn thiếu Visual C++ Redistributable (DLLs) cần thiết để chạy phiên bản này. Vui lòng nhấp vào liên kết bên dưới để tải xuống và cài đặt VC Runtime từ trang web chính thức của Microsoft.",
+ "versionRelation": "Tham chiếu khả năng tương thích phiên bản:",
+ "software": "Phần mềm",
+ "versionRange": "Phạm vi phiên bản",
+ "msvsVersion": "Phiên bản MSVC"
}
}
}
diff --git a/src/lang/vi/toolType.json b/src/lang/vi/toolType.json
index ba18b4be0..c411967c6 100644
--- a/src/lang/vi/toolType.json
+++ b/src/lang/vi/toolType.json
@@ -1,7 +1,7 @@
{
"Crypto": "Mã hóa",
"Converter": "Chuyển đổi",
- "Web": "Web",
+ "Web": "Trang web",
"Images": "Hình ảnh & Video",
"Development": "Phát triển",
"Network": "Mạng",
diff --git a/src/lang/vi/update.json b/src/lang/vi/update.json
index 3c597e2da..b1d29a4ec 100644
--- a/src/lang/vi/update.json
+++ b/src/lang/vi/update.json
@@ -6,6 +6,6 @@
"update-error-message": "Lỗi cập nhật",
"yes": "Có",
"no": "Không",
- "view-update-log": "View Update Log",
- "download-new-version": "Download New Version"
+ "view-update-log": "Xem nhật ký cập nhật",
+ "download-new-version": "Tải phiên bản mới"
}
diff --git a/src/lang/vi/util.json b/src/lang/vi/util.json
index b47e0bdd0..5aba68e6f 100644
--- a/src/lang/vi/util.json
+++ b/src/lang/vi/util.json
@@ -1,13 +1,13 @@
{
"savePath": "Thư mục lưu",
- "saveAs": "Lưu site: Thư mục lưu/Tên host của site",
+ "saveAs": "Lưu trang web: Thư mục lưu/Host trang web",
"proxy": "Proxy",
"pageLimit": "Giới hạn trang",
- "pageLimitTips": "Địa chỉ trang bị giới hạn phải chứa chuỗi này",
- "LinkExclusion": "Loại trừ host",
- "LinkExclusionTips": "Lọc URL chứa host này, mỗi dòng một host.",
+ "pageLimitTips": "Địa chỉ trang giới hạn phải chứa chuỗi ở đây",
+ "LinkExclusion": "Loại trừ Host",
+ "LinkExclusionTips": "Lọc các URL chứa host này, mỗi dòng một host.",
"timeout": "Thời gian chờ",
- "timeoutTips": "Mặc định 5000, tức 5 giây",
+ "timeoutTips": "Mặc định 5000, thời gian chờ 5 giây",
"maxImgSize": "Giới hạn kích thước tệp hình ảnh",
"maxVideoSize": "Giới hạn kích thước tệp âm thanh/video",
"ftpTableHeadUser": "Tên người dùng",
@@ -16,13 +16,13 @@
"ftpTableHeadSetup": "Cài đặt",
"fontSize": "Cỡ chữ",
"lineHeight": "Chiều cao dòng",
- "forceStart": "Buộc khởi động dịch vụ",
- "forceStartInfo": "Có tắt các dịch vụ xung đột không được khởi động bởi ứng dụng này khi dịch vụ bắt đầu hay không. Nhằm đảm bảo dịch vụ được bật đúng cách.",
- "showAIRobot": "Hiển thị trợ lý AI",
+ "forceStart": "Bắt buộc khởi động dịch vụ",
+ "forceStartInfo": "Có tắt các dịch vụ xung đột không do ứng dụng này khởi động khi dịch vụ được bật hay không. Nhằm đảm bảo các dịch vụ được bật đúng cách.",
+ "showAIRobot": "Hiển thị Trợ lý AI",
"mysqlDataDir": "Thư mục dữ liệu",
"mysqlState": "Trạng thái",
- "mysqlPopperSocket": "Sao chép đường dẫn socket",
- "macPortsSrcSwitch": "Chuyển đổi mirror MacPorts",
+ "mysqlPopperSocket": "Sao chép đường dẫn Socket",
+ "macPortsSrcSwitch": "Chuyển đổi máy chủ phản chiếu (Mirror) MacPorts",
"macPortsSrcDefault": "Mặc định",
"macPortsSrcAustraliBrisbane": "Úc, Brisbane",
"macPortsSrcCanadaManitoba": "Canada, Manitoba",
@@ -43,10 +43,10 @@
"toolSystemEnv": "Môi trường hệ thống",
"toolSSL": "Trình tạo chứng chỉ SSL",
"toolFileInfo": "Thông tin tệp",
- "toolTimestamp": "Chuyển đổi timestamp",
- "toolPortKill": "Đóng port",
- "toolProcessKill": "Dừng tiến trình",
- "toolPhpObfuscator": "Trình làm rối PHP",
+ "toolTimestamp": "Chuyển đổi Timestamp",
+ "toolPortKill": "Đóng cổng",
+ "toolProcessKill": "Đóng tiến trình",
+ "toolPhpObfuscator": "Làm rối mã PHP (Obfuscator)",
"toolUTF8BomClean": "Xóa BOM UTF-8",
"toolSiteSucker": "Thu thập URL",
"toolFileNotExist": "Tệp không tồn tại",
From 7e64d5ecdb66d9880f5899b8f95f8a7fbf437079 Mon Sep 17 00:00:00 2001
From: KietNT <113796420+TanNhatCMS@users.noreply.github.com>
Date: Sun, 1 Mar 2026 21:49:18 +0700
Subject: [PATCH 09/16] Add Cloudflare Tunnel translations (vi)
Add Vietnamese translations for Cloudflare Tunnel in src/lang/vi/host.json: TunnelInitFailTips (includes {error}) and TunnelRule. Also adjust CloudflaredNoFoundTips punctuation and remove extra blank lines for cleanup.
---
src/lang/vi/host.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/lang/vi/host.json b/src/lang/vi/host.json
index 979781138..8bc77eff8 100644
--- a/src/lang/vi/host.json
+++ b/src/lang/vi/host.json
@@ -68,12 +68,12 @@
"showFile": "Hiển thị tệp",
"sticky": "Ghim",
"dbclickRowToEdit": "Nhấp đúp vào dòng này để chỉnh sửa",
-
-
"OnlineDomain": "Tên miền trực tuyến",
"LocalDoman": "Tên miền cục bộ",
"CloudflareTunnel": {
"OnlineDomainExistsTips": "Tên miền trực tuyến tương tự đã tồn tại.",
- "CloudflaredNoFoundTips": "Không tìm thấy Cloudflared. Vui lòng cài đặt nó."
+ "CloudflaredNoFoundTips": "Không tìm thấy Cloudflared. Vui lòng cài đặt nó.",
+ "TunnelInitFailTips": "Tạo Tunnel thất bại: {error}. Vui lòng kiểm tra xem ApiToken có chính xác không và đảm bảo bạn có quyền chỉnh sửa Cloudflare Tunnel.",
+ "TunnelRule": "Quy tắc Tunnel"
}
}
From 2cf0a25f773601d76425b39f5db0888b703014df Mon Sep 17 00:00:00 2001
From: KietNT <113796420+TanNhatCMS@users.noreply.github.com>
Date: Mon, 2 Mar 2026 08:03:15 +0700
Subject: [PATCH 10/16] [feature] Add multi-language Git cheatsheet with code
copy functionality (#563)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* ✨ feat(git-cheatsheet): Add multi-language Git cheatsheet with code copy functionality
* ✨ feat(git-cheatsheet): Add cleanup for window copy function
and expose copy function to window.
* ✨ feat(git-cheatsheet): Update git stash command and improve copy button accessibility
* ✨ feat(git-cheatsheet): Improve credential helper documentation and copy behavior
This commit refactors the git cheatsheet component to:
- Update credential helper documentation in both English and Vietnamese.
- Enhance the code copy functionality by:
- Storing copy timeouts to prevent overlapping reset animations.
- Disabling HTML parsing in markdown-it for security.
- Filtering out comment lines from code snippets before copying.
- Using a reactive approach for language memo selection.
* ✨ feat(git-cheatsheet): Refactor code block rendering and add copy button functionality
* ✨ feat(git-cheatsheet): Prevent overlapping copy animations and enhance security
---
.../Tools/GitCheatsheet/git-memo.content.md | 77 ---
.../components/Tools/GitCheatsheet/index.vue | 247 ++++++++-
.../Tools/GitCheatsheet/lang/git-memo.en.md | 495 ++++++++++++++++++
.../Tools/GitCheatsheet/lang/git-memo.vi.md | 495 ++++++++++++++++++
4 files changed, 1229 insertions(+), 85 deletions(-)
delete mode 100644 src/render/components/Tools/GitCheatsheet/git-memo.content.md
create mode 100644 src/render/components/Tools/GitCheatsheet/lang/git-memo.en.md
create mode 100644 src/render/components/Tools/GitCheatsheet/lang/git-memo.vi.md
diff --git a/src/render/components/Tools/GitCheatsheet/git-memo.content.md b/src/render/components/Tools/GitCheatsheet/git-memo.content.md
deleted file mode 100644
index 6783ad864..000000000
--- a/src/render/components/Tools/GitCheatsheet/git-memo.content.md
+++ /dev/null
@@ -1,77 +0,0 @@
-## Configuration
-
-Set the global config
-
-```shell
-git config --global user.name "[name]"
-git config --global user.email "[email]"
-```
-
-## Get started
-
-Create a git repository
-
-```shell
-git init
-```
-
-Clone an existing git repository
-
-```shell
-git clone [url]
-```
-
-## Commit
-
-Commit all tracked changes
-
-```shell
-git commit -am "[commit message]"
-```
-
-Add new modifications to the last commit
-
-```shell
-git commit --amend --no-edit
-```
-
-## I’ve made a mistake
-
-Change last commit message
-
-```shell
-git commit --amend
-```
-
-Undo most recent commit and keep changes
-
-```shell
-git reset HEAD~1
-```
-
-Undo the `N` most recent commit and keep changes
-
-```shell
-git reset HEAD~N
-```
-
-Undo most recent commit and get rid of changes
-
-```shell
-git reset HEAD~1 --hard
-```
-
-Reset branch to remote state
-
-```shell
-git fetch origin
-git reset --hard origin/[branch-name]
-```
-
-## Miscellaneous
-
-Renaming the local master branch to main
-
-```shell
-git branch -m master main
-```
diff --git a/src/render/components/Tools/GitCheatsheet/index.vue b/src/render/components/Tools/GitCheatsheet/index.vue
index bd3a654da..362dac252 100644
--- a/src/render/components/Tools/GitCheatsheet/index.vue
+++ b/src/render/components/Tools/GitCheatsheet/index.vue
@@ -1,10 +1,3 @@
-
-
+
-
- {{ I18nT('base.info') }}
+
+ {{ I18nT('base.log') }}
@@ -215,7 +217,6 @@
add,
edit,
del,
- info,
list,
openOutUrl,
openLocalUrl,
@@ -223,7 +224,8 @@
copy,
editDNS,
delDNS,
- addDNS
+ addDNS,
+ log
} = Setup()
const action = (item: CloudflareTunnel, index: number, flag: string) => {
@@ -231,8 +233,8 @@
case 'edit':
edit(item)
break
- case 'info':
- info(item)
+ case 'log':
+ log(item)
break
case 'del':
del(item, index)
diff --git a/src/render/components/CloudflareTunnel/Logs.vue b/src/render/components/CloudflareTunnel/Logs.vue
new file mode 100644
index 000000000..dbfcccb96
--- /dev/null
+++ b/src/render/components/CloudflareTunnel/Logs.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+ {{ I18nT('base.log') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/render/components/CloudflareTunnel/addDNS.vue b/src/render/components/CloudflareTunnel/addDNS.vue
index c94862e73..eedde1a11 100644
--- a/src/render/components/CloudflareTunnel/addDNS.vue
+++ b/src/render/components/CloudflareTunnel/addDNS.vue
@@ -37,7 +37,19 @@
-
+
@@ -79,6 +91,7 @@
apiToken: '',
accountId: '',
+ protocol: 'http',
subdomain: '',
localService: '',
zoneId: '',
@@ -190,7 +203,8 @@
zoneId: form.value.zoneId,
zoneName: form.value.zoneName,
subdomain: form.value.subdomain,
- localService: form.value.localService
+ localService: form.value.localService,
+ protocol: form.value.protocol as any
}
find.dns.unshift(reactive(dns))
if (find.run) {
diff --git a/src/render/components/CloudflareTunnel/editDNS.vue b/src/render/components/CloudflareTunnel/editDNS.vue
index 0f8ec8b7a..99f1a7fcd 100644
--- a/src/render/components/CloudflareTunnel/editDNS.vue
+++ b/src/render/components/CloudflareTunnel/editDNS.vue
@@ -37,7 +37,19 @@
-
+
@@ -80,6 +92,7 @@
apiToken: '',
accountId: '',
+ protocol: 'http',
subdomain: '',
localService: '',
zoneId: '',
@@ -93,6 +106,7 @@
form.value.localService = props.dns.localService
form.value.zoneId = props.dns.zoneId
form.value.zoneName = props.dns.zoneName
+ form.value.protocol = props.dns.protocol || 'http'
const saveEnable = computed(() => {
return (
@@ -199,7 +213,8 @@
dns.zoneId !== form.value.zoneId ||
dns.zoneName !== form.value.zoneName ||
dns.subdomain !== form.value.subdomain ||
- dns.localService !== form.value.localService
+ dns.localService !== form.value.localService ||
+ dns.protocol !== form.value.protocol
)
}
return false
@@ -217,6 +232,8 @@
dns.zoneName = form.value.zoneName
dns.subdomain = form.value.subdomain
dns.localService = form.value.localService
+ dns.protocol = form.value.protocol as any
+
CloudflareTunnelStore.save()
if (find.run) {
find.restart().catch()
diff --git a/src/render/components/CloudflareTunnel/setup.ts b/src/render/components/CloudflareTunnel/setup.ts
index 0f224fa12..acb682076 100644
--- a/src/render/components/CloudflareTunnel/setup.ts
+++ b/src/render/components/CloudflareTunnel/setup.ts
@@ -6,7 +6,7 @@ import { AsyncComponentShow } from '@/util/AsyncComponent'
import { CloudflareTunnelDnsRecord, ZoneType } from '@/core/CloudflareTunnel/type'
import Base from '@/core/Base'
import { I18nT } from '@lang/index'
-import { clipboard } from '@/util/NodeFn'
+import { clipboard, shell } from '@/util/NodeFn'
import { MessageSuccess } from '@/util/Element'
export const ZoneDict: Record = reactive({})
@@ -38,7 +38,16 @@ export const Setup = () => {
}).then()
}
- function info(item: CloudflareTunnel) {}
+ let LogVM: any
+ import('./Logs.vue').then((res) => {
+ LogVM = res.default
+ })
+
+ function log(item: CloudflareTunnel) {
+ AsyncComponentShow(LogVM, {
+ item: JSON.parse(JSON.stringify(item))
+ }).then()
+ }
function del(item: CloudflareTunnel, index: number) {
Base._Confirm(I18nT('base.areYouSure'), undefined, {
@@ -50,9 +59,15 @@ export const Setup = () => {
})
}
- const openOutUrl = (item: CloudflareTunnel) => {}
+ const openOutUrl = (item: CloudflareTunnelDnsRecord) => {
+ const url = `http://${item.subdomain}.${item.zoneName}`
+ shell.openExternal(url).catch()
+ }
- const openLocalUrl = (item: CloudflareTunnel) => {}
+ const openLocalUrl = (item: CloudflareTunnelDnsRecord) => {
+ const url = `${item?.protocol || 'http'}://${item.localService}`
+ shell.openExternal(url).catch()
+ }
const groupTrunOn = (item: CloudflareTunnel) => {
const dict = JSON.parse(JSON.stringify(appStore.phpGroupStart))
@@ -113,7 +128,6 @@ export const Setup = () => {
return {
add,
edit,
- info,
del,
list,
openOutUrl,
@@ -122,6 +136,7 @@ export const Setup = () => {
copy,
editDNS,
delDNS,
- addDNS
+ addDNS,
+ log
}
}
diff --git a/src/render/core/CloudflareTunnel/CloudflareTunnelStore.ts b/src/render/core/CloudflareTunnel/CloudflareTunnelStore.ts
index 3c1bf83d5..5419e3962 100644
--- a/src/render/core/CloudflareTunnel/CloudflareTunnelStore.ts
+++ b/src/render/core/CloudflareTunnel/CloudflareTunnelStore.ts
@@ -14,6 +14,7 @@ class CloudflareTunnelStore {
StorageGetAsync(storeKey)
.then((res: CloudflareTunnel[]) => {
if (res) {
+ console.log('CloudflareTunnelStore init res:', res)
for (const item of res) {
const obj = reactiveBind(new CloudflareTunnel(item))
this.items.push(obj)
diff --git a/src/render/core/CloudflareTunnel/type.ts b/src/render/core/CloudflareTunnel/type.ts
index b4c002c98..36f0f5f12 100644
--- a/src/render/core/CloudflareTunnel/type.ts
+++ b/src/render/core/CloudflareTunnel/type.ts
@@ -13,4 +13,5 @@ export type CloudflareTunnelDnsRecord = {
localService: string
zoneId: string
zoneName: string
+ protocol: 'http' | 'https'
}
From d2e7e99924259d348f67e78c51020922e29a0a3c Mon Sep 17 00:00:00 2001
From: xupengfei <250881478@qq.com>
Date: Mon, 2 Mar 2026 15:36:17 +0800
Subject: [PATCH 12/16] 1. Add Cloudflare Tunnel Module 2. Add Cloudflared
Module 3. Python And Go add new project creation features.
---
.../components/GoLang/CreateProject.vue | 9 +
src/render/components/GoLang/Index.vue | 11 +-
.../Host/CreateProject/go/create.vue | 258 +++++++++++++++++
.../Host/CreateProject/go/create.win.vue | 262 ++++++++++++++++++
.../Host/CreateProject/go/index.vue | 131 +++++++++
.../Host/CreateProject/go/version.ts | 133 +++++++++
.../components/Host/CreateProject/new.vue | 8 +-
.../components/Host/CreateProject/nodejs.vue | 6 +-
.../Host/CreateProject/nodejsCreate.win.vue | 3 -
.../components/Host/CreateProject/php.vue | 6 +-
.../components/Host/CreateProject/project.ts | 29 +-
.../Host/CreateProject/python/create.vue | 258 +++++++++++++++++
.../Host/CreateProject/python/create.win.vue | 255 +++++++++++++++++
.../Host/CreateProject/python/index.vue | 131 +++++++++
.../Host/CreateProject/python/version.ts | 158 +++++++++++
.../Host/CreateProject/version_nodejs.ts | 60 ++++
.../components/Python/CreateProject.vue | 9 +
src/render/components/Python/Index.vue | 11 +-
18 files changed, 1725 insertions(+), 13 deletions(-)
create mode 100644 src/render/components/GoLang/CreateProject.vue
create mode 100644 src/render/components/Host/CreateProject/go/create.vue
create mode 100644 src/render/components/Host/CreateProject/go/create.win.vue
create mode 100644 src/render/components/Host/CreateProject/go/index.vue
create mode 100644 src/render/components/Host/CreateProject/go/version.ts
create mode 100644 src/render/components/Host/CreateProject/python/create.vue
create mode 100644 src/render/components/Host/CreateProject/python/create.win.vue
create mode 100644 src/render/components/Host/CreateProject/python/index.vue
create mode 100644 src/render/components/Host/CreateProject/python/version.ts
create mode 100644 src/render/components/Python/CreateProject.vue
diff --git a/src/render/components/GoLang/CreateProject.vue b/src/render/components/GoLang/CreateProject.vue
new file mode 100644
index 000000000..09440aa8e
--- /dev/null
+++ b/src/render/components/GoLang/CreateProject.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/src/render/components/GoLang/Index.vue b/src/render/components/GoLang/Index.vue
index 4f8b00bcc..0877c496f 100644
--- a/src/render/components/GoLang/Index.vue
+++ b/src/render/components/GoLang/Index.vue
@@ -19,7 +19,8 @@
url="https://go.dev/dl/"
:has-static="true"
>
-
+
+
@@ -38,7 +39,13 @@
import { I18nT } from '@lang/index'
import ProjectIndex from '@/components/LanguageProjects/index.vue'
import { Project } from '@/util/Project'
+ import ProjectCreateVM from './CreateProject.vue'
const { tab } = AppModuleSetup('golang')
- const tabs = [I18nT('base.service'), I18nT('base.versionManager'), I18nT('host.projectGo')]
+ const tabs = [
+ I18nT('base.service'),
+ I18nT('base.versionManager'),
+ I18nT('host.newProject'),
+ I18nT('host.projectGo')
+ ]
diff --git a/src/render/components/Host/CreateProject/go/create.vue b/src/render/components/Host/CreateProject/go/create.vue
new file mode 100644
index 000000000..ea36e0cf7
--- /dev/null
+++ b/src/render/components/Host/CreateProject/go/create.vue
@@ -0,0 +1,258 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Go {{ I18nT('base.version') }}
+
+
+
+
+
+
+
+
+
+
+ {{ I18nT('host.frameworkVersion') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/render/components/Host/CreateProject/go/create.win.vue b/src/render/components/Host/CreateProject/go/create.win.vue
new file mode 100644
index 000000000..a4044617d
--- /dev/null
+++ b/src/render/components/Host/CreateProject/go/create.win.vue
@@ -0,0 +1,262 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Go {{ I18nT('base.version') }}
+
+
+
+
+
+
+
+
+
+
+ {{ I18nT('host.frameworkVersion') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/render/components/Host/CreateProject/go/index.vue b/src/render/components/Host/CreateProject/go/index.vue
new file mode 100644
index 000000000..5535ca2c5
--- /dev/null
+++ b/src/render/components/Host/CreateProject/go/index.vue
@@ -0,0 +1,131 @@
+
+
+
+
diff --git a/src/render/components/Host/CreateProject/go/version.ts b/src/render/components/Host/CreateProject/go/version.ts
new file mode 100644
index 000000000..15bfbd3dc
--- /dev/null
+++ b/src/render/components/Host/CreateProject/go/version.ts
@@ -0,0 +1,133 @@
+const goVersion = {
+ 'Go (Standard)': {
+ url: 'https://golang.org/',
+ list: [
+ {
+ name: 'latest',
+ version: '*',
+ command: 'go mod init my-module; echo "package main\n\nfunc main() {}" > main.go',
+ commandWin:
+ 'go mod init my-module; "package main`n`nfunc main() {}" | Out-File -Encoding ascii main.go'
+ }
+ ]
+ },
+ Gin: {
+ url: 'https://gin-gonic.com/',
+ list: [
+ {
+ name: 'latest',
+ version: '*',
+ command:
+ 'go mod init myapp; go get github.com/gin-gonic/gin; printf "package main\nimport \"github.com/gin-gonic/gin\"\nfunc main() {\n r := gin.Default()\n r.GET(\"/ping\", func(c *gin.Context) { c.JSON(200, gin.H{\"message\": \"pong\"}) })\n r.Run()\n}" > main.go',
+ commandWin:
+ 'go mod init myapp; go get github.com/gin-gonic/gin; "package main`nimport `"github.com/gin-gonic/gin`"`nfunc main() {`n r := gin.Default()`n r.GET(`"/ping`签署, func(c *gin.Context) { c.JSON(200, gin.H{`"message`签署: `"pong`签署}) })`n r.Run()`n}" | Out-File -Encoding ascii main.go'
+ }
+ ]
+ },
+ Echo: {
+ url: 'https://echo.labstack.com/',
+ list: [
+ {
+ name: 'latest',
+ version: '*',
+ command:
+ 'go mod init myapp; go get github.com/labstack/echo/v4; printf "package main\nimport (\n\t\"github.com/labstack/echo/v4\"\n\t\"net/http\"\n)\nfunc main() {\n\te := echo.New()\n\te.GET(\"/\", func(c echo.Context) error {\n\t\treturn c.String(http.StatusOK, \"Hello, World!\")\n\t})\n\te.Logger.Fatal(e.Start(\":1323\"))\n}" > main.go',
+ commandWin:
+ 'go mod init myapp; go get github.com/labstack/echo/v4; "package main`nimport (`n`t`"github.com/labstack/echo/v4`"`n`t`"net/http`"`n)`nfunc main() {`n`te := echo.New()`n`te.GET(`"/`签署, func(c echo.Context) error {`n`t`treturn c.String(http.StatusOK, `"Hello, World!`签署)`n`t})`n`te.Logger.Fatal(e.Start(`":1323`签署))`n}" | Out-File -Encoding ascii main.go'
+ }
+ ]
+ },
+ Fiber: {
+ url: 'https://gofiber.io/',
+ list: [
+ {
+ name: 'latest',
+ version: '*',
+ command:
+ 'go mod init myapp; go get github.com/gofiber/fiber/v2; printf "package main\nimport \"github.com/gofiber/fiber/v2\"\nfunc main() {\n\tapp := fiber.New()\n\tapp.Get(\"/\", func(c *fiber.Ctx) error {\n\t\treturn c.SendString(\"Hello, World!\")\n\t})\n\tapp.Listen(\":3000\")\n}" > main.go',
+ commandWin:
+ 'go mod init myapp; go get github.com/gofiber/fiber/v2; "package main`nimport `"github.com/gofiber/fiber/v2`"`nfunc main() {`n`tapp := fiber.New()`n`tapp.Get(`"/`签署, func(c *fiber.Ctx) error {`n`t`treturn c.SendString(`"Hello, World!`签署)`n`t})`n`tapp.Listen(`":3000`签署)`n}" | Out-File -Encoding ascii main.go'
+ }
+ ]
+ },
+ Iris: {
+ url: 'https://www.iris-go.com/',
+ list: [
+ {
+ name: 'latest',
+ version: '*',
+ command:
+ 'go mod init myapp; go get github.com/kataras/iris/v12; printf "package main\nimport \"github.com/kataras/iris/v12\"\nfunc main() {\n\tapp := iris.New()\n\tapp.Get(\"/\", func(ctx iris.Context) {\n\t\tctx.WriteString(\"Hello, World!\")\n\t})\n\tapp.Listen(\":8080\")\n}" > main.go',
+ commandWin:
+ 'go mod init myapp; go get github.com/kataras/iris/v12; "package main`nimport `"github.com/kataras/iris/v12`"`nfunc main() {`n`tapp := iris.New()`n`tapp.Get(`"/`签署, func(ctx iris.Context) {`n`t`tctx.WriteString(`"Hello, World!`签署)`n`t})`n`tapp.Listen(`":8080`签署)`n}" | Out-File -Encoding ascii main.go'
+ }
+ ]
+ },
+ GoFrame: {
+ url: 'https://goframe.org/',
+ list: [
+ {
+ name: 'latest',
+ version: '*',
+ command:
+ 'go mod init myapp; go get github.com/gogf/gf/v2; printf "package main\nimport (\n\t\"github.com/gogf/gf/v2/frame/g\"\n\t\"github.com/gogf/gf/v2/net/ghttp\"\n)\nfunc main() {\n\ts := g.Server()\n\ts.BindHandler(\"/\", func(r *ghttp.Request) {\n\t\tr.Response.Write(\"Hello, World!\")\n\t})\n\ts.Run()\n}" > main.go',
+ commandWin:
+ 'go mod init myapp; go get github.com/gogf/gf/v2; "package main`nimport (`n`t`"github.com/gogf/gf/v2/frame/g`"`n`t`"github.com/gogf/gf/v2/net/ghttp`"`n)`nfunc main() {`n`ts := g.Server()`n`ts.BindHandler(`"/`签署, func(r *ghttp.Request) {`n`t`tr.Response.Write(`"Hello, World!`签署)`n`t})`n`ts.Run()`n}" | Out-File -Encoding ascii main.go'
+ }
+ ]
+ },
+ 'Go-Zero': {
+ url: 'https://go-zero.dev/',
+ list: [
+ {
+ name: 'latest',
+ version: '*',
+ command:
+ 'go install github.com/zeromicro/go-zero/tools/goctl@latest; $(go env GOPATH)/bin/goctl api new demo',
+ commandWin:
+ '$gopath = go env GOPATH; go install github.com/zeromicro/go-zero/tools/goctl@latest; & "$gopath\\bin\\goctl.exe" api new demo'
+ }
+ ]
+ },
+ Buffalo: {
+ url: 'https://gobuffalo.io/',
+ list: [
+ {
+ name: 'latest',
+ version: '*',
+ command:
+ 'go install github.com/gobuffalo/cli/cmd/buffalo@latest; $(go env GOPATH)/bin/buffalo new myapp',
+ commandWin:
+ '$gopath = go env GOPATH; go install github.com/gobuffalo/cli/cmd/buffalo@latest; & "$gopath\\bin\\buffalo.exe" new myapp'
+ }
+ ]
+ },
+ 'Hugo (Static)': {
+ url: 'https://gohugo.io/',
+ list: [
+ {
+ name: 'latest',
+ version: '*',
+ command:
+ 'go install github.com/gohugoio/hugo@latest; $(go env GOPATH)/bin/hugo new site my-hugo-site',
+ commandWin:
+ '$gopath = go env GOPATH; go install github.com/gohugoio/hugo@latest; & "$gopath\\bin\\hugo.exe" new site my-hugo-site'
+ }
+ ]
+ },
+ 'Cobra (CLI)': {
+ url: 'https://github.com/spf13/cobra',
+ list: [
+ {
+ name: 'latest',
+ version: '*',
+ command:
+ 'go install github.com/spf13/cobra-cli@latest; go mod init myapp; $(go env GOPATH)/bin/cobra-cli init',
+ commandWin:
+ '$gopath = go env GOPATH; go install github.com/spf13/cobra-cli@latest; go mod init myapp; & "$gopath\\bin\\cobra-cli.exe" init'
+ }
+ ]
+ }
+}
+
+export default goVersion
diff --git a/src/render/components/Host/CreateProject/new.vue b/src/render/components/Host/CreateProject/new.vue
index 69ff9d9b1..0b27179de 100644
--- a/src/render/components/Host/CreateProject/new.vue
+++ b/src/render/components/Host/CreateProject/new.vue
@@ -15,6 +15,8 @@
+
+
@@ -22,7 +24,9 @@