Build an Automatic Youth Study Reminder App with Flask and uni‑app

This article walks through creating a cross‑platform reminder application for the Chinese Youth Study program, covering the motivation, Flask backend setup with database models and API routes, data handling tricks, and the uni‑app front‑end design, complete with code snippets and screenshots.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Build an Automatic Youth Study Reminder App with Flask and uni‑app

1. Youth Study and Ice Ice

The author, a class youth league secretary, needed to remind classmates weekly to complete the Youth Study, so they built an automatic reminder script and later packaged it into an app.

2. Flask Backend

2.1 Overview

The data‑fetching part of the script is referenced at https://blog.csdn.net/weixin_45304503/article/details/114501006 .

2.2 Details

2.2.1 Database Section

HOSTNAME = '127.0.0.1'  # change to your MySQL config
PORT = '3306'
DATABASE = 'teenstudy'
USERNAME = 'root'
PASSWORD = 'root'

db_url = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(
    USERNAME,
    PASSWORD,
    HOSTNAME,
    PORT,
    DATABASE,
)

class Config(object):
    SQLALCHEMY_DATABASE_URI = db_url
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_COMMIT_ON_TEARDOWN = True

app = Flask(__name__)
CORS(app, supports_credentials=True)
pymysql.install_as_MySQLdb()
app.config.from_object(Config)
db = SQLAlchemy(app)
manager = Manager(app)  # data migration
Migrate(app, db)
manager.add_command("db", MigrateCommand)

engin = create_engine(db_url)  # create engine
Base = declarative_base(engin)
Session = sessionmaker(engin)
session = Session()

# User model
class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    account = db.Column(db.String(18))
    add_time = db.Column(db.DateTime, index=True, default=datetime.datetime.now())
    email = db.Column(db.String(100))
    name = db.Column(db.String(16))
    province = db.Column(db.String(255))
    school = db.Column(db.String(255))
    college = db.Column(db.String(255))
    origirtion = db.Column(db.String(255))
    grade = db.Column(db.String(255))
    major = db.Column(db.String(255))
    count = db.Column(db.Boolean, default=False)
    history_count = db.Column(db.Integer, default=False)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'), default=3)
    def __repr__(self):
        return "{}" % self.email

# Role model
class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(8), unique=True)
    users = db.relationship('User', backref='role')
    def __repr__(self):
        return "<roles(id:%d,name:%s)" % (self.id, self.name)

# TeenStudy model
class TeenStudy(db.Model):
    __tablename__ = 'teenstudy'
    id = db.Column(db.Integer, primary_key=True)
    study_id = db.Column(db.String(255))
    study_title = db.Column(db.String(255))
    add_time = db.Column(db.DateTime, index=True, default=datetime.datetime.now())
    def __repr__(self):
        return "<teenstudy(id:%d,study_id:%s,study_title:%s,add_time:%s)>" % (self.id, self.study_id, self.study_title, self.add_time)

# Admin model
class Admin(db.Model):
    __tablename__ = 'admin'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(255))
    password = db.Column(db.String(255))
    add_time = db.Column(db.DateTime, index=True, default=datetime.datetime.now())
    def __repr__(self):
        return "<admin(id:%d,name:%s,password:%s,add_time:%s)>" % (self.id, self.name, self.password, self.add_time)

2.2.3 Route Section

@app.route('/login', methods=['GET', 'POST'])
def login():
    username = request.form.get("username")
    password = request.form.get("password")
    cookie = GetCookie(username, password)
    if cookie == "500":
        return {"code": "500", "msg": "发生了点错误,请稍后重试"}
    headers = {
        'Host': 'm.fjcyl.com',
        'Referer': 'http://m.fjcyl.com/logout',
        'User-Agent': 'Mozilla/5.0 (iPad; CPU OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15',
        'Cookie': cookie
    }
    GetSchoolInfo(headers)
    cate, infoDetail, reg = GetStuInfo(headers)
    if cate == 3:  # ordinary member
        if reg == 10001:
            return {"code": 200, "msg": 3, "info": 10001, "infoDetail": infoDetail}
        elif reg == 10002:
            return {"code": 200, "msg": 3, "info": 10002, "infoDetail": infoDetail}
    elif cate == 2:  # league secretary
        DidNumListT = Parma(headers)
        if len(DidNumListT) == 0:
            return {"code": 200}
        if reg == 10001:
            result = {"code": "200", "info": 10001, "msg": 2, "data": eval(DidNumListT), "infoDetail": infoDetail}
            return result
        elif reg == 10002:
            result = {"code": "200", "msg": 2, "info": 10002, "data": eval(DidNumListT)}
            return result

@app.route('/init_email', methods=['GET', 'POST'])
def init_email():
    QQEmail = request.form.get("QQEmail")
    UserName = request.form.get("UserName")
    acctId = request.form.get("acctId")
    colName = request.form.get("colName")
    grade = request.form.get("grade")
    major = request.form.get("major")
    positionName = request.form.get("positionName")
    schoolName = request.form.get("schoolName")
    count = db.session.query(func.count(User.id)).filter(
        User.school == schoolName,
        User.college == colName,
        User.major == major,
        User.account == acctId
    ).scalar()
    if count == 0:
        user = User(account=acctId, name=UserName, school=schoolName, college=colName,
                    grade=grade, major=major, origirtion=positionName, email=QQEmail)
        db.session.add(user)
        db.session.commit()
        return {"msg": 200, "data": "success"}
    else:
        return {"msg": 200, "data": 10001}

@app.route('/sendMail', methods=['GET', 'POST'])
def sendMail():
    DidDoneLists = request.form.get("EmailList")
    DidDoneList = DidDoneLists.split(",")
    Email = []
    count = 1
    for k in DidDoneList:
        count += 1
        if count == 2:
            Email.append(k)
            count = 0
    msg = MIMEText('青年大学习!不用回复!赶紧做!!')
    msg["Subject"] = "青年大学习!!又是你!!!"
    msg["From"] = '辛苦勤劳艰苦奋斗的团支书'
    msg["To"] = '未做人员'
    from_addr = ''
    password = ''
    smtp_server = 'smtp.qq.com'
    to_addr = Email
    try:
        server = smtplib.SMTP_SSL(smtp_server, 465, timeout=2)
        server.login(from_addr, password)
        server.sendmail(from_addr, to_addr, msg.as_string())
        server.quit()
        logging.info("EMAIL SUCCESS")
        return {"code": "200", "info": "success"}
    except Exception as e:
        logging.error("EMAIL FAIL")
        return {"code": "500", "info": "fail"}

2.2.2 Data Exchange Section

strinfo = re.compile("'")
Num_Email = str(DidDoneNumList_Json)
Num_Email_Json = strinfo.sub('"', Num_Email)

3. uni‑app Frontend

3.1 Login Page

3.2 Reminder Page

3.3 Demo

4. Conclusion

The author emphasizes that the tool is only meant to help classmates finish the Youth Study on time and that they do not intend to provide a commercial service.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendPythonAutomationFlaskUniappEmail Notification
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.