自己做个UniCloud,自定义 uni-cloud-customize发布npm了,uniCloud如何使用本地数据库

独创敢说全网唯一,自己做个uniCloud, 本地部署uniCloud項目,摆脱官方限制

独创自己做个uniCloud本地部署uniCloud項目

插叙

- 开发动机
    由于之前做了个gpt AI的项目使用的unicloud,中途调试过程中由于出现死循环,没有任何提示的情况下第二天多扣费近百元的损失,因此想要改造成可以使用本地服务,特此做出了本项目

项目简介

- unicloud如何使用本地数据库?
- 参考项目:https://github.com/caohongshan/psyche-back

解决问题核心思路

其实问题没那么复杂,unicloude云函数无非就是node的函数运行到了远程,那么如何把云端的运行到本地不就可以了吗,核心就是这么简单

设计

说难点事=是自己造个unicloud,简单点就是自己用node搭个服务,然后重写下uniCloud的一些方法不就搞定了吗?

如何实现?

简单,咱们node搭个服务,重写unicloude方法,然后挂载全局,不清楚是不是讲的够粗暴直白?

代码上手

光说不练等于笨蛋,直接上代码
db.js
const { MongoClient } = require('mongodb');
const mongodbUrl = 'mongodb://x.x.x.x:27017/psychic';
let client;

async function dbConnect() {
  if (!client) {
    client = await MongoClient.connect(mongodbUrl, { useNewUrlParser: true, useUnifiedTopology: true });  
  }

  // 在事务中执行操作
  const session = client.startSession();

  return {
    collection: name => client.db().collection(name),
    command: async cmdObj => await client.db().command(cmdObj),
    startTransaction: async () => await session.startTransaction()
  };
}

module.exports = dbConnect;

使用代码

'use strict';

const http = require('http');
const fs = require('fs');
const path = require('path');
const formidable = require('formidable');
const dbConnect = require('./db');

function handleRequestBody(req, callback) {
  let body = '';
  if (req.method === 'POST') {
    req.on('data', chunk => {
      body += chunk.toString();
    });
    req.on('end', () => {
      const data = body ? JSON.parse(body) : {};
      callback(data);
    });
  } else {
    callback(null);
  }
}

function handleGetRequest(req, res) {
  const filePath = getFileFromRequest(req.url);
  if (filePath) {
    const extname = path.extname(filePath);
    const contentType = getContentType(extname);
    if (contentType) {
      res.setHeader('Content-Type', contentType);
      fs.readFile(filePath, function (err, data) {
        if (err) {
          res.statusCode = 404;       
          res.end('File not found');
        } else {
          res.statusCode = 200;
          res.end(data);
        }
      });
    } else {
      res.statusCode = 400;
      res.end('Invalid Content-Type');
    }
  } else {
    res.statusCode = 404;
    res.end('Not found');
  }
}

function handlePostRequest(req, res) {
  const form = new formidable.IncomingForm();
  form.parse(req, (err, fields, files) => {
    if (err) {
      res.statusCode = 500;
      res.end(JSON.stringify({
        error: 'Internal Server Error',
      }));
      return;
    }

    // 获取上传的图片文件对象
    const imageFile =  files.file;

    // 设置上传的图片文件路径
    const uploadPath = `./static/${Date.now()}-${imageFile.originalFilename}`;

    // 读取上传的图片文件并保存到指定目录
    const readStream = fs.createReadStream(imageFile.filepath);
    const writeStream = fs.createWriteStream(uploadPath);
    readStream.pipe(writeStream);

    // 上传图片文件成功后返回一个 JSON 数据
    res.setHeader("Content-Type", "application/json")
    res.setHeader("Access-Control-Allow-Headers", "Content-Type") 
    res.statusCode = 200;
    res.end(uploadPath.replace(/.*\//, ''));
  });
}

function getContentType(extname) {
  switch (extname) {
    case '.jpg':
      return 'image/jpg';
    case '.jpeg':
      return 'image/jpeg';
    case '.png':
      return 'image/png';
    default:
      return null;
  }
}

function getFileFromRequest(url) {
  const fileName = path.basename(url);
  if (fileName.indexOf('.') !== -1) {
    return path.join(__dirname + '\\static', fileName);
  } else {
    return null;
  }
}

(async () => {
  global.db = await dbConnect();
  const { Router } = require('./common/uni-cloud-router')
  const router = new Router(require('./config.js'))

  // 将处理请求体数据的代码放在一个函数中
  function requestListener(req, res) {
    res.setHeader("Access-Control-Allow-Origin", "*");
    if (req.method === 'POST' && req.url === '/upload') { 
      handlePostRequest(req, res);
    } else if(req.method === 'GET' && req.url.startsWith('/image/')) {
      handleGetRequest(req, res);
    } else {
      // 在函数handleRequestBody中处理请求体数据
      handleRequestBody(req, (data) => {
        // 设置响应头部信息,允许跨域访问
        router.serve({
          path: req.url,
          httpMethod: req.method,
          headers: {},
          data, // 直接传递解析出的JSON对象 
        }).then(result => { 
          res.setHeader("Content-Type", "application/json")
          res.setHeader("Access-Control-Allow-Headers", "Content-Type") 
          res.end(result.body)
        })
      })
    }
  }

  // 创建 HTTP 服务器
  const server = http.createServer(requestListener);
  server.listen(5000, () => console.log('Server started on port 5000'))

})()

本项目已发布npm包

可npm i uni-cloud-customize使用
npm包地址:https://www.npmjs.com/package/uni-cloud-customize

愿景

- 希望大家可以一起维护项目

商务合作及其它疑问请联系:

微信:itbang6
QQ: 3161838135

QQ技术交流群:133766030

如何本文对您有帮助,请支持一下,你的支持是我最大的动力!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT帮

你的鼓励是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值