jcq 4 天之前
父节点
当前提交
8de8ae770f
共有 11 个文件被更改,包括 961 次插入422 次删除
  1. 5 0
      .env
  2. 1 1
      auto-imports.d.ts
  3. 141 141
      convert-geojson-names.cjs
  4. 1 1
      index.html
  5. 26 39
      mock.json
  6. 302 0
      package-lock.json
  7. 8 0
      package.json
  8. 261 239
      pnpm-lock.yaml
  9. 0 0
      public/assets/styles/font-awesome.min.css
  10. 215 0
      publish.mjs
  11. 1 1
      src/views/marketing/config/form.vue

+ 5 - 0
.env

@@ -25,3 +25,8 @@ VITE_WEBSOCKET_ENABLE = false
 
 # 是否开启注册
 VITE_REGISTER_ENABLE  = true
+
+VITE_HOST=192.168.10.101
+VITE_POST=22
+VITE_USERNAME=root
+VITE_PASSWORD=yV6iL7bI2hN5zO4o

+ 1 - 1
auto-imports.d.ts

@@ -53,7 +53,7 @@ declare global {
   const readonly: typeof import('vue')['readonly']
   const ref: typeof import('vue')['ref']
   const resolveComponent: typeof import('vue')['resolveComponent']
-  const resolveDirective: typeof import('vue')['resolveDirective']
+  const resolveDirective: (typeof import('vue'))['resolveDirective']
   const setActivePinia: typeof import('pinia')['setActivePinia']
   const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
   const shallowReactive: typeof import('vue')['shallowReactive']

+ 141 - 141
convert-geojson-names.cjs

@@ -5,150 +5,150 @@ const fs = require('fs');
 const path = require('path');
 
 // 英文-中文对照表(可补充)
-const nameMap = { 
-    "China": "中国",
-    "United States of America": "美国",
-    "Japan": "日本",
-    "South Korea": "韩国",
-    "Australia": "澳大利亚",
-    "Canada": "加拿大",
-    "Russia": "俄罗斯",
-    "India": "印度",
-    "Brazil": "巴西",
-    "United Kingdom": "英国",
-    "France": "法国",
-    "Germany": "德国",
-    "Italy": "意大利",
-    "New Zealand": "新西兰",
-    "Papua New Guinea": "巴布亚新几内亚",
-    "Fiji": "斐济",
-    "Samoa": "萨摩亚",
-    "Tonga": "汤加",
-    "Vanuatu": "瓦努阿图",
-    "Solomon Islands": "所罗门群岛",
-    "Micronesia": "密克罗尼西亚",
-    "Palau": "帕劳",
-    "Nauru": "瑙鲁",
-    "Tuvalu": "图瓦卢",
-    "Kiribati": "基里巴斯",
-    "Maldives": "马尔代夫",
-    "Sri Lanka": "斯里兰卡",
-    "Cambodia": "柬埔寨",
-    "Vietnam": "越南",
-    "Thailand": "泰国",
-    "Philippines": "菲律宾",
-    "Indonesia": "印度尼西亚",
-    "Myanmar": "缅甸",
-    "Pakistan": "巴基斯坦",
-    "Nepal": "尼泊尔",
-    "Bangladesh": "孟加拉国",
-    "Mongolia": "蒙古",
-    "Tajikistan": "塔吉克斯坦",
-    "Uzbekistan": "乌兹别克斯坦",
-    "Kazakhstan": "哈萨克斯坦",
-    "Chile": "智利",
-    "Argentina": "阿根廷",
-    "Colombia": "哥伦比亚",
-    "Peru": "秘鲁",
-    "Bolivia": "玻利维亚",
-    "Ecuador": "厄瓜多尔",
-    "Paraguay": "巴拉圭",
-    "Uruguay": "乌拉圭",
-    "Hong Kong": "中国香港",
-    "Macau": "中国澳门",
-    "Taiwan": "中国台湾",
-    "South Africa": "南非",
-    "Nigeria": "尼日利亚",
-    "Kenya": "肯尼亚",
-    "Egypt": "埃及",
-    "Morocco": "摩洛哥",
-    "Ghana": "加纳",
-    "Senegal": "塞内加尔",
-    "Tanzania": "坦桑尼亚",
-    "Uganda": "乌干达",
-    "Zimbabwe": "津巴布韦",
-    "Algeria": "阿尔及利亚",
-    "Mali": "马里",
-    "Cameroon": "喀麦隆",
-    "Gabon": "加蓬",
-    "Congo": "刚果",
-    "Angola": "安哥拉",
-    "Mozambique": "莫桑比克",
-    "Zambia": "赞比亚",
-    "Botswana": "博茨瓦纳",
-    "Zambia": "赞比亚",
-    "Madagascar": "马达加斯加",
-    "Rwanda": "卢旺达",
-    "Burundi": "布隆迪",
-    "Togo": "多哥",
-    "Benin": "贝宁",
-    "Niger": "尼日",
-    "Chad": "乍得",
-    "Cameroon": "喀麦隆",
-    "South Sudan": "南苏丹",
-    "Sudan": "苏丹",
-    "Libya": "利比亚",
-    "Ethiopia": "埃塞俄比亚",
-    "Djibouti": "吉布提",
-    "Somalia": "索马里",
-    "Eritrea": "厄立特里亚",
-    "Seychelles": "塞舌尔",
-    "Comoros": "科摩罗",
-    "Mayotte": "马约特",
-    "Reunion": "留尼旺",
-    "Mauritius": "毛里求斯",
-    "Saint Helena": "圣赫勒拿",
-    "Saint Kitts and Nevis": "圣基茨和尼维斯",
-    "Saint Lucia": "圣卢西亚",
-    "Saint Pierre and Miquelon": "圣皮埃尔和密克隆",
-    "Saint Vincent and the Grenadines": "圣文森特和格林纳丁斯",
-    "Saint Martin": "圣马丁",
-    "Saint Barthelemy": "圣巴泰勒米",
-    "Saint Martin": "圣马丁",
-    "Saint Barthelemy": "圣巴泰勒米",
-    "Antigua and Barbuda": "安提瓜和巴布达",
-    "Dominica": "多米尼克",
-    "Grenada": "格林纳达",
-    "Trinidad and Tobago": "特立尼达和多巴哥",
-    "Bahamas": "巴哈马",
-    "Cuba": "古巴",
-    "Dominican Republic": "多米尼加共和国",
-    "Haiti": "海地",
-    "Jamaica": "牙买加",
-    "Barbados": "巴巴多斯",
-    "Suriname": "苏里南",
-    "French Guiana": "法属圭亚那",
-    "Mexico": "墨西哥",
-    "Cayman Islands": "开曼群岛",
-    "Bermuda": "百慕大",
-    "Puerto Rico": "波多黎各",
-    "Costa Rica": "哥斯达黎加",
-    "Nicaragua": "尼加拉瓜",
-    "El Salvador": "萨尔瓦多",
-    "Honduras": "洪都拉斯",
-    "Guatemala": "危地马拉",
-    "Belize": "伯利兹",
-    "Panama": "巴拿马",
-    "Aruba": "阿鲁巴",
-    "Antarctica": "南极洲",
-    "Malaysia": "马来西亚",
-    "Singapore": "新加坡",
-    "Laos": "老挝",
-    "Brunei": "文莱",
+const nameMap = {
+	China: '中国',
+	'United States of America': '美国',
+	Japan: '日本',
+	'South Korea': '韩国',
+	Australia: '澳大利亚',
+	Canada: '加拿大',
+	Russia: '俄罗斯',
+	India: '印度',
+	Brazil: '巴西',
+	'United Kingdom': '英国',
+	France: '法国',
+	Germany: '德国',
+	Italy: '意大利',
+	'New Zealand': '新西兰',
+	'Papua New Guinea': '巴布亚新几内亚',
+	Fiji: '斐济',
+	Samoa: '萨摩亚',
+	Tonga: '汤加',
+	Vanuatu: '瓦努阿图',
+	'Solomon Islands': '所罗门群岛',
+	Micronesia: '密克罗尼西亚',
+	Palau: '帕劳',
+	Nauru: '瑙鲁',
+	Tuvalu: '图瓦卢',
+	Kiribati: '基里巴斯',
+	Maldives: '马尔代夫',
+	'Sri Lanka': '斯里兰卡',
+	Cambodia: '柬埔寨',
+	Vietnam: '越南',
+	Thailand: '泰国',
+	Philippines: '菲律宾',
+	Indonesia: '印度尼西亚',
+	Myanmar: '缅甸',
+	Pakistan: '巴基斯坦',
+	Nepal: '尼泊尔',
+	Bangladesh: '孟加拉国',
+	Mongolia: '蒙古',
+	Tajikistan: '塔吉克斯坦',
+	Uzbekistan: '乌兹别克斯坦',
+	Kazakhstan: '哈萨克斯坦',
+	Chile: '智利',
+	Argentina: '阿根廷',
+	Colombia: '哥伦比亚',
+	Peru: '秘鲁',
+	Bolivia: '玻利维亚',
+	Ecuador: '厄瓜多尔',
+	Paraguay: '巴拉圭',
+	Uruguay: '乌拉圭',
+	'Hong Kong': '中国香港',
+	Macau: '中国澳门',
+	Taiwan: '中国台湾',
+	'South Africa': '南非',
+	Nigeria: '尼日利亚',
+	Kenya: '肯尼亚',
+	Egypt: '埃及',
+	Morocco: '摩洛哥',
+	Ghana: '加纳',
+	Senegal: '塞内加尔',
+	Tanzania: '坦桑尼亚',
+	Uganda: '乌干达',
+	Zimbabwe: '津巴布韦',
+	Algeria: '阿尔及利亚',
+	Mali: '马里',
+	Cameroon: '喀麦隆',
+	Gabon: '加蓬',
+	Congo: '刚果',
+	Angola: '安哥拉',
+	Mozambique: '莫桑比克',
+	Zambia: '赞比亚',
+	Botswana: '博茨瓦纳',
+	Zambia: '赞比亚',
+	Madagascar: '马达加斯加',
+	Rwanda: '卢旺达',
+	Burundi: '布隆迪',
+	Togo: '多哥',
+	Benin: '贝宁',
+	Niger: '尼日',
+	Chad: '乍得',
+	Cameroon: '喀麦隆',
+	'South Sudan': '南苏丹',
+	Sudan: '苏丹',
+	Libya: '利比亚',
+	Ethiopia: '埃塞俄比亚',
+	Djibouti: '吉布提',
+	Somalia: '索马里',
+	Eritrea: '厄立特里亚',
+	Seychelles: '塞舌尔',
+	Comoros: '科摩罗',
+	Mayotte: '马约特',
+	Reunion: '留尼旺',
+	Mauritius: '毛里求斯',
+	'Saint Helena': '圣赫勒拿',
+	'Saint Kitts and Nevis': '圣基茨和尼维斯',
+	'Saint Lucia': '圣卢西亚',
+	'Saint Pierre and Miquelon': '圣皮埃尔和密克隆',
+	'Saint Vincent and the Grenadines': '圣文森特和格林纳丁斯',
+	'Saint Martin': '圣马丁',
+	'Saint Barthelemy': '圣巴泰勒米',
+	'Saint Martin': '圣马丁',
+	'Saint Barthelemy': '圣巴泰勒米',
+	'Antigua and Barbuda': '安提瓜和巴布达',
+	Dominica: '多米尼克',
+	Grenada: '格林纳达',
+	'Trinidad and Tobago': '特立尼达和多巴哥',
+	Bahamas: '巴哈马',
+	Cuba: '古巴',
+	'Dominican Republic': '多米尼加共和国',
+	Haiti: '海地',
+	Jamaica: '牙买加',
+	Barbados: '巴巴多斯',
+	Suriname: '苏里南',
+	'French Guiana': '法属圭亚那',
+	Mexico: '墨西哥',
+	'Cayman Islands': '开曼群岛',
+	Bermuda: '百慕大',
+	'Puerto Rico': '波多黎各',
+	'Costa Rica': '哥斯达黎加',
+	Nicaragua: '尼加拉瓜',
+	'El Salvador': '萨尔瓦多',
+	Honduras: '洪都拉斯',
+	Guatemala: '危地马拉',
+	Belize: '伯利兹',
+	Panama: '巴拿马',
+	Aruba: '阿鲁巴',
+	Antarctica: '南极洲',
+	Malaysia: '马来西亚',
+	Singapore: '新加坡',
+	Laos: '老挝',
+	Brunei: '文莱',
 
-    // ...可继续补充
+	// ...可继续补充
 };
 
 function convertGeoJson(filePath) {
-    const geojson = JSON.parse(fs.readFileSync(filePath, 'utf8'));
-    geojson.features.forEach(f => {
-        const en = f.properties.name;
-        if (nameMap[en]) {
-            f.properties.name = nameMap[en];
-        }
-    });
-    fs.writeFileSync(filePath, JSON.stringify(geojson, null, 2), 'utf8');
-    console.log(`已处理: ${filePath}`);
+	const geojson = JSON.parse(fs.readFileSync(filePath, 'utf8'));
+	geojson.features.forEach((f) => {
+		const en = f.properties.name;
+		if (nameMap[en]) {
+			f.properties.name = nameMap[en];
+		}
+	});
+	fs.writeFileSync(filePath, JSON.stringify(geojson, null, 2), 'utf8');
+	console.log(`已处理: ${filePath}`);
 }
 
 convertGeoJson(path.join(__dirname, 'public/map/custom.geo.json'));
@@ -157,4 +157,4 @@ convertGeoJson(path.join(__dirname, 'public/map/africa.geo.json'));
 convertGeoJson(path.join(__dirname, 'public/map/asia.geo.json'));
 convertGeoJson(path.join(__dirname, 'public/map/europe.geo.json'));
 convertGeoJson(path.join(__dirname, 'public/map/northAmerica.geo.json'));
-convertGeoJson(path.join(__dirname, 'public/map/southAmerica.geo.json'));
+convertGeoJson(path.join(__dirname, 'public/map/southAmerica.geo.json'));

+ 1 - 1
index.html

@@ -1,4 +1,4 @@
-<!DOCTYPE html>
+<!doctype html>
 <html lang="zh-CN">
 	<head>
 		<meta charset="utf-8" />

+ 26 - 39
mock.json

@@ -1,40 +1,27 @@
 {
-    "code": 0,
-    "msg": null,
-    "data": 
-    {
-      "total": 2,
-      "records": [
-        {
-            "id": 1,
-            "appName": "数据营销平台",
-            "url": "www.baidu.com",
-            "isMarketing": 1,
-            "isHttp": 0,
-            "https": [
-              "192.168.1.1",
-              "192.168.1.2"
-            ],
-            "ips": [
-              "192.168.1.1",
-              "192.168.1.2"
-            ]
-        },
-        {
-            "id": 1,
-            "appName": "数据营销平台",
-            "url": "www.baidu.com",
-            "isMarketing": 1,
-            "isHttp": 0,
-            "https": [
-              "192.168.1.1",
-              "192.168.1.2"
-            ],
-            "ips": [
-              "192.168.1.1",
-              "192.168.1.2"
-            ]
-        }    
-    ]
-    }
-}
+	"code": 0,
+	"msg": null,
+	"data": {
+		"total": 2,
+		"records": [
+			{
+				"id": 1,
+				"appName": "数据营销平台",
+				"url": "www.baidu.com",
+				"isMarketing": 1,
+				"isHttp": 0,
+				"https": ["192.168.1.1", "192.168.1.2"],
+				"ips": ["192.168.1.1", "192.168.1.2"]
+			},
+			{
+				"id": 1,
+				"appName": "数据营销平台",
+				"url": "www.baidu.com",
+				"isMarketing": 1,
+				"isHttp": 0,
+				"https": ["192.168.1.1", "192.168.1.2"],
+				"ips": ["192.168.1.1", "192.168.1.2"]
+			}
+		]
+	}
+}

+ 302 - 0
package-lock.json

@@ -15,6 +15,7 @@
 				"@wangeditor-next/editor-for-vue": "5.1.14",
 				"autoprefixer": "10.4.20",
 				"axios": "1.7.9",
+				"child_process": "^1.0.2",
 				"china-area-data": "^5.0.1",
 				"codemirror": "5.65.18",
 				"crypto-js": "4.2.0",
@@ -26,6 +27,7 @@
 				"js-cookie": "3.0.5",
 				"mitt": "3.0.1",
 				"nprogress": "0.2.0",
+				"ora": "^8.2.0",
 				"pinia": "2.3.0",
 				"postcss": "8.4.49",
 				"qs": "6.13.1",
@@ -33,6 +35,7 @@
 				"sm-crypto": "0.3.13",
 				"sortablejs": "1.15.6",
 				"splitpanes": "3.1.8",
+				"ssh2": "^1.16.0",
 				"tailwindcss": "3.4.17",
 				"vue": "3.5.13",
 				"vue-clipboard3": "2.0.0",
@@ -2305,6 +2308,15 @@
 			"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
 			"dev": true
 		},
+		"node_modules/asn1": {
+			"version": "0.2.6",
+			"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+			"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+			"license": "MIT",
+			"dependencies": {
+				"safer-buffer": "~2.1.0"
+			}
+		},
 		"node_modules/async-validator": {
 			"version": "4.2.5",
 			"resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
@@ -2366,6 +2378,15 @@
 			"resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
 			"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
 		},
+		"node_modules/bcrypt-pbkdf": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+			"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+			"license": "BSD-3-Clause",
+			"dependencies": {
+				"tweetnacl": "^0.14.3"
+			}
+		},
 		"node_modules/binary-extensions": {
 			"version": "2.3.0",
 			"resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
@@ -2439,6 +2460,15 @@
 			"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
 			"dev": true
 		},
+		"node_modules/buildcheck": {
+			"version": "0.0.6",
+			"resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz",
+			"integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==",
+			"optional": true,
+			"engines": {
+				"node": ">=10.0.0"
+			}
+		},
 		"node_modules/call-bind-apply-helpers": {
 			"version": "1.0.1",
 			"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
@@ -2518,6 +2548,12 @@
 				"url": "https://github.com/chalk/chalk?sponsor=1"
 			}
 		},
+		"node_modules/child_process": {
+			"version": "1.0.2",
+			"resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz",
+			"integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g==",
+			"license": "ISC"
+		},
 		"node_modules/china-area-data": {
 			"version": "5.0.1",
 			"resolved": "https://registry.npmmirror.com/china-area-data/-/china-area-data-5.0.1.tgz",
@@ -2557,6 +2593,33 @@
 				"node": ">= 6"
 			}
 		},
+		"node_modules/cli-cursor": {
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+			"integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+			"license": "MIT",
+			"dependencies": {
+				"restore-cursor": "^5.0.0"
+			},
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/cli-spinners": {
+			"version": "2.9.2",
+			"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
+			"integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=6"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/clipboard": {
 			"version": "2.0.11",
 			"resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
@@ -2628,6 +2691,20 @@
 				"node": "^14.18.0 || >=16.10.0"
 			}
 		},
+		"node_modules/cpu-features": {
+			"version": "0.0.10",
+			"resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz",
+			"integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==",
+			"hasInstallScript": true,
+			"optional": true,
+			"dependencies": {
+				"buildcheck": "~0.0.6",
+				"nan": "^2.19.0"
+			},
+			"engines": {
+				"node": ">=10.0.0"
+			}
+		},
 		"node_modules/cross-env": {
 			"version": "7.0.3",
 			"resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz",
@@ -3473,6 +3550,18 @@
 				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
+		"node_modules/get-east-asian-width": {
+			"version": "1.3.0",
+			"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
+			"integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/get-intrinsic": {
 			"version": "1.2.7",
 			"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
@@ -3732,6 +3821,18 @@
 			"resolved": "https://registry.npmmirror.com/is-hotkey/-/is-hotkey-0.2.0.tgz",
 			"integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw=="
 		},
+		"node_modules/is-interactive": {
+			"version": "2.0.0",
+			"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
+			"integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=12"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/is-number": {
 			"version": "7.0.0",
 			"resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
@@ -3748,6 +3849,18 @@
 				"node": ">=0.10.0"
 			}
 		},
+		"node_modules/is-unicode-supported": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
+			"integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/is-url": {
 			"version": "1.2.4",
 			"resolved": "https://registry.npmmirror.com/is-url/-/is-url-1.2.4.tgz",
@@ -3971,6 +4084,46 @@
 			"resolved": "https://registry.npmmirror.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
 			"integrity": "sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw=="
 		},
+		"node_modules/log-symbols": {
+			"version": "6.0.0",
+			"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz",
+			"integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==",
+			"license": "MIT",
+			"dependencies": {
+				"chalk": "^5.3.0",
+				"is-unicode-supported": "^1.3.0"
+			},
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/log-symbols/node_modules/chalk": {
+			"version": "5.4.1",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+			"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
+			"license": "MIT",
+			"engines": {
+				"node": "^12.17.0 || ^14.13 || >=16.0.0"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/chalk?sponsor=1"
+			}
+		},
+		"node_modules/log-symbols/node_modules/is-unicode-supported": {
+			"version": "1.3.0",
+			"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz",
+			"integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=12"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/lru-cache": {
 			"version": "10.4.3",
 			"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz",
@@ -4044,6 +4197,18 @@
 				"node": ">= 0.6"
 			}
 		},
+		"node_modules/mimic-function": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+			"integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/minimatch": {
 			"version": "9.0.5",
 			"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
@@ -4105,6 +4270,13 @@
 			"resolved": "https://registry.npmmirror.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz",
 			"integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g=="
 		},
+		"node_modules/nan": {
+			"version": "2.23.0",
+			"resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz",
+			"integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==",
+			"license": "MIT",
+			"optional": true
+		},
 		"node_modules/nanoid": {
 			"version": "3.3.8",
 			"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz",
@@ -4203,6 +4375,21 @@
 				"url": "https://github.com/sponsors/ljharb"
 			}
 		},
+		"node_modules/onetime": {
+			"version": "7.0.0",
+			"resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+			"integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+			"license": "MIT",
+			"dependencies": {
+				"mimic-function": "^5.0.0"
+			},
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/optionator": {
 			"version": "0.9.4",
 			"resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz",
@@ -4220,6 +4407,64 @@
 				"node": ">= 0.8.0"
 			}
 		},
+		"node_modules/ora": {
+			"version": "8.2.0",
+			"resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz",
+			"integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==",
+			"license": "MIT",
+			"dependencies": {
+				"chalk": "^5.3.0",
+				"cli-cursor": "^5.0.0",
+				"cli-spinners": "^2.9.2",
+				"is-interactive": "^2.0.0",
+				"is-unicode-supported": "^2.0.0",
+				"log-symbols": "^6.0.0",
+				"stdin-discarder": "^0.2.2",
+				"string-width": "^7.2.0",
+				"strip-ansi": "^7.1.0"
+			},
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
+		"node_modules/ora/node_modules/chalk": {
+			"version": "5.4.1",
+			"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+			"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
+			"license": "MIT",
+			"engines": {
+				"node": "^12.17.0 || ^14.13 || >=16.0.0"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/chalk?sponsor=1"
+			}
+		},
+		"node_modules/ora/node_modules/emoji-regex": {
+			"version": "10.4.0",
+			"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
+			"integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
+			"license": "MIT"
+		},
+		"node_modules/ora/node_modules/string-width": {
+			"version": "7.2.0",
+			"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+			"integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+			"license": "MIT",
+			"dependencies": {
+				"emoji-regex": "^10.3.0",
+				"get-east-asian-width": "^1.0.0",
+				"strip-ansi": "^7.1.0"
+			},
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/p-limit": {
 			"version": "3.1.0",
 			"resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz",
@@ -4734,6 +4979,22 @@
 				"node": ">=4"
 			}
 		},
+		"node_modules/restore-cursor": {
+			"version": "5.1.0",
+			"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+			"integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+			"license": "MIT",
+			"dependencies": {
+				"onetime": "^7.0.0",
+				"signal-exit": "^4.1.0"
+			},
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/reusify": {
 			"version": "1.0.4",
 			"resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz",
@@ -4803,6 +5064,12 @@
 				"queue-microtask": "^1.2.2"
 			}
 		},
+		"node_modules/safer-buffer": {
+			"version": "2.1.2",
+			"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+			"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+			"license": "MIT"
+		},
 		"node_modules/sass": {
 			"version": "1.58.3",
 			"resolved": "https://registry.npmmirror.com/sass/-/sass-1.58.3.tgz",
@@ -5011,6 +5278,35 @@
 				"vue": "^3.2.0"
 			}
 		},
+		"node_modules/ssh2": {
+			"version": "1.16.0",
+			"resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.16.0.tgz",
+			"integrity": "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==",
+			"hasInstallScript": true,
+			"dependencies": {
+				"asn1": "^0.2.6",
+				"bcrypt-pbkdf": "^1.0.2"
+			},
+			"engines": {
+				"node": ">=10.16.0"
+			},
+			"optionalDependencies": {
+				"cpu-features": "~0.0.10",
+				"nan": "^2.20.0"
+			}
+		},
+		"node_modules/stdin-discarder": {
+			"version": "0.2.2",
+			"resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz",
+			"integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==",
+			"license": "MIT",
+			"engines": {
+				"node": ">=18"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/string-width": {
 			"version": "5.1.2",
 			"resolved": "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz",
@@ -5322,6 +5618,12 @@
 			"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
 			"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
 		},
+		"node_modules/tweetnacl": {
+			"version": "0.14.5",
+			"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+			"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
+			"license": "Unlicense"
+		},
 		"node_modules/type": {
 			"version": "2.7.3",
 			"resolved": "https://registry.npmmirror.com/type/-/type-2.7.3.tgz",

+ 8 - 0
package.json

@@ -10,6 +10,7 @@
 		"build": "cross-env NODE_OPTIONS=--max-old-space-size=4096 vite build",
 		"build:docker": "cross-env NODE_OPTIONS=--max-old-space-size=4096 vite build --outDir ./docker/dist/",
 		"lint:eslint": "eslint --fix --ext .js,.cjs,.mjs,.ts,.vue ./src",
+		"pub": "node publish.mjs",
 		"prettier": "prettier --write .",
 		"preview": "vite preview",
 		"serve": "npx serve dist"
@@ -21,17 +22,22 @@
 		"@wangeditor-next/editor-for-vue": "5.1.14",
 		"autoprefixer": "10.4.20",
 		"axios": "1.7.9",
+		"chalk": "^5.4.1",
+		"child_process": "^1.0.2",
 		"china-area-data": "^5.0.1",
 		"codemirror": "5.65.18",
 		"crypto-js": "4.2.0",
 		"dayjs": "^1.11.13",
+		"dotenv": "^17.2.1",
 		"driver.js": "1.3.1",
 		"echarts": "5.5.1",
 		"echarts-countries-js": "^1.0.5",
 		"element-plus": "2.8.7",
+		"fs": "0.0.1-security",
 		"js-cookie": "3.0.5",
 		"mitt": "3.0.1",
 		"nprogress": "0.2.0",
+		"ora": "^8.2.0",
 		"pinia": "2.3.0",
 		"postcss": "8.4.49",
 		"qs": "6.13.1",
@@ -39,6 +45,8 @@
 		"sm-crypto": "0.3.13",
 		"sortablejs": "1.15.6",
 		"splitpanes": "3.1.8",
+		"ssh2": "^1.16.0",
+		"ssh2-sftp-client": "^12.0.1",
 		"tailwindcss": "3.4.17",
 		"vue": "3.5.13",
 		"vue-clipboard3": "2.0.0",

文件差异内容过多而无法显示
+ 261 - 239
pnpm-lock.yaml


文件差异内容过多而无法显示
+ 0 - 0
public/assets/styles/font-awesome.min.css


+ 215 - 0
publish.mjs

@@ -0,0 +1,215 @@
+import { exec } from 'child_process'
+import { Client as SSHClient } from 'ssh2'
+import ora from 'ora'
+import SftpClient from 'ssh2-sftp-client'
+import chalk from 'chalk'
+import fs from 'fs'
+import { loadEnv } from 'vite'
+
+// 创建分隔线
+const createSeparator = (text) => {
+  const width = 60;
+  const padding = Math.floor((width - text.length - 2) / 2);
+  const separator = '='.repeat(padding) + ' ' + text + ' ' + '='.repeat(padding);
+  return chalk.blue('\n' + separator + '\n');
+};
+
+
+const spinner = ora('正在构建项目...').start()
+spinner.stopAndPersist({
+  text:
+    ' __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ \n' +
+    ' |                                                          |\n' +
+    ' |                    *** 运行发布流程 ***                   |\n' +
+    ' |                      【pigx管理系统】                     |\n' +
+    ' | __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ |\n'
+})
+
+spinner.start()
+let speed = 20
+let time = 20
+const count = 400
+const getProgress = () => {
+  const done = '█'
+  const undone = '░'
+  let progress = Math.floor((speed / count) * 50)
+  if (progress > 50) {
+    progress = 50
+  }
+  const progressBar = done.repeat(progress) + undone.repeat(50 - progress)
+  return progressBar
+}
+const interval = setInterval(() => {
+  spinner.text = `正在构建项目 ${getProgress()} 进度${((speed / count) * 100).toFixed(1)}% 耗时${(time / 10).toFixed(1)}秒 `
+  speed++
+  time++
+  if (speed > count) {
+    speed = 400
+  }
+}, 100)
+const env = loadEnv('', process.cwd())
+const command = (list, config, host) => {
+  return new Promise((resolveCommand, rejectCommand) => {
+    const ssh = new SSHClient();
+
+    const runCommand = (index) => {
+      if (index >= list.length) {
+        ssh.end();
+        console.log(chalk.green('✓'), chalk.blue(`端口 ${host} 的远程命令执行完毕`));
+        resolveCommand();
+        return;
+      }
+      const cmd = list[index];
+      console.log(chalk.blue('→'), chalk.gray(`执行命令: ${cmd}`));
+      ssh.exec(cmd, (err, stream) => {
+        if (err) {
+          console.error(chalk.red('✗'), chalk.red(`命令执行失败: ${err}`));
+          ssh.end();
+          rejectCommand(err);
+          return;
+        }
+        let hasError = false;
+        stream.on('close', (code, signal) => {
+          if (hasError && !cmd.includes('docker build')) {
+            console.error(chalk.red('✗'), chalk.red(`命令执行失败,退出码: ${code}`));
+            ssh.end();
+            rejectCommand(new Error(`命令 "${cmd}" 失败,退出码: ${code}`));
+            return;
+          }
+          console.log(chalk.green('✓'), chalk.gray(`命令执行完成: ${cmd}`));
+          runCommand(index + 1);
+        }).on('data', (data) => {
+          console.log(chalk.gray(data.toString())); // 实时输出命令结果
+        }).stderr.on('data', (data) => {
+          hasError = true;
+          console.error(chalk.yellow('!'), chalk.yellow(data.toString())); // 实时输出错误信息
+        });
+      });
+    };
+
+    ssh.on('ready', () => {
+      console.log(chalk.green('✓'), chalk.blue('SSH 连接成功'));
+      runCommand(0);
+    }).connect(config);
+
+    // Handle SSH connection errors
+    ssh.on('error', (err) => {
+      console.error(chalk.red('✗'), chalk.red('SSH 连接错误:'), err);
+      rejectCommand(err);
+    });
+  });
+};
+
+const updateFiles = async () => {
+  spinner.text = '正在链接服务器...';
+ 
+  const config = {
+     host: env.VITE_HOST,
+    port: env.VITE_POST,
+    username: env.VITE_USERNAME,
+    password: env.VITE_PASSWORD
+  };
+  const sftp = new SftpClient();
+
+  if (!fs.existsSync('dist')) {
+    console.error(chalk.red('✗'), chalk.red('构建目录不存在'));
+    spinner.fail('构建目录不存在');
+    spinner.stopAndPersist({ text: '' }); // 停止并清理 spinner
+    return;
+  }
+
+  try {
+    await sftp.connect(config);
+    spinner.succeed(chalk.green('服务器连接成功'));
+    console.log(chalk.blue('→'), chalk.gray('开始上传文件...'));
+    await sftp.uploadDir('dist', '/data/data-marketing-platform/build');
+    console.log(chalk.green('✓'), chalk.blue('6888端口文件上传完成'));
+   
+
+    sftp.end();
+
+    console.log(createSeparator('开始部署 6888 端口'));
+    await command([
+      "cd /data/data-marketing-platform && pwd",
+      "cd /data/data-marketing-platform && ls -la",
+      "cd /data/data-marketing-platform && docker rm -f seo-vue",
+      "cd /data/data-marketing-platform && docker rmi seo-vue",
+      "cd /data/data-marketing-platform && docker build -t seo-vue .",
+      "cd /data/data-marketing-platform && docker run -d --name seo-vue -p 6888:80 seo-vue"
+    ], config, "6888");
+
+   
+
+  } catch (err) {
+    console.error(chalk.red('✗'), chalk.red('部署或文件上传失败:'), err);
+    spinner.fail(err);
+    spinner.stopAndPersist({ text: '' }); // 停止并清理 spinner
+    sftp.end();
+    throw err; // 向上抛出错误,让main函数捕获并处理退出
+  }
+};
+// 项目构建
+console.log(createSeparator('开始构建项目'));
+
+// 使用 Promise 包装构建过程
+const buildWithProgress = () => {
+  return new Promise((resolve, reject) => {
+    // 重置进度条
+    speed = 20;
+    time = 20;
+    spinner.start(); // 确保每次构建前启动 spinner
+    const buildProcess = exec('npm run build');
+    let buildOutput = '';
+
+    buildProcess.stdout.on('data', (data) => {
+      buildOutput += data;
+      // 根据输出更新进度
+      if (data.includes('compiled successfully')) {
+        speed = count;
+      }
+    });
+
+    buildProcess.stderr.on('data', (data) => {
+      buildOutput += data;
+    });
+
+    buildProcess.on('close', async (code) => {
+      if (code === 0) {
+        
+
+        spinner.succeed(chalk.green(`构建成功`));
+        resolve(buildOutput);
+      } else {
+        spinner.fail(chalk.red(`构建失败`));
+        reject(new Error(buildOutput));
+      }
+    });
+  });
+};
+
+// 主构建流程
+const main = async () => {
+  spinner.start(); // 在主流程开始时启动 spinner,用于总体的进度指示
+  try {
+      console.log(createSeparator('开始构建 6888 端口'));
+    // 构建 6888 端口版本
+    await buildWithProgress();
+
+    // 开始部署
+    await updateFiles();
+
+    // 所有任务完成后,打印最终访问路径并停止 spinner
+    clearInterval(interval); // 在所有任务完成后停止进度条动画
+    console.log(createSeparator('部署完成'));
+    console.log(chalk.green('🚀'), chalk.cyan(`6888 端口访问地址: http://${env.VITE_HOST}:6888`));
+    spinner.stopAndPersist({ text: '' }); // 停止并清理 spinner,返回控制台
+    process.exit(0); // 正常退出,返回控制台
+  } catch (error) {
+    console.error(chalk.red('✗'), chalk.red('发布流程出错:'), error);
+    spinner.fail(error);
+    spinner.stopAndPersist({ text: '' }); // 停止并清理 spinner,返回控制台
+    process.exit(1); // 异常退出
+  }};
+
+// 启动主流程
+main();

+ 1 - 1
src/views/marketing/config/form.vue

@@ -37,7 +37,7 @@
 
 <script setup lang="ts" name="systemMenuDialog">
 import {useI18n} from 'vue-i18n';
-import {info, getAppList, save} from '/@/api/marketing/config';
+// import {info, getAppList, save} from '/@/api/marketing/config';
 import {useMessage} from '/@/hooks/message';
 import {rule} from '/@/utils/validate';
 

部分文件因为文件数量过多而无法显示