提交
This commit is contained in:
1 parent
ff1228873c
commit
34a843e790
23 files changed
+1541
-718
No files matched your search
+19
-23
@@ -9,13 +9,10 @@
|
||||
1. **`process_student_changes.sh`** - 处理毕业、退学、休学的状态变更
|
||||
2. **`process_student_resume.sh`** - 处理复学的状态变更
|
||||
3. **`control_scripts.sh`** - 脚本控制程序(启动、停止、重启)
|
||||
4. **`start_services.sh`** - 一键启动所有服务
|
||||
5. **`stop_services.sh`** - 一键停止所有服务
|
||||
6. **`health_check.sh`** - 服务健康检查脚本
|
||||
7. **`data.conf`** - 数据库配置文件
|
||||
8. **`test_data.sql`** - 测试数据脚本
|
||||
9. **`optional_crontab_config.txt`** - 可选的定时任务配置(备用)
|
||||
10. **`demo.sh`** - 脚本使用演示
|
||||
4. **`health_check.sh`** - 服务健康检查脚本
|
||||
5. **`data.conf`** - 数据库配置文件
|
||||
6. **`test_data.sql`** - 测试数据脚本
|
||||
7. **`optional_crontab_config.txt`** - 可选的定时任务配置(备用)
|
||||
|
||||
### 处理逻辑
|
||||
|
||||
@@ -53,7 +50,7 @@ DB_USER="root" # 数据库用户名
|
||||
DB_PASS="password" # 数据库密码
|
||||
|
||||
# Script configuration
|
||||
LOG_DIR="/var/log/student_status_change" # 日志目录
|
||||
LOG_DIR="./student_status_change" # 日志目录
|
||||
SCRIPT_DIR="/path/to/scripts" # 脚本目录
|
||||
LOCK_FILE="${SCRIPT_DIR}/script.lock" # 锁文件
|
||||
|
||||
@@ -84,7 +81,7 @@ DB_PASS="your_password"
|
||||
|
||||
```bash
|
||||
# 启动所有服务(持续运行模式)
|
||||
./start_services.sh
|
||||
./control_scripts.sh startall
|
||||
|
||||
# 查看服务状态
|
||||
./control_scripts.sh statusall
|
||||
@@ -92,7 +89,7 @@ DB_PASS="your_password"
|
||||
|
||||
#### 持续运行模式说明
|
||||
|
||||
- **启动方式**: `./start_services.sh` 一次性启动所有服务
|
||||
- **启动方式**: `./control_scripts.sh startall` 一次性启动所有服务
|
||||
- **运行逻辑**: 每个脚本启动后进入while循环,持续监控和处理数据
|
||||
- **处理周期**: 检查数据库 → 处理未处理记录 → 等待10分钟 → 重复循环
|
||||
- **并发控制**: 通过锁文件确保同一脚本只运行一个实例
|
||||
@@ -114,10 +111,10 @@ DB_PASS="your_password"
|
||||
|
||||
```bash
|
||||
# 正常停止所有服务
|
||||
./stop_services.sh
|
||||
./control_scripts.sh stopall
|
||||
|
||||
# 强制停止所有服务(如果正常停止失败)
|
||||
./stop_services.sh force
|
||||
# 手动kill进程或使用系统命令
|
||||
```
|
||||
|
||||
### 5. 健康检查
|
||||
@@ -187,7 +184,7 @@ DB_PASS="your_password"
|
||||
## 📝 日志说明
|
||||
|
||||
### 日志文件位置
|
||||
- 日志目录:`/var/log/student_status_change/`
|
||||
- 日志目录:`./student_status_change/`
|
||||
- 日志格式:`process_student_changes_YYYYMMDD_HHMMSS.log`
|
||||
|
||||
### 日志内容
|
||||
@@ -268,9 +265,9 @@ rm -f pids/*.pid
|
||||
|
||||
脚本采用持续运行模式,启动后自动循环执行:
|
||||
|
||||
1. **启动脚本**: `./start_services.sh`
|
||||
1. **启动脚本**: `./control_scripts.sh startall`
|
||||
2. **处理逻辑**: 检查未处理的记录 → 处理业务 → 等待10分钟 → 重复
|
||||
3. **停止脚本**: `./stop_services.sh`
|
||||
3. **停止脚本**: `./control_scripts.sh stopall`
|
||||
|
||||
### 可选的定时任务模式
|
||||
|
||||
@@ -286,7 +283,7 @@ crontab -e
|
||||
|
||||
| 特性 | 持续运行模式 | Crontab模式 |
|
||||
|------|-------------|-------------|
|
||||
| 启动方式 | `./start_services.sh` | crontab配置 |
|
||||
| 启动方式 | `./control_scripts.sh startall` | crontab配置 |
|
||||
| 执行频率 | 每10分钟自动 | 可自定义时间 |
|
||||
| 资源占用 | 常驻进程 | 按需启动 |
|
||||
| 监控便利性 | 更容易监控 | 需要额外配置 |
|
||||
@@ -297,16 +294,15 @@ crontab -e
|
||||
## 🚀 快速开始
|
||||
|
||||
### 💡 使用指南
|
||||
1. **查看演示**: 运行 `./demo.sh` 查看脚本使用说明
|
||||
2. **配置数据库**: 编辑 `data.conf` 配置数据库连接信息
|
||||
3. **启动服务**: 使用 `./start_services.sh` 启动持续运行的服务
|
||||
4. **监控运行**: 使用 `./health_check.sh` 检查服务状态
|
||||
5. **停止服务**: 需要时使用 `./stop_services.sh` 停止服务
|
||||
1. **配置数据库**: 编辑 `data.conf` 配置数据库连接信息
|
||||
2. **启动服务**: 使用 `./control_scripts.sh startall` 启动持续运行的服务
|
||||
3. **监控运行**: 使用 `./health_check.sh` 检查服务状态
|
||||
4. **停止服务**: 需要时使用 `./control_scripts.sh stopall` 停止服务
|
||||
|
||||
### 🧪 测试步骤
|
||||
1. **插入测试数据**: 执行 `test_data.sql` 插入测试记录
|
||||
2. **启动服务**: `./start_services.sh`
|
||||
3. **观察日志**: 查看 `/var/log/student_status_change/` 目录的日志
|
||||
2. **启动服务**: `./control_scripts.sh startall`
|
||||
3. **观察日志**: 查看 `./student_status_change/` 目录的日志
|
||||
4. **检查结果**: 确认 `xg_student_status_change.process_status` 已更新为1
|
||||
|
||||
---
|
||||
|
||||
@@ -12,7 +12,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="${SCRIPT_DIR}/data.conf"
|
||||
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "Error: Configuration file $CONFIG_FILE not found!"
|
||||
echo "错误:配置文件 $CONFIG_FILE 未找到!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -57,7 +57,7 @@ is_running() {
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
return 0 # Running
|
||||
else
|
||||
log "WARN" "Removing stale PID file for $script_name"
|
||||
log "WARN" "删除脚本 $script_name 的过期PID文件"
|
||||
rm -f "$pid_file"
|
||||
fi
|
||||
fi
|
||||
@@ -68,7 +68,7 @@ is_running() {
|
||||
if kill -0 "$lock_pid" 2>/dev/null; then
|
||||
return 0 # Running
|
||||
else
|
||||
log "WARN" "Removing stale lock file for $script_name"
|
||||
log "WARN" "删除脚本 $script_name 的过期锁定文件"
|
||||
rm -f "$lock_file"
|
||||
fi
|
||||
fi
|
||||
@@ -82,16 +82,16 @@ start_script() {
|
||||
local pid_file=$(get_pid_file "$script_name")
|
||||
|
||||
if [[ ! -f "$script_file" ]]; then
|
||||
log "ERROR" "Script file not found: $script_file"
|
||||
log "ERROR" "脚本文件未找到: $script_file"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if is_running "$script_name"; then
|
||||
log "INFO" "$script_name is already running"
|
||||
log "INFO" "$script_name 已在运行"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "INFO" "Starting $script_name..."
|
||||
log "INFO" "正在启动 $script_name..."
|
||||
chmod +x "$script_file"
|
||||
|
||||
# Start script in background
|
||||
@@ -103,10 +103,10 @@ start_script() {
|
||||
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
echo $pid > "$pid_file"
|
||||
log "INFO" "$script_name started successfully (PID: $pid)"
|
||||
log "INFO" "$script_name 启动成功 (PID: $pid)"
|
||||
return 0
|
||||
else
|
||||
log "ERROR" "Failed to start $script_name"
|
||||
log "ERROR" "$script_name 启动失败"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -117,30 +117,30 @@ stop_script() {
|
||||
local lock_file=$(get_lock_file "$script_name")
|
||||
local stopped=false
|
||||
|
||||
log "INFO" "Stopping $script_name..."
|
||||
log "INFO" "正在停止 $script_name..."
|
||||
|
||||
# Try to stop by PID file
|
||||
# 尝试通过PID文件停止
|
||||
if [[ -f "$pid_file" ]]; then
|
||||
local pid=$(cat "$pid_file")
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
kill "$pid"
|
||||
sleep 2
|
||||
if ! kill -0 "$pid" 2>/dev/null; then
|
||||
log "INFO" "$script_name stopped successfully (PID: $pid)"
|
||||
log "INFO" "$script_name 停止成功 (PID: $pid)"
|
||||
stopped=true
|
||||
fi
|
||||
fi
|
||||
rm -f "$pid_file"
|
||||
fi
|
||||
|
||||
# Try to stop by lock file
|
||||
# 尝试通过锁定文件停止
|
||||
if [[ -f "$lock_file" ]]; then
|
||||
local lock_pid=$(cat "$lock_file")
|
||||
if kill -0 "$lock_pid" 2>/dev/null; then
|
||||
kill "$lock_pid"
|
||||
sleep 2
|
||||
if ! kill -0 "$lock_pid" 2>/dev/null; then
|
||||
log "INFO" "$script_name stopped successfully (PID: $lock_pid)"
|
||||
log "INFO" "$script_name 停止成功 (PID: $lock_pid)"
|
||||
stopped=true
|
||||
fi
|
||||
fi
|
||||
@@ -148,13 +148,13 @@ stop_script() {
|
||||
fi
|
||||
|
||||
if [[ "$stopped" == false ]]; then
|
||||
log "WARN" "$script_name may not have been running or failed to stop gracefully"
|
||||
log "WARN" "$script_name 可能未运行或优雅停止失败"
|
||||
fi
|
||||
}
|
||||
|
||||
restart_script() {
|
||||
local script_name="$1"
|
||||
log "INFO" "Restarting $script_name..."
|
||||
log "INFO" "正在重启 $script_name..."
|
||||
stop_script "$script_name"
|
||||
sleep 3
|
||||
start_script "$script_name"
|
||||
@@ -168,43 +168,43 @@ status_script() {
|
||||
|
||||
if [[ -f "$pid_file" ]]; then
|
||||
local pid=$(cat "$pid_file")
|
||||
log "INFO" "$script_name is running (PID: $pid)"
|
||||
log "INFO" "$script_name 正在运行 (PID: $pid)"
|
||||
elif [[ -f "$lock_file" ]]; then
|
||||
local lock_pid=$(cat "$lock_file")
|
||||
log "INFO" "$script_name is running (PID: $lock_pid)"
|
||||
log "INFO" "$script_name 正在运行 (PID: $lock_pid)"
|
||||
else
|
||||
log "INFO" "$script_name status unknown"
|
||||
log "INFO" "$script_name 状态未知"
|
||||
fi
|
||||
else
|
||||
log "INFO" "$script_name is not running"
|
||||
log "INFO" "$script_name 未运行"
|
||||
fi
|
||||
}
|
||||
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $0 <command> <script_name>
|
||||
用法: $0 <命令> <脚本名称>
|
||||
|
||||
Commands:
|
||||
start Start the specified script
|
||||
stop Stop the specified script
|
||||
restart Restart the specified script
|
||||
status Show status of the specified script
|
||||
startall Start all scripts
|
||||
stopall Stop all scripts
|
||||
statusall Show status of all scripts
|
||||
命令:
|
||||
start 启动指定的脚本
|
||||
stop 停止指定的脚本
|
||||
restart 重启指定的脚本
|
||||
status 显示指定脚本的状态
|
||||
startall 启动所有脚本
|
||||
stopall 停止所有脚本
|
||||
statusall 显示所有脚本的状态
|
||||
|
||||
Script names:
|
||||
changes Student status changes script (休学/退学/毕业)
|
||||
resume Student resume script (复学)
|
||||
all All scripts
|
||||
脚本名称:
|
||||
changes 学生状态变更脚本 (休学/退学/毕业)
|
||||
resume 学生复学脚本 (复学)
|
||||
all 所有脚本
|
||||
|
||||
Examples:
|
||||
$0 start changes # Start changes processing script
|
||||
$0 stop resume # Stop resume processing script
|
||||
$0 restart changes # Restart changes processing script
|
||||
$0 status all # Show status of all scripts
|
||||
$0 startall # Start all scripts
|
||||
$0 stopall # Stop all scripts
|
||||
示例:
|
||||
$0 start changes # 启动状态变更处理脚本
|
||||
$0 stop resume # 停止复学处理脚本
|
||||
$0 restart changes # 重启状态变更处理脚本
|
||||
$0 status all # 显示所有脚本的状态
|
||||
$0 startall # 启动所有脚本
|
||||
$0 stopall # 停止所有脚本
|
||||
|
||||
EOF
|
||||
}
|
||||
@@ -223,7 +223,7 @@ main() {
|
||||
elif [[ -n "${SCRIPTS[$script_name]}" ]]; then
|
||||
start_script "$script_name"
|
||||
else
|
||||
log "ERROR" "Unknown script name: $script_name"
|
||||
log "ERROR" "未知的脚本名称: $script_name"
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
@@ -237,7 +237,7 @@ main() {
|
||||
elif [[ -n "${SCRIPTS[$script_name]}" ]]; then
|
||||
stop_script "$script_name"
|
||||
else
|
||||
log "ERROR" "Unknown script name: $script_name"
|
||||
log "ERROR" "未知的脚本名称: $script_name"
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
@@ -251,7 +251,7 @@ main() {
|
||||
elif [[ -n "${SCRIPTS[$script_name]}" ]]; then
|
||||
restart_script "$script_name"
|
||||
else
|
||||
log "ERROR" "Unknown script name: $script_name"
|
||||
log "ERROR" "未知的脚本名称: $script_name"
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
@@ -265,35 +265,35 @@ main() {
|
||||
elif [[ -n "${SCRIPTS[$script_name]}" ]]; then
|
||||
status_script "$script_name"
|
||||
else
|
||||
log "ERROR" "Unknown script name: $script_name"
|
||||
log "ERROR" "未知的脚本名称: $script_name"
|
||||
show_usage
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
startall)
|
||||
log "INFO" "Starting all scripts..."
|
||||
log "INFO" "正在启动所有脚本..."
|
||||
for script in "${!SCRIPTS[@]}"; do
|
||||
start_script "$script"
|
||||
done
|
||||
;;
|
||||
|
||||
stopall)
|
||||
log "INFO" "Stopping all scripts..."
|
||||
log "INFO" "正在停止所有脚本..."
|
||||
for script in "${!SCRIPTS[@]}"; do
|
||||
stop_script "$script"
|
||||
done
|
||||
;;
|
||||
|
||||
statusall)
|
||||
log "INFO" "Checking status of all scripts..."
|
||||
log "INFO" "正在检查所有脚本的状态..."
|
||||
for script in "${!SCRIPTS[@]}"; do
|
||||
status_script "$script"
|
||||
done
|
||||
;;
|
||||
|
||||
*)
|
||||
log "ERROR" "Unknown command: $command"
|
||||
log "ERROR" "未知命令: $command"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Database configuration
|
||||
DB_HOST="localhost"
|
||||
DB_HOST="47.99.164.66"
|
||||
DB_PORT="3306"
|
||||
DB_NAME="hzdyjs_xg"
|
||||
DB_USER="root"
|
||||
DB_PASS="password"
|
||||
DB_PASS="hn02le.34lkdLKD"
|
||||
|
||||
# Script configuration
|
||||
LOG_DIR="/var/log/student_status_change"
|
||||
LOG_DIR="${SCRIPT_DIR}/student_status_change"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
LOCK_FILE="${SCRIPT_DIR}/script.lock"
|
||||
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# 学生状态变更处理脚本演示
|
||||
# 展示如何使用这些脚本
|
||||
# ===========================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo "========================================"
|
||||
echo " 学生状态变更处理脚本演示"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
echo "脚本位置: $SCRIPT_DIR"
|
||||
echo ""
|
||||
|
||||
echo "📋 脚本文件说明:"
|
||||
echo " process_student_changes.sh - 处理毕业/退学/休学的状态变更"
|
||||
echo " process_student_resume.sh - 处理复学的状态变更"
|
||||
echo " control_scripts.sh - 脚本控制程序"
|
||||
echo " start_services.sh - 一键启动所有服务"
|
||||
echo " stop_services.sh - 一键停止所有服务"
|
||||
echo " health_check.sh - 服务健康检查"
|
||||
echo ""
|
||||
|
||||
echo "🔧 配置文件:"
|
||||
echo " data.conf - 数据库配置"
|
||||
echo " test_data.sql - 测试数据"
|
||||
echo ""
|
||||
|
||||
echo "📖 使用步骤:"
|
||||
echo ""
|
||||
|
||||
echo "1️⃣ 配置数据库连接:"
|
||||
echo " vim data.conf"
|
||||
echo " # 修改数据库连接信息"
|
||||
echo ""
|
||||
|
||||
echo "2️⃣ 启动服务(持续运行模式):"
|
||||
echo " ./start_services.sh"
|
||||
echo ""
|
||||
|
||||
echo "3️⃣ 查看服务状态:"
|
||||
echo " ./control_scripts.sh statusall"
|
||||
echo ""
|
||||
|
||||
echo "4️⃣ 执行健康检查:"
|
||||
echo " ./health_check.sh"
|
||||
echo ""
|
||||
|
||||
echo "5️⃣ 停止服务:"
|
||||
echo " ./stop_services.sh"
|
||||
echo ""
|
||||
|
||||
echo "📊 运行模式说明:"
|
||||
echo "• 脚本启动后进入持续运行模式"
|
||||
echo "• 每10分钟自动检查和处理一次数据"
|
||||
echo "• 支持并发控制,避免重复运行"
|
||||
echo "• 完整的日志记录和错误处理"
|
||||
echo ""
|
||||
|
||||
echo "🧪 测试数据:"
|
||||
echo "• 运行 test_data.sql 插入测试数据"
|
||||
echo "• 脚本会自动处理 process_status = 0 的记录"
|
||||
echo ""
|
||||
|
||||
echo "📝 日志位置:"
|
||||
echo "• /var/log/student_status_change/"
|
||||
echo "• 包含详细的处理日志和错误信息"
|
||||
echo ""
|
||||
|
||||
echo "⚠️ 注意事项:"
|
||||
echo "• 确保数据库连接正确"
|
||||
echo "• 确保用户有足够的数据库权限"
|
||||
echo "• 定期检查日志文件"
|
||||
echo "• 监控磁盘空间使用情况"
|
||||
echo ""
|
||||
|
||||
echo "========================================"
|
||||
echo " 演示完成"
|
||||
echo "========================================"
|
||||
+41
-41
@@ -20,7 +20,7 @@ NC='\033[0m' # No Color
|
||||
|
||||
# Load configuration
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo -e "${RED}Error: Configuration file $CONFIG_FILE not found!${NC}"
|
||||
echo -e "${RED}错误:配置文件 $CONFIG_FILE 未找到!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -50,34 +50,34 @@ info() {
|
||||
echo -e "${BLUE}ℹ $1${NC}"
|
||||
}
|
||||
|
||||
# Check database connection
|
||||
# 检查数据库连接
|
||||
check_database() {
|
||||
info "Checking database connection..."
|
||||
info "正在检查数据库连接..."
|
||||
|
||||
local db_test
|
||||
if db_test=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "SELECT 1 as test;" 2>/dev/null); then
|
||||
if echo "$db_test" | grep -q "test"; then
|
||||
success "Database connection successful"
|
||||
success "数据库连接成功"
|
||||
return 0
|
||||
else
|
||||
error "Database query failed"
|
||||
error "数据库查询失败"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
error "Database connection failed"
|
||||
error "数据库连接失败"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check service status
|
||||
# 检查服务状态
|
||||
check_service() {
|
||||
local service_name="$1"
|
||||
local service_desc="$2"
|
||||
|
||||
info "Checking $service_desc..."
|
||||
info "正在检查 $service_desc..."
|
||||
|
||||
if [[ ! -x "$CONTROL_SCRIPT" ]]; then
|
||||
error "Control script not found or not executable: $CONTROL_SCRIPT"
|
||||
error "控制脚本未找到或不可执行: $CONTROL_SCRIPT"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -85,58 +85,58 @@ check_service() {
|
||||
status_output=$("$CONTROL_SCRIPT" status "$service_name" 2>/dev/null)
|
||||
|
||||
if echo "$status_output" | grep -q "is running"; then
|
||||
success "$service_desc is running"
|
||||
success "$service_desc 正在运行"
|
||||
|
||||
# Extract PID if available
|
||||
# 提取PID(如果可用)
|
||||
local pid
|
||||
pid=$(echo "$status_output" | grep -o "PID: [0-9]*" | cut -d' ' -f2)
|
||||
if [[ -n "$pid" ]]; then
|
||||
info " Process ID: $pid"
|
||||
info " 进程ID: $pid"
|
||||
fi
|
||||
|
||||
return 0
|
||||
else
|
||||
error "$service_desc is not running"
|
||||
error "$service_desc 未运行"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check log files
|
||||
# 检查日志文件
|
||||
check_logs() {
|
||||
info "Checking log files..."
|
||||
info "正在检查日志文件..."
|
||||
|
||||
if [[ ! -d "$LOG_DIR" ]]; then
|
||||
warning "Log directory does not exist: $LOG_DIR"
|
||||
warning "日志目录不存在: $LOG_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Count log files
|
||||
# 统计日志文件数量
|
||||
local log_count
|
||||
log_count=$(find "$LOG_DIR" -name "*.log" -type f | wc -l)
|
||||
|
||||
if [[ $log_count -gt 0 ]]; then
|
||||
success "Found $log_count log files"
|
||||
success "发现 $log_count 个日志文件"
|
||||
|
||||
# Check for recent errors
|
||||
# 检查最近的错误
|
||||
local recent_errors
|
||||
recent_errors=$(find "$LOG_DIR" -name "*.log" -type f -mmin -60 -exec grep -l "ERROR" {} \; | wc -l)
|
||||
|
||||
if [[ $recent_errors -gt 0 ]]; then
|
||||
warning "Found $recent_errors log files with recent errors (last 60 minutes)"
|
||||
warning "发现 $recent_errors 个日志文件包含最近的错误 (最近60分钟)"
|
||||
else
|
||||
info "No recent errors found in log files"
|
||||
info "日志文件中未发现最近的错误"
|
||||
fi
|
||||
|
||||
return 0
|
||||
else
|
||||
warning "No log files found"
|
||||
warning "未发现日志文件"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check pending records
|
||||
# 检查待处理记录
|
||||
check_pending_records() {
|
||||
info "Checking pending records in database..."
|
||||
info "正在检查数据库中的待处理记录..."
|
||||
|
||||
local pending_changes pending_resume
|
||||
|
||||
@@ -171,39 +171,39 @@ check_pending_records() {
|
||||
local total_pending=$((pending_changes + pending_resume))
|
||||
|
||||
if [[ $total_pending -gt 0 ]]; then
|
||||
info "Found $total_pending pending records ($pending_changes changes, $pending_resume resume)"
|
||||
info "发现 $total_pending 条待处理记录 ($pending_changes 条变更, $pending_resume 条复学)"
|
||||
if [[ $pending_changes -gt 0 ]]; then
|
||||
warning " $pending_changes records waiting for changes processing"
|
||||
warning " $pending_changes 条记录等待变更处理"
|
||||
fi
|
||||
if [[ $pending_resume -gt 0 ]]; then
|
||||
warning " $pending_resume records waiting for resume processing"
|
||||
warning " $pending_resume 条记录等待复学处理"
|
||||
fi
|
||||
else
|
||||
success "No pending records found"
|
||||
success "未发现待处理记录"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Check disk space
|
||||
# 检查磁盘空间
|
||||
check_disk_space() {
|
||||
info "Checking disk space..."
|
||||
info "正在检查磁盘空间..."
|
||||
|
||||
local log_disk_usage
|
||||
log_disk_usage=$(df "$LOG_DIR" 2>/dev/null | tail -n1 | awk '{print $5}' | sed 's/%//')
|
||||
|
||||
if [[ -z "$log_disk_usage" ]]; then
|
||||
warning "Cannot determine log directory disk usage"
|
||||
warning "无法确定日志目录的磁盘使用情况"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ $log_disk_usage -gt 90 ]]; then
|
||||
error "Log directory disk usage is ${log_disk_usage}% - consider cleaning up old logs"
|
||||
error "日志目录磁盘使用率达到 ${log_disk_usage}% - 建议清理旧日志"
|
||||
return 1
|
||||
elif [[ $log_disk_usage -gt 75 ]]; then
|
||||
warning "Log directory disk usage is ${log_disk_usage}%"
|
||||
warning "日志目录磁盘使用率达到 ${log_disk_usage}%"
|
||||
else
|
||||
success "Log directory disk usage is ${log_disk_usage}%"
|
||||
success "日志目录磁盘使用率 ${log_disk_usage}%"
|
||||
fi
|
||||
|
||||
return 0
|
||||
@@ -267,9 +267,9 @@ generate_report() {
|
||||
} > "$report_file" 2>/dev/null
|
||||
|
||||
if [[ -f "$report_file" ]]; then
|
||||
success "Health check report generated: $report_file"
|
||||
success "健康检查报告已生成: $report_file"
|
||||
else
|
||||
error "Failed to generate health check report"
|
||||
error "生成健康检查报告失败"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ main() {
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo " 学生状态变更处理服务健康检查"
|
||||
echo " 学生状态变更处理服务健康检查"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
@@ -320,14 +320,14 @@ main() {
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Show usage
|
||||
# 显示使用方法
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [report]
|
||||
用法: $0 [report]
|
||||
|
||||
执行学生状态变更处理服务的健康检查。
|
||||
|
||||
Options:
|
||||
选项:
|
||||
report 生成详细的健康检查报告
|
||||
|
||||
检查内容:
|
||||
@@ -352,7 +352,7 @@ case "${1:-}" in
|
||||
main
|
||||
;;
|
||||
*)
|
||||
error "Unknown option: $1"
|
||||
error "未知选项: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
|
||||
@@ -12,7 +12,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="${SCRIPT_DIR}/data.conf"
|
||||
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "Error: Configuration file $CONFIG_FILE not found!"
|
||||
echo "错误:配置文件 $CONFIG_FILE 未找到!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -43,13 +43,13 @@ error_exit() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check if script is already running
|
||||
# 检查脚本是否已在运行
|
||||
if [[ -f "$LOCK_FILE" ]]; then
|
||||
if kill -0 $(cat "$LOCK_FILE") 2>/dev/null; then
|
||||
log "INFO" "Script is already running (PID: $(cat "$LOCK_FILE"))"
|
||||
log "INFO" "脚本已在运行 (PID: $(cat "$LOCK_FILE"))"
|
||||
exit 1
|
||||
else
|
||||
log "WARN" "Removing stale lock file"
|
||||
log "WARN" "删除过期的锁定文件"
|
||||
rm -f "$LOCK_FILE"
|
||||
fi
|
||||
fi
|
||||
@@ -57,10 +57,10 @@ fi
|
||||
# Create lock file
|
||||
echo $$ > "$LOCK_FILE"
|
||||
|
||||
# Cleanup function
|
||||
# 清理函数
|
||||
cleanup() {
|
||||
[[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
|
||||
log "INFO" "Script execution completed"
|
||||
log "INFO" "脚本执行完成"
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
@@ -74,8 +74,8 @@ execute_sql() {
|
||||
local exit_code=$?
|
||||
|
||||
if [[ $exit_code -ne 0 ]]; then
|
||||
log "ERROR" "SQL execution failed: $sql"
|
||||
log "ERROR" "MySQL error: $result"
|
||||
log "ERROR" "SQL执行失败: $sql"
|
||||
log "ERROR" "MySQL错误: $result"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -90,19 +90,54 @@ process_student_change() {
|
||||
local change_type="$4"
|
||||
local operator_id="${5:-1}"
|
||||
|
||||
log "INFO" "Processing student change - ID: $record_id, Student: $student_no ($student_id), Type: $change_type"
|
||||
|
||||
log "INFO" "正在处理学生状态变更 - ID: $record_id, 学生: $student_no ($student_id), 类型: $change_type"
|
||||
|
||||
# Get dormitory assignment info before transaction
|
||||
local dorm_query="
|
||||
SELECT GROUP_CONCAT(id), GROUP_CONCAT(bed_id)
|
||||
FROM xg_dorm_bed_student
|
||||
WHERE student_id = $student_id AND status = '0' AND deleted = 0;
|
||||
"
|
||||
|
||||
local dorm_info=""
|
||||
local dorm_ids=""
|
||||
local bed_ids=""
|
||||
|
||||
# Execute dormitory query with error handling
|
||||
if dorm_info=$(execute_sql "$dorm_query" 2>/dev/null); then
|
||||
# Parse the result (skip header if present)
|
||||
if [[ -n "$dorm_info" ]]; then
|
||||
# Remove warnings, keep only data rows
|
||||
dorm_info=$(echo "$dorm_info" | grep -v "mysql:" | grep -E "^[0-9]+\t" | head -n 1)
|
||||
if [[ -n "$dorm_info" && "$dorm_info" != "NULL" && "$dorm_info" != "NULL\tNULL" ]]; then
|
||||
# Split by tab and handle NULL values
|
||||
IFS=$'\t' read -r dorm_ids_raw bed_ids_raw <<< "$dorm_info"
|
||||
if [[ "$dorm_ids_raw" != "NULL" && -n "$dorm_ids_raw" ]]; then
|
||||
dorm_ids="$dorm_ids_raw"
|
||||
fi
|
||||
if [[ "$bed_ids_raw" != "NULL" && -n "$bed_ids_raw" ]]; then
|
||||
bed_ids="$bed_ids_raw"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log "WARN" "查询宿舍分配信息失败,将跳过宿舍处理 - 学生ID: $student_id"
|
||||
fi
|
||||
|
||||
log "INFO" "找到宿舍分配 - ID: ${dorm_ids:-无}, 床位: ${bed_ids:-无}"
|
||||
|
||||
# Start transaction
|
||||
local transaction_sql="
|
||||
START TRANSACTION;
|
||||
|
||||
-- 1. Backup original data to his tables
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = $student_id;
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = $student_id;
|
||||
INSERT INTO xg_class_pos_msg_his SELECT * FROM xg_class_pos_msg WHERE student_id = $student_id;
|
||||
INSERT INTO club_member_his SELECT * FROM club_member WHERE user_id = $student_id;
|
||||
INSERT INTO stgl_member_his SELECT * FROM stgl_member WHERE user_id = $student_id;
|
||||
INSERT INTO xg_dorm_bed_student_his SELECT * FROM xg_dorm_bed_student WHERE student_id = $student_id;
|
||||
-- 1. Backup original data to his tables (ignore if already exists)
|
||||
INSERT IGNORE INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = '$student_id';
|
||||
INSERT IGNORE INTO sys_user_his SELECT * FROM sys_user WHERE user_id = '$student_id';
|
||||
INSERT IGNORE INTO xg_class_pos_msg_his SELECT * FROM xg_class_pos_msg WHERE student_id = '$student_id';
|
||||
INSERT IGNORE INTO club_member_his SELECT * FROM club_member WHERE user_id = '$student_id';
|
||||
INSERT IGNORE INTO stgl_member_his SELECT * FROM stgl_member WHERE user_id = '$student_id';
|
||||
INSERT IGNORE INTO xg_dorm_bed_student_his SELECT * FROM xg_dorm_bed_student WHERE student_id = '$student_id';
|
||||
|
||||
-- 2. Update student status
|
||||
UPDATE xg_student_msg SET
|
||||
@@ -112,16 +147,16 @@ process_student_change() {
|
||||
WHEN '$change_type' = 'BI_YE' THEN '5'
|
||||
ELSE student_status
|
||||
END,
|
||||
update_by = $operator_id,
|
||||
update_by = '$operator_id',
|
||||
update_time = NOW()
|
||||
WHERE id = $student_id;
|
||||
WHERE id = '$student_id';
|
||||
|
||||
-- 3. Disable user account
|
||||
UPDATE sys_user SET
|
||||
status = '1',
|
||||
update_by = $operator_id,
|
||||
update_by = '$operator_id',
|
||||
update_time = NOW()
|
||||
WHERE user_id = $student_id AND account_type = '2';
|
||||
WHERE user_id = '$student_id' AND account_type = '2';
|
||||
|
||||
-- 4. Process class position (cadre) - only for XIU_XUE, TUI_XUE, BI_YE
|
||||
UPDATE xg_class_pos_msg SET
|
||||
@@ -140,98 +175,101 @@ process_student_change() {
|
||||
END,
|
||||
term_end_date = CURDATE(),
|
||||
term_duration = TIMESTAMPDIFF(MONTH, term_start_date, CURDATE()),
|
||||
update_by = $operator_id,
|
||||
update_by = '$operator_id',
|
||||
update_time = NOW()
|
||||
WHERE student_id = $student_id AND is_current = 1;
|
||||
WHERE student_id = '$student_id' AND is_current = 1;
|
||||
|
||||
-- 5. Process club membership - only for XIU_XUE, TUI_XUE, BI_YE
|
||||
UPDATE club_member SET
|
||||
member_status = '4',
|
||||
update_by = $operator_id,
|
||||
update_time = NOW(),
|
||||
remark = CONCAT(COALESCE(remark, ''), ' | 退出原因:',
|
||||
CASE
|
||||
WHEN '$change_type' = 'XIU_XUE' THEN '学生休学'
|
||||
WHEN '$change_type' = 'TUI_XUE' THEN '学生退学'
|
||||
WHEN '$change_type' = 'BI_YE' THEN '学生毕业'
|
||||
ELSE '学生状态变更'
|
||||
END, ' - ', NOW())
|
||||
WHERE user_id = $student_id AND member_status IN ('0', '1', '2');
|
||||
update_by = '$operator_id',
|
||||
update_time = NOW()
|
||||
WHERE user_id = '$student_id' AND member_status IN ('0', '1', '2');
|
||||
|
||||
-- 6. Process volunteer membership - only for XIU_XUE, TUI_XUE, BI_YE
|
||||
UPDATE stgl_member SET
|
||||
status = 4,
|
||||
update_by = $operator_id,
|
||||
update_by = '$operator_id',
|
||||
update_time = NOW()
|
||||
WHERE user_id = $student_id AND status IN (0, 1, 2);
|
||||
WHERE user_id = '$student_id' AND status IN (0, 1, 2);
|
||||
|
||||
-- 7. Process dormitory - only for TUI_XUE, BI_YE
|
||||
-- First, clear dormitory info from student record
|
||||
UPDATE xg_student_msg SET
|
||||
dormitory_building = NULL,
|
||||
dormitory_room = NULL,
|
||||
ext_field1 = NULL,
|
||||
update_time = NOW(),
|
||||
update_by = $operator_id
|
||||
WHERE id = $student_id;
|
||||
update_by = '$operator_id'
|
||||
WHERE id = '$student_id';"
|
||||
|
||||
# Add dormitory processing only if assignments exist and are valid
|
||||
if [[ -n "$dorm_ids" && "$dorm_ids" != "NULL" && -n "$bed_ids" && "$bed_ids" != "NULL" ]]; then
|
||||
transaction_sql+="
|
||||
-- Process dormitory checkout for specific assignments
|
||||
UPDATE xg_dorm_bed_student SET
|
||||
status = '1',
|
||||
checkout_time = NOW(),
|
||||
update_time = NOW(),
|
||||
update_by = $operator_id
|
||||
WHERE student_id = $student_id AND status = '0';
|
||||
update_by = '$operator_id'
|
||||
WHERE FIND_IN_SET(id, '$dorm_ids') AND deleted = 0;
|
||||
|
||||
-- Update bed status for specific beds
|
||||
UPDATE xg_dorm_bed SET
|
||||
bed_status = '0'
|
||||
WHERE id IN (
|
||||
SELECT bed_id FROM xg_dorm_bed_student
|
||||
WHERE student_id = $student_id AND status = '1'
|
||||
);
|
||||
WHERE FIND_IN_SET(id, '$bed_ids') AND deleted = 0;"
|
||||
log "INFO" "将处理宿舍退宿 - 分配ID: $dorm_ids, 床位ID: $bed_ids"
|
||||
else
|
||||
log "INFO" "无需处理宿舍退宿(无有效宿舍分配)"
|
||||
fi
|
||||
|
||||
transaction_sql+="
|
||||
|
||||
-- 8. Update change record status
|
||||
UPDATE xg_student_status_change SET
|
||||
process_status = 1,
|
||||
update_by = $operator_id,
|
||||
update_by = '$operator_id',
|
||||
update_time = NOW()
|
||||
WHERE id = $record_id;
|
||||
WHERE id = '$record_id';
|
||||
|
||||
COMMIT;
|
||||
"
|
||||
|
||||
# Execute transaction
|
||||
# 执行事务
|
||||
if execute_sql "$transaction_sql"; then
|
||||
log "INFO" "Successfully processed student change - ID: $record_id, Student: $student_no"
|
||||
log "INFO" "成功处理学生状态变更 - ID: $record_id, 学生: $student_no"
|
||||
return 0
|
||||
else
|
||||
log "ERROR" "Failed to process student change - ID: $record_id, Student: $student_no"
|
||||
log "ERROR" "处理学生状态变更失败 - ID: $record_id, 学生: $student_no"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
log "INFO" "Starting student status change processing daemon"
|
||||
log "INFO" "Processing types: XIU_XUE(休学), TUI_XUE(退学), BI_YE(毕业)"
|
||||
log "INFO" "Running in continuous mode with 10-minute intervals"
|
||||
log "INFO" "启动学生状态变更处理守护进程"
|
||||
log "INFO" "处理类型: XIU_XUE(休学), TUI_XUE(退学), BI_YE(毕业)"
|
||||
log "INFO" "以连续模式运行,间隔10分钟"
|
||||
|
||||
# Test database connection
|
||||
log "INFO" "Testing database connection..."
|
||||
# 测试数据库连接
|
||||
log "INFO" "正在测试数据库连接..."
|
||||
if ! execute_sql "SELECT 1;" >/dev/null 2>&1; then
|
||||
error_exit "Database connection failed"
|
||||
error_exit "数据库连接失败"
|
||||
fi
|
||||
log "INFO" "Database connection successful"
|
||||
log "INFO" "数据库连接成功"
|
||||
|
||||
# Main processing loop
|
||||
while true; do
|
||||
log "INFO" "Starting new processing cycle"
|
||||
log "INFO" "开始新的处理周期"
|
||||
|
||||
# Get unprocessed records
|
||||
# 获取未处理的记录
|
||||
local query_sql="
|
||||
SELECT id, student_id, student_no, change_type, operator_id
|
||||
FROM xg_student_status_change
|
||||
WHERE process_status = 0
|
||||
AND change_type IN ('XIU_XUE', 'TUI_XUE', 'BI_YE')
|
||||
AND deleted = 0
|
||||
AND effective_date <= NOW()
|
||||
ORDER BY create_time ASC
|
||||
LIMIT $BATCH_SIZE;
|
||||
"
|
||||
@@ -239,15 +277,17 @@ main() {
|
||||
local records
|
||||
records=$(execute_sql "$query_sql")
|
||||
|
||||
# Check if there are records to process
|
||||
|
||||
# 检查是否有记录需要处理
|
||||
local record_count
|
||||
record_count=$(echo "$records" | wc -l)
|
||||
|
||||
if [[ $record_count -le 1 ]]; then
|
||||
log "INFO" "No unprocessed records found, waiting..."
|
||||
log "INFO" "未找到未处理的记录,正在等待..."
|
||||
else
|
||||
# Remove header line
|
||||
records=$(echo "$records" | tail -n +2)
|
||||
# 移除标题行和可能的警告信息
|
||||
records=$(echo "$records" | grep -v "mysql:" | grep -v "id\t" | grep -v "^$")
|
||||
|
||||
|
||||
local processed_count=0
|
||||
local failed_count=0
|
||||
@@ -257,6 +297,7 @@ main() {
|
||||
# Skip empty lines
|
||||
[[ -z "$record_id" ]] && continue
|
||||
|
||||
|
||||
local retry_count=0
|
||||
local success=false
|
||||
|
||||
@@ -267,7 +308,7 @@ main() {
|
||||
else
|
||||
((retry_count++))
|
||||
if [[ $retry_count -lt $MAX_RETRY ]]; then
|
||||
log "WARN" "Processing failed, retrying in $RETRY_DELAY seconds... (attempt $retry_count/$MAX_RETRY)"
|
||||
log "WARN" "处理失败,$RETRY_DELAY 秒后重试... (尝试 $retry_count/$MAX_RETRY)"
|
||||
sleep $RETRY_DELAY
|
||||
fi
|
||||
fi
|
||||
@@ -275,16 +316,16 @@ main() {
|
||||
|
||||
if [[ $success == false ]]; then
|
||||
((failed_count++))
|
||||
log "ERROR" "Failed to process record after $MAX_RETRY attempts - ID: $record_id"
|
||||
log "ERROR" "$MAX_RETRY 次尝试后仍处理失败 - ID: $record_id"
|
||||
fi
|
||||
|
||||
done <<< "$records"
|
||||
|
||||
log "INFO" "Processing cycle completed - Processed: $processed_count, Failed: $failed_count"
|
||||
log "INFO" "处理周期完成 - 已处理: $processed_count, 失败: $failed_count"
|
||||
fi
|
||||
|
||||
# Wait for configured interval before next cycle
|
||||
log "INFO" "Waiting $CYCLE_INTERVAL seconds before next processing cycle..."
|
||||
# 等待配置的间隔时间后开始下一个周期
|
||||
log "INFO" "等待 $CYCLE_INTERVAL 秒后开始下一个处理周期..."
|
||||
sleep $CYCLE_INTERVAL
|
||||
done
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONFIG_FILE="${SCRIPT_DIR}/data.conf"
|
||||
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "Error: Configuration file $CONFIG_FILE not found!"
|
||||
echo "错误:配置文件 $CONFIG_FILE 未找到!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -43,13 +43,13 @@ error_exit() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check if script is already running
|
||||
# 检查脚本是否已在运行
|
||||
if [[ -f "$LOCK_FILE" ]]; then
|
||||
if kill -0 $(cat "$LOCK_FILE") 2>/dev/null; then
|
||||
log "INFO" "Script is already running (PID: $(cat "$LOCK_FILE"))"
|
||||
log "INFO" "脚本已在运行 (PID: $(cat "$LOCK_FILE"))"
|
||||
exit 1
|
||||
else
|
||||
log "WARN" "Removing stale lock file"
|
||||
log "WARN" "删除过期的锁定文件"
|
||||
rm -f "$LOCK_FILE"
|
||||
fi
|
||||
fi
|
||||
@@ -57,10 +57,10 @@ fi
|
||||
# Create lock file
|
||||
echo $$ > "$LOCK_FILE"
|
||||
|
||||
# Cleanup function
|
||||
# 清理函数
|
||||
cleanup() {
|
||||
[[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
|
||||
log "INFO" "Script execution completed"
|
||||
log "INFO" "脚本执行完成"
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
@@ -74,8 +74,8 @@ execute_sql() {
|
||||
local exit_code=$?
|
||||
|
||||
if [[ $exit_code -ne 0 ]]; then
|
||||
log "ERROR" "SQL execution failed: $sql"
|
||||
log "ERROR" "MySQL error: $result"
|
||||
log "ERROR" "SQL执行失败: $sql"
|
||||
log "ERROR" "MySQL错误: $result"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -90,74 +90,75 @@ process_student_resume() {
|
||||
local change_type="$4"
|
||||
local operator_id="${5:-1}"
|
||||
|
||||
log "INFO" "Processing student resume - ID: $record_id, Student: $student_no ($student_id), Type: $change_type"
|
||||
log "INFO" "正在处理学生复学 - ID: $record_id, 学生: $student_no ($student_id), 类型: $change_type"
|
||||
|
||||
# Start transaction
|
||||
local transaction_sql="
|
||||
START TRANSACTION;
|
||||
|
||||
-- 1. Backup original data to his tables
|
||||
INSERT INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = $student_id;
|
||||
INSERT INTO sys_user_his SELECT * FROM sys_user WHERE user_id = $student_id;
|
||||
-- 1. Backup original data to his tables (ignore if already exists)
|
||||
INSERT IGNORE INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = '$student_id';
|
||||
INSERT IGNORE INTO sys_user_his SELECT * FROM sys_user WHERE user_id = '$student_id';
|
||||
|
||||
-- 2. Update student status to resume (复学)
|
||||
UPDATE xg_student_msg SET
|
||||
student_status = '3',
|
||||
update_by = $operator_id,
|
||||
student_status = '1',
|
||||
update_by = '$operator_id',
|
||||
update_time = NOW()
|
||||
WHERE id = $student_id;
|
||||
WHERE id = '$student_id';
|
||||
|
||||
-- 3. Enable user account
|
||||
UPDATE sys_user SET
|
||||
status = '0',
|
||||
update_by = $operator_id,
|
||||
update_by = '$operator_id',
|
||||
update_time = NOW()
|
||||
WHERE user_id = $student_id AND account_type = '2';
|
||||
WHERE user_id = '$student_id' AND account_type = '2';
|
||||
|
||||
-- 4. Update change record status
|
||||
UPDATE xg_student_status_change SET
|
||||
process_status = 1,
|
||||
update_by = $operator_id,
|
||||
update_by = '$operator_id',
|
||||
update_time = NOW()
|
||||
WHERE id = $record_id;
|
||||
WHERE id = '$record_id';
|
||||
|
||||
COMMIT;
|
||||
"
|
||||
|
||||
# Execute transaction
|
||||
# 执行事务
|
||||
if execute_sql "$transaction_sql"; then
|
||||
log "INFO" "Successfully processed student resume - ID: $record_id, Student: $student_no"
|
||||
log "INFO" "成功处理学生复学 - ID: $record_id, 学生: $student_no"
|
||||
return 0
|
||||
else
|
||||
log "ERROR" "Failed to process student resume - ID: $record_id, Student: $student_no"
|
||||
log "ERROR" "处理学生复学失败 - ID: $record_id, 学生: $student_no"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
log "INFO" "Starting student resume processing daemon"
|
||||
log "INFO" "Processing type: FU_XUE(复学)"
|
||||
log "INFO" "Running in continuous mode with 10-minute intervals"
|
||||
log "INFO" "启动学生复学处理守护进程"
|
||||
log "INFO" "处理类型: FU_XUE(复学)"
|
||||
log "INFO" "以连续模式运行,间隔10分钟"
|
||||
|
||||
# Test database connection
|
||||
log "INFO" "Testing database connection..."
|
||||
# 测试数据库连接
|
||||
log "INFO" "正在测试数据库连接..."
|
||||
if ! execute_sql "SELECT 1;" >/dev/null 2>&1; then
|
||||
error_exit "Database connection failed"
|
||||
error_exit "数据库连接失败"
|
||||
fi
|
||||
log "INFO" "Database connection successful"
|
||||
log "INFO" "数据库连接成功"
|
||||
|
||||
# Main processing loop
|
||||
while true; do
|
||||
log "INFO" "Starting new resume processing cycle"
|
||||
log "INFO" "开始新的复学处理周期"
|
||||
|
||||
# Get unprocessed records
|
||||
# 获取未处理的记录
|
||||
local query_sql="
|
||||
SELECT id, student_id, student_no, change_type, operator_id
|
||||
FROM xg_student_status_change
|
||||
WHERE process_status = 0
|
||||
AND change_type = 'FU_XUE'
|
||||
AND deleted = 0
|
||||
AND effective_date <= NOW()
|
||||
ORDER BY create_time ASC
|
||||
LIMIT $BATCH_SIZE;
|
||||
"
|
||||
@@ -165,15 +166,15 @@ main() {
|
||||
local records
|
||||
records=$(execute_sql "$query_sql")
|
||||
|
||||
# Check if there are records to process
|
||||
# 检查是否有记录需要处理
|
||||
local record_count
|
||||
record_count=$(echo "$records" | wc -l)
|
||||
|
||||
if [[ $record_count -le 1 ]]; then
|
||||
log "INFO" "No unprocessed resume records found, waiting..."
|
||||
log "INFO" "未找到未处理的复学记录,正在等待..."
|
||||
else
|
||||
# Remove header line
|
||||
records=$(echo "$records" | tail -n +2)
|
||||
# 移除标题行和可能的警告信息
|
||||
records=$(echo "$records" | grep -v "mysql:" | grep -v "id\t" | grep -v "^$")
|
||||
|
||||
local processed_count=0
|
||||
local failed_count=0
|
||||
@@ -193,7 +194,7 @@ main() {
|
||||
else
|
||||
((retry_count++))
|
||||
if [[ $retry_count -lt $MAX_RETRY ]]; then
|
||||
log "WARN" "Processing failed, retrying in $RETRY_DELAY seconds... (attempt $retry_count/$MAX_RETRY)"
|
||||
log "WARN" "处理失败,$RETRY_DELAY 秒后重试... (尝试 $retry_count/$MAX_RETRY)"
|
||||
sleep $RETRY_DELAY
|
||||
fi
|
||||
fi
|
||||
@@ -201,16 +202,16 @@ main() {
|
||||
|
||||
if [[ $success == false ]]; then
|
||||
((failed_count++))
|
||||
log "ERROR" "Failed to process record after $MAX_RETRY attempts - ID: $record_id"
|
||||
log "ERROR" "$MAX_RETRY 次尝试后仍处理失败 - ID: $record_id"
|
||||
fi
|
||||
|
||||
done <<< "$records"
|
||||
|
||||
log "INFO" "Resume processing cycle completed - Processed: $processed_count, Failed: $failed_count"
|
||||
log "INFO" "复学处理周期完成 - 已处理: $processed_count, 失败: $failed_count"
|
||||
fi
|
||||
|
||||
# Wait for configured interval before next cycle
|
||||
log "INFO" "Waiting $CYCLE_INTERVAL seconds before next resume processing cycle..."
|
||||
# 等待配置的间隔时间后开始下一个周期
|
||||
log "INFO" "等待 $CYCLE_INTERVAL 秒后开始下一个复学处理周期..."
|
||||
sleep $CYCLE_INTERVAL
|
||||
done
|
||||
}
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# 学生状态变更处理服务启动脚本
|
||||
# 用于启动所有相关的处理服务
|
||||
# ===========================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONTROL_SCRIPT="${SCRIPT_DIR}/control_scripts.sh"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo -e "${timestamp} [$level] $message"
|
||||
}
|
||||
|
||||
success() {
|
||||
log "${GREEN}SUCCESS${NC}" "$1"
|
||||
}
|
||||
|
||||
error() {
|
||||
log "${RED}ERROR${NC}" "$1"
|
||||
}
|
||||
|
||||
warning() {
|
||||
log "${YELLOW}WARNING${NC}" "$1"
|
||||
}
|
||||
|
||||
# Check if control script exists and is executable
|
||||
if [[ ! -x "$CONTROL_SCRIPT" ]]; then
|
||||
error "Control script not found or not executable: $CONTROL_SCRIPT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to start a service
|
||||
start_service() {
|
||||
local service_name="$1"
|
||||
local service_desc="$2"
|
||||
|
||||
log "INFO" "Starting $service_desc..."
|
||||
if "$CONTROL_SCRIPT" start "$service_name"; then
|
||||
success "$service_desc started successfully"
|
||||
return 0
|
||||
else
|
||||
error "Failed to start $service_desc"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check service status
|
||||
check_service() {
|
||||
local service_name="$1"
|
||||
local service_desc="$2"
|
||||
|
||||
log "INFO" "Checking $service_desc status..."
|
||||
if "$CONTROL_SCRIPT" status "$service_name" | grep -q "is running"; then
|
||||
success "$service_desc is running"
|
||||
return 0
|
||||
else
|
||||
warning "$service_desc is not running"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
log "INFO" "=== 学生状态变更处理服务启动脚本 ==="
|
||||
log "INFO" "Starting all student status change processing services..."
|
||||
|
||||
local failed_services=()
|
||||
|
||||
# Start changes processing service
|
||||
if ! start_service "changes" "学生状态变更处理服务 (休学/退学/毕业)"; then
|
||||
failed_services+=("changes")
|
||||
fi
|
||||
|
||||
# Start resume processing service
|
||||
if ! start_service "resume" "学生复学处理服务"; then
|
||||
failed_services+=("resume")
|
||||
fi
|
||||
|
||||
# Wait a moment for services to fully start
|
||||
sleep 3
|
||||
|
||||
log "INFO" "=== 服务状态检查 ==="
|
||||
|
||||
# Check all services status
|
||||
check_service "changes" "学生状态变更处理服务 (休学/退学/毕业)"
|
||||
check_service "resume" "学生复学处理服务"
|
||||
|
||||
# Summary
|
||||
log "INFO" "=== 启动完成 ==="
|
||||
if [[ ${#failed_services[@]} -eq 0 ]]; then
|
||||
success "所有服务启动成功"
|
||||
echo ""
|
||||
echo "服务控制命令:"
|
||||
echo " 查看状态: $CONTROL_SCRIPT statusall"
|
||||
echo " 停止服务: $CONTROL_SCRIPT stopall"
|
||||
echo " 重启服务: $CONTROL_SCRIPT restart changes|resume"
|
||||
echo ""
|
||||
echo "日志文件位置: /var/log/student_status_change/"
|
||||
else
|
||||
error "以下服务启动失败: ${failed_services[*]}"
|
||||
echo ""
|
||||
echo "故障排除:"
|
||||
echo "1. 检查数据库配置: cat data.conf"
|
||||
echo "2. 查看日志文件: tail -f /var/log/student_status_change/*.log"
|
||||
echo "3. 检查数据库连接: mysql -h\$DB_HOST -P\$DB_PORT -u\$DB_USER -p\$DB_PASS \$DB_NAME -e 'SELECT 1;'"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
@@ -1,177 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ===========================================
|
||||
# 学生状态变更处理服务停止脚本
|
||||
# 用于停止所有相关的处理服务
|
||||
# ===========================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONTROL_SCRIPT="${SCRIPT_DIR}/control_scripts.sh"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
log() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
echo -e "${timestamp} [$level] $message"
|
||||
}
|
||||
|
||||
success() {
|
||||
log "${GREEN}SUCCESS${NC}" "$1"
|
||||
}
|
||||
|
||||
error() {
|
||||
log "${RED}ERROR${NC}" "$1"
|
||||
}
|
||||
|
||||
warning() {
|
||||
log "${YELLOW}WARNING${NC}" "$1"
|
||||
}
|
||||
|
||||
# Check if control script exists and is executable
|
||||
if [[ ! -x "$CONTROL_SCRIPT" ]]; then
|
||||
error "Control script not found or not executable: $CONTROL_SCRIPT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to stop a service
|
||||
stop_service() {
|
||||
local service_name="$1"
|
||||
local service_desc="$2"
|
||||
|
||||
log "INFO" "Stopping $service_desc..."
|
||||
if "$CONTROL_SCRIPT" stop "$service_name"; then
|
||||
success "$service_desc stopped successfully"
|
||||
return 0
|
||||
else
|
||||
warning "$service_desc may not have been running"
|
||||
return 0 # Not treating this as a hard error
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check service status after stop
|
||||
check_service_stopped() {
|
||||
local service_name="$1"
|
||||
local service_desc="$2"
|
||||
|
||||
log "INFO" "Verifying $service_desc has stopped..."
|
||||
if "$CONTROL_SCRIPT" status "$service_name" | grep -q "is not running"; then
|
||||
success "$service_desc confirmed stopped"
|
||||
return 0
|
||||
else
|
||||
warning "$service_desc may still be running"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to force kill if needed
|
||||
force_kill_service() {
|
||||
local service_name="$1"
|
||||
local script_pattern="$2"
|
||||
local service_desc="$3"
|
||||
|
||||
log "INFO" "Force killing $service_desc..."
|
||||
if pkill -f "$script_pattern"; then
|
||||
sleep 2
|
||||
success "$service_desc force killed"
|
||||
return 0
|
||||
else
|
||||
warning "No processes found for $service_desc"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
local force_kill="${1:-false}"
|
||||
|
||||
log "INFO" "=== 学生状态变更处理服务停止脚本 ==="
|
||||
|
||||
if [[ "$force_kill" == "force" ]]; then
|
||||
log "INFO" "Performing force stop of all services..."
|
||||
|
||||
# Force kill all related processes
|
||||
force_kill_service "changes" "process_student_changes.sh" "学生状态变更处理服务"
|
||||
force_kill_service "resume" "process_student_resume.sh" "学生复学处理服务"
|
||||
|
||||
# Clean up lock and PID files
|
||||
log "INFO" "Cleaning up lock and PID files..."
|
||||
rm -f "${SCRIPT_DIR}"/*.lock
|
||||
rm -f "${SCRIPT_DIR}/pids"/*.pid
|
||||
|
||||
success "Force stop completed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log "INFO" "Stopping all student status change processing services..."
|
||||
|
||||
# Stop services gracefully
|
||||
stop_service "changes" "学生状态变更处理服务 (休学/退学/毕业)"
|
||||
stop_service "resume" "学生复学处理服务"
|
||||
|
||||
# Wait a moment for services to fully stop
|
||||
sleep 3
|
||||
|
||||
log "INFO" "=== 服务状态验证 ==="
|
||||
|
||||
# Check all services are stopped
|
||||
check_service_stopped "changes" "学生状态变更处理服务 (休学/退学/毕业)"
|
||||
check_service_stopped "resume" "学生复学处理服务"
|
||||
|
||||
# Final cleanup
|
||||
log "INFO" "Performing final cleanup..."
|
||||
rm -f "${SCRIPT_DIR}"/*.lock 2>/dev/null || true
|
||||
rm -f "${SCRIPT_DIR}/pids"/*.pid 2>/dev/null || true
|
||||
|
||||
log "INFO" "=== 停止完成 ==="
|
||||
success "所有服务已停止"
|
||||
|
||||
echo ""
|
||||
echo "如果服务未能正常停止,请使用强制停止:"
|
||||
echo " $0 force"
|
||||
echo ""
|
||||
echo "重新启动服务:"
|
||||
echo " ./start_services.sh"
|
||||
}
|
||||
|
||||
# Show usage
|
||||
show_usage() {
|
||||
cat << EOF
|
||||
Usage: $0 [force]
|
||||
|
||||
停止所有学生状态变更处理服务。
|
||||
|
||||
Options:
|
||||
force 强制杀死所有相关进程并清理锁文件
|
||||
|
||||
Examples:
|
||||
$0 # 正常停止所有服务
|
||||
$0 force # 强制停止所有服务
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
case "${1:-}" in
|
||||
force)
|
||||
main "force"
|
||||
;;
|
||||
-h|--help)
|
||||
show_usage
|
||||
;;
|
||||
"")
|
||||
main
|
||||
;;
|
||||
*)
|
||||
error "Unknown option: $1"
|
||||
show_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,104 +0,0 @@
|
||||
-- ===========================================
|
||||
-- 学生状态变更处理测试数据
|
||||
-- 用于测试自动化处理脚本
|
||||
-- ===========================================
|
||||
|
||||
-- 注意:请根据实际情况修改学生ID和学号
|
||||
|
||||
-- 插入测试数据到 xg_student_status_change 表
|
||||
-- 状态:0=未处理,1=已处理
|
||||
|
||||
-- 测试休学处理
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) VALUES (
|
||||
10001, 10001, '20240001', 'XIU_XUE', NOW(),
|
||||
CURDATE(), '学生申请休学', 1, 'manual', 0
|
||||
);
|
||||
|
||||
-- 测试退学处理
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) VALUES (
|
||||
10002, 10002, '20240002', 'TUI_XUE', NOW(),
|
||||
CURDATE(), '学生申请退学', 1, 'manual', 0
|
||||
);
|
||||
|
||||
-- 测试毕业处理
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) VALUES (
|
||||
10003, 10003, '20240003', 'BI_YE', NOW(),
|
||||
CURDATE(), '学生毕业处理', 1, 'manual', 0
|
||||
);
|
||||
|
||||
-- 测试复学处理
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) VALUES (
|
||||
10004, 10004, '20240004', 'FU_XUE', NOW(),
|
||||
CURDATE(), '学生申请复学', 1, 'manual', 0
|
||||
);
|
||||
|
||||
-- 批量测试数据(休学)
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) SELECT
|
||||
20000 + (@row_number := @row_number + 1),
|
||||
20000 + @row_number,
|
||||
CONCAT('2024', LPAD(@row_number, 4, '0')),
|
||||
'XIU_XUE',
|
||||
NOW(),
|
||||
CURDATE(),
|
||||
CONCAT('批量测试休学-', @row_number),
|
||||
1,
|
||||
'manual',
|
||||
0
|
||||
FROM (SELECT @row_number := 0) r
|
||||
CROSS JOIN (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) nums;
|
||||
|
||||
-- 批量测试数据(退学)
|
||||
INSERT INTO xg_student_status_change (
|
||||
id, student_id, student_no, change_type, apply_date,
|
||||
effective_date, reason, operator_id, source, process_status
|
||||
) SELECT
|
||||
30000 + (@row_number2 := @row_number2 + 1),
|
||||
30000 + @row_number2,
|
||||
CONCAT('2024', LPAD(@row_number2 + 10, 4, '0')),
|
||||
'TUI_XUE',
|
||||
NOW(),
|
||||
CURDATE(),
|
||||
CONCAT('批量测试退学-', @row_number2),
|
||||
1,
|
||||
'manual',
|
||||
0
|
||||
FROM (SELECT @row_number2 := 0) r2
|
||||
CROSS JOIN (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5) nums2;
|
||||
|
||||
-- 查询测试数据
|
||||
SELECT
|
||||
'测试数据插入完成' as status,
|
||||
COUNT(*) as total_test_records
|
||||
FROM xg_student_status_change
|
||||
WHERE id >= 10001;
|
||||
|
||||
-- 按类型统计
|
||||
SELECT
|
||||
change_type,
|
||||
COUNT(*) as count
|
||||
FROM xg_student_status_change
|
||||
WHERE id >= 10001
|
||||
GROUP BY change_type
|
||||
ORDER BY change_type;
|
||||
|
||||
-- ===========================================
|
||||
-- 清理测试数据的SQL(执行前请确认)
|
||||
-- ===========================================
|
||||
|
||||
-- DELETE FROM xg_student_status_change WHERE id >= 10001;
|
||||
-- COMMIT;
|
||||
Reference in new issue
Block a user