1.项目背景
受到疫情影响,农作物物流运输受阻、产品滞销,给农民的“菜园子”和市民的“菜篮子”带来不少影响,一边是农民种植的蔬菜、草莓等地产农副食品滞销,一边是城区居民买不到新鲜、实惠的农副产品。
有很多地区,农民伯伯们因为住所偏僻、没有好的销售渠道、没有固定的客户,导致种的农作物和自家生产的产品,没有地方销售,而且还有一些中间商从他们手中低价够买,然后再高价售出;现在的助农团队一般是由团队操作的,也会上门收农产品,但是价格也压的很低。
根据调查,农业经营户表示,在2月中后期,逐步恢复农业生产。目前在恢复农业生产经营面临的主要困难在于:一是市场需求不足,产品不好卖(38.6%);二是人员出入管控措施,导致无法正常经营(37.7%);三是资金困难(23.7%)。 面对这一困境,我们组制定“益农”项目来解决上述问题。
2.技术体系
2.1MVC
MCV框架是一种软件架构模式,用于将应用程序的逻辑分离成不同的组件,以实现模块化和可维护性。MCV代表模型(Model)、视图(View)和控制器(Controller)。
模型(Model)是应用程序的数据和业务逻辑的表示。它负责处理数据的存储、检索和更新,并实现与数据相关的任何业务逻辑。模型通常被设计为独立于用户界面的组件。
视图(View)是应用程序的用户界面的表示。它负责显示数据给用户,并根据用户的输入和交互更新界面。视图通常是与具体平台相关的组件,可以是图形界面、命令行界面或网页界面。
控制器(Controller)是模型和视图之间的中间件。它负责接收用户输入并将其转发给模型进行处理,然后更新视图以反映模型的状态变化。控制器还可以管理应用程序的工作流程和协调模型和视图之间的通信。
MCV框架的主要优势包括:
(1)分离关注点:MCV框架通过将应用程序的不同方面分离成不同的组件,使得每个组件可以专注于自己的任务,提高了代码的可维护性和可重用性。
(2)模块化开发:由于MCV框架的模块化结构,开发人员可以并行开发不同的组件,提高了开发效率。
(3)可测试性:MCV框架将业务逻辑从用户界面中分离出来,使得业务逻辑的单元测试更容易实现。
(4)可扩展性:通过将模型、视图和控制器分离,MCV框架可以支持应用程序的功能和规模的增长,而不会引入太多的复杂性。
然而,MCV框架也有一些限制和挑战。例如,控制器可能变得过于庞大,导致代码的复杂性增加。此外,MCV框架需要开发人员熟悉和遵循特定的设计规范和约定,以确保正确实施框架。最后,MCV框架可能不适用于所有类型的应用程序,特别是那些没有明确定义的用户界面的应用程序。
2.2小程序技术
小程序是一种轻量级的应用程序,可以在手机等移动设备上运行,不需要用户下载安装即可直接使用。小程序通常以单个页面的形式呈现,提供特定的功能或服务,并具有较小的体积和快速的加载速度。
小程序技术主要有以下几个方面:
(1)前端开发技术:小程序前端开发主要使用的是Web前端开发技术,如HTML、CSS和JavaScript。开发者可以使用类似于网页的开发方式,通过编写HTML和CSS定义界面样式,通过JavaScript实现交互逻辑。
(2)框架和库:目前市场上主要有微信小程序和支付宝小程序两种主流平台。微信小程序使用基于JavaScript的框架Taro、mpVue、mpx等进行开发,支付宝小程序使用基于React框架的Antmove进行开发。这些框架和库提供了丰富的组件和API,简化了小程序的开发过程。
(3)后端服务和接口:小程序通常需要与后端服务器进行数据交互,获取数据并进行处理。开发者可以使用各种后端技术,如Node.js、Java、Python等,来编写后端服务和接口。后端服务可以提供数据存储、用户认证、业务逻辑处理等功能。
(4)数据库:小程序通常需要使用数据库来存储和管理数据。常见的数据库包括关系型数据库如MySQL、PostgreSQL,以及NoSQL数据库如MongoDB、Redis等。开发者可以根据具体需求选择合适的数据库。
(5)跨平台技术:为了在不同平台上运行小程序,开发者可以使用跨平台技术来实现一次开发,多平台适配。例如,uni-app和Weex等框架可以将小程序代码转换为不同平台的原生应用程序代码。
小程序技术的主要优势包括:低成本、快速开发、无需下载安装、节省设备资源、良好的用户体验等。然而,小程序也有一些限制,如功能受限、对硬件访问的限制、平台依赖性等。因此,在选择小程序技术时,需要根据具体需求和目标平台进行评估和选择。
3.功能介绍
(1)平台共设有采摘园、线上购买、在线直播、用户中心四个界面,主要是让顾客可以下采摘订单,去采摘园自己动手采摘产品;也可以线上购买,快递到家;可以通过在线直播观看农产品采摘过程,了解农产品的质量、口感,实现采摘-打包-发货全程关注。
(2)用户中心有顾客基本信息、订单详情。用户在使用“益农”时需要进行注册,包括用户名、密码、手机号、收货地址。
(3)采摘园主要是根据用户位置信息推荐附近农场、水果园,用户根据自己的兴趣爱好,选择园区,进行了解和预约。
(4)线上购买主要是顾客根据需求自行选择进行农产品的购买。
(5)在线直播主要有两种方式,一种是农场主对自己的农产品进行直播介绍,另一种是由采摘园的顾客直播分享采摘的过程与乐趣,可以在评论区进行评论交流。
4.小组成员分工
成员1:小组成员共同商讨完成项目策划书
成员2:主要制作PPT,编写数据库表格和增、删、改代码、填写实习报告。
成员3:主要制作小程序首页和购物车页面
成员4:主要制作直播页面、订单页面填写实习报告。
5.成果展示
6.核心代码
<!--pages/index.wxml--> <view class="container"> <swiper indicator-dots="true" autoplay="true" interval="{{swiper.interval}}" circular="{{swiper.circular || true }}" duration="{{swiper.duration}}" indicator-color="rgba(255, 255, 255, .3)" indicator-active-color="rgb(255, 80, 0)"> <block wx:for="{{swiper.imgsUrl}}" wx:key="index_swiper"> <swiper-item> <image src="{{item}}" class="slide-image"/> </swiper-item> </block> </swiper> <view class="DFrames"> <view class="layOut"> <block wx:for="{{DFrames.layOut}}" wx:key="index_DFrames"> <view class="layOut-item" data-route="{{item.route}}" bindtap='goto'> <image src="{{item.imgUrl}}"></image> <text class="layOut-item-text">{{item.text}}</text> </view> </block> </view> <view class="layOut-bg" style="background-image: url({{DFrames.bg}});"></view> </view> <view class="topLine"> <swiper circular="true" autoplay="true" interval="{{topLine.interval}}" duration="{{topLine.duration}}" vertical="true"> <block wx:for="{{topLine.tips}}" wx:key="index_topLine"> <swiper-item> <view class="topline-item"> <view class="topline-item-text"> <text class="topline-item-category">{{item.category1}}</text> <text class="topline-item-content">{{item.text1}}</text> </view> <view class="topLine-item-text"> <text class="topline-item-category">{{item.category2}}</text> <text class="topline-item-content">{{item.text2}}</text> </view> </view> </swiper-item> </block> </swiper> </view> <view class="recommend"> <block wx:for="{{recommend}}" wx:key="index_recommend"> <view class="rcd-item"> <view class="rcd-item-left"> <view class="rcd-item-title" style="background-image: url({{item.title}})"></view> <view class="rcd-item-subTitle" wx:if="item.subTitle">{{item.subTitle}}</view> <image src="{{item.imgUrl1}}"></image> </view> <view class="rcd-item-right"> <view class="rcd-item-right-bg" style="background-image: url({{item.imgUrl2}})"></view> </view> </view> </block> </view> <view class="TBlive"> <view class="live-show"> <view class="live-show-top"> <view class="show_top_title" style="background-image: url({{TBlive.top_bg}})"></view> <view class="show-top-left"> <view class="show-top-left-content" style="background-image: url({{TBlive.top_left_bg}})"> <view class="show_bg_mask" style="background-image: url({{TBlive.bg_mask}})"></view> <text class="top_left_title">{{TBlive.top_left_title}}</text> <text class="top_left_subTitle">{{TBlive.top_left_subTitle}}</text> <view class="show_top_heart" style="background-image: url({{TBlive.top_heart}})"></view> </view> </view> <view class="show-top-right"> <view class="show-top-right-content" style="background-image: url({{TBlive.top_right_bg}})"> <view class="show_bg_mask" style="background-image: url({{TBlive.bg_mask}})"></view> <text class="top_left_title">{{TBlive.top_right_title}}</text> <text class="top_left_subTitle">{{TBlive.top_right_subTitle}}</text> </view> </view> </view> <view class="live-show-bottom"> <view class="live-show-btm-content"> <block wx:for="{{TBlive.btm}}" wx:key="TBliveBottom"> <!-- <block v-if="{{index == 1}}"> </block> --> <view class="show-btm-item {{index == 1 ? 'show-btm-item-center' : ''}}"> <view class="show-btm-item-top" style="background-image: url({{item.bg}})"> <view class="btm-live-bg" style="background-image: url({{TBlive.btm_live_bg}})"></view> </view> <view class="show-btm-item-btm"> <view><text class="show-btm-title">{{item.title}}</text></view> <view><text class="show-btm-subTitle">{{item.subTitle}}</text></view> <view></view> </view> </view> </block> </view> </view> </view> </view> </view> <view class="container"> <!-- 顶部固定栏 --> <view class="catalogue flex text-normal text-999"> <view wx:for="{{sections}}" wx:key="{{index}}" class="catalogue-item {{ currSection === (index + 1) ? 'active' : '' }}">{{item}}</view> <!-- <view class="catalogue-item active">商品</view> <view class="catalogue-item">评价</view> <view class="catalogue-item">详情</view> --> </view> <view class="observe" data-observe="1"> <!-- 轮播图 --> <view class="section-top"> <swiper class="swiper" indicator-dots="false" indicator-color="transparent" indicator-active-color="transparent" autoplay="{{false}}" duration="300" bindchange="swiperChange"> <swiper-item wx:for="{{swiper}}" wx:key="{{index}}"> <image src="{{item}}" class="slide-image"/> </swiper-item> </swiper> <view class="swiper-curr">{{currSwiper}}/{{swiper.length}}</view> </view> <!-- 商品信息 --> <view class="section"> <view><text class="price">¥399.00</text></view> <view><text class="introd">唐狮2019春秋新款工装男外套青少年立领运动港风</text></view> </view> <!-- 选择和参数 --> <view class="section"> <view class="section-item text-normal" bindtap="showSelectBox"><text class="text-sm">选择 </text>请选择颜色尺码<image class="more" src="../../assert/imgs/more.png"></image></view> <view class="section-item text-normal" bindtap="showParamsBox"><text class="text-sm">参数 </text>品牌 尺码...<image class="more" src="../../assert/imgs/more.png"></image></view> </view> </view> <view class="observe" data-observe="2"> <!-- 商品评价 --> <view class="section"> <view class="box-header"> <text class="comment text-normal">商品评价 ({{commentLen || 0}})</text> <navigator url="/pages/comments/comments" class="text-danger text-normal pull-right"> <view >查看全部<image class="more" src="../../assert/imgs/more.png"></image></view> </navigator> </view> <view class="box-body"> <comment></comment> </view> </view> <!-- 店家信息 --> <view class="section"> <shop></shop> </view> <!-- 看了又看 --> <wxs module="common" src="../../filters/common.wxs"></wxs> <view class="section"> <view class="box-header"><text class="text-sm text-333">看了又看</text></view> <view class="box-body"> <view class="flex recomend"> <block wx:for="{{recomends}}" wx:key="{{index}}"> <view class="recomend-item {{ index == 0 ? 'text-left' : index == 1 ? 'text-center' : 'text-right'}}"> <image class="recomend-img" src="{{item.img}}"></image> <text class="recomend-text text-sm line2 text-333">{{item.text}}</text> <view class="recomend-oldPrice lineThrough text-sm text-ccc">{{common.num2Money(item.oldPrice)}}</view> <view class="recomend-newPrice text-sm text-333">{{common.num2Money(item.newPrice)}}</view> </view> </block> </view> </view> </view> </view> <!-- 详情 --> <view class="observe" data-observe="3"> <view class="details flex"> <view class="bar"></view> <view class="text-sm text-ccc details-text">详情</view> <view class="bar"></view> </view> <!-- 商品标题 --> <view class="section text-center"> <text class="text-lg">"简约不简单 夏季好搭配"</text> </view> <!-- 商品详情图片 --> <view> <image wx:for="{{detailImgs}}" wx:key="{{index}}" src="{{item}}" class="detail-imgs-item" mode="widthFix"></image> </view> </view> <!-- 底部固定栏 加入购物车 --> <view class="buy flex"> <view class="buy-item flex"> <view class="link flex"> <view class="icon icon-shop"></view> <text class="text-sm">店铺</text> </view> <view class="link flex"> <view class="icon icon-service"></view> <text class="text-sm">客服</text> </view> <view class="link flex" bindtap="collect"> <view class="icon {{ iscollected ? 'icon-collected' : 'icon-collect' }}"></view> <text class="text-sm">收藏</text> </view> </view> <view class="buy-item flex flex-center bg-yellow text-lg text-fff" data-footerType="true" bindtap="showSelectBox">加入购物车</view> <view class="buy-item flex flex-center bg-red text-lg text-fff" data-footerType="true" bindtap="showSelectBox">立即购买</view> </view> <!-- 商品规格选择弹窗 --> <select-box shopInfo="{{shopInfo}}" id="selectBox"></select-box> <!-- 参数弹窗 --> <params-box id="paramsBox"></params-box> </view>
7.PPT展示效果