process_student_resume.sh 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #!/bin/bash
  2. # ===========================================
  3. # 学生状态变更处理脚本 - 复学
  4. # 处理类型: FU_XUE(复学)
  5. # ===========================================
  6. set -euo pipefail
  7. # Load configuration
  8. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  9. CONFIG_FILE="${SCRIPT_DIR}/data.conf"
  10. if [[ ! -f "$CONFIG_FILE" ]]; then
  11. echo "错误:配置文件 $CONFIG_FILE 未找到!"
  12. exit 1
  13. fi
  14. source "$CONFIG_FILE"
  15. # Create log directory
  16. mkdir -p "$LOG_DIR"
  17. # Log file
  18. LOG_FILE="${LOG_DIR}/process_student_resume_$(date +%Y%m%d_%H%M%S).log"
  19. # Lock file to prevent multiple instances
  20. LOCK_FILE="${SCRIPT_DIR}/process_student_resume.lock"
  21. # Functions
  22. log() {
  23. local level="$1"
  24. local message="$2"
  25. local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
  26. echo "[$timestamp] [$level] $message" | tee -a "$LOG_FILE"
  27. }
  28. error_exit() {
  29. local message="$1"
  30. log "ERROR" "$message"
  31. # Remove lock file
  32. [[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
  33. exit 1
  34. }
  35. # 检查脚本是否已在运行
  36. if [[ -f "$LOCK_FILE" ]]; then
  37. if kill -0 $(cat "$LOCK_FILE") 2>/dev/null; then
  38. log "INFO" "脚本已在运行 (PID: $(cat "$LOCK_FILE"))"
  39. exit 1
  40. else
  41. log "WARN" "删除过期的锁定文件"
  42. rm -f "$LOCK_FILE"
  43. fi
  44. fi
  45. # Create lock file
  46. echo $$ > "$LOCK_FILE"
  47. # 清理函数
  48. cleanup() {
  49. [[ -f "$LOCK_FILE" ]] && rm -f "$LOCK_FILE"
  50. log "INFO" "脚本执行完成"
  51. }
  52. trap cleanup EXIT
  53. # Database functions
  54. execute_sql() {
  55. local sql="$1"
  56. local result
  57. result=$(mysql -h"$DB_HOST" -P"$DB_PORT" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "$sql" 2>&1)
  58. local exit_code=$?
  59. if [[ $exit_code -ne 0 ]]; then
  60. log "ERROR" "SQL执行失败: $sql"
  61. log "ERROR" "MySQL错误: $result"
  62. return 1
  63. fi
  64. echo "$result"
  65. }
  66. # Process student resume
  67. process_student_resume() {
  68. local record_id="$1"
  69. local student_id="$2"
  70. local student_no="$3"
  71. local change_type="$4"
  72. local operator_id="${5:-1}"
  73. log "INFO" "正在处理学生复学 - ID: $record_id, 学生: $student_no ($student_id), 类型: $change_type"
  74. # Start transaction
  75. local transaction_sql="
  76. START TRANSACTION;
  77. -- 1. Backup original data to his tables (ignore if already exists)
  78. INSERT IGNORE INTO xg_student_msg_his SELECT * FROM xg_student_msg WHERE id = '$student_id';
  79. INSERT IGNORE INTO sys_user_his SELECT * FROM sys_user WHERE user_id = '$student_id';
  80. -- 2. Update student status to resume (复学)
  81. UPDATE xg_student_msg SET
  82. student_status = '1',
  83. update_by = '$operator_id',
  84. update_time = NOW()
  85. WHERE id = '$student_id';
  86. -- 3. Enable user account
  87. UPDATE sys_user SET
  88. status = '0',
  89. update_by = '$operator_id',
  90. update_time = NOW()
  91. WHERE user_id = '$student_id' AND account_type = '2';
  92. -- 4. Update change record status
  93. UPDATE xg_student_status_change SET
  94. process_status = 1,
  95. update_by = '$operator_id',
  96. update_time = NOW()
  97. WHERE id = '$record_id';
  98. COMMIT;
  99. "
  100. # 执行事务
  101. if execute_sql "$transaction_sql"; then
  102. log "INFO" "成功处理学生复学 - ID: $record_id, 学生: $student_no"
  103. return 0
  104. else
  105. log "ERROR" "处理学生复学失败 - ID: $record_id, 学生: $student_no"
  106. return 1
  107. fi
  108. }
  109. # Main function
  110. main() {
  111. log "INFO" "启动学生复学处理守护进程"
  112. log "INFO" "处理类型: FU_XUE(复学)"
  113. log "INFO" "以连续模式运行,间隔10分钟"
  114. # 测试数据库连接
  115. log "INFO" "正在测试数据库连接..."
  116. if ! execute_sql "SELECT 1;" >/dev/null 2>&1; then
  117. error_exit "数据库连接失败"
  118. fi
  119. log "INFO" "数据库连接成功"
  120. # Main processing loop
  121. while true; do
  122. log "INFO" "开始新的复学处理周期"
  123. # 获取未处理的记录
  124. local query_sql="
  125. SELECT id, student_id, student_no, change_type, operator_id
  126. FROM xg_student_status_change
  127. WHERE process_status = 0
  128. AND change_type = 'FU_XUE'
  129. AND deleted = 0
  130. AND effective_date <= NOW()
  131. ORDER BY create_time ASC
  132. LIMIT $BATCH_SIZE;
  133. "
  134. local records
  135. records=$(execute_sql "$query_sql")
  136. # 检查是否有记录需要处理
  137. local record_count
  138. record_count=$(echo "$records" | wc -l)
  139. if [[ $record_count -le 1 ]]; then
  140. log "INFO" "未找到未处理的复学记录,正在等待..."
  141. else
  142. # 移除标题行和可能的警告信息
  143. records=$(echo "$records" | grep -v "mysql:" | grep -v "id\t" | grep -v "^$")
  144. local processed_count=0
  145. local failed_count=0
  146. # Process each record
  147. while IFS=$'\t' read -r record_id student_id student_no change_type operator_id; do
  148. # Skip empty lines
  149. [[ -z "$record_id" ]] && continue
  150. local retry_count=0
  151. local success=false
  152. while [[ $retry_count -lt $MAX_RETRY && $success == false ]]; do
  153. if process_student_resume "$record_id" "$student_id" "$student_no" "$change_type" "$operator_id"; then
  154. success=true
  155. ((processed_count++))
  156. else
  157. ((retry_count++))
  158. if [[ $retry_count -lt $MAX_RETRY ]]; then
  159. log "WARN" "处理失败,$RETRY_DELAY 秒后重试... (尝试 $retry_count/$MAX_RETRY)"
  160. sleep $RETRY_DELAY
  161. fi
  162. fi
  163. done
  164. if [[ $success == false ]]; then
  165. ((failed_count++))
  166. log "ERROR" "$MAX_RETRY 次尝试后仍处理失败 - ID: $record_id"
  167. fi
  168. done <<< "$records"
  169. log "INFO" "复学处理周期完成 - 已处理: $processed_count, 失败: $failed_count"
  170. fi
  171. # 等待配置的间隔时间后开始下一个周期
  172. log "INFO" "等待 $CYCLE_INTERVAL 秒后开始下一个复学处理周期..."
  173. sleep $CYCLE_INTERVAL
  174. done
  175. }
  176. # Run main function
  177. main "$@"