Browse Source

add:
1. 构建服务端基础代码
2. 添加产品相关接口

kindring 2 years ago
parent
commit
1f8ad1c71a

+ 0 - 25
package_back.json

@@ -1,25 +0,0 @@
-{
-  "name": "szhfy-wabsite",
-  "version": "1.0.0",
-  "private": true,
-  "scripts": {
-    "dev": "nuxt",
-    "build": "nuxt build",
-    "start": "nuxt start",
-    "generate": "nuxt generate"
-  },
-  "dependencies": {
-    "@nuxtjs/axios": "^5.12.2",
-    "ant-design-vue": "^1.6.5",
-    "core-js": "^3.6.5",
-    "express": "^4.17.1",
-    "net-ping": "^1.2.3",
-    "nuxt": "^2.14.6",
-    "pdfjs-dist": "^2.5.207",
-    "vue-pdf": "4.2"
-  },
-  "devDependencies": {
-    "@nuxtjs/tailwindcss": "^3.4.2",
-    "svg-sprite-loader": "^6.0.11"
-  }
-}

+ 8 - 0
server/configs/database.json.json

@@ -0,0 +1,8 @@
+{
+  "host": "154.23.140.251",
+  "port": "3306",
+  "user": "hostf26a75fef",
+  "password": "WCUhYmuIjV",
+  "connectionLimit": "100",
+  "database": "mysql85931094_db"
+}

+ 51 - 0
server/control/product.js

@@ -0,0 +1,51 @@
+const {handle} = require('../util/handle');
+const {loadProducts} = require('../database/d_product');
+
+/**
+ * 加载产品
+ * @param key 产品类别
+ * @param p 页码
+ * @param l 每页数量
+ * @returns {Promise<*[]>} [err,res]
+ */
+async function loadProduct(key,p,l)
+{
+  p = p || 1;
+  l = l || 10;
+  let offset = (p - 1) * l;
+  let [err,res] = await handle(loadProducts(key, offset, l));
+  if(err){
+    return [err,null];
+  }
+  return [null,res];
+}
+
+/**
+ * 获取产品信息
+ * @param id 产品id
+ * @returns {Promise<*[]>}
+ */
+async function getProductInfo(id)
+{
+  let [err,res] = await handle(getProductInfo(id));
+  if(err){
+    return [err,null];
+  }
+  return [null,res];
+}
+
+async function searchProduct(type, key, p, l)
+{
+  p = p || 1;
+  l = l || 10;
+  let offset = (p - 1) * l;
+
+}
+
+
+
+module.exports = {
+  loadProduct,
+  getProductInfo,
+  searchProduct
+};

+ 34 - 0
server/database/d_product.js

@@ -0,0 +1,34 @@
+const mysql = require('./mysql');
+
+function loadProducts(key, offset, limit) {
+  let sql = ``;
+  let values = [];
+  sql += `SELECT
+            p.proid as id,p.remark,p.name,p.image,p.source,p.sourceType
+          FROM
+            hfy_product as p ,
+            hfy_product_type as p_type
+          WHERE
+            p.type_id = p_type.type_id
+            and p_type.type_key = ? limit ?,?`;
+  values = [key, offset, limit];
+  return mysql.pq(sql, values);
+}
+
+function getProductInfo(id) {
+  let sql = ``;
+  let values = [];
+  sql += `SELECT
+              p.*
+          FROM
+            hfy_product as p
+          WHERE
+            p.proid = ?`;
+  values = [id];
+  return mysql.pq(sql, values);
+}
+
+module.exports = {
+  loadProducts,
+  getProductInfo
+}

+ 51 - 0
server/database/mysql.js

@@ -0,0 +1,51 @@
+/*
+ * @Description: 操作mysql相关的工具函数
+ * @Autor: kindring
+ * @Date: 2021-12-14 15:34:59
+ * @LastEditors: kindring
+ * @LastEditTime: 2022-01-25 18:29:18
+ * @LastDescript: 
+ */
+const pool = require('./pool');
+const log = require('../logger').logger('database')
+
+/**
+ * callback方式查询数据库
+ * @param {*} sql 
+ * @param {*} values 
+ * @param {*} cb 
+ */
+function query(sql, values, cb) {
+    pool.getConnection((err, conn) => {
+        if (err) { log.error(err.message); return cb(err) }
+        log.debug(`querySQL:${sql}  QueryValues:[${values.join(',')}]`)
+        conn.query(sql, values, cb);
+        conn.release();
+    })
+} //简写部分代码
+
+/**
+ * 以promise方式查询数据库
+ * @param {*} sql 
+ * @param {*} values 
+ * @returns 
+ */
+function pq(sql, values = []) {
+    return new Promise((resolve, reject) => {
+        query(sql, values, function(err, result) {
+            if (err) {
+                // 自动通过日志记录数据库查询错误的部分
+                log.info(`sql: ${sql} \nvalues: ${values.join(',')}`)
+                log.error(`Error ${err.message}`);
+                reject(err);
+                return
+            }
+            resolve(result);
+        });
+    })
+}
+
+module.exports = {
+    query,
+    pq
+}

+ 24 - 0
server/database/pool.js

@@ -0,0 +1,24 @@
+/*
+ * @Description: 全局mysql连接
+ * @Autor: kindring
+ * @Date: 2021-12-14 11:12:13
+ * @LastEditors: kindring
+ * @LastEditTime: 2021-12-15 14:34:31
+ * @LastDescript:
+ */
+const mysql = require('mysql2');
+const databseConfig = require('../configs/database.json.json'); //数据库连接的配置文件
+//作用
+
+//导出全局连接池对象,使其可以统一使用此连接池操作数据库
+const pool = mysql.createPool({
+    connectionLimit: databseConfig.connectionLimit || 100, //连接限制
+    host: databseConfig.host, //地址
+    user: databseConfig.user, //用户
+    password: databseConfig.password, // 密码
+    database: databseConfig.database // 数据库名称
+}); // 创建连接池对象
+
+
+
+module.exports = pool;

+ 0 - 2
server/index.js

@@ -1,12 +1,10 @@
 const express = require('express');
 
-const { router } = require('./router/index');
 const { router: r_product } = require('./router/r_product');
 console.log(router);
 const app = express();
 
 
-app.use(router);
 app.use(r_product);
 
 app.get('/hello', (req, res) => {

+ 39 - 0
server/map/rcodeMap.js

@@ -0,0 +1,39 @@
+// define("NotMATCH", 0);
+// // 请求正常
+// define("OK", 1);
+// // 缺少参数
+// define("NotParam", 2);
+// // 没有登录
+// define("NotLogin", 3);
+// // 鉴权失败,没有权限, 不同场景不同提示内容 在登录页面账号显示封禁
+// define("NotPermission", 4);
+// // 自定义错误信息,用于前端直接显示的信息
+// define("CustomError", 5);
+// // 服务器内部逻辑错误
+// define("ServerError", 6);
+// // 服务器操作超时
+// define("Timeout", 7);
+// // 无法找到记录,可用于账号密码错误等场景的自动化提示
+// define("NotFound", 8);
+// // 二次访问接口异常
+// define("ApiError", 9);
+// // 存储异常
+// define("SaveError", 10);
+// // 数据重复,在某些新增的场景表示该数据已经重复
+// define("DataRepeat", 11);
+
+const rCode = {
+  NotMATCH: 0,
+  OK: 1,
+  NotParam: 2,
+  NotLogin: 3,
+  NotPermission: 4,
+  CustomError: 5,
+  ServerError: 6,
+  Timeout: 7,
+  NotFound: 8,
+  ApiError: 9,
+  SaveError: 10,
+  DataRepeat: 11,
+}
+module.exports = rCode;

+ 66 - 0
server/router/r_product.js

@@ -1,3 +1,69 @@
+const {paramFail, ServerError, success, controlError, searchSuccess} = require("~/server/tools/result");
 const router = require('express').Router();
+const c = require('~/server/control/product');
+
+/**
+ * 获取产品信息
+ * @param id path 产品id
+ */
+router.get('/product/:id', async (req, res) => {
+  try{
+    let err, result;
+    let {id} = req.params;
+    if(!id){
+      paramFail(res, "id is required");
+      return;
+    }
+    [err, result] = await c.getProductInfo(id);
+    if(err){ return controlError(res, err, null);}
+    success(res, result);
+  }catch (e) {
+    ServerError(res, null, e.message);
+  }
+});
+
+/**
+ * 加载产品列表,根据类型
+ * @param key query 产品类别
+ * @param p query 页码
+ * @param l query 每页数量
+ */
+router.get('/products',
+  async (req, res) => {
+    try{
+      let err, result;
+      let {key, l, p} = req.query;
+      if(!key){
+        paramFail(res, "key is required");
+        return;
+      }
+      [err, result] = await c.loadProduct(key, p, l);
+      if(err){ return controlError(res, err, null);}
+      success(res, result);
+    }catch (e) {
+      ServerError(res, null, e.message);
+    }
+});
+
+router.get(
+  '/products/search',
+  async (req, res) => {
+      try{
+        let err, result;
+        let {key, l, p, type} = req.query;
+        type = type || 'all';
+        [err, result] = await c.searchProduct(type, key, p, l);
+        if(err){ return controlError(res, err, null);}
+        searchSuccess(res,
+          result.data,
+          result.total,
+          result.key,
+          result.page,
+          result.limit,
+        );
+      }catch (e) {
+        ServerError(res, null, e.message);
+      }
+  });
 
 module.exports = { router };

+ 48 - 0
server/tools/handle.js

@@ -0,0 +1,48 @@
+/*
+ * @Description: 
+ * @Autor: kindring
+ * @Date: 2021-12-14 15:19:56
+ * @LastEditors: kindring
+ * @LastEditTime: 2021-12-14 17:17:09
+ * @LastDescript: 
+ */
+function handle(promise) {
+    return new Promise(resolve => {
+        try{
+            promise.then(val => {
+                resolve([null, val])
+            }).catch(err => {
+                resolve([err])
+            })
+        }catch(err){
+            resolve([err])
+        }
+    })
+}
+
+// 支持多个promise的并行执行
+function handleAll() {
+    return new Promise(resolve => {
+        try{
+            // arguments 转数组
+            let arr = [...arguments]
+            console.log(arr)
+            // console.log(typeof arr)
+            Promise.all(arr).then(val => {
+                console.log(val);
+                resolve([null, ...val])
+            }).catch(err => {
+                console.log(err)
+                console.log(`promise all`)
+                resolve([err])
+            })
+        }catch(err){
+            resolve([err])
+        }
+    })
+}
+
+module.exports = {
+    handle,
+    handleAll
+};

+ 105 - 0
server/tools/result.js

@@ -0,0 +1,105 @@
+const rCode = require('../map/rcodeMap');
+
+function success(res,data) {
+  res.json({
+    code: rCode.OK,
+    data: data
+  })
+}
+
+function searchSuccess(res, data, total, key, page, limit) {
+  res.json({
+    code: rCode.OK,
+    data: data,
+    total: total,
+    count: data.length,
+    key: key,
+    page: page,
+    limit: limit
+  })
+}
+
+function ServerError(res,code,msg) {
+  res.json({
+    code: code?code:rCode.ServerError,
+    msg: msg
+  })
+}
+
+function paramFail(res,msg) {
+  res.json({
+    code: rCode.NotParam,
+    msg: msg
+  })
+}
+
+function notLogin(res,msg) {
+  res.json({
+    code: rCode.NotLogin,
+    msg: msg
+  })
+}
+
+function notPermission(res,msg) {
+  res.json({
+    code: rCode.NotPermission,
+    msg: msg
+  })
+}
+
+function customError(res,msg) {
+  res.json({
+    code: rCode.CustomError,
+    msg: msg
+  })
+}
+
+function controlError(res,err,msg) {
+  let errorCode,errorMsg;
+  if(msg){ errorMsg = msg }
+  if(err){
+    if(err.eCode){
+      errorCode = err.eCode;
+    }
+    if(!msg && err.eMsg){
+      errorMsg = err.eMsg;
+    }else{
+      errorMsg = err.message;
+    }
+  }
+  if(!errorCode){ errorCode = rCode.ServerError }
+  if(!errorMsg){ errorMsg = 'server error 9999' }
+  switch (errorCode) {
+    case rCode.OK:
+      success(res,errorMsg);
+      break;
+    case rCode.NotParam:
+      paramFail(res,errorMsg);
+      break;
+    case rCode.NotLogin:
+      notLogin(res,errorMsg);
+      break;
+    case rCode.NotPermission:
+      notPermission(res,errorMsg);
+      break;
+    case rCode.CustomError:
+      customError(res,errorMsg);
+      break;
+    case rCode.Timeout:
+    case rCode.NotFound:
+    case rCode.ApiError:
+    case rCode.SaveError:
+    case rCode.DataRepeat:
+    case rCode.ServerError:
+    default:
+      ServerError(res,errorCode,errorMsg);
+  }
+}
+
+module.exports = {
+  success,
+  searchSuccess,
+  ServerError,
+  paramFail,
+  controlError,
+}

+ 47 - 0
server/tools/searchSql.js

@@ -0,0 +1,47 @@
+const {toNumber} = require("../utils/typeTool");
+const {handle} = require("./handle");
+const codeMap = require("../map/rcodeMap");
+/**
+* 封装搜索数据库字段
+* @param errorText
+* @param dbFn
+* @param _params
+* @param page
+* @param limit
+* @returns {Promise<[err,{arr, total: number, limit, page}]>}
+*/
+async function searchHandle(errorText,dbFn,_params,page,limit){
+    let err,response,arrPromise,countPromise;
+    limit = toNumber(limit);
+    page = toNumber(page);
+    limit = limit||20;
+    page = page||1;
+    arrPromise = dbFn('array',_params,page,limit);
+    if(page <= 1){
+        // 添加计数字段
+        countPromise = dbFn('count',_params);
+        [err,response] = await handle(Promise.all([arrPromise,countPromise]))
+    }else{
+        [err,response] = await handle(Promise.all([arrPromise]))
+    }
+    if(err){
+        return [
+          {eCode:codeMap.ServerError,eMsg:`${errorText}`},
+          null
+        ]
+    }
+    let  result = {
+        arr: response[0],
+        limit: limit,
+        page: page,
+        total: 0
+    }
+    if(page <= 1){
+        result.total = response[1]?response[1][0].total:null
+    }
+    return [null,result];
+}
+
+module.exports = {
+    searchHandle
+}

+ 54 - 0
server/until/typeTool.js

@@ -0,0 +1,54 @@
+let matchNumberStr = ['0',]
+// 部分关键字转换为boolean值
+let falseField = ['false','False','FALSE','null','Null','NULL','undefined','Undefined'];
+let trueField = ['true','True','TRUE'];
+// 类型转换
+function toString(){
+    // 情况1 非对象,直接调用内部值
+}
+
+// 转换为number类型,先用toBoolean转换为布尔类型
+function toNumber(v){
+    if(isString(v)){
+        if(falseField.includes(v)){
+            v = toBoolean(v)
+        }else if (trueField.includes(v)){
+            v = toBoolean(v)
+        }
+    }
+    return Number(v)
+}
+
+// 考虑字段类型
+function toBoolean(v){
+    // 字符串类型
+    if (isString(v)){
+        if(falseField.includes(v)){
+            return false
+        }else if (trueField.includes(v)){
+            return true
+        }else{
+            Boolean(v)
+        }
+    }
+}
+
+function isArray(v){
+    return v instanceof Array
+}
+function isString(v){
+    return v instanceof String || typeof v === 'string'
+}
+function isNumber(v){
+    return v instanceof Number
+}
+function isObject(v){
+    return v instanceof Object
+}
+
+
+module.exports = {
+    toNumber,
+    toString,
+    toBoolean
+}