This commit is contained in:
zlwu committed 2025-12-25 22:20:22 +08:00
1 parent ff1228873c
commit 34a843e790
23 files changed
+1541 -718

No files matched your search

+19 -23
View File
@@ -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
;;
+3 -3
View File
@@ -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"
-84
View File
@@ -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 "========================================"
@@ -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;