@yorha2b-lab/autodev 2.1.4 → 2.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/main.yml +32 -24
- package/package.json +1 -1
- package/templates/react/utils/utils.js +53 -0
|
@@ -1,49 +1,50 @@
|
|
|
1
|
-
name: Bunker Native Stats
|
|
1
|
+
name: Bunker Native Stats & Intelligence
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
schedule:
|
|
5
|
-
- cron: '45 19 * * *' # 北京时间凌晨 03:45
|
|
5
|
+
- cron: '45 19 * * *' # 北京时间凌晨 03:45 自动巡航
|
|
6
6
|
workflow_dispatch:
|
|
7
7
|
|
|
8
|
-
# 💡 补丁 1:强制开启 Node.js 24,消灭那个烦人的黄色警告
|
|
9
8
|
env:
|
|
10
9
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
11
10
|
|
|
12
11
|
jobs:
|
|
13
|
-
|
|
12
|
+
recon-and-ledger:
|
|
14
13
|
runs-on: ubuntu-latest
|
|
15
14
|
permissions:
|
|
16
15
|
contents: write
|
|
17
16
|
steps:
|
|
18
|
-
# 1. 检出数据分支
|
|
19
17
|
- name: Checkout Data Branch
|
|
20
18
|
uses: actions/checkout@v4
|
|
21
19
|
with:
|
|
22
20
|
ref: github-repo-stats
|
|
23
21
|
token: ${{ secrets.STATS_TOKEN }}
|
|
24
|
-
fetch-depth: 0
|
|
22
|
+
fetch-depth: 0
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
- name: Fetch and Smart Merge
|
|
24
|
+
- name: Intelligence Gathering & Sovereign Merge
|
|
28
25
|
run: |
|
|
29
|
-
echo "🤖 Pod 042:
|
|
26
|
+
echo "🤖 Pod 042: 启动‘全频道情报采集协议 [坐标修正版]’..."
|
|
30
27
|
|
|
31
|
-
# A.
|
|
32
|
-
curl -
|
|
28
|
+
# A. [情报收集]:修正 API 路径,加入 /popular/ 层级
|
|
29
|
+
curl -s -H "Authorization: token ${{ secrets.STATS_TOKEN }}" \
|
|
33
30
|
-H "Accept: application/vnd.github.v3+json" \
|
|
34
|
-
https://api.github.com/repos/${{ github.repository }}/traffic/clones >
|
|
31
|
+
https://api.github.com/repos/${{ github.repository }}/traffic/clones > raw_clones.json
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
curl -s -H "Authorization: token ${{ secrets.STATS_TOKEN }}" \
|
|
34
|
+
-H "Accept: application/vnd.github.v3+json" \
|
|
35
|
+
https://api.github.com/repos/${{ github.repository }}/traffic/popular/referrers > raw_referrers.json
|
|
36
|
+
|
|
37
|
+
# B. [格式处理]
|
|
37
38
|
mkdir -p ghrs-data
|
|
38
39
|
echo "date,clones,uniques" > /tmp/new_data.csv
|
|
39
|
-
jq -r '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques)"'
|
|
40
|
+
jq -r '.clones[] | "\(.timestamp[0:10]),\(.count),\(.uniques)"' raw_clones.json >> /tmp/new_data.csv
|
|
40
41
|
|
|
41
|
-
# C.
|
|
42
|
+
# C. [物理焊接]
|
|
42
43
|
LEDGER="ghrs-data/clones_ledger.csv"
|
|
43
44
|
if [ ! -f "$LEDGER" ]; then
|
|
44
45
|
cp /tmp/new_data.csv "$LEDGER"
|
|
45
46
|
else
|
|
46
|
-
echo "📡
|
|
47
|
+
echo "📡 执行物理序列重组..."
|
|
47
48
|
(head -n 1 "$LEDGER"; tail -n +2 "$LEDGER"; tail -n +2 /tmp/new_data.csv) | \
|
|
48
49
|
sed 's/\//-/g' | \
|
|
49
50
|
awk -F',' 'NR>1 {
|
|
@@ -57,25 +58,32 @@ jobs:
|
|
|
57
58
|
cat /tmp/final_ledger.csv >> "$LEDGER"
|
|
58
59
|
fi
|
|
59
60
|
|
|
60
|
-
# D.
|
|
61
|
-
# 确保 awk 逻辑百分之百执行
|
|
61
|
+
# D. [战绩结算]
|
|
62
62
|
TOTAL_CLONES=$(awk -F',' 'NR>1 {sum+=$2} END {print sum}' "$LEDGER")
|
|
63
63
|
echo "{\"total_clones\": $TOTAL_CLONES}" > bunker-stats.json
|
|
64
|
-
echo "✅ 物理总数结算达成: $TOTAL_CLONES"
|
|
65
64
|
|
|
66
|
-
# E.
|
|
65
|
+
# E. [报表装修]
|
|
67
66
|
echo "# 🛰️ 地堡运行报告 (Sovereign Report)" > README.md
|
|
68
67
|
echo "### 📊 累计物理克隆总数: **$TOTAL_CLONES**" >> README.md
|
|
69
68
|
echo "数据已根据 AGPL-3.0 协议物理封存。愿人类荣光永存。" >> README.md
|
|
70
69
|
echo "" >> README.md
|
|
71
|
-
echo "
|
|
70
|
+
echo "#### 📡 流量来源实时追踪 (Top Referrers)" >> README.md
|
|
71
|
+
echo "| 来源站点 | 总访问量 | 独立指挥官 |" >> README.md
|
|
72
|
+
echo "| :--- | :--- | :--- |" >> README.md
|
|
73
|
+
# 增加判定,防止 referrers 为空时 jq 报错
|
|
74
|
+
if [ -s raw_referrers.json ]; then
|
|
75
|
+
jq -r '.[] | "| \(.referrer) | \(.count) | \(.uniques) |"' raw_referrers.json >> README.md
|
|
76
|
+
else
|
|
77
|
+
echo "| 暂无外部来源信号 | - | - |" >> README.md
|
|
78
|
+
fi
|
|
79
|
+
echo "" >> README.md
|
|
80
|
+
echo "> 📡 信号状态:全频道在线 | 数据物理封存点: $(date +'%Y-%m-%d %H:%M:%S') CST" >> README.md
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
- name: Commit and Push
|
|
82
|
+
- name: Sync Ledger to Cloud
|
|
75
83
|
run: |
|
|
76
84
|
git config user.name github-actions
|
|
77
85
|
git config user.email github-actions@github.com
|
|
78
86
|
git add -A
|
|
79
87
|
TOTAL=$(grep -oE "[0-9]+" bunker-stats.json | head -n 1)
|
|
80
|
-
git commit -m "chore:
|
|
88
|
+
git commit -m "chore: intelligence update - total $TOTAL" || echo "no changes"
|
|
81
89
|
git push origin github-repo-stats --force
|
package/package.json
CHANGED
|
@@ -70,6 +70,59 @@ export const exportDataToExcel = async (url, options, columns, fileName, formatt
|
|
|
70
70
|
} */
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
export const streamDownload = async ({ url, options, headers = {} }, fileName = '下载') => {
|
|
74
|
+
|
|
75
|
+
const response = await fetch(url, { ...options, headers })
|
|
76
|
+
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
console.error(response.statusText)
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const blob = await response.blob()
|
|
83
|
+
|
|
84
|
+
if (!blob.size) {
|
|
85
|
+
console.error('文件为空')
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const slice = blob.slice(0, 10)
|
|
90
|
+
const text = (await slice.text()).trim()
|
|
91
|
+
|
|
92
|
+
if (text.startsWith('{') || text.startsWith('[')) {
|
|
93
|
+
try {
|
|
94
|
+
const fullText = await blob.text()
|
|
95
|
+
const json = JSON.parse(fullText)
|
|
96
|
+
console.error(json?.msg ?? '系统异常')
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error(error)
|
|
99
|
+
}
|
|
100
|
+
return
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const disposition = response.headers.get('content-disposition')
|
|
104
|
+
let name = fileName
|
|
105
|
+
|
|
106
|
+
if (disposition) {
|
|
107
|
+
const match = disposition.match(/filename\*=UTF-8''([^;]+)|filename="?([^";]+)"?/)
|
|
108
|
+
if (match) {
|
|
109
|
+
name = decodeURIComponent(match[1] || match[2])
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const link = document.createElement('a')
|
|
114
|
+
const urlObj = URL.createObjectURL(blob)
|
|
115
|
+
|
|
116
|
+
link.href = urlObj
|
|
117
|
+
link.download = name
|
|
118
|
+
|
|
119
|
+
document.body.appendChild(link)
|
|
120
|
+
link.click()
|
|
121
|
+
link.remove()
|
|
122
|
+
|
|
123
|
+
setTimeout(() => URL.revokeObjectURL(urlObj), 1000)
|
|
124
|
+
}
|
|
125
|
+
|
|
73
126
|
export const moneyRender = (value, { decimals = 2, currency = 'CNY', language = 'zh-CN', showSymbol = true } = {}) => {
|
|
74
127
|
if (value === null || value === undefined || value === '') return '-'
|
|
75
128
|
const number = Number(value)
|