今天的文章分为两部分,一个是今天做完的部分修改,一部份是参赛感想
我目前规划做到的部分大概先暂时到从Line进行完整的购物流程,亦即
这部分在今天继续更新一些功能上的修改
现在会拒绝库存不足的品项加入购物车
def Control_Shopping_Cart_ViaMessageText(uid, user_type_text):
split_text = user_type_text.split(' ')
if(len(split_text) > 3):return "错误的购物车指令\ncart \{要加入或变更的产品ID\} \{该产品的数量\}\n输入数字不需要大括弧\{\}"
if(not split_text[1].isnumeric()):return "请输入罗马数字的产品ID"
scid = dbpm.INS_QUY_SC(uid)
if((split_text[2][0] == '+' or split_text[2][0] == '-') and split_text[2][1:].isnumeric()):
num = int(split_text[2])
new_qt = dbpm.QUY_Shopping_Cart_item_Quantity(split_text[1], scid) + num
elif(split_text[2].isnumeric()):
new_qt = int(split_text[2])
else:
return "请直接输入订购数量的罗马数字,或是+/-符号加数字"
if(new_qt < 0):
new_qt = 0
# app.logger.debug(f"{split_text[1]}, {new_qt}")
p_name, p_price = dbpm.QUY_Prod_Name_and_Price_by_pid(split_text[1])
current_quantity = dbpm.QUY_Prod_Quantity_by_pid(split_text[1])
if(current_quantity >= new_qt):
dbpm.INS_UPD_Prod_to_Cart(scid, split_text[1], new_qt)
if(new_qt == 0):
dbpm.DEL_Shopping_Cart_items(scid)
return f"已将{p_name}自购物车中删除"
else:
return f"已将{p_name}(单价:{p_price})的购买数量设定为{new_qt}"
else:
return f"{p_name}目前的库存不足,无法加入购物车"
现在付款ID不会再绑定订单,在付款成功前,使用者可以切换用什麽付款,以及加入库存更新 & 购物车内物品库存检查,建立订单流程:
# Server.py
elif(datapath == "action=buy"):
if(not datavalue):
isSucc, scidormsg = Handler.MakeOrder_1_Check_Cart(event.source.user_id)
app.logger.debug(f"建立订单-检查购物车, {isSucc}, {scidormsg}")
if(isSucc):
isSucc, oidormsg = Handler.MakeOrder_2_Create_Order(scidormsg, event.source.user_id)
if(isSucc):
template_msg = APIModel.OrderPaySelTemp(scidormsg, oidormsg)
line_bot_api.reply_message(
event.reply_token,
template_msg
)
else:
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=oidormsg)
)
else:
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=scidormsg)
)
else:
oid = datavalue.get('oid')[0]
scid = datavalue.get('scid')[0]
paytype = datavalue.get('paytype')[0]
app.logger.debug(f"订单:{oid}(scid:{scid}), 选择付款方式:{paytype}")
if(oid and scid and paytype):
isSucc, msg = Handler.MakeOrder_3_Request_Pay(oid, scid, paytype)
if(isSucc):
if(paytype == "1"):
app.logger.debug(f"银行转帐(ATM)付款资讯:{msg}")
elif(paytype == "2"):
app.logger.debug(f"信用卡付款资讯:{msg}")
template_msg = APIModel.OrderPayURLTemp(msg)
line_bot_api.reply_message(
event.reply_token,
template_msg
)
else:
line_bot_api.reply_message(
event.reply_token,
TextSendMessage(text=msg)
)
else:
app.logger.debug("建立订单时参数错误", datavalue)
# OrderHandler.py
def MakeOrder_1_Check_Cart(uid):
scid = dbpm.INS_QUY_SC(uid)
isSucc, msg = CheckQuantity(scid)
if(isSucc):
dbpm.UPD_Shopping_Cart_lock_bY_scid(True, scid)
return True, scid
else:
return False, msg
def CheckQuantity(scid):
shopping_list = dbpm.QUY_Shopping_Cart_by_scid(scid)
if(not shopping_list):
return False, "购物车内没有商品喔"
for prod in shopping_list:
current_quantity = dbpm.QUY_Prod_Quantity_by_pid(prod[0])
if(current_quantity - prod[1] < 0):
dbpm.INS_UPD_Prod_to_Cart(scid, prod[0], current_quantity)
dbpm.DEL_Shopping_Cart_items(scid)
app.logger.warn(f"商品{prod[0]},库存不足无法满足订单需求数量({prod[1]})")
return False, "部分商品库存不足,请稍後重试"
return True, None
def MakeOrder_2_Create_Order(scid, uid):
try:
oid = dbpm.INS_Order(uid, scid, ostatus="初始化订单")
return True, oid
except ExecError as Err:
app.logger.error(scid, uid, Err)
return False, f"建立订单时发生错误\n{Err}"
def MakeOrder_3_Request_Pay(oid, scid, paytype):
if(Check_order_ispaid(oid)):return False, "该笔订单已完成付款"
shopping_list = dbpm.QUY_Shopping_Cart_by_scid(scid)
amount = 0
msg = None
for cart_item in shopping_list:
product_name, product_price = dbpm.QUY_Prod_Name_and_Price_by_pid(cart_item[0])
amount = amount + product_price * cart_item[1]
if(paytype == "1"):
# ATM
expiredate = (datetime.now() + timedelta(days = 1)).strftime("%Y%m%d")
paid = dbpm.INS_payment_req('ATM', amount)
neworder = APIModel.ReqOrderCreate(ShopNo=os.environ['ShopNo'], OrderNo=paid, Amount=amount*100, \
PrdtName='IT铁人赛虚拟商店', Param1=oid, ReturnURL=os.environ['ReturnURL'], BackendURL=os.environ['BackendURL'], PayType="A", ExpireDate=expiredate)
msg = GenApi.OrderCreate(neworder)
app.logger.debug(f"MakeOrder:{msg}")
elif(paytype == "2"):
# 信用卡一次付清
paid = dbpm.INS_payment_req('C-1', amount)
neworder = APIModel.ReqOrderCreate(ShopNo=os.environ['ShopNo'], OrderNo=paid, Amount=amount*100, \
PrdtName='IT铁人赛虚拟商店', Param1=oid, ReturnURL=os.environ['ReturnURL'], BackendURL=os.environ['BackendURL'], PayType="C")
msg = GenApi.OrderCreate(neworder)
app.logger.debug(f"MakeOrder:{msg}")
if(msg):
if(msg.Status == 'S'):
dbpm.UPD_payment_bypaid(paid=paid, tsno=msg.TSNo, ts_decp=msg.Description, ts_status=True, cardpayurl=msg.CardParam.CardPayURL)
dbpm.UPD_Order_by_oid(paid=paid, ostatus="已产生付款请求", oid=oid)
isSucc, errmsg = UpdateQuantity(shopping_list)
if(isSucc):
return True, msg
else:
return False, errmsg
else:
dbpm.UPD_payment_bypaid(paid=paid, tsno=msg.TSNo, ts_decp=msg.Description, ts_status=False)
dbpm.UPD_Order_by_oid(paid=paid, ostatus="产生付款请求失败", oid=oid)
errmsg = f"与金流系统通讯时发生错误,{msg.Description}"
dbpm.UPD_Shopping_Cart_lock_bY_scid(False, scid)
return False, errmsg or "建立付款请求时发生错误"
付款通知的外层的Status只是讯息传送的Status,与付款相关的参数都在TSResultContent,所以会出现外层Status是成功,内部却是失败的情况,修改API解析参数调用
def OrderPayQueryHandler(resp:APIModel.ResOrderPayQuery, line_bot_api:LineBotApi):
app.logger.debug(f"ResOrderPayQuery:{resp}")
payinfo = resp.TSResultContent
if(payinfo.Status != 'S'):
dbpm.UPD_payment_bytsno(ispaid=False, paytoken=resp.PayToken, tsno=payinfo.TSNo, aptype=payinfo.APType)
app.logger.info(f"订单{payinfo.Param1}付款失败, 付款编号:{payinfo.OrderNo} - {payinfo.Description}")
uid = dbpm.UPD_Order_status_by_paid(ostatus=f"付款失败-{payinfo.Description}", paid = payinfo.OrderNo)
line_bot_api.push_message(uid, TextSendMessage(text=f"您的订单: {payinfo.Param1} 付款失败,原因可能为:\n{payinfo.Description}"))
else:
dbpm.UPD_payment_bytsno(ispaid=True, paytoken=resp.PayToken, tsno=payinfo.TSNo, aptype=payinfo.APType)
app.logger.info(f"订单{payinfo.Param1}付款成功, 付款编号:{payinfo.OrderNo} - {payinfo.Description}")
uid = dbpm.UPD_Order_status_by_paid(ostatus=f"付款成功-{payinfo.Description}", paid = payinfo.OrderNo)
line_bot_api.push_message(uid, TextSendMessage(text=f"您的订单: {payinfo.Param1} 付款成功罗"))
依购物车更新库存从建立订单时变更,改为付款成功後才变更,比较符合常见的库存逻辑
def UpdateQuantity(shopping_list, mode = 1):
if(shopping_list):
try:
if(mode):
for prod in shopping_list:
current_quantity = dbpm.QUY_Prod_Quantity_by_pid(prod[0])
new_quantity = current_quantity - prod[1]
dbpm.UPD_Prod_Quantity(prod[0], new_quantity)
# app.logger.debug(f"pid:{prod[0]}, oldqt:{current_quantity}, newqt:{new_quantity}")
else:
for prod in shopping_list:
current_quantity = dbpm.QUY_Prod_Quantity_by_pid(prod[0])
new_quantity = current_quantity + prod[1]
dbpm.UPD_Prod_Quantity(prod[0], new_quantity)
return True, None
except Exception as err:
return False, err
return False, f"shopping_list:{shopping_list}"
30天,铁腿了0rz
老实说参赛最初的构想是摩斯卡App,谁知道後来变成Line订餐机器人,只能说灵感就是这样,因为中期想了一堆有的没的的新功能,结果做不完哈哈
本次铁人赛,摸了一堆以前完全没玩过的框架与功能需求,主要有
其实最後一天还在想能加什麽功能,但想到BUG很多就还是赶紧改好品质更新,以下为想做却还没做的残念部分:
功能 | 说明 | 大概的构想 |
---|---|---|
使用者教学 | 如何使用系统 | 拍摄影片或是给使用者一组测试的资料可供输入 |
查询订单 | 显示近期订单 | 分为一般使用者与管理人员两种介面 |
优化显示 | Flex message | 现在的介面太丑啦 |
网页端的後台 | 控制库存、出货 | 目前订单系统只写了半套,还有一堆功能如出货,订单管理,之类的.....梦想太大 |
2021铁人赛暂时先到这边告一段落,如果有问题,欢迎留言给我喔
Line机器人官方帐号ID:@171ssmku
<<: day27_ARM 在 Server 领域的发展 (下)
>>: Day28:今天来聊一下Hacking Cloud Computing
Web 1. GET aHEAD 打开网页原始码发现目前有两个选项"GET"、&...
声音这东西实在是太自然了,所以我们很少去思考这东西的本质到底是什麽 简单的来复习一下声音是什麽,你...
在 Kubernetes 中元件间的通讯都是藉由 API Server 通讯,而 API Serve...
1. API? 应用程序介面 图形库中的一组API定义了绘制指标的方式,可於图形输出装置上显示指标。...
常常有人说做好一个企划需要勇气,但绝非这麽简单,创业不只需要勇气还需要运气、人脉、实力 、执着 做好...