IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> CmsWing源码分析(4)全局功能函数(三) -> 正文阅读

[JavaScript知识库]CmsWing源码分析(4)全局功能函数(三)

2021SC@SDUSC

接上一次博客继续分析global.js文件中的全局可用的功能函数

这次应当是最后一篇了

目录

自动给出更新价格

?四舍五入的格式化金额

获取商品SUK

获取文件信息

更新缓存

查看缓存权限列表

检查推荐值是否被包含

检验是否为智能手机

构建微信菜单数据结构

微信创建自定义菜单接口

总结


自动给出更新价格

将价格转化为字符串

在服务器发送的数据中,当discount_price非零时,返回“原价XX,现价XX”

否则,返回“原价XX”

global.formatprice = function(price) {
  const pr = JSON.parse(price);
  var present_price;
  // console.log(pr);
  if (think.isNumber(pr.present_price)) {
    pr.present_price = pr.present_price.toString();
  }
  var price = pr.present_price.split('-');
  if (price.length > 1) {
    present_price = formatCurrency(price[0]) + '-' + formatCurrency(price[1]);
  } else {
    present_price = formatCurrency(price[0]);
  }
  if (pr.discount_price == 0) {
    return `<span class="text-xs"><span class="text-danger">现价:¥${present_price}</span></span>`;
  } else {
    return `<span class="text-xs"><span class="text-danger">现价:¥${present_price}</span> <br>原价:¥${formatCurrency(pr.discount_price)}</span>`;
  }
};

JSON.parse()是用于将数据转换为javascript对象的方法,详细用法可见:JSON.parse() | 菜鸟教程

?四舍五入的格式化金额

金额格式的字符串,例如'1,234,567.45',用于好看

参数NUM为字符串或数字都可以,但不能是空,否则默认0

先处理小数部分,先乘100再除100,确保了有两位小数,加上的0.5则确保了四舍五入的功能

对小数点之前每三位数字进行取整并剔除,再接着处理剩下的

global.formatCurrency = function(num) {
  num = num.toString().replace(/\$|\,/g, '');
  if (isNaN(num)) { num = '0' }
  const sign = (num == (num = Math.abs(num)));
  num = Math.floor(num * 100 + 0.50000000001);
  let cents = num % 100;
  num = Math.floor(num / 100).toString();
  if (cents < 10) { cents = '0' + cents }
  for (let i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) {
    num = num.substring(0, num.length - (4 * i + 3)) + ',' +
            num.substring(num.length - (4 * i + 3));
  }
  return (((sign) ? '' : '-') + num + '.' + cents);
};

获取商品SUK

当arr这个类型数组中有一个、两个或三个元素时

商品元素也随之增加

逻辑简单又友善,就是用的函数都很怪

global.getsuk = function(suk, arr) {
  var suk_;
  suk.forEach(function(v, k) {
    if (v.name == arr[0]) {
      if (v.ch) {
        v.ch.forEach(function(v_, k_) {
          if (v_.name == arr[1]) {
            if (v_.ch) {
              v_.ch.forEach(function(v__, k__) {
                if (v__.name == arr[2]) {
                  suk_ = think.extend(v__, v_, v);
                }
              });
            } else {
              suk_ = think.extend(v_, v);
            }
          }
        });
      } else {
        suk_ = v;
      }
    }
  });
  return suk_;
};

获取文件信息

file_id 为文件id?

field为字段名

从服务器获取到文件之后,按照文件的参数类型和key的值进行本地暂存

然后返回此文件

file.savepath应当是在服务器中就准备好的信息属性

global.get_file = async(file_id, field, key = false) => {
  if (think.isEmpty(file_id)) {
    return false;
  }
  const file = await think.model('ext_attachment_file').find(file_id);
  if (file.type > 0 && key && key !== 1) {
    file.savename = `${get_pdq(file.type)}/${file.savename}?download/${file.savename}`;
  } else if (file.type > 0 && key === 1) {
    file.savename = `${get_pdq(file.type)}/${file.savename}`;
  } else {
    file.savename = `${file.savepath}/${file.savename}`;
  }
  return think.isEmpty(field) ? file : file[field];
};

更新缓存

针对接收到的服务器发来的type类型:category、channel、model、ext、hooks这五种情况后

分别做出不同的操作:更新栏目缓存、更新频道缓存、更新模型缓存、更新系统缓存、更新拦截缓存

global.update_cache = async(type) => {
  switch (type) {
    case 'category':
      // 更新栏目缓存
      await think.cache('sys_category_list', null);
      await think.cache('all_category', null);
      await think.cache('all_priv', null);// 栏目权限缓存
      break;
    case 'channel':// 更新频道缓存信息
      await think.cache('get_channel_cache', null);
      break;
    case 'model':
      await think.cache('get_document_model', null);// 清除模型缓存
      await think.cache('get_model', null);// 清除模型缓存
      break;
    case 'ext':
      await think.cache('extcache', null);
      break;
    case 'hooks':
      await think.cache('hookscache', null);
      break;
  }
};

关于cache函数的用法:

(method) ThinkCacheCtx.cache(name: string, value?: any, config?: object): Promise<any> (+2 overloads)
//get or set cache if value is null means delete cache if value is undefined, get cache by name else mean set cache

查看缓存权限列表

catid 要验证的栏目id

roleid 用户组

action 权限类型

is_admin 谁否前台 0前台,1后台

type true

{bool} 返回flase 或true false:没权限,true:有权限。

特别说明:整个程序中会存在一个缓存权限列表all_priv方便比对

global.priv = async(catid, roleid, action, is_admin = 0, type = true) => {
  const priv = await think.model('cmswing/category_priv').priv(catid, roleid, action, is_admin, type);
  if (!priv) {
    return false;
  } else {
    return true;
  }
};

检查推荐值是否被包含

pos为推荐位的值

contain为指定推荐位

将pos和contain两个参数进行按位与运算,不为0则表示$contain属于$pos

global.check_document_position = (pos = 0, contain = 0) => {
  if(think.isEmpty(pos) || think.isEmpty(contain)){
    return false;
  }
  const res = pos & contain;
  if (res !== 0){
    return true;
  }else{
    return false;
  }
}

检验是否为智能手机

CMS的建站功能可以在PC端,手机端和微信公众平台实行,因此,在用户的使用开始前,CMS需要能够辨别目前自己所处的平台是哪一个

这一边能够支持的手机系统有安卓、苹果、ipod、ipad、windows手机

然后特别的排除windows桌面系统和苹果桌面系统

agent的值似乎需要其他函数获得

global.checkMobile = function(agent) {
  let flag = false;
  agent = agent.toLowerCase();
  const keywords = ['android', 'iphone', 'ipod', 'ipad', 'windows phone', 'mqqbrowser'];

  // 排除 Windows 桌面系统  
  if (!(agent.indexOf('windows nt') > -1) || (agent.indexOf('windows nt') > -1 && agent.indexOf('compatible; msie 9.0;') > -1)) {
    // 排除苹果桌面系统  
    if (!(agent.indexOf('windows nt') > -1) && !agent.indexOf('macintosh') > -1 && !(agent.indexOf('ipad') > -1)) {
      for (const item of keywords) {
        if (agent.indexOf(item) > -1) {
          flag = true;
          break;
        }
      }
    }
  }
  return flag;
};

构建微信菜单数据结构

首先初始化一个带有按钮的菜单栏

global.createSelfMenu = function(data) {
  const menu = {
    'menu': {
      'button': []
    }
  };
const button = [];

将 data中的属性一个个写入到菜单的按钮列表中

  for (var i = 0; i < data.length; i++) {
    if (data[i].pid == '0') {
      const item = {
        'id': data[i].id,
        'm_id': data[i].m_id,
        'pid': data[i].pid,
        'type': data[i].type,
        'name': data[i].name,
        'sort': data[i].sort,
        'sub_button': []
      };
      menu.menu.button.push(item);
      button.push(item);
    }
  }

菜单分级

for (var x = 0; x < button.length; x++) {
    for (var y = 0; y < data.length; y++) {
      if (data[y].pid == button[x].m_id) {
        const sitem = {
          'type': data[y].type,
          'm_id': data[y].m_id,
          'sort': data[y].sort,
          'name': data[y].name,
          'url': data[y].url,
          'media_id': data[y].media_id
        };
        button[x].sub_button.push(sitem);
      }
    }
  }
  return menu;

微信创建自定义菜单接口

先是与上一个构建菜单一样的操作

global.buildselfmenu = function(data) {
  const menu = {
    'button': []
  };
  const button = [];

接下来也是和上一个几乎一样的操作

  for (var i = 0; i < data.length; i++) {
    if (data[i].pid == '0') {
      const item = {
        'id': data[i].id,
        'm_id': data[i].m_id,
        'pid': data[i].pid,
        'type': data[i].type,
        'name': data[i].name,
        'sort': data[i].sort,
        'sub_button': []
      };
      menu.menu.button.push(item);
      button.push(item);
    }
  }
  for (var x = 0; x < button.length; x++) {
    for (var y = 0; y < data.length; y++) {
      if (data[y].pid == button[x].m_id) {
        const sitem = {
          'type': data[y].type,
          'sort': data[y].sort,
          'name': data[y].name,
          'url': data[y].url,
          'media_id': data[y].media_id
        };
        button[x].sub_button.push(sitem);
      }
    }
  }
  return menu;

总结

至此,花了三篇文章的量,终于将global.js这一文件中的函数大致分析了一遍

这里面的基本都是在任何模块的使用频率都相当高的函数,对整个框架的构建起到螺丝一般微小但重要的作用

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-02 16:39:54  更:2021-12-02 16:42:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:52:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码