EE308-First assignment-- front-end and back-end separation contacts programming

832301308郑意捷 2025-11-07 20:19:59

目录

  • 一. 作业描述
  • 二. Github仓库地址
  • 三. PSP表
  • 四. 访问链接
  • 五. 成品展示
  • 六. 描述设计和实现过程
  • 七. 核心代码解释
  • 1. 前端
  • 2. 后端
  • 八. 个人历程和学习

一. 作业描述

本次作业所属课程EE308FZ
作业要求link
这项任务的目标前后端分离网页开发
其他参考资料https://peps.python.org/pep-0008/ https://google.github.io/styleguide/

二. Github仓库地址

| 前端链接 | https://github.com/CyberTrash-star/832301308_contacts_frontend |
| 后端链接 | https://github.com/CyberTrash-star/832301308_contacts_backend |

三. PSP表

任务预估时间(小时)实际时间(小时)
需求分析11
前端页面开发1215
后端开发1013
前后端联调32
服务器部署79
文档编写33
总计3643

四. 访问链接

http://47.112.217.152/

五. 成品展示

  • 联系人列表

    img

  • 添加联系人

    img

  • 修改联系人

    img

  • 删除联系人

    img

六. 描述设计和实现过程

  1. 项目概述与技术栈选择
  • 联系人信息(姓名、电话、地址)的添加、修改、删除
  • 响应式页面设计,适配不同设备
  1. 技术栈选型
    模块技术选型
    框架Flask
    ORMFlask-SQLAlchemy
    数据库MySQL
    页面结构HTML5
    样式CSS3 + Bootstrap 5
    交互jQuery
832301308_contacts_backend/src/
├── app.py           # 应用入口
├── config.py        # 全局配置
├── exts.py          # 扩展实例化
├── models.py        # 数据模型
├── controller/      # 接口控制器
│   └── contacts.py  # 联系人接口实现
├── gunicorn_conf.py # 部署配置
832301308_contacts_frontend/src/
├── index.html           # 前端界面

七. 核心代码解释

1. 前端
  • 数据加载与表格渲染
// 加载联系人数据
function loadContacts() {
  const keyword = $('#searchInput').val().trim();
  $.get(
    'http://47.112.217.152:5000/api/contacts',
    { keyword: keyword },
    function(response) {
      response.code === 200 && renderTable(response.data);
    }
  ).fail(() => alert('网络错误'));
}

// 渲染表格
function renderTable(contacts) {
  const tableBody = $('#contactTableBody').empty();
  contacts.forEach((contact, index) => {
    tableBody.append(`
      <tr>
        <td><input type="checkbox" class="contact-checkbox" data-id="${contact.id}"></td>
        <td>${index + 1}</td>
        <td>${contact.username}</td>
        <td>${contact.phone_number}</td>
        <td>${contact.address}</td>
      </tr>
    `);
  });
}

  • 新增/修改联系人
let currentContactId = null; // 标记当前操作ID

// 保存联系人(复用添加/修改逻辑)
function saveContact() {
  const contactData = {
    username: $('#username').val().trim(),
    phone_number: $('#phone').val().trim(),
    address: $('#address').val().trim()
  };
  // 表单验证
  if (!contactData.username || !contactData.phone_number || !contactData.address) {
    return alert('请填写所有字段');
  }
  // 区分操作类型
  const [url, method] = currentContactId 
    ? [`http://47.112.217.152:5000/api/contacts/${currentContactId}`, 'PUT']
    : ['http://47.112.217.152:5000/api/contacts', 'POST'];
  
  $.ajax({
    url: url,
    type: method,
    contentType: 'application/json',
    data: JSON.stringify(contactData),
    success: (response) => {
      if ([200, 201].includes(response.code)) {
        alert(response.message);
        $('#contactModal').modal('hide');
        loadContacts(); // 刷新数据
      }
    }
  });
}

  • 删除联系人
function deleteContact() {
  const checked = $('.contact-checkbox:checked');
  if (!checked.length) return alert('请选择联系人');
  if (confirm('确定删除?')) {
    $.ajax({
      url: `http://47.112.217.152:5000/api/contacts/${checked.first().data('id')}`,
      type: 'DELETE',
      success: (response) => {
        response.code === 200 && (alert(response.message), loadContacts());
      }
    });
  }
}

2. 后端
  • 定义联系人数据结构,映射数据库表
from datetime import datetime
from exts import db

class UserModel(db.Model):
    __tablename__ = 'user'  # 对应数据库表名
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)  # 主键自增
    username = db.Column(db.String(100), nullable=False, comment='联系人姓名')  # 必填
    phone_number = db.Column(db.String(20), nullable=False, unique=True, comment='联系电话')  # 唯一必填
    address = db.Column(db.String(200), nullable=False, comment='联系地址')  # 必填
    join_time = db.Column(db.DateTime, default=datetime.now, comment='创建时间')  # 自动填充

    def to_dict(self):
        """模型转字典,适配JSON响应"""
        return {
            'id': self.id,
            'username': self.username,
            'phone_number': self.phone_number,
            'address': self.address,
            'join_time': self.join_time.strftime('%Y-%m-%d %H:%M:%S')
        }

  • 核心接口
from flask import Blueprint, request, jsonify
from models import UserModel
from exts import db

bp = Blueprint('contacts', __name__)

# 添加联系人
@bp.route('/contacts', methods=['POST'])
def add_contact():
    data = request.get_json()
    if not all([data.get('username'), data.get('phone_number'), data.get('address')]):
        return jsonify({'code': 400, 'message': '请填写所有字段'}), 400
    if UserModel.query.filter_by(phone_number=data.get('phone_number')).first():
        return jsonify({'code': 400, 'message': '手机号已存在'}), 400
    new_contact = UserModel(username=data.get('username'), phone_number=data.get('phone_number'), address=data.get('address'))
    db.session.add(new_contact)
    db.session.commit()
    return jsonify({'code': 201, 'message': '添加成功', 'data': new_contact.to_dict()}), 201

# 更新联系人
@bp.route('/contacts/<int:id>', methods=['PUT'])
def update_contact(id):
    contact = UserModel.query.get(id)
    if not contact:
        return jsonify({'code': 404, 'message': '联系人不存在'}), 404
    data = request.get_json()
    if data.get('phone_number') != contact.phone_number and UserModel.query.filter_by(phone_number=data.get('phone_number')).first():
        return jsonify({'code': 400, 'message': '手机号已存在'}), 400
    contact.username = data.get('username')
    contact.phone_number = data.get('phone_number')
    contact.address = data.get('address')
    db.session.commit()
    return jsonify({'code': 200, 'message': '更新成功', 'data': contact.to_dict()})

# 删除联系人
@bp.route('/contacts/<int:id>', methods=['DELETE'])
def delete_contact(id):
    contact = UserModel.query.get(id)
    if not contact:
        return jsonify({'code': 404, 'message': '联系人不存在'}), 404
    db.session.delete(contact)
    db.session.commit()
    return jsonify({'code': 200, 'message': '删除成功'})

八. 个人历程和学习

在接触这个项目前,我虽然学过 Flask、jQuery 等技术,但大多停留在 “跟着教程敲代码” 的阶段。所以我希望通过这个联系人管理系统,实现两个目标:一是把零散的知识点串联起来,形成完整的开发思维;二是直面真实开发中的问题(比如跨域、数据验证、联调 bug),提升解决实际问题的能力。
开发中我发现,只靠后端验证数据远远不够。比如用户没填完表单就提交,要等后端返回错误才提示。于是在前端添加了表单验证:提交前检查姓名、电话、地址是否为空,及时给出提示。
另外,删除操作容易误触,所以我加了确认对话框;请求失败时(比如网络错误、后端服务未启动),会给出明确的错误提示,而不是让用户面对空白页面不知所措。这些细节虽然简单,却让系统变得更 “好用”。
后端:熟练掌握 Flask 框架的核心用法(工厂模式、蓝图、扩展),理解 SQLAlchemy ORM 的底层逻辑,能独立设计数据模型和规范接口;
前端:精通 jQuery 的 DOM 操作和 AJAX 请求,学会用 Bootstrap 快速搭建响应式界面,掌握表单验证、动态渲染等实用技巧;
我计划在后续的补充开发中完善联系人查询功能(目前只实现了前端界面设计和接口预留),这次的网站构建对我来说是一次 “从零到一” 的完整实践。

...全文
156 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

164

社区成员

发帖
与我相关
我的任务
社区描述
2501_MU_SE_FZU
软件工程 高校
社区管理员
  • FZU_SE_LQF
  • 助教_林日臻
  • 朱仕君
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧