SHIMMER
个人博客后台实现
前端|其它
发布于2021-08-13 最近修改2023-05-29
286
0
Shimmer

个人博客后台实现

有幸参与到公司的很多中后台管理项目,借鉴设计模式,实现一个自己的博客后台,项目中有很多没有实现的部分,还存在数据模型的不解,待后面慢慢完善。

介绍
之前大家有印象的话,我分享过一个在服务器搭建个人博客的帖子 技术分享-从0搭建个人网站
当时也有在后面搭建管理后台的想法,零零散散的,终于初见雏形,有了一些基本的功能,此次分享旨在介绍我是如何一步步从需求整理、产品设计、技术选型到项目开发落地进行整个项目的。
需求整理
在学习过程中,我们会沉淀下很多技术点,一些好的文章,好看的照片,以及一些实用的代码片段和项目等。对于这些,我迫切需要一个统一整理归纳的平台,兼分享和共创。在接触了一些博客框架(动态:WordPress;静态:Hexo)后,还是决定自己动手实现一个~~(嘿!我可是干前端的,想要什么自己不会写吗?自由使我拍板。)~~。
产品设计

Preview

这个图看起来是不是有那么一点专业了,从图上看,项目实施分为三大块,前台展示部分,后台管理部分,以及基础服务的支持。其中,最难搞的当属数据库了,表结构设计,emmm,完全没有章法,总是需要什么就加一个,万幸没有崩盘。权限方面采用的是RBAC权限管理模式。
下面粗计一下功能(当然先推销一波网站啦):
~~前台数据展示。 ~~于风里读诗
~~后台项目搭建。 ~~于风里读诗的后台管理
文章管理、树洞管理、网站时间轴管理、图片资源管理、用户列表及详情页管理。
数据统计页。
旅行日记管理。
个人中心。
评论管理。
项目管理。
操作日志。
通知管理。
......
(以上排列不分先后,基本想起什么就加什么)
技术选型
前端采用的是umijs,公司很多基于umijs的项目,让我对umi很亲切,熟悉才能更好更快的开发。后端是基于nodejs(eggjs),这里我要高呼一声“javascript yyds”,万能的js让我有了指染后端的能力。
这里有一个前期问题,到现在已经无法挽回,那就是SSR,服务端渲染的问题,作为一个博客站,竟然没有服务端渲染,这是非常失败的,这个问题在很久之后我才发觉,但是当时后台项目正慢慢展开,所以只能搁置,预期在完成后台之后,用Next.js 重写前台站。
项目开发落地
项目开发目前还看不到结尾,所以单就开发中遇到的问题,耗时间的地方列一下:
登陆注册。
权限处理:路由权限,单点权限,权限表设计
图片上传。(基于腾讯云cos)参考地址

javascript
复制代码
TypeScript/** * 腾讯云对象储存实例 */ import COS from 'cos-js-sdk-v5'; import type { GetBucketParams } from 'cos-js-sdk-v5'; import api from '@/api'; const { all } = api; // 存储桶名称,由bucketname-appid 组成,appid必须填入,可以在COS控制台查看存储桶名称。 https://console.cloud.tencent.com/cos5/bucket const Bucket = 'img-1302605407'; /* 存储桶,必须字段 */ // 存储桶region可以在COS控制台指定存储桶的概览页查看 https://console.cloud.tencent.com/cos5/bucket/ // 关于地域的详情见 https://cloud.tencent.com/document/product/436/6224 const Region = 'ap-beijing'; /* 存储桶所在地域,必须字段 */ const cos = new COS({ // 可选参数 FileParallelLimit: 3, // 控制文件上传并发数 ChunkParallelLimit: 3, // 控制单个文件下分片上传并发数 ChunkSize: 1024 * 1024, // 控制分片大小,单位 B ProgressInterval: 50, // 控制 onProgress 回调的间隔 ChunkRetryTimes: 3, // 控制文件切片后单片上传失败后重试次数 UploadCheckContentMd5: true, // 上传过程计算 Content-MD5 getAuthorization: async (options, callback) => { // 异步获取临时密钥 // 服务端 JS 和 PHP 例子:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/ // 服务端其他语言参考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk // STS 详细文档指引看:https://cloud.tencent.com/document/product/436/14048 await all._getCosKeyTemporary().then(({ data }) => { callback({ TmpSecretId: data.credentials.tmpSecretId, TmpSecretKey: data.credentials.tmpSecretKey, SecurityToken: data.credentials.sessionToken, // 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误 StartTime: data.startTime, // 时间戳,单位秒,如:1580000000 ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000000 }); }); }, }); // 接下来可以通过 cos 实例调用 COS 请求。 // 上传对象 export const putCos = ({ file, StorageClass = 'STANDARD', onProgress, onSuccess, onError, }) => { cos.putObject( { Bucket /* 必须 */, Region /* 存储桶所在地域,必须字段 */, Key: file.name /* 必须 */, StorageClass: StorageClass as any, Body: file, // 上传文件对象 ContentType: '', onProgress, onTaskReady: onSuccess, // onTaskStart: (TaskInfo) => { // console.log(TaskInfo); // }, }, function (err, data) { err ? onError(err) : onSuccess(data); }, ); }; // 查询对象列表 export const getCosList = (callback, opt?: GetBucketParams) => { cos.getBucket( { Bucket /* 必须 */, Region /* 存储桶所在地域,必须字段 */, ...opt, }, function (err, data) { callback(err || data); }, ); }; // 下载对象 export const getCosObj = (name, callback) => { cos.getObject( { Bucket /* 必须 */, Region /* 存储桶所在地域,必须字段 */, Key: name /* 必须 */, // QueryString: `watermark/3/type/1/image/aHR0cDovL2V4YW1wbGVzLTEyNTEwMDAwMDQucGljc2gubXlxY2xvdWQuY29tL3NodWl5aW4uanBn`, // 加水印 DataType: 'blob', }, function (err, data) { callback(err || data.Body); }, ); }; // 删除对象 export const delCosObj = (name, callback) => { cos.deleteObject( { Bucket /* 必须 */, Region /* 存储桶所在地域,必须字段 */, Key: name /* 必须 */, }, function (err, data) { callback(err || data); }, ); };
javascript
复制代码
TypeScript/* * @Descripttion: cos后端临时密钥生成 * @version: * @Author: WangPeng * @Date: 2022-07-04 17:30:40 * @LastEditors: WangPeng * @LastEditTime: 2022-08-23 13:31:34 */ 'use strict'; const Controller = require('egg').Controller; const STS = require('qcloud-cos-sts'); class CosServerController extends Controller { async index() { const { ctx } = this; const cosKeyObj = {}; const config = { bucket: 'img-1302605407', // 存储桶名称 region: 'ap-beijing', // 存储桶所在地域 // 密钥的权限列表 allowActions: '*', allowPrefix: '*', durationSeconds: 3600, }; await this.service.cos .getCosKey() .then(data => { cosKeyObj.SecretId = data.find(item => item.key === 'SecretId').value; cosKeyObj.SecretKey = data.find( item => item.key === 'SecretKey' ).value; }) .catch(e => { console.log(e); ctx.body = { code: 300, msg: '签名生成失败', }; }); // TODO 这里根据自己业务需要做好放行判断 // if (allowPrefix === '/') { // ctx.status = 300; // ctx.body = { // msg: '请修改 allowPrefix 配置项,指定允许上传的路径前缀', // }; // } // 获取临时密钥 const AppId = config.bucket.split('-')[1]; // 数据万象DescribeMediaBuckets接口需要resource为*,参考 https://cloud.tencent.com/document/product/460/41741 const policy = { version: '2.0', statement: [{ action: config.allowActions, effect: 'allow', resource: [ 'qcs::cos:' + config.region + ':uid/' + AppId + ':' + config.bucket + '/' + config.allowPrefix, ], }], }; const startTime = Math.round(Date.now() / 1000); await STS.getCredential({ secretId: cosKeyObj.SecretId, secretKey: cosKeyObj.SecretKey, region: config.region, durationSeconds: config.durationSeconds, policy, }).then(data => { data.startTime = startTime; ctx.body = data; }); } async getCosKey() { const { ctx } = this; await this.service.cos .getCosKey() .then(data => { ctx.body = { code: 200, msg: '数据获取成功', data, }; }) .catch(e => { console.log(e); ctx.body = { code: 300, msg: '数据获取失败', }; }); } } module.exports = CosServerController;

写到这里的时候脑补了很久,登陆鉴权怎么设计的,登陆过期如何处理,如何写sql语句去操作数据库,其实很多东西,都是从百度上自己查找类似方案,结合自己的项目修补整理,然后呈现在大家面前,由于我对后端涉猎很少,可能在这里会有很大的问题,望批评指正。
整体进度来讲,目前实现的,还距离我期望的样子很远,但能够在项目中不断进步成长,接触更广泛的知识,不仅仅局限于前端的思路去思考问题,我觉得,这是整个项目带给我最大的收获。
未解决难点问题
评论表设计。
操作日志的记录。
通知的实现。
埋点记录访客数据与资源浏览量统计。
期望
在我的计划中,整个项目不仅仅供给我个人使用,前台站的所有数据尽量实现可配置,未来通过不同的域名去到不同小伙伴的个人博客,通过同一个管理系统维护,实现系统最大的利用价值。
嘿!包老大在视频中可是说过:数据就是我们的“数字资产”。(什么?竟然有人不知道?solar宣传视频再看300遍)大量的数据支持,能够不断完善我的网站,让我们做更多的事(别问我,我也不知道做什么)
最后,欢迎感兴趣的小伙伴一起研究。 本人唯一联系微信: wp0403-

此处附上代码仓库(非实时更新,一般我在gitee上)
前端 https://github.com/wp0403/wp-boke-admin-client-react
后端 https://github.com/wp0403/wp-boke-admin-server
目录