-
2020-12-16 02:17:55
# 1、实现一个商品管理的程序。
# #输出1,添加商品 2、删除商品 3、查看商品
# 添加商品:
# 商品的名称:xxx 商品如果已经存在的话,提示商品商品已经存在
# 商品的价格:xxxx 数量只能为大于0的整数
# 商品的数量:xxx,数量只能为大于0的整数
# 2、删除商品:
# 输入商品名称:
# iphone 如果输入的商品名称不存在,要提示不存在
# 3、查看商品信息:
# 输入商品名称:
# iphone:
# 价格:xxx
# 数量是:xxx
# all:
# print出所有的商品信息
import json
def add_product():
product = input(‘请输入商品名称:‘).strip()
count = input(‘请输入商品数量:‘).strip()
price = input(‘请输入商品价格:‘).strip()
f = open(‘product.json‘, ‘a+‘, encoding=‘utf-8‘)
f.seek(0)
products = json.load(f)
if product == ‘‘:
print(‘商品名称不能为空‘)
elif product in products:
print(‘商品已存在‘)
elif not count.isdigit():
print(‘商品数量必须为正整数‘)
elif not price.isdigit():
print(‘商品价格必须为正整数‘)
else:
products[product] = {}
products[product][‘count‘] = int(count)
products[product][‘price‘] = int(price)
f.seek(0)
f.truncate()
json.dump(products, f, indent=4, ensure_ascii=False)
f.close()
def show_product(product):
f = open(‘product.json‘, encoding=‘utf-8‘)
products = json.load(f)
f.close()
if (product==‘all‘):
return products
elif not (product in products):
print(‘商品不存在‘)
else:
#print(products[product])
return product+‘:\n 数量:‘+str(products[product][‘count‘])+‘\n 价格:‘+str(products[product][‘price‘])
def del_product(product):
f = open(‘product.json‘, ‘a+‘, encoding=‘utf-8‘)
f.seek(0)
products = json.load(f)
if not (product in products):
print(‘商品不存在‘)
else:
del products[product]
f.seek(0)
f.truncate()
json.dump(products, f, indent=4, ensure_ascii=False)
f.close()
print("输出1、添加商品 2、删除商品 3、查看所有商品")
choice=input()
if choice=="1":
add_product()
elif choice=="2":
product=input(‘请输入要删除的商品名称:‘)
del_product(product)
elif choice=="3":
product=input(‘请输入要查询的商品名称:‘)
print(show_product(product))
else:
print(‘输入有误‘)
python编写商品管理
更多相关内容 -
商品管理系统完整源码(java+mysql+ui)(原创)
2019-10-29 18:06:18数据库中数据表通过外键链接,实现增加、删除、修改、查询功能(用户管理、商品管理、订单管理、商品类型管理、地址管理、评论管理、购物车管理)。用的是JDBC链接,设有事物回滚功能,本资源包含商品管理系统源码+... -
商品管理系统
2016-04-21 14:55:34北大青鸟S1项目,此为商品管理系统,有兴趣可以看看多多交流! -
nike货品管理理念——nike订货管理
2020-12-21 10:46:06相信与超市管理职业挂钩的你,可能需要了解一下nike货品管理理念——nike订货管理,现在就来下...该文档为nike货品管理理念——nike订货管理,是一份很不错的参考资料,具有较高参考价值,感兴趣的可以下载看看 -
商品管理系统python
2018-10-21 10:58:12基于python开发的商品管理系统,可以用于课程设计的参考。 -
浅析电商商品管理
2018-06-04 15:49:22商品中心是所有电商平台的底层核心业务,犹如海面下的冰山,除了各平台维护商品中心的人员外,旁人很难真正了解其中的诀窍。 -
货品管理人员工作结构图
2020-12-19 00:12:43这一款货品管理人员工作结构图专为客户需求而设计,随着内外环境变化而变化,欢迎大家下载货品管理人员工...该文档为货品管理人员工作结构图,是一份很不错的参考资料,具有较高参考价值,感兴趣的可以下载看看 -
零售行业货品管理
2020-12-16 04:10:02零售行业货品管理以围绕物流采购为核心,以方便大家了解学习零售行业货品管理为前提,喜欢零售行业货品管...该文档为零售行业货品管理,是一份很不错的参考资料,具有较高参考价值,感兴趣的可以下载看看 -
电商后台管理系统原型(商品管理、订单管理、库存管理用户管理、促销管理、运营活动等整套).rar
2019-07-25 16:56:12电商后台管理系统原型(商品管理、订单管理、库存管理用户管理、促销管理、运营活动等整套).rar,很全的一套后台原型 -
基于SSM的商品供应管理系统【项目源码+数据库脚本】(毕设)
2021-06-16 11:00:36供应商信息管理、供应商等级信息管理、管理员信息管理、网站公告管理、商品类别管理、商品信息管理、咨询价格管理、采购订单管理等功能。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际... -
QT+数据库(商品管理系统)
2016-07-25 09:17:08基于QT和数据库完成的商品管理系统,有详细解释,非常简单的例子,请放心使用,请放心使用,请放心使用! -
PHP商品管理系统
2013-03-19 11:48:55PHP商品管理系统,供大家一起共同分享学习。 -
java实现商品信息管理系统
2020-08-25 10:14:04主要为大家详细介绍了java实现商品信息管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
c++商品管理
2013-06-27 00:57:28某商场有如下的几种货品:衬衣、鞋子、帽子、裤子、冰箱、电视、立柜、壁橱、沙发。每一种货物都有详细的说明信息。 -
C#开发的超市商品管理系统
2014-08-03 12:28:52使用VS2010 + SQL Server 2008 开发的超市商品管理系统(C/S) 实现了商品入库、商品查询(浏览)、商品售出(收银台)和销售统计等功能 内包含C#源码 数据库 使用配置方法 以及课程设计论文。 -
电商后台管理系统——商品管理
2021-07-24 20:05:05电商后台管理系统——商品管理 商品管理模块分为商品分类,分类参数,商品列表三个小模块,商品分类模块实现展示商品分类数据,添加分类功能,编辑删除分类功能;分类参数模块实现根据商品分类展示该分类的静态属性...电商后台管理系统——商品管理
商品管理模块分为商品分类,分类参数,商品列表三个小模块,商品分类模块实现展示商品分类数据,添加分类功能,编辑删除分类功能;分类参数模块实现根据商品分类展示该分类的静态属性和动态参数,添加动态参数和静态属性功能,并实现删除修改每项属性以及每项属性下的tag内容功能;商品列表模块实现展示商品列表信息以及修改删除商品信息,搜索商品,添加商品功能。
一、商品分类
商品分类实现图
商品分类流程图
创建cate商品组件并设置路由规则——添加cate组件基本布局——请求商品分类数据保存到data中——使用第三方插件vue-table-with-tree-grid展示分类数据以及自定义列的数据——完成分页功能pagination组件——实现添加分类按钮功能
其中每部分详解:
基本布局
面包屑导航 卡片视图区域,卡片视图区域包括添加分类按钮,以及一个表单,这块通过el-row,el-col布局,表单数据分为五列,索引列,分类,名称列,是否有效列,排序列,操作列;请求商品分类数据
定义方法发送get请求获取商品分类数据保存到data中,并保存总数据条数;展示分类数据以及自定义列的数据
tree-table组件绑定:data=“catelist” ,show-index index-text="#" 设置索引列,其他三列通过作用域与插槽实现,具体实现类似之前实现方式;<tree-table :data="catelist" :columns="columns" :selection-type="false" :expand-type="false" show-index index-text="#" border :show-row-hover="false">
分页功能
与之前页面的分页功能实现代码类似;添加分类按钮功能
布局添加分类按钮对话框——添加分类按钮绑定事件实现打开对话框且获取数据渲染到页面——选项选择触发事件——对话框确定按钮
添加分类对话框为一个分类名称输入框以及一个下拉选择框选择父级分类,分类名称输入框双向绑定数据存入data并且设计验证规则即该框必须有输入。
获取数据渲染步骤
发送get请求获取父级分类数据列表存储到data ,利用cascader组件显示父级分类,options绑定父级类列表的数据即指定数据源,props是用来指定配置对象,如显示的值,真实值,父子嵌套使用的属性,v-model双向绑定选中的父级分类的id数组到data中<el-cascader expand-trigger="hover" :options="parentCateList" :props="cascaderProps" v-model="selectedKeys" @change="parentCateChanged" clearable change-on-select>
选择触发事件
即上面的parentCateChanged方法,在里面判断数组长度是否大于0,大于0则有选中,从selectedKeys中取出父级分类id赋值给data中的数据cat_id,再赋值data中当前分类的等级cat-leve(就selectedKeys数组长度)对话框确定按钮
首先预验证输入框,再通过post请求添加分类,成功后再重新获取商品分类 数据,以及关闭对话框额外的 监听添加分类对话框的关闭事件,需要在里面重置对话框的表单数据,并且将selectedKeys数组以及data中的cat_id和cat-level重新赋值为0。
二、分类参数
分类参数功能实现图
分类参数功能实现流程
分类参数实现过程
创建Param分类参数组件并设置路由规则——完成Params.vue组件的基本布局——完成选择商品分类级联选择框功能——实现展示动态参数以及静态属性参数数据功能——实现添加动态属性或静态参数属性功能——实现编辑参数,删除参数功能基本布局
面包屑导航 卡片视图,el-row.el-col布局
商品分类级联选择框
类似之前的先获取商品分类数据,再通过el-cascader渲染,绑定级联选择框选中项触发事件(这里的触发事件里是调用获取动态参数和静态参数页面数据并渲染的函数)
展示动态参数以及静态属性参数数据功能
需要额外的在tab页签el-tabs上绑定tab页签的点击事件,即一旦点击立马调用获取参数列表数据的函数重新渲染(针对于点击的是动态参数还是静态属性页签)
获取上述参数的函数
判断是否选中三级分类——选中三级分类后通过发送get请求(带cateid当前选项id)获取对应的参数)——循环遍历数据res.data存入数组attr_vals——通过参数判断点击的是动态参数页面还是静态参数页面——赋值res.data给对应的页面数据数组
注意项:通过在el-tabs最外层上v-model绑定选定选项卡的name可以明确当前点的是only还是many,再通过computed定义动态计算标题文本,即将两者判断返回值是动态参数还是静态属性
在展开列通过作用域插槽实现自定义格式,在el-tag循环遍历数组attr_vars实现循环渲染tag标签,并且还添加输入文本框实现可以自己在此添加标签以及删除标签的功能
添加标签功能:
输入文本框通过按钮点击事件将文本框的visbile设为true显示,而按钮事件的数据通过文本框双向绑定传递用到了**$nextTick** 方法
作用是当页面上元素被重新渲染之后,才会指定回调函数中的代码(如果不这样,元素没渲染就获取会报错)
this.$nextTick(_ => {
this. r e f s . s a v e T a g I n p u t . refs.saveTagInput. refs.saveTagInput.refs.input.focus()
})
回调函数代码则通过先判断是否有输入,有输入内容则需要发起请求put保存此此数据到数据库。
添加参数或属性功能
实现步骤:添加el-dialog布局——添加表单验证规则——确定按钮绑定添加事件——关闭事件重置对话框
添加事件:验证输入是否有效,再将该分类id以及添加的参数名字和属于哪个页面(静态页面还是动态参数页面)的数据通过post请求实现添加参数功能,添加成功则关闭对话框,重新调用获取参数数据函数。
编辑和删除参数功能
编辑功能
编辑el-dialog布局——对话框里绑定相关数据——校验规则——确定按钮绑定编辑参数事件(判断是否符合校验规则,符合再put数据,再 重新获取参数再关闭对话框)
删除功能
按钮绑定事件,通过splice函数传入选中的attr_id删除attr_vals数组中的数据,再调用发起请求保存到数据库的函数。
三、商品列表
商品列表实现图
商品列表流程图
商品列表实现过程
1.新建List组件,添加子级路由组件以及对应的规则,设置组件的基本结构——2.实现表单数据渲染以及分页功能,搜索功能,编辑删除商品功能(day11讲解删除更清楚)的实现(类似于用户列表页面)——3.添加按钮绑定点击事件通过编程式导航跳转到添加商品页面并添加路由规则——4.布局Add添加商品组件——5.基本信息页面实现(之前都做过类似功能)——5.添加tab栏切换验证——6.展示商品参数和商品属性页面的信息——7.商品图片上传——8.完成添加商品操作2实现开始页面
表单中中需要添加过滤器,将秒数过滤为年月日,时分秒4布局Add添加商品组件
使用了步骤条组件el-steps,在form表单中使用了tabs标签页,大致使用方法如下图
<el-form> <el-tabs> <el-tab-pane> <el-form-item> </el-form-item> <el-form-item> </el-form-item> </el-tab-pane> <el-tab-pane> </el-tab-pane> </el-tabs> </el-form>
5.添加tab栏切换验证
先给el-tabs绑定选中选项卡的name并添加绑定事件函数,事件函数通过传入选中选项卡的name和即将离开的选项卡的name,再判断是否满足各个页面的校验条件(这里是判断各个页面存储数据的数组情况)
6.展示商品参数和商品属性页面的信息
这两者的数据通过判断用户点击的tab栏的切换选择传入get请求各自的参数获取各自的数据
商品参数使用数组渲染复选框组 el-checkbox-group,商品属性通过循环生成静态属性渲染到el-form-item,这里的输入框依旧通过 v-model="item.attr_vals双向绑定
<el-tab-pane label="商品参数" name="1"> <!-- 渲染表单的Item项 --> <el-form-item :label="item.attr_name" v-for="item in manyTableData" :key="item.attr_id"> <!-- 复选框组 --> <el-checkbox-group v-model="item.attr_vals"> <el-checkbox :label="cb" v-for="(cb, i) in item.attr_vals" :key="i" border></el-checkbox> </el-checkbox-group> </el-form-item> </el-tab-pane>
<el-tab-pane label="商品属性" name="2"> <el-form-item :label="item.attr_name" v-for="item in onlyTableData" :key="item.attr_id"> <el-input v-model="item.attr_vals"></el-input> </el-form-item> </el-tab-pane>
7.商品图片上传
使用upload组件完成图片上传,upload组件进行图片上传的时候并不是使用axios发送请求,所以,我们需要手动为上传图片的请求添加token,即为upload组件添加headers属性。
<el-upload :action="uploadURL" :on-preview="handlePreview" :on-remove="handleRemove" :on-success="handleSuccess" list-type="picture" :headers="headerObj"> <el-button size="small" type="primary">点击上传</el-button> </el-upload>
action:指定图片上传api接口
:on-preview : 当点击图片时会触发该事件进行预览操作,处理图片预览
:on-remove : 当用户点击图片右上角的X号时触发执行
:on-success:当用户点击上传图片并成功上传时触发
list-type :设置预览图片的方式
:headers :设置上传图片的请求头设置预览图片对话框
<el-dialog title="图片预览" :visible.sync="previewVisible" width="50%"> <img :src="previewPath" class="previewImg" /> </el-dialog>
handlePreview预览事件:通过 this.previewPath = file.response.data.url设置预览图片的地址,通过 this.previewVisible = true显示预览图片对话框
handleRemove删除事件: 先获取将要删除的图片的临时路径,从data中的addform对象的 pics 数组中找到这个图片对应的索引值,调用数组的 splice 方法把图片信息对象,从 pics 数组中移除
handleSuccess上传成功事件:将图片信息对象push到pics数组中
8.完成商品添加操作
在添加商品之前,为了避免goods_cat数组转换字符串之后导致级联选择器(级联选择器只能绑定到数组)报错,我们需要打开vue控制条,点击依赖,安装lodash,把addForm(添加商品的对象信息)进行深拷贝存到新的数组。这里还有对其中动态参数的处理和静态属性的处理。即通过循环遍历各自存储的数组中 的数据item.attr_id,item.attr_vals再push保存到data中的添加商品的表单数据对象里。
添加事件通过发送post请求实现成功添加商品,再通过编程式导航跳转回商品分类最初的界面。
-
效期商品管理规程
2018-05-16 15:05:011、保证商品的销售、使用在其失效之前,这是进行商品效期管理的基本要求。 2、提高对商品效期的控制能力,缩短商品在仓库、店面的存放时间,加快商品周转,减少效期报损。 3、保证公司及门店商品的新鲜度。同时,对... -
基于JavaSwing+Mysql的超市商品管理系统设计和实现
2021-08-17 07:21:47本项目是使用Java swing开发,可实现超市管理系统商品列表信息查询、添加商品信息和修改商品管理以及删除商品信息和安装商品信息查询等功能。界面设计和功能比较简单基础、适合作为Java课设设计以及学习技术使用。 ...前言:
本项目是使用Java swing开发,可实现超市管理系统商品列表信息查询、添加商品信息和修改商品管理以及删除商品信息和安装商品信息查询等功能。界面设计和功能比较简单基础、适合作为Java课设设计以及学习技术使用。
摘要:
随着小超市规模的发展不断扩大, 商品数量急剧增加, 有关商品的各种信息量也成倍增长。 超市时时刻刻都需要对商品各种信息进行统计分析。 而大型的超市管理系统功能过于强大而造成操作繁琐降低了小超市的工作效率。 超市管理系统是市场上最流行的超市上常用的系统之一, 由于刚学Java知识、所有功能设计的比较简单、只有商品信息的增删改查。实现对商品信息全面、 动态、及时的管理。本文系统的分析了软件开发的背景以过程;首先介绍了软件的开发环境, 其次介绍了本软件的详细设计过程: 数据库的设计、各个模块的设计和实现,以及具体界面的设计和功能。超市库存管理系统是基于 Java eclipse 作为开发工具 , Mysql 作为后台数据库支持。超市库存管理系统开发主要是界面程序的开发、数据库的建立、数据库的维护。应用程序功能完善,界面人机交互要好,而且操作简单。同时 JAVASwing语言简单,在较短的时间内能够开发出使用性强、 功能完善, 易于操作的程序, 也能实现与数据库的连接。
主要模块:
商品列表数据展示、商品信息添加、商品信息修改、商品信息删除、按照商品名称查询商品信息
功能截图:
查询商品列表信息
添加商品信息:
修改商品信息:
删除商品信息:
删除之后需要刷新一下列表数据
编号查询商品信息:
部分关键代码:
主页功能:
public class GoodsManage extends JFrame { private JTextField textField; Select select = new Select(); Updata updata = new Updata(); Object[] header= {"商品编号","商品名称","数量","单价"}; String sql = "SELECT goodsID,goodsname,num,price FROM goods"; Object[][] data= select.getGoods(sql); DefaultTableModel df = new DefaultTableModel(data, header); int v=ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED; int h=ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED; public GoodsManage() { super("商品管理系统"); this.setBounds(0, 0, 700, 450); this.setLocationRelativeTo(null);//让窗口在屏幕中间显示 this.setResizable(false);//让窗口大小不可改变 getContentPane().setLayout(null); JTable jTable = new JTable(df); JScrollPane jsp=new JScrollPane(jTable,v,h); jsp.setBounds(10, 10, 515, 320); getContentPane().add(jsp); JButton button_1 = new JButton("显示所有商品"); button_1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String sql = "SELECT goodsID,goodsname,num,price FROM goods"; Object[][] data = Select.getGoods(sql); df.setDataVector(data, header); } }); button_1.setBounds(535, 80, 127, 30); getContentPane().add(button_1); JButton button_2 = new JButton("修改商品"); button_2.setBounds(535, 140, 127, 30); getContentPane().add(button_2); button_2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (jTable.getSelectedColumn()<0) { JOptionPane.showMessageDialog(null, "请选择要修改的数据!"); } else { int goodsID = Integer.parseInt(jTable.getValueAt(jTable.getSelectedRow(), 0).toString()); String name = jTable.getValueAt(jTable.getSelectedRow(), 1).toString(); int num = Integer.parseInt(jTable.getValueAt(jTable.getSelectedRow(), 2).toString()); String price = jTable.getValueAt(jTable.getSelectedRow(), 3).toString(); Goods goods = new Goods(goodsID,name,num,price); GoodsXG goodsXG = new GoodsXG(goods); goodsXG.setVisible(true); } } }); JButton button_3 = new JButton("删除商品"); button_3.setBounds(535, 200, 127, 30); getContentPane().add(button_3); button_3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (jTable.getSelectedColumn()<0) { JOptionPane.showMessageDialog(null, "请选中要删除的数据!"); } else { int goodsID = Integer.parseInt(jTable.getValueAt(jTable.getSelectedRow(), 0).toString()); String sql="delete from goods where goodsid="+goodsID; int result = updata.addData(sql); if (result>0) { JOptionPane.showMessageDialog(null, "删除成功!"); JOptionPane.showMessageDialog(null, "记得刷新一下哦!"); } else { JOptionPane.showMessageDialog(null, "删除失败!"); } } } }); JButton button_4 = new JButton("添加商品"); button_4.setBounds(535, 258, 127, 30); getContentPane().add(button_4); button_4.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { GoodsADD goodsAdd = new GoodsADD(); goodsAdd.setVisible(true); } }); JLabel label = new JLabel("商品编号:"); label.setBounds(40, 354, 112, 32); getContentPane().add(label); textField = new JTextField(); textField.setBounds(154, 358, 127, 26); getContentPane().add(textField); textField.setColumns(10); JButton button = new JButton("按编号查询"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { String sql = "SELECT goodsID,goodsname,num,price FROM goods WHERE goodsid LIKE '%"+textField.getText()+"%'"; Object[][] data = Select.getGoods(sql); df.setDataVector(data, header); } }); button.setBounds(305, 355, 112, 30); getContentPane().add(button); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { super.windowClosing(e); //加入动作 GoodsManagement m = new GoodsManagement(); m.setVisible(true); } }); } public static void main(String[] args) { GoodsManage t = new GoodsManage(); t.setVisible(true); } }
添加商品信息:
public class GoodsADD extends JFrame { private JTextField id,name,num,price; private JButton button; private JButton button_1; public GoodsADD() { super("商品管理系统"); this.setBounds(0, 0, 400, 450); this.setLocationRelativeTo(null);//让窗口在屏幕中间显示 this.setResizable(false);//让窗口大小不可改变 getContentPane().setLayout(null); JLabel label = new JLabel("商品编号:"); label.setBounds(85, 89, 87, 22); getContentPane().add(label); id = new JTextField(); id.setBounds(147, 90, 142, 21); getContentPane().add(id); id.setColumns(10); JLabel label_1 = new JLabel("商品名称"); label_1.setBounds(85, 139, 87, 22); getContentPane().add(label_1); name = new JTextField(); name.setColumns(10); name.setBounds(147, 140, 142, 21); getContentPane().add(name); JLabel label_2 = new JLabel("数量:"); label_2.setBounds(85, 193, 87, 22); getContentPane().add(label_2); num = new JTextField(); num.setColumns(10); num.setBounds(147, 194, 142, 21); getContentPane().add(num); JLabel label_3 = new JLabel("单价:"); label_3.setBounds(85, 241, 87, 22); getContentPane().add(label_3); price = new JTextField(); price.setColumns(10); price.setBounds(147, 242, 142, 21); getContentPane().add(price); button = new JButton("确定"); button.setBounds(78, 317, 93, 23); getContentPane().add(button); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { String addId = id.getText(); String addName = name.getText(); String addNum = num.getText(); String addPrice = num.getText(); if (addName.equals("")||addName.equals("")||addNum.equals("")||addPrice.equals("")) { JOptionPane.showMessageDialog(null, "请完整输入要添加的数据"); } else { String sql="INSERT INTO goods VALUES("+addId+",'"+addName+"','"+addNum+"','"+addPrice+"')"; int result = Updata.addData(sql); if (result>0) { JOptionPane.showMessageDialog(null, "添加成功!"); JOptionPane.showMessageDialog(null, "记得刷新一下哦!"); dispose(); // GoodsManage i = new GoodsManage(); // i.setVisible(true); } else { JOptionPane.showMessageDialog(null, "添加失败!"); } } } }); button_1 = new JButton("取消"); button_1.setBounds(208, 317, 93, 23); getContentPane().add(button_1); button_1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { dispose(); } }); } }
数据库设计:
商品表:
CREATE TABLE `NewTable` ( `goodsID` int(11) NOT NULL , `goodsName` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `num` int(11) NOT NULL , `price` decimal(10,4) NOT NULL , PRIMARY KEY (`goodsID`) ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=COMPACT ;
备注:项目来于网络、作者整理优化测试编写文档、若有侵权联系删除
总结:
通过这次课程设计。我学到了许多令我受益匪浅的知识。感觉java的界面设计和 mfc差不多。只是java没有可视化的界面做起来太累了。其他主要是类和对象的问题。实现起来还是挺简单的。综合了根据超市系统的实际情况的特点, 虽然用户界面和功能设计比较一般,但操作使用还是方便。满足学生学习的一个基本状态。了解Java对象和swing窗口化图形化编程的特性、由于时间仓促,只做了商品的CRUD、需要其他功能的可以自行设计和添加上、作为学生学习参考以及课程设计还是不错的选择。
完整源码下载地址
JavaSwing系列项目推荐:
打卡JavaSwing项目更新 7 / 100篇
大家可以点赞、收藏、关注、评论我啦
-
商品信息管理系统(Java实现+MySQL 数据库)
2019-12-20 00:42:04这是本人在做课程设计的时候写的用Java实现商品信息管理系统的代码,具体信息请看本人博客,博客地址https://blog.csdn.net/vegetable_haker/article/details/102556311,其中MySQL数据库需要根据本地配置做些修改 ... -
数据结构 仓库货品管理系统
2021-06-29 11:21:46建立一个仓库管理程序,可以按顺序和货物名称查询仓库存储情况,也可以增加或删除货物信息、实现货物的入库出库,最终能够实现对仓库信息进行有效的管理 含报告和答辩ppt -
货品管理的基本分类.pptx
2021-10-12 12:18:48货品管理的基本分类.pptx -
ssm商品超市管理系统
2018-07-20 11:35:49基于ssm+mysql搭建的一套商品超市管理系统,内置功能比较全,可用于毕业设计,项目导入即可实用配置简单。 -
QT下的商品管理系统
2015-06-11 12:34:01QT下实现的功能完善的商品管理系统,可实现增删查改基础功能和商品的拓展管理 -
基于JavaWeb的超市管理系统【项目源码+数据库脚本】(毕设)
2021-06-26 11:02:10商品信息管理、增加商品信息、商品信息查询 4.货架信息管理 货架信息管理、增加货架信息、货架信息查询 5.商品类型管理 商品类型管理、增加商品类型 6.进货信息管理 进货信息管理、增加进货信息、进货信息查询 7... -
服装品牌代理商货品管理体系.docx
2022-01-13 17:33:34服装品牌代理商货品管理体系.docx -
后台管理系统之商品管理
2020-04-11 15:36:44商品查询 效果预览 接下来,我们实现商品管理的页面,先看下我们要实现的效果: 可以看出整体是一个table,然后有新增按钮。是不是跟昨天写品牌管理很像? 页面请求 先看整体页面结构(Goods.vue): 并且在Vue实例...文章目录
1.商品查询
效果预览
接下来,我们实现商品管理的页面,先看下我们要实现的效果:
可以看出整体是一个table,然后有新增按钮。是不是跟昨天写品牌管理很像?
页面请求
先看整体页面结构(Goods.vue):
并且在Vue实例挂载后就会发起查询(mounted调用getDataFromServer方法初始化数据):
我们刷新页面,可以看到浏览器发起已经发起了查询商品数据的请求:
因此接下来,我们编写接口即可。后台(提供)接口
页面已经准备好,接下来在后台提供分页查询SPU的功能。
实体类
在leyou-item-interface工程中添加实体类:
SPU
@Table(name = "tb_spu") public class Spu { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Long brandId; private Long cid1;// 1级类目 private Long cid2;// 2级类目 private Long cid3;// 3级类目 private String title;// 标题 private String subTitle;// 子标题 private Boolean saleable;// 是否上架 private Boolean valid;// 是否有效,逻辑删除用 private Date createTime;// 创建时间 private Date lastUpdateTime;// 最后修改时间 // 省略getter和setter }
SPU详情
@Table(name="tb_spu_detail") public class SpuDetail { @Id private Long spuId;// 对应的SPU的id private String description;// 商品描述 private String specialSpec;// 商品特殊规格的名称及可选值模板 private String genericSpec;// 商品的全局规格属性 private String packingList;// 包装清单 private String afterService;// 售后服务 // 省略getter和setter }
mapper
public interface SpuMapper extends Mapper<Spu> { }
controller
先分析:
-
请求方式:GET
-
请求路径:/spu/page
-
请求参数:
- page:当前页
- rows:每页大小
- key:过滤条件
- saleable:上架或下架
-
返回结果:商品SPU的分页信息。
-
要注意,页面展示的是商品分类和品牌名称,而数据库中保存的是id,怎么办?
我们可以新建一个类,继承SPU,并且拓展cname和bname属性,写到
leyou-item-interface
public class SpuBo extends Spu { String cname;// 商品分类名称 String bname;// 品牌名称 // 略 。。 }
-
编写controller代码:
我们把与商品相关的一切业务接口都放到一起,起名为GoodsController,业务层也是这样
@Controller public class GoodsController { @Autowired private GoodsService goodsService; @GetMapping("spu/page") public ResponseEntity<PageResult<SpuBo>> querySpuBoByPage( @RequestParam(value = "key", required = false)String key, @RequestParam(value = "saleable", required = false)Boolean saleable, @RequestParam(value = "page", defaultValue = "1")Integer page, @RequestParam(value = "rows", defaultValue = "5")Integer rows ){ PageResult<SpuBo> pageResult = this.goodsService.querySpuBoByPage(key, saleable, page, rows); if(CollectionUtils.isEmpty(pageResult.getItems())){ return ResponseEntity.notFound().build(); } return ResponseEntity.ok(pageResult); } }
service
所有商品相关的业务(包括SPU和SKU)放到一个业务下:GoodsService。
@Service public class GoodsService { @Autowired private SpuMapper spuMapper; @Autowired private CategoryService categoryService; @Autowired private BrandMapper brandMapper; public PageResult<SpuBo> querySpuBoByPage(String key, Boolean saleable, Integer page, Integer rows) { Example example = new Example(Spu.class); Example.Criteria criteria = example.createCriteria(); // 搜索条件 if (StringUtils.isNotBlank(key)) { criteria.andLike("title", "%" + key + "%"); } if (saleable != null) { criteria.andEqualTo("saleable", saleable); } // 分页条件 PageHelper.startPage(page, rows); // 执行查询 List<Spu> spus = this.spuMapper.selectByExample(example); PageInfo<Spu> pageInfo = new PageInfo<>(spus); List<SpuBo> spuBos = new ArrayList<>(); spus.forEach(spu->{ SpuBo spuBo = new SpuBo(); // copy共同属性的值到新的对象 BeanUtils.copyProperties(spu, spuBo); // 查询分类名称 List<String> names = this.categoryService.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3())); spuBo.setCname(StringUtils.join(names, "/")); // 查询品牌的名称 spuBo.setBname(this.brandMapper.selectByPrimaryKey(spu.getBrandId()).getName()); spuBos.add(spuBo); }); return new PageResult<>(pageInfo.getTotal(), spuBos); } }
Category中拓展查询名称的功能
页面需要商品的分类名称需要在这里查询,因此要额外提供查询分类名称的功能,
在CategoryService中添加功能:
public List<String> queryNamesByIds(List<Long> ids) { List<Category> list = this.categoryMapper.selectByIdList(ids); List<String> names = new ArrayList<>(); for (Category category : list) { names.add(category.getName()); } return names; // return list.stream().map(category -> category.getName()).collect(Collectors.toList()); }
mapper的selectByIdList方法是来自于通用mapper。不过需要我们在mapper上继承一个通用mapper接口:
public interface CategoryMapper extends Mapper<Category>, SelectByIdListMapper<Category, Long> { }
测试
刷新页面,查看效果:
基本与预览的效果一致,OK!
2.商品新增
里面把商品的数据分为了4部分来填写:- 基本信息:主要是一些简单的文本数据,包含了SPU和SpuDetail的部分数据,如
- 商品分类:是SPU中的
cid1
,cid2
,cid3
属性 - 品牌:是spu中的
brandId
属性 - 标题:是spu中的
title
属性 - 子标题:是spu中的
subTitle
属性 - 售后服务:是SpuDetail中的
afterService
属性 - 包装列表:是SpuDetail中的
packingList
属性
- 商品分类:是SPU中的
- 商品描述:是SpuDetail中的
description
属性,数据较多,所以单独放一个页面 - 规格参数:商品规格信息,对应SpuDetail中的
genericSpec
属性 - SKU属性:spu下的所有Sku信息
对应到页面中的四个
stepper-content
:
品牌选择
页面需要去后台查询品牌信息,我们自然需要提供:
请求方式:GET
请求路径:/brand/cid/{cid}
请求参数:cid
响应数据:品牌集合
BrandController
@GetMapping("cid/{cid}") public ResponseEntity<List<Brand>> queryBrandsByCid(@PathVariable("cid")Long cid){ List<Brand> brands = this.brandService.queryBrandsByCid(cid); if (CollectionUtils.isEmpty(brands)) { return ResponseEntity.notFound().build(); } return ResponseEntity.ok(brands); }
BrandService
public List<Brand> queryBrandsByCid(Long cid) { return this.brandMapper.selectBrandByCid(cid); }
BrandMapper
根据分类查询品牌有中间表,需要自己编写Sql:
@Select("SELECT b.* from tb_brand b INNER JOIN tb_category_brand cb on b.id=cb.brand_id where cb.category_id=#{cid}") List<Brand> selectBrandByCid(Long cid);
商品描述
商品描述信息比较复杂,而且图文并茂,甚至包括视频。
这样的内容,一般都会使用富文本编辑器一款支持Vue的富文本编辑器:
vue-quill-editor
。
GitHub的主页:https://github.com/surmon-china/vue-quill-editorVue-Quill-Editor是一个基于Quill的富文本编辑器:Quill的官网
使用指南
使用非常简单:已经在项目中集成。以下步骤不需操作,仅供参考
第一步:安装,使用npm命令:
npm install vue-quill-editor --save
第二步:加载,在js中引入:
全局引入:
import Vue from 'vue' import VueQuillEditor from 'vue-quill-editor' const options = {}; /* { default global options } */ Vue.use(VueQuillEditor, options); // options可选
局部引入:
import 'quill/dist/quill.core.css' import 'quill/dist/quill.snow.css' import 'quill/dist/quill.bubble.css' import {quillEditor} from 'vue-quill-editor' var vm = new Vue({ components:{ quillEditor } })
我们这里采用局部引用:
第三步:页面使用:
<quill-editor v-model="goods.spuDetail.description" :options="editorOption"/>
自定义的富文本编辑器
不过这个组件有个小问题,就是图片上传的无法直接上传到后台,因此我们对其进行了封装,支持了图片的上传。<v-stepper-content step="2"> <v-editor v-model="goods.spuDetail.description" upload-url="/upload/image"/> </v-stepper-content>
- upload-url:是图片上传的路径
- v-model:双向绑定,将富文本编辑器的内容绑定到goods.spuDetail.description
可以看到这里是根据商品分类id查询规格参数:SpecParam。我们之前写过一个根据gid(分组id)来查询规格参数的接口,我们接下来完成根据分类id查询规格参数。
改造查询规格参数接口
我们在原来的根据 gid(规格组id)查询规格参数的接口上,添加一个参数:cid,即商品分类id。
等一下, 考虑到以后可能还会根据是否搜索、是否为通用属性等条件过滤,我们多添加几个过滤条件:
@GetMapping("params") public ResponseEntity<List<SpecParam>> queryParams( @RequestParam(value = "gid", required = false)Long gid, @RequestParam(value = "cid", required = false)Long cid, @RequestParam(value = "generic", required = false)Boolean generic, @RequestParam(value = "searching", required = false)Boolean searching ){ List<SpecParam> params = this.specificationService.queryParams(gid, cid, generic, searching); if (CollectionUtils.isEmpty(params)){ return ResponseEntity.notFound().build(); } return ResponseEntity.ok(params); }
改造SpecificationService:
/** * 根据gid查询规格参数 * @param gid * @return */ public List<SpecParam> queryParams(Long gid, Long cid, Boolean generic, Boolean searching) { SpecParam record = new SpecParam(); record.setGroupId(gid); record.setCid(cid); record.setGeneric(generic); record.setSearching(searching); return this.specParamMapper.select(record); }
如果param中有属性为null,则不会把属性作为查询条件,因此该方法具备通用性,即可根据gid查询,也可根据cid查询。
后台实现
实体类
SPU和SpuDetail实体类已经添加过,添加Sku和Stock(库存)对象:
Sku
@Table(name = "tb_sku") public class Sku { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Long spuId; private String title; private String images; private Long price; private String ownSpec;// 商品特殊规格的键值对 private String indexes;// 商品特殊规格的下标 private Boolean enable;// 是否有效,逻辑删除用 private Date createTime;// 创建时间 private Date lastUpdateTime;// 最后修改时间 @Transient private Integer stock;// 库存 }
注意:这里保存了一个库存字段,在数据库中是另外一张表保存的,方便查询。
Stock
@Table(name = "tb_stock") public class Stock { @Id private Long skuId; private Integer seckillStock;// 秒杀可用库存 private Integer seckillTotal;// 已秒杀数量 private Integer stock;// 正常库存 }
GoodsController
结合浏览器页面控制台,可以发现:
请求方式:POST
请求路径:/goods
请求参数:Spu的json格式的对象,spu中包含spuDetail和Sku集合。这里我们该怎么接收?我们之前定义了一个SpuBo对象,作为业务对象。这里也可以用它,不过需要再扩展spuDetail和skus字段:
public class SpuBo extends Spu { String cname;// 商品分类名称 String bname;// 品牌名称 SpuDetail spuDetail;// 商品详情 List<Sku> skus;// sku列表 }
- 返回类型:无
在GoodsController中添加新增商品的代码:
@PostMapping("goods") public ResponseEntity<Void> saveGoods(@RequestBody SpuBo spuBo){ this.goodsService.saveGoods(spuBo); return ResponseEntity.status(HttpStatus.CREATED).build(); }
注意:通过@RequestBody注解来接收Json请求
GoodsService
这里的逻辑比较复杂,我们除了要对SPU新增以外,还要对SpuDetail、Sku、Stock进行保存
/** * 新增商品 * @param spuBo */ @Transactional public void saveGoods(SpuBo spuBo) { // 新增spu // 设置默认字段 spuBo.setId(null); spuBo.setSaleable(true); spuBo.setValid(true); spuBo.setCreateTime(new Date()); spuBo.setLastUpdateTime(spuBo.getCreateTime()); this.spuMapper.insertSelective(spuBo); // 新增spuDetail SpuDetail spuDetail = spuBo.getSpuDetail(); spuDetail.setSpuId(spuBo.getId()); this.spuDetailMapper.insertSelective(spuDetail); saveSkuAndStock(spuBo); } private void saveSkuAndStock(SpuBo spuBo) { spuBo.getSkus().forEach(sku -> { // 新增sku sku.setSpuId(spuBo.getId()); sku.setCreateTime(new Date()); sku.setLastUpdateTime(sku.getCreateTime()); this.skuMapper.insertSelective(sku); // 新增库存 Stock stock = new Stock(); stock.setSkuId(sku.getId()); stock.setStock(sku.getStock()); this.stockMapper.insertSelective(stock); }); }
Mapper
都是通用Mapper,略
目录结构:
3.商品修改
查询SpuDetail接口
GoodsController
需要分析的内容:
- 请求方式:GET
- 请求路径:/spu/detail/{id}
- 请求参数:id,应该是spu的id
- 返回结果:SpuDetail对象
@GetMapping("spu/detail/{spuId}") public ResponseEntity<SpuDetail> querySpuDetailBySpuId(@PathVariable("spuId")Long spuId){ SpuDetail spuDetail = this.goodsService.querySpuDetailBySpuId(spuId); if (spuDetail == null) { return ResponseEntity.notFound().build(); } return ResponseEntity.ok(spuDetail); }
GoodsService
/** * 根据spuId查询spuDetail * @param spuId * @return */ public SpuDetail querySpuDetailBySpuId(Long spuId) { return this.spuDetailMapper.selectByPrimaryKey(spuId); }
查询sku
分析
- 请求方式:Get
- 请求路径:/sku/list
- 请求参数:id,应该是spu的id
- 返回结果:sku的集合
GoodsController
@GetMapping("sku/list") public ResponseEntity<List<Sku>> querySkusBySpuId(@RequestParam("id")Long spuId){ List<Sku> skus = this.goodsService.querySkusBySpuId(spuId); if (CollectionUtils.isEmpty(skus)) { return ResponseEntity.notFound().build(); } return ResponseEntity.ok(skus); }
GoodsService
需要注意的是,为了页面回显方便,我们一并把sku的库存stock也查询出来
/** * 根据spuId查询sku的集合 * @param spuId * @return */ public List<Sku> querySkusBySpuId(Long spuId) { Sku sku = new Sku(); sku.setSpuId(spuId); List<Sku> skus = this.skuMapper.select(sku); skus.forEach(s -> { Stock stock = this.stockMapper.selectByPrimaryKey(s.getId()); s.setStock(stock.getStock()); }); return skus; }
页面回显
随便点击一个编辑按钮,发现数据回显完成:
页面提交
这里的保存按钮与新增其实是同一个,因此提交的逻辑也是一样的,这里不再赘述。
随便修改点数据,然后点击保存,可以看到浏览器已经发出请求:
后台实现
接下来,我们编写后台,实现修改商品接口。
GoodsController
- 请求方式:PUT
- 请求路径:/
- 请求参数:Spu对象
- 返回结果:无
@PutMapping("goods") public ResponseEntity<Void> updateGoods(@RequestBody SpuBo spuBo){ this.goodsService.updateGoods(spuBo); return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); }
GoodsService
spu数据可以修改,但是SKU数据无法修改,因为有可能之前存在的SKU现在已经不存在了,或者以前的sku属性都不存在了。比如以前内存有4G,现在没了。
因此这里直接删除以前的SKU,然后新增即可。
代码:
@Transactional public void updateGoods(SpuBo spu) { // 查询以前sku List<Sku> skus = this.querySkuBySpuId(spu.getId()); // 如果以前存在,则删除 if(!CollectionUtils.isEmpty(skus)) { List<Long> ids = skus.stream().map(s -> s.getId()).collect(Collectors.toList()); // 删除以前库存 Example example = new Example(Stock.class); example.createCriteria().andIn("skuId", ids); this.stockMapper.deleteByExample(example); // 删除以前的sku Sku record = new Sku(); record.setSpuId(spu.getId()); this.skuMapper.delete(record); } // 新增sku和库存 saveSkuAndStock(spuBo); // 更新spu spu.setLastUpdateTime(new Date()); spu.setCreateTime(null); spu.setValid(null); spu.setSaleable(null); this.spuMapper.updateByPrimaryKeySelective(spu); // 更新spu详情 this.spuDetailMapper.updateByPrimaryKeySelective(spu.getSpuDetail()); }
-
-
货品管理.doc
2021-09-13 15:01:10货品管理.doc -
「超市管理系统——商品管理」 · Java Swing + MySQL JDBC开发
2020-09-16 16:46:56Java(SWING+JDBC),MySql B、开发环境 MyEclipse 9.0及以上版本,MySql 5.6及以上版本 二、要求 利用SWING编程实现商品的管理,要求如下: 1、商品管理页面布局,添加一个JScrollPanel(内嵌JTable),用来显示所有... -
服装品牌代理商-货品管理体系.docx
2022-01-13 17:33:40服装品牌代理商-货品管理体系.docx