Files
drl_2/xuexiao/routes/transfer.py
user9994793890 ee860ce0ae Initial commit
2026-05-29 10:28:07 +08:00

204 lines
9.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""转课/转赠路由"""
from flask import render_template, request, redirect, url_for, flash, session
from models import db, Student, Course, StudentAccount, TransferRecord
from utils import login_required, log_operation, permission_required, export_excel
import business_rules as rules
def register_routes(app):
@app.route('/transfers', endpoint='transfer_list')
@login_required
@permission_required('transfer_view')
def transfer_list():
records = TransferRecord.query.order_by(TransferRecord.created_at.desc()).all()
return render_template('transfer_list.html', records=records)
@app.route('/transfers/add', methods=['GET', 'POST'], endpoint='transfer_add')
@login_required
@permission_required('transfer_add')
def transfer_add():
if request.method == 'POST':
from_student_id = int(request.form.get('from_student_id'))
from_course_id = int(request.form.get('from_course_id'))
transfer_type = request.form.get('transfer_type', 'transfer')
transfer_hours = rules.normalize_consumption_hours(
request.form.get('transfer_hours', 1)
)
remark = request.form.get('remark', '')
from_account = rules.lock_student_account(from_student_id, from_course_id)
if not from_account:
flash('未找到转出课时账户', 'danger')
return redirect(url_for('transfer_add'))
normal_avail = int(float(from_account.normal_hours or 0))
if transfer_type == 'gift':
to_student_id = int(request.form.get('to_student_id'))
if transfer_hours > normal_avail:
flash(
f'赠课不可转赠。仅可转赠正课,当前正课余额{normal_avail}课时',
'danger',
)
return redirect(url_for('transfer_add'))
from_account.normal_hours = normal_avail - transfer_hours
rules.update_account_unit_price(from_account)
rules.sync_account_snapshots(from_account)
to_account = StudentAccount.query.filter_by(
student_id=to_student_id, course_id=from_course_id,
).first()
if not to_account:
to_account = StudentAccount(
student_id=to_student_id, course_id=from_course_id,
)
db.session.add(to_account)
db.session.flush()
to_account.normal_hours = int(float(to_account.normal_hours or 0)) + transfer_hours
rules.update_account_unit_price(to_account)
rules.sync_account_snapshots(to_account)
record = TransferRecord(
from_student_id=from_student_id,
to_student_id=to_student_id,
from_course_id=from_course_id,
to_course_id=from_course_id,
transfer_type='gift',
transfer_hours=transfer_hours,
operator_id=session.get('user_id'),
remark=remark,
)
db.session.add(record)
db.session.commit()
log_operation(
'转赠',
f'学员{from_student_id} 转赠正课{transfer_hours}课时给学员{to_student_id}',
)
flash('转赠成功(仅正课)', 'success')
elif transfer_type == 'upgrade':
# §五 升阶:100% 正课全额结转,不新建订单
to_course_id = int(request.form.get('to_course_id'))
from_course = db.session.get(Course, from_course_id)
to_course = db.session.get(Course, to_course_id)
from_unit = rules.account_effective_unit_price(from_account, from_course)
to_unit = rules.account_effective_unit_price(
StudentAccount.query.filter_by(
student_id=from_student_id, course_id=to_course_id,
).first() or from_account, to_course,
) or float(to_course.price_per_hour or 0) if to_course else 0
if to_unit <= 0 and to_course:
to_unit = float(to_course.price_per_hour or 0)
transfer_normal = normal_avail
to_hours = rules.calc_transfer_to_hours(
transfer_normal, from_unit, to_unit,
)
transfer_amount = transfer_normal * from_unit
from_account.normal_hours = 0
rules.update_account_unit_price(from_account)
rules.sync_account_snapshots(from_account)
to_account = StudentAccount.query.filter_by(
student_id=from_student_id, course_id=to_course_id,
).first()
if not to_account:
to_account = StudentAccount(
student_id=from_student_id, course_id=to_course_id,
)
db.session.add(to_account)
db.session.flush()
to_account.normal_hours = int(float(to_account.normal_hours or 0)) + to_hours
rules.update_account_unit_price(to_account)
rules.sync_account_snapshots(to_account)
record = TransferRecord(
from_student_id=from_student_id,
from_course_id=from_course_id,
to_course_id=to_course_id,
transfer_type='upgrade',
transfer_hours=transfer_normal,
transfer_amount=transfer_amount,
operator_id=session.get('user_id'),
remark=remark or '升阶结转',
)
db.session.add(record)
db.session.commit()
log_operation(
'升阶',
f'学员{from_student_id} 正课{transfer_normal}课时→课程{to_course_id} 转入{to_hours}课时',
)
flash(f'升阶成功!100%正课结转,转入{to_hours}课时', 'success')
else:
to_course_id = int(request.form.get('to_course_id'))
from_course = db.session.get(Course, from_course_id)
to_course = db.session.get(Course, to_course_id)
from_unit = rules.account_effective_unit_price(from_account, from_course)
to_account_pre = StudentAccount.query.filter_by(
student_id=from_student_id, course_id=to_course_id,
).first()
to_unit = rules.account_effective_unit_price(to_account_pre, to_course)
if to_unit <= 0 and to_course:
to_unit = float(to_course.price_per_hour or 0)
if transfer_hours > normal_avail:
flash(
f'仅可转出正课。当前正课{normal_avail}课时,赠课{int(float(from_account.gifted_hours or 0))}课时不可转课',
'danger',
)
return redirect(url_for('transfer_add'))
transfer_amount = transfer_hours * from_unit
to_hours = rules.calc_transfer_to_hours(
transfer_hours, from_unit, to_unit,
)
from_account.normal_hours = normal_avail - transfer_hours
rules.update_account_unit_price(from_account)
rules.sync_account_snapshots(from_account)
to_account = StudentAccount.query.filter_by(
student_id=from_student_id, course_id=to_course_id,
).first()
if not to_account:
to_account = StudentAccount(
student_id=from_student_id, course_id=to_course_id,
)
db.session.add(to_account)
db.session.flush()
to_account.normal_hours = int(float(to_account.normal_hours or 0)) + to_hours
rules.update_account_unit_price(to_account)
rules.sync_account_snapshots(to_account)
record = TransferRecord(
from_student_id=from_student_id,
from_course_id=from_course_id,
to_course_id=to_course_id,
transfer_type='transfer',
transfer_hours=transfer_hours,
transfer_amount=transfer_amount,
operator_id=session.get('user_id'),
remark=remark,
)
db.session.add(record)
db.session.commit()
log_operation(
'转课',
f'学员{from_student_id} 转出正课{transfer_hours}课时→转入{to_hours}课时',
)
flash(f'转课成功!转入{to_hours}课时(仅正课参与换算)', 'success')
return redirect(url_for('transfer_list'))
students = Student.query.filter_by(status=1).all()
courses = Course.query.filter_by(status=1).all()
return render_template('transfer_form.html', students=students, courses=courses)
@app.route('/transfers/export', endpoint='transfer_export')
@login_required
@permission_required('transfer_export')
def transfer_export():
from utils import export_transfers as do_export
return do_export()