Merge pull request #174 from JeremyYu-cn/generate-html

feat: format server import method: from commonJs to EsModule
This commit is contained in:
Jeremy Yu 2024-12-28 16:35:28 +08:00 committed by GitHub
commit b5b9fe385c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 440 additions and 403 deletions

View File

@ -19,6 +19,7 @@
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/multiparty": "^4.2.1",
"@types/node": "^16.18.105",
"cross-env": "^7.0.3",
"ts-loader": "^6.0.4",
@ -247,6 +248,16 @@
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
"dev": true
},
"node_modules/@types/multiparty": {
"version": "4.2.1",
"resolved": "https://registry.npmmirror.com/@types/multiparty/-/multiparty-4.2.1.tgz",
"integrity": "sha512-Wi6aK3FgvHLvCDxD7ngG4w8MsCK9h64EB53Gvc8t7FVX81tleiz8vFS3ebBohGxqHRzNGHaNwhfdxTGOGAXm6A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "16.18.105",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-16.18.105.tgz",
@ -4007,6 +4018,15 @@
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
"dev": true
},
"@types/multiparty": {
"version": "4.2.1",
"resolved": "https://registry.npmmirror.com/@types/multiparty/-/multiparty-4.2.1.tgz",
"integrity": "sha512-Wi6aK3FgvHLvCDxD7ngG4w8MsCK9h64EB53Gvc8t7FVX81tleiz8vFS3ebBohGxqHRzNGHaNwhfdxTGOGAXm6A==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/node": {
"version": "16.18.105",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-16.18.105.tgz",

View File

@ -27,6 +27,7 @@
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/multiparty": "^4.2.1",
"@types/node": "^16.18.105",
"cross-env": "^7.0.3",
"ts-loader": "^6.0.4",

View File

@ -17,34 +17,34 @@ const serviceComfig = {
/**
*
*/
exports.servicePort = serviceComfig.port
export const servicePort = serviceComfig.port
/**
*
*/
exports.drawLink = isDev ? 'http://127.0.0.1:5173/draw' : serviceComfig.website + '/draw'
export const drawLink = isDev ? 'http://127.0.0.1:5173/draw' : serviceComfig.website + '/draw'
/**
*
*/
exports.filePath = isDev ? process.cwd() + `/static/` : serviceComfig.filePath
export const filePath = isDev ? process.cwd() + `/static/` : serviceComfig.filePath
/**
* chrome浏览器位置
*/
exports.executablePath = isDev ? null : '/opt/google/chrome-unstable/chrome'
export const executablePath = isDev ? null : '/opt/google/chrome-unstable/chrome'
/**
*
*/
exports.maxNum = 2
export const maxNum = 2
/**
*
*/
exports.upperLimit = 20
export const upperLimit = 20
/**
*
*/
exports.releaseTime = 300
export const releaseTime = 300

View File

@ -7,7 +7,7 @@
*/
let path = '/api'
module.exports = {
export default {
SCREENGHOT: path + '/screenshots',
PRINTSCREEN: path + '/printscreen',
// 后端示例

View File

@ -5,12 +5,12 @@
* @LastEditors: ShawnPhang <https://m.palxp.cn>
* @LastEditTime: 2024-08-12 13:40:13
*/
const rExpress = require('express')
const screenshots = require('../service/screenshots.ts')
const fileService = require('../service/files.ts')
const userService = require('../service/user.ts')
const designService = require('../service/design.ts')
const api = require('./api.ts')
import rExpress from 'express'
import screenshots from '../service/screenshots'
import fileService from '../service/files'
import userService from '../service/user'
import designService from '../service/design'
import api from './api'
const rRouter = rExpress.Router()
rRouter.get(api.SCREENGHOT, screenshots.screenshots)
@ -23,4 +23,4 @@ rRouter.get(api.GET_MATERIAL, designService.getMaterial)
rRouter.get(api.GET_PHOTOS, designService.getPhotos)
rRouter.post(api.UPDATE_TEMPLATE, designService.saveTemplate)
module.exports = rRouter
export default rRouter

View File

@ -5,13 +5,13 @@
* @LastEditors: ShawnPhang <https://m.palxp.cn>
* @LastEditTime: 2024-11-14 17:36:17
*/
const express = require('express')
const bodyParser = require('body-parser')
const fs = require('fs')
// const path = require('path')
const router = require('./control/router.ts')
const { filePath, servicePort } = require('./configs.ts')
const handleTimeout = require('./utils/timeout.ts')
import express from 'express'
import bodyParser from 'body-parser'
import fs from 'fs'
import router from './control/router'
import { filePath, servicePort } from './configs'
import handleTimeout from './utils/timeout'
const port = process.env.PORT || servicePort
const app = express()

View File

@ -6,111 +6,120 @@
* @LastEditTime: 2024-08-17 11:22:42
*/
import { Request, Response } from 'express'
const fs = require('fs')
const path = require('path')
const axios = require('../utils/http.ts')
const multiparty = require('multiparty')
const { filePath } = require('../configs.ts')
const { checkCreateFolder, randomCode, send } = require('../utils/tools.ts')
import fs from 'fs'
import path from 'path'
import axios from '../utils/http'
import multiparty from 'multiparty'
import { filePath } from '../configs'
import { checkCreateFolder, randomCode, send } from '../utils/tools'
const FileUrl = 'http://localhost:7001/static/'
module.exports = {
// design/list 获取模板列表(虚拟)
async getTemplates(req: any, res: Response) {
/**
* @api {get} /design/list
* @apiVersion 1.0.0
* @apiGroup design
*/
const { cate, type } = req.query
const tempPath = type == 1 ? `../mock/components/list/${cate}.json` : '../mock/templates/list.json'
try {
const list = fs.readFileSync(path.resolve(__dirname, tempPath), 'utf8')
send.success(res, { list: JSON.parse(list) })
} catch (error) {}
},
// design/temp 获取模板(虚拟)
async getDetail(req: any, res: Response) {
/**
* @api {get} /design/list
* @apiVersion 1.0.0
* @apiGroup design
*/
const { cate, type, id } = req.query
const dPath = type == 1 ? `../mock/components/detail/${id}.json` : `../mock/templates/${id}.json`
try {
const detail = fs.readFileSync(path.resolve(__dirname, dPath), 'utf8')
send.success(res, JSON.parse(detail))
} catch (error) {}
},
// design/material 获取素材(虚拟)
async getMaterial(req: any, res: any) {
/**
* @api {get} /design/material
* @apiVersion 1.0.0
* @apiGroup design
*/
const { cate } = req.query
try {
const detail = fs.readFileSync(path.resolve(__dirname, `../mock/materials/${cate}.json`), 'utf8')
send.success(res, { list: JSON.parse(detail) })
} catch (error) {
console.log(error)
}
},
// design/imgs 获取照片素材(虚拟)
async getPhotos(req: any, res: any) {
/**
* @api {get} /design/imgs
* @apiVersion 1.0.0
* @apiGroup design
*/
const { cate } = req.query
try {
const detail = fs.readFileSync(path.resolve(__dirname, `../mock/materials/photos/${cate}.json`), 'utf8')
send.success(res, { list: JSON.parse(detail) })
} catch (error) {}
},
// design/edit 保存模板(虚拟)
async saveTemplate(req: any, res: any) {
/**
* @api {post} /design/edit
* @apiVersion 1.0.0
* @apiGroup design
*/
let { id, title, data, width, height, type, cate, tag } = req.body
const folder = type == 1 ? 'components/detail' : 'templates'
const listPath = type == 1 ? 'components/list/comp.json' : 'templates/list.json'
try {
const isAdd = !id // 是否新增模板
id = id || randomCode(8)
const savePath = path.resolve(__dirname, `../mock/${folder}/${id}.json`)
const jsonData = {
id,
data,
title,
width,
height,
}
fs.writeFileSync(savePath, JSON.stringify(jsonData))
// 生成封面
const size = width > height ? 640 : 320
const fetchScreenshotUrl = `http://localhost:7001/api/screenshots?tempid=${id}&tempType=${type}&width=${width}&height=${height}&type=cover&size=${size}&quality=75`
await axios.get(fetchScreenshotUrl, { responseType: 'arraybuffer' })
// 保存到其他地方可以设置 responseType: 'arraybuffer' 后操作buffer这里只为了得到封面发起请求就可以了
if (isAdd) {
const listVal = fs.readFileSync(path.resolve(__dirname, `../mock/${listPath}`), 'utf8')
const list = JSON.parse(listVal)
const cover = type == 1 ? FileUrl + `/${id}-screenshot.png` : FileUrl + `/${id}-cover.jpg`
list.unshift({ id, cover, title, width, height })
fs.writeFileSync(path.resolve(__dirname, `../mock/${listPath}`), JSON.stringify(list))
}
send.success(res, { id })
} catch (error) {
console.log(error)
}
},
// design/list 获取模板列表(虚拟)
export async function getTemplates(req: any, res: Response) {
/**
* @api {get} /design/list
* @apiVersion 1.0.0
* @apiGroup design
*/
const { cate, type } = req.query
const tempPath = type == 1 ? `../mock/components/list/${cate}.json` : '../mock/templates/list.json'
try {
const list = fs.readFileSync(path.resolve(__dirname, tempPath), 'utf8')
send.success(res, { list: JSON.parse(list) })
} catch (error) {}
}
export {}
// design/temp 获取模板(虚拟)
export async function getDetail(req: any, res: Response) {
/**
* @api {get} /design/list
* @apiVersion 1.0.0
* @apiGroup design
*/
const { cate, type, id } = req.query
const dPath = type == 1 ? `../mock/components/detail/${id}.json` : `../mock/templates/${id}.json`
try {
const detail = fs.readFileSync(path.resolve(__dirname, dPath), 'utf8')
send.success(res, JSON.parse(detail))
} catch (error) {}
}
// design/material 获取素材(虚拟)
export async function getMaterial(req: any, res: any) {
/**
* @api {get} /design/material
* @apiVersion 1.0.0
* @apiGroup design
*/
const { cate } = req.query
try {
const detail = fs.readFileSync(path.resolve(__dirname, `../mock/materials/${cate}.json`), 'utf8')
send.success(res, { list: JSON.parse(detail) })
} catch (error) {
console.log(error)
}
}
// design/imgs 获取照片素材(虚拟)
export async function getPhotos(req: any, res: any) {
/**
* @api {get} /design/imgs
* @apiVersion 1.0.0
* @apiGroup design
*/
const { cate } = req.query
try {
const detail = fs.readFileSync(path.resolve(__dirname, `../mock/materials/photos/${cate}.json`), 'utf8')
send.success(res, { list: JSON.parse(detail) })
} catch (error) {}
}
// design/edit 保存模板(虚拟)
export async function saveTemplate(req: any, res: any) {
/**
* @api {post} /design/edit
* @apiVersion 1.0.0
* @apiGroup design
*/
let { id, title, data, width, height, type, cate, tag } = req.body
const folder = type == 1 ? 'components/detail' : 'templates'
const listPath = type == 1 ? 'components/list/comp.json' : 'templates/list.json'
try {
const isAdd = !id // 是否新增模板
id = id || randomCode(8)
const savePath = path.resolve(__dirname, `../mock/${folder}/${id}.json`)
const jsonData = {
id,
data,
title,
width,
height,
}
fs.writeFileSync(savePath, JSON.stringify(jsonData))
// 生成封面
const size = width > height ? 640 : 320
const fetchScreenshotUrl = `http://localhost:7001/api/screenshots?tempid=${id}&tempType=${type}&width=${width}&height=${height}&type=cover&size=${size}&quality=75`
await axios.get(fetchScreenshotUrl, { responseType: 'arraybuffer' })
// 保存到其他地方可以设置 responseType: 'arraybuffer' 后操作buffer这里只为了得到封面发起请求就可以了
if (isAdd) {
const listVal = fs.readFileSync(path.resolve(__dirname, `../mock/${listPath}`), 'utf8')
const list = JSON.parse(listVal)
const cover = type == 1 ? FileUrl + `/${id}-screenshot.png` : FileUrl + `/${id}-cover.jpg`
list.unshift({ id, cover, title, width, height })
fs.writeFileSync(path.resolve(__dirname, `../mock/${listPath}`), JSON.stringify(list))
}
send.success(res, { id })
} catch (error) {
console.log(error)
}
}
export default {
getTemplates,
getDetail,
getMaterial,
getPhotos,
saveTemplate
}

View File

@ -12,49 +12,48 @@ const { checkCreateFolder, randomCode, copyFile, send } = require('../utils/tool
const FileUrl = 'http://localhost:7001/static/'
module.exports = {
// api/file/upload 上传接口
async upload(req: Request, res: Response) {
/**
* @api {post} /api/file/upload
* @apiVersion 1.0.0
* @apiGroup file
*
* @apiParam {File} file
* @apiParam {String} folder
* @apiParam {String} name
*
* @apiSuccess (__组__) {__类型__} __字段名__ __返回字段说明__
*/
const form = new multiparty.Form()
form.parse(req, async function (err: any, fields: any, files: any) {
if (err) {
console.error('上传文件出错!')
return
}
if (files) {
const file = files.file ? files.file[0] : {}
const { size, headers, originalFilename } = file
const fileType = headers['content-type'].split('/')[1]
const Suffix = originalFilename.split('.').pop() || fileType || 'png'
const { folder = '', name = `${randomCode(12)}.${Suffix}` } = fields
const folderPath = `${filePath}${folder ? `${folder}/` : ''}`
checkCreateFolder(folderPath) // 检测对应目录是否存在
const targetPath = `${folderPath}${name}`
copyFile(file.path, targetPath)
.then(() => {
const url = `${FileUrl}${folder ? folder + '/' : ''}${name}`
send.success(res, {
key: `${folder}/${name}`,
url,
})
// api/file/upload 上传接口
export async function upload(req: Request, res: Response) {
/**
* @api {post} /api/file/upload
* @apiVersion 1.0.0
* @apiGroup file
*
* @apiParam {File} file
* @apiParam {String} folder
* @apiParam {String} name
*
* @apiSuccess (__组__) {__类型__} __字段名__ __返回字段说明__
*/
const form = new multiparty.Form()
form.parse(req, async function (err: any, fields: any, files: any) {
if (err) {
console.error('上传文件出错!')
return
}
if (files) {
const file = files.file ? files.file[0] : {}
const { size, headers, originalFilename } = file
const fileType = headers['content-type'].split('/')[1]
const Suffix = originalFilename.split('.').pop() || fileType || 'png'
const { folder = '', name = `${randomCode(12)}.${Suffix}` } = fields
const folderPath = `${filePath}${folder ? `${folder}/` : ''}`
checkCreateFolder(folderPath) // 检测对应目录是否存在
const targetPath = `${folderPath}${name}`
copyFile(file.path, targetPath)
.then(() => {
const url = `${FileUrl}${folder ? folder + '/' : ''}${name}`
send.success(res, {
key: `${folder}/${name}`,
url,
})
.catch((err: any) => {
console.log('上传异常', err)
})
}
})
},
})
.catch((err: any) => {
console.log('上传异常', err)
})
}
})
}
export {}
export default { upload }

View File

@ -5,106 +5,105 @@
* @LastEditors: ShawnPhang <https://m.palxp.cn>
* @LastEditTime: 2024-08-17 11:23:58
*/
const { saveScreenshot } = require('../utils/download-single.ts')
const uuid = require('../utils/uuid.ts')
const { filePath, upperLimit, drawLink } = require('../configs.ts')
const { queueRun, queueList } = require('../utils/node-queue.ts')
import { saveScreenshot } from '../utils/download-single'
import uuid from '../utils/uuid'
import { filePath, upperLimit, drawLink } from '../configs'
import { queueRun, queueList } from '../utils/node-queue'
// const path = require('path')
const fs = require('fs')
module.exports = {
async screenshots(req: any, res: any) {
/**
* @api {get} api/screenshots
* @apiVersion 1.0.0
* @apiGroup screenShot
*
* @apiParam {String|Number} id () id
* @apiParam {String|Number} tempid () idid时取该值
* @apiParam {String|Number} tempType ()
* @apiParam {String} width ()
* @apiParam {String} height ()
* @apiParam {String} screenshot_url
* @apiParam {String} type , file正常截图返回cover封面生成file
* @apiParam {String} size ,
* @apiParam {String} quality ,
* @apiParam {String|Number} index ,
*/
let { id, tempid, tempType, width, height, screenshot_url, type = 'file', size, quality, index = 0 } = req.query
id == 'undefined' && (id = null)
const url = (screenshot_url || drawLink) + `${id ? '?id=' : '?tempid='}`
id = id || tempid
const path = filePath + `${id}-screenshot.png`
const thumbPath = type === 'cover' && tempType != 1 ? filePath + `${id}-cover.jpg` : null
/**
* @api {get} api/screenshots
* @apiVersion 1.0.0
* @apiGroup screenShot
*
* @apiParam {String|Number} id () id
* @apiParam {String|Number} tempid () idid时取该值
* @apiParam {String|Number} tempType ()
* @apiParam {String} width ()
* @apiParam {String} height ()
* @apiParam {String} screenshot_url
* @apiParam {String} type , file正常截图返回cover封面生成file
* @apiParam {String} size ,
* @apiParam {String} quality ,
* @apiParam {String|Number} index ,
*/
export async function screenshots(req: any, res: any) {
let { id, tempid, tempType, width, height, screenshot_url, type = 'file', size, quality, index = 0 } = req.query
id == 'undefined' && (id = null)
const url = (screenshot_url || drawLink) + `${id ? '?id=' : '?tempid='}`
id = id || tempid
const path = filePath + `${id}-screenshot.png`
const thumbPath = type === 'cover' && tempType != 1 ? filePath + `${id}-cover.jpg` : null
if (id && width && height) {
if (queueList.length > upperLimit) {
res.json({ code: 200, msg: '服务器表示顶不住啊,等等再来吧~' })
return
}
const targetUrl = url + id + `${tempType ? '&tempType=' + tempType : ''}` + `&index=${index}`
queueRun(saveScreenshot, targetUrl, { width, height, path, thumbPath, size, quality })
.then(() => {
res.setHeader('Content-Type', 'image/jpg')
// const stats = fs.statSync(path)
// res.setHeader('Cache-Control', stats.size)
type === 'file' ? res.sendFile(path) : res.sendFile(thumbPath)
})
.catch((e: any) => {
res.json({ code: 500, msg: '图片生成错误' })
})
} else {
res.json({ code: 500, msg: '缺少参数,请检查' })
if (id && width && height) {
if (queueList.length > upperLimit) {
res.json({ code: 200, msg: '服务器表示顶不住啊,等等再来吧~' })
return
}
},
async printscreen(req: any, res: any) {
/**
* @api {get} api/printscreen
* @apiVersion 1.0.0
* @apiGroup screenShot
*
* @apiParam {String} url () link
* @apiParam {String} width ()
* @apiParam {String} height ()
* @apiParam {Boolean} prevent (, false) true: 使
* @apiParam {String} type (, file) file: 返回二进制文件cover: 立即返回地址(path, thumbPath)
* @apiParam {String} size (type=cover生效, eg:300300jpeg
* @apiParam {String} quality (size生效, eg:75)压缩质量:1-100
* @apiParam {Number} wait () ms
* @apiParam {String} ua () eg: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1'
* @apiParam {String} devices () uawidthheight均会失效eg: iPhone 6 /src/utils/widget/Device.js
* @apiParam {Number} scale () (DPR) 1~41
*/
let { width = 375, height = 0, url, type = 'file', size, quality, prevent = false, ua, devices, scale, wait } = req.query
const path = filePath + `screenshot_${new Date().getTime()}_${uuid()}.png`
const thumbPath = type === 'cover' ? path.replace('.png', '.jpg') : null
if (url) {
const sign = `${new Date().getTime()}_${uuid(8)}`
req._queueSign = sign
// console.log(url + id, path, thumbPath);
if (queueList.length > upperLimit) {
res.json({ code: 200, msg: '业务繁忙,等等再来吧~' })
return
}
queueRun(saveScreenshot, url, { width, height, path, thumbPath, size, quality, prevent, ua, devices, scale, wait }, sign)
.then(() => {
if (!res.headersSent) {
// res.setHeader('Content-Type', 'image/jpg')
// const stats = fs.statSync(path)
// res.setHeader('Cache-Control', stats.size)
res.json({ code: 200, msg: '截图成功', data: { path, thumbPath } })
} else {
res.json({ code: 200, msg: 'ok' })
}
})
.catch((e: any) => {
res.json({ code: 500, msg: '图片生成错误!' })
})
} else {
res.json({ code: 500, msg: '缺少参数,请检查' })
}
},
const targetUrl = url + id + `${tempType ? '&tempType=' + tempType : ''}` + `&index=${index}`
queueRun(saveScreenshot, targetUrl, { width, height, path, thumbPath, size, quality })
.then(() => {
res.setHeader('Content-Type', 'image/jpg')
// const stats = fs.statSync(path)
// res.setHeader('Cache-Control', stats.size)
type === 'file' ? res.sendFile(path) : res.sendFile(thumbPath)
})
.catch((e: any) => {
res.json({ code: 500, msg: '图片生成错误' })
})
} else {
res.json({ code: 500, msg: '缺少参数,请检查' })
}
}
export {}
/**
* @api {get} api/printscreen
* @apiVersion 1.0.0
* @apiGroup screenShot
*
* @apiParam {String} url () link
* @apiParam {String} width ()
* @apiParam {String} height ()
* @apiParam {Boolean} prevent (, false) true: 使
* @apiParam {String} type (, file) file: 返回二进制文件cover: 立即返回地址(path, thumbPath)
* @apiParam {String} size (type=cover生效, eg:300300jpeg
* @apiParam {String} quality (size生效, eg:75)压缩质量:1-100
* @apiParam {Number} wait () ms
* @apiParam {String} ua () eg: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1'
* @apiParam {String} devices () uawidthheight均会失效eg: iPhone 6 /src/utils/widget/Device.js
* @apiParam {Number} scale () (DPR) 1~41
*/
export async function printscreen(req: any, res: any) {
let { width = 375, height = 0, url, type = 'file', size, quality, prevent = false, ua, devices, scale, wait } = req.query
const path = filePath + `screenshot_${new Date().getTime()}_${uuid()}.png`
const thumbPath = type === 'cover' ? path.replace('.png', '.jpg') : null
if (url) {
const sign = `${new Date().getTime()}_${uuid()}`
req._queueSign = sign
// console.log(url + id, path, thumbPath);
if (queueList.length > upperLimit) {
res.json({ code: 200, msg: '业务繁忙,等等再来吧~' })
return
}
queueRun(saveScreenshot, url, { width, height, path, thumbPath, size, quality, prevent, ua, devices, scale, wait }, sign)
.then(() => {
if (!res.headersSent) {
// res.setHeader('Content-Type', 'image/jpg')
// const stats = fs.statSync(path)
// res.setHeader('Cache-Control', stats.size)
res.json({ code: 200, msg: '截图成功', data: { path, thumbPath } })
} else {
res.json({ code: 200, msg: 'ok' })
}
})
.catch((e: any) => {
res.json({ code: 500, msg: '图片生成错误!' })
})
} else {
res.json({ code: 500, msg: '缺少参数,请检查' })
}
}
export default { printscreen, screenshots }

View File

@ -12,7 +12,7 @@ const { checkCreateFolder, filesReader, send } = require('../utils/tools.ts')
const FileUrl = 'http://localhost:7001/static/'
module.exports = {
export default {
// design/user/image 获取用户上传列表(虚拟)
async getUserImages(req: Request, res: Response) {
/**
@ -24,5 +24,3 @@ module.exports = {
send.success(res, { list })
},
}
export {}

View File

@ -15,7 +15,7 @@ const forceTimeOut = 60 // 强制超时时间,单位:秒
const maxPXs = 4211840 // 超出此规格会触发限制器降低dpr节省服务器资源
const maximum = 5000 // 最大宽高限制,超过截断以防止服务崩溃
const saveScreenshot = async (url: string, { path, width, height, thumbPath, size = 0, quality = 0, prevent, ua, devices, scale, wait }: any) => {
export const saveScreenshot = async (url: string, { path, width, height, thumbPath, size = 0, quality = 0, prevent, ua, devices, scale, wait }: any) => {
return new Promise(async (resolve: Function, reject: Function) => {
let isPageLoad = false
let browser: any = null
@ -154,6 +154,5 @@ const saveScreenshot = async (url: string, { path, width, height, thumbPath, siz
})
}
module.exports = { saveScreenshot }
export default { saveScreenshot }
export {}

View File

@ -13,7 +13,7 @@ const forceTimeOut = 60 // 强制超时时间,单位:秒
let browser: typeof puppeteer = null
let release: any = null
const saveScreenshot = async (url: string, { path, width, height, thumbPath, size = 0, quality = 0, prevent, ua, devices, scale, wait }: any) => {
export const saveScreenshot = async (url: string, { path, width, height, thumbPath, size = 0, quality = 0, prevent, ua, devices, scale, wait }: any) => {
return new Promise(async (resolve: Function) => {
// 启动浏览器
if (!browser) {
@ -123,6 +123,4 @@ async function autoScroll(page: any) {
})
}
module.exports = { saveScreenshot }
export {}
export default { saveScreenshot }

View File

@ -6,73 +6,77 @@
* @LastEditTime: 2024-08-12 06:29:58
*/
import fs from 'fs'
const path = require('path')
const imageSize = require('image-size')
const { filePath: StaticPath } = require('../configs.ts')
import path from 'path'
import imageSize from 'image-size'
import { filePath as StaticPath } from '../configs'
const FileUrl = 'http://localhost:7001/static/'
module.exports = {
copyFile(sourceFile: string, destinationFile: string): Promise<void> {
return new Promise((resolve, reject) => {
const readStream = fs.createReadStream(sourceFile)
const writeStream = fs.createWriteStream(destinationFile)
export function copyFile(sourceFile: string, destinationFile: string): Promise<void> {
return new Promise((resolve, reject) => {
const readStream = fs.createReadStream(sourceFile)
const writeStream = fs.createWriteStream(destinationFile)
readStream.on('error', (err: any) => {
reject(err)
})
writeStream.on('error', (err: any) => {
reject(err)
})
writeStream.on('finish', () => {
resolve()
})
readStream.pipe(writeStream)
readStream.on('error', (err: any) => {
reject(err)
})
},
// 读取目录
filesReader(directoryPath: string) {
return new Promise((resolve) => {
try {
const files = fs.readdirSync(StaticPath + directoryPath)
const filesArray: any = []
files.forEach((file) => {
const filePath = path.join(directoryPath, file)
// const stats = fs.statSync(filePath);
const { width, height } = imageSize(StaticPath + filePath)
if (file !== '.DS_Store') {
const fileInfo = {
width,
height,
// filename: file,
// link: FileUrl + directoryPath,
url: `${FileUrl + directoryPath}/${file}`,
// filepath: StaticPath + filePath
// size: stats.size, // 文件大小
// modified: stats.mtime // 最后修改时间
}
filesArray.push(fileInfo)
}
})
// JSON.stringify(filesArray, null, 2)
resolve(filesArray)
} catch (err) {
console.error('Error reading directory:', err)
}
writeStream.on('error', (err: any) => {
reject(err)
})
},
// 读取文件
readFile(directoryPath: string) {
return new Promise((resolve) => {
try {
resolve(fs.readFileSync(StaticPath + directoryPath, 'utf8'))
} catch (err) {
console.error('Error reading file:', err)
}
writeStream.on('finish', () => {
resolve()
})
},
readStream.pipe(writeStream)
})
}
export {}
// 读取目录
export function filesReader(directoryPath: string) {
return new Promise((resolve) => {
try {
const files = fs.readdirSync(StaticPath + directoryPath)
const filesArray: any = []
files.forEach((file) => {
const filePath = path.join(directoryPath, file)
// const stats = fs.statSync(filePath);
const { width, height } = imageSize(StaticPath + filePath)
if (file !== '.DS_Store') {
const fileInfo = {
width,
height,
// filename: file,
// link: FileUrl + directoryPath,
url: `${FileUrl + directoryPath}/${file}`,
// filepath: StaticPath + filePath
// size: stats.size, // 文件大小
// modified: stats.mtime // 最后修改时间
}
filesArray.push(fileInfo)
}
})
// JSON.stringify(filesArray, null, 2)
resolve(filesArray)
} catch (err) {
console.error('Error reading directory:', err)
}
})
}
// 读取文件
export function readFile(directoryPath: string) {
return new Promise((resolve) => {
try {
resolve(fs.readFileSync(StaticPath + directoryPath, 'utf8'))
} catch (err) {
console.error('Error reading file:', err)
}
})
}
export default {
copyFile,
filesReader,
readFile,
}

View File

@ -5,7 +5,7 @@
* @LastEditors: ShawnPhang <https://m.palxp.cn>
* @LastEditTime: 2024-08-12 13:59:34
*/
const axios = require('axios')
import axios from 'axios'
const httpRequest = axios.create({
maxContentLength: Infinity,
@ -16,4 +16,4 @@ httpRequest.interceptors.response.use((config: any) => {
return config.data
})
module.exports = httpRequest
export default httpRequest

View File

@ -10,7 +10,7 @@ interface Queue {
sign?: string | number
}
const { maxNum } = require('../configs.ts')
import { maxNum } from '../configs'
const queueList: any = [] // 任务队列
let curNum = 0 // 当前执行的任务数
@ -38,4 +38,4 @@ function run(Fn: Function) {
})
}
module.exports = { queueRun, queueList }
export { queueRun, queueList }

View File

@ -6,7 +6,7 @@
* @LastEditTime: 2023-07-05 20:17:00
*/
module.exports = async (req: any, res: any, next: any) => {
export default async (req: any, res: any, next: any) => {
const { queueList } = require('../utils/node-queue.ts')
const time = 30000 // 设置所有HTTP请求的服务器响应超时时间
res.setTimeout(time, () => {

View File

@ -5,71 +5,76 @@
* @LastEditors: ShawnPhang <https://m.palxp.cn>
* @LastEditTime: 2024-08-12 13:48:40
*/
const fs = require('fs')
const path = require('path')
const fsFunc = require('./fs.ts')
import fs from 'fs'
import path from 'path'
import { filesReader, copyFile, readFile } from './fs'
module.exports = {
send: {
success: (res: any, result: any, msg: string = 'ok') => {
res.json({
code: 200,
msg,
result: result || undefined,
})
},
error: (res: any, msg: string = 'error') => {
res.json({
code: 400,
msg,
})
},
export const send = {
success: (res: any, result: any, msg: string = 'ok') => {
res.json({
code: 200,
msg,
result: result || undefined,
})
},
isNumber: (value: any) => {
return typeof value === 'number' && !isNaN(value)
error: (res: any, msg: string = 'error') => {
res.json({
code: 400,
msg,
})
},
buildTree: (data: any[]) => {},
groupBy: (array: any[], property: any) => {},
// 检测目录并创建目录(支持深层级)
checkCreateFolder: (folder: string) => {
try {
const pathArr = splitPath(folder)
let _path = ''
for (let i = 0; i < pathArr.length; i++) {
if (pathArr[i]) {
_path += `/${pathArr[i]}`
!fs.existsSync(_path) && fs.mkdirSync(_path)
}
}
export const isNumber = (value: any) => {
return typeof value === 'number' && !isNaN(value)
}
export const buildTree = (data: any[]) => {}
export const groupBy = (array: any[], property: any) => {}
// 检测目录并创建目录(支持深层级)
export const checkCreateFolder = (folder: string) => {
try {
const pathArr = splitPath(folder)
let _path = ''
for (let i = 0; i < pathArr.length; i++) {
if (pathArr[i]) {
_path += `/${pathArr[i]}`
!fs.existsSync(_path) && fs.mkdirSync(_path)
}
} catch (e) {}
},
// 检测文件
checkCreateFile: (filePath: string) => {
try {
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, '')
}
} catch (e) {
}
} catch (e) {}
}
// 检测文件
export const checkCreateFile = (filePath: string) => {
try {
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, '')
}
},
// 生成随机码
randomCode: (length = 5) => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
let result = ''
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * chars.length)
result += chars[randomIndex]
}
return result
},
// 取数组差集
findDifference: (a: any, b: any) => {
return a.concat(b).filter((v: any) => !a.includes(v) || !b.includes(v))
},
...fsFunc,
} catch (e) {
fs.writeFileSync(filePath, '')
}
}
// 生成随机码
export const randomCode = (length = 5) => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
let result = ''
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * chars.length)
result += chars[randomIndex]
}
return result
}
// 取数组差集
export const findDifference = (a: any, b: any) => {
return a.concat(b).filter((v: any) => !a.includes(v) || !b.includes(v))
}
export { copyFile, readFile, filesReader }
/**
*
* @param dirPath
@ -81,4 +86,3 @@ function splitPath(dirPath: string) {
return normalizedPath.split(separator)
}
export {}

View File

@ -7,9 +7,9 @@
* @Description: ,`customMade`, koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
const nodeCrypto = require('crypto');
import nodeCrypto from 'crypto';
module.exports = () =>
export default () =>
// @ts-ignore
([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c: number) =>
(c ^ (nodeCrypto.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16)

View File

@ -3,7 +3,7 @@
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "ESNEXT", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"module": "ESNext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": ["dom", "es2015"], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */

View File

@ -39,6 +39,12 @@ module.exports = {
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'], // 解析的文件类型
alias: {
'@': path.resolve(__dirname, 'src') // 配置路径别名,指向 src 目录
}
},
// plugins: [new BundleAnalyzerPlugin()],
plugins: [ new buildPlugin() ]
}