文字目录:
目录
[2 技术介绍](#2 技术介绍)
[2.1 thinkphp5介绍](#2.1 thinkphp5介绍)
[2.2 MySQL数据库](#2.2 MySQL数据库)
[2.3 B/S结构](#2.3 B/S结构)
前言:
💗博主介绍:
✌全网粉丝100W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗
👇🏻 精彩专栏 推荐订阅👇🏻
🌟文末获取源码+数据库🌟
详细视频演示
文章底部名片或者私信我!!,联系我看更详细的演示视频
系统实现界面
在上一章中,对本论文中的购物网站进行了全面的系统设计。接下来第五章对本购物网站的实现过程进行说明,包括对购物网站所需的开发环境、运行环境的说明以及对上一章中提到的各种内容的实现。
1.1系统开发环境以及运行环境
1.1.1系统开发环境
表1-1 开发环境
|-----------|-----------|
| 开发使用的操作系统 | Windows10 |
| 开发使用的编程语言 | PHP |
| 开发框架选择 | ssm |
| 选取的数据库 | MySQL |
1.1.2系统运行环境
本购物网站的运行环境如表5-2所示。
表5-2 客户端运行环境
|----------|-----------|
| 运行使用操作系统 | Windows10 |
| 客户端软件 | Chrome浏览器 |
1.2系统功能实现
当人们打开系统的网址后,首先看到的就是首页界面。在这里,人们能够看到购物网站的导航条,通过导航条进入各信息展示页面进行操作。系统首页界面如图5-1所示:
图5-1 系统首页界面
系统注册:在系统注册页面的输入栏中输入用户注册信息进行注册操作,系统注册页面如图5-2所示商品信息:在商品信息页面的输入栏中输入商品名称、选择商品分类、品牌和价格进行查询,可以查看到商品详情信息,并根据需要进行赞一下、踩一下、收藏、添加到购物车、立即购买或评论等操作;如图5-3所示
购物公告:在购物公告页面的输入栏中输入标题进行查询,可以查看到购物公告详情信息;如图5-4所示
图5-4购物公告详细页面
个人中心:在个人中心页面通过填写个人详细信息进行信息更新操作,还可以对我的订单、我的地址和我的收藏进行详细操作;如图5-5所示
1.3管理员模块实现
管理员登录,在登录页面正确输入用户名和密码后,进入操作系统进行操作;如图5-6所示管理员进入主界面,主要功能包括对个人中心、用户管理、商品信息管理、商品分类管理、系统管理、订单管理等进行操作。如图5-7所示
图5-7 管理员主界面
管理员点击用户管理。在用户页面输入账号和姓名进行查询、新增或删除用户列表,并根据需要对用户详情信息进行详情、修改或删除操作;如图5-8所示管理员点击商品信息管理。在商品信息页面输入商品名称、选择商品分类、品牌和价格进行查询、新增或删除商品信息列表,并根据需要对商品详情信息进行详情、修改、查看评论或删除操作;如图5-9所示
图5-9商品信息管理界面
管理员点击商品分类管理。在商品分类页面输入商品分类进行查询、新增或删除商品分类列表,并根据需要对商品分类详情信息进行修改或删除操作;如图5-10所示管理员点击系统管理。在购物公告页面输入标题进行查询、新增或删除购物公告列表,并根据需要对购物公告详情信息进行详情、修改或删除操作;还可以对轮播图管理和在线客服进行详细操作;如图5-11所示管理员点击订单管理。在已支付订单页面输入订单编号和商品名称进行查询或删除已支付订单列表,并根据需要对已支付订单详情信息进行详情、发货或删除操作;还可以对已完成订单、已取消订单、已退款订单、未支付订单和已发货订单进行详细操作;如图5-12所示
2 技术介绍
在这一章中,主要是罗列出实现系统将采用的技术框架并对其做简单介绍。本论文中的购物网站使用当下主流的PHP开发。系统前端的业务逻辑以及数据展示来实现,系统的底层数据库选用了关系型数据库MySQL。
2.1 thinkphp5介绍
ThinkPHP是一个免费开源的,快速、简单的面向对象的轻量级PHP开发框架,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。遵循Apache2开源许可协议发布,意味着你可以免费使用ThinkPHP,甚至允许把你基于ThinkPHP开发的应用开源或商业产品发布/销售。
2.2 MySQL数据库
MySQL是一个小型,廉价,快速的开源数据库。本系统对大量的数据进行了全面的支持,可以同时处理数百万的数据,在调试、管理、优化等方面都有较大的优势。它支持 SQL语句的通用规格,使用非常灵活和安全的授权和口令。虽然 Sql服务器易于使用,并且可以存储大量的数据,但是它比 MS Sql服务器要好得多。但是在网络连接的速度上,无法实现实时、高效的目的。因此,尽管 MySql有很大的缺陷,但是它的可移植性,支持多线程,优化查询算法,这使得 MySql在个人和中小型企业中非常流行[8]。
2.3 B/S结构
B/S(浏览器/服务器)结构是目前主流的网络化的结构模式,它能够把系统核心功能集中在服务器上面,可以帮助系统开发人员简化操作,便于维护和使用。只需要用户在客户端安装360浏览器、谷歌浏览器、QQ浏览器等当前大众浏览器,在电脑里面安装sqlserver、mysql数据库等数据库。安装好的浏览器与服务器端的数据库进行信息数据的交互。很多专门软件能够做到的事情,采用B/S结构模式也能实现,它能够结合Web浏览器技术,ActiveX技术以及多种脚本语言等技术。帮助程序开发者节约了不少开发成本。目前B/S结构成为程序开发主流结构,它最好的地方就是没有地点限制还不用专门安装软件,笔记本或者电脑能够上网就能访问系统。系统使用B/S进行开发在后期系统维护上面就会很省事,不用什么问题都在服务器上面操作,简单的客户端处理就解决部分问题,开发出来的程序跟用户交互性上面也会增强,还可以实时刷新浏览器进行程序局部的数据信息更新
系统设计:
4.1系统结构设计
随着互联网的兴起以及国内外许多B/S架构的优秀系统被广泛使用而变得流行,B/S架构成为了系统开发的主流。本论文中的购物网站也同样采用了B/S架构标准的三层架构,即将整个系统划分为表现层、业务层和持久层这三层,并且在表现层采用MVC设计模型。
采用B/S架构,整个系统的核心业务逻辑都被放在服务器端,使得开发过程变得方便。虽然这会使得服务器端的压力较大,但在Ajax等技术兴起后,在前端也就是浏览器端也可以实现部分业务逻辑,一定程度上分担了服务器的压力。
同时,该系统采用的B/S架构,将整个系统进行分层。在表现层,主要负责处理从客户端接收到的请求,根据请求内容进行处理后向客户端响应结果。在业务层中,囊括了整个系统的核心业务逻辑,它位于数据访问层之上表现层之下,表现层的请求发送至业务层,业务层将根据编写好的业务逻辑与数据层进行交互。但是每个层之间是不具有必然联系的,表现层的请求发送至业务层,业务层在接受到后可以不进行处理,这并不会导致整个系统出现错误。所以只要层与层之间交互的接口不发生变化,某一层的变更并不会对其它层产生影响。所以这种架构的系统实际上很易于扩充,只要表现层有新的请求发送给业务层,业务层只要有相应的处理逻辑就好了,所以业务逻辑层的设计是十分重要的。而在持久层,主要进行的就是数据的存取,也就是和数据库打交道。
以上这种对程序进行分层的方式,可以使开发者专注于结构中的某一层,每一层要进行的工作十分明确,降低了耦合性,这种标准化的开发方式,有利于程序的复用,也极大地降低了之后对系统功能扩充和维护的成本。
4.2系统功能结构设计图
所涉及到的有关的功能,都是用功能结构图来简洁和清晰的表示出来,功能结构图就是能够把比较复杂的功能结构用图的形式清晰的描绘下来,并且为后续的设计以及测试等模块提供了明确的方向,在构思功能结构图的时候,便可以给设计的过程带来一定的思维导向,不至于在设计过程中有所遗漏,可以尽可能的明确系统所涉及到的功能。
系统的总体功能结构图如图4-1所示
参考代码:
html
<template>
<div
class="theme-container"
:class="pageClasses"
@touchstart="onTouchStart"
@touchend="onTouchEnd"
>
<Navbar
v-if="shouldShowNavbar"
@toggle-sidebar="toggleSidebar"
/>
<div
class="sidebar-mask"
@click="toggleSidebar(false)"
></div>
<Sidebar
:items="sidebarItems"
@toggle-sidebar="toggleSidebar"
v-show="showSidebar"
>
<slot
name="sidebar-top"
#top
/>
<slot
name="sidebar-bottom"
#bottom
/>
</Sidebar>
<!-- 首页 -->
<Home v-if="$page.frontmatter.home"/>
<!-- 分类页 -->
<CategoriesPage v-else-if="$page.frontmatter.categoriesPage"/>
<!-- 标签页 -->
<TagsPage v-else-if="$page.frontmatter.tagsPage"/>
<!-- 归档页 -->
<ArchivesPage v-else-if="$page.frontmatter.archivesPage"/>
<!-- 文章页或其他页 -->
<Page
v-else
:sidebar-items="sidebarItems"
>
<slot
name="page-top"
#top
/>
<slot
name="page-bottom"
#bottom
/>
</Page>
<Footer />
<Buttons
ref="buttons"
@toggle-theme-mode="toggleThemeMode"
/>
<BodyBgImg v-if="$themeConfig.bodyBgImg" />
</div>
</template>
<script>
import Home from '@theme/components/Home.vue'
import Navbar from '@theme/components/Navbar.vue'
import Page from '@theme/components/Page.vue'
import CategoriesPage from '@theme/components/CategoriesPage.vue'
import TagsPage from '@theme/components/TagsPage.vue'
import ArchivesPage from '@theme/components/ArchivesPage.vue'
import Sidebar from '@theme/components/Sidebar.vue'
import Buttons from '@theme/components/Buttons.vue'
import Footer from '@theme/components/Footer'
import BodyBgImg from '@theme/components/BodyBgImg'
import { resolveSidebarItems } from '../util'
import storage from 'good-storage' // 本地存储
import _ from 'lodash'
const MOBILE_DESKTOP_BREAKPOINT = 719 // refer to config.styl
const NAVBAR_HEIGHT = 58 // 导航栏高度
export default {
components: { Home, Navbar, Page, CategoriesPage, TagsPage, ArchivesPage, Sidebar, Footer, Buttons, BodyBgImg },
data () {
return {
hideNavbar: false,
isSidebarOpen: true,
showSidebar: false,
themeMode: 'light'
}
},
beforeMount(){
// 引入图标库
const social = this.$themeConfig.social
if(social && social.iconfontCssFile ) {
let linkElm = document.createElement("link")
linkElm.setAttribute('rel', 'stylesheet');
linkElm.setAttribute("type", "text/css")
linkElm.setAttribute("href", social.iconfontCssFile)
document.head.appendChild(linkElm)
}
},
computed: {
showRightMenu() {
const { headers } = this.$page
return (
!this.$frontmatter.home
&& headers
&& headers.length
&& this.$frontmatter.sidebar !== false
)
},
shouldShowNavbar () {
const { themeConfig } = this.$site
const { frontmatter } = this.$page
if (
frontmatter.navbar === false
|| themeConfig.navbar === false) {
return false
}
return (
this.$title
|| themeConfig.logo
|| themeConfig.repo
|| themeConfig.nav
|| this.$themeLocaleConfig.nav
)
},
shouldShowSidebar () {
const { frontmatter } = this.$page
return (
!frontmatter.home
&& frontmatter.sidebar !== false
&& this.sidebarItems.length
)
},
sidebarItems () {
return resolveSidebarItems(
this.$page,
this.$page.regularPath,
this.$site,
this.$localePath
)
},
pageClasses () {
const userPageClass = this.$page.frontmatter.pageClass
return [
{
'no-navbar': !this.shouldShowNavbar,
'hide-navbar': this.hideNavbar, // 向下滚动隐藏导航栏
'sidebar-open': this.isSidebarOpen,
'no-sidebar': !this.shouldShowSidebar,
'have-rightmenu': this.showRightMenu,
'have-body-img': this.$themeConfig.bodyBgImg
},
// 'theme-mode-' + this.themeMode,
userPageClass
]
}
},
created() {
const sidebarOpen = this.$themeConfig.sidebarOpen
if (sidebarOpen === false) {
this.isSidebarOpen = sidebarOpen
}
},
beforeMount() {
this.isSidebarOpenOfclientWidth()
const mode = storage.get('mode') // 不放在created是因为vuepress不能在created访问浏览器api,如window
if(!mode || mode === 'auto') { // 当未切换过模式,或模式处于'跟随系统'时
this._autoMode()
} else {
this.themeMode = mode
}
this.setBodyClass()
},
mounted () {
// 初始化页面时链接锚点无法跳转到指定id的解决方案
const hash = document.location.hash;
if (hash.length > 1) {
const id = decodeURIComponent(hash.substring(1))
const element = document.getElementById(id)
if (element) element.scrollIntoView()
}
// 解决移动端初始化页面时侧边栏闪现的问题
this.showSidebar = true
this.$router.afterEach(() => {
this.isSidebarOpenOfclientWidth()
})
// 向下滚动收起导航栏
let p = 0, t = 0;
window.addEventListener('scroll', _.throttle(() => {
if(!this.isSidebarOpen) { // 侧边栏关闭时
p = this.getScrollTop()
if(t < p && p > NAVBAR_HEIGHT) { // 向下滚动
this.hideNavbar = true
} else { // 向上
this.hideNavbar = false
}
setTimeout(() => {t = p},0)
}
}, 300))
},
watch: {
isSidebarOpen() {
if(this.isSidebarOpen) { // 侧边栏打开时,恢复导航栏显示
this.hideNavbar = false
}
},
themeMode() {
this.setBodyClass()
}
},
methods: {
setBodyClass() {
document.body.className = 'theme-mode-' + this.themeMode
},
getScrollTop () {
return window.pageYOffset
|| document.documentElement.scrollTop
|| document.body.scrollTop || 0
},
isSidebarOpenOfclientWidth() {
if (document.documentElement.clientWidth < MOBILE_DESKTOP_BREAKPOINT) {
this.isSidebarOpen = false
}
},
toggleSidebar (to) {
this.isSidebarOpen = typeof to === 'boolean' ? to : !this.isSidebarOpen
this.$emit('toggle-sidebar', this.isSidebarOpen)
},
_autoMode () {
if(window.matchMedia('(prefers-color-scheme: dark)').matches){ // 系统处于深色模式
this.themeMode = 'dark'
} else {
this.themeMode = 'light'
}
},
toggleThemeMode (key) {
if(key === 'auto') {
this._autoMode()
} else {
this.themeMode = key
}
storage.set('mode', key)
},
// side swipe
onTouchStart (e) {
this.touchStart = {
x: e.changedTouches[0].clientX,
y: e.changedTouches[0].clientY
}
},
onTouchEnd (e) {
const dx = e.changedTouches[0].clientX - this.touchStart.x
const dy = e.changedTouches[0].clientY - this.touchStart.y
if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 40) {
if (dx > 0 && this.touchStart.x <= 80) {
this.toggleSidebar(true)
} else {
this.toggleSidebar(false)
}
}
}
}
}
</script>
为什么选择我:
博主本身从事开发软件开发、有丰富的编程能力和水平、累积帮助上千名同学进行辅导成果拿下优秀毕业设计!、全网累积粉丝超过10W。是CSDN特邀作者、博客专家、新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流和合作。
源码获取:
大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻
精彩专栏推荐订阅:在下方专栏👇🏻