功能操作流程

  1. 从左侧拖入组件到中间容器内。左侧组件不变,只是clone节点到中间容器。
  2. 中间容器不可再拖入左侧。中间容器各个部件可以在容器内上下拖动进行排序。
  3. 支持同类型多组件。从左侧拖入相同组件的时候,会先从中间容器拷贝同类型的部件。重用样式。每个部件id值唯一。
  4. 中间容器 选中某个部件,在选中的部件右上角显示删除按钮。右边显示对应的部件属性。
  5. 修改右边对应的部件属性,中间容器对应的部件可实时显示效果。
  6. 右边部件的属性根据 每个部件的类型不同而决定。
  7. 中间容器下方底部可设置大容器的页面背景颜色。
  8. 最后提交保存全部部件的属性。这样就完成了一个页面模板。 下次页面模板编辑的时候,页面进入直接显示实时效果。
    图片

大多数产品在本地Sqlite存储的时候,基本都是用了串行模式。即整个应用全局只有一个sql操作句柄,用单例管理着这个SqlHandler。另外还有一个模式叫线程模式。这种模式下很容易出现Sqlite_Busy错误。

  1. 当有写操作时,其他读操作会被驳回。
  2. 当有写操作时,其他写操作会被驳回。
  3. 当开启事务时,在事务提交之前,其他写操作会被驳回。
  4. 当开启事务时,在事务提交之前,其他事务请求会被驳回。
  5. 当有读操作时,其他写操作会被驳回。
  6. 读操作之间能够并发执行。

第三方库WCDB支持多线程度于读与读,读与写并发执行,写与写串行执行。WCDB 在多线程方面明显优于 FMDB 和 ModelSqliteKit,通过 WCDB 的改造,使得SQLite的性能发挥到极致。

简介

图片编辑是基于 CLImageEditor 第三方进行改装得到仿微信的图片编辑交互。原CLImageEditor库是一个日本人写的图片编辑,支持涂鸦,裁剪,旋转,文字帖功能。但有几项我们进行改进。

  • 所有的这些图片操作我们汇总到一起进行编辑,最终保存的时候才处理所有操作汇总成一张处理图片。
  • 涂鸦撤销功能实现真正的上一步撤销,而不是仅仅透明色进行橡皮擦擦除。
  • 新增马赛克操作功能。
  • 把图片裁剪和旋转进行结合到一个页面操作,另外新增裁剪、旋转之后的图片恢复。
  • 改变颜色选择,文字编辑的交互,新增图片裁剪区域的边角重点标注。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    CLImageEditorViewController

    usedToolDic:使用过的工具【toolName:CLImageToolBase

    -(CLImageToolBase *)currentEditTool; 当前正在使用的工具。

    -(UIImage *)getMergeDrawImageForCropTool; 最后合成的图片。用于业务转发、保存、回调给用户。

    //图片编辑器所支持的工具类都继承于CLImageToolBase, 通过CLClassList辅助类runtime方式自动将相关工具类注入到菜单项中。
    + (NSArray*)subtools
    {
    return [CLImageToolInfo toolsWithToolClass:[CLImageToolBase class]];
    }
    CLImageToolBase 工具基类:持有editor编辑器方便拿到图片,同时具有setup, cleanUp 这几个“生命周期”方法,做相关工具的视图创建与清除。

我们每个人的手机都安装有微信App,肯定大家都使用过以下场景在聊天群中,当有新的成员进入的时候,可以看到 某某邀请了某某1进入群聊,或者当你是群主的时候,某管理人员邀请了几个人进入时候看到 某某管理员邀请了张三、李四,王五,张三(同名)进入了群聊。对于邀请人员或者被邀请人员,我们发现人员的名称是可以点击的,即使同名的人,点击其名字也可以跳转到各自的主页详情中。

如何存储人员的id?

一条群成员变更通知就是一串文本,我们点击的时候肯定要存储好他的人员id,然后点击的时候就能拿到对应人员的id。从最简单的存储方案来看,这条内容可以写成以下格式: 管理员刘某某邀请了张三李四王五张三进入了群聊。换成代码的格式即为:“管理员\”刘某某::1000\”邀请了\”张三::1001、李四::1002、王五::1003、张三::1004\”进入了群聊”。其中的代码格式为userName::userId这样一种形式进行拼接,中间的符号可以采用其他特殊符号代替。这里为了区别用户特殊性输入用了双冒号。多个成员之间用顿号隔开,人员与普通内容之间用符号双引号\”进行分割(斜杆为转义符)。 我们需要对这一串文字表达式进行解析进行UI显示,把人员名字后的拼接符号用户id进行过滤掉,组合成不带用户id的易懂文字内容给到用户。

群插件的基础属性

群插件一般是用H5配置的网页小插件,然后和群构造一个入口。本地通过sqlite维护一个插件表,以及群插件关系表。插件信息升级一下可分为平台系统必须插件以及业务自定义插件。具体可由业务决定。
插件有其基本属性:名称,插件id,类型,默认排序值,跳转内容(本地模块名/h5链接地址),跳转类型:h5/本地模块 等等。
插件关系表: 群id,插件id,角标数量,排序值,是否显示,等等。

聊天输入框@某人逻辑分类点说明

IM 应用软件无论是App端或者是PC端都有@某人这样一个功能点,由于用户输入框输入条件的复杂随机性种类多,@的针对不同情况进行拼接或者新增样式显示蓝色字体表示该人名可链接。由输入框开始,用户输入@的方式进行分类:

  1. 首字母为空,用户直接输入@,然后跳转到成员页面进行选择相关人员,选完即带回人名 结果为:“@某人”
  2. input输入框输入了文字的基础上: 在最前面下班为0的第1个位置进行插入@ 结果为:“@某人原input输入框的文字”
  3. input输入框输入了文字的基础上,在最后面下班为length-1的第后一个位置进行插入@ 结果为:“原input输入框的文字@某人”
  4. input输入框输入了文字的基础上,在文字内容中输入@。即条件 0 < index < length-1 结果为:“原input输入@某人框的文字”

在以上四种输入情况中,3,4 输入拼接@某人的时候,需要判断前一个字是否为@, 如果是,则后面拼接的时候直接+某人即可。另外当在第4种情况文字中间输入的时候,中英文下输入可能遇到文本框的值为 “ @@文字”,按照之前的逻辑当光标输入在第2个@后时,然后键盘输入@跳转页面选择成员,最后的结果应该是“ @@某人文字”这个组合,为了更友好地显示,还需检查当前两个也是@的时候,即出现1个@. 即结果为“ @某人文字” 以便更友好地显示。

核心逻辑:根据文本框原输入文字是否有内容,无内容时候直接拼接。有内容时候分两种情况,即光标的输入位置情况:当location等于0的时候,即在首位置输入@某人拼接原文本内容。当location大于0的时候,即光标可能出现在内容文字之间,也可能是在最后面。也是分两种情况:根据location+1判断是否小于原文本框文字长度length.如果小于,则表示在内容之间插入。否则,在内容最后尾部插入。无论是之间还是尾部做插入,都需检查前一个字符是否为@,如果是,则在做拼接人名时候就无需再追加@。当在之间做插入的时候,为了友好显示,可适当判断前两个字符为@@时候进行替换为一个@。

Echart

数据看板首要问题,就是我们要解决数据分组的问题。你可以存储到浏览器的websql中通过sql语句groupBy来进行分组统计,或者你自己用js对数据进行分组。由于数据量有限,也就几百个吧,这里采取js方式对数据进行内存分组统计。

1
2
3
4
5
6
7
8
9
export const groupBy = (list, fn) => {
const groups = {};
list.forEach(function(o) {
const group = JSON.stringify(fn(o));
groups[group] = groups[group] || [];
groups[group].push(o);
});
return groups;
}

前言

SKU百度百科为 库存保有单位 (Stock keeping Unit 或者SKU)是对每一个产品和服务的唯一标示符。 也就是说sku 为商品对应的很多种类规格情况下的 库存,价格 各有不同。需要通过sku 这样一种组合结构存储这些计量值。
在移动电商时代,网购已然成为潮流。更是全民参与。每一年都有购物节 : 京东618 , 淘宝天猫双11, 双12 。 一个淘宝店家月销售额30万背后 ,他的商品sku有上千种。 一个卖橱柜的,小到抽屉,拉篮,五金 ,把手,螺丝钉 都可以细分成很小的SKU。移动电商商品背后的SKU种类的复杂性。可正是因为商品SKU的多样化,才能商家带来巨量的销售额。

从详情页认识SKU

C端sku选择

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
这个商品包含的SKU信息:{
规格类型:[{
尺寸:[XS, S, M, L,XL, XXL]
},{
颜色: [白色,珊瑚粉,草木绿]
}],
规格明细组合描述: {
XS-白色:{
图片: 图片url,
价格: ¥328,
库存: 188件,
扩展..字段: 值
},
其他规格组合:{
图片: 图片url,
价格: 价格..,
库存: 库存数量..,
扩展..字段: 值
}
}
}

图片

抽奖功能模块源码
产品出发点
1、通过动态抽奖数据和排行激发用户抽奖消费;
2、通过技能和宝石等以及转盘的燃爆值,中奖率翻倍等等吸引用户;
3、根本上是为了激发用户活跃性以及刺激消费

技术难点
1、抽奖转盘分为两种转盘,业务逻辑分一个parentVC 管理两个 子 VC;
2、抽奖奖品服务端返回,显示在每一个扇形区域的中间,金额同似;
3、点击抽奖,拿到奖品id, 找出是在转盘中的哪个区域,让转盘指针停止在那一区域;
4、抽奖动态弹幕;
5、燃烧值 和 倒计时的控制;

业务操作说明
1、两个转盘,某个转盘点击开始抽奖 互不影响; 黄金转盘具有宝箱和技能;
2、每抽取一次,扣除相应的金额,如有中奖,则弹出中奖奖品;抽奖分为单次,十连抽,三十连抽等;
3、抽奖后产生记录;在记录中可看到每次抽奖消费情况;
4、转盘有燃烧值,当满时候,触发倒计时3分钟,倒计时内 中奖率将翻倍;
5、燃烧值每3秒刷新一次,当中途离开再次打开,则拿到最新倒计时显示;
6、弹幕从最新100条记录 每隔2秒随机生成一条记录;

模块设计
1、整个框架布局在一个 MainVC中控制转盘类型,请求余额,通知等刷新金额; 管理childVC ;
2、childVC 中 处理抽奖业务逻辑;UI 布局,抽奖请求, 燃烧值处理,弹幕处理;
3、其他功能性子View 单独自定义视图; 转盘视图,燃烧值进度视图,倒计时进度视图, 弹窗类视图;弹幕视图;
4、弹窗类视图 以一个ParentView公共视图容器 ,其中子视图由枚举参数值控制自定义;有玩法视图,记录视图,保险视图,技能视图,排行榜视图;

图片
图片2
当需要在地图上层覆盖一个列表时候,我们想看到更多的内容,列表被拉出来后翻看数据;
当想收起时候,可用下拉,或者随着手势滑落下来;

需解决的问题:
1、滑动表格,地图不移动;手势来回滑时候,列表要跟着高度变化;
2、当滑到最高时候,不再往上滑动;相反,滑到最低高度时候不再继续向下;
3、滑上去之后,再往下滑动 不影响列表数据的查看与浏览;

思考

手势开始:记录 开始点startY,

手势移动:
根据起始位置移动差 确定上滑动 , 下滑动;

起点B 点 记录方向 0;
B-A 正向, 记录方向符号 1;
B-C 反向 ,记录方向 -1;

偏移值 大于0 , 上滑动;
当B-A-C 后,立马记录 1 变成 -1; 记录标记状态前,

正向如:B-A 的过程 ,需判断是否为 为 -1 到1 还是 0-1 , 如果是-1 则是来回拖动;否则为正向拖动;

code :以下是重点逻辑代码;