合并JWL,WZY,TRM代码
Change-Id: Ifb4fcad3c06733e1e005e7d8d9403e3561010fb4
diff --git a/Merge/back_trm/README.md b/Merge/back_trm/README.md
new file mode 100644
index 0000000..cef32ef
--- /dev/null
+++ b/Merge/back_trm/README.md
@@ -0,0 +1,70 @@
+# Back-end Flask Project
+
+## Overview
+This project is a basic Flask application structure designed to demonstrate the organization of a Flask project. It includes essential components such as routes, models, templates, and configuration files.
+
+## Project Structure
+```
+Back
+├── app
+│ ├── __init__.py
+│ ├── routes.py
+│ ├── models.py
+│ └── templates
+│ ├── base.html
+│ └── index.html
+├── tests
+│ └── test_app.py
+├── app.py
+├── config.py
+├── requirements.txt
+└── README.md
+```
+
+## Setup Instructions
+
+1. **Clone the repository**:
+ ```
+ git clone <repository-url>
+ cd Back
+ ```
+
+2. **Create a virtual environment**:
+ ```
+ python -m venv venv
+ ```
+
+3. **Activate the virtual environment**:
+ - On Windows:
+ ```
+ venv\Scripts\activate
+ ```
+ - On macOS/Linux:
+ ```
+ source venv/bin/activate
+ ```
+
+4. **Install dependencies**:
+ ```
+ pip install -r requirements.txt
+ ```
+
+5. **Run the application**:
+ ```
+ python app.py
+ ```
+
+## Usage
+Once the application is running, you can access it at `http://127.0.0.1:5000/`. The index page will be displayed.
+
+## Testing
+To run the tests, ensure the virtual environment is activated and execute:
+```
+pytest tests/test_app.py
+```
+
+## Contributing
+Feel free to submit issues or pull requests for improvements or bug fixes.
+
+## License
+This project is licensed under the MIT License.
\ No newline at end of file
diff --git a/Merge/back_trm/__pycache__/__init__.cpython-312.pyc b/Merge/back_trm/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000..aad3f55
--- /dev/null
+++ b/Merge/back_trm/__pycache__/__init__.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_trm/__pycache__/config.cpython-310.pyc b/Merge/back_trm/__pycache__/config.cpython-310.pyc
new file mode 100644
index 0000000..47d55f3
--- /dev/null
+++ b/Merge/back_trm/__pycache__/config.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_trm/app.py b/Merge/back_trm/app.py
new file mode 100644
index 0000000..3c7fb86
--- /dev/null
+++ b/Merge/back_trm/app.py
@@ -0,0 +1,8 @@
+from app import create_app
+from flask_cors import CORS
+
+app = create_app()
+CORS(app, resources={r"/*": {"origins": "*"}})
+
+if __name__ == "__main__":
+ app.run(debug=True,port=5713,host='0.0.0.0')
\ No newline at end of file
diff --git a/Merge/back_trm/app/__init__.py b/Merge/back_trm/app/__init__.py
new file mode 100644
index 0000000..5587d2a
--- /dev/null
+++ b/Merge/back_trm/app/__init__.py
@@ -0,0 +1,15 @@
+from flask import Flask
+
+def create_app():
+ app = Flask(__name__)
+
+ # Load configuration
+ app.config.from_object('config.Config')
+
+ # Register blueprints or routes
+ from .routes import main as main_blueprint
+ app.register_blueprint(main_blueprint)
+
+ return app
+
+app = create_app()
\ No newline at end of file
diff --git a/Merge/back_trm/app/__pycache__/__init__.cpython-310.pyc b/Merge/back_trm/app/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..f713fad
--- /dev/null
+++ b/Merge/back_trm/app/__pycache__/__init__.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_trm/app/__pycache__/__init__.cpython-312.pyc b/Merge/back_trm/app/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000..ec28c7e
--- /dev/null
+++ b/Merge/back_trm/app/__pycache__/__init__.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_trm/app/__pycache__/routes.cpython-310.pyc b/Merge/back_trm/app/__pycache__/routes.cpython-310.pyc
new file mode 100644
index 0000000..5166bf4
--- /dev/null
+++ b/Merge/back_trm/app/__pycache__/routes.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_trm/app/functions/Fpost.py b/Merge/back_trm/app/functions/Fpost.py
new file mode 100644
index 0000000..7d6ccd2
--- /dev/null
+++ b/Merge/back_trm/app/functions/Fpost.py
@@ -0,0 +1,102 @@
+from ..models.users import User as users
+from ..models.post import Post as post
+import secrets
+import hashlib
+from datetime import datetime, timedelta
+from sqlalchemy.orm import Session
+class Fpost:
+ def __init__(self,session:Session):
+ self.session=session
+ return
+
+
+ def getlist(self):
+ results = self.session.query(post.id, post.title,post.status)
+ return results
+
+ def getuserlist(self):
+ results= self.session.query(users.id, users.username, users.role)
+ return results
+
+ def giveadmin(self,userid):
+ res=self.session.query(users).filter(users.id==userid).first()
+ if not res:
+ return False
+ res.role='admin'
+ self.session.commit()
+ return True
+
+ def giveuser(self,userid):
+ res=self.session.query(users).filter(users.id==userid).first()
+ if not res:
+ return False
+ res.role='user'
+ self.session.commit()
+ return True
+
+ def givesuperadmin(self,userid):
+ res=self.session.query(users).filter(users.id==userid).first()
+ if not res:
+ return False
+ res.role='superadmin'
+ self.session.commit()
+ return True
+
+
+ def getpost(self,postid):
+ res=self.session.query(post).filter(post.id==postid).first()
+ return res
+ def checkid(self,userid,status=''):
+ res=self.session.query(users).filter(users.id==userid).first()
+ if(not res):
+ return False
+ if res.role !=status:
+ return False
+ return True
+
+ def review(self,postid,status):
+ print(status)
+ res=self.session.query(post).filter(post.id==postid).first()
+ if not res:
+ return False
+ res.status=status
+ self.session.commit()
+ return True
+
+ def createtoken(self, userid):
+ """
+ 根据userid创建token并插入到数据库
+ :param userid: 用户ID
+ :return: 生成的token字符串
+ """
+ # 生成随机盐值
+ salt = secrets.token_hex(16)
+
+ # 创建哈希值:userid + 当前时间戳 + 随机盐值
+ current_time = str(datetime.now().timestamp())
+ hash_input = f"{userid}_{current_time}_{salt}"
+
+ # 生成SHA256哈希值作为token
+ token = hashlib.sha256(hash_input.encode()).hexdigest()
+
+ # 设置时间
+ created_time = datetime.now()
+ expires_time = created_time + timedelta(days=1) # 一天后过期
+
+ try:
+ # 创建新的token记录
+ new_token = Token(
+ token=token,
+ expires_at=expires_time,
+ created_at=created_time
+ )
+
+ # 假设self.session是数据库会话对象
+ self.session.add(new_token)
+ self.session.commit()
+
+ return token
+
+ except Exception as e:
+ self.session.rollback()
+ raise Exception(f"创建token失败: {str(e)}")
\ No newline at end of file
diff --git a/Merge/back_trm/app/functions/__pycache__/Fpost.cpython-310.pyc b/Merge/back_trm/app/functions/__pycache__/Fpost.cpython-310.pyc
new file mode 100644
index 0000000..f9b1bc6
--- /dev/null
+++ b/Merge/back_trm/app/functions/__pycache__/Fpost.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_trm/app/models/__init__.py b/Merge/back_trm/app/models/__init__.py
new file mode 100644
index 0000000..f726a19
--- /dev/null
+++ b/Merge/back_trm/app/models/__init__.py
@@ -0,0 +1,8 @@
+from sqlalchemy.ext.declarative import declarative_base
+
+Base = declarative_base()
+
+# 先定义好 Base,再把所有 model import 进来,让 SQLAlchemy 一次性注册它们
+from .users import User
+from .topics import Topic
+from .post import Post
\ No newline at end of file
diff --git a/Merge/back_trm/app/models/__pycache__/__init__.cpython-310.pyc b/Merge/back_trm/app/models/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000..015de51
--- /dev/null
+++ b/Merge/back_trm/app/models/__pycache__/__init__.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_trm/app/models/__pycache__/post.cpython-310.pyc b/Merge/back_trm/app/models/__pycache__/post.cpython-310.pyc
new file mode 100644
index 0000000..8d33351
--- /dev/null
+++ b/Merge/back_trm/app/models/__pycache__/post.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_trm/app/models/__pycache__/topics.cpython-310.pyc b/Merge/back_trm/app/models/__pycache__/topics.cpython-310.pyc
new file mode 100644
index 0000000..fba569b
--- /dev/null
+++ b/Merge/back_trm/app/models/__pycache__/topics.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_trm/app/models/__pycache__/users.cpython-310.pyc b/Merge/back_trm/app/models/__pycache__/users.cpython-310.pyc
new file mode 100644
index 0000000..155a86c
--- /dev/null
+++ b/Merge/back_trm/app/models/__pycache__/users.cpython-310.pyc
Binary files differ
diff --git a/Merge/back_trm/app/models/post.py b/Merge/back_trm/app/models/post.py
new file mode 100644
index 0000000..041e263
--- /dev/null
+++ b/Merge/back_trm/app/models/post.py
@@ -0,0 +1,111 @@
+from .users import User
+from . import Base
+
+from sqlalchemy import (
+ Column, Integer, String, Text, JSON, Enum,
+ TIMESTAMP, ForeignKey, Index, func, text
+)
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import relationship
+
+
+class Post(Base):
+ __tablename__ = 'posts'
+ __table_args__ = (
+ # 索引
+ Index('idx_posts_heat', 'heat'),
+ # MySQL 引擎、字符集、校对规则、表注释
+ {
+ 'mysql_engine': 'InnoDB',
+ 'mysql_charset': 'utf8mb4',
+ 'mysql_collate': 'utf8mb4_general_ci',
+ 'comment': '内容帖子表'
+ }
+ )
+
+ def to_dict(self):
+ return {
+ 'id': self.id if self.id else None,
+ 'user_id': self.user_id if self.user_id else None,
+ 'topic_id': self.topic_id if self.topic_id else None,
+ 'type': self.type if self.type else None,
+ 'title': self.title if self.title else None,
+ 'content': self.content if self.content else None,
+ 'media_urls': self.media_urls if self.media_urls else None,
+ 'status': self.status if self.status else None,
+ 'heat': self.heat if self.heat else None,
+ 'created_at': self.created_at.isoformat() if self.created_at else None,
+ 'updated_at': self.updated_at.isoformat() if self.updated_at else None
+ }
+
+
+ id = Column(
+ Integer,
+ primary_key=True,
+ autoincrement=True,
+ comment='帖子ID'
+ )
+ user_id = Column(
+ Integer,
+ ForeignKey('users.id', ondelete='CASCADE'),
+ nullable=False,
+ index=True,
+ comment='作者ID'
+ )
+ topic_id = Column(
+ Integer,
+ ForeignKey('topics.id', ondelete='SET NULL'),
+ nullable=True,
+ index=True,
+ comment='所属话题ID'
+ )
+ type = Column(
+ Enum('text', 'image', 'video', 'document', name='post_type'),
+ nullable=False,
+ server_default=text("'text'"),
+ comment='内容类型'
+ )
+ title = Column(
+ String(255),
+ nullable=False,
+ comment='标题'
+ )
+ content = Column(
+ Text,
+ nullable=False,
+ comment='正文内容'
+ )
+ media_urls = Column(
+ JSON,
+ nullable=True,
+ comment='媒体资源URL数组'
+ )
+ status = Column(
+ Enum('draft', 'pending', 'published', 'deleted', 'rejected', name='post_status'),
+ nullable=False,
+ server_default=text("'draft'"),
+ comment='状态'
+ )
+ heat = Column(
+ Integer,
+ nullable=False,
+ server_default=text('0'),
+ comment='热度值'
+ )
+ created_at = Column(
+ TIMESTAMP,
+ nullable=True,
+ server_default=func.current_timestamp(),
+ comment='创建时间'
+ )
+ updated_at = Column(
+ TIMESTAMP,
+ nullable=True,
+ server_default=func.current_timestamp(),
+ onupdate=func.current_timestamp(),
+ comment='更新时间'
+ )
+
+ # 可选:与 User/Topic 模型的关系(需要在 User、Topic 中也定义 back_populates)
+ # user = relationship('User', back_populates='posts')
+ # topic = relationship('Topic', back_populates='posts')
diff --git a/Merge/back_trm/app/models/token.py b/Merge/back_trm/app/models/token.py
new file mode 100644
index 0000000..cbe864b
--- /dev/null
+++ b/Merge/back_trm/app/models/token.py
@@ -0,0 +1,27 @@
+from sqlalchemy import Column, Integer, String, DateTime, TIMESTAMP, Index
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.sql import func
+from datetime import datetime
+
+Base = declarative_base()
+
+class Token(Base):
+ __tablename__ = 'tokens'
+
+ id = Column(Integer, primary_key=True, autoincrement=True)
+ token = Column(String(255), nullable=False, unique=True)
+ expires_at = Column(DateTime, nullable=False)
+ created_at = Column(TIMESTAMP, default=func.current_timestamp())
+ updated_at = Column(TIMESTAMP, default=func.current_timestamp(), onupdate=func.current_timestamp())
+
+ __table_args__ = (
+ Index('idx_token', 'token'),
+ Index('idx_expires_at', 'expires_at'),
+ )
+
+ def __repr__(self):
+ return f"<Token(id={self.id}, token='{self.token[:10]}...', expires_at={self.expires_at})>"
+
+ def is_expired(self):
+ """检查token是否已过期"""
+ return datetime.now() > self.expires_at
\ No newline at end of file
diff --git a/Merge/back_trm/app/models/topics.py b/Merge/back_trm/app/models/topics.py
new file mode 100644
index 0000000..1a35a38
--- /dev/null
+++ b/Merge/back_trm/app/models/topics.py
@@ -0,0 +1,26 @@
+from . import Base
+from sqlalchemy import Column, Integer, String, Text, Enum, TIMESTAMP
+from sqlalchemy.sql import func
+
+class Topic(Base):
+ __tablename__ = 'topics'
+ __table_args__ = {
+ 'mysql_engine': 'InnoDB',
+ 'mysql_charset': 'utf8mb4',
+ 'mysql_collate': 'utf8mb4_general_ci',
+ 'comment': '话题/超话表'
+ }
+
+ id = Column(Integer, primary_key=True, autoincrement=True, comment='话题ID')
+ name = Column(String(100, collation='utf8mb4_general_ci'), nullable=False, unique=True, comment='话题名称')
+ description = Column(Text(collation='utf8mb4_general_ci'), comment='话题描述')
+ status = Column(
+ Enum('active', 'archived', name='topic_status', collation='utf8mb4_general_ci'),
+ default='active',
+ comment='状态'
+ )
+ created_at = Column(
+ TIMESTAMP,
+ server_default=func.current_timestamp(),
+ comment='创建时间'
+ )
\ No newline at end of file
diff --git a/Merge/back_trm/app/models/users.py b/Merge/back_trm/app/models/users.py
new file mode 100644
index 0000000..0505e86
--- /dev/null
+++ b/Merge/back_trm/app/models/users.py
@@ -0,0 +1,51 @@
+from . import Base
+from sqlalchemy import (
+ Column, Integer, String, Enum, TIMESTAMP, text
+)
+from sqlalchemy.ext.declarative import declarative_base
+
+
+class User(Base):
+ __tablename__ = 'users'
+
+ def to_dict(self):
+ return {
+ 'id': self.id,
+ 'username': self.username if self.username else None,
+ 'email': self.email if self.email else None,
+ 'avatar': self.avatar if self.avatar else None,
+ 'role': self.role if self.role else None,
+ 'bio': self.bio if self.bio else None,
+ 'status': self.status if self.status else None,
+ 'created_at': self.created_at.isoformat() if self.created_at else None,
+ 'updated_at': self.updated_at.isoformat() if self.updated_at else None
+ }
+
+
+
+ id = Column(Integer, primary_key=True, autoincrement=True, comment='用户ID')
+ username = Column(String(50), nullable=False, unique=True, comment='用户名')
+ password = Column(String(255), nullable=False, comment='加密密码')
+ email = Column(String(100), nullable=False, unique=True, comment='邮箱')
+ avatar = Column(String(255), comment='头像URL')
+ role = Column(Enum('user', 'admin', 'superadmin', name='user_role'), comment='角色')
+ bio = Column(String(255), comment='个人简介')
+ status = Column(
+ Enum('active','banned','muted', name='user_status'),
+ nullable=False,
+ server_default=text("'active'"),
+ comment='账号状态'
+ )
+ created_at = Column(
+ TIMESTAMP,
+ nullable=True,
+ server_default=text('CURRENT_TIMESTAMP'),
+ comment='创建时间'
+ )
+ updated_at = Column(
+ TIMESTAMP,
+ nullable=True,
+ server_default=text('CURRENT_TIMESTAMP'),
+ onupdate=text('CURRENT_TIMESTAMP'),
+ comment='更新时间'
+ )
\ No newline at end of file
diff --git a/Merge/back_trm/app/routes.py b/Merge/back_trm/app/routes.py
new file mode 100644
index 0000000..41b022b
--- /dev/null
+++ b/Merge/back_trm/app/routes.py
@@ -0,0 +1,155 @@
+from flask import Blueprint, render_template
+from .functions.Fpost import Fpost;
+from sqlalchemy import create_engine
+from sqlalchemy.orm import sessionmaker
+from config import Config
+from flask import jsonify,request
+
+main = Blueprint('main', __name__)
+
+@main.route('/sgiveadmin',methods=['POST','GET'])
+def giveadmin():
+ data=request.get_json()
+ print(data)
+ engine=create_engine(Config.SQLURL)
+ SessionLocal = sessionmaker(bind=engine)
+ session = SessionLocal()
+ f=Fpost(session)
+ checres=f.checkid(data['userid'],'superadmin')
+ if(not checres):
+ return jsonify({'status': 'error', 'message': 'Unauthorized'})
+
+ res=f.giveadmin(data['targetid'])
+ if not res:
+ return jsonify({'status': 'error', 'message': 'User not found'})
+
+ return jsonify({'status': 'success', 'message': 'User role updated to admin'})
+
+@main.route('/sgiveuser',methods=['POST','GET'])
+def giveuser():
+ data=request.get_json()
+ print(data)
+ engine=create_engine(Config.SQLURL)
+ SessionLocal = sessionmaker(bind=engine)
+ session = SessionLocal()
+ f=Fpost(session)
+ checres=f.checkid(data['userid'],'superadmin')
+ if(not checres):
+ return jsonify({'status': 'error', 'message': 'Unauthorized'})
+
+ res=f.giveuser(data['targetid'])
+ if not res:
+ return jsonify({'status': 'error', 'message': 'User not found'})
+
+ return jsonify({'status': 'success', 'message': 'User role updated to user'})
+
+
+@main.route('/sgivesuperadmin',methods=['POST','GET'])
+def givesuperadmin():
+ data=request.get_json()
+ print(data)
+ engine=create_engine(Config.SQLURL)
+ SessionLocal = sessionmaker(bind=engine)
+ session = SessionLocal()
+ f=Fpost(session)
+ checres=f.checkid(data['userid'],'superadmin')
+ if(not checres):
+ return jsonify({'status': 'error', 'message': 'Unauthorized'})
+
+ res=f.givesuperadmin(data['targetid'])
+ if not res:
+ return jsonify({'status': 'error', 'message': 'User not found'})
+
+ return jsonify({'status': 'success', 'message': 'User role updated to superadmin'})
+
+@main.route('/sgetuserlist',methods=['POST','GET'])
+def userlist():
+ data=request.get_json()
+ print(data)
+ engine=create_engine(Config.SQLURL)
+ SessionLocal = sessionmaker(bind=engine)
+ session = SessionLocal()
+ f=Fpost(session)
+ checres=f.checkid(data['userid'],'superadmin')
+ if(not checres):
+ return jsonify({'status': 'error', 'message': 'Unauthorized'})
+ res=f.getuserlist()
+ respons=[]
+ for datai in res:
+ respons.append({
+ 'id': datai[0],
+ 'username': datai[1],
+ 'role': datai[2]
+ })
+ return jsonify(respons)
+
+@main.route('/apostlist',methods=['POST','GET'])
+def postlist():
+ data=request.get_json()
+ print(data)
+ engine=create_engine(Config.SQLURL)
+ SessionLocal = sessionmaker(bind=engine)
+ session = SessionLocal()
+ f=Fpost(session)
+ checres=f.checkid(data['userid'],'admin')
+ if(not checres):
+ return jsonify({'status': 'error', 'message': 'Unauthorized'})
+ res=f.getlist()
+ respons=[]
+ for datai in res:
+ respons.append({
+ 'id': datai[0],
+ 'title': datai[1],
+ 'status': datai[2]
+ })
+ return jsonify(respons)
+
+@main.route('/agetpost',methods=['POST','GET'])
+def post():
+ data=request.get_json()
+ engine=create_engine(Config.SQLURL)
+ SessionLocal = sessionmaker(bind=engine)
+ session = SessionLocal()
+ f=Fpost(session)
+ checres=f.checkid(data['userid'],'admin')
+ if(not checres):
+ return jsonify({'status': 'error', 'message': 'Unauthorized'})
+ res=f.getpost(data['postid'])
+
+ return jsonify(res.to_dict() if res else {})
+
+@main.route('/areview',methods=['POST','GET'])
+def review():
+ data=request.get_json()
+ engine=create_engine(Config.SQLURL)
+ SessionLocal = sessionmaker(bind=engine)
+ session = SessionLocal()
+ f=Fpost(session)
+ checres=f.checkid(data['userid'],'admin')
+ if(not checres):
+ return jsonify({'status': 'error', 'message': 'Unauthorized'})
+
+ res=f.review(data['postid'],data['status'])
+ if not res:
+ return jsonify({'status': 'error', 'message': 'Post not found'})
+
+ return jsonify({'status': 'success', 'message': 'Post reviewed successfully'})
+
+
+
+@main.route('/nginxauth',methods=['POST','GET'])
+def nginxauth():
+ data=request.get_json()
+ engine=create_engine(Config.SQLURL)
+ SessionLocal = sessionmaker(bind=engine)
+ session = SessionLocal()
+ f=Fpost(session)
+ checres=f.checkid(data['userid'],'admin')
+ if(not checres):
+ return jsonify({'status': 'error', 'message': 'Unauthorized'})
+
+ res=f.nginxauth(data['postid'],data['status'])
+ if not res:
+ return jsonify({'status': 'error', 'message': 'Post not found'})
+
+ return jsonify({'status': 'success', 'message': 'Nginx auth updated successfully'})
\ No newline at end of file
diff --git a/Merge/back_trm/app/templates/base.html b/Merge/back_trm/app/templates/base.html
new file mode 100644
index 0000000..3c6f3cb
--- /dev/null
+++ b/Merge/back_trm/app/templates/base.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>{% block title %}My Flask App{% endblock %}</title>
+ <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
+</head>
+<body>
+ <header>
+ <h1>Welcome to My Flask App</h1>
+ <nav>
+ <ul>
+ <li><a href="{{ url_for('index') }}">Home</a></li>
+ <!-- Add more navigation links here -->
+ </ul>
+ </nav>
+ </header>
+
+ <main>
+ {% block content %}
+ {% endblock %}
+ </main>
+
+ <footer>
+ <p>© 2023 My Flask App</p>
+ </footer>
+</body>
+</html>
\ No newline at end of file
diff --git a/Merge/back_trm/app/templates/index.html b/Merge/back_trm/app/templates/index.html
new file mode 100644
index 0000000..6631bea
--- /dev/null
+++ b/Merge/back_trm/app/templates/index.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Index Page</title>
+ <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
+</head>
+<body>
+ {% extends 'base.html' %}
+
+ {% block content %}
+ <h1>Welcome to the Index Page</h1>
+ <p>This is the main page of the application.</p>
+ {% endblock %}
+</body>
+</html>
\ No newline at end of file
diff --git a/Merge/back_trm/config.py b/Merge/back_trm/config.py
new file mode 100644
index 0000000..d4a2e88
--- /dev/null
+++ b/Merge/back_trm/config.py
@@ -0,0 +1,12 @@
+import os
+from dotenv import load_dotenv
+load_dotenv()
+class Config:
+ SECRET_KEY = os.environ.get('SECRET_KEY') or 'a_default_secret_key'
+ SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///site.db'
+ SQLALCHEMY_TRACK_MODIFICATIONS = False
+ SQLURL=os.getenv('SQLURL')
+ SQLPORT=os.getenv('SQLPORT')
+ SQLNAME=os.getenv('SQLNAME')
+ SQLUSER=os.getenv('SQLUSER')
+ SQLPWD=os.getenv('SQLPWD')
\ No newline at end of file
diff --git a/Merge/back_trm/requirements.txt b/Merge/back_trm/requirements.txt
new file mode 100644
index 0000000..8e65f82
--- /dev/null
+++ b/Merge/back_trm/requirements.txt
@@ -0,0 +1,6 @@
+Flask==2.2.2
+SQLAlchemy==1.4.36
+Flask-Migrate==3.1.0
+Flask-WTF==1.0.0
+pytest==7.1.2
+```
\ No newline at end of file
diff --git a/Merge/back_trm/tests/__init__.py b/Merge/back_trm/tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Merge/back_trm/tests/__init__.py
diff --git a/Merge/back_trm/tests/__pycache__/__init__.cpython-312.pyc b/Merge/back_trm/tests/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000..48c8068
--- /dev/null
+++ b/Merge/back_trm/tests/__pycache__/__init__.cpython-312.pyc
Binary files differ
diff --git a/Merge/back_trm/tests/__pycache__/test_app.cpython-312-pytest-7.4.4.pyc b/Merge/back_trm/tests/__pycache__/test_app.cpython-312-pytest-7.4.4.pyc
new file mode 100644
index 0000000..9a2b7de
--- /dev/null
+++ b/Merge/back_trm/tests/__pycache__/test_app.cpython-312-pytest-7.4.4.pyc
Binary files differ
diff --git a/Merge/back_trm/tests/test_app.py b/Merge/back_trm/tests/test_app.py
new file mode 100644
index 0000000..3ed6bf9
--- /dev/null
+++ b/Merge/back_trm/tests/test_app.py
@@ -0,0 +1,41 @@
+import requests
+url = 'http://127.0.0.1:5713/'
+
+def test_get_postlist():
+ print()
+ urlx=url+'apostlist'
+ payload = {
+ 'userid': 3
+ }
+ headers = {'Content-Type': 'application/json'}
+
+ resp = requests.get(urlx, json=payload, headers=headers)
+ # print(resp.status_code)
+ print(resp.json())
+
+def test_get_post():
+ print()
+ urlx=url+'agetpost'
+ payload = {
+ 'userid': 3,
+ 'postid': 21
+ }
+ headers = {'Content-Type': 'application/json'}
+
+ resp = requests.get(urlx, json=payload, headers=headers)
+ # print(resp.status_code)
+ print(resp.json())
+
+def test_review_post():
+ print()
+ urlx=url+'areview'
+ payload = {
+ 'userid': 3,
+ 'postid': 21,
+ 'status': 'rejected'
+ }
+ headers = {'Content-Type': 'application/json'}
+
+ resp = requests.get(urlx, json=payload, headers=headers)
+ # print(resp.status_code)
+ print(resp.json())
\ No newline at end of file