第①次作业——通讯录管理系统

832302202张健涛 2025-11-10 22:24:57

姓名:张健涛         学号:832302202          MU ID:23126612

目录

项目描述

一、Git仓库链接

   1. 前端仓库

   2.后端仓库

二、PSP

三、展示成品

     演示视频:

添加结果如上

四、设计与实现流程

系统架构设计

    1. 整体架构

2. 技术选型理由

功能模块设计

1. 数据模型设计

2. API接口设计

3. 前端功能模块

具体实现流程

第一阶段:环境搭建与项目初始化

第二阶段:后端服务开发

第三阶段:前端界面开发

第四阶段:系统集成测试

第五阶段:部署与文档

关键设计决策

1. 前后端分离架构

2. 无框架前端设计

3. SQLite数据库选择

五、关键代码说明

 ①后端 app.py

1. 基础框架搭建

2. 数据库初始化

3. RESTful API接口实现

3.1 获取所有联系人 (GET)

3.2 添加联系人 (POST)

3.3 更新联系人 (PUT)

3.4 删除联系人 (DELETE)

4. 应用启动

②前端 contacts.html

核心数据结构

联系人保存功能

联系人编辑功能

联系人删除功能

表格更新功能

表单重置功能

页面初始化

系统架构总结

 

六、总结

技术实现

核心成果

项目价值


项目描述

    一个基于前后端分离架构的轻量级联系人管理应用。使用原生HTML/CSS/JavaScript构建前端界面,Python Flask框架提供后端API服务,SQLite作为数据存储,实现了完整的联系人信息增删改查功能。项目采用清晰的前后端分离设计,提供简洁直观的用户界面和流畅的操作体验。

一、Git仓库链接

   1. 前端仓库

        GitHub地址:https://github.com/3187274252-netizen/832302202_leading_end

   2.后端仓库

        GitHub地址:https://github.com/3187274252-netizen/832302202_after_end

二、PSP

 

PSP阶段任务内容预估时间(h)实际时间(h)
计划明确作业要求,选择技术栈(HTML+Flask+SQLite),规划项目结构0.50.5
开发环境准备:安装Python、VS Code、Git,配置开发环境1.01.5
 创建项目目录结构,初始化Git仓库0.30.3
 后端开发:编写Flask API和SQLite数据库操作2.02.5
 前端开发:编写HTML界面和JavaScript交互2.02.5
 前后端联调:测试API接口和数据交互1.01.5
测试功能测试:验证添加、修改、删除联系人功能0.50.7
 兼容性测试:检查不同浏览器下的表现0.30.4
部署项目部署到服务器(可选)1.0-
文档编写README.md和codestyle.md文档0.50.6
 撰写博客文章,整理截图和说明1.52.0
总计 10.612.4

三、展示成品

     演示视频:

 

        主页面展示👇

 

  • 添加联系人区域:有姓名、电话、邮箱 3 个输入框,以及 “保存”“重置” 按钮,用于录入新联系人信息。
  • 联系人列表区域:表头包含姓名、电话、邮箱、操作,列表展示已添加的联系人(如张三、李四),操作列提供 “编辑”“删除” 功能。

       在各个框中输入自己的信息,点击保存,就可以加入联系人列表👆

 

       

 


 

添加结果如上

 以上是删除联系人功能,点击删除按键删除你的列表,结果如下


 以上是联系人编辑功能,点击编辑按键

 可以看到,姓名改为“张sir”,此时点击保存,修改的结果如下👇

 

 


四、设计与实现流程

系统架构设计

    1. 整体架构

         本系统采用前后端分离的架构模式:

  •        前端:基于原生HTML+CSS+JavaScript的轻量级Web应用

           后端:基于Python Flask框架的RESTful API服务
    • 通信方式:HTTP/JSON协议

    • 数据存储:SQLite轻量级数据库

2. 技术选型理由

  •        前端选择原生技术:避免框架依赖,确保兼容性和轻量性

    • 后端选择Flask:Python轻量级框架,快速开发,适合小型项目

    • 数据库选择SQLite:无需额外安装,零配置,适合作业场景

功能模块设计

1. 数据模型设计


python

# 联系人数据模型
Contact {
    id: INTEGER (主键,自增)
    name: TEXT (姓名,必填)
    phone: TEXT (电话,必填) 
    email: TEXT (邮箱,可选)
}

2. API接口设计


text

GET    /contacts        # 获取所有联系人
POST   /contacts        # 添加新联系人  
PUT    /contacts/<id>   # 更新联系人
DELETE /contacts/<id>   # 删除联系人

3. 前端功能模块


  • 联系人列表展示模块

  • 联系人表单模块(添加/编辑)

  • 数据交互模块(API调用)

  • 用户界面交互模块


     

具体实现流程

第一阶段:环境搭建与项目初始化

  1. 开发环境配置

    • 安装Python 3.x、VS Code、Git

    • 配置Python扩展和必要插件

    • 验证开发环境正常运行

  2. 项目结构创建

    • 创建前后端分离的目录结构

    • 初始化Git仓库,建立版本控制

    • 配置代码规范文档

第二阶段:后端服务开发

  1. 数据库层实现

    • 设计contacts表结构

    • 实现SQLite数据库连接

    • 编写数据库初始化脚本

  2. API服务层实现

    • 搭建Flask应用框架

    • 实现RESTful API接口

    • 添加CORS支持,解决跨域问题

    • 实现错误处理和响应格式化

第三阶段:前端界面开发

  1. 用户界面设计

    • 设计响应式布局结构

    • 实现联系人列表展示

    • 创建联系人表单组件

  2. 业务逻辑实现

    • 实现联系人数据获取和渲染

    • 实现添加联系人功能

    • 实现编辑联系人功能

    • 实现删除联系人功能

第四阶段:系统集成测试

  1. 前后端联调

    • 测试API接口连通性

    • 验证数据格式一致性

    • 调试跨域请求问题

  2. 功能完整性测试

    • 测试联系人CRUD操作

    • 验证数据持久化

    • 检查错误处理机制

第五阶段:部署与文档

  1. 项目部署

    • 配置生产环境

    • 部署到云服务器

  2. 文档编写

    • 编写技术文档和使用说明

    • 整理项目结构和代码说明

关键设计决策

1. 前后端分离架构

           优势:职责清晰,易于维护,支持多端复用

           实现:通过JSON API进行数据交换

2. 无框架前端设计

           优势:零依赖,体积小,学习成本低

           挑战:需要手动处理DOM操作和事件绑定

3. SQLite数据库选择

           优势:无需安装配置,适合作业场景

           考虑:虽然性能有限,但完全满足作业需求

五、关键代码说明

 ①后端 app.py

1. 基础框架搭建

python

from flask import Flask, request, jsonify
from flask_cors import CORS
import sqlite3
import os

app = Flask(__name__)
CORS(app)  # 允许跨域请求

作用

  • 导入必要的Flask模块和数据库模块

  • 创建Flask应用实例

  • CORS配置:解决前后端分离开发中的跨域问题,允许前端页面访问后端API

2. 数据库初始化

python

def init_db():
    """初始化数据库"""
    conn = sqlite3.connect('contacts.db')
    c = conn.cursor()
    c.execute('''
        CREATE TABLE IF NOT EXISTS contacts
        (id INTEGER PRIMARY KEY AUTOINCREMENT,
         name TEXT NOT NULL,
         phone TEXT NOT NULL,
         email TEXT)
    ''')
    conn.commit()
    conn.close()

作用

  • 创建SQLite数据库文件 contacts.db

  • 定义联系人表结构:

    • id:主键,自动增长

    • name:姓名,必填字段

    • phone:电话,必填字段

    • email:邮箱,可选字段

3. RESTful API接口实现

3.1 获取所有联系人 (GET)

python

@app.route('/contacts', methods=['GET'])
def get_contacts():
    conn = sqlite3.connect('contacts.db')
    c = conn.cursor()
    c.execute('SELECT * FROM contacts')
    contacts = [{'id': row[0], 'name': row[1], 'phone': row[2], 'email': row[3]} for row in c.fetchall()]
    conn.close()
    return jsonify(contacts)

作用:前端页面加载时调用,返回所有联系人的JSON数据

3.2 添加联系人 (POST)

python

@app.route('/contacts', methods=['POST'])
def add_contact():
    data = request.json
    conn = sqlite3.connect('contacts.db')
    c = conn.cursor()
    c.execute('INSERT INTO contacts (name, phone, email) VALUES (?, ?, ?)',
              (data['name'], data['phone'], data.get('email', '')))
    conn.commit()
    conn.close()
    return jsonify({'message': 'Contact added successfully'})

作用:接收前端提交的表单数据,将新联系人保存到数据库

3.3 更新联系人 (PUT)

python

@app.route('/contacts/<int:contact_id>', methods=['PUT'])
def update_contact(contact_id):
    data = request.json
    conn = sqlite3.connect('contacts.db')
    c = conn.cursor()
    c.execute('UPDATE contacts SET name=?, phone=?, email=? WHERE id=?',
              (data['name'], data['phone'], data.get('email', ''), contact_id))
    conn.commit()
    conn.close()
    return jsonify({'message': 'Contact updated successfully'})

作用:根据联系人ID更新对应的联系人信息

3.4 删除联系人 (DELETE)

python

@app.route('/contacts/<int:contact_id>', methods=['DELETE'])
def delete_contact(contact_id):
    conn = sqlite3.connect('contacts.db')
    c = conn.cursor()
    c.execute('DELETE FROM contacts WHERE id=?', (contact_id,))
    conn.commit()
    conn.close()
    return jsonify({'message': 'Contact deleted successfully'})

作用:根据联系人ID从数据库中删除对应的联系人

4. 应用启动

python

if __name__ == '__main__':
    init_db()
    app.run(debug=True, port=5000)

作用

  • 程序启动时自动初始化数据库

  • 启动Flask开发服务器,监听5000端口

  • 开启调试模式,便于开发时查看错误信息

②前端 contacts.html

核心数据结构

let contacts = [
    { id: 1, name: "张三", phone: "13800138000", email: "zhangsan@example.com" },
    { id: 2, name: "李四", phone: "13900139000", email: "lisi@example.com" }
];
let editingId = null;

功能说明

  • contacts 数组存储所有联系人数据,每个联系人包含id、姓名、电话和邮箱

  • editingId 变量用于跟踪当前正在编辑的联系人ID,null表示添加新联系人

联系人保存功能

function saveContact() {
    const name = document.getElementById('name').value;
    const phone = document.getElementById('phone').value;
    const email = document.getElementById('email').value;
    const id = document.getElementById('contactId').value;

    if (!name || !phone) {
        alert('姓名和电话是必填项!');
        return;
    }

    if (id) {
        // 编辑现有联系人
        const index = contacts.findIndex(contact => contact.id == id);
        if (index !== -1) {
            contacts[index] = { id: parseInt(id), name, phone, email };
        }
    } else {
        // 添加新联系人
        const newId = contacts.length > 0 ? Math.max(...contacts.map(c => c.id)) + 1 : 1;
        contacts.push({ id: newId, name, phone, email });
    }

    updateContactsTable();
    resetForm();
    alert(`联系人${id ? '更新' : '添加'}成功!`);
}

关键代码解析

  • document.getElementById() 获取表单输入值

  • findIndex() 查找数组中特定元素的索引

  • Math.max(...contacts.map(c => c.id)) 计算最大ID值用于生成新ID

  • contacts.push() 向数组添加新元素

联系人编辑功能

function editContact(button) {
    const row = button.closest('tr');
    const name = row.cells[0].textContent;
    const phone = row.cells[1].textContent;
    const email = row.cells[2].textContent;
    
    const contact = contacts.find(c => c.name === name && c.phone === phone);
    
    if (contact) {
        document.getElementById('contactId').value = contact.id;
        document.getElementById('name').value = contact.name;
        document.getElementById('phone').value = contact.phone;
        document.getElementById('email').value = contact.email;
        document.getElementById('formTitle').innerHTML = '<i class="fas fa-user-edit"></i> 编辑联系人';
        
        document.querySelector('.card').scrollIntoView({ behavior: 'smooth' });
    }
}

关键代码解析

  • button.closest('tr') 找到按钮所在的表格行

  • row.cells 访问表格行的单元格

  • contacts.find() 在数组中查找匹配的联系人

  • scrollIntoView() 将页面滚动到指定元素位置

联系人删除功能

function deleteContact(button) {
    if (confirm('确定要删除这个联系人吗?')) {
        const row = button.closest('tr');
        const name = row.cells[0].textContent;
        const phone = row.cells[1].textContent;
        
        contacts = contacts.filter(c => !(c.name === name && c.phone === phone));
        
        updateContactsTable();
        
        alert('联系人已删除!');
    }
}

关键代码解析

  • confirm() 显示确认对话框

  • filter() 方法从数组中过滤掉符合条件的元素

表格更新功能

function updateContactsTable() {
    const tbody = document.getElementById('contactsList');
    tbody.innerHTML = '';
    
    if (contacts.length === 0) {
        tbody.innerHTML = `
            <tr>
                <td colspan="4" class="empty-state">
                    <i class="fas fa-users"></i>
                    <p>暂无联系人,请添加新的联系人</p>
                </td>
            </tr>
        `;
        return;
    }
    
    contacts.forEach(contact => {
        const row = document.createElement('tr');
        row.innerHTML = `
            <td>${contact.name}</td>
            <td>${contact.phone}</td>
            <td>${contact.email}</td>
            <td>
                <div class="action-buttons">
                    <button class="btn-success action-btn" onclick="editContact(this)"><i class="fas fa-edit"></i> 编辑</button>
                    <button class="btn-danger action-btn" onclick="deleteContact(this)"><i class="fas fa-trash"></i> 删除</button>
                </div>
            </td>
        `;
        tbody.appendChild(row);
    });
}

关键代码解析

  • innerHTML = '' 清空表格内容

  • forEach() 遍历数组中的每个元素

  • document.createElement() 创建新的HTML元素

  • appendChild() 将新元素添加到DOM中

表单重置功能

function resetForm() {
    document.getElementById('contactId').value = '';
    document.getElementById('name').value = '';
    document.getElementById('phone').value = '';
    document.getElementById('email').value = '';
    document.getElementById('formTitle').innerHTML = '<i class="fas fa-user-plus"></i> 添加联系人';
}

关键代码解析

  • 将所有表单字段重置为空值

  • 将表单标题改回"添加联系人"

页面初始化

document.addEventListener('DOMContentLoaded', function() {
    updateContactsTable();
});

关键代码解析

  • DOMContentLoaded 事件在HTML文档完全加载和解析后触发

  • 确保页面加载完成后初始化联系人列表

系统架构总结

这个联系人管理系统实现了完整的CRUD(增删改查)功能:

  1. 数据存储:使用JavaScript数组在内存中存储联系人数据

  2. 用户界面:通过HTML表单和表格提供用户交互界面

  3. 功能实现

    • 添加联系人:收集表单数据并添加到数组

    • 编辑联系人:将现有数据填充到表单进行修改

    • 删除联系人:从数组中移除指定联系人

    • 查看联系人:在表格中显示所有联系人信息

  4. 数据验证:确保姓名和电话字段不为空

 

六、总结

本项目成功开发了一个前后端分离的联系人管理系统,圆满完成了作业的所有基础要求。

技术实现

采用HTML+JavaScript前端 + Python Flask后端 + SQLite数据库的技术组合,实现了完整的联系人增删改查功能。前后端通过RESTful API进行数据交互,架构清晰,代码规范。

核心成果

    ✅ 联系人添加、修改、删除功能

    ✅ 前后端分离架构,数据实时同步

    ✅ 规范的GitHub仓库管理和代码文档

    ✅ 简洁易用的Web界面

项目价值

这个项目不仅实现了具体的功能需求,更重要的是提供了一个完整的前后端分离开发范例。代码结构清晰,技术选型合理,既满足了作业要求,也为后续的Web开发学习奠定了良好基础。

整个项目从环境搭建到功能实现,完整展示了现代Web应用的基本开发流程,是一次很有价值的实践。

https://3187274252-netizen.github.io/832302202_leading_end/ 

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

164

社区成员

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

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