基于Layui和SpringBoot动漫商城管理的设计与实现

@TOC

springboot597基于Layui和SpringBoot动漫商城管理的设计与实现--论文

第一章 绪论

1.1研究背景

20世纪,随着科学技术的飞速发展,数字化和信息化成为了一个新的发展趋势,信息化的管理方式成为了各个行业的追求的目标,而信息化的管理方式更是成为了人们追求的目标。目前,我国高等院校工程技术和电子管理学已经将信息化技术作为必修课。

在当今社会,人们的生活节奏逐渐加快,人们对经济的要求逐渐降低,越来越多的人开始追求简单、快捷的方式。随着经济的发展,人们的工作环境也得到改善,动漫商城系统的管理更加完善。然而,动漫商城管理模式的改进却是一项比较繁杂的工作,因此,动漫商城管理人员要充分发挥信息化管理的作用,提高动漫商城管理系统的整体管理能力和整体素质。

在科技飞速发展的今天,动漫商城管理体系已全面更新,管理体系的更新,不但能让用户享受到更为高品质的服务,同时也能提升动漫商城管理的工作效率。通过管理上的便利,使动漫商城的管理也更加有序。然而,当前市场上的动漫商城管理大多仍采用大规模的人工管理方式[2],这种管理方式耗费了较多的人力物力,而且很难维持。而本网站要采用一种易于使用、处理速度快、计算准确且适应动漫商城的服务需求的经营模式。这种新型的经营管理体系将有助于动漫商城管理系统的发展,改进当前的经营状况,提升用户的工作效率,同时为动漫商城管理系统创造更多的收益。

1.2社会调查

较好的线上管理软件,能根据用户的需求,开发不同的产品提供用户使用,还可根据用户实际需求做调整或是二次开发。所以希望能通过调研来收集更多信息,完善自己的软件系统。

不同机构所使用的软件都不一样,但软件程序十分相似,在本次调研中,我以中美健身的佳成软件作为主要调研对象。佳成软件一般有C/S,B/S两种构架。C/S构架即Client/Server结构,动漫商城将服务器安装在本地,其他机器以安装用户端的形式连接服务器,以实现数据同步。B/S构架全称为Browser/Server。B/S构架的产品就是把服务器放在互联网上,使用者通过浏览网页来使用系统。选择B/S构架的动漫商城的所有数据,包括动漫商城信息、动漫商城活动、动漫商城公告、在线留言、后台管理等都会通过互联网的服务器来保存。B/S构架不需要安装,拥有一个浏览器即可访问,面向范围以更广。维护也足够简单,更新页面,即可实现面对所有用户的更新,因此也更适合动漫商城。

据调研了解,佳成软件主要运用的VS和SQL两种开发工具。

VS是领先于业内的数据库工具,应用程序可体现行业需求,而这些需求是由最了解它们的个别专家定义的,因而使工程更加完美。它有高效的体系结构指导,用户可使用业界标准方法来表达应用程序的体系结构和功能,提高开发团队的效率。

SQL是一种应用广泛的数据库管理系统,具有许多显著的优点,如:易用性、适合分布式组织的可伸缩性、用于决策支持的数据仓库功能、与许多其他服务器软件紧密关联的集成性、良好的性价比等适用于大型或超大型数据库服务器端。

经调研发现,该软件主要优点在于强大而方便的功能,减轻了工作负担。但也仍有不足之处,如部分系统操作过于复杂,数据导入容易搞混,导致信息查询失败。而这些也恰恰是目前大部分动漫商城管理的通病。

1.3研究意义

开发动漫商城管理系统,不仅可以改善用户查看信息难的局面,还可以提供管理效率,同时也可以增强系统的竞争力。利用动漫商城管理系统的MIS,可以有效地提高系统管理者的工作效率和信息化水平,快速了解信息更新及服务的进度。这既可以确保系统服务的品质,又可以降低管理者的工作压力。

1.4研究内容

动漫商城管理系统主要分为前台用户端、后台管理端。

前台用户端主要的功能为:注册登录,对首页,动漫商品,动漫资讯,个人中心,购物车,在线咨询等功能进行操作。

后台管理端主要功能为:首页,个人中心,用户管理,商品类型管理,动漫商品管理,系统管理,订单管理等功能。

第二章 关键技术介绍

2.1 Java技术

Java是一种在Web应用开发中得到广泛使用的脚本语言,经常被用来对用户的相关行为做出反应。它还具有面向对象的设计能力,使设计开发过程更加直观和模块化,并在HTML基础上进行交互Web页面的开发[9]。这种脚本语言的问世,使用户与页面之间的实时、动态交互成为现实,丰富了页面的内容,增强了页面的活力。另外,Java技术也被广泛地运用于该系统,比如对用户输入的数据进行检测,以保证其有效性。Java技术[10]可以在不依赖Web服务程序的基础上在本地用户机上运行。从而有效地解决了因网络速度所带来的迟缓问题,使用户能够更加顺畅、快捷地进行访问。一些功能,比如用户的数据输入,可以通过JavaScript这样的用户语言来完成。该系统采用Java用户机进行用户身份认证,确保了系统的安全性和可靠性。

2.2SpringBoot框架

Spring Boot是由Pivotal的开发团队在2013年开发的一个免费、轻量级、开源的系统框架。SpringBoot的主要设计思想是约定大于配置,因此SpringBoot在设计时几乎达到零配置。SpringBoot集成了业界的开源框架。

SpringBoot是一个非常强大的后台框架,因为SpringBoot的开发基本上不需要写配置文件,所以利用SpringBoot来构建网站的后台环境,在SpringBoot的YML配置文件中写项目启动端口,项目就可以启动了。项目的Java和静态文件由SpringBoot管理。

2.3 Tomcat技术

假定要开发一个Web应用,必须预先建立一个支持它的运行环境,而JavaWeb应用则需要JDK和Web服务。通过使用该工具开发的软件,可以减少以往人工需要进行的大量工作,从而大大加快了软件的开发速度。这个系统所采用的Web服务程序的运行环境是Apache Tomacat。由于Apache Tomacat是我们经常使用的环境,所以可以通过Apache Tomacat可以充分地描述JSP和Java Web。

2.4 MySQL数据库

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,属于Oracle旗下产品。MySQL谁最流行的关系型数据库管理系统之一,在Web应用方面,MySQL是最好的RDBMS(关系型数据库管理系统)应用软件之一。

MySQL所使用的SQL语言是用于访问数据库的最常用标准化语言。MySQL软件采用了双授权政策,分为社区版和商业版,由于其体积小,速度快,总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择MySQL作为网站数据库。

MySQL 数据库它有很多的优点,例如它在操作上能够让人通俗易懂、功能强大、信息储存量高等优点。所以被人们广泛应用,对于MySQL数据库来说它一般主要是对数据进行编码和查询,而且在很多的设计当中都应用到了该数据库,在此过程当中我们可以对常规的数据进行查询和组合,所以我们在进行使用MySQL数据库的时候只要对编写一小段的数据就能实现相应的功能。数据库,就是数据存储的储藏室,只不过数据是存储在计算机上的,而不是现实中的储藏室,数据的存放是按固定格式,而不是无序的,则定义就是 :长期有固定格式,可以共享的存储在计算机存储器上。数据库管理主要包括数据表的建立,数据存储、修改和增加数据,为了使数据库系统能够正常运行,相关人员进行的管理工作。数据表的建立,可以对数据表中的数据进行调整,数据的重新组合及重新构造,保证数据的安全性。

2.5 B/S模式

Web程序设计技术是一项用于网页制造方面的专业技术,主要实现了网页的动态交互功能,通过此项技术语言(如PHP、CGI、ASP等)所设计的相关网页可以对用户所发出的及时操作以及需求进展相应的相应,从而到达实现即时动态交互的目的。

B/S构造(Browser/Server,浏览器/效劳器模式),其是一种分布式的计算机网络系统,用户通过浏览器向上一级的网站程序传递相关的参数和请求,然后效劳器上的程序再将这些请求和参数进展处理,最后将结果通过反响回用户浏览器反映出来。

第三章 系统分析

进行动漫商城管理的开发,首先需要进行系统需求分析。对用户需求进行调研,接着设计系统的体系构造和数据库表构造,确定使用的开发工具和后台数据库。

系统分析的重点是对用户和系统的需求进行相关分析,包括对系统的需求进行分析。在系统的分析中,要介绍目前系统的运行过程,并对目前的系统的问题进行分析,给出业务需求,且一并给出相应的解决方案,然后将其应用于平时的管理之中。

3.1业务需求分析

首先,对现在业务需求进展描述。当前,我国大部分企业普遍存在着资本规模小、人员素质差、管理不规范等问题,基本停留在人工录入的阶段。因此不可避免地导致了经营过程的低效,且易出现错误。然而,在网络上出现的各种动漫商城管理,往往都是费用很高,因为操作过于繁琐,对于一般动漫商城管理来说,使用起来比较困难,维修起来也不方便。在互联网蓬勃发展的今天,在平时的管理中涉及到的各类业务信息也变得复杂起来,面对不断增长的信息量,利用MIS提高工作效率是非常有必要的,因此,制定一套专用的动漫商城管理系统就是一个很好的办法。利用动漫商城管理系统进行信息的处理,具有传统的人工记录所不能比拟的优势,它可以实现对数据的规范化,同时也可以对进度进行科学的统计,并快速地查找,从而到达提高工作效率、服务质量的目的。本文在对动漫商城管理的实践中,提出了实现工作信息化的必要性。

易于操作;快速反应;准确的记录和方便的操作是评价一个系统服务质量的重要指标,它可以提高服务质量,并让用户迅速得到以下有关的信息。

  1. 使用不便。
  2. 信息管理复杂。

3.效率低,安全性及准确率不够。

本文在对上述问题进行归纳和剖析后,针对上述问题,给出了相应的改进措施:利用MySQL数据库技术,将用户管理,商品类型管理,动漫商品管理,系统管理,订单管理等信息存储在预先设定的相应的数据表单中,并利用程序技术进行信息的分类处理,从而达到可以动态地更改信息的目标。用户只要搜索一下关键字,就能找到所需要的信息。用户只要提交相应的要求,就能得到相应的反馈。运用电脑技术和数据库技术,极大地提高了的工作质量,为用户提供了便利。

3.2系统的非功能需求分析

根据近年来动漫商城管理的发展情况,结合文献资料,对动漫商城管理的信息化;至此,开发具有一定的技术可行性和安全性。

该系统的核心内容是对首页,个人中心,用户管理,商品类型管理,动漫商品管理,系统管理,订单管理模块的管理。有关的动漫商城管理系统规定如下:

(1)可行性:该体系应具有可行性,并与动漫商城管理相适应。

(2)完整:功能模块可以满足系统的要求。

(3)简单:使用简单,维修简单。

(4)安全:安全的系统。

3.3系统可行性分析

3.3.1 技术可行性

该平台采用Java技术,而Eclipse则是利用MySQL进行数据库的选择,在数据库的开发中,SQL是最高效、最简洁的,在这个体系中,Eclipse是最安全、最稳定的。由于它的使用方便,无论是开发者,还是管理员,都可以轻松地使用它们。综合来看,解决技术上的问题是切实可行的。

3.3.2 经济可行性

针对本系统而言,需要一系列的硬软件支持,主要硬软件及相关费用如下:需要CPU为400MHz及以上的处理器的计算机,硬盘空间为100M及以上即可,除此之外,相关的设备的安装工作都比较简单,并且设计开发软件的本钱也不高,都相比照较简单,所以只需要对用户进展相关的提示工作便可以让其成功地使用本系统,故本系统的本钱是非常低的。综上所述,本系统在经济上也是可行的。

3.3.3 操作可行性

在动漫商城管理系统方面,目前已经有许多成功的动漫商城管理信息化系统在支撑系统的运营。就本系统而言,操作简捷,适合大部分动漫商城或个人使用。无论是对业务过程的系统的处理,还是对工作人员的系统的运用,都能够很好地适应系统的正常运作需求。综上所述,本系统在操作上也是可行的。

3.4系统功能分析

考虑到实际生活中在动漫商城管理方面的需要以及对该系统认真的分析,将系统权限按进行划分。

管理员登入使用本系统涉到的功能主要有个人中心,用户管理,商品类型管理,动漫商品管理,系统管理,订单管理等功能。管理员用例如图3-1所示。

图3-1 管理员用例图

用户登入使用本系统涉到的功能主要有动漫商品,动漫资讯,个人中心,购物车,在线咨询等功能。用户用例如图3-2所示。

图3-2 用户用例图

3.5系统流程的分析

3.5.1登录流程

登录流程如图3-3所示:

图3-3 登录流程

3.5.2系统操作流程

系统操作流程如图3-4所示:

图3-4系统操作流程图

第四章 系统设计

4.1系统的框架设计

该体系结构将以MVC模型作为体系结构,其体系结构上将其划分为三个层次:表示级、服务级、数据库级。采用MVC模型的思路,实现了各个业务的分离,实现了多个功能的高内聚和低耦合。在代码编写中,对通用代码、相同逻辑代码进行精化和包装,以提升代码使用效率,并使代码逻辑更为清楚。

1.表示层:网页浏览器是展示层面的主体,使用者可以透过网页浏览进入该网页。利用Java技术在前端网页中的应用,通过Ajax技术来与后台的业务服务进行交互,以满足网页的局部动态改变。

2.逻辑层:当系统使用者在进入该体系之后,能够在该层呼叫该业务的业务函数界面。

3.数据库:该系统使用MySQL实现对数据的持久性管理,为了实现数据的标准化、简化和快速的存储,将会引进MybatisORM持久性架构。

4.2系统功能模块设计

动漫商城管理系统在设计与实施时,采取了模块性的设计理念,把相似的系统的功能整合到一个模组中,以增强内部的功能,减少各组件之间的联系,从而达到减少相互影响的目的。

管理员主要功能是:首页,个人中心,用户管理,商品类型管理,动漫商品管理,系统管理,订单管理等功能。系统总体功能结构图如图4-1所示。

图4-1 系统总体功能结构图

4.3 数据库设计

4.3.1数据库概念设计

概念模型用于独立于指定的数据库管理系统对信息世界进行建模。方便将现实世界中的实际事物抽象出来,形成适合数据库管理系统的数据库模型。人们倾向于将现实世界抽象为信息世界,再将信息世界抽象为机器世界。也就是说,首先将现实世界中的目标抽象为一个独立于专用计算机软件和专用数据库管理系统的信息结构,而是一个数据模型,然后将实体模型在电子计算机上转化为一个适用于数据库管理系统的数据库系统。事实上,数据模型是介于现实世界和机器世界之间的一个层次。信息世界的基本要素包含实体和关联。

(1)实体(entity)

实体(entity) 客观存在并可相互区别的事物称为实体。实体可以是实际的人、事或物,还可以是抽象化的概念或联络。主要的实体属性图如下图所示:

动漫资讯实体属性如图4-2所示。

图4-2动漫资讯实体属性图

动漫商品评论实体属性如图4-3所示。

图4-3动漫商品评论实体属性图

地址实体属性如图4-4所示。

图4-4地址实体属性图

动漫商品实体属性如图4-5所示。

图4-5动漫商品实体属性图

用户实体属性如图4-6所示。

图4-6用户实体属性图

4.3.2 数据库表设计

在本系统中,采用的是目前比较主流的MySQL数据库,并且设计了几个数据表如下所示:

表4-1:用户表

字段名称类型长度字段说明主键默认值
idbigint主键主键
usernamevarchar100用户名
passwordvarchar100密码
rolevarchar100角色管理员
addtimetimestamp新增时间CURRENT_TIMESTAMP

表4-2:token表

字段名称类型长度字段说明主键默认值
idbigint主键主键
useridbigint用户id
usernamevarchar100用户名
tablenamevarchar100表名
rolevarchar100角色
tokenvarchar200密码
addtimetimestamp新增时间CURRENT_TIMESTAMP
expiratedtimetimestamp过期时间CURRENT_TIMESTAMP

表4-3:收藏表

字段名称类型长度字段说明主键默认值
idbigint主键主键
addtimetimestamp创建时间CURRENT_TIMESTAMP
useridbigint用户id
refidbigint商品id
tablenamevarchar200表名
namevarchar200名称
picturelongtext4294967295图片
typevarchar200类型(1:收藏,21:赞,22:踩,31:竞拍参与,41:关注)1
inteltypevarchar200推荐类型
remarkvarchar200备注

表4-4:动漫资讯

字段名称类型长度字段说明主键默认值
idbigint主键主键
addtimetimestamp创建时间CURRENT_TIMESTAMP
titlevarchar200标题
introductionlongtext4294967295简介
picturelongtext4294967295图片
contentlongtext4294967295内容

表4-5:动漫商品评论表

字段名称类型长度字段说明主键默认值
idbigint主键主键
addtimetimestamp创建时间CURRENT_TIMESTAMP
refidbigint关联表id
useridbigint用户id
nicknamevarchar200用户名
contentlongtext4294967295评论内容
replylongtext4294967295回复内容

表4-6:配置文件

字段名称类型长度字段说明主键默认值
idbigint主键主键
namevarchar100配置参数名称
valuevarchar100配置参数值

表4-7:地址

字段名称类型长度字段说明主键默认值
idbigint主键主键
addtimetimestamp创建时间CURRENT_TIMESTAMP
useridbigint用户id
addressvarchar200地址
namevarchar200收货人
phonevarchar200电话
isdefaultvarchar200是否默认地址[是/否]

表4-8:商品类型

字段名称类型长度字段说明主键默认值
idbigint主键主键
addtimetimestamp创建时间CURRENT_TIMESTAMP
shangpinleixingvarchar200商品类型

表4-9:订单

字段名称类型长度字段说明主键默认值
idbigint主键主键
addtimetimestamp创建时间CURRENT_TIMESTAMP
orderidvarchar200订单编号
tablenamevarchar200商品表名dongmanshangpin
useridbigint用户id
goodidbigint商品id
goodnamevarchar200商品名称
picturelongtext4294967295商品图片
buynumberint购买数量
pricefloat价格0
discountpricefloat折扣价格0
totalfloat总价格0
discounttotalfloat折扣总价格0
typeint支付类型1
statusvarchar200状态
addressvarchar200地址
telvarchar200电话
consigneevarchar200收货人
remarkvarchar200备注
logisticslongtext4294967295物流

表4-10:动漫商品

字段名称类型长度字段说明主键默认值
idbigint主键主键
addtimetimestamp创建时间CURRENT_TIMESTAMP
shangpinbianhaovarchar200商品编号
shangpinmingchengvarchar200商品名称
tupianlongtext4294967295图片
shangpinleixingvarchar200商品类型
pinpaivarchar200品牌
chandivarchar200产地
shangpinxiangqinglongtext4294967295商品详情
onelimittimesint单限
alllimittimesint库存
clicktimedatetime最近点击时间
pricefloat价格

表4-11:在线咨询

字段名称类型长度字段说明主键默认值
idbigint主键主键
addtimetimestamp创建时间CURRENT_TIMESTAMP
useridbigint用户id
adminidbigint管理员id
asklongtext4294967295提问
replylongtext4294967295回复
isreplyint是否回复

表4-12:用户

字段名称类型长度字段说明主键默认值
idbigint主键主键
addtimetimestamp创建时间CURRENT_TIMESTAMP
zhanghaovarchar200账号
mimavarchar200密码
nichengvarchar200昵称
xingbievarchar200性别
shoujivarchar200手机
touxianglongtext4294967295头像
moneyfloat余额0

表4-13:购物车表

字段名称类型长度字段说明主键默认值
idbigint主键主键
addtimetimestamp创建时间CURRENT_TIMESTAMP
tablenamevarchar200商品表名dongmanshangpin
useridbigint用户id
goodidbigint商品id
goodnamevarchar200商品名称
picturelongtext4294967295图片
buynumberint购买数量
pricefloat单价
discountpricefloat会员价

第五章 系统实现

5.1系统功能实现

当人们打开系统的网址后,首先看到的就是首页界面。在这里,人们能够看到动漫商城管理系统的导航条和动漫商品推荐等。系统首页界面如图5-1所示:

图5-1 系统首页界面

系统注册:在系统注册页面的输入用户注册信息进行注册操作,系统注册页面如图5-2所示:

图5-2系统注册页面

动漫商品:在动漫商品页面的输入栏中输入商品名称进行查询,并进行收藏、评论、添加购物车或立即购买操作等;动漫商品页面如图5-3所示:

图5-3动漫商品详细页面

个人中心:在个人中心页面输入个人信息可以进行更新操作,还可以对我的订单,我的地址和我的收藏进行操作等,如图5-4所示:

图5-4个人中心界面

5.2管理员模块实现

管理员进入主页面,主要功能包括对首页,个人中心,用户管理,商品类型管理,动漫商品管理,系统管理,订单管理等进行操作。管理员主页面如图5-5所示:

图5-5 管理员主界面

管理员点击用户管理。在用户页面输入昵称,性别进行查询、新增或删除用户列表,并根据需要对用户详情信息进行详情、修改或删除操作;如图5-6所示:

图5-6用户管理界面

管理员点击商品类型管理。在商品类型页面输入商品类型进行查询、新增或删除用户列表,并根据需要对商品类型详情信息进行详情、修改或删除操作;如图5-7所示:

图5-7商品类型管理界面

管理员点击动漫商品管理。在动漫商品页面输入商品名称进行查询、新增或删除动漫商品列表,并根据需要对动漫商品详情信息进行详情、修改、查看评论或删除操作;如图5-8所示:

图5-8动漫商品管理界面

管理员点击系统管理。在轮播图管理页面可以对轮播图进行详情、修改操作;并根据需要对动漫资讯,在线咨询进行相应操作,如图5-9所示:

图5-9轮播图管理界面

管理员点击订单管理。在已退款订单页面输入订单编号,商品名称进行查询、已退款订单列表,对已退款订单信息进行详情操作;并根据需要对未支付订单,已发货订单,已支付订单,已完成订单,已取消订单等进行相应操作,如图5-10所示:

图5-10系统管理界面

UsersServiceImpl.java

package com.service.impl;


import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.dao.UsersDao;
import com.entity.UsersEntity;
import com.service.UsersService;
import com.utils.PageUtils;
import com.utils.Query;


/**
 * 系统用户
 */
@Service("usersService")
public class UsersServiceImpl extends ServiceImpl<UsersDao, UsersEntity> implements UsersService {

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		Page<UsersEntity> page = this.selectPage(
                new Query<UsersEntity>(params).getPage(),
                new EntityWrapper<UsersEntity>()
        );
        return new PageUtils(page);
	}

	@Override
	public List<UsersEntity> selectListView(Wrapper<UsersEntity> wrapper) {
		return baseMapper.selectListView(wrapper);
	}

	@Override
	public PageUtils queryPage(Map<String, Object> params,
			Wrapper<UsersEntity> wrapper) {
		 Page<UsersEntity> page =new Query<UsersEntity>(params).getPage();
	        page.setRecords(baseMapper.selectListView(page,wrapper));
	    	PageUtils pageUtil = new PageUtils(page);
	    	return pageUtil;
	}
}

UsersController.java

package com.controller;


import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.annotation.IgnoreAuth;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.TokenEntity;
import com.entity.UsersEntity;
import com.service.TokenService;
import com.service.UsersService;
import com.utils.CommonUtil;
import com.utils.MPUtil;
import com.utils.PageUtils;
import com.utils.R;
import com.utils.ValidatorUtils;

/**
 * 登录相关
 */
@RequestMapping("users")
@RestController
public class UsersController{
	
	@Autowired
	private UsersService userService;
	
	@Autowired
	private TokenService tokenService;

	/**
	 * 登录
	 */
	@IgnoreAuth
	@PostMapping(value = "/login")
	public R login(String username, String password, String captcha, HttpServletRequest request) {
		UsersEntity user = userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", username));
		if(user==null || !user.getPassword().equals(password)) {
			return R.error("账号或密码不正确");
		}
		String token = tokenService.generateToken(user.getId(),username, "users", user.getRole());
		return R.ok().put("token", token);
	}
	
	/**
	 * 注册
	 */
	@IgnoreAuth
	@PostMapping(value = "/register")
	public R register(@RequestBody UsersEntity user){
//    	ValidatorUtils.validateEntity(user);
    	if(userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", user.getUsername())) !=null) {
    		return R.error("用户已存在");
    	}
        userService.insert(user);
        return R.ok();
    }

	/**
	 * 退出
	 */
	@GetMapping(value = "logout")
	public R logout(HttpServletRequest request) {
		request.getSession().invalidate();
		return R.ok("退出成功");
	}
	
	/**
     * 密码重置
     */
    @IgnoreAuth
	@RequestMapping(value = "/resetPass")
    public R resetPass(String username, HttpServletRequest request){
    	UsersEntity user = userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", username));
    	if(user==null) {
    		return R.error("账号不存在");
    	}
    	user.setPassword("123456");
        userService.update(user,null);
        return R.ok("密码已重置为:123456");
    }
	
	/**
     * 列表
     */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params,UsersEntity user){
        EntityWrapper<UsersEntity> ew = new EntityWrapper<UsersEntity>();
    	PageUtils page = userService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.allLike(ew, user), params), params));
        return R.ok().put("data", page);
    }

	/**
     * 列表
     */
    @RequestMapping("/list")
    public R list( UsersEntity user){
       	EntityWrapper<UsersEntity> ew = new EntityWrapper<UsersEntity>();
      	ew.allEq(MPUtil.allEQMapPre( user, "user")); 
        return R.ok().put("data", userService.selectListView(ew));
    }

    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") String id){
        UsersEntity user = userService.selectById(id);
        return R.ok().put("data", user);
    }
    
    /**
     * 获取用户的session用户信息
     */
    @RequestMapping("/session")
    public R getCurrUser(HttpServletRequest request){
    	Long id = (Long)request.getSession().getAttribute("userId");
        UsersEntity user = userService.selectById(id);
        return R.ok().put("data", user);
    }

    /**
     * 保存
     */
    @PostMapping("/save")
    public R save(@RequestBody UsersEntity user){
//    	ValidatorUtils.validateEntity(user);
    	if(userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", user.getUsername())) !=null) {
    		return R.error("用户已存在");
    	}
        userService.insert(user);
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody UsersEntity user){
//        ValidatorUtils.validateEntity(user);
    	UsersEntity u = userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", user.getUsername()));
    	if(u!=null && u.getId()!=user.getId() && u.getUsername().equals(user.getUsername())) {
    		return R.error("用户名已存在。");
    	}
        userService.updateById(user);//全部更新
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids){
        userService.deleteBatchIds(Arrays.asList(ids));
        return R.ok();
    }
}

DongmanshangpinController.java
package com.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;

import com.utils.ValidatorUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.annotation.IgnoreAuth;

import com.entity.DongmanshangpinEntity;
import com.entity.view.DongmanshangpinView;

import com.service.DongmanshangpinService;
import com.service.TokenService;
import com.utils.PageUtils;
import com.utils.R;
import com.utils.MD5Util;
import com.utils.MPUtil;
import com.utils.CommonUtil;
import java.io.IOException;
import com.service.StoreupService;
import com.entity.StoreupEntity;

/**
 * 动漫商品
 * 后端接口
 * @author 
 * @email 
 * @date 2023-01-27 20:13:13
 */
@RestController
@RequestMapping("/dongmanshangpin")
public class DongmanshangpinController {
    @Autowired
    private DongmanshangpinService dongmanshangpinService;

    @Autowired
    private StoreupService storeupService;

    


    /**
     * 后端列表
     */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params,DongmanshangpinEntity dongmanshangpin,
		HttpServletRequest request){
        EntityWrapper<DongmanshangpinEntity> ew = new EntityWrapper<DongmanshangpinEntity>();

		PageUtils page = dongmanshangpinService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, dongmanshangpin), params), params));

        return R.ok().put("data", page);
    }
    
    /**
     * 前端列表
     */
	@IgnoreAuth
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params,DongmanshangpinEntity dongmanshangpin, 
		HttpServletRequest request){
        EntityWrapper<DongmanshangpinEntity> ew = new EntityWrapper<DongmanshangpinEntity>();

		PageUtils page = dongmanshangpinService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, dongmanshangpin), params), params));
        return R.ok().put("data", page);
    }

	/**
     * 列表
     */
    @RequestMapping("/lists")
    public R list( DongmanshangpinEntity dongmanshangpin){
       	EntityWrapper<DongmanshangpinEntity> ew = new EntityWrapper<DongmanshangpinEntity>();
      	ew.allEq(MPUtil.allEQMapPre( dongmanshangpin, "dongmanshangpin")); 
        return R.ok().put("data", dongmanshangpinService.selectListView(ew));
    }

	 /**
     * 查询
     */
    @RequestMapping("/query")
    public R query(DongmanshangpinEntity dongmanshangpin){
        EntityWrapper< DongmanshangpinEntity> ew = new EntityWrapper< DongmanshangpinEntity>();
 		ew.allEq(MPUtil.allEQMapPre( dongmanshangpin, "dongmanshangpin")); 
		DongmanshangpinView dongmanshangpinView =  dongmanshangpinService.selectView(ew);
		return R.ok("查询动漫商品成功").put("data", dongmanshangpinView);
    }
	
    /**
     * 后端详情
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id){
        DongmanshangpinEntity dongmanshangpin = dongmanshangpinService.selectById(id);
		dongmanshangpin.setClicktime(new Date());
		dongmanshangpinService.updateById(dongmanshangpin);
        return R.ok().put("data", dongmanshangpin);
    }

    /**
     * 前端详情
     */
	@IgnoreAuth
    @RequestMapping("/detail/{id}")
    public R detail(@PathVariable("id") Long id){
        DongmanshangpinEntity dongmanshangpin = dongmanshangpinService.selectById(id);
		dongmanshangpin.setClicktime(new Date());
		dongmanshangpinService.updateById(dongmanshangpin);
        return R.ok().put("data", dongmanshangpin);
    }
    



    /**
     * 后端保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody DongmanshangpinEntity dongmanshangpin, HttpServletRequest request){
    	dongmanshangpin.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
    	//ValidatorUtils.validateEntity(dongmanshangpin);
        dongmanshangpinService.insert(dongmanshangpin);
        return R.ok();
    }
    
    /**
     * 前端保存
     */
    @RequestMapping("/add")
    public R add(@RequestBody DongmanshangpinEntity dongmanshangpin, HttpServletRequest request){
    	dongmanshangpin.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
    	//ValidatorUtils.validateEntity(dongmanshangpin);
        dongmanshangpinService.insert(dongmanshangpin);
        return R.ok();
    }



    /**
     * 修改
     */
    @RequestMapping("/update")
    @Transactional
    public R update(@RequestBody DongmanshangpinEntity dongmanshangpin, HttpServletRequest request){
        //ValidatorUtils.validateEntity(dongmanshangpin);
        dongmanshangpinService.updateById(dongmanshangpin);//全部更新
        return R.ok();
    }


    

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids){
        dongmanshangpinService.deleteBatchIds(Arrays.asList(ids));
        return R.ok();
    }
    
    /**
     * 提醒接口
     */
	@RequestMapping("/remind/{columnName}/{type}")
	public R remindCount(@PathVariable("columnName") String columnName, HttpServletRequest request, 
						 @PathVariable("type") String type,@RequestParam Map<String, Object> map) {
		map.put("column", columnName);
		map.put("type", type);
		
		if(type.equals("2")) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar c = Calendar.getInstance();
			Date remindStartDate = null;
			Date remindEndDate = null;
			if(map.get("remindstart")!=null) {
				Integer remindStart = Integer.parseInt(map.get("remindstart").toString());
				c.setTime(new Date()); 
				c.add(Calendar.DAY_OF_MONTH,remindStart);
				remindStartDate = c.getTime();
				map.put("remindstart", sdf.format(remindStartDate));
			}
			if(map.get("remindend")!=null) {
				Integer remindEnd = Integer.parseInt(map.get("remindend").toString());
				c.setTime(new Date());
				c.add(Calendar.DAY_OF_MONTH,remindEnd);
				remindEndDate = c.getTime();
				map.put("remindend", sdf.format(remindEndDate));
			}
		}
		
		Wrapper<DongmanshangpinEntity> wrapper = new EntityWrapper<DongmanshangpinEntity>();
		if(map.get("remindstart")!=null) {
			wrapper.ge(columnName, map.get("remindstart"));
		}
		if(map.get("remindend")!=null) {
			wrapper.le(columnName, map.get("remindend"));
		}


		int count = dongmanshangpinService.selectCount(wrapper);
		return R.ok().put("count", count);
	}
	
	/**
     * 前端智能排序
     */
	@IgnoreAuth
    @RequestMapping("/autoSort")
    public R autoSort(@RequestParam Map<String, Object> params,DongmanshangpinEntity dongmanshangpin, HttpServletRequest request,String pre){
        EntityWrapper<DongmanshangpinEntity> ew = new EntityWrapper<DongmanshangpinEntity>();
        Map<String, Object> newMap = new HashMap<String, Object>();
        Map<String, Object> param = new HashMap<String, Object>();
		Iterator<Map.Entry<String, Object>> it = param.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry<String, Object> entry = it.next();
			String key = entry.getKey();
			String newKey = entry.getKey();
			if (pre.endsWith(".")) {
				newMap.put(pre + newKey, entry.getValue());
			} else if (StringUtils.isEmpty(pre)) {
				newMap.put(newKey, entry.getValue());
			} else {
				newMap.put(pre + "." + newKey, entry.getValue());
			}
		}
		params.put("sort", "clicktime");
        params.put("order", "desc");
		PageUtils page = dongmanshangpinService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, dongmanshangpin), params), params));
        return R.ok().put("data", page);
    }









}

list.vue
<template>
  <div class="main-content">
    <!-- 列表页 -->
    <div v-if="!showFlag" style="width: 100%;">
      <div>
        <el-table
		  :stripe='false'
		  :style='{"width":"100%","padding":"0","borderColor":"#147A7C","borderStyle":"solid","borderWidth":"0 10px 10px","background":"#fff"}'
          :data="dataList"
          border
          v-loading="dataListLoading"
          style="width: 100%;"
        >
          <el-table-column :resizable='true' :sortable='false' prop="ask" :formatter="askFormat" header-align="center" align="center" sortable label="新消息"></el-table-column>
          <el-table-column
		    :resizable='true' :sortable='false'
            prop="allnode"
            header-align="center"
            align="center"
            sortable
            label="状态"
            width="150"
          >
            <template slot-scope="scope">
              <el-tag v-if="scope.row.isreply==1" type="success">未回复</el-tag>
              <el-tag v-if="scope.row.isreply==0" type="info">已回复</el-tag>
            </template>
          </el-table-column>
          <el-table-column
            header-align="center"
            align="center"
            width="150"
            label="操作"
          >
            <template slot-scope="scope">
              <el-button
                type="text"
				:style='{"border":"2px solid #147A7C","cursor":"pointer","padding":"0 24px","margin":"0 10px 4px 0","outline":"none","color":"#147A7C","borderRadius":"30px","background":"#fff","width":"auto","fontSize":"14px","height":"32px"}'
                size="small"
                @click="addOrUpdateHandler(scope.row)"
              >回复</el-button>
            </template>
          </el-table-column>
        </el-table>
		
        <el-pagination
          @size-change="sizeChangeHandle"
          @current-change="currentChangeHandle"
          :current-page="pageIndex"
          :page-sizes="[10, 20, 50, 100]"
          :page-size="pageSize"
          :total="totalPage"
          :layout="layouts.join()"
          prev-text="<"
          next-text=">"
          :hide-on-single-page="true"
          :style='{"width":"100%","padding":"0","margin":"20px 0 0","whiteSpace":"nowrap","color":"#333","fontWeight":"500"}'
        ></el-pagination>
      </div>
    </div>
    <!-- 添加/修改页面  将父组件的search方法传递给子组件-->
    <add-or-update v-else :parent="this" ref="addOrUpdate"></add-or-update>
  </div>
</template>
<script>
import AddOrUpdate from "./chat-add-or-update";
import { setInterval, clearInterval } from 'timers';
export default {
  data() {
    return {
	  layouts: ["total","prev","pager","next","sizes","jumper"],
      searchForm: {},
      dataList: [],
      pageIndex: 1,
      pageSize: 10,
      totalPage: 0,
      dataListLoading: false,
      showFlag: false,
      dataListSelections: [],
      inter: null
    };
  },
  created() {
    var that = this;
    var inter = setInterval(function(){
        that.getDataList();
    },5000);
    this.inter = inter;
  },
  destroyed(){
    clearInterval(this.inter);
  },
  components: {
    AddOrUpdate
  },
  methods: {
    askFormat(row, column) {
      if (row.ask && row.ask.startsWith('upload/')) {
          return '[图片]'
      } else{
          return row.ask
      }
    },
    getDataList() {
      this.dataListLoading = true;
      this.$http({
        url: this.$api.chatpage,
        method: "get",
        params: {
          page: this.pageIndex,
          limit: this.pageSize,
          sort: 'id'
        }
      }).then(({ data }) => {
        if (data && data.code === 0) {
          this.dataList = data.data.list;
          this.totalPage = data.data.total;
        } else {
          this.dataList = [];
          this.totalPage = 0;
        }
        this.dataListLoading = false;
      });
    },
    // 每页数
    sizeChangeHandle(val) {
      this.pageSize = val;
      this.pageIndex = 1;
      this.getDataList();
    },
    // 当前页
    currentChangeHandle(val) {
      this.pageIndex = val;
      this.getDataList();
    },
    // 回复
    addOrUpdateHandler(row) {
      this.showFlag = true;
      this.$nextTick(() => {
        this.$refs.addOrUpdate.init(row.userid);
      });
    }
  }
};
</script>
<style lang="scss" scoped>
.table-content {
	background: transparent;
}
	
	.center-form-pv {
		.el-input {
		  width: auto;
		}
	  .el-date-editor.el-input {
	    width: auto;
	  }
	}
	
	// table
	.el-table /deep/ .el-table__header-wrapper thead {
				color: #999;
				font-weight: 500;
				width: 100%;
			}
	
	.el-table /deep/ .el-table__header-wrapper thead tr {
				background: #fff;
			}
	
	.el-table /deep/ .el-table__header-wrapper thead tr th {
				padding: 12px 0;
				color: #fff;
				background: #147A7C;
				border-color: #fff;
				border-width: 0 1px 1px 0;
				border-style: solid;
				text-align: left;
			}
	
	.el-table /deep/ .el-table__header-wrapper thead tr th .cell {
				padding: 0 10px;
				word-wrap: normal;
				word-break: break-all;
				white-space: normal;
				font-weight: bold;
				display: inline-block;
				vertical-align: middle;
				width: 100%;
				line-height: 24px;
				position: relative;
				text-overflow: ellipsis;
			}
	
	
	.el-table /deep/ .el-table__body-wrapper tbody {
				width: 100%;
			}
	
	.el-table /deep/ .el-table__body-wrapper tbody tr {
				background: #fff;
			}
	
	.el-table /deep/ .el-table__body-wrapper tbody tr td {
				padding: 12px 0;
				color: #666;
				background: #fff;
				border-color: #1F2E41;
				border-width: 1px 1px 0 0;
				border-style: solid;
				text-align: center;
			}
	
		
	.el-table /deep/ .el-table__body-wrapper tbody tr:hover td {
				padding: 12px 0;
				color: #000;
				background: rgba(20, 122, 124, 0.1);
				border-color: #1F2E41;
				border-width: 1px 1px 0 0;
				border-style: solid;
				text-align: center;
			}
	
	.el-table /deep/ .el-table__body-wrapper tbody tr td {
				padding: 12px 0;
				color: #666;
				background: #fff;
				border-color: #1F2E41;
				border-width: 1px 1px 0 0;
				border-style: solid;
				text-align: center;
			}
	
	.el-table /deep/ .el-table__body-wrapper tbody tr td .cell {
				padding: 0 10px;
				overflow: hidden;
				word-break: break-all;
				white-space: normal;
				line-height: 24px;
				text-overflow: ellipsis;
			}
	
	// pagination
	.main-content .el-pagination /deep/ .el-pagination__total {
				margin: 0 10px 0 0;
				color: #666;
				font-weight: 400;
				display: inline-block;
				vertical-align: top;
				font-size: 13px;
				line-height: 28px;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .btn-prev {
				border: none;
				border-radius: 2px;
				padding: 0;
				margin: 0 5px;
				color: #666;
				background: #f4f4f5;
				display: inline-block;
				vertical-align: top;
				font-size: 13px;
				line-height: 28px;
				min-width: 35px;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .btn-next {
				border: none;
				border-radius: 2px;
				padding: 0;
				margin: 0 5px;
				color: #666;
				background: #f4f4f5;
				display: inline-block;
				vertical-align: top;
				font-size: 13px;
				line-height: 28px;
				min-width: 35px;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .btn-prev:disabled {
				border: none;
				cursor: not-allowed;
				border-radius: 2px;
				padding: 0;
				margin: 0 5px;
				color: #C0C4CC;
				background: #f4f4f5;
				display: inline-block;
				vertical-align: top;
				font-size: 13px;
				line-height: 28px;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .btn-next:disabled {
				border: none;
				cursor: not-allowed;
				border-radius: 2px;
				padding: 0;
				margin: 0 5px;
				color: #C0C4CC;
				background: #f4f4f5;
				display: inline-block;
				vertical-align: top;
				font-size: 13px;
				line-height: 28px;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .el-pager {
				padding: 0;
				margin: 0;
				display: inline-block;
				vertical-align: top;
			}
	
	.main-content .el-pagination /deep/ .el-pager .number {
				cursor: pointer;
				padding: 0 4px;
				margin: 0 5px;
				color: #666;
				display: inline-block;
				vertical-align: top;
				font-size: 13px;
				line-height: 28px;
				border-radius: 2px;
				background: #f4f4f5;
				text-align: center;
				min-width: 30px;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .el-pager .number:hover {
				cursor: pointer;
				padding: 0 4px;
				margin: 0 5px;
				color: #409EFF;
				display: inline-block;
				vertical-align: top;
				font-size: 13px;
				line-height: 28px;
				border-radius: 2px;
				background: #147A7C;
				text-align: center;
				min-width: 30px;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .el-pager .number.active {
				cursor: default;
				padding: 0 4px;
				margin: 0 5px;
				color: #FFF;
				display: inline-block;
				vertical-align: top;
				font-size: 13px;
				line-height: 28px;
				border-radius: 2px;
				background: #147A7C;
				text-align: center;
				min-width: 30px;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .el-pagination__sizes {
				display: inline-block;
				vertical-align: top;
				font-size: 13px;
				line-height: 28px;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .el-pagination__sizes .el-input {
				margin: 0 5px;
				width: 100px;
				position: relative;
			}
	
	.main-content .el-pagination /deep/ .el-pagination__sizes .el-input .el-input__inner {
				border: 1px solid #DCDFE6;
				cursor: pointer;
				padding: 0 25px 0 8px;
				color: #606266;
				display: inline-block;
				font-size: 13px;
				line-height: 28px;
				border-radius: 3px;
				outline: 0;
				background: #FFF;
				width: 100%;
				text-align: center;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .el-pagination__sizes .el-input span.el-input__suffix {
				top: 0;
				position: absolute;
				right: 0;
				height: 100%;
			}
	
	.main-content .el-pagination /deep/ .el-pagination__sizes .el-input .el-input__suffix .el-select__caret {
				cursor: pointer;
				color: #C0C4CC;
				width: 25px;
				font-size: 14px;
				line-height: 28px;
				text-align: center;
			}
	
	.main-content .el-pagination /deep/ .el-pagination__jump {
				margin: 0 0 0 24px;
				color: #606266;
				display: inline-block;
				vertical-align: top;
				font-size: 13px;
				line-height: 28px;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .el-pagination__jump .el-input {
				border-radius: 3px;
				padding: 0 2px;
				margin: 0 2px;
				display: inline-block;
				width: 50px;
				font-size: 14px;
				line-height: 18px;
				position: relative;
				text-align: center;
				height: 28px;
			}
	
	.main-content .el-pagination /deep/ .el-pagination__jump .el-input .el-input__inner {
				border: 1px solid #DCDFE6;
				cursor: pointer;
				padding: 0 3px;
				color: #606266;
				display: inline-block;
				font-size: 14px;
				line-height: 28px;
				border-radius: 3px;
				outline: 0;
				background: #FFF;
				width: 100%;
				text-align: center;
				height: 28px;
			}
</style>

  • 22
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值