有个人家开店,店里商品堆积越来越多,多了就不好管理了,那有没有想过需要类似于商品管理的一套小程序呢,这里给大家提供一个容易上手的商品管理微信小程序解决方案,非常适合新手学习入门。
先说明一下这里讲得是一个微信小程序项目,非常适合熟悉使用微信开发工具开发的同学阅读。
一. 流程图
这是在微信的扫码功能基础上开发的,主要功能类似于仓库管理,有清单结算,先看如下流程图,之后的拓展应用可以根据自己的需求改动项目源码添加。
二. 展示数据
想好了小程序页面需要展示的哪些数据,然后细分,分别为清单页,账单页,商品页,展示数据模型,如下图所示
三. 页面设计
理解清楚了,那么接下来,打开微信开发者工具,新建一个项目,选择小程序,逻辑代码就选Javascript,项目创建好后,只需要做四个页面就好,在小程序项目的app.json
文件里,参考如下代码中的pages
展开的四个页面路径,
在做页面之前,需要在中添加一段代码,代码如下,展开的tabBar
就是添加页面底部展示的分页选项卡,
{
"pages": [
"pages/index/index",
"pages/bill/bill",
"pages/goods/goods",
"pages/edit/edit",
//...
],
"window": {
"navigationBarTitleText": "商品管理",
//...
},
//...
"tabBar": {
"list": [
{
"text": "清单",
"pagePath": "pages/index/index",
"iconPath": "static/icon/dingdan.png",
"selectedIconPath": "static/icon/dingdan2.png"
},
{
"text": "账单",
"pagePath": "pages/bill/bill",
"iconPath": "static/icon/qupiao.png",
"selectedIconPath": "static/icon/qupiao2.png"
},
{
"text": "商品",
"pagePath": "pages/goods/goods",
"iconPath": "static/icon/yinhangka.png",
"selectedIconPath": "static/icon/yinhangka2.png"
}
]
}
}
1. 清单页
清单页index.wxml
是扫码添加商品的列表页面,类似于购物车,也是用扫码枪记录的待结算商品清单,它的布局大致如下图所示,有两个按钮,一个扫码,另一个结算。
2. 修改页
商品修改页edit.wxml
,就是添加或修改商品信息的页面,用表单组件布局就可以,如下图所示,如果是添加商品,底下按钮是会变成添加按钮的
3. 账单页
账单页bill.wxml
,是记录结算产生的账单的列表展示页面,方便自己核实账单,它的布局大致如下图所示
4. 商品页
商品页goods.wxml
,是展示商品列表的,也是仓库的展示页面,它的布局大致如下图所示,如果商品太多,就点列表头部的搜索,方便找到
四. 页面逻辑
页面的逻辑其实很简单,如果按照之前做的流程图一路写下来,就会发现写得逻辑代码越来越多,就需要及时处理分离开,减少相互影响,把所有页面需要用到的公共变量放一个全局变量中,就在项目app.js
文件里的globalData
去添加,参考代码如下
// app.js
App({
onLaunch() {
//如果是开发环境,就假设一些数据用于测试
const { platform } = wx.getSystemInfoSync();
if (platform=='devtools') {
//...
} else {
// 展示本地存储能力
const { goods, logs } = uni.getStorageSync(...);
}
},
//不用前保存数据缓存
onHide(){
//...
wx.setStorage({...})
},
globalData: {
goods:[],//商品
bills:[],//账单
},
})
1. 清单页
清单的页面逻辑index.js
,就是管理列表的增删改简单逻辑了,还有扫码和结算的逻辑需要写,代码如下,
// index.js
// 获取应用实例
const App = getApp()
Page({
data: {
list:[],
count:0,
sum:0.00,
},
//打开小程序会首先加载第一个页面,这里写初始化
onLoad() {
//将全局变量中的goods复制一份给list,用于显示清单列表
//注意这里仅限测试用,在正式场景这里list是个空数组,无需关心
let list = App.globalData.goods.map(g=>{...});
this.reloadList(list);
},
//按钮点击事件
onclick(e){
const { com } = e.currentTarget.dataset;
switch(com){
case 'calc'://结算按钮被点击
{
const { count, sum, list } = this.data;
//...省略了处理结算的逻辑
wx.showToast({
title:'结算完成',
icon:'success',
success:()=>{
this.setData({
list:[],
count:0,
sum:0.00
});
}
});
break;
}
case 'scan'://扫码按钮被点击
{
wx.scanCode({
onlyFromCamera: true,
scanType:['barCode'],
success:(res)=>{
const { result } = res;
let goods = {
name:'',
code:result,
price:1.00,
count:1,
unit:0,
no:''
};
const { goods:gGoods } = App.globalData;
let index=gGoods.findIndex(g=>g.code==goods.code);
if(index<0){
wx.showModal({
title:'系统提示',
content:'商品不存在,是否先录入库?',
success: (res) => {
if(!res.confirm) return;
this.addAndEditGoods(goods,index,(res)=>{
//...省略添加逻辑
wx.showToast({
title:'已入库',
icon:'success',
success() {}
});
});
}
});
return;
}
const { list } = this.data;
let count=goods.count;
//...省略处理数量的逻辑
if(gGoods[index].count<count){
wx.showModal({
title:'系统提示',
content:'此商品剩余数量不足,请及时补充',
showCancel:false,
success: (res) => {}
})
}
//...省略处理添加或者更新的逻辑
this.reloadList(list);
},
fail:(err)=>{...}
})
break;
}
}
},
//清单列表项点击事件
onclickitem(e){
const { index } = e.currentTarget.dataset;
wx.showActionSheet({
itemList: ['1.删除','2.修改'],
success:(res)=>{
const { list } = this.data;
switch(res.tapIndex){
case 0://删除后重新加载列表
list.splice(index,1);
this.reloadList(list);
break;
case 1://修改后重新加载列表
this.addAndEditGoods(list[index],index,(res)=>{
//...省略更新的逻辑
this.reloadList(list);
});
break;
}
}
})
},
//重新加载列表
reloadList(list){
this.setData({
list,
count:list.reduce((pre,cur)=>pre+=cur.count,0),
sum:list.reduce((pre,cur)=>pre+=cur.count*cur.price,0)
});
},
//添加或者修改商品信息的
addAndEditGoods(goods,index=-1,success){
//打开修改商品信息的页面,参数index默认-1表示为添加商品模式
wx.navigateTo({
url: '/pages/edit/edit',
events:{
success:(res)=>{
if(!res.goods) return;
success(res);//添加或者修改后就调用回调success方法处理最后的任务
}
},
success:(res)=>res.eventChannel.emit('msg',{index,goods}),//打开页面后传参数
})
}
})
代码是有点多,尽量省略了,在方法
reloadList()
里,结算时用到了数组的函数reduce()
,写够一行就能算出总数,或者总金额,只要正确理解它就发现很好用,不用再写好几行代码,学到了吗
2. 修改页面
修改商品页面edit.js
,逻辑很简单把,就处理表单和初始化和提交修改就可以
// pages/edit/edit.js
Page({
/**
* 页面的初始数据
*/
data: {
index:-1,
//...
result:null,
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
this.getOpenerEventChannel().once('msg',res=>{
const { index, goods:g } = res;
this.index=index;
//得到传递过来的参数,初始化表单数据
this.setData({...});
})
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
//当页面关闭了,就返回结果
this.getOpenerEventChannel().emit('success',{
index:this.data.index,
goods:this.data.result
});
},
onsubmit(e){
const { value } = e.detail;
//...这里省略处理表单提交的信息
this.data.result = value;
wx.navigateBack()
}
})
3. 账单页面
账单页面的逻辑bill.js
,只处理显示列表就可以,如果需要,可以添加一个点击删除事件处理
// pages/bill/bill.js
const App = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
list:[],
},
/**
* 页面相关事件处理函数--监听用户点击底部选项卡动作
*/
onTabItemTap(e){
let list = App.globalData.bills;
this.setData({
list
});
},
onclickitem(e){
const { index } = e.currentTarget.dataset;
wx.showActionSheet({
itemList: ['1.删除'],
success:(res)=>{
switch(res.tapIndex){
case 0:
this.data.list.splice(index,1);
this.onTabItemTap();
break;
}
}
})
}
})
4. 商品页面
商品页面的逻辑goods.js
,是一个操作列表的相关逻辑,比之前的要复杂一点,多了一个查询的逻辑,来看看怎么写得
// pages/goods/goods.js
const App = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
count:0,
sum:0.00,
fList:App.globalData.goods,
},
/**
* 监听页面的搜索按钮点击
*/
onsubmit(e){
const { kw } = e.detail.value;
this.reloadList(kw);
},
/**
* 页面相关事件处理函数--监听用户点击底部选项卡动作
*/
onTabItemTap(e){
this.reloadList();
},
reloadList(kw=''){
//...省略搜索过滤处理的逻辑
this.setData({...})
},
onclickitem(e){
const { index } = e.currentTarget.dataset;
wx.showActionSheet({
itemList: ['1.删除','2.修改'],
success:(res)=>{
const { fList:goods } = this.data;
switch(res.tapIndex){
case 0:
goods.splice(index,1);
this.reloadList();
break;
case 1:
wx.navigateTo({
url: '/pages/edit/edit',
events:{
success:(res)=>{
if(!res.goods) return;
//...省略更新处理的逻辑
this.reloadList();
}
},
success:(res)=>res.eventChannel.emit('msg',{index,goods:goods[index]})
});
break;
}
}
})
}
})
就讲到这里,最后给看一下项目的整个目录截图,如下图所示,
- 小程序项目
- components …自定义组件文件夹
- num-money …处理金额两位小数显示的
- time-tostring …处理时间格式显示的
- pages …页面文件夹
- bill … 账单页面文件夹
- edit …修改页面文件夹
- goods …商品页面文件夹
- index …清单页面文件夹
- static …图标资源文件夹
- icon …存放一些图标文件的
- utils …公用函数文件夹
- common.wxs …这是页面模板公用的处理方法文件,例如数量单位转换
- app.js …小程序入口的逻辑文件
- app.json …小程序主要配置文件
- app.wxss …小程序主要样式文件
- …其它一些文件由微信开发者工具创建项目时生成,一般不用管
- components …自定义组件文件夹
整个项目写得文件不是很多的,能看懂吧,应该适合新手研究学习,上面只是展示了重要代码部分,方便理解,还有相关的页面布局wxml文件和样式wxss文件怎样弄,还有用到的自定义组件怎么写,都写在项目源码里的,在这里就不贴上去了,文章不能写得过长哈,
如有需要完整项目源码的就去本作者的资源一栏查找相关的项目源码(下载点这里)下载即可,如遇到什么问题请留言,得到答复可能会慢很多,谢谢理解!