220 lines
6.1 KiB
Bash
Executable File
220 lines
6.1 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# ===========================================
|
|
# 学生状态变更处理脚本 - 复学
|
|
# 处理类型: FU_XUE(复学)
|
|
# ===========================================
|
|
|
|
set -euo pipefail
|
|
|
|
# Load configuration
|
|
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!"
|
|
exit 1
|
|
fi
|
|
|
|
source "$CONFIG_FILE"
|
|
|
|
# Create log directory
|
|
mkdir -p "$LOG_DIR"
|
|
|
|
# Log file
|
|
LOG_FILE="${LOG_DIR}/process_student_resume_$(date +%Y%m%d_%H%M%S).log"
|
|
|
|
# Lock file to prevent multiple instances
|
|
LOCK_FILE="${SCRIPT_DIR}/process_student_resume.lock"
|
|
|
|
# Functions
|
|
log() {
|
|
local level="$1"
|
|
local message="$2"
|
|
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
error_exit() {
|
|
local message="$1"
|
|
log "ERROR" "$message"
|
|
# Remove lock file
|
|
[[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
|
|
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"))"
|
|
exit 1
|
|
else
|
|
log "WARN" "Removing stale lock file"
|
|
rm -f "$LOCK_FILE"
|
|
fi
|
|
fi
|
|
|
|
# Create lock file
|
|
echo $$ > "$LOCK_FILE"
|
|
|
|
# Cleanup function
|
|
cleanup() {
|
|
[[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
|
|
log "INFO" "Script execution completed"
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
|
|
# Database functions
|
|
execute_sql() {
|
|
local sql="$1"
|
|
local result
|
|
|
|
result=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "$sql" 2>&1)
|
|
local exit_code=$?
|
|
|
|
if [[ $exit_code -ne 0 ]]; then
|
|
log "ERROR" "SQL execution failed: $sql"
|
|
log "ERROR" "MySQL error: $result"
|
|
return 1
|
|
fi
|
|
|
|
echo "$result"
|
|
}
|
|
|
|
# Process student resume
|
|
process_student_resume() {
|
|
local record_id="$1"
|
|
local student_id="$2"
|
|
local student_no="$3"
|
|
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"
|
|
|
|
# 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;
|
|
|
|
-- 2. Update student status to resume (复学)
|
|
UPDATE xg_student_msg SET
|
|
student_status = '3',
|
|
update_by = $operator_id,
|
|
update_time = NOW()
|
|
WHERE id = $student_id;
|
|
|
|
-- 3. Enable user account
|
|
UPDATE sys_user SET
|
|
status = '0',
|
|
update_by = $operator_id,
|
|
update_time = NOW()
|
|
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_time = NOW()
|
|
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"
|
|
return 0
|
|
else
|
|
log "ERROR" "Failed to process student resume - ID: $record_id, Student: $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"
|
|
|
|
# Test database connection
|
|
log "INFO" "Testing database connection..."
|
|
if ! execute_sql "SELECT 1;" >/dev/null 2>&1; then
|
|
error_exit "Database connection failed"
|
|
fi
|
|
log "INFO" "Database connection successful"
|
|
|
|
# Main processing loop
|
|
while true; do
|
|
log "INFO" "Starting new resume processing cycle"
|
|
|
|
# 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
|
|
ORDER BY create_time ASC
|
|
LIMIT $BATCH_SIZE;
|
|
"
|
|
|
|
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..."
|
|
else
|
|
# Remove header line
|
|
records=$(echo "$records" | tail -n +2)
|
|
|
|
local processed_count=0
|
|
local failed_count=0
|
|
|
|
# Process each record
|
|
while IFS=$'\t' read -r record_id student_id student_no change_type operator_id; do
|
|
# Skip empty lines
|
|
[[ -z "$record_id" ]] && continue
|
|
|
|
local retry_count=0
|
|
local success=false
|
|
|
|
while [[ $retry_count -lt $MAX_RETRY && $success == false ]]; do
|
|
if process_student_resume "$record_id" "$student_id" "$student_no" "$change_type" "$operator_id"; then
|
|
success=true
|
|
((processed_count++))
|
|
else
|
|
((retry_count++))
|
|
if [[ $retry_count -lt $MAX_RETRY ]]; then
|
|
log "WARN" "Processing failed, retrying in $RETRY_DELAY seconds... (attempt $retry_count/$MAX_RETRY)"
|
|
sleep $RETRY_DELAY
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [[ $success == false ]]; then
|
|
((failed_count++))
|
|
log "ERROR" "Failed to process record after $MAX_RETRY attempts - ID: $record_id"
|
|
fi
|
|
|
|
done <<< "$records"
|
|
|
|
log "INFO" "Resume processing cycle completed - Processed: $processed_count, Failed: $failed_count"
|
|
fi
|
|
|
|
# Wait for configured interval before next cycle
|
|
log "INFO" "Waiting $CYCLE_INTERVAL seconds before next resume processing cycle..."
|
|
sleep $CYCLE_INTERVAL
|
|
done
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|