当前位置: 首页 > news >正文

订单后台管理系统-day07菜品模块

添加和编辑菜品模块

文件上传

  • 菜品的添加需要使用到富文本编辑器

  • 添加菜品时需要上传图片,所以我们需要配置文件上传的操作,设定全局变量

 UPLOAD = {# 定义可上传的图片类型'ext': ['jpg', 'gif', 'bmp', 'jpeg', 'png'],# 普通文件保存路径'prefix_path': 'web/static/upload/',# 富文本图片路径'prefix_url': 'static/upload/'}
  • utils/views.py全局工具文件中

@utils_bp.route('/upload_pic', methods=['GET', 'POST'])
def upload_pic():# 获取传递过来的值,这里的值需要前后端配合。固定为upfile,这个属性可以修改,但是前端请求时也需要使用对应的属性file_target = request.filesupfile = file_target['upfile'] if 'upfile' in file_target else None# 用于触发,set.js文件中的success方法,回显图片callback_target = 'window.parent'# 如果没有值,则弹窗显示上传失败。此处我们前后端未分离,后期可以修改为返回json格式的内容,由前端弹窗提示if upfile is None:return '<script>{0}.error("{1}")</script>'.format(callback_target, '上传失败')# 调用upload_file方法,实现图片上传,此方法在utils/utils.py文件中ret = upload_file(upfile)# 判断图片上传的返回值,给出不同反馈if ret['code'] != 200:return '<script>{0}.error("{1}")</script>'.format(callback_target, '上传失败:' + ret['msg'])
​return '<script>{0}.success("{1}")</script>'.format(callback_target, ret['data']['file_key'])
  • utils/utils.py中实现了upload_file方法,用于文件上传

# 文件上传本地
def upload_file(file_storage):resp = {'code': 200, 'msg': '操作成功!', 'data': {}}# 获取文件名称filename = secure_filename(file_storage.filename)# 按照文件名进行分割,并且取后缀ext = filename.rsplit('.', 1)[1]# 如果该后缀名不在配置文件里面,那么就要返回错误消息if ext not in Config.UPLOAD['ext']:resp['code'] = -1resp['msg'] = '不允许的扩展类型文件'return resp
​file_dir = datetime.now().strftime('%Y%m%d')save_dir = Config.UPLOAD['prefix_path'] + file_dir
​if not os.path.exists(save_dir):os.makedirs(save_dir)os.chmod(save_dir, stat.S_IRWXU | stat.S_IRGRP | stat.S_IRWXO)
​# 构建文件名称file_name = str(uuid.uuid4().hex) + '.' + ext# 保存文件file_storage.save('{0}/{1}'.format(save_dir, file_name))
​# 将上传记录存储到数据库中add_file_obj = Files()add_file_obj.file_key = file_dir + '/' + file_namedb.session.add(add_file_obj)db.session.commit()
​resp['data'] = {'file_key': add_file_obj.file_key}
​return resp
# 上传图片
def upload_image():resp = {'state': 'SUCCESS','url': '','title': '','original': ''}file_target = request.filesupfile = file_target['upfile'] if 'upfile' in file_target else Noneif upfile is None:resp['state'] = '上传失败'return jsonify(resp)
​ret = upload_file(upfile)if ret['code'] != 200:resp['state'] = '上传失败:' + ret['msg']# 调用图片回显方法,传入图片名称resp['url'] = build_image_url(ret['data']['file_key'])

图片回显

# 返回图片地址
def build_image_url(path):url = Config.DOMAIN + '/' + Config.UPLOAD['prefix_url'] + pathreturn url

添加和编辑菜品

  • 富文本的添加图片逻辑类似。不过路由返回的是一个完整路径http://127.0.0.1:8999/static/upload/20250709/84a0dc4388154fd18c224cc6d3123270.jpg。方便后续在富文本中编译显示

  • 准备添加路由,开始添加和编辑菜品

@manage_bp.route('/food/edit', methods=['GET', 'POST'])
def food_edit():resp = {'code': 200, 'msg': '操作成功', 'data': {}}if request.method == 'GET':
​resp_data = {}req = request.argsf_id = int(req.get('id', 0))
​food_obj = Noneif f_id:food_obj = Food.query.get(f_id)
​cat_list = FoodCat.query.all()resp_data['info'] = food_objresp_data['current'] = 'index'resp_data['cat_list'] = cat_list
​return ops_render('food/set.html', resp_data)
​if request.method == 'POST':req = request.values
​f_id = req['food_id'] if 'food_id' in req else 0c_id = int(req['cat_id']) if 'cat_id' in req else 0name = req['name'] if 'name' in req else ''price = req['price'] if 'price' in req else ''main_image = req['main_image'] if 'main_image' in req else ''summary = req['summary'] if 'summary' in req else ''stock = int(req['stock']) if 'stock' in req else ''tags = req['tags'] if 'tags' in req else ''
​price = Decimal(price).quantize(Decimal('0.00'))
​# if f_id < 1:#     resp['code'] = -1#     resp['msg'] = '商品不存在!'#     return jsonify(resp)
​if c_id < 1:resp['code'] = -1resp['msg'] = '请选择分类'return jsonify(resp)
​if len(name) < 1 or name is None:resp['code'] = -1resp['msg'] = '名称不符合规范'return jsonify(resp)
​if price <= 0 or price is None:resp['code'] = -1resp['msg'] = '售卖价格不能为空且大于等于0'return jsonify(resp)
​if main_image is None or len(main_image) < 3:resp['code'] = -1resp['msg'] = '请上传封面图'return jsonify(resp)
​if summary is None or len(summary) < 10:resp['code'] = -1resp['msg'] = '详情不能少于十个字符!'return jsonify(resp)
​if stock < 1:resp['code'] = -1resp['msg'] = '库存不能小于1'return jsonify(resp)
​if tags is None or len(tags) < 1:resp['code'] = -1resp['msg'] = '请输入标签!'return jsonify(resp)
​food_obj = Food.query.get(f_id)before_stock = 0
​if not food_obj:food_obj = Food()else:before_stock = food_obj.stock
​food_obj.cat_id = c_idfood_obj.name = namefood_obj.price = pricefood_obj.main_image = main_imagefood_obj.summary = summaryfood_obj.stock = stockfood_obj.tags = tags
​db.session.add(food_obj)db.session.commit()
​stock_change = FoodStockChangeLog()stock_change.food_id = food_obj.idstock_change.unit = int(stock) - int(before_stock)stock_change.total_stock = stockstock_change.note = '后台调整'db.session.add(stock_change)db.session.commit()
​return jsonify(resp)

显示所有菜品

@manage_bp.route('/food/list')
def food_list():resp_data = {}# 有page就取pagepage = int(request.args.get('page', 1))
​query = Food.query# 有status就取statusstatus_name = int(request.args.get('status', '-1'))if status_name > -1:query = query.filter(Food.status == status_name)# 有cat_id就取cat_idcat_id = int(request.args.get('cat_id', 0))if cat_id > 0:query = query.filter_by(cat_id=cat_id)# 有查询的信息就使用查询信息mix_kw = request.args.get('mix_kw', '')if mix_kw:rule = or_(Food.name.contains('%s' % mix_kw), Food.tags.contains('%s' % mix_kw))page_data = query.filter(rule).order_by(Food.id.desc()).paginate(page=page, per_page=Config.PER_PAGE)else:page_data = query.order_by(Food.id.desc()).paginate(page=page, per_page=Config.PER_PAGE)
​resp_data = {'list': page_data,'status_mapping': constants.STATUS_MAPPING}# 这里获取分类数据,用于筛选.food_list_obj = FoodCat.query.all()resp_data['current'] = 'index'resp_data['cat_list'] = food_list_objreturn ops_render('food/index.html', resp_data)

查看菜品详情

  • 路由中接收传递过来的id值,根据id查询数据

  • 详情中,我们还需要展示当前菜品的库存变更记录

  • 后期还可以加上销售记录

@manage_bp.route('/food/info')
def food_info():resp_data = {}
​req = request.argsf_id = int(req.get('id', 0))if f_id < 1:return redirect('manage.food_list')
​food_obj = Food.query.get(f_id)if not food_obj:return redirect('manage.food_list')# 关联查询,库存记录变更表stock_change_list = FoodStockChangeLog.query.filter(FoodStockChangeLog.food_id == f_id).order_by(FoodStockChangeLog.id.desc()).all()
​resp_data['info'] = food_objresp_data['current'] = 'index'resp_data['stock_change_list'] = stock_change_list
​return ops_render('food/info.html', resp_data)

删除菜品(修改状态)

  • 同理可得,根据传递过来的id和act的值,修改状态

@manage_bp.route('/food/ops', methods=['PUT'])
def foot_ops():resp = {'code': 200, 'msg': '操作成功!', 'data': {}}req = request.values
​f_id = req['id'] if 'id' in req else 0act = req['act'] if 'act' in req else ''if not f_id:resp['code'] = -1resp['msg'] = '操作失败!'return jsonify(resp)if act not in ['remove', 'recover']:resp['code'] = -1resp['msg'] = '操作失败!'return jsonify(resp)food_obj = Food.query.get(f_id)if not food_obj:resp['code'] = -1resp['msg'] = '指定食物不存在!'return jsonify(resp)if act == 'remove':food_obj.status = 0elif act == 'recover':food_obj.status = 1db.session.commit()return jsonify(resp)

http://www.dtcms.com/a/361759.html

相关文章:

  • 域名备案后不解析可以吗
  • 五、导入现有模型
  • Docker基本介绍
  • 面试记录8 Linux/c++中级开发工程师(智能座舱)
  • 六大关键步骤:用MES系统重构生产计划管理闭环
  • Linux开发必备:yum/vim/gcc/make全攻略
  • 如何使用 JMeter 进行接口测试。
  • Java 常见异常系列:NumberFormatException 数字格式异常
  • ROS1系列学习笔记之ROS的调用,示例为激光雷达N10P的运行(含常见问题与踩坑解答)
  • 数据结构:计数排序 (Counting Sort)
  • 逻辑门编程(一)——与或非门
  • 接口响应慢 问题排查指南
  • MongoDB 内存管理:WiredTiger 引擎原理与配置优化
  • GraalVM Native Image:让 Java 程序秒启动
  • 植物中lncRNA鉴定和注释流程,代码(包含Identified,Classification,WGCNA.....)
  • shell编程 函数、数组与正则表达式
  • 预处理——嵌入式学习笔记
  • day06——类型转换、赋值、深浅拷贝、可变和不可变类型
  • 009=基于YOLO12与PaddleOCR的车牌识别系统(Python+PySide6界面+训练代码)
  • C++运行时类型识别
  • k8s知识点汇总2
  • Java 加载自定义字体失败?从系统 fontconfig 到 Maven 损坏的全链路排查指南
  • 基于 C 语言的网络单词查询系统设计与实现(客户端 + 服务器端)
  • 适合工程软件使用的python画图插件对比
  • Maven - Nexus搭建maven私有仓库;上传jar包
  • 20250829的学习笔记
  • OPENCV 基于旋转矩阵 旋转Point2f
  • 代码随想录二刷之“回溯”~GO
  • 机器翻译:python库translatepy的详细使用(集成了多种翻译服务)
  • Spring框架入门:从IoC到AOP