发布文章功能,怎么解析文章的格式,怎么生成一个带格式的文章

175 阅读2分钟

最近有个需求,用户需要发布一些文章,我就在想用户发布文章就用一个富文本吧,然后展示文章的时候,用一些能解析html标签的组件。这样文章就能带格式显示了。但实际中还有会遇到一些问题。

我以前的一些方案

就是发布文章用公众号发布,或者其他第三方,掘金,语雀等。好处就是这些平台的发布文章做的很漂亮,并且公众号还可以在小程序中展示,(需关联)。但坏处就是,用户觉得去其它地方麻烦。哎,劝不了,一点都劝不了。

富文本wangeditor + 移动端解析插件uv-parse

富文本的好处就是可以像编辑word 一样带格式(文本里面会生成html 样式)。uv-parse是可以解析样式,比原生的rich-text 标签更强。

但实际操作中,发现wangeditor 的图片上传在uniCloud 中会有问题,奇怪就是我成功了一次,恍惚间?但后面怎么都不成功,最后我只能把图片全转成base64,这就会导致一个文章的存储量太大,前端请求过来很久不显示。延伸的问题就来了。

延伸问题,在unicloud 中怎么解决只需要返回某些字段,而不需要全部返回

field()可以只返回你需要的字段,这就能解决数据量大,网络返回请求比较慢的问题。这涉及到对unicloud 操作数据库的细节方法。为了更好的学会看unicloud的文档,我出一道题,下面我有一个封装代码,里面涉及的全是unicloud操作方法,你看看我(作者,第一人称方便描述)为什么这么封装?理解透了,就能同步更加理解unicloud的文档方法细节。

import {
 Message,
 Loading
} from 'element-ui';

import config from '@/admin.config.js'

let db = {};
let unidb = uniCloud.database();

db = new Proxy(db, {
 get: function(target, key) {
  // console.log(target, key);
  if (key === '$cmd'return unidb.command;
  return new DbContext(key);
 }
});

function DbContext(name) {
 this.table = name;
 this.where_obj = {};
 this.where_arr = [];
 this.where_str = '';
 this.isgroup = false;
 this.group = {};
 
 this.response = {
  code: 200,
  datas: {},
  msg: ''
 }
}

DbContext.prototype = {
 table: ''// 数据集合|表名
 field: '',
 isgroup: false,
 group: {},
 where_obj: {}, // where 条件
 where_arr: [], // where 条件
 where_str: ''// where 条件
 response: {} // 统一响应格式
};

DbContext.prototype.where = function(params) {
 if (typeof params === 'object') {
  Object.assign(this.where_obj, params);
 }
 if (typeof params === 'string') {
  this.where_arr.push(params);
 }
 return this
}
DbContext.prototype.whereif = function(_flag, _obj) {
 if (_flag) this.where(_obj);
 return this;
}

DbContext.prototype.field = function(params) {
 this.field = params;
 return this;
}

DbContext.prototype.collection = function() {
 return unidb.collection(this.table);
}

DbContext.prototype.add = function(obj) {
 uni.showLoading({
  title: '请求中'
 })
 return this.collection()
  .add(obj)
  .then(res => {
   if (config.debug) {
    console.log(this.table + ' add', res);
   }
   if (res.result) {
    this.response.datas = res.result;
    if (res.result.errCode === 0this.response.code = 200;

    return Promise.resolve(this.response);
   }

   return Promise.reject(res);
  })
  .catch(err => {
   if (config.debug) {
    console.log(this.table + ' add catch', err);
    Message.error(err.message);
   }
   return Promise.reject(err);
  })
  .finally(res => {
   uni.hideLoading();
  });
}

DbContext.prototype.remove = function(_id) {
 uni.showLoading({
  title: '请求中'
 })

 if (_id) {
  return this.collection()
   .doc(_id)
   .remove()
   .then(res => {
    if (config.debug) {
     console.log(this.table + ' remove', res);
    }
    if (res.result) {
     this.response.datas = res.result;
     if (res.result.errCode === 0this.response.code = 200;

     return Promise.resolve(this.response);
    }

    return Promise.reject(res);
   })
   .catch(err => {
    if (config.debug) {
     console.log(this.table + ' remove catch', err);
     Message.error(err.message);
    }
    return Promise.reject(err);
   })
   .finally(res => {
    uni.hideLoading();
   });
 }
 this.where_str = this.where_arr.join(' && ');
 return this.collection()
  .where(this.where_str || this.where_obj)
  .remove()
  .then(res => {
   if (config.debug) {
    console.log(this.table + ' remove', res);
   }
   if (res.result) {
    this.response.datas = res.result;
    if (res.result.errCode === 0this.response.code = 200;

    return Promise.resolve(this.response);
   }

   return Promise.reject(res);
  })
  .catch(err => {
   if (config.debug) {
    console.log(this.table + ' remove catch', err);
    Message.error(err.message);
   }
   return Promise.reject(err);
  })
  .finally(res => {
   uni.hideLoading();
  });
}

DbContext.prototype.set = function(_id, obj) {
 uni.showLoading({
  title: '请求中'
 })
 return this.collection()
  .doc(_id)
  .set(obj)
  .then(res => {
   if (config.debug) {
    console.log(this.table + ' set', res);
   }
   if (res.result) {
    this.response.datas = res.result;
    if (res.result.errCode === 0this.response.code = 200;

    return Promise.resolve(this.response);
   }

   return Promise.reject(res);
  })
  .catch(err => {
   if (config.debug) {
    console.log(this.table + ' set catch', err);
    Message.error(err.message);
   }
   return Promise.reject(err);
  })
  .finally(res => {
   uni.hideLoading();
  });
}

DbContext.prototype.update = function(_id, obj) {
 uni.showLoading({
  title: '请求中'
 })
 if (_id) {
  return this.collection()
   .doc(_id)
   .update(obj)
   .then(res => {
    if (config.debug) {
     console.log(this.table + ' update', res);
    }
    if (res.result) {
     this.response.datas = res.result;
     if (res.result.errCode === 0this.response.code = 200;

     return Promise.resolve(this.response);
    }

    return Promise.reject(res);
   })
   .catch(err => {
    if (config.debug) {
     console.log(this.table + ' update catch', err);
     Message.error(err.message);
    }
    return Promise.reject(err);
   })
   .finally(res => {
    uni.hideLoading();
   });
 }

 this.where_str = this.where_arr.join(' && ');
 return this.collection()
  .where(this.where_str || this.where_obj)
  .update(obj)
  .then(res => {
   if (config.debug) {
    console.log(this.table + ' update', res);
   }
   if (res.result) {
    this.response.datas = res.result;
    if (res.result.errCode === 0this.response.code = 200;

    return Promise.resolve(this.response);
   }

   return Promise.reject(res);
  })
  .catch(err => {
   if (config.debug) {
    console.log(this.table + ' update catch', err);
    Message.error(err.message);
   }
   return Promise.reject(err);
  })
  .finally(res => {
   uni.hideLoading();
  });
}

DbContext.prototype.tofirst = function(_obj) {
 let _id = '';
 let _loading = true;
 if (typeof _obj === 'object') {
  _id = _obj._id || '';
  if (typeof _obj.loadding === 'boolean') _loading = _obj.loadding;
 }
 if (typeof _obj === 'string') {
  _id = _obj;
 }
 
 if (_loading) {
  uni.showLoading({
   title: '请求中'
  })
 }
 
 let ctx = this.collection();
 
 if (_id) {
  ctx = ctx.doc(_id);
  if (this.field) { ctx = ctx.field(this.field); }
  return ctx.get()
   .then(res => {
    if (config.debug) {
     console.log(this.table + ' tofirst', res);
    }
    const data = res.result.data[0];
    if (res.result.errCode === 0) {
     this.response.code = 200;
     this.response.datas = data;

     return Promise.resolve(this.response);
    }

    return Promise.reject(res);
   })
   .catch(err => {
    if (config.debug) {
     console.log(this.table + ' tofirst catch', err);
     Message.error(err.message);
    }
    return Promise.reject(err);
   })
   .finally(res => {
    if (_loading) {
     uni.hideLoading();
    }
   });
 }
 this.where_str = this.where_arr.join(' && ');
 ctx = ctx.where(this.where_str || this.where_obj);
 if (this.field) { ctx = ctx.field(this.field); }
 return ctx.get({
   getOne: true
  })
  .then(res => {
   if (config.debug) {
    console.log(this.table + ' tofirst', res);
   }
   const data = res.result.data;
   if (res.result.errCode === 0) {
    this.response.code = 200;
    this.response.datas = data;

    return Promise.resolve(this.response);
   }

   return Promise.reject(res);
  })
  .catch(err => {
   if (config.debug) {
    console.log(this.table + ' tofirst catch', err);
    Message.error(err.message);
   }
   return Promise.reject(err);
  })
  .finally(res => {
   uni.hideLoading();
  });
}

DbContext.prototype.totree = function(req) {
 // 页码 页数 排序
 req = Object.assign({
  page: 1,
  rows: 50,
  orderby: '',
  loadding: true
 }, req);
 
 if (req.loadding) {
  uni.showLoading({
   title: '请求中'
  })
 }
 
 return this.collection()
  .orderBy(req.orderby)
  .get({
   getTree: {
    limitLevel: 15,
    startWith: req.startWith
   }
  })
  .then(res => {
   if (config.debug) {
    console.log(this.table + ' totree', res);
   }
   if (res.result) {
    this.response.datas = res.result.data;

    if (res.result.errCode === 0this.response.code = 200;

    return Promise.resolve(this.response);
   }

   return Promise.reject(res);
  })
  .catch(err => {
   if (config.debug) {
    console.log(this.table + ' totree catch', err);
    Message.error(err.message);
   }
   return Promise.reject(err);
  })
  .finally(res => {
   if (req.loadding) {
    uni.hideLoading();
   }
  });
}

DbContext.prototype.tolist = function(req) {
 // 页码 页数 排序
 req = Object.assign({
  page: 1,
  rows: 30,
  orderby: ''
 }, req);
 uni.showLoading({
  title: '请求中'
 })
 this.where_str = this.where_arr.join(' && ');
 return this.collection()
  .where(this.where_str || this.where_obj)
  .orderBy(req.orderby)
  .skip((req.page - 1) * req.rows)
  .limit(req.rows)
  .get()
  .then(res => {
   if (config.debug) {
    console.log(this.table + ' tolist', res);
   }
   if (res.result) {
    this.response.datas = res.result.data;

    if (res.result.errCode === 0this.response.code = 200;

    return Promise.resolve(this.response);
   }

   return Promise.reject(res);
  })
  .catch(err => {
   if (config.debug) {
    console.log(this.table + ' tolist catch', err);
    Message.error(err.message);
   }
   return Promise.reject(err);
  })
  .finally(res => {
   uni.hideLoading();
  });
}

DbContext.prototype.withgroup = function (param) {
 this.isgroup = true;
 this.group = param;
 return this;
}

DbContext.prototype.totable = async function(req) {
 // 页码 页数 排序
 req = Object.assign({
  page: 1,
  rows: 10,
  orderby: ''
 }, req);
 uni.showLoading({
  title: '请求中'
 })
 this.where_str = this.where_arr.join(' && ');
 
 if (this.isgroup) {
  this.response.datas.groupDatas = [];
  let groupWhereStr = this.where_arr.filter(x => x.indexOf(this.group.field) == -1).join(' && ');
  let groupWhereObj = Object.assign({}, this.where_obj);
  delete groupWhereObj[this.group.field];
  const $ = unidb.command.aggregate;
  const groupRes = await this.collection()
     .aggregate()
     .match(groupWhereStr || groupWhereObj)
     .group({
      _id: '$' + this.group.field,
      cnt: $.sum(1)
     })
     .end();
  
  if (groupRes.result && groupRes.result.data) {
   this.response.datas.groupDatas = groupRes.result.data;
   this.response.datas.group = this.group;
   this.group.datas = [];
   this.group.total = 0;
   
   for (let key in this.group.obj) {
    this.group.obj[key] = 0;
   }
   
   this.response.datas.groupDatas.forEach(x =>{
    x.name = x._id;
    
    if(Object.keys(this.group.obj).includes(x._id)) {
     this.group.obj[x._id] = x.cnt;
     this.group.total += x.cnt;
    }
   })
   if (Object.keys(this.group.obj).includes('全部')) {
    this.group.obj['全部'] = this.group.total;
   }
   
   for (let key in this.group.obj) {
    this.group.datas.push({
     name: key,
     cnt: this.group.obj[key]
    })
   }
  }
 }
 
 let ctx = this.collection();
 
 if (this.where_obj) { ctx = ctx.where(this.where_obj); }
 if (this.where_str) { ctx = ctx.where(this.where_str); }
 if (this.field) { ctx = ctx.field(this.field); }
 
 return ctx.skip((req.page - 1) * req.rows)
  .orderBy(req.orderby)
  .limit(req.rows)
  .get({
   getCount: true
  })
  .then(res => {
   if (config.debug) {
    console.log(this.table + ' totable', res);
   }
   if (res.result) {
    this.response.datas.rows = res.result.data;
    this.response.datas.total = res.result.count;

    if (res.result.errCode === 0this.response.code = 200;

    return Promise.resolve(this.response);
   }

   return Promise.reject(res);
  })
  .catch(err => {
   if (config.debug) {
    console.log(this.table + ' totable catch', err);
    Message.error(err.message);
   }
   return Promise.reject(err);
  })
  .finally(res => {
   uni.hideLoading();
  });
}

export default db;

如果你喜欢我的文章,一定关注一下我的公众号,九月有风。这是对我最好的支持了,谢谢了