《简单库存管理开发(一)》演示了单用户版的开发,这篇文章中我们把单用户版升级为多用户SaaS服务模式。
《简单库存管理开发(一)》中开发的是一个单用户版应用,每个客户都必须独立部署一个专属实例,如今SaaS风靡全球,客户无需自己维护服务器等,只管使用系统服务。
开发SaaS多用户系统,首先需要修改用户业务数据库结构,增加客户信息,我们已经设计了表:tb_shop,门店信息表(由于是演示简单库存管理开发,没有做复杂业务的设计——例如多门店管理,分库管理等,这些需求在平台开发非常容易实现),同时在用户信息表:adm_user中,字段deptid在创建账号是强制绑定了 tb_shop.id,这是多用户实现的管理基础。

为业务表增加 shop_id 商户商铺编号字段:
ALTER TABLE tb_goods_type ADD COLUMN shop_id INTEGER; ALTER TABLE tb_goods ADD COLUMN shop_id INTEGER; ALTER TABLE tb_store ADD COLUMN shop_id INTEGER; ALTER TABLE tb_store_in ADD COLUMN shop_id INTEGER; ALTER TABLE tb_store_out ADD COLUMN shop_id INTEGER;
打开【链接管理】点击工具栏【数据】按钮,复制上面SQL脚本,【执行】,数据库结构升级完毕。
2、把新增加的shop_id 选入各模块的字段列表中模块设计中,数据结构的修改是实时反映到可视化设计界面的。
3、为模块增加数据访问条件把 shop_id 字段选入模块字段列表后,点击各模块的【编辑】、【数据管理】在条件中增加:
shop_id={{ME.deptid}}
条件中: {{ME.deptid}} 是有效云开发系统中为实现可视化、低代码设计的系统变量,用户登录系统后,用户的基本信息映射为了 ME 变量,在模块的编程接口中可以随时调用。
这时,各应用模块可以访问数据就被限定到了当前登录账号所绑定商铺。
4、升级模块内业务逻辑处理模块内业务数据主要包括<商品分类>和<商品选择>,作为SaaS服务,开发时我们无法预知用户商品分类都相同,所以我们要允许商户拥有自己独立的分类信息和商品信息。在选择下拉框绑定 SQL 中增加商铺限定条件:
select id,name as val from tb_goods_type where pid=0 and shop_id={{ME.deptid}}
单用户版在通过接口获取商品库存时,只根据当前出库商品检索库存,理论上SaaS 系统中所有商铺的库存信息、商品信息都是唯一的,不做升级理论上可行,但为了系统的更加稳健,我们还是增加商铺信息关联:
修改接口的 r 参数检索条件为:
select goods_id,goods_count from tb_store where goods_id={{.goods_id}} and shop_id={{ME.deptid}} limit 1;
偷个
业务功能模块部分升级完毕!
最后,增加 SaaS 管理者,商铺管理和账号管理功能,以及商户的店铺信息管理和账号管理。
通过系统提供的克隆功能,【复制】商铺管理模块和用户管理模块。
(1)、SaaS管理端商铺管理修改该新克隆的模块名称为:<系统-商铺管理>;【编辑】、【数据管理】条件改为:
{{ME.ismanager}}=1 and {{ME.deptid}}=0
前面我们设置商铺账号的店铺名称字段必填,如果为零代表是SaaS管理者,这样的设置,系统管理员可以查看和管理所有商户信息。
(2)、SaaS管理端账号管理修改管理者账号管理模块的<所属商户>字段绑定SQL如下:
select 0 as id, '服务方' as val union select id,name as val from tb_shop where state = 1 order by name
(3)、商铺信息管理
【编辑】商铺模块,修改【数据管理】条件为:
id in (select deptid from adm_user where id={{UID}})
其中,{{UID}} 即为:{{ME.id}}。该语句限定,只能访问当前账号绑定的商铺信息——这与写为:id={{ME.deptid}},有何区别呢?一个账号是否能够管理个店铺呢?
(4)、商铺账号管理【编辑】商户账号管理模块,【数据管理】条件设置为:
id!={{UID}} and id !=1 and deptid={{ME.deptid}}
id=1 为内置账号过滤掉,id != {{UID}} :当前用户不能操作账号(我的信息可以修改)。
模块【表单】管理,【编辑】deptid 所属商铺下拉框绑定SQL为:
select id,name as val from tb_shop where state = 1 and id in (select deptid from adm_user where id={{UID}} and deptid!=0)
这样,所属商铺选项就只能选择自己所属商铺——这里也可以把该字段组件类型改为文本框,默认值设为:{{ME.deptid}},同时设为只读或隐藏。
至此,所有升级工作完成。