智慧门店会员联通ERP开卡需求

先说说智慧门店会员联通ERP,这个功能就是实现商家的会员在手机淘宝上开卡成为商家的会员,会员身份信息与商家自有ERP打通一体。开卡渠道一般分为两种,1.顾客扫描淘宝智慧门店的门店二维码,二维码对于ERP来说是带有门店信息2.就是会员自主搜索或打开开卡链接进行开卡活动,这个操作没有门店信息传入ERP。
废话少说,先见如下需求调整:

客户需求

看到这个需求一开始是郁闷的,因为以前遇到过类似的需求都是开发改,从字面上看,仿佛需要改线上的代码。我们不妨分析一下内容,看是不是有更简洁的方法靠我们自己来实现。只要按照客户的要求实现功能即可,不管它手段多卑劣。
1.卡号规则,虽然比较多内容,但是我们可以确认就是 固定字符+to_char(sysdate,’YYDDMM’)+流水(使用for循环实现流水)
2.默认开卡类型,即默认传值
3.开卡店仓和手淘开卡店仓,实际上这两个字段和店仓表就是主外键关系。在传值时候可以仿照给开卡店仓传值的方法,来给手淘开卡店仓传值,关于扫码开卡或自选开卡,对于线下而言就是:’扫码门店’字段是否为空,我们可以使用这个字段进行验证,通俗来说,我用一下两张图就能解释开卡的这种逻辑

Created with Raphaël 2.1.2 ***新会员扫门店码绑定天猫卡*** 开卡门店 开卡门店 手淘开卡门店 手淘开卡门店 脚本 脚本 我有女朋友了 国家规定这种情况我跟开卡门店的女朋友必须是同一个 好吧真tm可怜,你俩共用一个 真好,咱俩都是一家人
Created with Raphaël 2.1.2 ***新会员未扫门店码绑定天猫卡*** 开卡门店 开卡门店 手淘开卡门店 手淘开卡门店 脚本 脚本 我没有女朋友 国家规定咱俩都没有的话,国家包发 好吧真tm可怜,你俩落魄到国家发放女朋友 真好,还是国家对咱们好

4.因为都是通过手机淘宝开卡,我们就默认传值:’Y’,或者更合理的方式,在where条件后面判断来源,传’Y’。
5.关于绑卡。逻辑与开卡类似,其实就是在第三步上进行改动,将insert改为update
我们整理一下,其实都是可以从线下脚本调整实现,大致列为下面几类:
传门店值>新会员即insert,老会员即update>固定值传固定字符>卡号流水使用for循环实现递增。我还是用下面两个图表达这种绑卡会员身份的逻辑

Created with Raphaël 2.1.2 ***老会员扫门店码绑定天猫卡*** 手淘开卡门店 手淘开卡门店 开卡门店 开卡门店 我有女朋友啦! 开卡门店愣了一下,说:你tm有还跟我说?没有我借你 自给自足,衣食无忧。
Created with Raphaël 2.1.2 ***老会员未扫门店码绑定天猫卡*** 手淘开卡门店 手淘开卡门店 脚本 脚本 开卡门店 开卡门店 我有没有女朋友 他没有对象,你的借给他装逼吧 好的,大哥你说了算 老屌丝,开卡门店的女朋友借给你

思路有了,环境咱们也有了,咱们动手实践。先来第一步,卡号规则,难点在于流水号生成如何递增,先确定流水号,则有初始值。要将初始值存于表中,还要将递增后的值也更新进去。
在we_os表中设置流水卡号初始值为1。新增字段

alter table we_os  add card_no NUMBER(10);
update we_os set card_no=1;
commit
cardnolength := length(v_cardno);--获取流水号的长度2018/08/21 author xiaowei
  if cardnolength <> 5 then            --流水号初始值为0,长度为1
    while (5-cardnolength) >0 loop -- 判断流水号如果低于5位,就执行循环
      v_cardno := 0||v_cardno;        --每次循环都在流水号上加0,即直到为00001
      cardnolength := cardnolength +1; --每次循环,都将卡号长度值加1
    end loop;
  end if;          --循环结束,此时card_no变更为00001_cardno := cardprefix ||to_char(sysdate,'yymmdd')|| v_cardno; --卡号规则2018/08/22
                            --卡号=TM+180822+00001  即TM18082200001
 update we_os set card_no = v_cardno+1 where appid=p_appid;--在每生成一张会员卡,card_no就加1,实现流水号递增

现在json参数进行测试
测试结果

返回0,执行成功,现在我们看下卡号生成结果
卡号生成结果
因为设置初始值为0,第一个卡号就是0结尾,卡号按照需求生成成功。

现在开始实现开卡门店与手淘门店传值。
判断传入的开卡门店并赋值给开卡门店和手淘开卡门店

IF   P_OPENCARDSTORE_CODE IS NOT NULL THEN--如果门店参数不为空
       SELECT c.ID INTO  P_OPENCARDSTORE_ID FROM C_STORE C WHERE C.CODE= P_OPENCARDSTORE_CODE; --将参数传给手淘开卡门店
     ELSE --如果为空,即业务上理解为未扫门店码
       SELECT W.c_Store_Id INTO P_OPENCARDSTORE_ID FROM c_client_vip W  WHERE W.Id=p_c_vip_id;--将这个会员的手淘开卡门店设置为默认门店
     END IF;--给手淘开卡门店P_OPENCARDSTORE_ID 赋值
      update c_client_vip cc set cc.st_opencardstore_id=P_OPENCARDSTORE_ID,cc.wisdom_store='Y' where cc.mobil=p_phonenum;--将手淘开卡门店字段传给VIP档案,将是否天猫会员变更为'Y'

但是,新的问题来了。五位流水号,如果开卡人数达到99999个,第100000个人卡号就是’TM180824100000 ‘流水号达到6位数了。所以再次与客户确认卡号规则。
最终确定每天凌晨,五位流水号还原,那么就可以满足:’日期+5位流水号’为唯一数值
还原动作分两步:
1.设定还原数据的脚本,以存储过程最佳
2.设置job任务调用数据库存储过程
直接来个简单粗暴的,不传参的存储过程

CREATE OR REPLACE PROCEDURE UPDATE_WEOS_CARDNUMBER IS
BEGIN
  UPDATE WE_OS SET CARD_NO=0,MODIFIEDDATE=SYSDATE WHERE APPID='20180820115920';--每次被调用时候,把调用时间更新到we_os表中
  COMMIT;
END;

测试一下!

这里写图片描述
测试结果成功!
脚本设定好了,接下来就是job定时器设置,直接贴上代码

declare JOBAUTO PLS_INTEGER;
<!--pls_integer类型也是数字类型,但和number类型不同,number可以存储实数,而pls_integer只能存储-2147483647到+2147483647之间的整数,如果使用pls_integer类型时发生溢出,系统将会报错。--!>
BEGIN 
   sys.DBMS_JOB.submit(job=>JOBAUTO,
   what=>'UPDATE_WEOS_CARDNUMBER;',--调用的存储过程名
   NEXT_DATE=>TO_DATE('25-08-2018 00:00:00','DD-MM-YYYY HH24:MI:SS'),--下次执行时间
   interval=>'trunc(sysdate+1)') ;--执行周期每24H一次
   commit;
end;

至此在每天凌晨对流水号清零任务已启动。

改代码测试过程中遇到疑难问题一:
老的会员绑卡时候,按照要求,如果传参,保留原开卡门店,参数传给手淘开卡店仓,但是实际测试中发现,传参同时都更新了开卡门店和手淘开卡门店。
代码无限检查ing。。。。
将传参打印出来,确定是不是传参问题

jor.put('errMessage', '本次扫码传入门店参数是'||P_OPENCARDSTORE_ID);

确定不是参数问题,。。。。几近崩溃

继续查!终于发现坑爹的问题,见如下代码

--判断门店是以线上为准
if isonlinestore='Y' and v_storeid is not null then
    update c_client_vip c set c.c_store_id=v_storeid,c.c_customer_id=v_customerid where c.id=p_c_vip_id;
  else
  if c_openstorecode is null and v_storeid is not null then  --线下是空,就已线上为准
      update c_client_vip c set c.c_store_id=v_storeid,c.c_customer_id=v_customerid where c.id=p_c_vip_id;
  else
    p_openstorecode:=c_openstorecode;
  end IF;

以上代码是说,如果传入参数为空,门店以线上为准,但是这个会员的线下开卡门店有,那么就将参数更新进开卡门店字段。再来看看我们的测试请求参数,果然是以线上门店为准
请求参数
ok,再次简单粗暴,确认以上代码不影响其它业务场景和流程后,赶紧注释注释注释掉!~

问题二:
设置会员表的手淘开卡门店与门店档案表主外键关联,无法创建主外键约束

alter table C_CLIENT_VIP
  add constraint FK_STC_STORE foreign key (ST_OPENCARDSTORE_ID)
  references C_STORE (ID) on delete set null;--设置主外键关系名FK_STC_STORE 当删除门店数据后,就将ST_OPENCARDSTORE_ID设置为null(空)

请求参数
百度,也查不出来,真的坑爹。。。继续无限查问题中。。。。。

能改的都改了,找了很久很久,OK,原来会员表的ST_OPENCARDSTORE_ID有部分数据外键值为0,排查发现0不在主键表的ID中,所以创建主外键时候,0无法在主键表的ID中找到,将ST_OPENCARDSTORE_ID设置为null

update C_CLIENT_VIP set ST_OPENCARDSTORE_ID=null where id=19088

再次执行,成功了!

猜你喜欢

转载自blog.csdn.net/qq_34739564/article/details/82014886