aaden-cli 1.6.109-rc.0 → 1.6.110
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/AadenDeploy/Utils/enableNgrok.sh +21 -19
- package/AadenDeploy/Utils/fixCronJob.sh +5 -4
- package/AadenDeploy/aadensetup.sh +217 -163
- package/AadenDeploy/checkDeviceId.sh +104 -0
- package/AadenDeploy/setDeviceId.sh +130 -0
- package/README.md +2 -1
- package/dist/index.js +168 -13
- package/dist/patch/202608190700removeGitDoUpdateCron.sh +39 -0
- package/index.js +27 -6
- package/modules/tse-cert.js +89 -0
- package/modules/tse-info.js +44 -6
- package/package.json +2 -2
- package/patch/202608190700removeGitDoUpdateCron.sh +39 -0
- package/dist/patch/202304051415FixDatevMemory.sh +0 -19
- package/patch/202304051415FixDatevMemory.sh +0 -19
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
# 和 aaden-cli 其他地方一样用 -S 喂密码:aaden 没有免密 sudo、又没有终端时(被装机脚本或 set-device-id 调用)裸 sudo 会直接失败
|
|
3
|
+
sudoS() { echo "Innerken322." | sudo -S -p '' "$@"; }
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
sudoS npm config set prefix /usr/local
|
|
4
6
|
cd || exit
|
|
5
|
-
|
|
7
|
+
sudoS rm -rf ngrok
|
|
6
8
|
axel -n 8 "https://aaden-storage.s3.eu-central-1.amazonaws.com/ngrok"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
sudoS cp -f ngrok /etc/aaden/ngrok
|
|
10
|
+
sudoS chmod +x /etc/aaden/ngrok
|
|
9
11
|
|
|
10
12
|
DeviceId=$(cat /var/www/html/Resource/config/config.ini | grep -e DeviceId | cut -d = -f 2 | grep '[1-9]*' | sed 's/"//g')
|
|
11
13
|
aaden-cli update-ngrok-config $DeviceId
|
|
12
14
|
|
|
13
15
|
ServiceFileName=/etc/systemd/system/aaden-ngrok-v3.service
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
sudoS touch $ServiceFileName
|
|
18
|
+
sudoS chmod 777 $ServiceFileName
|
|
17
19
|
echo -e "
|
|
18
20
|
[Unit]
|
|
19
21
|
Description=Ngrok Service v3 For Aaden
|
|
@@ -29,24 +31,24 @@ ExecStart=/etc/aaden/ngrok -config=/etc/aaden/ngrok-config.yml start-all --log=/
|
|
|
29
31
|
[Install]
|
|
30
32
|
WantedBy=multi-user.target
|
|
31
33
|
" >$ServiceFileName
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
sudoS rm /etc/systemd/system/aaden-ngrok.service
|
|
35
|
+
sudoS rm /etc/systemd/system/aaden-ngrok-2.service
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
sudoS systemctl daemon-reload
|
|
38
|
+
sudoS systemctl start aaden-ngrok-v3.service
|
|
39
|
+
sudoS systemctl enable aaden-ngrok-v3.service
|
|
40
|
+
sudoS systemctl stop aaden-ngrok.service
|
|
41
|
+
sudoS systemctl stop aaden-ngrok-2.service
|
|
42
|
+
sudoS systemctl disable aaden-ngrok.service
|
|
43
|
+
sudoS systemctl disable aaden-ngrok-2.service
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
sudoS service aaden-ngrok-v3 restart
|
|
44
46
|
|
|
45
47
|
|
|
46
48
|
|
|
47
49
|
ServiceFileName=/etc/avahi/services/aaden.service
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
sudoS touch $ServiceFileName
|
|
51
|
+
sudoS chmod 777 $ServiceFileName
|
|
50
52
|
echo -e "
|
|
51
53
|
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
|
|
52
54
|
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
|
|
@@ -59,7 +61,7 @@ echo -e "
|
|
|
59
61
|
</service-group>
|
|
60
62
|
" >$ServiceFileName
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
sudoS service avahi-daemon restart
|
|
63
65
|
|
|
64
66
|
echo "ngrok 修复脚本执行完毕。请直接检查ngrok是否正常开启。如果开启,请无视这里的任何报错。"
|
|
65
67
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
# 和 aaden-cli 其他地方一样用 -S 喂密码:aaden 没有免密 sudo、又没有终端时(被装机脚本或 set-device-id 调用)裸 sudo 会直接失败
|
|
3
|
+
sudoS() { echo "Innerken322." | sudo -S -p '' "$@"; }
|
|
2
4
|
echo 'Cronjob Before Aaden'
|
|
3
5
|
echo "Innerken322." | sudo -S crontab -l -u aaden
|
|
4
6
|
echo 'Cronjob Before Root'
|
|
@@ -15,11 +17,10 @@ echo "* * * * * curl --location --request GET 'http://localhost/PHP/BackendData.
|
|
|
15
17
|
echo "* * * * * curl --location --request GET 'http://localhost/PHP/BackendData.php?op=autoSendMonthSummary'" >>conf
|
|
16
18
|
echo "* * * * * curl --location --request GET 'http://localhost/PHP/ZBon.php?op=autoAddCombinedRecord'" >>conf
|
|
17
19
|
echo "3 * * * * curl --location --request GET 'http://localhost/PHP/writeDETax2024.php'" >>conf
|
|
18
|
-
|
|
19
|
-
echo "@reboot sleep 60 && curl --location -X POST 'http://localhost/PHP/UpdateSelf.php?op=doUpdate'" >>conf
|
|
20
|
+
# 不再写 git doUpdate(59 4 / @reboot):git 通道 2026-08 已停用,后端 doUpdate 直接跳过,后端更新改走 root 的 auto-upgrade → light-update
|
|
20
21
|
echo "*/5 * * * * /usr/local/bin/aaden-cli do-log" >>conf
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
sudoS crontab -u aaden -r
|
|
23
|
+
sudoS crontab -u aaden conf
|
|
23
24
|
echo "Innerken322." | sudo -S rm -f conf
|
|
24
25
|
crontab -l -u aaden
|
|
25
26
|
echo "END Aaden Deploy CONFIG"
|
|
@@ -1,180 +1,234 @@
|
|
|
1
|
-
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Aaden 收银机装机:全新的 Ubuntu(或 WSL)→ 可以交付的收银机。
|
|
3
|
+
# aaden-cli install <设备号> (或在 AadenDeploy 目录下 ./aadensetup.sh <设备号>)
|
|
4
|
+
#
|
|
5
|
+
# - 设备号最先问并查云端(checkDeviceId.sh),撞号在装任何东西之前拦下来
|
|
6
|
+
# - 每一步记下退出码和耗时;关键步骤失败就停下;最后做一遍自检,连同每一步的结果作为「出厂安装」事件上报云端
|
|
7
|
+
# - 全部输出另存一份到 /var/log/aaden-setup.log
|
|
8
|
+
# - 可以重跑:数据库已经初始化过就跳过,配置、主机名、/etc/hosts、定时任务都是覆盖写,不会重复追加
|
|
9
|
+
export PATH="/usr/local/bin:$PATH"
|
|
10
|
+
DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
11
|
+
PW='Innerken322.'
|
|
12
|
+
LOG=/var/log/aaden-setup.log
|
|
13
|
+
WEB=/var/www/html
|
|
14
|
+
BACKEND_SRC=/etc/aaden/updateFiles/backendFiles
|
|
15
|
+
|
|
16
|
+
# 和 aaden-cli 其他地方一样用 -S 从 stdin 喂密码。不能再往 sudoS 的命令里重定向 stdin(密码会被当成内容),
|
|
17
|
+
# 需要重定向时写成 sudoS sh -c '… < 文件'
|
|
18
|
+
sudoS() { echo "$PW" | sudo -S -p '' "$@"; }
|
|
19
|
+
is_wsl() { grep -qi microsoft /proc/version 2>/dev/null; }
|
|
20
|
+
|
|
21
|
+
banner() {
|
|
22
|
+
echo ""
|
|
2
23
|
echo "#######################################################################"
|
|
3
|
-
echo
|
|
24
|
+
echo "# $*"
|
|
4
25
|
echo "#######################################################################"
|
|
5
26
|
}
|
|
6
27
|
|
|
7
|
-
|
|
8
|
-
echo "#######################################################################"
|
|
9
|
-
echo "# Start to configurate aaden! #"
|
|
10
|
-
echo "# V 1.0.0 #"
|
|
11
|
-
echo "#######################################################################"
|
|
12
|
-
echo ""
|
|
13
|
-
sudo add-apt-repository ppa:ondrej/php -y
|
|
28
|
+
banner "Aaden 收银机装机"
|
|
14
29
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
echoWithWait "Installing Lamp...."
|
|
22
|
-
sudo snap install axel
|
|
23
|
-
|
|
24
|
-
sudo apt install apache2 -y
|
|
25
|
-
sudo apt install net-tools -y
|
|
26
|
-
sudo apt install software-properties-common apt-transport-https -y
|
|
27
|
-
echoWithWait "Install PHP7.4"
|
|
28
|
-
|
|
29
|
-
sudo apt install mysql-server -y
|
|
30
|
-
sudo apt install aptitude -y
|
|
31
|
-
sudo apt install curl -y
|
|
32
|
-
sudo aptitude -y install expect
|
|
33
|
-
sudo apt install default-jdk -y
|
|
34
|
-
sudo apt install php7.4 php7.4-common libapache2-mod-php7.4 php7.4-cli -y
|
|
35
|
-
sudo apt install php7.4-xml -y
|
|
36
|
-
sudo apt install php7.4-curl php7.4-mysql php7.4-gd php7.4-zip php7.4-intl php7.4-common php7.4-mbstring -y
|
|
37
|
-
sudo update-alternatives --set php /usr/bin/php7.4
|
|
38
|
-
sudo update-alternatives --set phar /usr/bin/phar7.4
|
|
39
|
-
sudo update-alternatives --set phar.phar /usr/bin/phar.phar7.4
|
|
40
|
-
|
|
41
|
-
sudo systemctl restart apache2
|
|
42
|
-
|
|
43
|
-
echoWithWait "Install Complate"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
sudo apt -y install vim apt-transport-https wget software-properties-common
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
echoWithWait "Install Docker Requirment"
|
|
50
|
-
sudo apt-get install -y \
|
|
51
|
-
apt-transport-https \
|
|
52
|
-
ca-certificates \
|
|
53
|
-
curl \
|
|
54
|
-
gnupg-agent \
|
|
55
|
-
software-properties-common
|
|
56
|
-
|
|
57
|
-
sudo apt update -y
|
|
58
|
-
sudo apt-get install ttyload -y
|
|
59
|
-
|
|
60
|
-
echoWithWait "Deploying ssh"
|
|
61
|
-
|
|
62
|
-
sudo apt-get install openssh-server -y
|
|
63
|
-
|
|
64
|
-
echoWithWait "Installing Pip for python3"
|
|
65
|
-
sudo apt-get install python3-pip -y
|
|
66
|
-
|
|
67
|
-
echoWithWait "Get Requests library for python3"
|
|
68
|
-
python3 -m pip install requests
|
|
69
|
-
|
|
70
|
-
sudo apt-get install unzip -y
|
|
71
|
-
curl -sS https://getcomposer.org/installer -o composer-setup.php
|
|
72
|
-
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
|
|
73
|
-
sudo composer self-update
|
|
74
|
-
composer -v
|
|
75
|
-
|
|
76
|
-
sudo chmod +x files/getFile.sh
|
|
77
|
-
sudo chmod 777 -R .
|
|
78
|
-
|
|
79
|
-
cd files/ || exit
|
|
80
|
-
./getFile.sh
|
|
81
|
-
cd ..
|
|
82
|
-
|
|
83
|
-
echoWithWait "Configing MYSQL SECURE, only for remote root disable no, else follow it and set to yes, please set the root password as defaultPassword"
|
|
84
|
-
|
|
85
|
-
sudo chmod +x scureSql.sh
|
|
86
|
-
sudo /bin/bash scureSql.sh 'Innerken322.'
|
|
87
|
-
|
|
88
|
-
echoWithWait "Configing Mysql"
|
|
89
|
-
cd /etc/aaden/updateFiles || exit
|
|
90
|
-
|
|
91
|
-
sudo mysql -uroot < backendFiles/new.sql
|
|
92
|
-
|
|
93
|
-
echoWithWait "Uploading PHP Files"
|
|
94
|
-
sudo mv backendFiles/* /var/www/html/
|
|
95
|
-
sudo service apache2 restart
|
|
96
|
-
sudo chown -hR www-data:www-data /var/www/html
|
|
97
|
-
|
|
98
|
-
sudo chmod -R 777 /var/www/html/Resource
|
|
99
|
-
sudo chmod +x /var/www/html/crontab.sh
|
|
100
|
-
|
|
101
|
-
# give excute permission to migrations
|
|
102
|
-
sudo chmod +x /var/www/html/PHP/vendor/bin/phinx
|
|
103
|
-
sudo chmod +x /var/www/html/PHP/vendor/robmorgan/phinx/bin/phinx
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
echoWithWait "Skip App Install"
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
echoWithWait "Add Cronjob"
|
|
112
|
-
sudo touch conf
|
|
113
|
-
sudo chmod 777 conf
|
|
114
|
-
echo "* * * * * wget -O /dev/null http://localhost/PHP/AccessLog.php?op=reportStatus" >>conf
|
|
115
|
-
echo "* * * * * /var/www/html/crontab.sh > /dev/null" >>conf
|
|
116
|
-
crontab conf && sudo rm -f conf
|
|
117
|
-
crontab -l
|
|
118
|
-
|
|
119
|
-
echoWithWait "Finishing Install"
|
|
120
|
-
|
|
121
|
-
if [ -z "$1" ]; then
|
|
122
|
-
read -p 'DeviceId: ' DeviceId
|
|
123
|
-
else
|
|
124
|
-
DeviceId=$1
|
|
30
|
+
# ---------------------------------------------------------------- 设备号(最先问,先查撞号)
|
|
31
|
+
DEVICE_ID="$1"
|
|
32
|
+
if [ -z "$DEVICE_ID" ]; then
|
|
33
|
+
read -r -p '设备号: ' DEVICE_ID
|
|
125
34
|
fi
|
|
35
|
+
bash "$DIR/checkDeviceId.sh" "$DEVICE_ID" || exit 1
|
|
36
|
+
DEVICE_ID=$((10#$DEVICE_ID))
|
|
37
|
+
export AADEN_SKIP_DEVICE_CHECK=1 # 后面 set-device-id 不再问第二遍
|
|
38
|
+
|
|
39
|
+
# sudo 凭据先缓存上并一直续着:装机要十几分钟,中途调的 aaden-cli 子命令里还有裸 sudo
|
|
40
|
+
sudoS -v 2>/dev/null || sudo -v || exit 1
|
|
41
|
+
(while kill -0 $$ 2>/dev/null; do sudoS -v 2>/dev/null; sleep 50; done) &
|
|
42
|
+
KEEPALIVE=$!
|
|
43
|
+
trap 'kill $KEEPALIVE 2>/dev/null' EXIT
|
|
44
|
+
|
|
45
|
+
sudoS touch "$LOG" && sudoS chmod 666 "$LOG"
|
|
46
|
+
exec > >(tee -a "$LOG") 2>&1
|
|
47
|
+
echo "$(date '+%F %T') 开始装机,设备号 $DEVICE_ID"
|
|
48
|
+
|
|
49
|
+
# ---------------------------------------------------------------- 步骤记录与上报
|
|
50
|
+
STEPS=""
|
|
51
|
+
step() { # step <名字> <命令…>:输出照常打到屏幕,记下退出码和耗时
|
|
52
|
+
local name=$1 start=$SECONDS code
|
|
53
|
+
shift
|
|
54
|
+
banner "$name"
|
|
55
|
+
"$@"
|
|
56
|
+
code=$?
|
|
57
|
+
STEPS="$STEPS $name=$code/$((SECONDS - start))s"
|
|
58
|
+
[ "$code" = 0 ] || echo "✗ $name 失败(退出码 $code),详细输出见 $LOG"
|
|
59
|
+
return "$code"
|
|
60
|
+
}
|
|
126
61
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
sudo usermod -a -G lp aaden
|
|
138
|
-
sudo usermod -a -G lp www-data
|
|
139
|
-
sudo usermod -a -G root aaden
|
|
140
|
-
sudo usermod -a -G root www-data
|
|
141
|
-
sudo usermod -a -G adm aaden
|
|
142
|
-
sudo usermod -a -G sudo aaden
|
|
143
|
-
|
|
144
|
-
echoWithWait "RUN MIGRATION"
|
|
145
|
-
# run migrations
|
|
146
|
-
cd /var/www/html/PHP || exit
|
|
147
|
-
vendor/bin/phinx migrate
|
|
62
|
+
report() { # report <result> <附加内容>:「出厂安装」事件,在云端设备事件里能看到每一步和自检结果
|
|
63
|
+
local content="出厂安装 [${STEPS# }]$2 result:$1"
|
|
64
|
+
python3 - "$DEVICE_ID" "$content" "$(aaden-cli --version 2>/dev/null | tail -n 1)" <<'PY' || echo "(上报云端失败)"
|
|
65
|
+
import json, sys, urllib.request
|
|
66
|
+
device_id, content, version = sys.argv[1:4]
|
|
67
|
+
body = json.dumps({"deviceId": device_id, "content": content, "type": "系统生成", "operator": "aaden-cli v" + version}).encode()
|
|
68
|
+
urllib.request.urlopen(urllib.request.Request("https://cloud-v2.aaden.io/deviceLog/createEvent", body, {"Content-Type": "application/json"}), timeout=10)
|
|
69
|
+
PY
|
|
70
|
+
}
|
|
148
71
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
aaden-cli fix-ngrok
|
|
72
|
+
must() { # 关键步骤:失败就上报并停下,后面的步骤都依赖它
|
|
73
|
+
step "$@" && return 0
|
|
74
|
+
report 1 " 中止于 $1"
|
|
75
|
+
banner "装机中止:$1 失败。修好之后重新运行同一条命令即可,已经完成的部分会跳过或覆盖。日志:$LOG"
|
|
76
|
+
exit 1
|
|
77
|
+
}
|
|
156
78
|
|
|
79
|
+
# ---------------------------------------------------------------- 1. 系统软件
|
|
80
|
+
install_packages() {
|
|
81
|
+
local apt="env DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold"
|
|
82
|
+
# 上次装到一半断掉(断电、断网、包脚本失败)留下的半配置状态先收拾掉,否则后面的 apt 全部报错
|
|
83
|
+
sudoS env DEBIAN_FRONTEND=noninteractive dpkg --configure -a
|
|
84
|
+
command -v add-apt-repository >/dev/null || sudoS $apt install software-properties-common || return 1
|
|
85
|
+
# Ubuntu 22.04 起官方源没有 PHP 7.4
|
|
86
|
+
sudoS add-apt-repository -y ppa:ondrej/php || return 1
|
|
87
|
+
sudoS apt-get update || return 1
|
|
88
|
+
sudoS $apt install \
|
|
89
|
+
apache2 mysql-server \
|
|
90
|
+
php7.4 php7.4-common php7.4-cli libapache2-mod-php7.4 \
|
|
91
|
+
php7.4-xml php7.4-curl php7.4-mysql php7.4-gd php7.4-zip php7.4-intl php7.4-mbstring \
|
|
92
|
+
default-jdk openssh-server \
|
|
93
|
+
curl wget unzip axel expect vim net-tools ttyload ca-certificates apt-transport-https \
|
|
94
|
+
python3-requests || return 1
|
|
95
|
+
# 装了别的 PHP 版本时,命令行默认的 php 也指向 7.4
|
|
96
|
+
sudoS update-alternatives --set php /usr/bin/php7.4
|
|
97
|
+
sudoS update-alternatives --set phar /usr/bin/phar7.4 2>/dev/null
|
|
98
|
+
sudoS update-alternatives --set phar.phar /usr/bin/phar.phar7.4 2>/dev/null
|
|
99
|
+
sudoS systemctl restart apache2 2>/dev/null || sudoS service apache2 restart
|
|
100
|
+
}
|
|
101
|
+
must apt install_packages
|
|
157
102
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
103
|
+
# ---------------------------------------------------------------- 2. 后端代码
|
|
104
|
+
download_backend() {
|
|
105
|
+
bash "$DIR/files/getFile.sh" && [ -f "$BACKEND_SRC/package.json" ]
|
|
106
|
+
}
|
|
107
|
+
must download download_backend
|
|
108
|
+
|
|
109
|
+
# ---------------------------------------------------------------- 3. 数据库
|
|
110
|
+
setup_database() {
|
|
111
|
+
# 先确保 MySQL 在跑(没有 systemd 的 WSL 不会自动起),否则下面的判断会把已有的库当成没有
|
|
112
|
+
sudoS service mysql start 2>/dev/null
|
|
113
|
+
# 没有 systemd 时 socket 目录可能是 700,aaden 跑数据库迁移会连不上(SQLSTATE 2002 Permission denied)
|
|
114
|
+
sudoS chmod 755 /var/run/mysqld 2>/dev/null
|
|
115
|
+
if sudoS mysql -uroot -e 'USE aaden' 2>/dev/null || sudoS test -d /var/lib/mysql/aaden; then
|
|
116
|
+
echo "数据库 aaden 已存在,跳过初始化(重跑装机不会覆盖门店数据)"
|
|
117
|
+
return 0
|
|
118
|
+
fi
|
|
119
|
+
sudoS bash "$DIR/scureSql.sh" "$PW"
|
|
120
|
+
sudoS sh -c "mysql -uroot < '$BACKEND_SRC/new.sql'" && sudoS mysql -uroot -e 'USE aaden'
|
|
121
|
+
}
|
|
122
|
+
must db setup_database
|
|
123
|
+
|
|
124
|
+
# ---------------------------------------------------------------- 4. 部署后端
|
|
125
|
+
deploy_backend() {
|
|
126
|
+
# cp 而不是 mv:重跑时目标目录已存在,mv 会失败
|
|
127
|
+
sudoS cp -a "$BACKEND_SRC/." "$WEB/" || return 1
|
|
128
|
+
sudoS rm -rf "$BACKEND_SRC"
|
|
129
|
+
sudoS chown -hR www-data:www-data "$WEB"
|
|
130
|
+
sudoS chmod -R 777 "$WEB/Resource"
|
|
131
|
+
sudoS chmod +x "$WEB/crontab.sh" "$WEB/PHP/vendor/bin/phinx" "$WEB/PHP/vendor/robmorgan/phinx/bin/phinx"
|
|
132
|
+
sudoS systemctl restart apache2 2>/dev/null || sudoS service apache2 restart
|
|
133
|
+
sleep 2
|
|
134
|
+
curl -fsS -m 10 http://localhost/package.json | grep '"version"'
|
|
135
|
+
}
|
|
136
|
+
must deploy deploy_backend
|
|
164
137
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
echo "# Install TeamViewer #"
|
|
168
|
-
echo "# V 1.0.0 #"
|
|
169
|
-
echo "#######################################################################"
|
|
170
|
-
echo ""
|
|
138
|
+
# ---------------------------------------------------------------- 5. 设备号:配置、主机名、ngrok、上报
|
|
139
|
+
must device aaden-cli set-device-id "$DEVICE_ID"
|
|
171
140
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
sudo apt -y install ./teamviewer_amd64.deb
|
|
141
|
+
# ---------------------------------------------------------------- 6. 数据库迁移
|
|
142
|
+
must migrate sh -c "cd '$WEB/PHP' && vendor/bin/phinx migrate"
|
|
175
143
|
|
|
176
|
-
|
|
144
|
+
# ---------------------------------------------------------------- 7. 系统配置(失败不中止,最后的自检会标出来)
|
|
145
|
+
add_groups() {
|
|
146
|
+
# 打印机(lp)、读日志(adm)、aaden 能 sudo;www-data 要能访问 USB 打印机
|
|
147
|
+
sudoS usermod -a -G lp,root,adm,sudo aaden && sudoS usermod -a -G lp,root www-data
|
|
148
|
+
}
|
|
149
|
+
step groups add_groups
|
|
150
|
+
step patch aaden-cli patch
|
|
151
|
+
# 日结物化守护进程:每日数据库备份和 DSFinV-K 日结物化都靠它
|
|
152
|
+
step gdpdu aaden-cli auto-write-gdpdu
|
|
153
|
+
# aaden 和 root 的定时任务整份覆盖写(do-log 上报、每日自动更新等)
|
|
154
|
+
step cron aaden-cli fix-cronjob
|
|
155
|
+
# 升级 aaden-cli、跑补丁、后端 light-update、同步 AppCenter 前端
|
|
156
|
+
step upgrade aaden-cli upgrade
|
|
157
|
+
|
|
158
|
+
if ! is_wsl; then
|
|
159
|
+
install_teamviewer() {
|
|
160
|
+
local deb
|
|
161
|
+
deb=$(mktemp --suffix=.deb)
|
|
162
|
+
wget -q -O "$deb" https://download.teamviewer.com/download/linux/teamviewer_amd64.deb \
|
|
163
|
+
&& sudoS env DEBIAN_FRONTEND=noninteractive apt-get -y install "$deb"
|
|
164
|
+
local code=$?
|
|
165
|
+
rm -f "$deb"
|
|
166
|
+
wget -q -O "$HOME/background.png" https://aaden.online/AadenOS/background.png
|
|
167
|
+
return $code
|
|
168
|
+
}
|
|
169
|
+
step teamviewer install_teamviewer
|
|
170
|
+
fi
|
|
177
171
|
|
|
172
|
+
# ---------------------------------------------------------------- 8. 自检
|
|
173
|
+
banner "自检"
|
|
174
|
+
CHECKS=""
|
|
175
|
+
BAD=""
|
|
176
|
+
check() { # check <key> <说明> <命令…>
|
|
177
|
+
local key=$1 label=$2
|
|
178
|
+
shift 2
|
|
179
|
+
if "$@" >/dev/null 2>&1; then
|
|
180
|
+
CHECKS="$CHECKS $key=ok"
|
|
181
|
+
echo " ✓ $label"
|
|
182
|
+
else
|
|
183
|
+
CHECKS="$CHECKS $key=FAIL"
|
|
184
|
+
BAD="$BAD $label"
|
|
185
|
+
echo " ✗ $label"
|
|
186
|
+
fi
|
|
187
|
+
}
|
|
188
|
+
NGROK_HOST="ik$(printf '%04d' "$DEVICE_ID").ngrok.aaden.io"
|
|
178
189
|
|
|
190
|
+
check_cloud() {
|
|
191
|
+
aaden-cli do-log >/dev/null 2>&1
|
|
192
|
+
curl -fsS -m 15 "https://cloud-v2.aaden.io/deviceLog/install-check/$DEVICE_ID" \
|
|
193
|
+
| python3 -c 'import json,sys; m = json.load(sys.stdin).get("lastReportMinutesAgo"); sys.exit(0 if m is not None and m <= 10 else 1)'
|
|
194
|
+
}
|
|
195
|
+
check_ngrok() { # 隧道刚起来时要等几秒
|
|
196
|
+
local i
|
|
197
|
+
for i in 1 2 3 4 5 6; do
|
|
198
|
+
curl -fsS -m 10 "https://$NGROK_HOST/package.json" | grep -q '"version"' && return 0
|
|
199
|
+
sleep 10
|
|
200
|
+
done
|
|
201
|
+
return 1
|
|
202
|
+
}
|
|
203
|
+
check_gdpdu() {
|
|
204
|
+
systemctl is-active --quiet aaden-gdpdu.service 2>/dev/null \
|
|
205
|
+
|| pgrep -f 'autoWriteGdpdu\.php' >/dev/null \
|
|
206
|
+
|| [ -f /etc/cron.d/aaden-gdpdu ]
|
|
207
|
+
}
|
|
208
|
+
check_cron() {
|
|
209
|
+
crontab -l 2>/dev/null | grep -q 'do-log' && sudoS crontab -l -u root 2>/dev/null | grep -q 'auto-upgrade'
|
|
210
|
+
}
|
|
179
211
|
|
|
212
|
+
check_id() {
|
|
213
|
+
[ "$(awk -F= '/^\[/ { s = $0 } s ~ /^\[Device\]/ && $1 ~ /^[ \t]*DeviceId[ \t]*$/ { gsub(/[ \t"\r]/, "", $2); print $2; exit }' "$WEB/Resource/config/config.ini")" = "$DEVICE_ID" ]
|
|
214
|
+
}
|
|
180
215
|
|
|
216
|
+
check backend "后端在跑(http://localhost/package.json)" sh -c 'curl -fsS -m 10 http://localhost/package.json | grep -q version'
|
|
217
|
+
check id "设备号写入配置($DEVICE_ID)" check_id
|
|
218
|
+
check cloud "云端收到本机上报(ERP 门店列表「机器」列显示就绪)" check_cloud
|
|
219
|
+
check ngrok "远程访问 https://$NGROK_HOST" check_ngrok
|
|
220
|
+
check gdpdu "日结守护进程 aaden-gdpdu(没有它就没有每日备份)" check_gdpdu
|
|
221
|
+
check cron "定时任务(上报、每日自动更新)" check_cron
|
|
222
|
+
|
|
223
|
+
FAILED_STEPS=$(echo "$STEPS" | tr ' ' '\n' | grep -v '=0/' | cut -d= -f1 | tr '\n' ' ')
|
|
224
|
+
if [ -z "$BAD" ] && [ -z "${FAILED_STEPS// /}" ]; then
|
|
225
|
+
report 0 " [自检${CHECKS}]"
|
|
226
|
+
banner "装机完成,设备号 $DEVICE_ID,可以交付"
|
|
227
|
+
exit 0
|
|
228
|
+
fi
|
|
229
|
+
report 1 " [自检${CHECKS}]"
|
|
230
|
+
banner "装机跑完了,但有问题要处理"
|
|
231
|
+
[ -n "${FAILED_STEPS// /}" ] && echo "失败的步骤:$FAILED_STEPS"
|
|
232
|
+
[ -n "$BAD" ] && echo "没通过的自检:$BAD"
|
|
233
|
+
echo "处理完可以重新运行同一条命令。日志:$LOG"
|
|
234
|
+
exit 1
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 装机前检查设备号:这个号在 ERP 是哪家店、是不是已经有收银机在用。拦住输错号、用了别家号的「撞号」——
|
|
3
|
+
# 同一个号装两台机器,云端的上报、备份、报表、远程连接(ngrok ik 号)会互相覆盖。
|
|
4
|
+
#
|
|
5
|
+
# 退出码 0 = 继续装;1 = 号不对或装机同事取消。
|
|
6
|
+
# 连不上云端只警告、不挡安装(现场网络常常不好)。确实要跳过检查:AADEN_SKIP_DEVICE_CHECK=1
|
|
7
|
+
DeviceId="$1"
|
|
8
|
+
CLOUD="${AADEN_CLOUD_URL:-https://cloud-v2.aaden.io}"
|
|
9
|
+
|
|
10
|
+
[ -n "$AADEN_SKIP_DEVICE_CHECK" ] && { echo "跳过设备号检查(AADEN_SKIP_DEVICE_CHECK)"; exit 0; }
|
|
11
|
+
if ! [[ "$DeviceId" =~ ^[0-9]+$ ]]; then
|
|
12
|
+
echo "设备号必须是数字:'$DeviceId'"
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
# 提问走 /dev/tty:脚本的标准输入可能被管道占着。没有终端(自动化装机)时 ask 返回空串
|
|
17
|
+
HAVE_TTY=""
|
|
18
|
+
{ exec 3</dev/tty; } 2>/dev/null && HAVE_TTY=1
|
|
19
|
+
ask() {
|
|
20
|
+
local answer=""
|
|
21
|
+
[ -n "$HAVE_TTY" ] && read -r -p "$1" answer <&3 2>/dev/tty
|
|
22
|
+
echo "$answer"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
URL="$CLOUD/deviceLog/install-check/$DeviceId"
|
|
26
|
+
JSON=$(curl -fsS -m 15 "$URL" 2>/dev/null || wget -qO- -T 15 "$URL" 2>/dev/null)
|
|
27
|
+
|
|
28
|
+
# 第一行是结论(OK / IN_USE / NO_STORE / ERROR),后面是给装机同事看的说明
|
|
29
|
+
REPORT=$(python3 - "$JSON" <<'PY'
|
|
30
|
+
import json, sys
|
|
31
|
+
try:
|
|
32
|
+
d = json.loads(sys.argv[1])
|
|
33
|
+
store, machine = d.get("store"), d.get("machine")
|
|
34
|
+
except Exception:
|
|
35
|
+
print("ERROR")
|
|
36
|
+
sys.exit()
|
|
37
|
+
|
|
38
|
+
status = {"AwaitingInstallation": "等待安装", "Installed": "已安装", "Closed": "已关停", "StopService": "停止服务"}
|
|
39
|
+
|
|
40
|
+
def when(v):
|
|
41
|
+
return v[:16].replace("T", " ") if v else "—"
|
|
42
|
+
|
|
43
|
+
def ago(minutes):
|
|
44
|
+
if minutes is None:
|
|
45
|
+
return "—"
|
|
46
|
+
if minutes < 60:
|
|
47
|
+
return f"{max(minutes, 1)} 分钟前"
|
|
48
|
+
if minutes < 24 * 60:
|
|
49
|
+
return f"{round(minutes / 60)} 小时前"
|
|
50
|
+
return f"{round(minutes / 60 / 24)} 天前"
|
|
51
|
+
|
|
52
|
+
if not store:
|
|
53
|
+
print("NO_STORE")
|
|
54
|
+
sys.exit()
|
|
55
|
+
|
|
56
|
+
parts = [p for p in (store.get("displayCode"), store.get("city"), status.get(store.get("status"), store.get("status"))) if p]
|
|
57
|
+
store_line = f"ERP 门店「{store.get('name') or '—'}」({','.join(parts)})"
|
|
58
|
+
|
|
59
|
+
if machine:
|
|
60
|
+
print("IN_USE")
|
|
61
|
+
print(f" 收银机里的餐厅名:{machine.get('posName') or '—'}")
|
|
62
|
+
print(f" 第一次上报 {when(machine.get('firstReportAt'))},最近上报 {ago(d.get('lastReportMinutesAgo'))}")
|
|
63
|
+
print(f" {store_line}")
|
|
64
|
+
else:
|
|
65
|
+
print("OK")
|
|
66
|
+
print(f" {store_line}")
|
|
67
|
+
print(" 云端还没收到过这个号的收银机上报")
|
|
68
|
+
PY
|
|
69
|
+
)
|
|
70
|
+
VERDICT=$(echo "$REPORT" | head -n 1)
|
|
71
|
+
DETAIL=$(echo "$REPORT" | tail -n +2)
|
|
72
|
+
|
|
73
|
+
echo ""
|
|
74
|
+
echo "#######################################################################"
|
|
75
|
+
echo "检查设备号 $DeviceId"
|
|
76
|
+
case "$VERDICT" in
|
|
77
|
+
OK)
|
|
78
|
+
echo "$DETAIL"
|
|
79
|
+
# 没有终端可问(自动化装机)时号也没人用,直接继续
|
|
80
|
+
if [ -n "$HAVE_TTY" ]; then
|
|
81
|
+
answer=$(ask "是这家店吗?[y/N] ")
|
|
82
|
+
[[ "$answer" =~ ^[yY] ]] || { echo "已取消。"; exit 1; }
|
|
83
|
+
fi
|
|
84
|
+
;;
|
|
85
|
+
IN_USE)
|
|
86
|
+
echo "⚠ 这个号已经有收银机在用:"
|
|
87
|
+
echo "$DETAIL"
|
|
88
|
+
echo "同一个号装两台机器,云端的上报、备份、报表、远程连接会互相覆盖。"
|
|
89
|
+
echo "只有给这家店换机或重装才应该继续,而且旧机器要先关掉。"
|
|
90
|
+
answer=$(ask "确认继续请再输入一遍设备号(直接回车取消):")
|
|
91
|
+
[ "$answer" = "$DeviceId" ] || { echo "已取消。"; exit 1; }
|
|
92
|
+
;;
|
|
93
|
+
NO_STORE)
|
|
94
|
+
echo "✗ ERP 里没有编号 $DeviceId 的门店:先在 ERP 建档,或者检查设备号有没有输错。"
|
|
95
|
+
echo " 确实要装:AADEN_SKIP_DEVICE_CHECK=1 再跑一次"
|
|
96
|
+
exit 1
|
|
97
|
+
;;
|
|
98
|
+
*)
|
|
99
|
+
echo "⚠ 连不上云端($CLOUD),没法检查设备号有没有撞号,继续安装。"
|
|
100
|
+
sleep 3
|
|
101
|
+
;;
|
|
102
|
+
esac
|
|
103
|
+
echo "#######################################################################"
|
|
104
|
+
exit 0
|