def __fill_approval(self, pt, start, content, **kwargs): if pt.PTid == 'tocash': return self.__fill_cash(start, content, **kwargs) elif pt.PTid == 'toagent': return self.__fill_agent(start, content) elif pt.PTid == 'toshelves': return self.__fill_shelves(start, content) elif pt.PTid == 'topublish': return self.__fill_publish(start, content) elif pt.PTid == 'toguessnum': return self.__fill_guessnum(start, content) elif pt.PTid == 'tomagicbox': return self.__fill_magicbox(start, content) elif pt.PTid == 'tofreshmanfirstproduct': return self.__fill_freshmanfirstproduct(start, content) elif pt.PTid == 'totrialcommodity': return self.__fill_trialcommodity(start, content) elif pt.PTid == 'toreturn': # todo 退货申请目前没有图 raise ParamsError('退货申请前往订单页面实现') elif pt.PTid == 'toactivationcode': return self.__fill_activationcode(start, content) elif pt.PTid == 'tosettlenment': return self.__fill_settlenment(start, content) else: raise ParamsError('参数异常, 请检查审批类型是否被删除。如果新增了审批类型,请联系开发实现后续逻辑')
def update(self): data = parameter_required(('gbid', )) gb = GroupBuying.query.filter( GroupBuying.isdelete == False, GroupBuying.GBid == data.get('gbid')).first_('该活动已删除') with db.auto_commit(): starttime, endtime = self._check_time( data.get('starttime') or str(gb.GBstarttime), data.get('endtime') or str(gb.GBendtime)) gb.GBendtime = endtime gb.GBstarttime = starttime gb.GBstatus = GroupBuyingStatus.wait_check.value if data.get('delete'): self._delete_gb(gb) if data.get('gbnum'): if not self._check_pint(data.get('gbnum')): raise ParamsError('gbnum 格式错误') gb.GBnum = data.get('gbnum') if data.get('gbtimes'): if not self._check_pint(data.get('gbtimes')): raise ParamsError('gbtimes 格式错误') gb.GBtimes = data.get('gbtimes') if data.get('prid') or data.get('gpfreight') or data.get( 'gpstocks') or data.get('skus'): self._update_groupbuying_product(data, gb) return Success('更新成功')
def update_category(self): """更新/删除分类""" self._check_user(request.user.id) data = parameter_required(('mcid', 'mcname', 'mctype')) mcid, mctype, mcsort = data.get('mcid'), data.get( 'mctype', 0), data.get('mcsort') mcisdelete = data.get('mcisdelete') category = MaterialCategory.query.filter_by_( MCid=mcid).frist_('要修改的分类不存在') if mctype == CategoryType.material.value: if mcid in [ 'case_community', 'knowledge_classroom', 'disease_treatment', 'health_encyclopedia', 'hot_topic' ]: raise ParamsError('系统内置分类不允许更改') mcsort = self._check_sort(mctype, mcsort, category.MCparentid) if category.MClevel == 1: raise ParamsError('该层分类不允许修改') update_dict = { 'MCname': data.get('mcname'), 'MCsort': mcsort, } if category.MCparentid == 'hot_topic': update_dict['MCpicture'] = data.get('mcpicture') update_dict['MCdesc'] = data.get('mcdesc') with db.auto_commit(): if mcisdelete: category.update({'isdelete': True}) else: category.update(update_dict) db.session.add(category) return Success('修改成功', data=dict(MCid=mcid))
def create(self): data = parameter_required(('pcdesc', 'pcname', 'pcpic')) pcdesc = data.get('pcdesc') pcname = data.get('pcname') pcpic = data.get('pcpic') parentpcid = data.get('parentpcid') pcsort = data.get('pcsort', 1) if not isinstance(pcsort, int): raise ParamsError('pcsort 类型错误') if not parentpcid: pctype = 1 else: # parent_catory = self._get_category_one(parentpcid, '指定父级目录不存在') parent_catory = ProductCategory.query.filter( ProductCategory.PCid == parentpcid, ProductCategory.isdelete == False).first_('指定父级目录不存在') pctype = parent_catory.PCtype + 1 pcsort = self._check_sort(pctype, pcsort, parentpcid) with db.auto_commit() as s: category_instance = ProductCategory.create({ 'PCid': str(uuid.uuid4()), 'PCtype': pctype, 'PCname': pcname, 'PCdesc': pcdesc, 'ParentPCid': parentpcid, 'PCpic': pcpic, 'PCsort': pcsort, 'PCtopPic': data.get('pctoppic') }) s.add(category_instance) return Success('创建成功', {'pcid': category_instance.PCid})
def guess_search(self): """推荐搜索""" data = parameter_required(('kw', 'shtype')) shtype = data.get('shtype') if shtype not in ['product', 'news']: raise ParamsError('shtype, 参数错误') shtype = getattr(UserSearchHistoryType, shtype, 'product').value kw = data.get('kw').strip() if not kw: raise ParamsError() search_words = UserSearchHistory.query.filter( UserSearchHistory.USHtype == shtype, UserSearchHistory.USHname.like(kw + '%'), ).order_by(UserSearchHistory.createtime.desc()).all_with_page() [sw.hide('USid', 'USHid') for sw in search_words] return Success(data=search_words)
def __get_approvalcontent(self, pt, startid, avcontentid, **kwargs): start, content = self.__fill_approval(pt, startid, avcontentid, **kwargs) gennerc_log('get start {0} content {1}'.format(start, content)) if not (start or content): raise ParamsError('审批流创建失败,发起人或需审批内容已被删除') return start, content
def create(self): data = parameter_required(('pcid', 'pasort', 'paimg')) self._check_pcid(data.get('pcid')) pasort = data.get('pasort') # assert isinstance(pasort, int), 'pasort 类型错误' if not isinstance(pasort, int): raise ParamsError('类型错误') pasort = self._check_pasort(pasort) productarea_instance = ProductArea.create({ 'PAid': str(uuid.uuid1()), 'PCid': data.get('pcid'), 'PAstatus': ProductAreaStatus.wait.value, 'PAdesc': data.get('padesc'), 'PAsort': pasort, 'PAimg': data.get('paimg'), }) with db.auto_commit(): db.session.add(productarea_instance) return Success(data=productarea_instance.PAid)
def approve_comment(self): """处理评论 置顶/删除/通过/驳回""" self._check_admin(request.user.id) data = parameter_required(('mcoid', 'operation')) mcoid = data.get('mcoid') operation = data.get('operation') if operation not in ['top', 'del', 'pass', 'reject']: raise ParamsError('operation参数错误') with db.auto_commit(): mco = MaterialComment.query.filter_by_( MCOid=mcoid).first_('该评论不存在') if str(operation) == 'top': opt_dict = {'MCOistop': True} MaterialComment.query.filter( MaterialComment.MTid == mco.MTid, MaterialComment.MCOid != mco.MCOid, MaterialComment.isdelete == False).update( {'MCOistop': False}) # 只有一个置顶 elif str(operation) == 'del': opt_dict = {'isdelete': True} elif str(operation) == 'pass': opt_dict = {'MCOstatus': MaterialCommentStatus.usual.value} else: opt_dict = {'MCOstatus': MaterialCommentStatus.reject.value} mco.update(opt_dict) db.session.add(mco) return Success('修改成功', data=dict(mcoid=mcoid))
def update(self): data = parameter_required(('paid', )) with db.auto_commit(): productarea = ProductArea.query.filter( ProductArea.PAid == data.get('paid')).first_('专题已取消') if data.get('delete'): productarea.isdelete = True return Success('删除成功') if data.get('pastatus'): # if re.match(r'^-?\d+$', str(data.get('pastatus'))): if self._check_int(data.get('pastatus')): # ProductAreaStatus. try: productarea.PAstatus = ProductAreaStatus( int(data.get('pastatus'))).value except Exception as e: current_app.logger.info( 'pastatus {} 违法 error msg {}'.format( data.get('pastatus'), e.args)) raise ParamsError('pastatus 参数违法') if data.get('pcid'): self._check_pcid(data.get('pcid')) productarea.PCid = data.get('pcid') if data.get('pasort'): productarea.PAsort = self._check_pasort(data.get('pasort')) if data.get('paimg'): productarea.PAimg = data.get('paimg') return Success('更新成功')
def join(self): """用户加入拼团""" user = get_current_user() data = parameter_required(('giid', )) gu = GroupbuyingUser.query.join( GroupbuyingItem, GroupbuyingItem.GIid == GroupbuyingUser.GIid).filter( GroupbuyingItem.isdelete == False, GroupbuyingUser.isdelete == False, GroupbuyingItem.GIstatus == GroupbuyingItemStatus.underway.value, GroupbuyingUser.USid == user.USid, GroupbuyingUser.GIid == data.get('giid')).first() if gu: raise ParamsError('账号已经在队伍里了') gi = GroupbuyingItem.query.filter( GroupbuyingItem.isdelete == False, GroupbuyingItem.GIid == data.get('giid')).first_('该拼团已结束') now = datetime.datetime.now() gb = GroupBuying.query.filter( GroupBuying.GBstarttime <= now, GroupBuying.GBendtime >= now, GroupBuying.GBid == gi.GBid, GroupBuying.isdelete == False).first_('活动已结束') gus = GroupbuyingUser.query.filter( GroupbuyingUser.GIid == gi.GIid, GroupbuyingUser.isdelete == False).all() if len(gus) >= int(gb.GBnum): raise ParamsError('队伍已经满了,选择另外一个队伍吧') # gu_times = GroupbuyingUser.query.join(GroupbuyingItem, GroupbuyingItem.GIid == GroupbuyingUser.GIid).join( # GroupBuying, GroupBuying.GBid == GroupbuyingItem.GBid).filter( # GroupbuyingUser.USid == user.USid, GroupBuying.GBid == data.get('gbid')).count() # if gu_times >= gb.GBtimes: # raise ParamsError('超过限购次数') self._check_bgtimes(gb.GBid, user.USid, gb.GBtimes) with db.auto_commit(): gu = GroupbuyingUser.create({ 'GUid': str(uuid.uuid1()), 'GIid': data.get('giid'), 'USid': user.USid, 'UShead': user.USheader, 'USname': user.USname }) db.session.add(gu) if int(gb.GBnum) - len(gus) == 1: gi.GIstatus = GroupbuyingItemStatus.success.value return Success('加入成功')
def _check_time(self, starttimestr, endtimestr): # todo 截止时间校验 now = datetime.datetime.now() try: starttime = datetime.datetime.strptime(starttimestr, '%Y-%m-%d %H:%M:%S') endtime = datetime.datetime.strptime(endtimestr, '%Y-%m-%d %H:%M:%S') if starttime < endtime and now < endtime: return starttime, endtime except Exception as e: current_app.logger.info( '转置时间错误 starttime is {} endtime is {} error msg is {}'.format( starttimestr, endtimestr, e.args)) raise ParamsError('起止时间非法') raise ParamsError('起止时间非法')
def _add_groupbuying_product(self, data, product, gbid): instance_list = [] self._check_price(data.get('gpprice')) gpid = str(uuid.uuid1()) gp_stock = 0 # error_list = [] for sku in data.get('skus'): sku_model = ProductSku.query.filter( ProductSku.isdelete == False, ProductSku.SKUid == sku.get('skuid')).first() if not sku_model or sku.get('skugpstock') > sku_model.SKUstock: current_app.logger.info('{} 已删除或库存不足'.format(sku)) raise ParamsError('该sku 库存不足') gs_instance = GroupbuyingSku.create({ 'GSid': str(uuid.uuid1()), 'GPid': gpid, 'SKUid': sku.get('skuid'), 'PRid': product.PRid, 'SKUgpPrice': sku.get('skugpprice'), 'SKUgpStock': sku.get('skugpstock') }) sku_model.SKUstock -= sku.get('skugpstock') gp_stock += gs_instance.SKUgpStock instance_list.append(gs_instance) # 校验库存 self._check_stocks(gp_stock, product) product.PRstocks -= gp_stock gp_instance = GroupbuyingProduct.create({ 'GPid': gpid, 'GBid': gbid, 'PRid': product.PRid, 'PRtitle': product.PRtitle, 'GPprice': data.get('gpprice'), 'GPfreight': data.get('gpfreight'), 'GPstocks': gp_stock, }) instance_list.append(gp_instance) return instance_list
def upload_img(self): self.check_file_size() file = request.files.get('file') data = parameter_required() folder = self.allowed_folder(data.get('type')) if not file: raise ParamsError(u'上传有误') file_data = self._upload_file(file, folder) return Success('上传成功', data=file_data[0]).get_body(video_thum=file_data[1], video_dur=file_data[2], upload_type=file_data[3])
def create_category(self): """创建分类""" self._check_admin(request.user.id) data = parameter_required(( 'mcname', 'mctype', )) mctype = data.get('mctype', 0) mcsort = data.get('mcsort') mcparentid = data.get('mcparentid') with db.auto_commit(): if mctype == CategoryType.material.value: if not mcparentid: raise ParamsError('mcparentid 不能为空') parent_category = MaterialCategory.query.filter_by_( MCid=mcparentid).first_('上级分类不存在') if parent_category.MCid == 'knowledge_classroom': raise ParamsError('不允许在该层下创建分类') # 知识课堂下不允许创建二级分类 mcsort = self._check_sort(mctype, mcsort, mcparentid) category_dict = { 'MCid': str(uuid.uuid1()), 'MCname': data.get('mcname'), 'MCparentid': mcparentid, 'MClevel': parent_category.MClevel + 1, 'MCsort': mcsort, 'MCtype': mctype } if category_dict['MClevel'] > 3: raise ParamsError('超出分类最高层级') if mcparentid == 'hot_topic': # 热门话题有简介 和 图片 category_dict['MCpicture'] = data.get('mcpicture') category_dict['MCdesc'] = data.get('mcdesc') else: category_dict = { 'MCid': str(uuid.uuid1()), 'MCname': data.get('mcname'), 'MClevel': 1, 'MCsort': mcsort, 'MCtype': mctype } category_instance = MaterialCategory.create(category_dict) db.session.add(category_instance) return Success('创建成功', data=dict(MCid=category_dict['MCid']))
def _send_sms_ali(self, mobiles, tpl_params): sign_name = SignName params_lst = self.params(mobiles, tpl_params, sign_name) eps = self.encode_params(params_lst) prepare_str = self.prepare_sign(eps) sign_str = self.sign(prepare_str) url = "{0}Signature={1}&{2}".format(self.prefix_url, sign_str, eps) r = requests.get(url) if r.status_code != 200: raise ParamsError('短信验证获取失败') else: jn = json.loads(r.text) gennerc_log('get sms response : {0}'.format(jn)) if jn.get("Code") == "OK": return True else: raise ParamsError('短信验证获取失败')
def delete(self): data = parameter_required(('prids', )) prids = data.get('prids') if not isinstance(prids, list): raise ParamsError('prids 参数异常') with db.auto_commit(): Products.query.filter( Products.isdelete == False, Products.PRid.in_(prids)).delete_(synchronize_session=False) return Success('删除成功')
def off_shelves(self): """下架""" data = parameter_required(('prids', )) if not isinstance(data.get('prids'), list): raise ParamsError('数据异常') with db.auto_commit(): product = Products.query.filter( Products.PRid.in_(data.get('prids')), Products.isdelete == False).first_('商品不存在') product.PRstatus = ProductStatus.off_shelves.value return Success('下架成功')
def _check_bgtimes(self, gbid, usid, times): gu_times = GroupbuyingUser.query.join( GroupbuyingItem, GroupbuyingItem.GIid == GroupbuyingUser.GIid).join( GroupBuying, GroupBuying.GBid == GroupbuyingItem.GBid).filter( GroupbuyingUser.GUstatus >= GroupbuyingUserStatus.waitpay.value, GroupbuyingItem.GIstatus <= GroupbuyingItemStatus.cancel.value, GroupbuyingUser.USid == usid, GroupBuying.GBid == gbid).count() if gu_times >= times: raise ParamsError('已超出限购次数')
def create(self): data = parameter_required(('starttime', 'endtime', 'gbnum', 'prid', 'gpprice', 'skus', 'gbtimes')) starttime, endtime = self._check_time(data.get('starttime'), data.get('endtime')) if not self._check_pint(data.get('gbnum')): raise ParamsError('gbnum 格式错误') if not self._check_pint(data.get('gbtimes')): raise ParamsError('gbtimes 格式错误') product = Products.query.filter( Products.isdelete == False, Products.PRid == data.get('prid'), Products.PRstatus == ProductStatus.usual.value).first_('商品未上架') # todo 校验商品不在同一时间的其他活动里 self._check_product(data.get('prid'), starttime, endtime) with db.auto_commit(): instance_list = [] gb_instance = GroupBuying.create({ 'GBid': str(uuid.uuid1()), 'GBstarttime': starttime, 'GBendtime': endtime, 'GBnum': data.get('gbnum'), 'GBtimes': data.get('gbtimes'), 'GBstatus': GroupBuyingStatus.wait_check.value }) instance_list.append(gb_instance) instance_list.extend( self._add_groupbuying_product(data, product, gb_instance.GBid)) db.session.add_all(instance_list) return Success('申请成功')
def _check_pasort(self, pasort): # if not re.match(r'^-?\d+$', str(pasort)): if not self._check_int(pasort): raise ParamsError('pasort 类型异常') pasort = int(str(pasort)) if pasort < 1: return 1 pacount = ProductArea.query.filter( ProductArea.isdelete == False, ProductArea.PAstatus == ProductAreaStatus.normal.value).count() if pasort > pacount: return pacount return pasort
def del_search_history(self): """清空当前搜索历史""" if not is_tourist(): data = parameter_required(('shtype', )) shtype = data.get('shtype') if shtype not in ['product', 'news']: raise ParamsError('shtype, 参数错误') shtype = getattr(UserSearchHistoryType, shtype, 'product').value usid = request.user.id with db.auto_commit() as s: s.query(UserSearchHistory).filter_by({ 'USid': usid, 'USHtype': shtype }).delete_() return Success('删除成功')
def search_history(self): """"搜索历史""" if not is_tourist(): args = parameter_required(('shtype', )) shtype = args.get('shtype') if shtype not in ['product', 'news']: raise ParamsError('shtype, 参数错误') shtype = getattr(UserSearchHistoryType, shtype, 'product').value usid = request.user.id search_history = UserSearchHistory.query.filter( UserSearchHistory.USid == usid, UserSearchHistory.USHtype == shtype, UserSearchHistory.isdelete == False, ).order_by(UserSearchHistory.createtime.desc()).all_with_page() else: search_history = [] return Success(data=search_history)
def _check_product(self, prid, starttime, endtime, gpid=None): """校验该商品是否重复提交活动""" # 拼团 filter_args = { GroupBuying.isdelete == False, or_(GroupBuying.GBstarttime < endtime, GroupBuying.GBendtime > starttime), GroupbuyingProduct.isdelete == False, GroupbuyingProduct.PRid == prid } if gpid: filter_args.add(GroupbuyingProduct.GPid != gpid) gb = GroupBuying.query.join( GroupbuyingProduct, GroupbuyingProduct.GBid == GroupBuying.GBid).filter( *filter_args).first() if gb: raise ParamsError('该商品已经参与拼团') return True
def batch_upload(self): self.check_file_size() files = request.files.to_dict() if len(files) > 9: raise ParamsError('最多可同时上传9张图片') # todo 视频数量限制 data = parameter_required() folder = self.allowed_folder(data.get('type')) file_url_list = [] for file in files.values(): upload_file = self._upload_file(file, folder) file_dict = { 'file_url': upload_file[0], 'video_thum': upload_file[1], 'video_dur': upload_file[2], 'upload_type': upload_file[3] } file_url_list.append(file_dict) return Success('上传成功', file_url_list)
def _sub_category(self, category, deep, parent_ids=()): """遍历子分类""" parent_ids = list(parent_ids) try: deep = int(deep) except TypeError as e: raise ParamsError() if deep <= 0: del parent_ids return deep -= 1 pcid = category.PCid if pcid not in parent_ids: # subs = self.sproduct.get_categorys({'ParentPCid': pcid}) subs = ProductCategory.query.filter( ProductCategory.ParentPCid == pcid, ProductCategory.isdelete == False).all() if subs: parent_ids.append(pcid) category.fill('subs', subs) for sub in subs: self._sub_category(sub, deep, parent_ids)
def pay(self): """订单发起支付""" data = parameter_required(('omid', )) omid = data.get('omid') usid = request.user.id try: omclient = int(data.get('omclient', Client.wechat.value)) # 客户端(app或者微信) Client(omclient) opaytype = int(data.get('opaytype', PayType.wechat_pay.value)) # 付款方式 PayType(opaytype) except ValueError as e: raise e except Exception as e: raise ParamsError('客户端或支付方式类型错误') from bechi.control.CUser import CUser cuser = CUser() with db.auto_commit(): opayno = self.wx_pay.nonce_str order_main = OrderMain.query.filter_by_({ 'OMid': omid, 'USid': usid, 'OMstatus': OrderMainStatus.wait_pay.value }).first_('不存在的订单') # 原支付流水删除 OrderPay.query.filter_by({'OPayno': order_main.OPayno}).delete_() # 更改订单支付编号 order_main.OPayno = opayno # 判断订单是否是开店大礼包 # 是否是开店大礼包 if order_main.OMlogisticType == OMlogisticTypeEnum.online.value: cuser = CUser() cuser._check_gift_order('重复购买开店大礼包') db.session.add(order_main) # 新建支付流水 order_pay_instance = OrderPay.create({ 'OPayid': str(uuid.uuid1()), 'OPayno': opayno, 'OPayType': opaytype, 'OPayMount': order_main.OMtrueMount }) # 付款时候的body信息 order_parts = OrderPart.query.filter_by_({'OMid': omid}).all() body = ''.join([getattr(x, 'PRtitle', '') for x in order_parts]) db.session.add(order_pay_instance) user = User.query.filter(User.USid == order_main.USid).first() pay_args = self._pay_detail(omclient, opaytype, opayno, float(order_main.OMtrueMount), body, openid=user.USopenid1 or user.USopenid2) response = { 'pay_type': PayType(opaytype).name, 'opaytype': opaytype, 'args': pay_args } return Success('生成付款参数成功', response)
def update_product(self): """更新商品""" data = parameter_required(('prid', )) # product_from = ProductFrom.platform.value prid = data.get('prid') pbid = data.get('pbid') # 品牌id pcid = data.get('pcid') # 分类id images = data.get('images') skus = data.get('skus') prdescription = data.get('prdescription') if data.get('prsalesvaluefake'): # if not re.match(r'^\d+$', str(data.get('prsalesvaluefake'))): if not self._check_pint(data.get('prsalesvaluefake')): raise ParamsError('虚拟销量数据异常') else: data['prsalesvaluefake'] = 0 with db.auto_commit(): session_list = [] # 商品 prattribute = data.get('prattribute') product = Products.query.filter_by_({'PRid': prid}).first_('商品不存在') prmarks = data.get('prmarks') # 备注 if prmarks: try: prmarks = json.dumps(prmarks) if not isinstance(prmarks, dict): raise TypeError except Exception as e: pass if pcid: product_category = ProductCategory.query.filter( ProductCategory.PCid == pcid, ProductCategory.isdelete == False).first_('指定目录不存在') # sku, 有skuid为修改, 无skuid为新增 if skus: new_sku = [] sku_ids = [] # 此时传入的skuid prstock = 0 for index, sku in enumerate(skus): skuattritedetail = sku.get('skuattritedetail') if not isinstance( skuattritedetail, list) or len(skuattritedetail) != len(prattribute): raise ParamsError('skuattritedetail与prattribute不符') skuprice = int(sku.get('skuprice', 0)) skustock = int(sku.get('skustock', 0)) assert skuprice > 0 and skustock >= 0, 'sku价格或库存错误' # 更新或添加删除 if 'skuid' in sku: skuid = sku.get('skuid') sn = sku.get('skusn') # self._check_sn(sn=sn, skuid=skuid) sku_ids.append(skuid) sku_instance = ProductSku.query.filter_by({ 'SKUid': skuid }).first_('sku不存在') sku_instance.update({ 'SKUpic': sku.get('skupic'), 'SKUattriteDetail': json.dumps(skuattritedetail), 'SKUstock': int(skustock), 'SKUprice': sku.get('skuprice'), 'SKUsn': sn }) else: sku_instance = ProductSku.create({ 'SKUid': str(uuid.uuid1()), 'PRid': prid, 'SKUpic': sku.get('skupic'), 'SKUprice': round(skuprice, 2), 'SKUstock': int(skustock), 'SKUattriteDetail': json.dumps(skuattritedetail), 'SKUsn': sku.get('skusn'), }) new_sku.append(sku_instance) session_list.append(sku_instance) prstock += sku_instance.SKUstock # 剩下的就是删除 old_sku = ProductSku.query.filter( ProductSku.isdelete == False, ProductSku.PRid == prid, ProductSku.SKUid.notin_(sku_ids)).delete_( synchronize_session=False) current_app.logger.info( '删除了{}个不需要的sku, 更新了{}个sku, 添加了{}个新sku '.format( old_sku, len(sku_ids), len(new_sku))) prdesc = data.get('prdesc') product_dict = { 'PRtitle': data.get('prtitle'), 'PRprice': data.get('prprice'), 'PRlinePrice': data.get('prlineprice'), 'PRfreight': data.get('prfreight'), 'PRstocks': prstock, 'PRmainpic': data.get('prmainpic'), 'PCid': pcid, 'PBid': pbid, 'PRdesc': prdesc, 'PRattribute': json.dumps(prattribute), 'PRremarks': prmarks, 'PRdescription': prdescription, 'PRsalesValueFake': int(data.get('prsalesvaluefake')), 'PRstatus': ProductStatus.auditing.value, # 'PRfeatured': prfeatured, } product.update(product_dict) if product.PRstocks == 0: product.PRstatus = ProductStatus.sell_out.value session_list.append(product) # sku value pskuvalue = data.get('pskuvalue') if pskuvalue: if not isinstance(pskuvalue, list) or len(pskuvalue) != len( json.loads(product.PRattribute)): raise ParamsError('pskuvalue与prattribute不符') # todo skudetail校验 # sku_value表 exists_sku_value = ProductSkuValue.query.filter_by_({ 'PRid': prid }).first() if exists_sku_value: exists_sku_value.update( {'PSKUvalue': json.dumps(pskuvalue)}) session_list.append(exists_sku_value) else: sku_value_instance = ProductSkuValue.create({ 'PSKUid': str(uuid.uuid1()), 'PRid': prid, 'PSKUvalue': json.dumps(pskuvalue) }) session_list.append(sku_value_instance) else: sku_value_instance = ProductSkuValue.query.filter_by_({ 'PRid': prid, }).first() if sku_value_instance: # 默认如果不传就删除原来的, 防止value混乱, todo sku_value_instance.isdelete = True session_list.append(sku_value_instance) # images, 有piid为修改, 无piid为新增 if images: piids = [] new_piids = [] for image in images: if 'piid' in image: # 修改 piid = image.get('piid') piids.append(piid) image_instance = ProductImage.query.filter_by({ 'PIid': piid }).first_('商品图片信息不存在') else: # 新增 piid = str(uuid.uuid1()) image_instance = ProductImage() new_piids.append(piid) image_dict = { 'PIid': piid, 'PRid': prid, 'PIpic': image.get('pipic'), 'PIsort': image.get('pisort'), 'isdelete': image.get('isdelete') } image_instance.update(image_dict) session_list.append(image_instance) # 删除其他 delete_images = ProductImage.query.filter( ProductImage.isdelete == False, ProductImage.PIid.notin_(piids), ProductImage.PRid == prid, ).delete_(synchronize_session=False) current_app.logger.info('删除了{}个图片, 修改了{}个, 新增了{}个 '.format( delete_images, len(piids), len(new_piids))) db.session.add_all(session_list) return Success('更新成功')
def add_product(self): # if is_admin(): product_from = ProductFrom.platform.value # else: # raise AuthorityError() data = parameter_required(('pcid', 'prtitle', 'prprice', 'prattribute', 'prmainpic', 'prdesc', 'images', 'skus')) pbid = data.get('pbid') # 品牌id pcid = data.get('pcid') # 3级分类id images = data.get('images') skus = data.get('skus') # prfeatured = data.get('prfeatured', False) prdescription = data.get('prdescription') # 简要描述 # PCtype 是表示分类等级, 该系统只有两级 product_category = ProductCategory.query.filter( ProductCategory.PCid == pcid, ProductCategory.isdelete == False).first_('指定目录不存在') if data.get('prsalesvaluefake'): # if not re.match(r'^\d+$', str(data.get('prsalesvaluefake'))): if not self._check_pint(data.get('prsalesvaluefake')): raise ParamsError('虚拟销量数据异常') else: data['prsalesvaluefake'] = 0 prstocks = 0 with db.auto_commit() as s: session_list = [] # 商品 prattribute = data.get('prattribute') prid = str(uuid.uuid1()) prmarks = data.get('prmarks') # 备注 if prmarks: try: prmarks = json.dumps(prmarks) if not isinstance(prmarks, dict): raise TypeError except Exception: pass prdesc = data.get('prdesc') if prdesc: if not isinstance(prdesc, list): raise ParamsError('prdesc 格式不正确') # sku sku_detail_list = [] # 一个临时的列表, 使用记录的sku_detail来检测sku_value是否符合规范 for index, sku in enumerate(skus): sn = sku.get('skusn') # self._check_sn(sn=sn) skuattritedetail = sku.get('skuattritedetail') if not isinstance( skuattritedetail, list) or len(skuattritedetail) != len(prattribute): raise ParamsError('skuattritedetail与prattribute不符') sku_detail_list.append(skuattritedetail) skuprice = float(sku.get('skuprice')) skustock = int(sku.get('skustock')) assert skuprice > 0 and skustock >= 0, 'sku价格或库存错误' prstocks += int(skustock) sku_dict = { 'SKUid': str(uuid.uuid1()), 'PRid': prid, 'SKUpic': sku.get('skupic'), 'SKUprice': round(skuprice, 2), 'SKUstock': int(skustock), 'SKUattriteDetail': json.dumps(skuattritedetail), 'SKUsn': sn } sku_instance = ProductSku.create(sku_dict) session_list.append(sku_instance) # 商品 product_dict = { 'PRid': prid, 'PRtitle': data.get('prtitle'), 'PRprice': data.get('prprice'), 'PRlinePrice': data.get('prlineprice'), 'PRfreight': data.get('prfreight'), 'PRstocks': prstocks, 'PRmainpic': data.get('prmainpic'), 'PCid': pcid, 'PBid': pbid, 'PRdesc': prdesc, 'PRattribute': json.dumps(prattribute), 'PRremarks': prmarks, 'PRfrom': product_from, 'CreaterId': request.user.id, 'PRsalesValueFake': int(data.get('prsalesvaluefake')), 'PRdescription': prdescription, # 描述 # 'PRfeatured': prfeatured, # 是否为精选 } # 库存为0 的话直接售罄 if prstocks == 0: product_dict['PRstatus'] = ProductStatus.sell_out.value product_instance = Products.create(product_dict) session_list.append(product_instance) # sku value pskuvalue = data.get('pskuvalue') if pskuvalue: if not isinstance(pskuvalue, list) or len(pskuvalue) != len(prattribute): raise ParamsError('pskuvalue与prattribute不符') sku_reverce = [] for index in range(len(prattribute)): value = list( set([ attribute[index] for attribute in sku_detail_list ])) sku_reverce.append(value) # 对应位置的列表元素应该相同 if set(value) != set(pskuvalue[index]): raise ParamsError('请核对pskuvalue') # sku_value表 sku_value_instance = ProductSkuValue.create({ 'PSKUid': str(uuid.uuid1()), 'PRid': prid, 'PSKUvalue': json.dumps(pskuvalue) }) session_list.append(sku_value_instance) # images for image in images: image_dict = { 'PIid': str(uuid.uuid1()), 'PRid': prid, 'PIpic': image.get('pipic'), 'PIsort': image.get('pisort'), } image_instance = ProductImage.create(image_dict) session_list.append(image_instance) s.add_all(session_list) return Success('添加成功', {'prid': prid})
def video2frames( pathin, # 视频的路径 pathout, # 设定提取的图片保存在哪个文件夹下 only_output_video_info=False, # 如果为True,只输出视频信息(长度、帧数和帧率),不提取图片 extract_time_points=None, # 提取的时间点,单位为秒,为元组数据,如(2, 3, 5) initial_extract_time=0, # 提取的起始时刻,单位为秒,默认为0(即从视频最开始提取) end_extract_time=None, # 提取的终止时刻,单位为秒,默认为None(即视频终点) extract_time_interval=-1, # 提取的时间间隔,单位为秒,默认为-1(即输出时间范围内的所有帧) output_prefix='frame', # 图片的前缀名,默认为frame,图片的名称将为frame_000001.jpg jpg_quality=100, # 设置图片质量,范围为0到100,默认为100(质量最佳) iscolor=True): # 如果为False,输出的将是黑白图片 """ pathin:视频的路径,比如:F:\python_tutorials\test.mp4 pathout:设定提取的图片保存在哪个文件夹下,比如:F:\python_tutorials\frames1\。如果该文件夹不存在,函数将自动创建它 only_output_video_info:如果为True,只输出视频信息(长度、帧数和帧率),不提取图片 extract_time_points:提取的时间点,单位为秒,为元组数据,比如,(2, 3, 5)表示只提取视频第2秒, 第3秒,第5秒图片 initial_extract_time:提取的起始时刻,单位为秒,默认为0(即从视频最开始提取) end_extract_time:提取的终止时刻,单位为秒,默认为None(即视频终点) extract_time_interval:提取的时间间隔,单位为秒,默认为-1(即输出时间范围内的所有帧) output_prefix:图片的前缀名,默认为frame,图片的名称将为frame_000001.jpg、frame_000002.jpg、frame_000003.jpg...... jpg_quality:设置图片质量,范围为0到100,默认为100(质量最佳) iscolor:如果为False,输出的将是黑白图片 """ cap = cv2.VideoCapture(pathin) # 打开视频文件 n_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 视频的帧数 fps = cap.get(cv2.CAP_PROP_FPS) # 视频的帧率 dur = n_frames / fps # 视频的时间 thumbnail_name_list = [] if int(dur) > 60: os.remove(pathin) raise ParamsError('视频时长不能超过60秒') if int(dur) < 3: os.remove(pathin) raise ParamsError('视频时长不能少于3秒') # 如果only_output_video_info=True, 只输出视频信息,不提取图片 if only_output_video_info: print( 'only output the video information (without extract frames)::::::') print("Duration of the video: {} seconds".format(dur)) print("Number of frames: {}".format(n_frames)) print("Frames per second (FPS): {}".format(fps)) # 提取特定时间点图片 elif extract_time_points is not None: if max(extract_time_points) > dur: # 判断时间点是否符合要求 # raise NameError('the max time point is larger than the video duration....') print('the max time point is larger than the video duration....') extract_time_points = (0.1, ) try: os.mkdir(pathout) except OSError: pass success = True count = 0 while success and count < len(extract_time_points): cap.set(cv2.CAP_PROP_POS_MSEC, (1000 * extract_time_points[count])) success, image = cap.read() if success: if not iscolor: image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 转化为黑白图片 print('Write a new frame: {}, {}th'.format(success, count + 1)) # cv2.imwrite(os.path.join(pathout, "{}{}_{:06d}.jpg".format(str(dur)[:6], output_prefix, count + 1)), image, # [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality]) # save frame as JPEG file thumbnail_name = "{}_{:06d}.jpg".format( output_prefix, count + 1) cv2.imwrite(os.path.join(pathout, thumbnail_name), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality ]) # save frame as JPEG file count = count + 1 thumbnail_name_list.append(thumbnail_name) else: # 判断起始时间、终止时间参数是否符合要求 if initial_extract_time > dur: raise NameError( 'initial extract time is larger than the video duration....') if end_extract_time is not None: if end_extract_time > dur: raise NameError( 'end extract time is larger than the video duration....') if initial_extract_time > end_extract_time: raise NameError( 'end extract time is less than the initial extract time....' ) # 时间范围内的每帧图片都输出 if extract_time_interval == -1: if initial_extract_time > 0: cap.set(cv2.CAP_PROP_POS_MSEC, (1000 * initial_extract_time)) try: os.mkdir(pathout) except OSError: pass print('Converting a video into frames......') if end_extract_time is not None: N = (end_extract_time - initial_extract_time) * fps + 1 success = True count = 0 while success and count < N: success, image = cap.read() if success: if not iscolor: image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) print('Write a new frame: {}, {}/{}'.format( success, count + 1, n_frames)) # cv2.imwrite(os.path.join(pathout, "{}_{:06d}.jpg".format(output_prefix, count + 1)), image, # [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality]) # save frame as JPEG file thumbnail_name = "{}_{:06d}.jpg".format( output_prefix, count + 1) cv2.imwrite( os.path.join(pathout, thumbnail_name), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality ]) # save frame as JPEG file count = count + 1 thumbnail_name_list.append(thumbnail_name) else: success = True count = 0 while success: success, image = cap.read() if success: if not iscolor: image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) print('Write a new frame: {}, {}/{}'.format( success, count + 1, n_frames)) # cv2.imwrite(os.path.join(pathout, "{}_{:06d}.jpg".format(output_prefix, count + 1)), image, # [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality]) # save frame as JPEG file thumbnail_name = "{}_{:06d}.jpg".format( output_prefix, count + 1) cv2.imwrite( os.path.join(pathout, thumbnail_name), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality ]) # save frame as JPEG file count = count + 1 thumbnail_name_list.append(thumbnail_name) # 判断提取时间间隔设置是否符合要求 elif extract_time_interval > 0 and extract_time_interval < 1 / fps: raise NameError( 'extract_time_interval is less than the frame time interval....' ) elif extract_time_interval > (n_frames / fps): raise NameError( 'extract_time_interval is larger than the duration of the video....' ) # 时间范围内每隔一段时间输出一张图片 else: try: os.mkdir(pathout) except OSError: pass print('Converting a video into frames......') if end_extract_time is not None: N = (end_extract_time - initial_extract_time) / extract_time_interval + 1 success = True count = 0 while success and count < N: cap.set(cv2.CAP_PROP_POS_MSEC, (1000 * initial_extract_time + count * 1000 * extract_time_interval)) success, image = cap.read() if success: if not iscolor: image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) print('Write a new frame: {}, {}th'.format( success, count + 1)) # cv2.imwrite(os.path.join(pathout, "{}_{:06d}.jpg".format(output_prefix, count + 1)), image, # [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality]) # save frame as JPEG file thumbnail_name = "{}_{:06d}.jpg".format( output_prefix, count + 1) cv2.imwrite( os.path.join(pathout, thumbnail_name), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality ]) # save frame as JPEG file count = count + 1 thumbnail_name_list.append(thumbnail_name) else: success = True count = 0 while success: cap.set(cv2.CAP_PROP_POS_MSEC, (1000 * initial_extract_time + count * 1000 * extract_time_interval)) success, image = cap.read() if success: if not iscolor: image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) print('Write a new frame: {}, {}th'.format( success, count + 1)) # cv2.imwrite(os.path.join(pathout, "{}_{:06d}.jpg".format(output_prefix, count + 1)), image, # [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality]) # save frame as JPEG file thumbnail_name = "{}_{:06d}.jpg".format( output_prefix, count + 1) cv2.imwrite( os.path.join(pathout, thumbnail_name), image, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality ]) # save frame as JPEG file count = count + 1 thumbnail_name_list.append(thumbnail_name) re_data = { "thumbnail_name_list": thumbnail_name_list, "video_duration": dur } return re_data
def check_file_size(self): max_file_size = 20 * 1024 * 1024 upload_file_size = request.content_length current_app.logger.info(">>> Upload File Size is {0} MB <<<".format(round(upload_file_size/1048576, 2))) if upload_file_size > max_file_size: raise ParamsError("上传文件过大,请上传小于20MB的文件")