初次提交

This commit is contained in:
MoonLeeeaf
2025-03-15 00:15:44 +08:00
commit 0559f0ecaa
7 changed files with 1421 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
node_modules/
white_silk_data/

1053
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

8
package.json Normal file
View File

@@ -0,0 +1,8 @@
{
"private": "true",
"type": "module",
"dependencies": {
"express": "^4.21.2",
"socket.io": "^4.8.1"
}
}

42
server/api/User.js Normal file
View File

@@ -0,0 +1,42 @@
class UserManager {
static findUserById(id) {
}
static findUserByName(name) {
}
/**
* 创建新用户
* @param { Object } arg
* @param { String } [arg.name] 用户名
* @param { String } [arg.name] 用户名
* @returns { User }
*/
static createUser() {
}
}
class User {
/** @type { Number } */
id
/** @type { String } */
name
/** @type { String } */
nick
/** @type { String } */
description
}
class UserApi {
static createUser() {
}
}
export {
User,
UserManager,
UserApi
}

249
server/lib/io.js Normal file
View File

@@ -0,0 +1,249 @@
/*
* Simple File Access Library
* Author - @MoonLeeeaf <https://github.com/MoonLeeeaf>
*/
import fs from 'node:fs'
/**
* 简单文件类
*/
class io {
/**
* 构建函数
* @param { String } path
* @param { String } mode
*/
constructor(path, mode) {
this.path = path
this.r = mode.includes('r')
this.w = mode.includes('w')
}
/**
* 构建函数
* @param { String } path
* @param { String } mode
*/
static open(path, mode) {
if (!mode || mode == '')
throw new Error('当前文件对象未设置属性!')
return new io(path, mode)
}
/**
* 检测文件或目录是否存在
* @param { String } path
* @returns { Boolean }
*/
static exists(path) {
return fs.existsSync(path)
}
/**
* 枚举目录下所有文件
* @param { String } 扫描路径
* @param { Function<String> } 过滤器<文件完整路径>
* @param { Boolean } 是否搜索文件夹内的文件
* @returns { String[] } 文件完整路径列表
*/
static listFiles(path, filter, recursive) {
let a = fs.readdirSync(path, { recursive: recursive })
a.forEach(function(v, index, arrayThis) {
arrayThis[index] = `${path}//${v}`
})
return a.filter(function(v) {
if (!fs.lstatSync(v).isFile()) return false
if (filter) return filter(v)
return true
})
}
/**
* 枚举目录下所有文件夹
* @param { String } 扫描路径
* @param { Function<String> } 过滤器<文件夹完整路径>
* @param { Boolean } 是否搜索文件夹内的文件夹
* @returns { String[] } 文件夹完整路径列表
*/
static listFolders(path, filter, recursive) {
let a = fs.readdirSync(path, { recursive: recursive })
a.forEach(function(v, index, arrayThis) {
arrayThis[index] = `${path}//${v}`
})
return a.filter(function(v) {
if (!fs.lstatSync(v).isDirectory()) return false
if (filter) return filter(v)
return true
})
}
/**
* 获取文件(夹)的全名
* @param { String } path
* @returns { String } name
*/
static getName(path) {
let r = /\\|\//
let s = path.search(r)
while (s != -1) {
path = path.substring(s + 1)
s = path.search(r)
}
return path
}
/**
* 获取文件(夹)的父文件夹路径
* @param { String } path
* @returns { String } parentPath
*/
static getParent(path) {
return path.substring(0, path.lastIndexOf(this.getName(path)) - 1)
}
/**
* 复制某文件夹的全部内容, 自动创建文件夹
* @param { String } from
* @param { String } to
*/
static copyDir(from, to) {
this.mkdirs(to)
this.listFiles(from).forEach(function(v) {
io.open(v, 'r').pipe(io.open(`${to}//${io.getName(v)}`, 'w')).close()
})
this.listFolders(from).forEach(function(v) {
io.copyDir(v, `${to}//${io.getName(v)}`)
})
}
/**
* 删除文件
* @param { String } path
*/
static remove(f) {
fs.rmSync(f, { recursive: true })
}
/**
* 移动文件
* @param { String }} path
* @param { String } newPath
*/
static move(path, newPath) {
fs.renameSync(path, newPath)
}
/**
* 创建文件夹, 有则忽略
* @param { String } path
* @returns { String } path
*/
static mkdirs(path) {
if (!this.exists(path))
fs.mkdirSync(path, { recursive: true })
return path
}
/**
* 将文件内容写入到另一个文件
* @param { io } file
* @returns { io } this
*/
pipe(file) {
file.writeAll(this.readAll())
file.close()
return this
}
/**
* 检查文件是否存在, 若无则写入, 有则忽略
* @param { Buffer | String } 写入数据
* @returns { io } 对象自身
*/
checkExistsOrWrite(data) {
if (!io.exists(this.path))
this.writeAll(data)
return this
}
/**
* 检查文件是否存在, 若无则写入 JSON 数据, 有则忽略
* @param { Object } 写入数据
* @returns { io } 对象自身
*/
checkExistsOrWriteJson(data) {
if (!io.exists(this.path))
this.writeAllJson(data)
return this
}
/**
* 读取一个文件
* @returns { Buffer } 文件数据字节
*/
readAll() {
if (this.r)
return fs.readFileSync(this.path)
throw new Error('当前文件对象未设置可读')
}
/**
* 读取一个文件并关闭
* @returns { Buffer } 文件数据
*/
readAllAndClose() {
let r
if (this.r)
r = this.readAll()
else
throw new Error('当前文件对象未设置可读!')
this.close()
return r
}
/**
* 写入一个文件
* @param { Buffer | String } 写入数据
* @returns { io } 对象自身
*/
writeAll(data) {
if (this.w)
fs.writeFileSync(this.path, data)
else
throw new Error('当前文件对象未设置可写!')
return this
}
/**
* 写入一个JSON文件
* @param { Object } 写入数据
* @returns { io } 对象自身
*/
writeAllJson(data) {
if (!data instanceof Object)
throw new Error('你只能输入一个 JSON 对象!')
if (this.w)
this.writeAll(JSON.stringify(data))
else
throw new Error('当前文件对象未设置可写!')
return this
}
/**
* 读取一个JSON文件
* @returns { Object } 文件数据
*/
readAllJson() {
if (this.r)
return JSON.parse(this.readAll().toString())
throw new Error('当前文件对象未设置可读!')
}
/**
* 读取一个JSON文件并关闭
* @returns { Object } 文件数据
*/
readAllJsonAndClose() {
let r
if (this.r)
r = JSON.parse(this.readAll().toString())
else
throw new Error('当前文件对象未设置可读!')
this.close()
return r
}
/**
* 回收文件对象
*/
close() {
delete this.path
delete this.r
delete this.w
}
}
export default io

45
server/main.js Normal file
View File

@@ -0,0 +1,45 @@
import http from 'node:http'
// import https from 'node:https' // 暂时
import express from 'express'
import { Server as SocketIoServer } from 'socket.io'
const app = express()
const httpApp = http.createServer(app)
const io = new SocketIoServer(httpApp, {})
class ThewhiteSilkParams {
/**
* @type { String }
*/
method
/**
* @type { Object }
*/
args
}
const events = []
import { UserApi } from './api/User.js'
for (let i of [
UserApi
]) {
for (let i2 of Object.keys(i)) {
events.push(i[i2])
}
}
io.on("connection", (socket) => {
socket.on('the_white_silk',
/**
* @param { ThewhiteSilkParams } params
* @param { Function } callback
*/
(params, callback) => {
if ((params || callback) == null) return;
}
)
})
httpApp.listen(80)

22
大纲.md Normal file
View File

@@ -0,0 +1,22 @@
### TheWhiteSilk
这是满月不知道第几次试图写即时通讯项目了
创日: 2025/3/17
#### 后端开发清单
* 后端
* 数据库 (JSON) - 虽然我知道这很低效但是我目前只会使用这个 以后会考虑更换
* 用户
* 初始化信息
* 唯一 ID (不可用于**用户**查询账号, 管理用途)
* 安全
* 两步验证
* 多客户端
* 资料
* 用户名(仅用于**用户**查询, 因为随时可改, 因此不具备管理用途)
* 用户头像
* 昵称
* 用户简介
* ~~WIP~~