背景
最近的 DeepSeek 大模型着实火了一趟糊涂,我最近刚好有一个需求应用开发,就想这利用大模型,看看完全通过AI能到什么程度。
这个应用的作用是这样的,为了激发小孩子的学习热情,规范他的日常行为。给他设计了一个积分系统,比如每天晚上学习英语就给他奖励一个星星积分、在家里收拾玩具等奖励一颗星星。同时过年的时候他收到了不少的压岁钱,但是这些钱交给他保管的话就容易丢。因此像星星和压岁钱都通过这个系统来管理。
需求分析
我先写一个 PRD 稿。首先将上面的背景发生给 AI,AI 给我以下的 PRD 稿
我的提问:
为了激发小孩子的学习热情,规范他的日常行为。给他设计了一个积分系统?
AI 的回答:
好的,没问题!这是一份针对激发孩子学习热情和规范日常行为的积分系统 PRD (Product Requirements Document) 初稿。请注意,这只是一个基础框架,你需要根据实际情况进行调整和完善。
产品需求文档 (PRD)
1. 产品名称: 星星乐园 (可根据实际情况修改)
2. 产品目标:
- 激发孩子学习热情: 通过奖励机制,鼓励孩子主动学习,培养良好的学习习惯。
- 规范孩子日常行为: 通过积分奖励,引导孩子养成良好的生活习惯和行为规范。
- 培养孩子理财意识: 通过积分兑换和压岁钱管理,培养孩子初步的理财意识。
- 增强亲子互动: 家长可以通过系统了解孩子的学习和生活情况,进行有针对性的引导和鼓励。
3. 目标用户:
家长: 负责设置积分规则、奖励积分、管理孩子账户、查看孩子表现。
孩子: 查看积分、了解奖励规则、兑换奖励。
4. 产品功能:
4.1 家长端 (Web/App):
4.1.1 积分规则设置:
功能描述: 家长可以自定义积分规则,例如:
- 学习英语 30 分钟:奖励 1 颗星星
- 完成作业:奖励 2 颗星星
- 收拾玩具:奖励 1 颗星星
- 按时睡觉:奖励 1 颗星星
- 帮助做家务:奖励 2 颗星星
界面元素:
- 行为描述输入框
- 积分奖励数值输入框
- 添加/删除规则按钮
- 规则列表展示
交互流程:
- 家长点击“添加规则”按钮,输入行为描述和积分奖励数值,点击“保存”。
- 家长可以在规则列表中修改或删除已有的规则。
4.1.2 积分奖励:
功能描述: 家长可以根据孩子的表现,手动奖励积分。
界面元素:
- 孩子账户选择
- 行为选择 (下拉列表,显示已设置的积分规则)
- 自定义奖励描述输入框 (可选)
- 奖励积分按钮
交互流程:
- 家长选择孩子账户,选择行为,输入自定义奖励描述 (可选),点击“奖励积分”按钮。
4.1.3 积分兑换管理:
功能描述: 家长可以设置积分兑换的奖品,并管理孩子的兑换申请。
界面元素:
- 奖品列表展示 (名称、所需积分、图片)
- 添加/删除奖品按钮
- 兑换申请列表 (孩子、奖品、所需积分、状态)
- 同意/拒绝兑换申请按钮
交互流程:
- 家长点击“添加奖品”按钮,输入奖品名称、所需积分、上传图片,点击“保存”。
- 家长可以在奖品列表中修改或删除已有的奖品。
- 家长在兑换申请列表中查看孩子的兑换申请,点击“同意”或“拒绝”。
4.1.4 压岁钱管理:
功能描述: 家长可以记录孩子的压岁钱收入和支出,并设置支出权限。
界面元素:
- 压岁钱总额显示
- 收入记录列表 (日期、金额、来源)
- 支出记录列表 (日期、金额、用途)
- 添加收入/支出记录按钮
- 支出权限设置 (例如:每月可支配金额)
交互流程:
- 家长点击“添加收入”或“添加支出”按钮,输入日期、金额、来源/用途,点击“保存”。
- 家长可以设置孩子每月可支配的压岁钱金额。
4.1.5 孩子账户管理:
功能描述: 家长可以创建和管理孩子的账户信息。
界面元素:
- 孩子账户列表 (头像、昵称)
- 添加/删除孩子账户按钮
- 孩子账户信息编辑 (头像、昵称、生日等)
交互流程:
- 家长点击“添加孩子账户”按钮,输入孩子信息,上传头像,点击“保存”。
- 家长可以在孩子账户列表中修改或删除已有的账户。
4.1.6 数据统计与分析:
功能描述: 家长可以查看孩子的学习和行为数据统计,了解孩子的进步和不足。
界面元素:
- 积分增长趋势图
- 各行为积分占比图
- 压岁钱收支明细图
交互流程:
- 家长选择不同的时间范围,查看相应的数据统计图表。
4.2 孩子端 (App):
4.2.1 积分查看:
功能描述: 孩子可以查看自己的积分余额和积分明细。
界面元素:
- 积分余额显示
- 积分明细列表 (日期、行为、积分)
交互流程:
- 孩子打开 App,即可看到自己的积分余额和积分明细。
4.2.2 奖励规则查看:
功能描述: 孩子可以查看当前的积分奖励规则。
界面元素:
- 积分规则列表 (行为描述、积分奖励)
交互流程:
- 孩子点击“奖励规则”按钮,即可看到当前的积分奖励规则。
4.2.3 奖品兑换:
功能描述: 孩子可以查看可兑换的奖品,并提交兑换申请。
界面元素:
- 奖品列表展示 (名称、所需积分、图片)
- 兑换按钮
交互流程:
- 孩子选择想要兑换的奖品,点击“兑换”按钮,提交兑换申请。
4.2.4 压岁钱查看:
功能描述: 孩子可以查看自己的压岁钱余额和收支明细。
界面元素:
- 压岁钱余额显示
- 收支明细列表 (日期、金额、来源/用途)
交互流程:
- 孩子打开 App,即可看到自己的压岁钱余额和收支明细。
5. 非功能性需求:
- 性能: 系统响应速度快,数据加载流畅。
- 安全: 保护用户数据安全,防止恶意攻击。
- 易用性: 界面简洁直观,操作简单易懂。
- 兼容性: 兼容主流的手机操作系统和浏览器。
- 可扩展性: 系统架构具有良好的可扩展性,方便后续功能的添加和升级。
6. 界面设计:
- 整体风格: 活泼、卡通、色彩鲜艳,符合儿童的审美。
- 家长端: 界面简洁、清晰,信息展示完整。
- 孩子端: 界面有趣、互动性强,操作简单易懂。
7. 技术方案:
- 前端: React (Web), React Native (App)
- 后端: Node.js, Python (Django/Flask)
- 数据库: MongoDB, MySQL
- 云服务: AWS, Google Cloud, Azure
8. 风险与挑战:
- 孩子对积分失去兴趣: 需要不断更新奖励规则和奖品,保持新鲜感。
- 家长不积极参与: 需要提供便捷的操作方式和有价值的数据分析,鼓励家长参与。
- 系统安全问题: 需要加强安全防护,防止恶意攻击和数据泄露。
9. 未来发展方向:
- 引入 AI 智能推荐: 根据孩子的学习和行为习惯,智能推荐奖励规则和奖品。
- 增加社交互动功能: 孩子可以分享自己的学习成果和奖励,与其他孩子互动。
- 与教育平台对接: 与在线教育平台对接,自动记录孩子的学习时间和进度,奖励积分。
10. 附件:
- 原型图: (建议提供高保真原型图)
- 流程图: (描述关键业务流程)
注意事项:
- 用户调研: 在设计产品之前,进行充分的用户调研,了解家长和孩子的需求。
- 迭代开发: 采用迭代开发模式,逐步完善产品功能。
- 数据分析: 持续跟踪用户数据,分析产品效果,并进行优化。
希望这份 PRD 初稿能帮助你更好地规划你的产品!记得根据实际情况进行调整和完善。祝你成功!
后端开发
后端考虑用Node的express来实现,考虑到我是前端。首先是设计数据库
我的提问
设计一个记账系统的数据库
AI的回答
下面给出一种基于 MySQL 的设计方案,满足以下需求:
- 多人记账,每个用户有自己的账户余额。
- 每笔交易记录(收入或支出)有详细信息。
- 每个用户可以自定义自己的分类(类别),支持增加和删除。
1. 用户表 (Users)
存储用户的基本信息。
CREATE TABLE Users ( user_id INT AUTO_INCREMENT PRIMARY KEY, -- 用户ID username VARCHAR(100) NOT NULL, -- 用户名 email VARCHAR(100) NOT NULL, -- 邮箱 password_hash VARCHAR(255) NOT NULL, -- 密码哈希 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 注册时间 );
2. 账户表 (Accounts)
记录每个用户的总余额。
CREATE TABLE Accounts ( account_id INT AUTO_INCREMENT PRIMARY KEY, -- 账户ID user_id INT NOT NULL, -- 对应用户ID total_balance DECIMAL(10, 2) DEFAULT 0.00, -- 总余额 FOREIGN KEY (user_id) REFERENCES Users(user_id) ON DELETE CASCADE );
3. 自定义类别表 (Categories)
每个用户可以拥有自己的类别,类别用于对交易进行归类,支持自定义增加和删除。
CREATE TABLE Categories ( category_id INT AUTO_INCREMENT PRIMARY KEY, -- 类别ID user_id INT NOT NULL, -- 类别所属的用户 name VARCHAR(100) NOT NULL, -- 类别名称(如:餐饮、工资等) description TEXT, -- 类别描述,可选 transaction_type ENUM('income', 'expense') NOT NULL, -- 类别对应的交易类型 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间 FOREIGN KEY (user_id) REFERENCES Users(user_id) ON DELETE CASCADE );说明:
- 这里的
transaction_type用于约束一个类别是用于收入还是支出(也可以允许相同名称的类别跨类型,但一般业务逻辑中区分会更清晰)。- 当用户删除账户时,相关类别会自动删除;但删除类别时需要考虑已有交易的处理。
4. 交易记录表 (Transactions)
记录每笔收入或支出的详细信息。
CREATE TABLE Transactions ( transaction_id INT AUTO_INCREMENT PRIMARY KEY, -- 交易记录ID user_id INT NOT NULL, -- 对应用户ID amount DECIMAL(10, 2) NOT NULL, -- 金额(收入为正,支出也可以统一规定正数并根据交易类型决定加减) transaction_type ENUM('income', 'expense') NOT NULL, -- 交易类型 category_id INT, -- 对应的类别ID(允许为空,若用户未指定类别) description TEXT, -- 交易描述 transaction_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 交易时间 FOREIGN KEY (user_id) REFERENCES Users(user_id) ON DELETE CASCADE, FOREIGN KEY (category_id) REFERENCES Categories(category_id) ON DELETE SET NULL );注意:
category_id设置为可为空(NULL),原因在于当用户删除某个类别时,不会级联删除交易历史,而是将该字段置为 NULL,从而保留交易记录。- 如果业务中不允许删除已有交易的类别,也可以在业务层做检查或在数据库层通过触发器实现相应逻辑。
业务操作示例
增加自定义类别
用户可以增加自己的类别,例如用户
user_id=1新增一个支出类别 “餐饮”:INSERT INTO Categories (user_id, name, description, transaction_type) VALUES (1, '餐饮', '与饮食相关的支出', 'expense');删除自定义类别
当用户删除某个类别时,建议先检查是否存在关联的交易记录。如果允许删除,同时保留交易记录,则使用:
DELETE FROM Categories WHERE category_id = 5 AND user_id = 1;此时,所有引用该类别的交易记录中,
category_id会因为ON DELETE SET NULL机制而被置为 NULL。记一笔交易
假设用户
user_id=1使用类别category_id=3记一笔收入 200 元:
- 插入交易记录:
INSERT INTO Transactions (user_id, amount, transaction_type, category_id, description) VALUES (1, 200.00, 'income', 3, '工资收入');2. 更新账户余额:
UPDATE Accounts SET total_balance = total_balance + 200.00 WHERE user_id = 1;
小结
- Users 表 用于存储用户基本信息。
- Accounts 表 用于维护用户总余额。
- Categories 表 为每个用户提供自定义类别管理,支持增加和删除,同时通过
user_id实现用户私有化。- Transactions 表 记录每笔交易,关联用户和类别,并在类别删除时采用
ON DELETE SET NULL方式保留交易记录。这样的设计能够满足多用户记账和每个用户自定义类别管理的需求,同时便于后续的扩展和维护。如果有更复杂的业务逻辑,也可以在此基础上做进一步调整。
我的提问
基于上面的数据库设计后端
AI的回答
基于上述数据库设计方案,下面我将提供一个基于 Node.js 和 Express 实现的登录接口。假设你已经使用
bcrypt来加密密码,并使用jsonwebtoken来生成 JWT Token 进行身份验证。
首先,确保你安装了所需的依赖:
npm install express mysql2 bcryptjs jsonwebtoken body-parser1. 数据库连接
// db.js const mysql = require('mysql2'); // 创建数据库连接池 const pool = mysql.createPool({ host: 'localhost', user: 'root', password: 'yourpassword', database: 'yourdatabase', }); module.exports = pool.promise(); // 使用 promise 版本的连接池2. 登录接口实现
// server.js const express = require('express'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const bodyParser = require('body-parser'); const pool = require('./db'); const app = express(); app.use(bodyParser.json()); // 解析 JSON 请求体 const JWT_SECRET = 'your_jwt_secret'; // 用于生成 JWT 的密钥 // 登录接口 app.post('/login', async (req, res) => { const { email, password } = req.body; // 检查请求是否包含email和password if (!email ||!password) { return res.status(400).json({ message: 'Email and password are required' }); } try { // 查询数据库用户 const [rows] = await pool.execute('SELECT * FROM Users WHERE email =?', [email]); if (rows.length === 0) { return res.status(401).json({ message: 'Invalid credentials' }); } const user = rows[0]; // 比对密码 const isMatch = await bcrypt.compare(password, user.password_hash); if (!isMatch) { return res.status(401).json({ message: 'Invalid credentials' }); } // 生成 JWT const token = jwt.sign({ user_id: user.user_id, username: user.username }, JWT_SECRET, { expiresIn: '1h' }); // 返回 token 和用户信息 res.json({ message: 'Login successful', token, user: { user_id: user.user_id, username: user.username, email: user.email, }, }); } catch (err) { console.error(err); res.status(500).json({ message: 'Internal server error' }); } }); // 启动服务器 const PORT = 3000; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); });3. 生成密码哈希(用于注册时)
// 使用 bcryptjs 来生成哈希密码 const bcrypt = require('bcryptjs'); // 假设用户的原始密码是 'password123' const password = 'password123'; bcrypt.hash(password, 10, (err, hash) => { if (err) { console.error('Error hashing password:', err); } else { console.log('Hashed password:', hash); } });4. 保护路由(需要验证 JWT)
为确保只有登录用户才能访问某些接口,我们可以使用 JWT 来保护路由。首先,创建一个中间件来验证 Token:
// authMiddleware.js const jwt = require('jsonwebtoken'); const JWT_SECRET = 'your_jwt_secret'; // 用于生成 JWT 的密钥 module.exports = function (req, res, next) { const token = req.headers['authorization']?.split(' ')[1]; // 从 Authorization 头部获取 token if (!token) { return res.status(403).json({ message: 'No token provided' }); } jwt.verify(token, JWT_SECRET, (err, decoded) => { if (err) { return res.status(403).json({ message: 'Invalid token' }); } // 将解码后的用户信息附加到请求中 req.user = decoded; next(); // 调用下一个中间件或路由处理程序 }); };然后,在你需要保护的路由中使用这个中间件:
// 受保护的路由 const authMiddleware = require('./authMiddleware'); app.get('/profile', authMiddleware, async (req, res) => { try { // 使用 req.user 来获取当前登录的用户 const [userRows] = await pool.execute('SELECT * FROM Users WHERE user_id =?', [req.user.user_id]); if (userRows.length === 0) { return res.status(404).json({ message: 'User not found' }); } const user = userRows[0]; res.json({ user_id: user.user_id, username: user.username, email: user.email, }); } catch (err) { console.error(err); res.status(500).json({ message: 'Internal server error' }); } });5. 启动服务器
确保你的数据库已经运行,并且可以通过
mysql2连接。然后通过以下命令启动服务器:node server.js
总结
这个示例包括了一个简单的登录接口,用户通过邮箱和密码进行登录,密码会与数据库中的哈希进行比对。如果验证成功,系统会生成一个 JWT Token 并返回给用户,之后用户可以通过这个 Token 访问受保护的路由。
此设计还支持在需要时使用
authMiddleware来验证 JWT,确保只有认证过的用户才能访问敏感数据。
我的提问
请写一个注册的接口
AI的回答
好的,下面是一个完整的注册接口实现,用户通过提供用户名、邮箱和密码进行注册,密码会在存入数据库前加密,确保安全性。
1. 注册接口实现
// server.js const express = require('express'); const bcrypt = require('bcryptjs'); const bodyParser = require('body-parser'); const pool = require('./db'); const app = express(); app.use(bodyParser.json()); // 解析 JSON 请求体 // 注册接口 app.post('/register', async (req, res) => { const { username, email, password } = req.body; // 检查是否提供了所有必要的字段 if (!username ||!email ||!password) { return res.status(400).json({ message: '用户名、邮箱和密码是必填的' }); } try { // 检查邮箱是否已被注册 const [existingUser] = await pool.execute('SELECT * FROM Users WHERE email =?', [email]); if (existingUser.length > 0) { return res.status(400).json({ message: '该邮箱已被注册' }); } // 加密密码 const hashedPassword = await bcrypt.hash(password, 10); // 插入新用户数据 const [result] = await pool.execute( 'INSERT INTO Users (username, email, password_hash) VALUES (?,?,?)', [username, email, hashedPassword] ); // 返回成功响应 res.status(201).json({ message: '注册成功', user_id: result.insertId }); } catch (err) { console.error(err); res.status(500).json({ message: '注册失败,请稍后重试' }); } }); // 启动服务器 const port = 3000; app.listen(port, () => { console.log(`Server running on port ${port}`); });2. 说明
- 字段验证:接口首先会检查请求体中是否包含了
username、password字段。如果缺少任何一个字段,接口会返回一个400 Bad Request的错误。- 检查邮箱是否已注册:在注册新用户之前,系统会检查邮箱是否已经存在于数据库中。如果已存在,接口会返回
400错误,提示用户邮箱已被注册。- 密码加密:在注册时,用户的密码会被加密(使用
bcryptjs的hash方法),然后存入数据库。- 插入用户数据:在成功加密密码后,接口将用户名、邮箱和加密后的密码插入
Users表。- 返回结果:注册成功后,返回一个
201 Created状态码以及新用户的user_id。3. 测试
假设你的服务器在
localhost:3000上运行,你可以使用 Postman 或curl测试接口。请求示例:
POST http://localhost:3000/register Content-Type: application/json { "username": "newuser", "email": "newuser@example.com", "password": "securePassword123" }响应示例:
{ "message": "注册成功", "user_id": 1 }如果该邮箱已经被注册,你会收到类似以下的错误消息:
{ "message": "该邮箱已被注册" }
4. 启动服务器
同样,确保你已在项目中安装并配置好所有依赖后,运行以下命令启动服务器:
node server.js
通过这个接口,你就能实现一个基本的用户注册功能,确保密码安全并避免重复注册。
我的提问
如何给前端页面种Cookie
AI的回答
在用户登录成功后,服务器可以生成一个令牌(比如 JWT)并将其发送到客户端,客户端可以将该令牌存储在浏览器中,然后将其附加到每个后续的请求中,以便服务器进行验证。
步骤概览:
- 用户登录成功后生成 JWT
- 将 JWT 返回给客户端,并存储在浏览器的 cookies 或 localStorage 中
- 客户端每次请求时,在 HTTP 请求头中携带 JWT
- 服务器验证请求中的 JWT 来校验用户身份
1. 登录时返回 JWT
假设你使用的是 Node.js 和 Express,生成 JWT 的代码大致如下:
const jwt = require('jsonwebtoken'); // 登录路由 app.post('/login', (req, res) => { const { email, password } = req.body; // 验证用户凭证(这里是一个简单的例子) if (email === 'user@example.com' && password ==='securePassword123') { // 用户认证通过,生成 JWT const token = jwt.sign({ email }, 'your-secret-key', { expiresIn: '1h' }); // 将 token 返回给客户端(存储到 cookies 或 localStorage) res.json({ token }); } else { res.status(401).json({ message: '邮箱或密码错误' }); } });2. 客户端存储 JWT
使用 Cookies 存储(推荐)
将 JWT 存储在 cookies 中,可以使得每个请求自动带上 token,浏览器会自动处理 cookie 的发送。
登录成功后,前端可以将 JWT 存储到
HttpOnly和Secure的 cookie 中,以提高安全性:// 使用 Express 设置 HttpOnly cookie app.post('/login', (req, res) => { const { email, password } = req.body; if (email === 'user@example.com' && password ==='securePassword123') { const token = jwt.sign({ email }, 'your-secret-key', { expiresIn: '1h' }); // 将 token 设置到 cookie 中,设置 HttpOnly 和 Secure 标志 res.cookie('authToken', token, { httpOnly: true, // 客户端无法访问这个 cookie secure: true, // 只有在 HTTPS 环境下才能使用 maxAge: 3600000 // 1 小时有效期 }); res.json({ message: '登录成功' }); } else { res.status(401).json({ message: '邮箱或密码错误' }); } });使用 LocalStorage 存储
如果你不希望使用 cookies,也可以将 token 存储在
localStorage中:// 登录成功后,存储 token 到 localStorage fetch('/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'user@example.com', password:'securePassword123' }) }) .then(response => response.json()) .then(data => { localStorage.setItem('authToken', data.token); // 存储在 localStorage }) .catch(error => console.log(error));3. 客户端发送带有 JWT 的请求
在后续的请求中,客户端需要将 token 添加到请求头中,以便服务器验证用户身份。
使用 Cookies 发送(自动)
如果你将 token 存储在 cookies 中,浏览器会自动处理,不需要额外的代码。
使用 LocalStorage 发送
如果你将 token 存储在
localStorage中,则需要手动将 token 附加到每个请求的 Authorization 头部:const token = localStorage.getItem('authToken'); fetch('/protected - endpoint', { method: 'GET', headers: { 'Authorization': `Bearer ${token}` // 在请求头中附加 token } }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.log(error));4. 服务器验证 JWT
服务器收到请求时,需要从请求头中获取 token,并验证其有效性:
const jwt = require('jsonwebtoken'); // 中间件用于验证 token function authenticateToken(req, res, next) { const token = req.cookies.authToken || req.headers['authorization']?.split(' ')[1]; if (!token) { return res.status(403).json({ message: '缺少认证 token' }); } jwt.verify(token, 'your - secret - key', (err, user) => { if (err) { return res.status(403).json({ message: '无效的 token' }); } req.user = user; // 保存用户信息到请求中 next(); // 调用下一个中间件或路由处理程序 }); } // 保护的路由 app.get('/protected - endpoint', authenticateToken, (req, res) => { res.json({ message: '访问受限的资源成功', user: req.user }); });总结
- 在用户登录后,服务器生成并返回一个 JWT。
- 客户端存储 JWT(通常通过 Cookies 或
localStorage)。- 客户端发送请求时附加 JWT(通过
Authorizationheader 或 cookies)。- 服务器通过中间件验证 JWT,确保请求是由授权用户发起的。
这种方式可以确保每次请求都得到验证,并且提高了应用的安全性。
前端开发
前端的AI的回复忘记记录了。。。
问题大概就是利用react框架,搭建一个记账系统。包括登录、列表等。
总结
利用AI是可以搭建起来这个前后端的架构和应用,但是还是需要熟悉基本的前后端搭建知识。包括服务如何部署搭建等等。你知道了这些东西后,只要问了AI就会给你相应的代码。
AI给的代码质量确实一般,甚至是有点糟糕的。
后端代码的问题包括变量的命名、整体的代码结构等等。同时还有问题就是AI前后给出的代码可能一致性不好(代码风格和实现不一样),不像是单人或者团队合作的时候会遵守一定的编码规范等
解决办法就是实现完整体功能后,再把所有代码一块给AI,让AI给你优化。(持续通过AI来迭代、优化代码)。
前端代码的问题除了以上的就是,前端给出代码的UI很丑,有一说一确实非常不好看。还处于勉强能用的阶段。有些地方的甚至没有没有处于中心,有些UI甚至是不能对齐。当然对前端开发者来说UI还原本身也是很耗时耗力的工作,但是前端工程师可以利用成熟的业务组件,快速搭建出美观的页面来。
成品效果
手机APP是通过把web页面打包成APK来实现的
github地址:github.com/bravedavid/…