Showing preview only (9,151K chars total). Download the full file or copy to clipboard to get everything.
Repository: linlinjava/litemall
Branch: master
Commit: a1ef964a718b
Files: 1373
Total size: 8.5 MB
Directory structure:
gitextract_gl0yirf4/
├── .gitbook.yaml
├── .github/
│ └── workflows/
│ └── main.yml
├── .gitignore
├── .workflow/
│ ├── BranchPipeline.yml
│ ├── MasterPipeline.yml
│ └── PRPipeline.yml
├── CHANGELOG.md
├── CONTRIBUTE.md
├── LICENSE
├── README.md
├── SECURITY.md
├── deploy/
│ ├── .gitignore
│ ├── README.md
│ ├── bin/
│ │ ├── deploy.sh
│ │ ├── reset.sh
│ │ └── stop.sh
│ ├── db/
│ │ └── .gitkeep
│ ├── litemall/
│ │ └── application.yml
│ └── util/
│ ├── lazy.sh
│ └── package.sh
├── doc/
│ ├── FAQ.md
│ ├── README.md
│ ├── admin.md
│ ├── api.md
│ ├── conf/
│ │ └── nginx.conf
│ ├── database.md
│ ├── how to implement best admin.md
│ ├── mobmall.md
│ ├── note.md
│ ├── performance.md
│ ├── platform.md
│ ├── project.md
│ └── wxmall.md
├── docker/
│ ├── .gitignore
│ ├── README.md
│ ├── bin/
│ │ ├── deploy.sh
│ │ └── reset.sh
│ ├── db/
│ │ ├── conf.d/
│ │ │ └── my.cnf
│ │ ├── data/
│ │ │ └── .gitkeep
│ │ └── init-sql/
│ │ └── .gitkeep
│ ├── docker-compose.yml
│ ├── litemall/
│ │ ├── .gitkeep
│ │ ├── Dockerfile
│ │ └── application.yml
│ └── util/
│ ├── lazy.sh
│ └── package.sh
├── litemall-admin/
│ ├── .editorconfig
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── babel.config.js
│ ├── build/
│ │ └── index.js
│ ├── jest.config.js
│ ├── jsconfig.json
│ ├── package.json
│ ├── postcss.config.js
│ ├── public/
│ │ ├── index.html
│ │ └── tinymce4.7.5/
│ │ ├── langs/
│ │ │ └── zh_CN.js
│ │ └── plugins/
│ │ ├── codesample/
│ │ │ └── css/
│ │ │ └── prism.css
│ │ └── visualblocks/
│ │ └── css/
│ │ └── visualblocks.css
│ ├── src/
│ │ ├── App.vue
│ │ ├── api/
│ │ │ ├── ad.js
│ │ │ ├── admin.js
│ │ │ ├── aftersale.js
│ │ │ ├── brand.js
│ │ │ ├── category.js
│ │ │ ├── comment.js
│ │ │ ├── config.js
│ │ │ ├── coupon.js
│ │ │ ├── dashboard.js
│ │ │ ├── goods.js
│ │ │ ├── groupon.js
│ │ │ ├── issue.js
│ │ │ ├── keyword.js
│ │ │ ├── log.js
│ │ │ ├── login.js
│ │ │ ├── notice.js
│ │ │ ├── order.js
│ │ │ ├── profile.js
│ │ │ ├── region.js
│ │ │ ├── role.js
│ │ │ ├── stat.js
│ │ │ ├── storage.js
│ │ │ ├── topic.js
│ │ │ └── user.js
│ │ ├── components/
│ │ │ ├── BackToTop/
│ │ │ │ └── index.vue
│ │ │ ├── Breadcrumb/
│ │ │ │ └── index.vue
│ │ │ ├── Hamburger/
│ │ │ │ └── index.vue
│ │ │ ├── LocaleChanger/
│ │ │ │ └── index.vue
│ │ │ ├── Notice/
│ │ │ │ └── index.vue
│ │ │ ├── Pagination/
│ │ │ │ └── index.vue
│ │ │ ├── Screenfull/
│ │ │ │ └── index.vue
│ │ │ ├── ScrollPane/
│ │ │ │ └── index.vue
│ │ │ ├── SizeSelect/
│ │ │ │ └── index.vue
│ │ │ └── SvgIcon/
│ │ │ └── index.vue
│ │ ├── directive/
│ │ │ ├── clipboard/
│ │ │ │ ├── clipboard.js
│ │ │ │ └── index.js
│ │ │ └── permission/
│ │ │ ├── index.js
│ │ │ └── permission.js
│ │ ├── filters/
│ │ │ └── index.js
│ │ ├── icons/
│ │ │ ├── index.js
│ │ │ └── svgo.yml
│ │ ├── locales/
│ │ │ ├── en.js
│ │ │ └── zh-Hans.js
│ │ ├── main.js
│ │ ├── permission.js
│ │ ├── router/
│ │ │ └── index.js
│ │ ├── store/
│ │ │ ├── getters.js
│ │ │ ├── index.js
│ │ │ └── modules/
│ │ │ ├── app.js
│ │ │ ├── permission.js
│ │ │ ├── tagsView.js
│ │ │ └── user.js
│ │ ├── styles/
│ │ │ ├── btn.scss
│ │ │ ├── element-ui.scss
│ │ │ ├── element-variables.scss
│ │ │ ├── index.scss
│ │ │ ├── mixin.scss
│ │ │ ├── sidebar.scss
│ │ │ ├── transition.scss
│ │ │ └── variables.scss
│ │ ├── utils/
│ │ │ ├── auth.js
│ │ │ ├── clipboard.js
│ │ │ ├── index.js
│ │ │ ├── openWindow.js
│ │ │ ├── permission.js
│ │ │ ├── print.js
│ │ │ ├── request.js
│ │ │ ├── scrollTo.js
│ │ │ └── validate.js
│ │ ├── vendor/
│ │ │ └── Export2Excel.js
│ │ └── views/
│ │ ├── config/
│ │ │ ├── express.vue
│ │ │ ├── mall.vue
│ │ │ ├── order.vue
│ │ │ └── wx.vue
│ │ ├── dashboard/
│ │ │ └── index.vue
│ │ ├── errorPage/
│ │ │ ├── 401.vue
│ │ │ └── 404.vue
│ │ ├── goods/
│ │ │ ├── comment.vue
│ │ │ ├── create.vue
│ │ │ ├── edit.vue
│ │ │ └── list.vue
│ │ ├── layout/
│ │ │ ├── Layout.vue
│ │ │ ├── components/
│ │ │ │ ├── AppMain.vue
│ │ │ │ ├── Navbar.vue
│ │ │ │ ├── Sidebar/
│ │ │ │ │ ├── FixiOSBug.js
│ │ │ │ │ ├── Item.vue
│ │ │ │ │ ├── Link.vue
│ │ │ │ │ ├── SidebarItem.vue
│ │ │ │ │ └── index.vue
│ │ │ │ ├── TagsView/
│ │ │ │ │ ├── ScrollPane.vue
│ │ │ │ │ └── index.vue
│ │ │ │ └── index.js
│ │ │ └── mixin/
│ │ │ └── ResizeHandler.js
│ │ ├── login/
│ │ │ ├── authredirect.vue
│ │ │ └── index.vue
│ │ ├── mall/
│ │ │ ├── aftersale.vue
│ │ │ ├── brand.vue
│ │ │ ├── category.vue
│ │ │ ├── issue.vue
│ │ │ ├── keyword.vue
│ │ │ ├── order.vue
│ │ │ └── region.vue
│ │ ├── profile/
│ │ │ ├── notice.vue
│ │ │ └── password.vue
│ │ ├── promotion/
│ │ │ ├── ad.vue
│ │ │ ├── coupon.vue
│ │ │ ├── couponDetail.vue
│ │ │ ├── grouponActivity.vue
│ │ │ ├── grouponRule.vue
│ │ │ ├── topic.vue
│ │ │ ├── topicCreate.vue
│ │ │ └── topicEdit.vue
│ │ ├── redirect/
│ │ │ └── index.vue
│ │ ├── stat/
│ │ │ ├── goods.vue
│ │ │ ├── order.vue
│ │ │ └── user.vue
│ │ ├── sys/
│ │ │ ├── admin.vue
│ │ │ ├── log.vue
│ │ │ ├── notice.vue
│ │ │ ├── os.vue
│ │ │ └── role.vue
│ │ └── user/
│ │ ├── address.vue
│ │ ├── collect.vue
│ │ ├── feedback.vue
│ │ ├── footprint.vue
│ │ ├── history.vue
│ │ └── user.vue
│ └── vue.config.js
├── litemall-admin-api/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── org/
│ │ │ └── linlinjava/
│ │ │ └── litemall/
│ │ │ └── admin/
│ │ │ ├── Application.java
│ │ │ ├── annotation/
│ │ │ │ └── RequiresPermissionsDesc.java
│ │ │ ├── config/
│ │ │ │ ├── AdminSwagger2Configuration.java
│ │ │ │ ├── KaptchaConfig.java
│ │ │ │ ├── ShiroConfig.java
│ │ │ │ └── ShiroExceptionHandler.java
│ │ │ ├── dto/
│ │ │ │ └── GoodsAllinone.java
│ │ │ ├── job/
│ │ │ │ ├── CouponJob.java
│ │ │ │ ├── DbJob.java
│ │ │ │ └── OrderJob.java
│ │ │ ├── service/
│ │ │ │ ├── AdminGoodsService.java
│ │ │ │ ├── AdminOrderService.java
│ │ │ │ └── LogHelper.java
│ │ │ ├── shiro/
│ │ │ │ ├── AdminAuthorizingRealm.java
│ │ │ │ └── AdminWebSessionManager.java
│ │ │ ├── task/
│ │ │ │ ├── AdminTaskStartupRunner.java
│ │ │ │ └── GrouponRuleExpiredTask.java
│ │ │ ├── util/
│ │ │ │ ├── AdminResponseCode.java
│ │ │ │ ├── Permission.java
│ │ │ │ └── PermissionUtil.java
│ │ │ ├── vo/
│ │ │ │ ├── CatVo.java
│ │ │ │ ├── CategoryVo.java
│ │ │ │ ├── PermVo.java
│ │ │ │ ├── RegionVo.java
│ │ │ │ └── StatVo.java
│ │ │ └── web/
│ │ │ ├── AdminAdController.java
│ │ │ ├── AdminAddressController.java
│ │ │ ├── AdminAdminController.java
│ │ │ ├── AdminAftersaleController.java
│ │ │ ├── AdminAuthController.java
│ │ │ ├── AdminBrandController.java
│ │ │ ├── AdminCategoryController.java
│ │ │ ├── AdminCollectController.java
│ │ │ ├── AdminCommentController.java
│ │ │ ├── AdminConfigController.java
│ │ │ ├── AdminCouponController.java
│ │ │ ├── AdminDashbordController.java
│ │ │ ├── AdminFeedbackController.java
│ │ │ ├── AdminFootprintController.java
│ │ │ ├── AdminGoodsController.java
│ │ │ ├── AdminGrouponController.java
│ │ │ ├── AdminHistoryController.java
│ │ │ ├── AdminIndexController.java
│ │ │ ├── AdminIssueController.java
│ │ │ ├── AdminKeywordController.java
│ │ │ ├── AdminLogController.java
│ │ │ ├── AdminNoticeController.java
│ │ │ ├── AdminOrderController.java
│ │ │ ├── AdminProfileController.java
│ │ │ ├── AdminRegionController.java
│ │ │ ├── AdminRoleController.java
│ │ │ ├── AdminStatController.java
│ │ │ ├── AdminStorageController.java
│ │ │ ├── AdminTopicController.java
│ │ │ └── AdminUserController.java
│ │ └── resources/
│ │ ├── application-admin.yml
│ │ └── application.yml
│ └── test/
│ └── java/
│ └── org/
│ └── linlinjava/
│ └── litemall/
│ └── admin/
│ ├── AdminConfigTest.java
│ ├── BcryptTest.java
│ ├── CreateShareImageTest.java
│ ├── DbTest.java
│ └── PermissionTest.java
├── litemall-all/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── org/
│ │ │ └── linlinjava/
│ │ │ └── litemall/
│ │ │ └── Application.java
│ │ └── resources/
│ │ ├── application.yml
│ │ └── logback-spring.xml
│ └── test/
│ └── java/
│ └── org/
│ └── linlinjava/
│ └── litemall/
│ └── allinone/
│ └── AllinoneConfigTest.java
├── litemall-all-war/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ └── main/
│ ├── java/
│ │ └── org/
│ │ └── linlinjava/
│ │ └── litemall/
│ │ └── Application.java
│ └── resources/
│ ├── application.yml
│ └── logback-spring.xml
├── litemall-core/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── org/
│ │ │ └── linlinjava/
│ │ │ └── litemall/
│ │ │ └── core/
│ │ │ ├── config/
│ │ │ │ ├── AsyncConfig.java
│ │ │ │ ├── CorsConfig.java
│ │ │ │ ├── GlobalExceptionHandler.java
│ │ │ │ ├── JacksonConfig.java
│ │ │ │ ├── ValidatorConfiguration.java
│ │ │ │ ├── WxConfig.java
│ │ │ │ └── WxProperties.java
│ │ │ ├── express/
│ │ │ │ ├── ExpressService.java
│ │ │ │ ├── config/
│ │ │ │ │ ├── ExpressAutoConfiguration.java
│ │ │ │ │ └── ExpressProperties.java
│ │ │ │ └── dao/
│ │ │ │ ├── ExpressInfo.java
│ │ │ │ └── Traces.java
│ │ │ ├── notify/
│ │ │ │ ├── AliyunSmsSender.java
│ │ │ │ ├── NotifyService.java
│ │ │ │ ├── NotifyType.java
│ │ │ │ ├── SmsResult.java
│ │ │ │ ├── SmsSender.java
│ │ │ │ ├── TencentSmsSender.java
│ │ │ │ └── config/
│ │ │ │ ├── NotifyAutoConfiguration.java
│ │ │ │ └── NotifyProperties.java
│ │ │ ├── qcode/
│ │ │ │ └── QCodeService.java
│ │ │ ├── storage/
│ │ │ │ ├── AliyunStorage.java
│ │ │ │ ├── LocalStorage.java
│ │ │ │ ├── QiniuStorage.java
│ │ │ │ ├── Storage.java
│ │ │ │ ├── StorageService.java
│ │ │ │ ├── TencentStorage.java
│ │ │ │ └── config/
│ │ │ │ ├── StorageAutoConfiguration.java
│ │ │ │ └── StorageProperties.java
│ │ │ ├── system/
│ │ │ │ ├── SystemConfig.java
│ │ │ │ └── SystemInistService.java
│ │ │ ├── task/
│ │ │ │ ├── Task.java
│ │ │ │ └── TaskService.java
│ │ │ ├── util/
│ │ │ │ ├── BeanUtil.java
│ │ │ │ ├── CharUtil.java
│ │ │ │ ├── DateTimeUtil.java
│ │ │ │ ├── HttpUtil.java
│ │ │ │ ├── IpUtil.java
│ │ │ │ ├── JacksonUtil.java
│ │ │ │ ├── RegexUtil.java
│ │ │ │ ├── ResponseUtil.java
│ │ │ │ ├── SystemInfoPrinter.java
│ │ │ │ └── bcrypt/
│ │ │ │ ├── BCrypt.java
│ │ │ │ └── BCryptPasswordEncoder.java
│ │ │ └── validator/
│ │ │ ├── Order.java
│ │ │ ├── OrderValidator.java
│ │ │ ├── Sort.java
│ │ │ └── SortValidator.java
│ │ └── resources/
│ │ ├── application-core.yml
│ │ └── application.yml
│ └── test/
│ └── java/
│ └── org/
│ └── linlinjava/
│ └── litemall/
│ └── core/
│ ├── AliyunStorageTest.java
│ ├── Application.java
│ ├── AsyncTask.java
│ ├── AsyncTest.java
│ ├── CoreConfigTest.java
│ ├── ExpressTest.java
│ ├── IntegerTest.java
│ ├── LocalStorageTest.java
│ ├── MailTest.java
│ ├── QiniuStorageTest.java
│ ├── SmsTest.java
│ ├── TaskTest.java
│ ├── TencentStorageTest.java
│ └── util/
│ └── bcrypt/
│ └── BCryptTest.java
├── litemall-db/
│ ├── .gitignore
│ ├── mybatis-generator/
│ │ └── generatorConfig.xml
│ ├── pom.xml
│ ├── sql/
│ │ ├── README.md
│ │ ├── litemall_data.sql
│ │ ├── litemall_schema.sql
│ │ └── litemall_table.sql
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── org/
│ │ │ └── linlinjava/
│ │ │ └── litemall/
│ │ │ └── db/
│ │ │ ├── dao/
│ │ │ │ ├── GoodsProductMapper.java
│ │ │ │ ├── LitemallAdMapper.java
│ │ │ │ ├── LitemallAddressMapper.java
│ │ │ │ ├── LitemallAdminMapper.java
│ │ │ │ ├── LitemallAftersaleMapper.java
│ │ │ │ ├── LitemallBrandMapper.java
│ │ │ │ ├── LitemallCartMapper.java
│ │ │ │ ├── LitemallCategoryMapper.java
│ │ │ │ ├── LitemallCollectMapper.java
│ │ │ │ ├── LitemallCommentMapper.java
│ │ │ │ ├── LitemallCouponMapper.java
│ │ │ │ ├── LitemallCouponUserMapper.java
│ │ │ │ ├── LitemallFeedbackMapper.java
│ │ │ │ ├── LitemallFootprintMapper.java
│ │ │ │ ├── LitemallGoodsAttributeMapper.java
│ │ │ │ ├── LitemallGoodsMapper.java
│ │ │ │ ├── LitemallGoodsProductMapper.java
│ │ │ │ ├── LitemallGoodsSpecificationMapper.java
│ │ │ │ ├── LitemallGrouponMapper.java
│ │ │ │ ├── LitemallGrouponRulesMapper.java
│ │ │ │ ├── LitemallIssueMapper.java
│ │ │ │ ├── LitemallKeywordMapper.java
│ │ │ │ ├── LitemallLogMapper.java
│ │ │ │ ├── LitemallNoticeAdminMapper.java
│ │ │ │ ├── LitemallNoticeMapper.java
│ │ │ │ ├── LitemallOrderGoodsMapper.java
│ │ │ │ ├── LitemallOrderMapper.java
│ │ │ │ ├── LitemallPermissionMapper.java
│ │ │ │ ├── LitemallRegionMapper.java
│ │ │ │ ├── LitemallRoleMapper.java
│ │ │ │ ├── LitemallSearchHistoryMapper.java
│ │ │ │ ├── LitemallStorageMapper.java
│ │ │ │ ├── LitemallSystemMapper.java
│ │ │ │ ├── LitemallTopicMapper.java
│ │ │ │ ├── LitemallUserMapper.java
│ │ │ │ ├── OrderMapper.java
│ │ │ │ └── StatMapper.java
│ │ │ ├── domain/
│ │ │ │ ├── LitemallAd.java
│ │ │ │ ├── LitemallAdExample.java
│ │ │ │ ├── LitemallAddress.java
│ │ │ │ ├── LitemallAddressExample.java
│ │ │ │ ├── LitemallAdmin.java
│ │ │ │ ├── LitemallAdminExample.java
│ │ │ │ ├── LitemallAftersale.java
│ │ │ │ ├── LitemallAftersaleExample.java
│ │ │ │ ├── LitemallBrand.java
│ │ │ │ ├── LitemallBrandExample.java
│ │ │ │ ├── LitemallCart.java
│ │ │ │ ├── LitemallCartExample.java
│ │ │ │ ├── LitemallCategory.java
│ │ │ │ ├── LitemallCategoryExample.java
│ │ │ │ ├── LitemallCollect.java
│ │ │ │ ├── LitemallCollectExample.java
│ │ │ │ ├── LitemallComment.java
│ │ │ │ ├── LitemallCommentExample.java
│ │ │ │ ├── LitemallCoupon.java
│ │ │ │ ├── LitemallCouponExample.java
│ │ │ │ ├── LitemallCouponUser.java
│ │ │ │ ├── LitemallCouponUserExample.java
│ │ │ │ ├── LitemallFeedback.java
│ │ │ │ ├── LitemallFeedbackExample.java
│ │ │ │ ├── LitemallFootprint.java
│ │ │ │ ├── LitemallFootprintExample.java
│ │ │ │ ├── LitemallGoods.java
│ │ │ │ ├── LitemallGoodsAttribute.java
│ │ │ │ ├── LitemallGoodsAttributeExample.java
│ │ │ │ ├── LitemallGoodsExample.java
│ │ │ │ ├── LitemallGoodsProduct.java
│ │ │ │ ├── LitemallGoodsProductExample.java
│ │ │ │ ├── LitemallGoodsSpecification.java
│ │ │ │ ├── LitemallGoodsSpecificationExample.java
│ │ │ │ ├── LitemallGroupon.java
│ │ │ │ ├── LitemallGrouponExample.java
│ │ │ │ ├── LitemallGrouponRules.java
│ │ │ │ ├── LitemallGrouponRulesExample.java
│ │ │ │ ├── LitemallIssue.java
│ │ │ │ ├── LitemallIssueExample.java
│ │ │ │ ├── LitemallKeyword.java
│ │ │ │ ├── LitemallKeywordExample.java
│ │ │ │ ├── LitemallLog.java
│ │ │ │ ├── LitemallLogExample.java
│ │ │ │ ├── LitemallNotice.java
│ │ │ │ ├── LitemallNoticeAdmin.java
│ │ │ │ ├── LitemallNoticeAdminExample.java
│ │ │ │ ├── LitemallNoticeExample.java
│ │ │ │ ├── LitemallOrder.java
│ │ │ │ ├── LitemallOrderExample.java
│ │ │ │ ├── LitemallOrderGoods.java
│ │ │ │ ├── LitemallOrderGoodsExample.java
│ │ │ │ ├── LitemallPermission.java
│ │ │ │ ├── LitemallPermissionExample.java
│ │ │ │ ├── LitemallRegion.java
│ │ │ │ ├── LitemallRegionExample.java
│ │ │ │ ├── LitemallRole.java
│ │ │ │ ├── LitemallRoleExample.java
│ │ │ │ ├── LitemallSearchHistory.java
│ │ │ │ ├── LitemallSearchHistoryExample.java
│ │ │ │ ├── LitemallStorage.java
│ │ │ │ ├── LitemallStorageExample.java
│ │ │ │ ├── LitemallSystem.java
│ │ │ │ ├── LitemallSystemExample.java
│ │ │ │ ├── LitemallTopic.java
│ │ │ │ ├── LitemallTopicExample.java
│ │ │ │ ├── LitemallUser.java
│ │ │ │ ├── LitemallUserExample.java
│ │ │ │ ├── OrderGoodsVo.java
│ │ │ │ ├── OrderVo.java
│ │ │ │ └── UserVo.java
│ │ │ ├── mybatis/
│ │ │ │ ├── JsonIntegerArrayTypeHandler.java
│ │ │ │ ├── JsonNodeTypeHandler.java
│ │ │ │ └── JsonStringArrayTypeHandler.java
│ │ │ ├── service/
│ │ │ │ ├── CouponAssignService.java
│ │ │ │ ├── CouponVerifyService.java
│ │ │ │ ├── LitemallAdService.java
│ │ │ │ ├── LitemallAddressService.java
│ │ │ │ ├── LitemallAdminService.java
│ │ │ │ ├── LitemallAftersaleService.java
│ │ │ │ ├── LitemallBrandService.java
│ │ │ │ ├── LitemallCartService.java
│ │ │ │ ├── LitemallCategoryService.java
│ │ │ │ ├── LitemallCollectService.java
│ │ │ │ ├── LitemallCommentService.java
│ │ │ │ ├── LitemallCouponService.java
│ │ │ │ ├── LitemallCouponUserService.java
│ │ │ │ ├── LitemallFeedbackService.java
│ │ │ │ ├── LitemallFootprintService.java
│ │ │ │ ├── LitemallGoodsAttributeService.java
│ │ │ │ ├── LitemallGoodsProductService.java
│ │ │ │ ├── LitemallGoodsService.java
│ │ │ │ ├── LitemallGoodsSpecificationService.java
│ │ │ │ ├── LitemallGrouponRulesService.java
│ │ │ │ ├── LitemallGrouponService.java
│ │ │ │ ├── LitemallIssueService.java
│ │ │ │ ├── LitemallKeywordService.java
│ │ │ │ ├── LitemallLogService.java
│ │ │ │ ├── LitemallNoticeAdminService.java
│ │ │ │ ├── LitemallNoticeService.java
│ │ │ │ ├── LitemallOrderGoodsService.java
│ │ │ │ ├── LitemallOrderService.java
│ │ │ │ ├── LitemallPermissionService.java
│ │ │ │ ├── LitemallRegionService.java
│ │ │ │ ├── LitemallRoleService.java
│ │ │ │ ├── LitemallSearchHistoryService.java
│ │ │ │ ├── LitemallStorageService.java
│ │ │ │ ├── LitemallSystemConfigService.java
│ │ │ │ ├── LitemallTopicService.java
│ │ │ │ ├── LitemallUserService.java
│ │ │ │ └── StatService.java
│ │ │ └── util/
│ │ │ ├── AftersaleConstant.java
│ │ │ ├── CouponConstant.java
│ │ │ ├── CouponUserConstant.java
│ │ │ ├── DbUtil.java
│ │ │ ├── GrouponConstant.java
│ │ │ ├── OrderHandleOption.java
│ │ │ └── OrderUtil.java
│ │ └── resources/
│ │ ├── application-db.yml
│ │ ├── application.yml
│ │ └── org/
│ │ └── linlinjava/
│ │ └── litemall/
│ │ └── db/
│ │ └── dao/
│ │ ├── GoodsProductMapper.xml
│ │ ├── LitemallAdMapper.xml
│ │ ├── LitemallAddressMapper.xml
│ │ ├── LitemallAdminMapper.xml
│ │ ├── LitemallAftersaleMapper.xml
│ │ ├── LitemallBrandMapper.xml
│ │ ├── LitemallCartMapper.xml
│ │ ├── LitemallCategoryMapper.xml
│ │ ├── LitemallCollectMapper.xml
│ │ ├── LitemallCommentMapper.xml
│ │ ├── LitemallCouponMapper.xml
│ │ ├── LitemallCouponUserMapper.xml
│ │ ├── LitemallFeedbackMapper.xml
│ │ ├── LitemallFootprintMapper.xml
│ │ ├── LitemallGoodsAttributeMapper.xml
│ │ ├── LitemallGoodsMapper.xml
│ │ ├── LitemallGoodsProductMapper.xml
│ │ ├── LitemallGoodsSpecificationMapper.xml
│ │ ├── LitemallGrouponMapper.xml
│ │ ├── LitemallGrouponRulesMapper.xml
│ │ ├── LitemallIssueMapper.xml
│ │ ├── LitemallKeywordMapper.xml
│ │ ├── LitemallLogMapper.xml
│ │ ├── LitemallNoticeAdminMapper.xml
│ │ ├── LitemallNoticeMapper.xml
│ │ ├── LitemallOrderGoodsMapper.xml
│ │ ├── LitemallOrderMapper.xml
│ │ ├── LitemallPermissionMapper.xml
│ │ ├── LitemallRegionMapper.xml
│ │ ├── LitemallRoleMapper.xml
│ │ ├── LitemallSearchHistoryMapper.xml
│ │ ├── LitemallStorageMapper.xml
│ │ ├── LitemallSystemMapper.xml
│ │ ├── LitemallTopicMapper.xml
│ │ ├── LitemallUserMapper.xml
│ │ ├── OrderMapper.xml
│ │ └── StatMapper.xml
│ └── test/
│ └── java/
│ └── org/
│ └── linlinjava/
│ └── litemall/
│ └── db/
│ ├── Application.java
│ ├── DbConfigTest.java
│ ├── DbTest.java
│ ├── DbUtilTest.java
│ ├── MapperReturnTest.java
│ ├── StatMapperTest.java
│ └── StockTest.java
├── litemall-vue/
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── .postcssrc.js
│ ├── .prettierrc.js
│ ├── babel.config.js
│ ├── package.json
│ ├── public/
│ │ └── index.html
│ ├── src/
│ │ ├── App.vue
│ │ ├── api/
│ │ │ └── api.js
│ │ ├── assets/
│ │ │ └── scss/
│ │ │ ├── _mixin.scss
│ │ │ ├── _vant-theme.scss
│ │ │ ├── _var.scss
│ │ │ ├── common.scss
│ │ │ ├── global.scss
│ │ │ ├── iconfont/
│ │ │ │ └── iconfont.css
│ │ │ └── mixin/
│ │ │ └── _one-border.scss
│ │ ├── components/
│ │ │ ├── Header/
│ │ │ │ └── index.vue
│ │ │ ├── Tabbar/
│ │ │ │ └── index.vue
│ │ │ ├── field/
│ │ │ │ └── index.vue
│ │ │ ├── field-group/
│ │ │ │ └── index.vue
│ │ │ └── is-empty/
│ │ │ └── index.vue
│ │ ├── filter/
│ │ │ └── index.js
│ │ ├── main.js
│ │ ├── mixin/
│ │ │ └── scroll-fixed.js
│ │ ├── router/
│ │ │ ├── home.js
│ │ │ ├── index.js
│ │ │ ├── items.js
│ │ │ ├── login.js
│ │ │ ├── order.js
│ │ │ └── user.js
│ │ ├── store/
│ │ │ ├── getters.js
│ │ │ ├── index.js
│ │ │ ├── mutation-types.js
│ │ │ └── mutations.js
│ │ ├── utils/
│ │ │ ├── auth.js
│ │ │ ├── local-storage.js
│ │ │ ├── location-param.js
│ │ │ ├── request.js
│ │ │ ├── scroll.js
│ │ │ └── validate.js
│ │ └── views/
│ │ ├── home/
│ │ │ └── tabbar-home.vue
│ │ ├── items/
│ │ │ ├── brand/
│ │ │ │ └── index.vue
│ │ │ ├── brand-list/
│ │ │ │ └── index.vue
│ │ │ ├── category/
│ │ │ │ └── index.vue
│ │ │ ├── detail/
│ │ │ │ ├── index.vue
│ │ │ │ └── popup-props.vue
│ │ │ ├── groupon/
│ │ │ │ └── index.vue
│ │ │ ├── hot/
│ │ │ │ └── index.vue
│ │ │ ├── new/
│ │ │ │ └── index.vue
│ │ │ ├── search/
│ │ │ │ └── index.vue
│ │ │ ├── tabbar-catalog.vue
│ │ │ ├── topic/
│ │ │ │ └── index.vue
│ │ │ └── topic-list/
│ │ │ └── index.vue
│ │ ├── login/
│ │ │ ├── forget/
│ │ │ │ └── index.vue
│ │ │ ├── forget-reset/
│ │ │ │ └── index.vue
│ │ │ ├── forget-status/
│ │ │ │ └── index.vue
│ │ │ ├── login.vue
│ │ │ ├── register-getCode/
│ │ │ │ └── index.vue
│ │ │ ├── register-status/
│ │ │ │ └── index.vue
│ │ │ └── register-submit/
│ │ │ └── index.vue
│ │ ├── order/
│ │ │ ├── checkout.vue
│ │ │ ├── order-detail/
│ │ │ │ └── index.vue
│ │ │ ├── payment/
│ │ │ │ └── index.vue
│ │ │ ├── payment-status/
│ │ │ │ └── index.vue
│ │ │ └── tabbar-cart.vue
│ │ └── user/
│ │ ├── coupon-list/
│ │ │ └── index.vue
│ │ ├── module-address/
│ │ │ └── index.vue
│ │ ├── module-address-edit/
│ │ │ ├── area.json
│ │ │ └── index.vue
│ │ ├── module-collect/
│ │ │ └── index.vue
│ │ ├── module-feedback/
│ │ │ └── index.vue
│ │ ├── module-help/
│ │ │ └── index.vue
│ │ ├── module-server/
│ │ │ └── index.vue
│ │ ├── order-list/
│ │ │ └── index.vue
│ │ ├── refund-list/
│ │ │ └── index.vue
│ │ ├── tabbar-user-coupon.vue
│ │ ├── tabbar-user-header.vue
│ │ ├── tabbar-user-module.vue
│ │ ├── tabbar-user-order.vue
│ │ ├── tabbar-user.vue
│ │ └── user-information-set/
│ │ ├── index.vue
│ │ ├── set-mobile/
│ │ │ └── index.vue
│ │ ├── set-nickname/
│ │ │ └── index.vue
│ │ └── set-password/
│ │ └── index.vue
│ └── vue.config.js
├── litemall-wx/
│ ├── app.js
│ ├── app.json
│ ├── app.wxss
│ ├── config/
│ │ └── api.js
│ ├── lib/
│ │ ├── vant-weapp/
│ │ │ ├── action-sheet/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── area/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── button/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── card/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── cell/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── cell-group/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── checkbox/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── checkbox-group/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── circle/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── col/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── collapse/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── collapse-item/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── common/
│ │ │ │ ├── color.d.ts
│ │ │ │ ├── color.js
│ │ │ │ ├── component.d.ts
│ │ │ │ ├── component.js
│ │ │ │ ├── index.wxss
│ │ │ │ ├── style/
│ │ │ │ │ ├── clearfix.wxss
│ │ │ │ │ ├── ellipsis.wxss
│ │ │ │ │ ├── hairline.wxss
│ │ │ │ │ ├── mixins/
│ │ │ │ │ │ ├── clearfix.wxss
│ │ │ │ │ │ ├── ellipsis.wxss
│ │ │ │ │ │ └── hairline.wxss
│ │ │ │ │ ├── theme.wxss
│ │ │ │ │ └── var.wxss
│ │ │ │ ├── utils.d.ts
│ │ │ │ └── utils.js
│ │ │ ├── count-down/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxss
│ │ │ │ ├── utils.d.ts
│ │ │ │ └── utils.js
│ │ │ ├── datetime-picker/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── definitions/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── weapp.d.ts
│ │ │ │ └── weapp.js
│ │ │ ├── dialog/
│ │ │ │ ├── dialog.d.ts
│ │ │ │ ├── dialog.js
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── divider/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── dropdown-item/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── dropdown-menu/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxs
│ │ │ │ └── index.wxss
│ │ │ ├── field/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── goods-action/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── goods-action-button/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── goods-action-icon/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── grid/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── grid-item/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── icon/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── image/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── index-anchor/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── index-bar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── info/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── loading/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── mixins/
│ │ │ │ ├── basic.d.ts
│ │ │ │ ├── basic.js
│ │ │ │ ├── button.d.ts
│ │ │ │ ├── button.js
│ │ │ │ ├── link.d.ts
│ │ │ │ ├── link.js
│ │ │ │ ├── observer/
│ │ │ │ │ ├── behavior.d.ts
│ │ │ │ │ ├── behavior.js
│ │ │ │ │ ├── index.d.ts
│ │ │ │ │ └── index.js
│ │ │ │ ├── open-type.d.ts
│ │ │ │ ├── open-type.js
│ │ │ │ ├── touch.d.ts
│ │ │ │ ├── touch.js
│ │ │ │ ├── transition.d.ts
│ │ │ │ └── transition.js
│ │ │ ├── nav-bar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── notice-bar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── notify/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxss
│ │ │ │ ├── notify.d.ts
│ │ │ │ └── notify.js
│ │ │ ├── overlay/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── panel/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── picker/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxss
│ │ │ │ ├── shared.d.ts
│ │ │ │ └── shared.js
│ │ │ ├── picker-column/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxs
│ │ │ │ └── index.wxss
│ │ │ ├── popup/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── progress/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxs
│ │ │ │ └── index.wxss
│ │ │ ├── radio/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── radio-group/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── rate/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── row/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── search/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── sidebar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── sidebar-item/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── skeleton/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── slider/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── stepper/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── steps/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── sticky/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── submit-bar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── swipe-cell/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── switch/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── tab/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── tabbar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── tabbar-item/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── tabs/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxs
│ │ │ │ └── index.wxss
│ │ │ ├── tag/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── toast/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxss
│ │ │ │ ├── toast.d.ts
│ │ │ │ └── toast.js
│ │ │ ├── transition/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── tree-select/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxs
│ │ │ │ └── index.wxss
│ │ │ ├── uploader/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxss
│ │ │ │ ├── utils.d.ts
│ │ │ │ └── utils.js
│ │ │ └── wxs/
│ │ │ ├── array.wxs
│ │ │ ├── bem.wxs
│ │ │ ├── memoize.wxs
│ │ │ ├── object.wxs
│ │ │ └── utils.wxs
│ │ └── wxParse/
│ │ ├── html2json.js
│ │ ├── htmlparser.js
│ │ ├── showdown.js
│ │ ├── wxDiscode.js
│ │ ├── wxParse.js
│ │ ├── wxParse.wxml
│ │ └── wxParse.wxss
│ ├── pages/
│ │ ├── about/
│ │ │ ├── about.js
│ │ │ ├── about.json
│ │ │ ├── about.wxml
│ │ │ └── about.wxss
│ │ ├── auth/
│ │ │ ├── accountLogin/
│ │ │ │ ├── accountLogin.js
│ │ │ │ ├── accountLogin.json
│ │ │ │ ├── accountLogin.wxml
│ │ │ │ └── accountLogin.wxss
│ │ │ ├── login/
│ │ │ │ ├── login.js
│ │ │ │ ├── login.json
│ │ │ │ ├── login.wxml
│ │ │ │ └── login.wxss
│ │ │ ├── register/
│ │ │ │ ├── register.js
│ │ │ │ ├── register.json
│ │ │ │ ├── register.wxml
│ │ │ │ └── register.wxss
│ │ │ └── reset/
│ │ │ ├── reset.js
│ │ │ ├── reset.json
│ │ │ ├── reset.wxml
│ │ │ └── reset.wxss
│ │ ├── brand/
│ │ │ ├── brand.js
│ │ │ ├── brand.json
│ │ │ ├── brand.wxml
│ │ │ └── brand.wxss
│ │ ├── brandDetail/
│ │ │ ├── brandDetail.js
│ │ │ ├── brandDetail.json
│ │ │ ├── brandDetail.wxml
│ │ │ └── brandDetail.wxss
│ │ ├── cart/
│ │ │ ├── cart.js
│ │ │ ├── cart.json
│ │ │ ├── cart.wxml
│ │ │ └── cart.wxss
│ │ ├── catalog/
│ │ │ ├── catalog.js
│ │ │ ├── catalog.json
│ │ │ ├── catalog.wxml
│ │ │ └── catalog.wxss
│ │ ├── category/
│ │ │ ├── category.js
│ │ │ ├── category.json
│ │ │ ├── category.wxml
│ │ │ └── category.wxss
│ │ ├── checkout/
│ │ │ ├── checkout.js
│ │ │ ├── checkout.json
│ │ │ ├── checkout.wxml
│ │ │ └── checkout.wxss
│ │ ├── comment/
│ │ │ ├── comment.js
│ │ │ ├── comment.json
│ │ │ ├── comment.wxml
│ │ │ └── comment.wxss
│ │ ├── commentPost/
│ │ │ ├── commentPost.js
│ │ │ ├── commentPost.json
│ │ │ ├── commentPost.wxml
│ │ │ └── commentPost.wxss
│ │ ├── coupon/
│ │ │ ├── coupon.js
│ │ │ ├── coupon.json
│ │ │ ├── coupon.wxml
│ │ │ └── coupon.wxss
│ │ ├── goods/
│ │ │ ├── goods.js
│ │ │ ├── goods.json
│ │ │ ├── goods.wxml
│ │ │ └── goods.wxss
│ │ ├── groupon/
│ │ │ ├── grouponDetail/
│ │ │ │ ├── grouponDetail.js
│ │ │ │ ├── grouponDetail.json
│ │ │ │ ├── grouponDetail.wxml
│ │ │ │ └── grouponDetail.wxss
│ │ │ ├── grouponList/
│ │ │ │ ├── grouponList.js
│ │ │ │ ├── grouponList.json
│ │ │ │ ├── grouponList.wxml
│ │ │ │ └── grouponList.wxss
│ │ │ └── myGroupon/
│ │ │ ├── myGroupon.js
│ │ │ ├── myGroupon.json
│ │ │ ├── myGroupon.wxml
│ │ │ └── myGroupon.wxss
│ │ ├── help/
│ │ │ ├── help.js
│ │ │ ├── help.json
│ │ │ ├── help.wxml
│ │ │ └── help.wxss
│ │ ├── hotGoods/
│ │ │ ├── hotGoods.js
│ │ │ ├── hotGoods.json
│ │ │ ├── hotGoods.wxml
│ │ │ └── hotGoods.wxss
│ │ ├── index/
│ │ │ ├── index.js
│ │ │ ├── index.json
│ │ │ ├── index.wxml
│ │ │ └── index.wxss
│ │ ├── newGoods/
│ │ │ ├── newGoods.js
│ │ │ ├── newGoods.json
│ │ │ ├── newGoods.wxml
│ │ │ └── newGoods.wxss
│ │ ├── payResult/
│ │ │ ├── payResult.js
│ │ │ ├── payResult.json
│ │ │ ├── payResult.wxml
│ │ │ └── payResult.wxss
│ │ ├── search/
│ │ │ ├── search.js
│ │ │ ├── search.json
│ │ │ ├── search.wxml
│ │ │ └── search.wxss
│ │ ├── topic/
│ │ │ ├── topic.js
│ │ │ ├── topic.json
│ │ │ ├── topic.wxml
│ │ │ └── topic.wxss
│ │ ├── topicComment/
│ │ │ ├── topicComment.js
│ │ │ ├── topicComment.json
│ │ │ ├── topicComment.wxml
│ │ │ └── topicComment.wxss
│ │ ├── topicCommentPost/
│ │ │ ├── topicCommentPost.js
│ │ │ ├── topicCommentPost.json
│ │ │ ├── topicCommentPost.wxml
│ │ │ └── topicCommentPost.wxss
│ │ ├── topicDetail/
│ │ │ ├── topicDetail.js
│ │ │ ├── topicDetail.json
│ │ │ ├── topicDetail.wxml
│ │ │ └── topicDetail.wxss
│ │ └── ucenter/
│ │ ├── address/
│ │ │ ├── address.js
│ │ │ ├── address.json
│ │ │ ├── address.wxml
│ │ │ └── address.wxss
│ │ ├── addressAdd/
│ │ │ ├── addressAdd.js
│ │ │ ├── addressAdd.json
│ │ │ ├── addressAdd.wxml
│ │ │ └── addressAdd.wxss
│ │ ├── aftersale/
│ │ │ ├── aftersale.js
│ │ │ ├── aftersale.json
│ │ │ ├── aftersale.wxml
│ │ │ └── aftersale.wxss
│ │ ├── aftersaleDetail/
│ │ │ ├── aftersaleDetail.js
│ │ │ ├── aftersaleDetail.json
│ │ │ ├── aftersaleDetail.wxml
│ │ │ └── aftersaleDetail.wxss
│ │ ├── aftersaleList/
│ │ │ ├── aftersaleList.js
│ │ │ ├── aftersaleList.json
│ │ │ ├── aftersaleList.wxml
│ │ │ └── aftersaleList.wxss
│ │ ├── collect/
│ │ │ ├── collect.js
│ │ │ ├── collect.json
│ │ │ ├── collect.wxml
│ │ │ └── collect.wxss
│ │ ├── couponList/
│ │ │ ├── couponList.js
│ │ │ ├── couponList.json
│ │ │ ├── couponList.wxml
│ │ │ └── couponList.wxss
│ │ ├── couponSelect/
│ │ │ ├── couponSelect.js
│ │ │ ├── couponSelect.json
│ │ │ ├── couponSelect.wxml
│ │ │ └── couponSelect.wxss
│ │ ├── feedback/
│ │ │ ├── feedback.js
│ │ │ ├── feedback.json
│ │ │ ├── feedback.wxml
│ │ │ └── feedback.wxss
│ │ ├── footprint/
│ │ │ ├── footprint.js
│ │ │ ├── footprint.json
│ │ │ ├── footprint.wxml
│ │ │ └── footprint.wxss
│ │ ├── index/
│ │ │ ├── index.js
│ │ │ ├── index.json
│ │ │ ├── index.wxml
│ │ │ └── index.wxss
│ │ ├── order/
│ │ │ ├── order.js
│ │ │ ├── order.json
│ │ │ ├── order.wxml
│ │ │ └── order.wxss
│ │ └── orderDetail/
│ │ ├── orderDetail.js
│ │ ├── orderDetail.json
│ │ ├── orderDetail.wxml
│ │ └── orderDetail.wxss
│ ├── project.config.json
│ ├── project.private.config.json
│ ├── sitemap.json
│ └── utils/
│ ├── area.js
│ ├── check.js
│ ├── user.js
│ └── util.js
├── litemall-wx-api/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── org/
│ │ │ └── linlinjava/
│ │ │ └── litemall/
│ │ │ └── wx/
│ │ │ ├── Application.java
│ │ │ ├── annotation/
│ │ │ │ ├── LoginUser.java
│ │ │ │ └── support/
│ │ │ │ └── LoginUserHandlerMethodArgumentResolver.java
│ │ │ ├── config/
│ │ │ │ ├── WxSwagger2Configuration.java
│ │ │ │ └── WxWebMvcConfiguration.java
│ │ │ ├── dto/
│ │ │ │ ├── CaptchaItem.java
│ │ │ │ ├── UserInfo.java
│ │ │ │ ├── UserToken.java
│ │ │ │ └── WxLoginInfo.java
│ │ │ ├── service/
│ │ │ │ ├── CaptchaCodeManager.java
│ │ │ │ ├── GetRegionService.java
│ │ │ │ ├── HomeCacheManager.java
│ │ │ │ ├── UserInfoService.java
│ │ │ │ ├── UserTokenManager.java
│ │ │ │ ├── WxGrouponRuleService.java
│ │ │ │ └── WxOrderService.java
│ │ │ ├── task/
│ │ │ │ ├── OrderUnpaidTask.java
│ │ │ │ └── TaskStartupRunner.java
│ │ │ ├── util/
│ │ │ │ ├── JwtHelper.java
│ │ │ │ └── WxResponseCode.java
│ │ │ ├── vo/
│ │ │ │ ├── CouponVo.java
│ │ │ │ └── GrouponRuleVo.java
│ │ │ └── web/
│ │ │ ├── WxAddressController.java
│ │ │ ├── WxAftersaleController.java
│ │ │ ├── WxAuthController.java
│ │ │ ├── WxBrandController.java
│ │ │ ├── WxCartController.java
│ │ │ ├── WxCatalogController.java
│ │ │ ├── WxCollectController.java
│ │ │ ├── WxCommentController.java
│ │ │ ├── WxCouponController.java
│ │ │ ├── WxFeedbackController.java
│ │ │ ├── WxFootprintController.java
│ │ │ ├── WxGoodsController.java
│ │ │ ├── WxGrouponController.java
│ │ │ ├── WxHomeController.java
│ │ │ ├── WxIndexController.java
│ │ │ ├── WxIssueController.java
│ │ │ ├── WxMsgController.java
│ │ │ ├── WxOrderController.java
│ │ │ ├── WxSearchController.java
│ │ │ ├── WxStorageController.java
│ │ │ ├── WxTopicController.java
│ │ │ └── WxUserController.java
│ │ └── resources/
│ │ ├── application-wx.yml
│ │ └── application.yml
│ └── test/
│ └── java/
│ └── org/
│ └── linlinjava/
│ └── litemall/
│ └── wx/
│ ├── BigDecimalTest.java
│ └── WxConfigTest.java
├── pom.xml
└── renard-wx/
├── app.js
├── app.json
├── app.wxss
├── components/
│ ├── capsule/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── good/
│ │ ├── good.js
│ │ ├── good.json
│ │ ├── good.wxml
│ │ └── good.wxss
│ ├── goodList/
│ │ ├── goodList.js
│ │ ├── goodList.json
│ │ ├── goodList.wxml
│ │ └── goodList.wxss
│ ├── icon/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── notice-bar/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── notify/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ └── sharePop/
│ ├── sharePop.js
│ ├── sharePop.json
│ ├── sharePop.wxml
│ └── sharePop.wxss
├── config/
│ └── api.js
├── lib/
│ └── wxParse/
│ ├── html2json.js
│ ├── htmlparser.js
│ ├── showdown.js
│ ├── wxDiscode.js
│ ├── wxParse.js
│ ├── wxParse.wxml
│ └── wxParse.wxss
├── pages/
│ ├── auth/
│ │ └── login/
│ │ ├── login.js
│ │ ├── login.json
│ │ ├── login.wxml
│ │ └── login.wxss
│ ├── brand/
│ │ ├── brand.js
│ │ ├── brand.json
│ │ ├── brand.wxml
│ │ └── brand.wxss
│ ├── brandDetail/
│ │ ├── brandDetail.js
│ │ ├── brandDetail.json
│ │ ├── brandDetail.wxml
│ │ └── brandDetail.wxss
│ ├── cart/
│ │ ├── cart.js
│ │ ├── cart.json
│ │ ├── cart.wxml
│ │ └── cart.wxss
│ ├── catalog/
│ │ ├── catalog.js
│ │ ├── catalog.json
│ │ ├── catalog.wxml
│ │ └── catalog.wxss
│ ├── category/
│ │ ├── category.js
│ │ ├── category.json
│ │ ├── category.wxml
│ │ └── category.wxss
│ ├── commentPost/
│ │ ├── commentPost.js
│ │ ├── commentPost.json
│ │ ├── commentPost.wxml
│ │ └── commentPost.wxss
│ ├── goods/
│ │ ├── goods.js
│ │ ├── goods.json
│ │ ├── goods.wxml
│ │ └── goods.wxss
│ ├── groupon/
│ │ ├── grouponDetail/
│ │ │ ├── grouponDetail.js
│ │ │ ├── grouponDetail.json
│ │ │ ├── grouponDetail.wxml
│ │ │ └── grouponDetail.wxss
│ │ ├── grouponList/
│ │ │ ├── grouponList.js
│ │ │ ├── grouponList.json
│ │ │ ├── grouponList.wxml
│ │ │ └── grouponList.wxss
│ │ └── myGroupon/
│ │ ├── myGroupon.js
│ │ ├── myGroupon.json
│ │ ├── myGroupon.wxml
│ │ └── myGroupon.wxss
│ ├── hotGoods/
│ │ ├── hotGoods.js
│ │ ├── hotGoods.json
│ │ ├── hotGoods.wxml
│ │ └── hotGoods.wxss
│ ├── index/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── newGoods/
│ │ ├── newGoods.js
│ │ ├── newGoods.json
│ │ ├── newGoods.wxml
│ │ └── newGoods.wxss
│ ├── payResult/
│ │ ├── payResult.js
│ │ ├── payResult.json
│ │ ├── payResult.wxml
│ │ └── payResult.wxss
│ ├── search/
│ │ ├── search.js
│ │ ├── search.json
│ │ ├── search.wxml
│ │ └── search.wxss
│ ├── shopping/
│ │ └── checkout/
│ │ ├── checkout.js
│ │ ├── checkout.json
│ │ ├── checkout.wxml
│ │ └── checkout.wxss
│ ├── topic/
│ │ ├── topic.js
│ │ ├── topic.json
│ │ ├── topic.wxml
│ │ └── topic.wxss
│ ├── topicDetail/
│ │ ├── topicDetail.js
│ │ ├── topicDetail.json
│ │ ├── topicDetail.wxml
│ │ └── topicDetail.wxss
│ └── ucenter/
│ ├── address/
│ │ ├── address.js
│ │ ├── address.json
│ │ ├── address.wxml
│ │ └── address.wxss
│ ├── addressAdd/
│ │ ├── addressAdd.js
│ │ ├── addressAdd.json
│ │ ├── addressAdd.wxml
│ │ └── addressAdd.wxss
│ ├── coupon/
│ │ ├── coupon.js
│ │ ├── coupon.json
│ │ ├── coupon.wxml
│ │ └── coupon.wxss
│ ├── index/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── order/
│ │ ├── order.js
│ │ ├── order.json
│ │ ├── order.wxml
│ │ └── order.wxss
│ └── orderDetail/
│ ├── orderDetail.js
│ ├── orderDetail.json
│ ├── orderDetail.wxml
│ └── orderDetail.wxss
├── project.config.json
├── sitemap.json
└── utils/
├── area.js
├── check.js
├── user.js
└── util.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitbook.yaml
================================================
structure:
summary: doc/README.md
================================================
FILE: .github/workflows/main.yml
================================================
name: Actions
on: [push, pull_request]
jobs:
# Building and testing Java with Maven
# https://docs.github.com/en/actions/guides/building-and-testing-java-with-maven
Litemall-all:
runs-on: ubuntu-latest
strategy:
matrix:
java-version:
- 8
- 8.0.192
- 11
- 11.0.3
steps:
- uses: actions/checkout@v2
- name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v2
with:
java-version: ${{ matrix.java-version }}
distribution: zulu
- name: Cache Maven packages
uses: actions/cache@v2
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
- name: Build with Maven
run: mvn --batch-mode --update-snapshots verify
# Building and testing Node.js
# https://docs.github.com/en/actions/guides/building-and-testing-nodejs
Litemall-admin:
runs-on: ubuntu-latest
strategy:
matrix:
node-version:
- 10.x
- 12.x
- 14.x
# - 15.x
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm --prefix litemall-admin install
- run: npm --prefix litemall-admin run test
Litemall-vue:
runs-on: ubuntu-latest
strategy:
matrix:
node-version:
- 10.x
- 12.x
- 14.x
# - 15.x
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm --prefix litemall-vue install
- run: npm --prefix litemall-vue run test
================================================
FILE: .gitignore
================================================
### gradle ###
.gradle
/build/
!gradle/wrapper/gradle-wrapper.jar
### STS ###
.settings/
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
### IntelliJ IDEA ###
/.idea/
/private/
/storage/
/litemall.iml
.checkstyle
.idea
*.iws
*.iml
*.ipr
rebel.xml
### maven ###
target/
*.war
*.ear
*.zip
*.tar
*.tar.gz
### logs ####
/logs/
*.log
### temp ignore ###
*.cache
*.diff
*.patch
*.tmp
*.java~
*.properties~
*.xml~
### system ignore ###
.DS_Store
Thumbs.db
Servers
.metadata
upload
gen_code
================================================
FILE: .workflow/BranchPipeline.yml
================================================
version: '1.0'
name: branch-pipeline
displayName: BranchPipeline
stages:
- stage:
name: compile
displayName: 编译
steps:
- step: build@maven
name: build_maven
displayName: Maven 构建
# 支持6、7、8、9、10、11六个版本
jdkVersion: 8
# 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本
mavenVersion: 3.3.9
# 构建命令
commands:
- mvn -B clean package -Dmaven.test.skip=true
# 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除
artifacts:
# 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
- name: BUILD_ARTIFACT
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录
path:
- ./target
- step: publish@general_artifacts
name: publish_general_artifacts
displayName: 上传制品
# 上游构建任务定义的产物名,默认BUILD_ARTIFACT
dependArtifact: BUILD_ARTIFACT
# 上传到制品库时的制品命名,默认output
artifactName: output
dependsOn: build_maven
- stage:
name: release
displayName: 发布
steps:
- step: publish@release_artifacts
name: publish_release_artifacts
displayName: '发布'
# 上游上传制品任务的产出
dependArtifact: output
# 发布制品版本号
version: '1.0.0.0'
# 是否开启版本号自增,默认开启
autoIncrement: true
triggers:
push:
branches:
exclude:
- master
include:
- .*
================================================
FILE: .workflow/MasterPipeline.yml
================================================
version: '1.0'
name: master-pipeline
displayName: MasterPipeline
stages:
- stage:
name: compile
displayName: 编译
steps:
- step: build@maven
name: build_maven
displayName: Maven 构建
# 支持6、7、8、9、10、11六个版本
jdkVersion: 8
# 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本
mavenVersion: 3.3.9
# 构建命令
commands:
- mvn -B clean package -Dmaven.test.skip=true
# 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除
artifacts:
# 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
- name: BUILD_ARTIFACT
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录
path:
- ./target
- step: publish@general_artifacts
name: publish_general_artifacts
displayName: 上传制品
# 上游构建任务定义的产物名,默认BUILD_ARTIFACT
dependArtifact: BUILD_ARTIFACT
# 上传到制品库时的制品命名,默认output
artifactName: output
dependsOn: build_maven
- stage:
name: release
displayName: 发布
steps:
- step: publish@release_artifacts
name: publish_release_artifacts
displayName: '发布'
# 上游上传制品任务的产出
dependArtifact: output
# 发布制品版本号
version: '1.0.0.0'
# 是否开启版本号自增,默认开启
autoIncrement: true
triggers:
push:
branches:
include:
- master
================================================
FILE: .workflow/PRPipeline.yml
================================================
version: '1.0'
name: pr-pipeline
displayName: PRPipeline
stages:
- stage:
name: compile
displayName: 编译
steps:
- step: build@maven
name: build_maven
displayName: Maven 构建
# 支持6、7、8、9、10、11六个版本
jdkVersion: 8
# 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本
mavenVersion: 3.3.9
# 构建命令
commands:
- mvn -B clean package -Dmaven.test.skip=true
# 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除
artifacts:
# 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
- name: BUILD_ARTIFACT
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录
path:
- ./target
- step: publish@general_artifacts
name: publish_general_artifacts
displayName: 上传制品
# 上游构建任务定义的产物名,默认BUILD_ARTIFACT
dependArtifact: BUILD_ARTIFACT
# 构建产物制品库,默认default,系统默认创建
artifactRepository: default
# 上传到制品库时的制品命名,默认output
artifactName: output
dependsOn: build_maven
triggers:
pr:
branches:
include:
- master
================================================
FILE: CHANGELOG.md
================================================
# 更新日志
## V 1.8.0
*2021-01-10* 一些完善。。。
## V 1.7.0
*2020-02-15* 支持docker部署、售后管理、通知管理、数据库七天备份。
#### Bug 修复
* `小商城`后端接口部分存在水平越权漏洞
* `小商城`验证码未超时仍会发送验证码
* `小商城`显示管理员评论回复(#340 by sunyinggang)
* `管理后台`管理员评论回复(#340 by sunyinggang)
* `轻商城`添加收货地址返回不正确(#320 by kevinleeex)
#### 优化
* `管理后台`专题支持排序、批量删除
* `基础系统`数据库四个表索引(#328 #330 #332 #334 by wtune)
#### 新特性
* `基础系统`支持docker部署(参考实现 #321 by yuana1)
* `基础系统`自动备份7天数据到backup文件夹
* `管理后台`通知中心和通知管理
* `管理后台`登录页面增加版权内容
* `管理后台`售后管理
* `小商城`订单售后列表、售后详情、申请售后
* `轻商城`实现账号注册功能(#324 by yelongbao)
## V 1.6.1
*2020-01-01*
#### Bug 修复
* `基础系统`删除不必要的Bean注解,导致不必要的实例化。
## V 1.6.0
*2019-12-31*,优化团购实现,删除微信模板实现。
#### Bug 修复
* `管理后台`修复查看商品详情时, 图片溢出(#305 by zaoangod)
#### 优化
* `小商城`重构团购实现
* `小商城`删除微信模板实现
* `管理后台`优化查询区域速度(# by)
* `管理后台`更新vue-element-admin框架版本4.2.1
#### 新特性
* `小商城`尽可能替换vant图标
* `小商城`首页banner添加产品跳转(#299 by staneychan)
* `小商城`发送邮件通知使用ssl方式(#307 by jessonxiang)
## V 1.5.0
*2019-11-15*, 持续优化轻商城模块,以及推荐项目Flutter_Mall
#### Bug 修复
* `小商城`优惠券绑定绑定优惠券ID(#157 by @beaver383)
* `小商城`评论列表不能正确显示
* `轻商城`修正取消订单接口 (#256 by @1037621594)
#### 优化
* `小商城`采用延迟队列实现支付超时取消订单功能(参考#275 by @alexzhu0592)
* `小商城`分享按钮可选配置 (#239 by @galenzhao)
#### 新特性
* `基础系统`支持阿里云短信
* `轻商城`接入微信支付H5支付 (#291 by @beaver383)
* `小商城`团购拼团超期取消 (#284 by @beaver383)
* `管理后台`订单详情新增打印 (#274 by @fanchenggang )
* README文档推荐项目Flutter_Mall
## V 1.4.0
*2019-05-16*,支持移动端轻商城
#### Bug 修复
* `小商场`购物车和订单的商品数量必须正整数
* `小商城`微信支付回调校验失败通知信息
* `小商城`收货地址采用userId和id联合查询
* `管理后台`管理员不能删除自己账号
#### 优化
* `文档`支持API文档
* `基础系统`更新第三方插件mybatis-generator-plugin到1.3.2
* `管理后台`不允许管理员通过编辑接口修改管理员密码
#### 新特性
* `小商城`帮助中心页面
* `小商城`后端登录验证方式采用JWT (#167 by @Bigger-Ma)
* `轻商场`基本结构完成 (#157 by @pkwenda)
* `管理后台`支持操作日志管理
## V 1.3.0
*2019-03-11*,支持配置管理
* `管理后台`商品类目页面和行政区域页面采用树形结构显示;
* `管理后台`取消国际化和主题;
* `管理后台`支持配置管理;
注意:虽然配置管理中可以设置订单超时时间,但是由于目前采用定时查询方式会产生延时,
因此最终订单超时时间需要额外加上这些延迟才能更新状态。以后会解决这个问题(例如使用redis)。
## V 1.2.0
*2019-03-03*,支持权限管理
* `管理后台`支持权限管理;
* `小商城`取消编程式事务管理,采用注解式事务管理;
* `小商城`采用多线程进行数据库查询操作;
## V 1.1.0
*2018-12-23*,支持优惠券
* `管理后台`支持优惠券管理;
* `管理后台`调整定时任务到job子包,方便以后进一步迁移至独立模块;
* `小商城`支持优惠券列表展示和个人优惠券功能;
* `基础系统`快递鸟即时API调整
## V 1.0.0
*2018-12-03*,文档完善
## V 1.0.0.rc1
*2018-11-30*,接入微信退款API
* `管理后台`接入微信退款API;
* `管理后台`错误码取消magic number;
* `管理后台`禁止超级管理员修改密码;
## V 1.0.0.rc0
*2018-11-23*,清理代码,更新管理后台前端框架
* `管理后台`基于vue-element-admin更新至3.9.3;
* `管理后台`商品货品库存增加减少采用自定义Mapper;
* `管理后台`支持商品回复;
* `小商城`支持商品回复;
## V 0.10.2
*2018-11-08*,修复一些小错误
* `管理后台`富文本编辑调整,修复小程序端文本对齐不正确问题;
* `小商城`支持团购专区列表页面
* `小商城`关闭默认内置缓存功能
## V 0.10.1
*2018-11-07*,修复一些小错误
## V 0.10.0
*2018-10-26*,修复很多小错误
* `管理后台`校验POST参数
* `管理后台`乐观锁取消,仅用于订单表
## V 0.9.0
*2018-09-14*,支持团购,第二套小商城renard-wx
* `小商场`支持团购
* `小商场`开源第二套小商城renard-wx
* `小商场`支持意见反馈组件
* `管理后台`采用乐观锁更新
* `管理后台`升级Spring Boot到2.x
## V 0.8.0
*2018-07-30*,删除os模块,小程序完善
* `小商场`支持商品分享
* `小商场`物流显示
* `小商场`优化商品购买样式,感谢[usgeek](https://github.com/linlinjava/litemall/pull/31)
* `小商场`支持客服、关于页面、手机绑定,感谢[usgeek](https://github.com/linlinjava/litemall/pull/31)
* `小商场`支持账号注册和密码找回时短信验证码
* `管理后台`页面查询时默认基于创建时间排序
* `基础系统`支持物流追踪
* `基础系统`支持阿里云存储,感谢[usgeek](https://github.com/linlinjava/litemall/pull/31)
* `项目`删除os模块,相关功能迁移至wx-api模块和admin-api模块
* `项目`从默认单机多服务方案调整至默认单机单服务方案
* `项目`暂时取消docker支持和.gitlab-ci.yml支持
* `项目`数据库添加litemall_system表,存储系统配置信息
* `项目`取消swagger支持
## V 0.7.0
*2018-07-16*,数据库再次简化,同时支持短信提醒、邮件提醒、腾讯对象存储服务
* `管理后台`页面查询时默认基于创建时间排序
* `管理后台`多个页面完善页面效果
* `管理后台`支持商品上架和商品编辑
* `基础系统`支持腾讯云短信提醒和邮件提醒,感谢[Menethil](https://github.com/linlinjava/litemall/pull/23)
* `基础系统`支持腾讯对象存储,感谢[Menethil](https://github.com/linlinjava/litemall/pull/24)
* `项目`数据库再次简化,同时小商城和管理后台代码进行相应调整
## V 0.6.0
*2018-06-30*,项目支持商品上架和统计功能
* `小商场`因wx.getUserInfo接口调整,微信登录调整
* `小商场`支持手机号码验证
* `管理后台`支持简单的统计
* `管理后台`支持商品上架
* `管理后台`基于官方tinymce-vue实现富文本编辑
* `项目`支持docker部署
## V 0.5.0
*2018-05-11*,项目支持微信支付和修复小程序的一些BUG
* `小商场`因wx.getUserInfo接口调整,微信登录调整
* `小商场`修复立即购买会下单购物车所有商品
* `小商场`修复下单商品时添加收货地址成功但是没有显示
* `小商场`修复下单商品时添加收货地址的地址信息不能滚动
* `小商场`修复购物车商品不能删除
* `小商场`支持微信支付
* `管理后台`支持微信支付
* `基础系统`数据库litemall_collect的id设置自增
* `基础系统`数据库删除region相关的四个临时表
* `基础系统`litemall-core模块swagger2配置,支持swagger文档
* `项目`多模块maven结构重新设计
* `项目`文档整理部署方案和上线方案
* `项目`文档支持更新日志、贡献指南和常见问题
## V 0.4.0
*2018-04-21*,项目结构调整,增加了两个模块
* `小商场`的后端服务代码添加注释,校验输入参数
* `小商场`商品无货时显示“商品已售空”
* `管理后台`支持管理员同一账户多终端登录,方便演示
* `管理后台`专题内容支持富文本编辑
* `基础系统`litemall-os-api的链接从`storage/index/index`调整至`os/index/index`
* `基础系统`litemall-os-api支持浏览器显示。
* `基础系统`新增litemall-core模块,综合了litemall-os-api、litemall-wx-api
和litemall-admin-api的共性代码
* `基础系统`新增litemall-all模块作为包裹模块,支持三个后端服务和静态文件
打包成一个war项目包
## V 0.3.0
*2018-04-07*,业务模块从物理删除调整成逻辑删除
* `小商场`的后端服务加密用户账号密码
* `小商场`如果用户选择货品,则显示货品对应的价格;否则显示商品价格
* `小商场`只有规格都选择,则商品页面才显示所对应货品的规格文本
* `管理后台`商品详细信息支持tinymce富文本编辑
* `管理后台`的后端服务加密管理员密码
* `管理后台`完善登录退出逻辑
* `基础系统`数据库中除regions几个表,其他所有表都添加`add_time`和`deleted`字段
* `基础系统`litemall-db模块不支持数据物理删除,删除则设置`deleted`,而查询则过滤`deleted`
## V 0.2.0
*2018-04-02*,修复一些小商场出现的问题。
* `小商场`微信登录
* `小商场`账号登录、注册、找回密码
(注意手机验证码不支持,因此目前只是完成基本功能,但是存在安全风险)
* `小商场`订单编号采用日期+6位随机数
* `小商场`简单运费计算
* `小商场`专题评价
* `管理后台`禁止管理员修改超级管理员信息
* `基础系统`自动脚本util/lazy.sh和util/upload.sh
## V 0.1.0
*2018-03-24*, 项目架构基本完成。
================================================
FILE: CONTRIBUTE.md
================================================
# 贡献指南
任何形式的贡献都欢迎,包括:
* Issue里面报告的BUG
* Issue里面对业务或技术的讨论
* Pull Request
* 对文档的意见或补充
* 其他任何有意义本项目的行为
个人能力有限,欢迎一起开发。
目前项目基本框架已经建立,但是还不完整,因此非常欢迎人一起讨论技术和业务。
但是交流合作之前,请查看以下碎碎念。
## 项目理念
litemall的设计受众是小微型企业,而不是互联网企业,因此litemall的开发理念是一个小而美:
* 小,指的是技术简单、架构简单、性能指标低、业务仅覆盖基本功能
* 美,指的是技术新、架构清晰易扩展、安全系数不低、业务可直接部署使用
正是因为以上考虑,目前litemall的架构是简单的,三种技术栈都是最基本的。
虽然这么说,但是实际上开发的入门门槛不低:
* 项目采用了三种技术栈,相互之间是相对独立的;
* 采用的spring boot框架和vue-element-admin框架已经依赖相当多的库;
* 除了开发技术,开发过程中也会涉及其他技术,包括环境配置、版本控制、
测试技术、日志、部署等等。
因此贡献新的代码或讨论业务前,建议考虑以下问题:
* 是否引入过多的复杂性,而没有带来相应的收益?
因为本项目希望能够为更多的人所学习使用,项目的复杂性是需要考虑的问题。
如果是复杂性和收益是相同的,那么接收贡献的可能性其实值得讨论。
* 是否依赖过多的库?是否必须依赖该库?如果仅仅是该库的微小部分,是否可以自己实现一个简单的util类?
例如,一些技术框架采用了fastjson,而实际上spring boot已经默认采用jackson,因此如果没有特殊原因,
贡献者应该尽可能采用jackson。
* 是否盲目地采用过多过先进的技术?是否可以暂缓采用?
这里是谨慎的。例如,如果要引入缓存技术,则需要去学习缓存相关的类库,以及可能会遇到一些使用中存在的问题。
而v2.0.0之前其实没有必要提前考虑性能问题。同样地,单点登录技术是分布式架构中必须存在的基本功能,但是
目前两个后端服务分别采用各自登录方案即可。
注意:
> 这里并不是拒绝新技术,而是希望采取一个渐进式的谨慎的态度。
> 此外,对于新技术运用,其实规划是基于本项目稳定版本再开发一个独立的分布式版本。
* 已经有了一个技术,是否有必要贡献相同目的的另外一种技术?
这里是欢迎的。例如,已经有了vue框架的管理后台,但是采用其他前端框架的管理后台也是欢迎的。
这样可以给不同技术背景的用户所选择。当然,应该尽量保持不同版本之间的同步。又或者,小程序
已经有了一些开发框架,而目前小商场的小程序端仍然是原始的小程序技术,因此基于这些新的开发框架
来重构小程序端是欢迎的。
也就是说本项目希望避免技术深度,而倾向于技术宽度,帮助自己以及更多的人学习了解不同的技术。
* 贡献代码量不大,或者改善文档。
这里是欢迎的。很多开源项目都建议贡献代码时应该少量并且逻辑分明。这样审阅代码时才能明确。
当然,如果是单词拼写不对之类,那么应该尽可能在一次commit中修复同样的问题。
虽然这里可能表现出对新技术的谨慎态度,但是如果用户发现有更好的技术或者有必要,欢迎讨论。
当然,如果开发者不认同这里的一些理念,也可以基于自己的技术选型来开发自己的版本。
如果认为自己开发的好,可以在本项目提交链接地址,让其他开发者了解。
## 项目业务
本项目所设想的基本业务功能已经在文档中列举完成。
如果希望引入高级功能,例如分销功能等,建议用户在本项目基础上自行开发。
如果认为有基本业务没有实现,可以Issue或者QQ群讨论,加入后续开发计划。
当然更希望开发者直接提供代码,丰富完善目前的基础业务功能。
## 代码贡献
* 代码规范目前没有严格要求,后续会补充。
## Issue规范
* 在提交issue之前,请搜索是否存在相关问题。
* 提交的Issue请尽可能给出详细信息
* 建议Issue基于最新的代码
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018 linlinjava(linlinjava@163.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# litemall
又一个小商场系统。
litemall = Spring Boot后端 + Vue管理员前端 + 微信小程序用户前端 + Vue用户移动端
* [文档](https://linlinjava.gitbook.io/litemall)
* [贡献](https://linlinjava.gitbook.io/litemall/contribute)
* [FAQ](https://linlinjava.gitbook.io/litemall/faq)
* [API](https://linlinjava.gitbook.io/litemall/api)
## 项目代码
* [码云](https://gitee.com/linlinjava/litemall)
* [GitHub](https://github.com/linlinjava/litemall)
## 项目架构

## 技术栈
> 1. Spring Boot
> 2. Vue
> 3. 微信小程序

## 功能
### 小商城功能
* 首页
* 专题列表、专题详情
* 分类列表、分类详情
* 品牌列表、品牌详情
* 新品首发、人气推荐
* 优惠券列表、优惠券选择
* 团购
* 搜索
* 商品详情、商品评价、商品分享
* 购物车
* 下单
* 订单列表、订单详情、订单售后
* 地址、收藏、足迹、意见反馈
* 客服
### 管理平台功能
* 会员管理
* 商城管理
* 商品管理
* 推广管理
* 系统管理
* 配置管理
* 统计报表
## 快速启动
1. 配置最小开发环境:
* [MySQL](https://dev.mysql.com/downloads/mysql/)
* [JDK1.8或以上](http://www.oracle.com/technetwork/java/javase/overview/index.html)
* [Maven](https://maven.apache.org/download.cgi)
* [Nodejs](https://nodejs.org/en/download/)
* [微信开发者工具](https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html)
2. 数据库依次导入litemall-db/sql下的数据库文件
* litemall_schema.sql
* litemall_table.sql
* litemall_data.sql
3. 启动小商场和管理后台的后端服务
打开命令行,输入以下命令
```bash
cd litemall
mvn install
mvn clean package
java -Dfile.encoding=UTF-8 -jar litemall-all/target/litemall-all-0.1.0-exec.jar
```
4. 启动管理后台前端
打开命令行,输入以下命令
```bash
cd litemall/litemall-admin
npm install --registry=https://registry.npm.taobao.org
npm run dev
```
此时,浏览器打开,输入网址`http://localhost:9527`, 此时进入管理后台登录页面。
5. 启动小商城前端
这里存在两套小商场前端litemall-wx和renard-wx,开发者可以分别导入和测试:
1. 微信开发工具导入litemall-wx项目;
2. 项目配置,启用“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”
3. 点击“编译”,即可在微信开发工具预览效果;
4. 也可以点击“预览”,然后手机扫描登录(但是手机需开启调试功能)。
注意:
> 这里只是最简启动方式,而小商场的微信登录、微信支付等功能需开发者设置才能运行,
> 更详细方案请参考[文档](https://linlinjava.gitbook.io/litemall/project)。
6. 启动轻商城前端
打开命令行,输入以下命令
```bash
cd litemall/litemall-vue
npm install --registry=https://registry.npm.taobao.org
npm run dev
```
此时,浏览器(建议采用chrome 手机模式)打开,输入网址`http://localhost:6255`, 此时进入轻商场。
注意:
> 现在功能很不稳定,处在开发阶段。
## 警告
> 1. 本项目仅用于学习练习
> 2. 本项目还不完善,仍处在开发中,不承担任何使用后果
> 3. 本项目代码开源[MIT](./LICENSE),项目文档采用 [署名-禁止演绎 4.0 国际协议许可](https://creativecommons.org/licenses/by-nd/4.0/deed.zh)
## 致谢
本项目基于或参考以下项目:
1. [nideshop-mini-program](https://github.com/tumobi/nideshop-mini-program)
项目介绍:基于Node.js+MySQL开发的开源微信小程序商城(微信小程序)
项目参考:
1. litemall项目数据库基于nideshop-mini-program项目数据库;
2. litemall项目的litemall-wx模块基于nideshop-mini-program开发。
2. [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
项目介绍: 一个基于Vue和Element的后台集成方案
项目参考:litemall项目的litemall-admin模块的前端框架基于vue-element-admin项目修改扩展。
3. [mall-admin-web](https://github.com/macrozheng/mall-admin-web)
项目介绍:mall-admin-web是一个电商后台管理系统的前端项目,基于Vue+Element实现。
项目参考:litemall项目的litemall-admin模块的一些页面布局样式参考了mall-admin-web项目。
4. [biu](https://github.com/CaiBaoHong/biu)
项目介绍:管理后台项目开发脚手架,基于vue-element-admin和springboot搭建,前后端分离方式开发和部署。
项目参考:litemall项目的权限管理功能参考了biu项目。
5. [vant--mobile-mall](https://github.com/qianzhaoy/vant--mobile-mall)
项目介绍:基于有赞 vant 组件库的移动商城。
项目参考:litemall项目的litemall-vue模块基于vant--mobile-mall项目开发。
## 推荐
1. [Flutter_Mall](https://github.com/youxinLu/mall)
项目介绍:Flutter_Mall是一款Flutter开源在线商城应用程序。
2. [Taro_Mall](https://github.com/jiechud/taro-mall)
项目介绍:Taro_Mall是一款多端开源在线商城应用程序,后台是基于litemall基础上进行开发,前端采用Taro框架编写。
## License
[MIT](https://github.com/linlinjava/litemall/blob/master/LICENSE)
Copyright (c) 2018-present linlinjava
================================================
FILE: SECURITY.md
================================================
# Security Policy
## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
| 1.8.x | :white_check_mark: |
| < 1.8 | :x: |
## Reporting a Vulnerability
Please report security issues to linlinjavaer@gmail.com
================================================
FILE: deploy/.gitignore
================================================
/db/litemall.sql
/litemall/litemall.jar
================================================
FILE: deploy/README.md
================================================
## deploy
### 项目打包
1. 在服务器或者开发机打包项目到deploy;
```
cd litemall
cat ./litemall-db/sql/litemall_schema.sql > ./deploy/db/litemall.sql
cat ./litemall-db/sql/litemall_table.sql >> ./deploy/db/litemall.sql
cat ./litemall-db/sql/litemall_data.sql >> ./deploy/db/litemall.sql
cd ./litemall-admin
npm install --registry=https://registry.npm.taobao.org
npm run build:dep
cd ..
mvn clean package
cp -f ./litemall-all/target/litemall-all-*-exec.jar ./deploy/litemall/litemall.jar
```
这里的工作是:
1. 把数据库文件拷贝到deploy/db文件夹
2. 编译litemall-admin项目
3. 编译litemall-all模块,同时把litemall-admin编译得到的静态文件拷贝到
litemall-all模块的static目录
2. 修改litemall文件夹下面的*.yml外部配置文件,当litemall-all模块启动时会
加载外部配置文件,而覆盖默认jar包内部的配置文件。
例如,配置文件中一些地方需要设置成远程服务器的IP地址
此时deploy部署包结构如下:
* bin
存放远程服务器运行的脚本,包括deploy.sh脚本和reset.sh脚本
* db
存放litemall数据库文件
* litemall
存放远程服务器运行的代码,包括litemall-all二进制可执行包和litemall外部配置文件
* util
存放开发服务器运行的脚本,包括package.sh脚本和lazy.sh脚本。
由于是本地开发服务器运行,因此开发者可以不用上传到远程服务器。
### 项目部署
1. 远程服务器环境(MySQL和JDK1.8)已经安装好,请确保云服务器的安全组已经允许相应的端口。
2. 导入db/litemall.sql
```bash
cd /home/ubuntu/deploy/db
mysql -h localhost -u $ROOT -p$PASSWORD < litemall.sql
```
3. 启动服务
```bash
sudo service litemall stop
sudo ln -f -s /home/ubuntu/deploy/litemall/litemall.jar /etc/init.d/litemall
sudo service litemall start
```
4. 测试是否部署成功(xxx.xxx.xxx.xxx是云服务器IP):
```
http://xxx.xxx.xxx.xxx:8080/wx/index/index
http://xxx.xxx.xxx.xxx:8080/admin/index/index
http://xxx.xxx.xxx.xxx:8080/#/login
```
### 项目辅助脚本
在前面的项目打包和项目部署中都是采用手动命令来部署。
这里可以写一些脚本简化:
* util/packet.sh
在开发服务器运行可以自动项目打包
* util/lazy.sh
在开发服务器运行可以自动项目打包、项目上传远程服务器、自动登录系统执行项目部署脚本。
注意:
> 1. 开发者需要在util/lazy.sh中设置相应的远程服务器登录账号和密钥文件路径。
> 2. 开发者需要在bin/reset.sh设置远程服务器的MySQL的root登录账户。
* bin/deploy.sh
在远程服务器运行可以自动部署服务
* bin/reset.sh
在远程服务器运行可以自动项目导入数据、删除本地上传图片、再执行bin/deploy.sh部署服务。
注意:
> 开发者需要在bin/reset.sh设置远程服务器的MySQL的root登录账户。
总结,当开发者设置好配置信息以后,可以在本地运行lazy.sh脚本自动一键部署:
```bash
cd litemall
./deploy/util/lazy.sh
```
不过由于需要设置的信息会包含敏感安全信息,强烈建议开发者参考这里的deploy文件夹,
然后实现自己的deploy文件夹,妥善处置外部配置文件和脚本中的敏感安全信息!!!
================================================
FILE: deploy/bin/deploy.sh
================================================
#!/bin/bash
# 本脚本的作用是停止当前Spring Boot应用,然后再次部署
PID=$(ps -ef | grep litemall.jar | grep -v grep | awk '{ print $2 }')
if [ ! -z "$PID" ]
then
kill $PID
fi
cd /home/ubuntu/deploy/litemall || exit 2
nohup java -jar litemall.jar > log.log 2>&1 &
================================================
FILE: deploy/bin/reset.sh
================================================
#!/bin/bash
# 本脚本的作用是重置部署环境
# 1.重置数据库
# 2.删除storage文件夹内文件
# 3.调用deploy.sh启动服务
# 注意:由于1和2的原因,请仅在开发测试阶段使用本脚本!
# 重置数据库
# i. 请在`XXXXXX`处设置相应的root密码
# ii. 同时请注意root密码放在脚本是非常危险的,因此这里仅仅是用于开发测试阶段。
ROOT=root
PASSWORD=
if test -z "$PASSWORD"
then
echo "请设置云服务器MySQL的root账号密码"
exit 1
fi
# 导入数据
cd /home/ubuntu/deploy/db || exit 2
mysql -h localhost -u $ROOT -p$PASSWORD < litemall.sql
# 删除storage文件夹内文件
cd /home/ubuntu/deploy/litemall/storage || exit 2
rm -f ./**
# 重新部署服务
cd /home/ubuntu/deploy/bin || exit 2
sudo ./stop.sh
sudo ./deploy.sh
================================================
FILE: deploy/bin/stop.sh
================================================
#!/bin/bash
PID=$(ps -ef | grep litemall.jar | grep -v grep | awk '{ print $2 }')
if [ ! -z "$PID" ]
then
kill $PID
fi
================================================
FILE: deploy/db/.gitkeep
================================================
================================================
FILE: deploy/litemall/application.yml
================================================
spring:
profiles:
active: none
message:
encoding: UTF-8
datasource:
druid:
url: jdbc:mysql://localhost:3306/litemall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&verifyServerCertificate=false&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: litemall
password: litemall123456
initial-size: 10
max-active: 50
min-idle: 10
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
validation-query: SELECT 1 FROM DUAL
test-on-borrow: false
test-on-return: false
test-while-idle: true
time-between-eviction-runs-millis: 60000
filters: stat,wall
server:
port: 8080
logging:
config: classpath:logback-spring.xml
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
litemall:
# 开发者应该设置成自己的wx相关信息
wx:
app-id: wxa5b486c6b918ecfb
app-secret: e04004829d4c383b4db7769d88dfbca1
mch-id: 111111
mch-key: xxxxxx
notify-url: http://122.51.199.160:8080/wx/order/pay-notify
# 商户证书文件路径
# 请参考“商户证书”一节 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3
key-path: xxxxx
#通知相关配置
notify:
mail:
# 邮件通知配置,邮箱一般用于接收业务通知例如收到新的订单,sendto 定义邮件接收者,通常为商城运营人员
enable: false
host: smtp.exmail.qq.com
username: ex@ex.com.cn
password: XXXXXXXXXXXXX
sendfrom: ex@ex.com.cn
sendto: ex@qq.com
port: 465
# 短消息模版通知配置
# 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
sms:
enable: false
# 如果是腾讯云短信,则设置active的值tencent
# 如果是阿里云短信,则设置active的值aliyun
active: tencent
sign: litemall
template:
- name: paySucceed
templateId: 156349
- name: captcha
templateId: 156433
- name: ship
templateId: 158002
- name: refund
templateId: 159447
tencent:
appid: 111111111
appkey: xxxxxxxxxxxxxx
aliyun:
regionId: xxx
accessKeyId: xxx
accessKeySecret: xxx
# 快鸟物流查询配置
express:
enable: false
appId: "XXXXXXXXX"
appKey: "XXXXXXXXXXXXXXXXXXXXXXXXX"
vendors:
- code: "ZTO"
name: "中通快递"
- code: "YTO"
name: "圆通速递"
- code: "YD"
name: "韵达速递"
- code: "YZPY"
name: "邮政快递包裹"
- code: "EMS"
name: "EMS"
- code: "DBL"
name: "德邦快递"
- code: "FAST"
name: "快捷快递"
- code: "ZJS"
name: "宅急送"
- code: "TNT"
name: "TNT快递"
- code: "UPS"
name: "UPS"
- code: "DHL"
name: "DHL"
- code: "FEDEX"
name: "FEDEX联邦(国内件)"
- code: "FEDEX_GJ"
name: "FEDEX联邦(国际件)"
# 对象存储配置
storage:
# 当前工作的对象存储模式,分别是local、aliyun、tencent
active: local
# 本地对象存储配置信息
local:
storagePath: storage
address: http://122.51.199.160:8080/wx/storage/fetch/
# 阿里云对象存储配置信息
aliyun:
endpoint: oss-cn-shenzhen.aliyuncs.com
accessKeyId: 111111
accessKeySecret: xxxxxx
bucketName: xxxxxx
# 腾讯对象存储配置信息
# 请参考 https://cloud.tencent.com/document/product/436/6249
tencent:
secretId: 111111
secretKey: xxxxxx
region: xxxxxx
bucketName: xxxxxx
# 七牛云对象存储配置信息
qiniu:
endpoint: http://pd5cb6ulu.bkt.clouddn.com
accessKey: 111111
secretKey: xxxxxx
bucketName: litemall
swagger:
production: true
================================================
FILE: deploy/util/lazy.sh
================================================
#!/bin/bash
# 本脚本的作用是
# 1. 项目打包
# 2. 上传云服务器
# 3. 远程登录云服务器并执行reset脚本
# 请设置云服务器的IP地址和账户
# 例如 ubuntu@122.51.199.160
REMOTE=
# 请设置本地SSH私钥文件id_rsa路径
# 例如 /home/litemall/id_rsa
ID_RSA=
if test -z "$REMOTE"
then
echo "请设置云服务器登录IP地址和账户"
exit 1
fi
if test -z "$ID_RSA"
then
echo "请设置云服务器登录IP地址和账户"
exit 1
fi
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
cd $DIR/../.. || exit 2
LITEMALL_HOME=$PWD
echo "LITEMALL_HOME $LITEMALL_HOME"
# 项目打包
cd $LITEMALL_HOME || exit 2
./deploy/util/package.sh
# 上传云服务器
cd $LITEMALL_HOME || exit 2
scp -i $ID_RSA -r ./deploy $REMOTE:/home/ubuntu/
# 远程登录云服务器并执行reset脚本
# 这里使用tr命令,因为有可能deploy.sh和reset.sh的换行格式是CRLF,而LINUX环境应该是LF
ssh $REMOTE -i $ID_RSA << eeooff
cd /home/ubuntu/deploy/bin
cat deploy.sh | tr -d '\r' > deploy2.sh
mv deploy2.sh deploy.sh
chmod +x deploy.sh
cat reset.sh | tr -d '\r' > reset2.sh
mv reset2.sh reset.sh
chmod +x reset.sh
sudo ./reset.sh
exit
eeooff
================================================
FILE: deploy/util/package.sh
================================================
#!/bin/bash
# 请注意
# 本脚本的作用是把本项目编译的结果保存到deploy文件夹中
# 1. 把项目数据库文件拷贝到deploy/db
# 2. 编译litemall-admin
# 3. 编译litemall-all模块,然后拷贝到deploy/litemall
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
cd $DIR/../..
LITEMALL_HOME=$PWD
echo "LITEMALL_HOME $LITEMALL_HOME"
# 复制数据库
cat $LITEMALL_HOME/litemall-db/sql/litemall_schema.sql > $LITEMALL_HOME/deploy/db/litemall.sql
cat $LITEMALL_HOME/litemall-db/sql/litemall_table.sql >> $LITEMALL_HOME/deploy/db/litemall.sql
cat $LITEMALL_HOME/litemall-db/sql/litemall_data.sql >> $LITEMALL_HOME/deploy/db/litemall.sql
# 打包litemall-admin
cd $LITEMALL_HOME/litemall-admin
npm install --registry=https://registry.npm.taobao.org
npm run build:dep
# 打包litemall-vue
cd $LITEMALL_HOME/litemall-vue
npm install --registry=https://registry.npm.taobao.org
npm run build:dep
cd $LITEMALL_HOME
mvn clean package
cp -f $LITEMALL_HOME/litemall-all/target/litemall-all-*-exec.jar $LITEMALL_HOME/deploy/litemall/litemall.jar
================================================
FILE: doc/FAQ.md
================================================
# 常见问题
## 1 小商城
这里主要是指litemall-wx-api、litemall-wx和renard-wx三个模块的相关问题。
### 1.1 小程序微信登录失败
现象:
小程序微信登录失败
原因:
小程序未上线之前,开发者必须设置自己申请的appid,否则微信登录肯定会失败。
解决:
1. 如果只是体验商品购买流程,开发者可以采用账号注册登录方式。
2. 开发者在litemall-wx、renard-wx和litemall-core模块的appid信息设置成自己申请的信息。
### 1.2 appid已经修改,微信登陆仍然失败
现象:
微信开发者工具修改了开发者自己申请的appid,后端也更新了相应信息,但是微信登录仍然报错。
原因:
这里可能是缓存问题,虽然修改了appid,但是微信开发者工具未及时更新。
解决:
微信开发者工具中修改appid以后,请关闭litemall-wx项目或者微信开发者工具,重新启动导入litemall-wx。
### 1.3 手机真机测试不正常
现象:
微信开发者工具打开正常,但是手机真机扫描加载小商场以后,只有页面结构,没有数据和图片。
原因:
数据或者图片不可访问。
解决:
1. 确保小商场后端服务可以访问,可以通过手机浏览器访问后端服务地址测试
* 小商场的后端服务地址是localhost,则手机不可访问;
* 小商场的后端服务地址是局域网地址,而手机不在局域网中(例如不是相同wifi,或者手机是移动网络)
* 小商场的后端服务未启动
2. 手机小商场的**调试功能**开启
### 1.4 第三方手机测试不正常
现象:
开发者自己手机测试正常,而第三者手机测试不正常。
解决:
1. 确保小商场后端服务可以访问,可以通过第三者手机浏览器访问后端服务地址测试
2. 第三者手机小商场的**调试功能**开启
3. 在微信小程序平台设置第三者的微信账号是**体验者**
### 1.5 微信支付失败
现象:
小商场不能支付,或者点击支付总是报错
原因:
开发者必须拥有商户支付权限,然后设置好以下信息:
```
litemall.wx.app-id=
litemall.wx.app-secret=
litemall.wx.mch-id=
litemall.wx.mch-key=
litemall.wx.notify-url=
```
解决:
参考`3.0 小商场环境`,设置相应支付配置信息
### 1.6 支付成功,但商品仍未付款
现象:
在微信开发者工具中已经成功支付,但是返回订单页面时商品订单仍然显示`未付款`状态。
原因是:
微信平台支付成功以后,会把支付结果推送到`wx.notify-url`所指定的地址。
因此,开发者必须确定`wx.notify-url`所指向的访问链接是可以成功访问,同时
能够返回正常的响应结果。
解决:
1. 如果开发者是在微信开发者工具中测试支付,那么需要采用一些内网穿透工具,
把`WxOrderController.payNotify`所代表的本地地址,例如`http://localhots/wx/order/pay-notify`,
转换成外网可以访问的地址,例如`http://xxx.com/wx/order/pay-notify`,最后
设置`wx.notify-url`指向该地址。
2. 如果开发者已经上线服务,请确认`wx.notify-url`所指向的访问链接可以正常工作。
## 2. 管理后台
这里主要是指litemall-admin-api和litemall-admin两个模块的相关问题。
### 2.1 登录连接超时,联系管理员
现象:
管理后台登录时,出现报错信息:登录连接超时
原因:
1. 首先,需要明白这是前后端分离项目,前端会向后端发送请求;
2. 其次,需要明白报错的地方,是litemall-admin/src/utils/request.js文件中;
3. 最后,连接超时是说发送给后端的请求长时间未反应。这里存在两个可能性:
* 真连接超时,目前request.js文件中设置请求超时时间是5s,因此真的可能5s后端
未及时返回数据;
* 假连接超时,例如向一个不存在的地址请求数据,那自然是返回连接失败。
解决:
通常是开发者设置不正确引起的假连接超时。
1. 首先,用chrome的开发者工具查看登录页面向后端请求的具体地址;
2. 然后,测试后端的服务是否已启动,请求地址是否可以访问。
3. 最后,如果设置正确,用chrome的开发者工具查看登录页面向后端请求返回数据信息;
如果设置不正确,请启动相应的后端服务。
### 2.2 安装失败/启动不成功
现象:
执行`npm install`失败
原因:
可能下载依赖失败。
解决:
清空node_modules,重新执行`npm install`命令,或者自行百度、Google。
### 2.3 分页数据返回不正常
现象:
如果管理后台点击很大的分页页数(实际已超过当时数据最大页数),后端仍然能够返回数据。
原因:
这个不是BUG,而是开发者对于查询页面超过实际页面后应该产生何种效果的不同理解。
* 返回最后一页数据可能是合理的;
* 返回空数据可能也是合理的。
解决:
litemall-db模块的application-db.yaml资源文件中reasonable是true
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
开发者可以尝试设置reasonable为false,然后检查是否能够解决问题。
## 3. 基础系统
这里主要是指litemall-db、litemall-core和litemall-all模块三个模块的相关问题。
### 3.1 Invalid bound statement
现象:
有时(特别是采用mybatis generator重新生成代码)后端服务报错
```
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): org.linlinjava.litemall.db.dao.XXXX
```
原因:
应该是自动生成的新的XML文件没有及时更新到编译文件夹target中,造成了target中mybatis的Java代码和XML文件不对应。
解决:
采用maven命令或者插件先清理项目再重新编译打包,例如
```bash
mvn clean
mvn package
```
### 3.2 Unknown Column
现象:
```
Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'add_time' in 'field list'
The error may exist in org/linlinjava/litemall/db/dao/LitemallSystemMapper.xml
The error may involve org.linlinjava.litemall.db.dao.LitemallSystemMapper.selectByExample-Inline
The error occurred while setting parameters
SQL: select id, key_name, key_value, add_time, update_time, deleted from litemall_system
Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'add_time' in 'field list'
```
原因:
系统处在开发中,所以数据库表根据业务会不断调整,因此如果开发者更新代码以后直接运行,有可能导致当前代码
操作数据库失败,因为开发者当前的数据库表已经过时。
解决:
如果出现数据库方面的报错,建议开发者重新导入数据库。
### 3.3 数据库导入失败
现象:
开发者直接(或使用Navicat)运行litemall_schema.sql时运行失败。
原因:
可能是`drop user if exists`在MySQL低版本不支持,也可能是Navicat不支持。
解决:
首先,请开发者请直接打开litemall_schema.sql文件,可以看到
```
drop database if exists litemall;
drop user if exists 'litemall'@'localhost';
create database litemall default character set utf8mb4 collate utf8mb4_unicode_ci;
use litemall;
create user 'litemall'@'localhost' identified by 'litemall123456';
grant all privileges on litemall.* to 'litemall'@'localhost';
flush privileges;
```
可以看到,这里主要是完成三个工作
* 创建数据库
* 创建数据库用户
* 分配该用户所有操作权限
因此,如果开发者运行litemall_schema.sql失败,开发者可以自行使用
相关SQL命令或者使用SQL工具创建数据库、用户和分配权限工作。
此外实际上,**开发者也不应该在部署或者上线阶段运行litemall_schema.sql**
## 4. 项目
这里主要是指其他项目开发相关问题。
### 4.1 项目导入IDEA时卡顿
现象:
IDEA导入项目时,非常耗时间,或者卡断,或者一直疯狂运行。
原因:
应该是litemall-admin模块和litemall-vue模块的node_modules文件夹导致的。
node_modules是litemall-admin和litemall-vue模块所依赖的项目库,可能有近200M的文件。
而IDEA如果没有设置,则可能尝试对该文件夹进行解析索引,从而导致卡断。
解决方案:
1. 先关闭IDEA,然后删除litemall-admin和litemall-vue模块内的node_modules文件夹;
2. 然后分别创建空的node_modules文件夹;
3. 重新打开IDEA,分别设置litemall-admin模块和litemall-vue模块的node_modules文件夹Excluded状态。

================================================
FILE: doc/README.md
================================================
# Table of Contents
* [介绍](../README.md)
* [更新日志](../CHANGELOG.md)
* [贡献指南](../CONTRIBUTE.md)
* [FAQ](./FAQ.md)
* [API](./api.md)
* [数据库](./database.md)
* [1. 系统架构](./project.md)
* [2. 基础系统](./platform.md)
* [3. 小商场](./wxmall.md)
* [4. 管理后台](./admin.md)
* [5. 轻商城](./mobmall.md)
================================================
FILE: doc/admin.md
================================================
# 4 litemall管理后台
项目技术架构:
* 管理后台前端,即litemall-admin模块
* vue
* vuex
* vue-router
* axios
* element
* vue-element-admin 4.3.0
* 其他,见package.json
* 管理后台后端, 即litemall-admin-api模块
* Spring Boot 2.x
* Spring MVC
目前存在的问题:
* `缺失`首页中实现一些小组件,同时点击能够跳转相应页面
* `缺失`支持导出表所有数据
## 4.1 litemall-admin-api
本节介绍管理后台的后台服务模块。
### 4.1.1 授权服务
见AdminAuthController类
### 4.1.2 用户管理服务
用户管理服务进一步分成:
* 会员管理服务,见AdminUserController类
* 收货地址服务,见AdminAddressController类
* 会员收藏服务,见AdminCollectController类
* 会员足迹服务,见AdminFootprintController类
* 搜索历史服务,见AdminHistoryController类
* 意见反馈服务,见AdminFeedbackController类
### 4.1.3 商场管理服务
商城管理服务进一步分成:
* 行政区域服务,见AdminRegionController类
* 品牌制造商服务,见AdminBrandController类
* 商品类目服务,见AdminCategoryController类
* 订单管理服务,见AdminOrderController类
* 通用问题服务,见AdminIssueController类
* 关键词服务,见AdminKeywordController类
### 4.1.4 商品管理服务
商品服务,见AdminAdminController类
### 4.1.5 推广管理服务
推广管理服务进一步分成:
* 广告服务,见AdminAdController类
* 专题服务,见AdminTopicController类
* 团购服务,见AdminGrouponController类
### 4.1.6 系统管理服务
系统管理服务进一步分成:
* 管理员服务,见AdminAdminController类
* 对象存储服务,见见AdminStorageController类
### 4.1.7 其他服务
* 统计服务,见AdminStatController类
* 个人服务,见AdminProfileController类
### 4.1.8 安全
这里的安全基于Shiro。
#### 4.1.8.1 认证
#### 4.1.8.2 账号密码加盐
如果是微信登录,那么无需账号和密码。
而如果用户采用了账号和密码的形式登录,那么后端需要把用户密码加盐。
#### 4.1.8.3 权限控制
后端实现权限管理功能来支持一定的安全控制。
具体细节见4.1.9。
### 4.1.9 权限管理
权限管理只完成了操作权限的功能,而数据权限的功能未完成。
#### 4.1.9.1 权限设计
权限控制在数据库层面涉及到三个表`litemall_admin`, `litemall_role`和`litemall_permission`:
* litemall_admin表中存在roleId字段,保存角色ID数组;
* litemall_role表记录角色名称和角色介绍;
* litemall_permission表记录角色所用于的权限值。
权限控制在后端层面通过这三个表可以构建出管理员所属的角色以及所拥有的操作权限。
当管理员登录以后,访问一些受权限保护的后端地址时,后端会验证当前管理员的操作权限和后端地址需要的操作权限;
如果不匹配则会抛出异常,然后前端就会收到无操作权限的提示信息。
权限控制在前端层面可以简单地把无操作权限显示给用户即可。
但是前端可以进一步优化完成菜单权限特性和按钮权限特性:
* 菜单权限,即管理员登录以后,前端的菜单是自动生成的;
* 按钮权限,即管理员点击菜单跳转到页面,而页面中只出现当前管理员可操作的按钮。
以上内容参考了网上资料和开源项目,但是实现细节方面会存在一些出入。
##### 4.1.9.1.1 三个表,而不是五个表
通常是五个表,user, role, user_role, permission, role_permission。
但是本项目只需要三个表:
* user_role表的关联关系,可以通过user表的roles字段完成,因此可以省略;
* permission表省略,这里可能是非常奇怪的做法,但是实际上是可行的。
很多开源项目的permission表是记录当前系统的所有权限,最终呈现给管理后台的使用者;
但是数据来源则是开发者或者系统用户来进行数据输入的,但是这样真的合理吗?
* 开发者开发完系统以后,需要额外在数据库中写入权限相关内容,这样存在独立两个步骤
可能不是很好;此外,如果系统升级,完成新的权限,那么如何添加这些权限到数据库也
不是很好。
* 如果开发者设计权限页面,支持系统管理员手动添加新的权限,那样其实也不合适,
因为系统管理员可能对系统的权限并不了解,例如url地址所需要的权限。
这里很多开源项目都是采取这种方法,但是实际上管理员可能根本不会理解或者使用。
这里本项目参考了[biu](https://github.com/CaiBaoHong/biu)项目中注解的方式,
系统的所有的权限不是通过数据库中权限表数据获取,而是通过注解自动解析生产当前系统
所有的权限。而且因为是注解,所以开发者在开发新的权限时,只需要在代码内直接书写,
不需要再次在数据库中写入。
当然,这里并意味说三个表就好或者五个表就不好,开发者可以按照自己的理解来做。
本项目具体如何实现见下文细节。
##### 4.1.9.1.2 权限只有一种类型,而不是三种类型
在[biu](https://github.com/CaiBaoHong/biu)项目中明确了存在三种权限类型,分别是
菜单权限元数据、按钮权限元数据、接口权限元数据。
很明显地,前两种权限对应了前端权限,而接口权限元数据就是后端权限。
本项目没有采用这种理念,其原因是因为对于最终管理员而言,或者说有可能是不懂IT的
普通管理员,前端权限页面存在三个权限给用户勾选,可能反而会造成困惑。实际上,
前端页面建议还是应该出现一种权限效果。
本项目对管理员而言只有一种权限,但是这个权限本身对应了菜单权限元数据、按钮权限元数据、接口权限元数据。
因此,管理员勾选一个权限以后,后台权限即授权成功,同时前端的菜单权限和按钮权限也自动调整。
具体实现细节见下文。
后端权限基于shiro来实现,相关代码见litemall-admin-api模块。
##### 4.1.9.2 基本配置
1. config子包的`ShiroConfig`引入了Shiro并配置了shirFilter、realm和sessionManager;
2. shiroFilter配置只允许少量url可以匿名访问,其他url都需要登录才能访问;
3. realm设置的是shiro子包的`AdminAuthorizingRealm`类,该类作用是认证和授权的功能;
4. sessionManager设置的是shiro子包的`AdminWebSessionManager`类,该类作用是重置会话管理器。
默认会话管理器是基于cookie实现会话保持,而这里是基于自定义头部实现会话保持。
经过以上步骤,shiro就配置正常。
* 当管理员登录时,先认证;
* 认证成功,则授权,在后端内保存roles和permissions;同时,在响应头部写入自定义头部和sessionId;
* 认证失败,则抛出认证异常;
* 管理员再次访问页面时,shiro通过自定义头自动认证成功。
##### 4.1.9.3 权限校验
但是以上只完成授权功能,而没有完成权限校验功能。
这里开发者应该在Controller类的方法中使用`RequiresPermissions`注解。
例如:
```
@RestController
@RequestMapping("/admin/ad")
public class AdminAdController {
@RequiresPermissions("admin:ad:list")
@RequiresPermissionsDesc(menu={"推广管理" , "广告管理"}, button="查询")
@GetMapping("/list")
public Object list(String name, String content,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
List<LitemallAd> adList = adService.querySelective(name, content, page, limit, sort, order);
int total = adService.countSelective(name, content, page, limit, sort, order);
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", adList);
return ResponseUtil.ok(data);
}
}
```
而具体的权限校验逻辑则由shiro自动完成:
1. 登录成功或者会话登录,shiro已经有当前用户的权限列表;
2. 访问权限保护的方法时,shiro通过`RequiresPermissions`注解得到所需操作权限列表;
3. 测试已分配的权限和操作所需权限是否一致,如果一致则可以调用方法,否则抛出无权限的异常。
##### 4.1.9.4 权限描述
在annotation子包中存在一个自定义的`RequiresPermissionsDesc`注解
```
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermissionsDesc {
String[] menu();
String button();
}
```
这里讨论一下为什么要自定义权限描述注解?
> 当后端设计好权限以后,需要向前端发送系统的权限情况,管理员可以查看系统当前所有权限以及允许为一个角色配置权限。
> 这里就带来了实现方面的问题:
> 一些开源项目在数据库设计一个permission表,记录系统所有权限,但是4.1.9.1.1节讨论了这种方式的局限性。
> 因此本项目采用权限注解方式,要求开发者在使用权限注解(RequiresPermissions)的地方应该同时使用权限文档注解(RequiresPermissionsDesc),
> 这样系统能够通过权限注解自动生成权限列表,向前端返回可读的信息。
例如:
```
@RestController
@RequestMapping("/admin/ad")
public class AdminAdController {
@RequiresPermissions("admin:ad:list")
@RequiresPermissionsDesc(menu={"推广管理" , "广告管理"}, button="查询")
@GetMapping("/list")
public Object list(String name, String content,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
List<LitemallAd> adList = adService.querySelective(name, content, page, limit, sort, order);
int total = adService.countSelective(name, content, page, limit, sort, order);
Map<String, Object> data = new HashMap<>();
data.put("total", total);
data.put("items", adList);
return ResponseUtil.ok(data);
}
}
```
本项目通过搜索`RequiresPermissions`注解和`RequiresPermissionsDesc`注解(见util子包的PermissionUtil类),
在内部生产了`Permission`类的集合:
```
public class Permission {
private RequiresPermissions requiresPermissions;
private RequiresPermissionsDesc requiresPermissionsDesc;
private String api;
}
```
也就是说,对于一个权限,既有权限值(requiresPermissions的value),也有权限对应的操作API,
也有权限的描述内容(requiresPermissionsDesc的menu和button)。
前端权限所需要的一些权限内容可以从这里来间接产生,具体方式见4.2.1节。
当然,需要指出的是,这里利用注解方式可以不需要在数据库中保存权限信息,
但是在灵活性方面可能也会有问题。
### 4.1.10 定时任务
job子包存在以下定时任务:
* OrderJob类
* checkOrderUnpaid
* checkOrderUnconfirm
* checkOrderComment
* CouponJob类
* checkCouponExpired
注意:
> 虽然定时任务放在AdminOrderController类中,但是可能这里不是很合适,
> 以后需要调整或者完善。
## 4.2 litemall-admin
本章介绍管理后台的前端模块。
litemall-admin模块的代码基于[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
#### 4.2.1 前端权限
需要再次明确的是,前端权限的作用仅仅是隐藏菜单或者页面按钮,优化用户使用体验,
而实际上没有真正的权限保护功能。
这里前端校验的思路可以参考vue-element-admin的文档:
* [路由和侧边栏](https://panjiachen.github.io/vue-element-admin-site/zh/guide/essentials/router-and-nav.html)
* [权限验证](https://panjiachen.github.io/vue-element-admin-site/zh/guide/essentials/permission.html)
##### 4.2.1.2 角色页面
管理员的角色页面用于创建角色和分配权限。
其中点击授权按钮,则会出现系统所有的权限和当前已经分配的权限,具体代码可以见AdminRoleController的getPermissions。
* 系统所有的权限,可以通过后端自动解析权限描述注解来获取;
* 当前已分配权限,可以通过数据库访问来获取。
#### 4.2.1.3 权限API
vue-element-admin中权限校验是基于role完成的权限校验;
而其他一些开源项目中权限校验是基于permission权限值完成的权限校验;
而本项目进行了调整,基于permission URL完成权限校验。
首先讨论为什么基于role的权限校验不是很好:
vue-element-admin的权限校验要求在菜单或者页面按钮中写上role信息,
这里原理是可以的。但是存在一个问题,就是角色是管理员动态创建的,
因此菜单或者页面按钮直接写死访问所需要的role,不利于后期维护升级。
接着讨论为什么基于permission权限值的权限校验不是很好:
在前后端分离项目中,前端和后端应该是不同的开发者开发。如果采用权限值的方式,
可能导致前后端耦合紧密的问题。
例如,后端开发者开发了一个API是`/admin/ad/list`,后端访问所需的权限值是`admin:ad:list`,
此时前端也需要写菜单或者页面按钮的地方写上`admin:ad:list"`。
当然,这里原理上和操作上都是可行的。但是,这里要求前端开发者必须知道自己访问后端
API所对应的操作权限值。因此如何以一种好的前后端分离的方式来做可能是一个问题。
本项目则基于permission URL的权限校验方式:
后端权限校验逻辑仍然是权限值,而前端权限校验逻辑则是URL。
例如,后端开发者开发了一个API是`/admin/ad/list`,后端访问所需的权限值是`admin:ad:list`,
此时前端则不需要考虑权限值,而是仅仅需要知道自己访问API的方式,也就是在
菜单或者页面按钮的地方写上`GET /admin/ad/list`,而不是`admin:ad:list"`。
之所以是可行的,是因为后端权限是一个(权限值,权限描述,权限访问API)构成的Permission类。
当然,这里也存在一定的局限性。
#### 4.2.1.4 菜单权限
见`src/route/index.js`代码
例如
```
{
path: '/promotion',
component: Layout,
redirect: 'noredirect',
alwaysShow: true,
name: 'promotionManage',
meta: {
title: '推广管理',
icon: 'chart'
},
children: [
{
path: 'ad',
component: () => import('@/views/promotion/ad'),
name: 'ad',
meta: {
perms: ['GET /admin/ad/list', 'POST /admin/ad/create', 'GET /admin/ad/read', 'POST /admin/ad/update', 'POST /admin/ad/delete'],
title: '广告管理',
noCache: true
}
}
}
]
},
```
在菜单的meta中的perms属性声明了当前菜单所需要的操作权限。
如果管理员登录以后,所分配的操作权限存在至少一个,那么该菜单就会显示;
否则该菜单就会隐藏。
##### 4.2.1.4 按钮权限
在每个页面中一些组件可以采用指令`v-permission`或者函数`checkPermission`来实现按钮权限。
例如,`src/views/promation/ad`页面中
```
<div class="filter-container">
<el-input v-model="listQuery.name" clearable class="filter-item" style="width: 200px;" placeholder="请输入广告标题"/>
<el-input v-model="listQuery.content" clearable class="filter-item" style="width: 200px;" placeholder="请输入广告内容"/>
<el-button v-permission="['GET /admin/ad/list']" class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">查找</el-button>
<el-button v-permission="['POST /admin/ad/create']" class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate">添加</el-button>
<el-button :loading="downloadLoading" class="filter-item" type="primary" icon="el-icon-download" @click="handleDownload">导出</el-button>
</div>
```
element的`el-button`组件声明了操作权限是`GET /admin/ad/list'`。
如果管理员登录以后,所分配的操作权限匹配,那么该按钮就会显示;
否则该按钮就会隐藏。
##### 4.1.1.5 权限局限性
前端权限这里的代码调整旨在解决一些认为不合理的地方,但是实际上也同时带来了
一定的局限性或者限制。
这里列出一些可能的问题,开发者可以自己审阅或者重新设计代码。
## 4.3 开发新组件
本章节介绍如何开发新的管理后台功能。
### 4.3.1 管理后台前端页面
### 4.3.2 前后端交互服务API
### 4.3.3 管理后台后端服务
### 4.3.4 数据库
================================================
FILE: doc/api.md
================================================
# 前后端接口文档
本项目前后端接口规范和接口文档。
注意:
> 1. 以下API部分基于nideshop开源项目的API设计;
> 2. 以下API是参考API,可能不是很合理,欢迎开发者交流。
> 3. 接口文档处于开发中,如果发现接口描述和接口实际不对应,欢迎PR或者报告。
## 1 前后端接口规范
### 1.1 请求格式
这里没有采用RESTful风格的接口,而是定义具体语义的接口。
目前只使用`GET`和`POST`来表示请求内容和更新内容两种语义。
#### 1.1.1 GET请求
GET API_URL?params
例如
GET /home/index
或者
GET /goods/list?page=1&limit=10
#### 1.1.2 POST更新
POST API_URL
{
body
}
例如
POST /cart/clear
或者
POST /goods/star
{
id: 1
}
#### 1.1.3 分页请求参数
当GET请求后端获取数组数据时,需要传递分页参数。
例如
GET /goods/list?page=1&limit=10&sort=add_time&order=desc
本项目的通用分页请求参数统一传递四个:
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
* page, 和通常计算机概念中数组下标从0开始不同,这里的page参数应该从1开始,1即代表第一页数据;
* limit, 分页大小;
* sort, 例如"add_time"或者"id";
* order, 只能是"desc"或者"asc"。
此外,这里四个参数是可选的,后端应该设置默认参数,因此即使前端不设置,
后端也会自动返回合适的对象数组响应数据。
注意:
> 这里的参数是需要后端支持的,在一些场景下,例如数组对象是组装而成,
> 有可能sort和order不支持。
讨论:
> 有些请求后端是所有数据,这里page和limit可能设置是无意义的。但是
> 仍然建议加上两个参数,例如page=1, limit=1000。
也就是说,请求后端数组数据时,同一传递四个分页参数,可能是比较良好的做法。
### 1.2 响应格式
Content-Type: application/json;charset=UTF-8
{
body
}
而body是存在一定格式的json内容:
{
errno: xxx,
errmsg: xxx,
data: {}
}
#### 1.2.1 失败异常
{
errno: xxx,
errmsg: xxx
}
* errno是错误码,具体语义见1.3节。
* errmsg是错误信息。
#### 1.2.2 操作成功
{
errno: 0,
errmsg: "成功",
}
#### 1.2.3 普通对象
{
errno: 0,
errmsg: "成功",
data: {}
}
#### 1.2.4 数组对象
{
errno: 0,
errmsg: "成功",
data: {
list: [],
total: XX,
page: XX,
limit: XX,
pages: XX
}
}
list是对象数组,total是总的数量。
### 1.3 错误码
#### 1.3.1 系统通用错误码
系统通用错误码包括4XX和5XX
* 4xx,前端错误,说明前端开发者需要重新了解后端接口使用规范:
* 401,参数错误,即前端没有传递后端需要的参数;
* 402,参数值错误,即前端传递的参数值不符合后端接收范围。
* 5xx,后端系统错误,除501外,说明后端开发者应该继续优化代码,尽量避免返回后端系统错误码:
* 501,验证失败,即后端要求用户登录;
* 502,系统内部错误,即没有合适命名的后端内部错误;
* 503,业务不支持,即后端虽然定义了接口,但是还没有实现功能;
* 504,更新数据失效,即后端采用了乐观锁更新,而并发更新时存在数据更新失效;
* 505,更新数据失败,即后端数据库更新失败(正常情况应该更新成功)。
#### 1.3.2 商场业务错误码
* AUTH_INVALID_ACCOUNT = 700
* AUTH_CAPTCHA_UNSUPPORT = 701
* AUTH_CAPTCHA_FREQUENCY = 702
* AUTH_CAPTCHA_UNMATCH = 703
* AUTH_NAME_REGISTERED = 704
* AUTH_MOBILE_REGISTERED = 705
* AUTH_MOBILE_UNREGISTERED = 706
* AUTH_INVALID_MOBILE = 707
* AUTH_OPENID_UNACCESS = 708
* AUTH_OPENID_BINDED = 709
* GOODS_UNSHELVE = 710
* GOODS_NO_STOCK = 711
* GOODS_UNKNOWN = 712
* GOODS_INVALID = 713
* ORDER_UNKNOWN = 720
* ORDER_INVALID = 721
* ORDER_CHECKOUT_FAIL = 722
* ORDER_CANCEL_FAIL = 723
* ORDER_PAY_FAIL = 724
* ORDER_INVALID_OPERATION = 725
* ORDER_COMMENTED = 726
* ORDER_COMMENT_EXPIRED = 727
* GROUPON_EXPIRED = 730
* COUPON_EXCEED_LIMIT = 740
* COUPON_RECEIVE_FAIL= 741
* COUPON_CODE_INVALID= 742
#### 1.3.3 管理后台业务错误码
* ADMIN_INVALID_NAME = 601
* ADMIN_INVALID_PASSWORD = 602
* ADMIN_NAME_EXIST = 602
* ADMIN_ALTER_NOT_ALLOWED = 603
* ADMIN_DELETE_NOT_ALLOWED = 604
* ADMIN_INVALID_ACCOUNT = 605
* GOODS_UPDATE_NOT_ALLOWED = 610
* GOODS_NAME_EXIST = 611
* ORDER_CONFIRM_NOT_ALLOWED = 620
* ORDER_REFUND_FAILED = 621
* ORDER_REPLY_EXIST = 622
* USER_INVALID_NAME = 630
* USER_INVALID_PASSWORD = 631
* USER_INVALID_MOBILE = 632
* USER_NAME_EXIST = 633
* USER_MOBILE_EXIST = 634
* ROLE_NAME_EXIST = 640
* ROLE_SUPER_SUPERMISSION = 641
* ROLE_USER_EXIST = 642
### 1.4 Token
前后端采用token来验证访问权限。
#### 1.4.1 Header&Token
前后端Token交换流程如下:
1. 前端访问商场登录API或者管理后台登录API;
2. 成功以后,前端会接收后端响应的一个token,保存在本地;
3. 请求受保护API则,则采用自定义头部携带此token
4. 后端检验Token,成功则返回受保护的数据。
#### 1.4.2 商场自定义Header
访问受保护商场API采用自定义`X-Litemall-Token`头部
1. 小商城(或轻商场)前端访问小商城后端登录API`/wx/auth/login`
POST /wx/auth/login
{
"username": "user123",
"password": "user123"
}
2. 成功以后,前端会接收后端响应的一个token,
{
"errno": 0,
"data": {
"userInfo": {
"nickName": "user123",
"avatarUrl": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0aGlzIGlzIGxpdGVtYWxsIHRva2VuIiwiYXVkIjoiTUlOSUFQUCIsImlzcyI6IkxJVEVNQUxMIiwiZXhwIjoxNTU3MzI2ODUwLCJ1c2VySWQiOjEsImlhdCI6MTU1NzMxOTY1MH0.XP0TuhupV_ttQsCr1KTaPZVlTbVzVOcnq_K0kXdbri0"
},
"errmsg": "成功"
}
3. 请求受保护API则,则采用自定义头部携带此token
GET http://localhost:8080/wx/address/list
X-Litemall-Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0aGlzIGlzIGxpdGVtYWxsIHRva2VuIiwiYXVkIjoiTUlOSUFQUCIsImlzcyI6IkxJVEVNQUxMIiwiZXhwIjoxNTU3MzM2ODU0LCJ1c2VySWQiOjIsImlhdCI6MTU1NzMyOTY1NH0.JY1-cqOnmi-CVjFohZMqK2iAdAH4O6CKj0Cqd5tMF3M
#### 1.4.3 管理后台自定义Header
访问受保护管理后台API则是自定义`X-Litemall-Admin-Token`头部。
1. 管理后台前端访问管理后台后端登录API`/admin/auth/login`
POST /admin/auth/login
{
"username": "admin123",
"password": "admin123"
}
2. 成功以后,管理后台前端会接收后端响应的一个token,
{
"errno": 0,
"data": {
"adminInfo": {
"nickName": "admin123",
"avatar": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
},
"token": "f2dbcae8-6e25-4f8e-bc58-aa81d512c952"
},
"errmsg": "成功"
}
3. 请求受保护API时,则采用自定义头部携带此token
GET http://localhost:8080/wx/address/list
X-Litemall-Admin-Token: f2dbcae8-6e25-4f8e-bc58-aa81d512c952
### 1.5 版本控制
API应该存在版本控制,以保证兼容性。
由于仍处于开发中,因此目前未引入版本控制。
### 1.6 API格式
这里定义一个API的格式:
应用场景
xxx
接口链接
xxx
请求参数
xxx
响应内容
xxx
错误码
xxx
### 1.7 API预览
接下来会分别从用户层面和管理员层面构建商场API服务和管理后台API服务。
商场API服务涉及
* 安全服务
* 首页服务
* 类目服务
* 商品服务
* 购物车服务
* 订单服务
* 会员服务
* 收货地址服务
* 品牌商服务
* 收藏服务
* 评论服务
* 优惠券服务
* 反馈服务
* 足迹服务
* 团购服务
* 帮助服务
* 搜索服务
* 专题服务
* 对象存储服务
管理后台API服务涉及:
* 略
### 1.8 API测试
本节以GET、POST两种方式以及是否需要登录举例说明如何测试和使用本项目API。
开发者可以使用各种API测试命令或者工具,这里以Postman作为工具。
#### 1.8.1 GET 示例
如果一个API是GET方法,那么请求参数需要在访问链接后面:
例如测试2.4.2节商品详情API

#### 1.8.2 GET & Token 示例
如果需要登录才能访问数据,则需要先向后端请求登录,得到token,然后请求时携带token。
例如测试2.8.1节收货地址列表API
如果没有登录,则返回未登录信息

因此测试这些API,需要先登录

然后,采用自定义`X-Litemall-Token`来携带token访问商场API

注意:
> 访问受保护商场API是采用自定义`X-Litemall-Token`头部;
> 而访问受保护管理后台API则是自定义`X-Litemall-Admin-Token`头部。
#### 1.8.3 POST 示例
通常POST请求后端时,都需要先登录才能有权限上传数据,因此这里不举例说明。
#### 1.8.4 POST & Token 示例
如果需要登录才能提交数据,则需要先向后端请求登录,得到token,然后请求时携带token。

因此测试这些API,需要先登录

然后,采用自定义`X-Litemall-Token`来携带token访问商场API

注意:
> 访问受保护商场API是采用自定义`X-Litemall-Token`头部;
> 而访问受保护管理后台API则是自定义`X-Litemall-Admin-Token`头部。
### 1.9 API保护
为了保护API不被滥用,通常API需要引入保护机制,例如OAuth2。
本项目暂时无保护机制,因此实际上一旦开发者知道服务器,就很容易访问API。
### 1.10 API局限性
当前API还存在一些问题,后面需要继续优化和完善。
* 无意义的通用字段
* 团购API完善
### 1.11 Not Like Swagger
本项目不是很接受Swagger,基于以下考虑:
* 前后端中立
在前后端分离项目中,依赖后端的Swagger来生成项目API似乎不是很理想,
这实际上把项目API设计工作过多地压在后端,同时前端也被迫依赖后端,
因为后端如果没有写好文档注解,前端不可能了解API的输入输出。
可能一种合理的做法应该这样:
项目初期前后端一起完成一个完整基本的API文档,定义好交互规范和具体API的行为,然后双方同时开始开发工作;
某个开发阶段,前端需要更多的数据或者新的API支持,此时也不需要立即联系后端(除非API产生破坏性变更),
而是暂时基于mock和自定义mock数据独立开发;之后,在合适阶段(可以按照项目规定,例如三天或者周五),
前后端再次沟通API的变更,后端了解需求后则可以接受、拒绝或者调整,当然变更必须要在API文档中体现和更新;
下一个开发阶段,前端和后端能够再次基于最新的API文档来调整自己代码。
最后项目测试时,只要前端对照API文档,后端也是对照API文档。
* 后端代码简洁
如果使用Swagger,为了得到完整的文档,需要在每一个方法前面加上多个文档注解,文档越是详尽,则注解越多,
造成代码不是很简洁。特别是具备代码属性的注解和Swagger文档注解混杂在一起,可能不是很好。
当然,本项目也简单地配置了Swagger(见`WxSwagger2Configuration`和`AdminSwagger2Configuration`),
* 在线Swagger文档链接:http://122.51.199.160:8080/swagger-ui.html
* 本地Swagger文档链接:http://localhost:8080/swagger-ui.html
此外,也使用了swagger-bootstrap-ui对Swagger进一步增强了使用效果。
* 在线swagger-bootstrap-ui文档链接:http://122.51.199.160:8080/doc.html
* 本地swagger-bootstrap-ui文档链接:http://localhost:8080/doc.html
当然正如上文讨论,本项目不是很接受Swagger的理念,所以后端没有使用Swagger的相关文档注解,
这也导致了Swagger接口文档的不具可读性。如果开发者需要,可以自行在后端补充Swagger注解。
需要注意的是:
> 这里接口默认是公开的,因此项目一旦需要上线,请及时删除swagger和swagger-bootstrap-ui依赖和配置,
> 或者采取其他手段,防止接口对外暴露造成**安全隐患**。
例如
```
swagger:
production: false
```
## 2 商城API服务
### 2.1 安全服务
#### 2.1.1 小程序微信登录
应用场景
小程序环境下微信登录。
接口链接
xxx
请求参数
xxx
响应内容
xxx
错误码
xxx
#### 2.1.2 账号登录
应用场景
基于用户名和密码的账号登录
接口链接
POST /wx/auth/login
请求参数
{
"username": "user123",
"password": "user123"
}
响应内容
{
"errno": 0,
"data": {
"userInfo": {
"nickName": "user123",
"avatarUrl": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0aGlzIGlzIGxpdGVtYWxsIHRva2VuIiwiYXVkIjoiTUlOSUFQUCIsImlzcyI6IkxJVEVNQUxMIiwiZXhwIjoxNTU3MzI2ODUwLCJ1c2VySWQiOjEsImlhdCI6MTU1NzMxOTY1MH0.XP0TuhupV_ttQsCr1KTaPZVlTbVzVOcnq_K0kXdbri0"
},
"errmsg": "成功"
}
错误码
略
#### 2.1.3 注册
应用场景
xxx
接口链接
xxx
请求参数
xxx
响应内容
xxx
错误码
xxx
#### 2.1.4 退出
应用场景
账号退出
接口链接
POST /wx/auth/logout
请求参数
{
"username": "user123",
"password": "user123"
}
响应内容
{
"errno": 0,
"errmsg": "成功"
}
错误码
略
#### 2.1.5 注册验证码
应用场景
用户未登录情况下,请求后端发送注册验证码用于注册。
接口链接
xxx
请求参数
xxx
响应内容
xxx
错误码
xxx
#### 2.1.6 操作验证码
应用场景
用户已登录情况下,请求后端发送操作验证码用于相关操作。
接口链接
xxx
请求参数
xxx
响应内容
xxx
错误码
xxx
#### 2.1.7 账号密码修改
应用场景
账号密码修改
接口链接
xxx
请求参数
xxx
响应内容
xxx
错误码
xxx
#### 2.1.8 微信手机号码绑定
应用场景
微信手机号码绑定,仅用于小程序环境。
接口链接
xxx
请求参数
xxx
响应内容
xxx
错误码
xxx
#### 2.1.9 手机号码修改
应用场景
手机号码修改
接口链接
xxx
请求参数
xxx
响应内容
xxx
错误码
xxx
#### 2.1.10 账号信息
应用场景
账号信息
接口链接
GET /wx/auth/info
请求参数
无
响应内容
{
"errno": 0,
"data": {
"gender": 1,
"nickName": "user123",
"mobile": "",
"avatar": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
},
"errmsg": "成功"
}
错误码
略
#### 2.1.11 账号信息更新
应用场景
账号信息更新。
接口链接
POST /wx/auth/profile
请求参数
{
"gender": 1,
"nickName": "user123",
"avatar": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
}
响应内容
{
"errno": 0,
"errmsg": "成功"
}
错误码
略
### 2.2 首页服务
#### 2.2.1 首页数据
应用场景
首页数据
接口链接
GET /wx/home/index
请求参数
无
响应内容
{
"errno": 0,
"data": {
"newGoodsList": [
{
"id": 1181000,
"name": "母亲节礼物-舒适安睡组合",
"brief": "安心舒适是最好的礼物",
"picUrl": "http://yanxuan.nosdn.127.net/1f67b1970ee20fd572b7202da0ff705d.png",
"isNew": true,
"isHot": false,
"counterPrice": 2618.00,
"retailPrice": 2598.00
},
{
"id": 1116011,
"name": "蔓越莓曲奇 200克",
"brief": "酥脆奶香,甜酸回味",
"picUrl": "http://yanxuan.nosdn.127.net/767b370d07f3973500db54900bcbd2a7.png",
"isNew": true,
"isHot": true,
"counterPrice": 56.00,
"retailPrice": 36.00
},
{
"id": 1127047,
"name": "趣味粉彩系列笔记本",
"brief": "粉彩色泽,记录生活",
"picUrl": "http://yanxuan.nosdn.127.net/6c03ca93d8fe404faa266ea86f3f1e43.png",
"isNew": true,
"isHot": false,
"counterPrice": 49.00,
"retailPrice": 29.00
},
{
"id": 1135002,
"name": "宫廷奢华真丝四件套",
"brief": "100%桑蚕丝,丝滑润肤",
"picUrl": "http://yanxuan.nosdn.127.net/45548f26cfd0c7c41e0afc3709d48286.png",
"isNew": true,
"isHot": false,
"counterPrice": 2619.00,
"retailPrice": 2599.00
},
{
"id": 1152161,
"name": "竹语丝麻印花四件套",
"brief": "3重透气,清爽柔滑",
"picUrl": "http://yanxuan.nosdn.127.net/977401e75113f7c8334c4fb5b4bf6215.png",
"isNew": true,
"isHot": false,
"counterPrice": 479.00,
"retailPrice": 459.00
},
{
"id": 1166008,
"name": "Carat钻石 不粘厨具组合",
"brief": "钻石涂层,不粘锅锅具组",
"picUrl": "http://yanxuan.nosdn.127.net/615a16e899e01efb780c488df4233f48.png",
"isNew": true,
"isHot": false,
"counterPrice": 479.00,
"retailPrice": 459.00
}
],
"couponList": [
{
"id": 2,
"name": "限时满减券",
"desc": "全场通用",
"tag": "无限制",
"discount": 10.00,
"min": 99.00,
"days": 10
}
],
"channel": [
{
"id": 1005000,
"name": "居家",
"iconUrl": "http://yanxuan.nosdn.127.net/a45c2c262a476fea0b9fc684fed91ef5.png"
},
{
"id": 1005001,
"name": "餐厨",
"iconUrl": "http://yanxuan.nosdn.127.net/ad8b00d084cb7d0958998edb5fee9c0a.png"
},
{
"id": 1005002,
"name": "饮食",
"iconUrl": "http://yanxuan.nosdn.127.net/c9280327a3fd2374c000f6bf52dff6eb.png"
},
{
"id": 1008000,
"name": "配件",
"iconUrl": "http://yanxuan.nosdn.127.net/11abb11c4cfdee59abfb6d16caca4c6a.png"
},
{
"id": 1010000,
"name": "服装",
"iconUrl": "http://yanxuan.nosdn.127.net/28a685c96f91584e7e4876f1397767db.png"
},
{
"id": 1011000,
"name": "婴童",
"iconUrl": "http://yanxuan.nosdn.127.net/1ba9967b8de1ac50fad21774a4494f5d.png"
},
{
"id": 1012000,
"name": "杂货",
"iconUrl": "http://yanxuan.nosdn.127.net/c2a3d6349e72c35931fe3b5bcd0966be.png"
},
{
"id": 1013001,
"name": "洗护",
"iconUrl": "http://yanxuan.nosdn.127.net/9fe068776b6b1fca13053d68e9c0a83f.png"
},
{
"id": 1019000,
"name": "志趣",
"iconUrl": "http://yanxuan.nosdn.127.net/7093cfecb9dde1dd3eaf459623df4071.png"
}
],
"grouponList": [
{
"id": 1109008,
"name": "云端沙发组合",
"brief": "MUJI供应商携手打造",
"picUrl": "http://yanxuan.nosdn.127.net/c5be2604c0e4186a4e7079feeb742cee.png",
"counterPrice": 4019.00,
"retailPrice": 3999.00,
"grouponPrice": 3949.00,
"grouponDiscount": 50,
"grouponMember": 5
},
{
"id": 1039051,
"name": "多功能午睡枕",
"brief": "放松自在的午后时光",
"picUrl": "http://yanxuan.nosdn.127.net/c8ca0600fa7ba11ca8be6a3173dd38c9.png",
"counterPrice": 99.00,
"retailPrice": 79.00,
"grouponPrice": 59.00,
"grouponDiscount": 20,
"grouponMember": 20
}
],
"banner": [
{
"id": 1,
"name": "合作 谁是你的菜",
"link": "",
"url": "http://yanxuan.nosdn.127.net/65091eebc48899298171c2eb6696fe27.jpg",
"position": 1,
"content": "合作 谁是你的菜",
"enabled": true,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 2,
"name": "活动 美食节",
"link": "",
"url": "http://yanxuan.nosdn.127.net/bff2e49136fcef1fd829f5036e07f116.jpg",
"position": 1,
"content": "活动 美食节",
"enabled": true,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 3,
"name": "活动 母亲节",
"link": "",
"url": "http://yanxuan.nosdn.127.net/8e50c65fda145e6dd1bf4fb7ee0fcecc.jpg",
"position": 1,
"content": "活动 母亲节5",
"enabled": true,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
}
],
"brandList": [
{
"id": 1001000,
"name": "MUJI制造商",
"desc": "严选精选了MUJI制造商和生产原料,\n用几乎零利润的价格,剔除品牌溢价,\n让用户享受原品牌的品质生活。",
"picUrl": "http://yanxuan.nosdn.127.net/1541445967645114dd75f6b0edc4762d.png",
"floorPrice": 12.90
},
{
"id": 1001002,
"name": "内野制造商",
"desc": "严选从世界各地挑选毛巾,最终选择了为日本内野代工的工厂,追求毛巾的柔软度与功能性。品质比肩商场几百元的毛巾。",
"picUrl": "http://yanxuan.nosdn.127.net/8ca3ce091504f8aa1fba3fdbb7a6e351.png",
"floorPrice": 29.00
},
{
"id": 1001003,
"name": "Adidas制造商",
"desc": "严选找到为Adidas等品牌制造商,\n选取优质原材料,与厂方一起设计,\n为你提供好的理想的运动装备。",
"picUrl": "http://yanxuan.nosdn.127.net/335334d0deaff6dc3376334822ab3a2f.png",
"floorPrice": 49.00
},
{
"id": 1001007,
"name": "优衣库制造商",
"desc": "严选找到日本知名服装UNIQLO的制造商,\n选取优质长绒棉和精梳工艺,\n与厂方一起设计,为你提供理想的棉袜。",
"picUrl": "http://yanxuan.nosdn.127.net/0d72832e37e7e3ea391b519abbbc95a3.png",
"floorPrice": 29.00
}
],
"hotGoodsList": [
{
"id": 1152008,
"name": "魔兽世界 部落 护腕 一只",
"brief": "吸汗、舒适、弹性、防护、耐用",
"picUrl": "http://yanxuan.nosdn.127.net/203cb83d93606865e3ddde57b69b9e9a.png",
"isNew": false,
"isHot": true,
"counterPrice": 49.00,
"retailPrice": 29.00
},
{
"id": 1152009,
"name": "魔兽世界 联盟 护腕 一只",
"brief": "吸汗、舒适、弹性、防护、耐用",
"picUrl": "http://yanxuan.nosdn.127.net/ae6d41117717387b82dcaf1dfce0cd97.png",
"isNew": false,
"isHot": true,
"counterPrice": 49.00,
"retailPrice": 29.00
},
{
"id": 1152031,
"name": "魔兽世界-伊利丹颈枕眼罩套装",
"brief": "差旅好伴侣",
"picUrl": "http://yanxuan.nosdn.127.net/fd6e78a397bd9e9804116a36f0270b0a.png",
"isNew": false,
"isHot": true,
"counterPrice": 119.00,
"retailPrice": 99.00
},
{
"id": 1022000,
"name": "意式毛线绣球四件套",
"brief": "浪漫毛线绣球,简约而不简单",
"picUrl": "http://yanxuan.nosdn.127.net/5350e35e6f22165f38928f3c2c52ac57.png",
"isNew": false,
"isHot": true,
"counterPrice": 319.00,
"retailPrice": 299.00
},
{
"id": 1011004,
"name": "色织精梳AB纱格纹空调被",
"brief": "加大加厚,双色精彩",
"picUrl": "http://yanxuan.nosdn.127.net/0984c9388a2c3fd2335779da904be393.png",
"isNew": false,
"isHot": true,
"counterPrice": 219.00,
"retailPrice": 199.00
},
{
"id": 1084003,
"name": "纯棉美式绞花针织盖毯",
"brief": "美式提花,温暖舒适",
"picUrl": "http://yanxuan.nosdn.127.net/cf40c167e7054fe184d49f19121f63c7.png",
"isNew": false,
"isHot": true,
"counterPrice": 219.00,
"retailPrice": 199.00
}
],
"topicList": [
{
"id": 264,
"title": "设计师们推荐的应季好物",
"subtitle": "原创设计春款系列上新",
"price": 29.90,
"readCount": "77.7k",
"picUrl": "https://yanxuan.nosdn.127.net/14918201901050274.jpg"
},
{
"id": 266,
"title": "一条丝巾就能提升时髦度",
"subtitle": "不知道大家对去年G20时,严选与国礼制造商一起推出的《凤凰于飞》等几款丝巾是否还...",
"price": 0.00,
"readCount": "35.0k",
"picUrl": "https://yanxuan.nosdn.127.net/14919007135160213.jpg"
},
{
"id": 268,
"title": "米饭好吃的秘诀:会呼吸的锅",
"subtitle": "今年1月份,我们联系到了日本伊贺地区的长谷园,那里有着180年伊贺烧历史的窑厂。...",
"price": 0.00,
"readCount": "33.3k",
"picUrl": "https://yanxuan.nosdn.127.net/14920623353130483.jpg"
},
{
"id": 271,
"title": "选式新懒人",
"subtitle": "懒出格调,懒出好生活。",
"price": 15.00,
"readCount": "57.7k",
"picUrl": "https://yanxuan.nosdn.127.net/14924199099661697.jpg"
}
],
"floorGoodsList": [
{
"name": "居家",
"goodsList": [
{
"id": 1110016,
"name": "天然硅胶宠物除毛按摩刷",
"brief": "顺滑平面,猫狗通用,去除死毛",
"picUrl": "http://yanxuan.nosdn.127.net/3bd73b7279a83d1cbb50c0e45778e6d6.png",
"isNew": false,
"isHot": false,
"counterPrice": 59.00,
"retailPrice": 39.00
},
{
"id": 1110017,
"name": "耐用材料猫咪护理清洁套装",
"brief": "精致钢材,美容清洁",
"picUrl": "http://yanxuan.nosdn.127.net/534231583f82572398ec84bad425cdaf.png",
"isNew": false,
"isHot": false,
"counterPrice": 99.00,
"retailPrice": 79.00
},
{
"id": 1110018,
"name": "耐用狗狗清洁美容护理套装",
"brief": "精致钢材,耐咬美容",
"picUrl": "http://yanxuan.nosdn.127.net/d93aa5d6e7a296101cf4cb72613aeda6.png",
"isNew": false,
"isHot": false,
"counterPrice": 99.00,
"retailPrice": 79.00
},
{
"id": 1110019,
"name": "宠物合金钢安全除菌指甲护理组合",
"brief": "猫狗皆可用,保护家具",
"picUrl": "http://yanxuan.nosdn.127.net/1e7e392b6fc9da99dc112197b7444eec.png",
"isNew": false,
"isHot": false,
"counterPrice": 89.00,
"retailPrice": 69.00
}
],
"id": 1005000
},
{
"name": "餐厨",
"goodsList": [
{
"id": 1023003,
"name": "100年传世珐琅锅 全家系列",
"brief": "特质铸铁,大容量全家共享",
"picUrl": "http://yanxuan.nosdn.127.net/c39d54c06a71b4b61b6092a0d31f2335.png",
"isNew": false,
"isHot": false,
"counterPrice": 418.00,
"retailPrice": 398.00
},
{
"id": 1073008,
"name": "铸铁珐琅牛排煎锅",
"brief": "沥油隔水,煎出外焦里嫩",
"picUrl": "http://yanxuan.nosdn.127.net/619e46411ccd62e5c0f16692ee1a85a0.png",
"isNew": false,
"isHot": false,
"counterPrice": 169.00,
"retailPrice": 149.00
},
{
"id": 1051000,
"name": "Carat钻石炒锅30cm",
"brief": "安全涂层,轻便无烟",
"picUrl": "http://yanxuan.nosdn.127.net/e564410546a11ddceb5a82bfce8da43d.png",
"isNew": false,
"isHot": false,
"counterPrice": 200.00,
"retailPrice": 180.00
},
{
"id": 1051001,
"name": "Carat钻石煎锅28cm",
"brief": "耐磨涂层,导热迅速",
"picUrl": "http://yanxuan.nosdn.127.net/f53ed57d9e23fda7e24dfd0e0a50c5d1.png",
"isNew": false,
"isHot": false,
"counterPrice": 179.00,
"retailPrice": 159.00
}
],
"id": 1005001
},
{
"name": "饮食",
"goodsList": [
{
"id": 1045000,
"name": "绿茶蛋黄酥 200克/4枚入",
"brief": "香甜茶食,果腹优选",
"picUrl": "http://yanxuan.nosdn.127.net/b2adc3fd9b84a289a1be03e8ee400e61.png",
"isNew": false,
"isHot": false,
"counterPrice": 48.00,
"retailPrice": 28.00
},
{
"id": 1116011,
"name": "蔓越莓曲奇 200克",
"brief": "酥脆奶香,甜酸回味",
"picUrl": "http://yanxuan.nosdn.127.net/767b370d07f3973500db54900bcbd2a7.png",
"isNew": true,
"isHot": true,
"counterPrice": 56.00,
"retailPrice": 36.00
},
{
"id": 1070000,
"name": "星云酥 180克/3颗",
"brief": "酥饼界的小仙女",
"picUrl": "http://yanxuan.nosdn.127.net/8392725765cdd57fdae3f173877f4bda.png",
"isNew": false,
"isHot": false,
"counterPrice": 46.00,
"retailPrice": 26.00
},
{
"id": 1155015,
"name": "绿豆糕 80克(4枚入)",
"brief": "细腻松软,入口绵柔",
"picUrl": "http://yanxuan.nosdn.127.net/66b9f1638c0517d179262f14ed1345f9.png",
"isNew": true,
"isHot": false,
"counterPrice": 32.90,
"retailPrice": 12.90
}
],
"id": 1005002
},
{
"name": "配件",
"goodsList": [
{
"id": 1085019,
"name": "20寸 纯PC“铝框”(非全铝)登机箱",
"brief": "铝质包角,牢固抗摔",
"picUrl": "http://yanxuan.nosdn.127.net/65c955a7a98e84d44ca30bb88a591eac.png",
"isNew": false,
"isHot": false,
"counterPrice": 369.00,
"retailPrice": 349.00
},
{
"id": 1086052,
"name": "20寸 铝镁合金登机箱",
"brief": "时尚金属箱,奢品质感",
"picUrl": "http://yanxuan.nosdn.127.net/93171a281c4ed272c007a050816e6f6c.png",
"isNew": false,
"isHot": false,
"counterPrice": 879.00,
"retailPrice": 859.00
},
{
"id": 1152101,
"name": "魔兽世界 部落 奥格瑞玛 拉杆箱 可登机",
"brief": "18寸,可携带登机",
"picUrl": "http://yanxuan.nosdn.127.net/c1c62211a17b71a634fa0c705d11fb42.png",
"isNew": false,
"isHot": true,
"counterPrice": 908.00,
"retailPrice": 888.00
},
{
"id": 1114011,
"name": "104升 纯PC拉链斜纹拉杆箱",
"brief": "104升的体积,90升的价格",
"picUrl": "http://yanxuan.nosdn.127.net/196b5ce11930b4eadaec563cb0406634.png",
"isNew": false,
"isHot": false,
"counterPrice": 319.00,
"retailPrice": 299.00
}
],
"id": 1008000
}
]
},
"errmsg": "成功"
}
错误码
无
### 2.3 类目服务
### 2.4 商品服务
#### 2.4.1 商品列表
应用场景
商品列表
接口链接
GET /wx/goods/list
请求参数
isNew: 是否新品,true或者false
isHot: 是否热卖商品,true或者false
keyword: 关键字,如果设置则查询是否匹配关键字
brandId: 品牌商ID,如果设置则查询品牌商所属商品
categoryId: 商品分类ID,如果设置则查询分类所属商品
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应内容
{
"errno": 0,
"data": {
"total": 11,
"pages": 6,
"limit": 2,
"page": 1,
"list": [
{
"id": 1181000,
"name": "母亲节礼物-舒适安睡组合",
"brief": "安心舒适是最好的礼物",
"picUrl": "http://yanxuan.nosdn.127.net/1f67b1970ee20fd572b7202da0ff705d.png",
"isNew": true,
"isHot": false,
"counterPrice": 2618.00,
"retailPrice": 2598.00
},
{
"id": 1116011,
"name": "蔓越莓曲奇 200克",
"brief": "酥脆奶香,甜酸回味",
"picUrl": "http://yanxuan.nosdn.127.net/767b370d07f3973500db54900bcbd2a7.png",
"isNew": true,
"isHot": true,
"counterPrice": 56.00,
"retailPrice": 36.00
}
],
"filterCategoryList": [
{
"id": 1005007,
"name": "锅具",
"keywords": "",
"desc": "一口好锅,炖煮生活一日三餐",
"pid": 1005001,
"iconUrl": "http://yanxuan.nosdn.127.net/4aab4598017b5749e3b63309d25e9f6b.png",
"picUrl": "http://yanxuan.nosdn.127.net/d2db0d1d0622c621a8aa5a7c06b0fc6d.png",
"level": "L2",
"sortOrder": 1,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 1008002,
"name": "布艺软装",
"keywords": "",
"desc": "各种风格软装装点你的家",
"pid": 1005000,
"iconUrl": "http://yanxuan.nosdn.127.net/8bbcd7de60a678846664af998f57e71c.png",
"picUrl": "http://yanxuan.nosdn.127.net/2e2fb4f2856a021bbcd1b4c8400f2b06.png",
"level": "L2",
"sortOrder": 6,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 1008008,
"name": "被枕",
"keywords": "",
"desc": "守护你的睡眠时光",
"pid": 1005000,
"iconUrl": "http://yanxuan.nosdn.127.net/927bc33f7ae2895dd6c11cf91f5e3228.png",
"picUrl": "http://yanxuan.nosdn.127.net/b43ef7cececebe6292d2f7f590522e05.png",
"level": "L2",
"sortOrder": 2,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 1008009,
"name": "床品件套",
"keywords": "",
"desc": "MUJI等品牌制造商出品",
"pid": 1005000,
"iconUrl": "http://yanxuan.nosdn.127.net/243e5bf327a87217ad1f54592f0176ec.png",
"picUrl": "http://yanxuan.nosdn.127.net/81f671bd36bce05d5f57827e5c88dd1b.png",
"level": "L2",
"sortOrder": 4,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 1008015,
"name": "糕点",
"keywords": "",
"desc": "四季糕点,用心烘焙",
"pid": 1005002,
"iconUrl": "http://yanxuan.nosdn.127.net/93168242df456b5f7bf3c89653b3db76.png",
"picUrl": "http://yanxuan.nosdn.127.net/66ea1d6ad602a8e441af7cada93bdc7a.png",
"level": "L2",
"sortOrder": 1,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 1012003,
"name": "文具",
"keywords": "",
"desc": "找回书写的力量",
"pid": 1012000,
"iconUrl": "http://yanxuan.nosdn.127.net/e1743239e41ca9af76875aedc73be7f0.png",
"picUrl": "http://yanxuan.nosdn.127.net/e074795f61a83292d0f20eb7d124e2ac.png",
"level": "L2",
"sortOrder": 1,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 1020003,
"name": "服饰",
"keywords": "",
"desc": "萌宝穿搭,柔软舒适触感",
"pid": 1011000,
"iconUrl": "http://yanxuan.nosdn.127.net/4e50f3c4e4d0a64cd0ad14cfc0b6bd17.png",
"picUrl": "http://yanxuan.nosdn.127.net/004f5f96df4aeb0645abbd70c0637239.png",
"level": "L2",
"sortOrder": 1,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.4.2 商品详情
应用场景
商品详情
接口链接
GET /wx/goods/detail
请求参数
id: 商品ID,例如id=1152008
响应内容
{
"errno": 0,
"data": {
"specificationList": [
{
"name": "规格",
"valueList": [
{
"id": 231,
"goodsId": 1152008,
"specification": "规格",
"value": "标准",
"picUrl": "",
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
}
]
}
],
"groupon": [],
"issue": [
{
"id": 1,
"question": "购买运费如何收取?",
"answer": "单笔订单金额(不含运费)满88元免邮费;不满88元,每单收取10元运费。\n(港澳台地区需满",
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 2,
"question": "使用什么快递发货?",
"answer": "严选默认使用顺丰快递发货(个别商品使用其他快递),配送范围覆盖全国大部分地区(港澳台地区除",
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 3,
"question": "如何申请退货?",
"answer": "1.自收到商品之日起30日内,顾客可申请无忧退货,退款将原路返还,不同的银行处理时间不同,",
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 4,
"question": "如何开具发票?",
"answer": "1.如需开具普通发票,请在下单时选择“我要开发票”并填写相关信息(APP仅限2.4.0及以",
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
}
],
"userHasCollect": 0,
"shareImage": "",
"comment": {
"data": [],
"count": 0
},
"attribute": [],
"brand": {},
"productList": [
{
"id": 232,
"goodsId": 1152008,
"specifications": [
"标准"
],
"price": 29.00,
"number": 100,
"url": "http://yanxuan.nosdn.127.net/203cb83d93606865e3ddde57b69b9e9a.png",
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
}
],
"info": {
"id": 1152008,
"goodsSn": "1152008",
"name": "魔兽世界 部落 护腕 一只",
"categoryId": 1032000,
"brandId": 0,
"gallery": [
"http://yanxuan.nosdn.127.net/46bcddbc57e70bf5f36bdff9c9195c65.png",
"http://yanxuan.nosdn.127.net/46bcddbc57e70bf5f36bdff9c9195c65.png",
"http://yanxuan.nosdn.127.net/46bcddbc57e70bf5f36bdff9c9195c65.png",
"http://yanxuan.nosdn.127.net/46bcddbc57e70bf5f36bdff9c9195c65.png",
"http://yanxuan.nosdn.127.net/46bcddbc57e70bf5f36bdff9c9195c65.png"
],
"keywords": "",
"brief": "吸汗、舒适、弹性、防护、耐用",
"isOnSale": true,
"sortOrder": 7,
"picUrl": "http://yanxuan.nosdn.127.net/203cb83d93606865e3ddde57b69b9e9a.png",
"shareUrl": "",
"isNew": false,
"isHot": true,
"unit": "件",
"counterPrice": 49.00,
"retailPrice": 29.00,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false,
"detail": ""
}
},
"errmsg": "成功"
}
错误码
略
#### 2.4.3 商品推荐
应用场景
针对某个商品推荐其他商品
接口链接
GET /wx/goods/related
请求参数
id: 商品ID,例如id=1152008
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应内容
{
"errno": 0,
"data": {
"total": 8,
"pages": 2,
"limit": 6,
"page": 1,
"list": [
{
"id": 1152004,
"name": "魔兽世界 蛋盾包 双肩包",
"brief": "伊利丹掉落,挤地铁神器",
"picUrl": "http://yanxuan.nosdn.127.net/8c93cef435d888bd79833777df1cd0c2.png",
"isNew": false,
"isHot": false,
"counterPrice": 419.00,
"retailPrice": 399.00
},
{
"id": 1152008,
"name": "魔兽世界 部落 护腕 一只",
"brief": "吸汗、舒适、弹性、防护、耐用",
"picUrl": "http://yanxuan.nosdn.127.net/203cb83d93606865e3ddde57b69b9e9a.png",
"isNew": false,
"isHot": true,
"counterPrice": 49.00,
"retailPrice": 29.00
},
{
"id": 1152009,
"name": "魔兽世界 联盟 护腕 一只",
"brief": "吸汗、舒适、弹性、防护、耐用",
"picUrl": "http://yanxuan.nosdn.127.net/ae6d41117717387b82dcaf1dfce0cd97.png",
"isNew": false,
"isHot": true,
"counterPrice": 49.00,
"retailPrice": 29.00
},
{
"id": 1152031,
"name": "魔兽世界-伊利丹颈枕眼罩套装",
"brief": "差旅好伴侣",
"picUrl": "http://yanxuan.nosdn.127.net/fd6e78a397bd9e9804116a36f0270b0a.png",
"isNew": false,
"isHot": true,
"counterPrice": 119.00,
"retailPrice": 99.00
},
{
"id": 1152095,
"name": "魔兽世界 联盟·暴风城 堡垒收纳盒",
"brief": "桌面整理神器",
"picUrl": "http://yanxuan.nosdn.127.net/c86b49f635fa141decebabbd0966a6ef.png",
"isNew": false,
"isHot": false,
"counterPrice": 519.00,
"retailPrice": 499.00
},
{
"id": 1152097,
"name": "魔兽世界 雷霆之怒逐风者的祝福之剑 雨伞",
"brief": "炫酷装备,可以背的雨伞",
"picUrl": "http://yanxuan.nosdn.127.net/532836444ae5eaec40b5810ca4f9b1e6.png",
"isNew": false,
"isHot": false,
"counterPrice": 419.00,
"retailPrice": 399.00
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.4.4 商品分类
应用场景
针对某个商品推荐其他商品
接口链接
GET /wx/goods/related
请求参数
响应内容
错误码
#### 2.4.5 在售商品总数
应用场景
在售商品总数
接口链接
GET /wx/goods/count
请求参数
无
响应内容
{
"errno": 0,
"data": 238,
"errmsg": "成功"
}
错误码
无
### 2.5 购物车服务
#### 2.5.1 用户购物车
应用场景
用户购物车
接口链接
请求参数
无
响应内容
错误码
略
### 2.6 订单服务
#### 2.6.1 订单列表
应用场景
订单列表
接口链接
GET /wx/order/list
请求参数
showType: 订单类型,0则全部,1则待付款,2则待发货,3则待收货,4则代评价
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应结果
{
"errno": 0,
"data": {
"total": 1,
"pages": 1,
"limit": 10,
"page": 1,
"list": [
{
"orderStatusText": "未付款",
"isGroupin": false,
"orderSn": "20190509607545",
"actualPrice": 3989.00,
"goodsList": [
{
"number": 1,
"picUrl": "http://yanxuan.nosdn.127.net/c5be2604c0e4186a4e7079feeb742cee.png",
"id": 3,
"goodsName": "云端沙发组合",
"specifications": [
"标准"
]
}
],
"id": 3,
"handleOption": {
"cancel": true,
"delete": false,
"pay": true,
"comment": false,
"confirm": false,
"refund": false,
"rebuy": false
}
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.6.2 订单详情
应用场景
订单详情
接口链接
GET /wx/order/detail
请求参数
orderId: 订单ID
响应结果
{
"errno": 0,
"data": {
"orderInfo": {
"consignee": "d",
"address": "北京市市辖区东城区 ddd",
"addTime": "2019-05-09 15:30:29",
"orderSn": "20190509607545",
"actualPrice": 3989.00,
"mobile": "13811111111",
"orderStatusText": "未付款",
"goodsPrice": 3999.00,
"couponPrice": 10.00,
"id": 3,
"freightPrice": 0.00,
"handleOption": {
"cancel": true,
"delete": false,
"pay": true,
"comment": false,
"confirm": false,
"refund": false,
"rebuy": false
}
},
"orderGoods": [
{
"id": 3,
"orderId": 3,
"goodsId": 1109008,
"goodsName": "云端沙发组合",
"goodsSn": "1109008",
"productId": 140,
"number": 1,
"price": 3999.00,
"specifications": [
"标准"
],
"picUrl": "http://yanxuan.nosdn.127.net/c5be2604c0e4186a4e7079feeb742cee.png",
"comment": 0,
"addTime": "2019-05-09 15:30:29",
"updateTime": "2019-05-09 15:30:29",
"deleted": false
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.6.3 创建订单
应用场景
创建新订单
接口链接
POST /wx/order/submit
请求参数
{
"cartId": 0,
"addressId": 3,
"couponId": -1,
"message": "",
"grouponRulesId": 0,
"grouponLinkId": 0
}
响应结果
{
"errno": 0,
"data": {
"orderId": 4
},
"errmsg": "成功"
}
错误码
略
#### 2.6.4 取消订单
应用场景
取消订单
接口链接
POST /wx/order/cancel
请求参数
orderId: 订单ID
响应结果
{
"errno": 0,
"errmsg": "成功"
}
错误码
略
#### 2.6.5 微信预支付交易单
应用场景
订单的微信预支付交易单
接口链接
POST /wx/order/prepay
说明
具体微信支付交互流程和预支付使用方式,见官方文档: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1
请求参数
orderId: 订单ID
响应结果
{
errno: 0,
errmsg: "成功",
data: {
appId: 'xxx',
timeStamp: 'xxx',
nonceStr: 'xxx',
packageValue: 'xxx',
signType: 'xxx',
paySign: 'xxx'
}
}
错误码
略
#### 2.6.6 确认收货
应用场景
订单确认收货
接口链接
POST /wx/order/confirm
请求参数
orderId: 订单ID
响应结果
{
"errno": 0,
"errmsg": "成功"
}
错误码
略
#### 2.6.7 订单删除
应用场景
删除订单记录
接口链接
POST /wx/order/delete
请求参数
orderId: 订单ID
响应结果
{
"errno": 0,
"errmsg": "成功"
}
错误码
略
#### 2.6.8 订单退款
应用场景
订单已经支付但是商家未发货,用户可以点击退款按钮申请退款取消订单。
说明
退款请求发送以后,不会自动退款,仅仅是后端设置退款请求记录。
管理员在管理后台看到退款请求以后会手动退款或者拒绝退款。
接口链接
POST /wx/order/refund
请求参数
orderId: 订单ID
响应结果
{
"errno": 0,
"errmsg": "成功"
}
错误码
略
#### 2.6.9 待评价商品
应用场景
用户确认收货以后,可以待评价的订单商品。
接口链接
GET /wx/order/goods
请求参数
orderId: 订单ID
goodsId: 商品ID
响应结果
{
"errno": 0,
"data": {
"id": 4,
"orderId": 4,
"goodsId": 1109008,
"goodsName": "云端沙发组合",
"goodsSn": "1109008",
"productId": 140,
"number": 1,
"price": 3999.00,
"specifications": [
"标准"
],
"picUrl": "http://yanxuan.nosdn.127.net/c5be2604c0e4186a4e7079feeb742cee.png",
"comment": 0,
"addTime": "2019-05-09 17:06:54",
"updateTime": "2019-05-09 17:06:54",
"deleted": false
},
"errmsg": "成功"
}
错误码
略
#### 2.6.10 订单评价
应用场景
订单评价
接口链接
POST /wx/order/comment
请求参数
orderGoodsId: 订单商品ID
content: 评价内容
star: 评分,1分至5分
hasPicture: 是否有评价图片
picUrls: 评价图片列表
例如
{
"orderGoodsId": 4,
"content": "不错",
"star": 5,
"hasPicture": true,
"picUrls": []
}
响应结果
{
"errno": 0,
"errmsg": "成功"
}
错误码
略
### 2.7 会员服务
### 2.8 收货地址服务
#### 2.8.1 收货地址列表
应用场景
用户收货地址列表
接口链接
GET /wx/address/list
请求参数
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应结果
{
"errno": 0,
"data": {
"total": 1,
"pages": 1,
"limit": 1,
"page": 1,
"list": [
{
"id": 3,
"name": "d",
"userId": 2,
"province": "北京市",
"city": "市辖区",
"county": "东城区",
"addressDetail": "ddd",
"areaCode": "110101",
"tel": "13811111111",
"isDefault": true,
"addTime": "2019-05-06 14:17:32",
"updateTime": "2019-05-06 14:17:32",
"deleted": false
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.8.2 收货地址详情
应用场景
请求用户的收货地址详情
接口链接
GET /wx/address/detail
请求参数
id: 收货地址ID
响应结果
{
errno: 0,
errmsg: "成功",,
data: {
id: 收货地址ID,
name: 收货人,
tel: 手机号
province: 省级行政区域,
city: 市级行政区域,
county: 区级行政区域,
addressDetail: 具体地址,
areaCode: 地址编码,
postalCode: 邮政编码
isDefault: 是否默认
}
}
错误码
略
#### 2.8.3 保存收货地址
应用场景
添加或者更新用户收货地址
接口链接
POST /wx/address/save
请求参数
id: 收货地址ID,如果是0则是添加,否则是更新
name: 收货人,
tel: 手机号
province: 省级行政区域,
city: 市级行政区域,
county: 区级行政区域,
addressDetail: 具体地址,
areaCode: 地址编码,
postalCode: 邮政编码
isDefault: 是否默认
例如
{
"id": 0,
"name": "xxx",
"tel": "13811111111",
"province": "北京市",
"city": "市辖区",
"county": "东城区",
"areaCode": "110101",
"addressDetail": "dddd",
"isDefault": true
}
响应结果
{
errno: 0,
errmsg: "成功",,
data: 3
}
错误码
略
#### 2.8.4 删除收货地址
应用场景
删除用户的某个收货地址
接口链接
POST /wx/address/delete
请求参数
id: 收货地址ID
响应结果
{
errno: 0,
errmsg: "成功"
}
错误码
略
### 2.9 品牌商服务
#### 2.9.1 品牌商列表
应用场景
访问品牌商列表信息
接口链接
GET /wx/brand/list
请求参数
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应内容
{
"errno": 0,
"data": {
"total": 49,
"pages": 5,
"limit": 10,
"page": 1,
"list": [
{
"id": 1024000,
"name": "WMF制造商",
"desc": "严选找寻德国百年高端厨具WMF的制造商,\n选择拥有14年经验的不锈钢生产工厂,\n为你甄选事半功倍的优质厨具。",
"picUrl": "http://yanxuan.nosdn.127.net/2018e9ac91ec37d9aaf437a1fd5d7070.png",
"floorPrice": 9.90
},
{
"id": 1024001,
"name": "OBH制造商",
"desc": "严选寻找OBH品牌的制造商,打造精致厨具,\n韩国独资工厂制造,严格质检,品质雕琢\n力求为消费者带来全新的烹饪体验。",
"picUrl": "http://yanxuan.nosdn.127.net/bf3499ac17a11ffb9bb7caa47ebef2dd.png",
"floorPrice": 39.00
},
{
"id": 1024003,
"name": "Stoneline制造商",
"desc": "严选找寻德国经典品牌Stoneline的制造商,\n追踪工艺,考量细节,亲自试用,\n为你甄选出最合心意的锅具和陶瓷刀,下厨如神。",
"picUrl": "http://yanxuan.nosdn.127.net/3a44ae7db86f3f9b6e542720c54cc349.png",
"floorPrice": 9.90
},
{
"id": 1024006,
"name": "KitchenAid制造商",
"desc": "严选寻访KitchenAid品牌的制造商,\n采用德国LFGB认证食品级专用不锈钢,\n欧式简约设计,可靠安心,尽享下厨乐趣。",
"picUrl": "http://yanxuan.nosdn.127.net/e11385bf29d1b3949435b80fcd000948.png",
"floorPrice": 98.00
},
{
"id": 1034001,
"name": "Alexander McQueen制造商",
"desc": "为制造精致实用的高品质包包,\n严选团队选择Alexander McQueen制造商,\n严格筛选,带来轻奢优雅体验。",
"picUrl": "http://yanxuan.nosdn.127.net/db7ee9667d84cbce573688297586699c.jpg",
"floorPrice": 69.00
},
{
"id": 1023000,
"name": "PetitBateau小帆船制造商",
"desc": "为打造适合宝宝的婴童服装,\n严选团队寻找PetitBateau小帆船的品牌制造商,\n无荧光剂,国家A类标准,让宝宝穿的放心。",
"picUrl": "http://yanxuan.nosdn.127.net/1a11438598f1bb52b1741e123b523cb5.jpg",
"floorPrice": 36.00
},
{
"id": 1001000,
"name": "MUJI制造商",
"desc": "严选精选了MUJI制造商和生产原料,\n用几乎零利润的价格,剔除品牌溢价,\n让用户享受原品牌的品质生活。",
"picUrl": "http://yanxuan.nosdn.127.net/1541445967645114dd75f6b0edc4762d.png",
"floorPrice": 12.90
},
{
"id": 1001002,
"name": "内野制造商",
"desc": "严选从世界各地挑选毛巾,最终选择了为日本内野代工的工厂,追求毛巾的柔软度与功能性。品质比肩商场几百元的毛巾。",
"picUrl": "http://yanxuan.nosdn.127.net/8ca3ce091504f8aa1fba3fdbb7a6e351.png",
"floorPrice": 29.00
},
{
"id": 1001003,
"name": "Adidas制造商",
"desc": "严选找到为Adidas等品牌制造商,\n选取优质原材料,与厂方一起设计,\n为你提供好的理想的运动装备。",
"picUrl": "http://yanxuan.nosdn.127.net/335334d0deaff6dc3376334822ab3a2f.png",
"floorPrice": 49.00
},
{
"id": 1033003,
"name": "Armani制造商",
"desc": "严选团队携手国际标准化专业生产厂家,\n厂家长期为Armani、Alexander wang等知名品牌代工,\n专业进口设备,精密质量把控,精于品质居家体验。",
"picUrl": "http://yanxuan.nosdn.127.net/981e06f0f46f5f1f041d7de3dd3202e6.jpg",
"floorPrice": 199.00
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.9.2 品牌商详情
应用场景
访问单个品牌商详情信息
接口链接
GET /wx/brand/detail
请求参数
id: 品牌商ID,例如1001020
响应内容
{
"errno": 0,
"data": {
"id": 1001020,
"name": "Ralph Lauren制造商",
"desc": "我们与Ralph Lauren Home的制造商成功接洽,掌握先进的生产设备,传承品牌工艺和工序。追求生活品质的你,值得拥有。",
"picUrl": "http://yanxuan.nosdn.127.net/9df78eb751eae2546bd3ee7e61c9b854.png",
"sortOrder": 20,
"floorPrice": 29.00,
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
"errmsg": "成功"
}
错误码
略
### 2.10 收藏服务
#### 2.10.1 收藏列表
应用场景
收藏列表
接口链接
GET /wx/collect/list
请求参数
type: 收藏类型,如果是0则是商品收藏,如果是1则是专题收藏
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应内容
{
"errno": 0,
"data": {
"total": 2,
"pages": 1,
"limit": 10,
"page": 1,
"list": [
{
"brief": "酥脆奶香,甜酸回味",
"picUrl": "http://yanxuan.nosdn.127.net/767b370d07f3973500db54900bcbd2a7.png",
"valueId": 1116011,
"name": "蔓越莓曲奇 200克",
"id": 3,
"type": 0,
"retailPrice": 36.00
},
{
"brief": "MUJI供应商携手打造",
"picUrl": "http://yanxuan.nosdn.127.net/c5be2604c0e4186a4e7079feeb742cee.png",
"valueId": 1109008,
"name": "云端沙发组合",
"id": 2,
"type": 0,
"retailPrice": 3999.00
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.10.2 收藏添加或删除
应用场景
用户收藏添加或删除
说明
如果用户已经收藏,则请求API会删除已收藏商品或专题;
如果用户未收藏,则请求API会添加新的商品或专题收藏记录。
接口链接
POST /wx/collect/addordelete
请求参数
type: 收藏类型,如果是0则是商品收藏,如果是1则是专题收藏
valueId: 收藏对象ID,如果type=0则设置商品ID,如果type=1则设置专题ID
例如
{
"type": 0,
"valueId": 1116011
}
响应内容
错误码
略
### 2.11 评论服务
#### 2.11.1 评论数量
应用场景
某个商品或者专题的评论数量,包括总的评论数量和包含图片的评论数量
接口链接
GET /wx/comment/count
请求参数
type: 评论类型,如果是0则是商品评论,如果是1则是专题评论
valueId: 评论对象ID,如果type=0,则设置商品ID,如果type=0,则设置专题ID
响应内容
{
"errno": 0,
"data": {
"hasPicCount": 34,
"allCount": 96
},
"errmsg": "成功"
}
错误码
无
#### 2.11.2 评论列表
应用场景
某个商品或者专题的评论列表
接口链接
GET /wx/comment/list
请求参数
valueId=1181000&type=0&limit=20&page=1&showType=0
type: 评论类型,如果是0则是商品评论,如果是1则是专题评论
valueId: 评论对象ID,如果type=0,则设置商品ID,如果type=0,则设置专题ID
showType: 评论显示类型,如果是0则是所有评论,如果是1则是包含图片的评论
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应内容
{
"errno": 0,
"data": {
"total": 96,
"pages": 20,
"limit": 5,
"page": 1,
"list": [
{
"userInfo": {
"nickName": "user123",
"avatarUrl": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
},
"addTime": "2018-02-01 00:00:00",
"picList": [
"https://yanxuan.nosdn.127.net/218783173f303ec6d8766810951d0790.jpg"
],
"content": "布料很厚实,触感不错,洗过之后不缩水不掉色"
},
{
"userInfo": {
"nickName": "user123",
"avatarUrl": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
},
"addTime": "2018-02-01 00:00:00",
"picList": [
"https://yanxuan.nosdn.127.net/33978a0d6f56d94c45e4fc594b4b8606.jpg"
],
"content": "料子很舒服,凉凉的,配合蚕丝被,夏天很凉快~"
},
{
"userInfo": {
"nickName": "user123",
"avatarUrl": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
},
"addTime": "2018-02-01 00:00:00",
"picList": [
"https://yanxuan.nosdn.127.net/d3975d1b6d88e9f9d762cd9a879d1a14.jpg"
],
"content": "一直喜欢粗布的床上用品。冬暖夏凉。这套看起来非常漂亮。实际感觉有点粗布的感觉。很好!"
},
{
"userInfo": {
"nickName": "user123",
"avatarUrl": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
},
"addTime": "2018-02-01 00:00:00",
"picList": [
"https://yanxuan.nosdn.127.net/5fe1121396458cfe0dc1b25ec86f7ff9.jpg",
"https://yanxuan.nosdn.127.net/d5a55abd6ced5c811d775b04929aaabc.jpg",
"https://yanxuan.nosdn.127.net/f1764d820ba6ddaf51d297e3cf3826cd.jpg"
],
"content": "太好了,舒服的不得了,腰,腿,脊柱,头,颈椎!\n无一处不舒服,真没想到这么优惠!\n搬了新家还要买!"
},
{
"userInfo": {
"nickName": "user123",
"avatarUrl": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
},
"addTime": "2018-02-01 00:00:00",
"picList": [
"https://yanxuan.nosdn.127.net/f753f91430dfb56f574c737d4b2fde46.jpg"
],
"content": "抱着试试的态度 先买了小的 果然感觉很舒服 深陷其中 把自己全身心都给了它 第二个床垫已经在路上"
}
]
},
"errmsg": "成功"
}
错误码
无
#### 2.11.3 发表评论
应用场景
针对某个商品或者专题的发表评论
接口链接
请求参数
响应内容
错误码
略
### 2.12 优惠券服务
#### 2.12.1 优惠券列表
应用场景
优惠券列表
接口链接
GET /wx/coupon/list
请求参数
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应内容
{
"errno": 0,
"data": {
"total": 2,
"pages": 1,
"limit": 10,
"page": 1,
"list": [
{
"id": 1,
"name": "限时满减券",
"desc": "全场通用",
"tag": "无限制",
"discount": 5.00,
"min": 99.00,
"days": 10
},
{
"id": 2,
"name": "限时满减券",
"desc": "全场通用",
"tag": "无限制",
"discount": 10.00,
"min": 99.00,
"days": 10
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.12.2 用户优惠券列表
应用场景
用户优惠券列表
接口链接
GET /wx/coupon/mylist
请求参数
status: 优惠券状态,如果0则未使用,如果1则已使用,如果2则已过期
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应内容
{
"errno": 0,
"data": {
"total": 2,
"pages": 1,
"limit": 10,
"page": 1,
"list": [
{
"id": 1,
"name": "限时满减券",
"desc": "全场通用",
"tag": "无限制",
"min": "99.00",
"discount": "5.00",
"startTime": "2019-05-06 16:21:38",
"endTime": "2019-05-16 16:21:38"
},
{
"id": 3,
"name": "新用户优惠券",
"desc": "全场通用",
"tag": "无限制",
"min": "99.00",
"discount": "10.00",
"startTime": "2019-05-06 12:30:06",
"endTime": "2019-05-16 12:30:06"
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.12.3 下单可用优惠券
应用场景
当前购物车下单商品订单可用优惠券
接口链接
GET /wx/coupon/selectlist
请求参数
cartId: 购物车ID,如果0则是购物车商品,如果非0则是立即单一商品
grouponRulesId: 团购规则ID,如果是团购商品则需要设置具体团购规则ID
响应内容
{
"errno": 0,
"data": {
"total": 1,
"pages": 1,
"limit": 1,
"page": 1,
"list": [
{
"id": 2,
"name": "限时满减券",
"desc": "全场通用",
"tag": "无限制",
"min": "99.00",
"discount": "10.00",
"startTime": "2019-05-09 15:27:29",
"endTime": "2019-05-19 15:27:29"
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.12.4 优惠券领取
应用场景
领取优惠券
接口链接
POST /wx/coupon/receive
请求参数
couponId: 可领取优惠券ID
例如
{
"couponId": 2
}
响应内容
{
"errno": 0,
"errmsg": "成功"
}
错误码
略
#### 2.12.5 优惠券兑换
应用场景
通过兑换码兑换优惠券
接口链接
POST /wx/coupon/exchange
请求参数
code: 优惠券兑换码
响应内容
{
"errno": 0,
"errmsg": "成功"
}
错误码
略
### 2.13 反馈服务
### 2.14 足迹服务
#### 2.14.1 用户足迹列表
应用场景
用户足迹列表
接口链接
GET /wx/footprint/list
请求参数
page: 请求页码
limit: 每一页数量
响应内容
{
"errno": 0,
"data": {
"total": 22,
"pages": 6,
"limit": 4,
"page": 1,
"list": [
{
"brief": "酥脆奶香,甜酸回味",
"picUrl": "http://yanxuan.nosdn.127.net/767b370d07f3973500db54900bcbd2a7.png",
"addTime": "2019-05-09 10:10:01",
"goodsId": 1116011,
"name": "蔓越莓曲奇 200克",
"id": 22,
"retailPrice": 36.00
},
{
"brief": "MUJI供应商携手打造",
"picUrl": "http://yanxuan.nosdn.127.net/c5be2604c0e4186a4e7079feeb742cee.png",
"addTime": "2019-05-09 10:09:49",
"goodsId": 1109008,
"name": "云端沙发组合",
"id": 21,
"retailPrice": 3999.00
},
{
"brief": "酥脆奶香,甜酸回味",
"picUrl": "http://yanxuan.nosdn.127.net/767b370d07f3973500db54900bcbd2a7.png",
"addTime": "2019-05-08 22:40:55",
"goodsId": 1116011,
"name": "蔓越莓曲奇 200克",
"id": 20,
"retailPrice": 36.00
},
{
"brief": "MUJI供应商携手打造",
"picUrl": "http://yanxuan.nosdn.127.net/c5be2604c0e4186a4e7079feeb742cee.png",
"addTime": "2019-05-07 14:35:41",
"goodsId": 1109008,
"name": "云端沙发组合",
"id": 19,
"retailPrice": 3999.00
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.14.2 用户足迹删除
应用场景
用户足迹删除
接口链接
POST /wx/footprint/delete
请求参数
id: 用户足迹ID
响应内容
{
"errno": 0,
"errmsg": "成功"
}
错误码
略
### 2.15 团购服务
注意
> 团购业务还不完善
#### 2.15.1 团购商品列表
应用场景
参加团购的商品列表信息
接口链接
请求参数
响应内容
错误码
略
#### 2.15.2 团购活动详情
应用场景
团购活动详情
接口链接
请求参数
响应内容
错误码
略
#### 2.15.3 参加团购
应用场景
参加团购的商品列表信息
接口链接
请求参数
响应内容
错误码
略
#### 2.15.4 用户参团列表
应用场景
用户参团列表
接口链接
请求参数
响应内容
错误码
略
### 2.16 帮助服务
#### 2.16.1 帮助列表
应用场景
帮助列表
接口链接
GET /wx/issue/list
请求参数
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应内容
{
"errno": 0,
"data": {
"total": 4,
"pages": 1,
"limit": 10,
"page": 1,
"list": [
{
"id": 1,
"question": "购买运费如何收取?",
"answer": "单笔订单金额(不含运费)满88元免邮费;不满88元,每单收取10元运费。\n(港澳台地区需满",
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 2,
"question": "使用什么快递发货?",
"answer": "严选默认使用顺丰快递发货(个别商品使用其他快递),配送范围覆盖全国大部分地区(港澳台地区除",
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 3,
"question": "如何申请退货?",
"answer": "1.自收到商品之日起30日内,顾客可申请无忧退货,退款将原路返还,不同的银行处理时间不同,",
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
},
{
"id": 4,
"question": "如何开具发票?",
"answer": "1.如需开具普通发票,请在下单时选择“我要开发票”并填写相关信息(APP仅限2.4.0及以",
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false
}
]
},
"errmsg": "成功"
}
错误码
无
### 2.17 搜索服务
### 2.18 专题服务
#### 2.18.1 专题列表
应用场景
访问专题列表信息
接口链接
GET /wx/topic/list
请求参数
page: 请求页码
limit: 每一页数量
sort: 排序字段
order: 升序降序
响应内容
{
"errno": 0,
"data": {
"total": 20,
"pages": 2,
"limit": 10,
"page": 1,
"list": [
{
"id": 264,
"title": "设计师们推荐的应季好物",
"subtitle": "原创设计春款系列上新",
"price": 29.90,
"readCount": "77.7k",
"picUrl": "https://yanxuan.nosdn.127.net/14918201901050274.jpg"
},
{
"id": 266,
"title": "一条丝巾就能提升时髦度",
"subtitle": "不知道大家对去年G20时,严选与国礼制造商一起推出的《凤凰于飞》等几款丝巾是否还...",
"price": 0.00,
"readCount": "35.0k",
"picUrl": "https://yanxuan.nosdn.127.net/14919007135160213.jpg"
},
{
"id": 268,
"title": "米饭好吃的秘诀:会呼吸的锅",
"subtitle": "今年1月份,我们联系到了日本伊贺地区的长谷园,那里有着180年伊贺烧历史的窑厂。...",
"price": 0.00,
"readCount": "33.3k",
"picUrl": "https://yanxuan.nosdn.127.net/14920623353130483.jpg"
},
{
"id": 271,
"title": "选式新懒人",
"subtitle": "懒出格调,懒出好生活。",
"price": 15.00,
"readCount": "57.7k",
"picUrl": "https://yanxuan.nosdn.127.net/14924199099661697.jpg"
},
{
"id": 272,
"title": "料理也要精细简单",
"subtitle": "享受天然的味道,日子每天都好新鲜",
"price": 69.00,
"readCount": "125.6k",
"picUrl": "https://yanxuan.nosdn.127.net/14925200530030186.jpg"
},
{
"id": 274,
"title": "没有软木拖,怎么过夏天",
"subtitle": "刚入四月,杭州的气温就已升高至30度。店庆时买了软木拖的用户,陆续发回评价说,很...",
"price": 0.00,
"readCount": "46.4k",
"picUrl": "https://yanxuan.nosdn.127.net/14925822213780237.jpg"
},
{
"id": 277,
"title": "治愈生活的满怀柔软",
"subtitle": "太鼓抱枕的上架历程,是从失踪开始的。由于表面的绒感,最初它被安排在秋冬季上架。某...",
"price": 0.00,
"readCount": "19.6k",
"picUrl": "https://yanxuan.nosdn.127.net/14926737925770587.jpg"
},
{
"id": 281,
"title": "条纹新风尚",
"subtitle": "经典百搭,时尚线条",
"price": 29.00,
"readCount": "76.5k",
"picUrl": "https://yanxuan.nosdn.127.net/14926859849200826.jpg"
},
{
"id": 282,
"title": "成就一室笋香",
"subtitle": "三石哥办公室常备小食推荐",
"price": 12.00,
"readCount": "40.9k",
"picUrl": "https://yanxuan.nosdn.127.net/14927695046601069.jpg"
},
{
"id": 283,
"title": "孩子成长中少不了的一双鞋",
"subtitle": "说起毛毛虫鞋,好处实在太多了,作为一个2岁孩子的宝妈选品员,按捺不住想告诉大家,...",
"price": 0.00,
"readCount": "42.5k",
"picUrl": "https://yanxuan.nosdn.127.net/14927748974441080.jpg"
}
]
},
"errmsg": "成功"
}
错误码
略
#### 2.18.2 专题详情
应用场景
单个专题详情信息
接口链接
GET /wx/topic/detail
请求参数
id: 专题ID,例如 id=264
响应内容
{
"errno": 0,
"data": {
"topic": {
"id": 264,
"title": "设计师们推荐的应季好物",
"subtitle": "原创设计春款系列上新",
"price": 29.90,
"readCount": "77.7k",
"picUrl": "https://yanxuan.nosdn.127.net/14918201901050274.jpg",
"sortOrder": 0,
"goods": [],
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false,
"content": ""
},
"goods": []
},
"errmsg": "成功"
}
错误码
略
#### 2.18.3 专题推荐
应用场景
基于某个专题推荐其他专题
接口链接
GET /wx/topic/related
请求参数
id: 专题ID,例如 id=264
响应内容
{
"errno": 0,
"data": {
"total": 19,
"pages": 5,
"limit": 4,
"page": 1,
"list": [
{
"id": 266,
"title": "一条丝巾就能提升时髦度",
"subtitle": "不知道大家对去年G20时,严选与国礼制造商一起推出的《凤凰于飞》等几款丝巾是否还...",
"price": 0.00,
"readCount": "35.0k",
"picUrl": "https://yanxuan.nosdn.127.net/14919007135160213.jpg",
"sortOrder": 0,
"goods": [],
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false,
"content": "\u003cimg src\u003d\"//yanxuan.nosdn.127.net/75c55a13fde5eb2bc2dd6813b4c565cc.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/e27e1de2b271a28a21c10213b9df7e95.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/9d413d1d28f753cb19096b533d53418d.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/64b0f2f350969e9818a3b6c43c217325.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/a668e6ae7f1fa45565c1eac221787570.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/0d4004e19728f2707f08f4be79bbc774.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/79ee021bbe97de7ecda691de6787241f.jpg\"\u003e"
},
{
"id": 268,
"title": "米饭好吃的秘诀:会呼吸的锅",
"subtitle": "今年1月份,我们联系到了日本伊贺地区的长谷园,那里有着180年伊贺烧历史的窑厂。...",
"price": 0.00,
"readCount": "33.3k",
"picUrl": "https://yanxuan.nosdn.127.net/14920623353130483.jpg",
"sortOrder": 0,
"goods": [],
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false,
"content": "\u003cimg src\u003d\"//yanxuan.nosdn.127.net/75c55a13fde5eb2bc2dd6813b4c565cc.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/e27e1de2b271a28a21c10213b9df7e95.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/9d413d1d28f753cb19096b533d53418d.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/64b0f2f350969e9818a3b6c43c217325.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/a668e6ae7f1fa45565c1eac221787570.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/0d4004e19728f2707f08f4be79bbc774.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/79ee021bbe97de7ecda691de6787241f.jpg\"\u003e"
},
{
"id": 271,
"title": "选式新懒人",
"subtitle": "懒出格调,懒出好生活。",
"price": 15.00,
"readCount": "57.7k",
"picUrl": "https://yanxuan.nosdn.127.net/14924199099661697.jpg",
"sortOrder": 0,
"goods": [],
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false,
"content": "\u003cimg src\u003d\"//yanxuan.nosdn.127.net/75c55a13fde5eb2bc2dd6813b4c565cc.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/e27e1de2b271a28a21c10213b9df7e95.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/9d413d1d28f753cb19096b533d53418d.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/64b0f2f350969e9818a3b6c43c217325.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/a668e6ae7f1fa45565c1eac221787570.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/0d4004e19728f2707f08f4be79bbc774.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/79ee021bbe97de7ecda691de6787241f.jpg\"\u003e"
},
{
"id": 272,
"title": "料理也要精细简单",
"subtitle": "享受天然的味道,日子每天都好新鲜",
"price": 69.00,
"readCount": "125.6k",
"picUrl": "https://yanxuan.nosdn.127.net/14925200530030186.jpg",
"sortOrder": 0,
"goods": [],
"addTime": "2018-02-01 00:00:00",
"updateTime": "2018-02-01 00:00:00",
"deleted": false,
"content": "\u003cimg src\u003d\"//yanxuan.nosdn.127.net/75c55a13fde5eb2bc2dd6813b4c565cc.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/e27e1de2b271a28a21c10213b9df7e95.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/9d413d1d28f753cb19096b533d53418d.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/64b0f2f350969e9818a3b6c43c217325.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/a668e6ae7f1fa45565c1eac221787570.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/0d4004e19728f2707f08f4be79bbc774.jpg\"\u003e\n \u003cimg src\u003d\"//yanxuan.nosdn.127.net/79ee021bbe97de7ecda691de6787241f.jpg\"\u003e"
}
]
},
"errmsg": "成功"
}
### 2.19 对象存储服务
### 2.20 其他服务
## 3 管理后台API服务
略
## 4 更新日志
略
================================================
FILE: doc/conf/nginx.conf
================================================
user www-data;
worker_processes auto;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
server {
listen 443;
server_name www.example.com;
ssl on;
ssl_certificate /etc/nginx/1_www.example.com_bundle.crt;
ssl_certificate_key /etc/nginx/2_www.example.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name www.example.com;
rewrite https://$server_name$request_uri? permanent;
}
#include /etc/nginx/conf.d/*.conf;
#include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
================================================
FILE: doc/database.md
================================================
# 数据库
litemall数据库基于nideshop中的[nideshop.sql](https://github.com/tumobi/nideshop/blob/master/nideshop.sql)数据库,
然后在实际开发过程中进行了调整和修改:
* 删除了一些目前不必要的表;
* 删除了表中一些目前不必要的字段;
* 行政区域数据litemall_region没有采用原nideshop中的数据,而是采用了[Administrative-divisions-of-China](https://github.com/modood/Administrative-divisions-of-China);
* 表中的某些字段采用JSON存储;
* 表中的日期或时间字段采用DATE、DATETIME;
* 字段的数据类型粗粒度化,例如避免MEDIUMINT,而是INT;
* 表的数据做了清理、调整和补充(假数据)。
litemall数据库由三个sql文件组成,在litemall-db文件夹下面的sql文件夹中:
1. litemall_schema.sql
作用是创建空数据库、创建用户、设置访问权限。
开发者开发测试阶段可以使用,但是部署生产阶段一定要注意修改这里的默认用户名和密码。
注意,这里的sql文件不一定需要运行,开发者可以自己手动或命令行或IDE进行对应的操作即可。
2. litemall_table.sql
作用是创建数据库表,但是没有创建任何数据。
因此,开发者可以在部署生产阶段直接使用。
3. litemall_data.sql
作用是创建测试数据。
开发者开发测试阶段可以使用,但是部署开发阶段应该使用自己的数据。
综上,这里litemall真正必须运行的sql文件是litemall_table.sql,其他两个sql文件开发者自行决定如何是否使用。
## 1 数据表结构
### 1.1 用户相关

### 1.2 商品相关

### 1.3 订单相关

### 1.4 其他

## 2 数据表设计
接下来讨论一些数据表的关键细节。
### 2.1 商品和货品设计
这里商品存在商品表(litemall_goods),商品属性表(litemall_goods_attribute),商品规格表(litemall_goods_specification),商品货品表(litemall_goods_product)四种表
商品表是一种商品的基本信息,主要包括商品介绍,商品图片,商品所属类目,商品品牌商等;
商品参数表其实也是商品的基本信息,但是由于是一对多关系,因此不能直接保存在商品表中(虽然采用JSON也可以但是不合理),
因此采用独立的商品参数表,通常是商品的一些公共基本商品参数;
商品规格表是商品进一步区分货品的标识,例如同样一款衣服,基本信息一致,基本属性一致,但是在尺寸这个属性上可以
把衣服区分成多个货品,而且造成对应的数量和价格不一致。商品规格可以看着是商品属性,但具有特殊特征。
商品规格和规格值存在以下几种关系:
* 单一规格和单一规格值,最常见的,即当前商品存在一种货品;
* 单一规格和多个规格值,较常见,即当前商品基于某个规格存在多种货品,通常价格都是相同的,当然也可能不相同;
* 多个规格和单一规格值,可以简化成第一种情况,或者采用第四种情况,通常实际情况下不常见;
* 多个规格和多个规格值,通常是两种规格或者三种规格较为常见,而且对应的价格不完全相同。
商品货品表则是最终实现商品库存管理、购买业务的实体对象,存在多个规格值、数量和价格。
例如,同样的衣服品牌,可能因为不能尺寸和颜色而存在最终的货品,这里每个货品的价格可以一样,也可以不一样。
总结一下,一个普通商品,实际上在数据库中,存在一个商品表项,存在(至少0个)多个商品属性表项目,存在(至少一个)多个商品规格表项,
存在(至少一个)多个货品表项。
举例如下:
* 一个商品“2018春季衣服商品编号1111111”,
* 存在两个商品参数,
* 属性名称“面向人群”,属性值“男士”
* 属性名称“面料”,属性值“100%棉”
* 存在两种规格(分别五个规格值和三个规格值)共八个商品规格项,
* 规格名称“尺寸”,规则值“S”
* 规格名称“尺寸”,规则值“M”
* 规格名称“尺寸”,规则值“L”
* 规格名称“尺寸”,规则值“XL”
* 规格名称“尺寸”,规则值“XXL”
* 规格名称“颜色”,规格值“蓝色”
* 规格名称“颜色”,规格值“灰色”
* 规格名称“颜色”,规格值“黑色”
* 存在15个货品(尺寸*颜色=15个货品)
* 货品“S蓝”,数量 100, 价格 100
* 货品“M蓝”,数量 100, 价格 100
* 货品“L蓝”,数量 100, 价格 100
* 货品“XL蓝”,数量 100, 价格 100
* 货品“XXL蓝”,数量 100, 价格 100
* 货品“S灰”,数量 100, 价格 100
* 货品“M灰”,数量 100, 价格 100
* 货品“L灰”,数量 100, 价格 100
* 货品“XL灰”,数量 100, 价格 100
* 货品“XXL灰”,数量 100, 价格 100
* 货品“S黑”,数量 100, 价格 100
* 货品“M黑”,数量 100, 价格 100
* 货品“L黑”,数量 100, 价格 100
* 货品“XL黑”,数量 0, 价格 100
* 货品“XXL黑”,数量 0, 价格 100
以下是一些细节的讨论:
* 商品表中可能存在数量和价格属性,而货品中也存在数量和价格属性,目前设计这样:
* 商品表的价格应该和某个货品的价格一样,通常应该是所有货品价格的最小值,或者基本款式的价格;
* 商品表中的数量和价格应该仅用于展示,而不能用于最终的订单价格计算;
* 商品表的数量应该设置成所有货品数量的总和;
* 在管理后台添加商品时,如果管理员不填写商品表的数量和价格属性,则自动填写合适的值;如果填写,则使用显示。
* 当小商城中,用户查看商品详情时,初始显示商品表的价格,而如果用户选择具体规格后,则商品
详情里面的价格需要自动切换到该规格的价格。
* 商品规格可以存在规格图片,效果是规格名称前放置规格图片
* 货品也可以存在货品图片,效果是所有规格选定以后对应的货品有货,则在货品价格前放置货品图片
* 如果商品是两种规格,分别是M个和N个规格值,那么通常应该是`M*N`个货品,但是有些货品可能天然不存在。
目前这里要求所有货品信息都应该存在,如果实际中货品不存在,也要设置商品数量为0.
注意:
> 这里的设计可能与实际项目设计不一致,但是目前是可行的。
> 商品的中文用语“商品”和英语用语“goods”,货品的中文用语“货品”和英语用语“product”可能是不正确的。
### 2.2 用户和微信用户设计
目前准备支持用户普通账号登录和微信登录两种方式,两种登录方式仅仅采用一个litemall-user表可能不是很合适。
外,如果进一步支持其他多种第三方登录,那么这里需要重新设计。
### 2.3 行政区域设计
litemall_region表保存了行政区域信息,包括省级、市级、县级三个等级,
原nideship.sql中存在region数据,但是litemall.sql的region数据则来自
[Administrative-divisions-of-China](https://github.com/modood/Administrative-divisions-of-China)项目。
### 2.4 订单设计
订单信息主要由基本信息、商品信息、地址信息、费用信息、快递信息、支付信息和其他信息组成,
由litemall_order表和litemall_order_goods表保存。
* 基本信息
订单创建时的一些基本信息,例如用户、订单状态和订单留言等。
其中订单状态是最重要的信息。
* 商品信息
由于订单可以存在多个商品,因此订单的商品信息是由独立的订单商品表记录(可能更应该称为货品)。
* 费用信息
订单一些费用情况,例如商品总价、优惠减免和实际付费等。
* 收货信息
用户下单时选择的收货地址以及联系人信息。
* 快递信息
目前快递信息仅仅记录快递公司、快递单号、快递发出时间。
而如果快递过程中如果存在一些异常,例如物品丢失,则目前系统难以处理。
* 支付信息
支付时间和支付订单ID。
* 评论信息
订单商品的评论情况。
* 其他信息
#### 2.4.1 订单状态

订单分成几种基本的状态:
* 101
状态码101,此时订单生成,记录订单编号、收货地址信息、订单商品信息和订单相关费用信息;
* 201
状态码201,此时用户微信支付付款,系统记录微信支付订单号、支付时间、支付状态;
* 301
状态码301,此时商场已经发货,系统记录快递公司、快递单号、快递发送时间。
当快递公司反馈用户签收后,系统记录快递到达时间。
* 401
状态码401,当用户收到货以后点击确认收货,系统记录确认时间。
以上是一个订单成功完成的基本流程,但实际中还存在其他情况。
* 102
状态码102,用户下单后未付款之前,点击取消按钮,系统记录结束时间
* 103
状态码103,用户下单后半小时未付款则系统自动取消,系统记录结束时间
* 202
状态码202,用户付款以后未发货前,点击退款按钮,系统进行设置退款状态,等待管理员退款操作
* 203
状态码203,管理员在管理后台看到用户的退款申请,点击退款按钮进行退款操作。
* 402
状态码402,用户已签收却不点击确认收货,超期7天以后,则系统自动确认收货。
用户不能再点击确认收货按钮,但是可以评价订单商品。
此外,当订单状态码是102、103、203、401和402时,订单可以执行删除操作。
目前的设计是不执行物理删除,而是逻辑删除,因此用户查看自己订单时将看不到这些“已删除”的订单。
注意:
> 在上图中可以看到`101`到`101`的状态变化,这里只是小商场用户的操作,不会影响订单状态码。
> 如果用户点击付款时,后端服务会生成预支付会话id,但是不会影响订单状态。
> 如果而用户支付过程中,放弃支付,则也不会影响订单状态。
#### 2.4.2 状态变化
* 初始 -> 101
小商场用户在小商场点击`下单`按钮,此时小商城后端服务会生产商户订单。
所对应的后台服务方法是litemall-wx-api模块的`WxOrderController.submit`方法。
* 101 -> 101
这里开发者可能会奇怪,这里存在101->101的变化,这里表明后台没有响应
小程序端的请求,但是这里的响应没有导致订单状态实际的变化。这里所指的
响应小程序端请求是指下单成功以后小程序端自动请求付款或者用户在订单页面中
点击`付款`所导致的对后台服务的预支付请求。
关于微信支付流程,可以参看官方文档的[小程序支付业务流程](https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=3)
也就是说这里小商城后台服务会返回付支付信息。
所对应的后台服务方法是litemall-wx-api模块的`WxOrderController.prepay`
小商城接收返回的预支付信息后,会在小程序端出现支付页面。
如果用户放弃支付,则不会出现任何效果,不会向小商场后台服务发送任何信息。
如果用户支付,则会导致微信商户平台向小商场后台服务推送支付结果。
* 101 -> 102
如果用户没有支付,那么此时用户可以点击`取消订单`按钮来放弃当前订单。
所对应的后台服务方法是litemall-wx-api模块的`WxOrderController.cancel`
* 101 -> 103
如果用户没有支付,也没有点击`取消订单`按钮,那么系统会定时查询数据库的订单信息。
如果发现存在订单未支付状态超时半小时,此时系统会自动取消订单,来释放商品资源。
对应的应该是litemall-admin-api模块的系统定时任务的`OrderJob.checkOrderUnpaid`
* 101 -> 201
如果用户支付,微信商户平台会向小商场后台服务推送支付结果。
而响应结果表示支付成功,则订单状态信息设置201,表示支付成功。
所对应的后台服务方法是litemall-wx-api模块的`WxOrderController.payNotify`
* 201 -> 202
当用户支付以后,管理员未发货前,用户可以点击`退款`申请退款取消订单。
通常用户点击退款以后系统可以基于微信商户平台的退款接口实现自动退款,
但是这里考虑到安全原因,不支持系统自动退款操作。
相应地,这里小商场后台服务只是设置订单状态,表示退款申请中。
所对应的后台服务方法是litemall-wx-api模块的`WxOrderController.refund`
* 202 -> 203
这里退款操作是由管理员在微信商户平台手动退款,然后在本项目的
管理平台里面点击`退款确认`按钮,此时订单状态会设置成203,表明
退款已经成功,同时系统会自动恢复订单商品数量。
所对应的后台服务方法是litemall-admin-api模块的`AdminOrderController.refundConfirm`
* 201 -> 301
当订单支付以后,管理员进行订单发货,然后在管理平台点击`发货`,填写快递信息,
设置订单状态是301,表示管理员已发货状态。
所对应的后台服务方法是litemall-admin-api模块的`AdminOrderController.ship`
* 301 -> 401
当用户收到商品以后,用户点击`收货确认`按钮,设置订单状态401,表示用户成功收货。
所对应的后台服务方法是litemall-wx-api模块的`WxOrderController.confirm`
* 301 -> 402
当管理员发货以后,用户一直没有确认收货,系统定时检测订单状态,如果发现发货以后
七天用户都没有收货,此时系统自动确认用户收货,设置订单状态402。
应该改为 litemall-admin-api模块的系统定时任务`OrderJob.checkOrderUnconfirm`
注意:
> 上述订单状态变化中具体的逻辑处理可以参考相应模块文档和模块代码。
#### 2.4.2 用户操作
订单状态码标识了订单的状态,但是对于用户而言,真正关心的只是他们能够进行的操作,
也就是在小商场的小程序端用户可以进行点击的按钮操作,目前支持:
* `支付`,如果下单后未立即支付,则订单详情页面会出现`支付`按钮;
* `取消`,如果用户未支付,则订单详情页面会出现`取消`按钮;
* `退款`,如果用户支付后但是管理员未发货,则订单详情页面会出现`退款`按钮;
* `确认收货`,如果管理员已发货,则订单详情页面会出现`确认收货`按钮;
* `申请退货`,如果用户已经确认收货同时未超过一段时间,则订单详情页面会出现`申请退货`按钮;
注意,这里如果是系统超时自动确认收货,则不会出现;
* `去评价`,如果用户确认收货以后,则订单详情页面会出现`去评价`按钮;
* `再次购买`,如果用户确认收货以后,则订单详情页面会出现`再次购买`按钮;
* `删除`,如果当前订单状态码是102、103、203、401和402时,则订单详情页面会出现`删除订单`按钮;
注意,这里的删除操作是逻辑删除,即设置订单的删除状态`deleted`。
因此订单状态码和小商场用户操作之间存在映射关系:
* 101
用户可以`支付`、`取消`
* 102
用户可以`删除`
* 103
用户可以`删除`
* 201
用户可以`退款`
* 203
用户可以`删除`
* 301
用户可以`确认收货`
* 401
用户可以`删除`、`去评价`、`申请售后`、`再次购买`
* 402
用户可以`删除`、`去评价`、`申请售后`、`再次购买`
#### 2.4.3 申请售后
当用户确认收货或者系统自动确认收货以后,订单可以申请售后。
目前仅支持订单整体售后,而不支持订单商品独立售后。
这是因为:订单存在商品售价、优惠券减免、团购减免以及物流运费属性,
如果要支持单个商品退款,那么存在一个需要解决的问题就是单个商品的
退款金额如何计算。如果开发者这里考虑清楚,也可以参考当前代码实现
订单商品独立售后
litemall_order表中存在`aftersale_status`字段,记录订单售后状态。
而具体的售后记录则是litemall_aftersale表记录。
这里`type`字段表示当前售后类型,目前存在三种类型:
* 如果type=0,即“未收货退款”,通常是系统超时自动确认收货,而实际上用户没有收货,因此可以选择这个;
* 如果type=1,即“无需退货退款”,通常是用户确认收货后申请售后,而管理员同意可以不需要退货,直接退款给用户;
* 如果type=2,即“退货退款”,通常是用户确认收货后申请售后,管理员同意用户退货,当管理员收到货以后再退款给用户。
需要注意的是:当前实现中,如果是“退货退款”类型,那么管理员在进行退款以后,系统会自动恢复货品数量。
这是因为管理员完成“退货退款”售后,说明管理员已经收到用户的退货。
开发者可以改变这里的实现逻辑,例如采用独立的退货入库流程。
`status`字段表示当前售后状态,分别是:
* 如果status=0,未申请售后;
* 如果status=1,用户申请售后,等待管理员审核;
* 如果status=2,管理员审核通过,等待管理员退款;
* 如果status=3,管理员已退款,售后完成;
* 如果status=4,管理员审核不通过,售后完成;
* 如果status=5,用户已取消售后,当用户在申请售后以后可以在管理员审核前申请取消。
这里需要补充的是:订单litemall_order表的`aftersale_status`字段,和订单售后litemall_aftersale
表的`status`字段是完全一致的,方便前端分别查询订单状态和订单售后状态。
`amount`字段表示当前售后退款金额,正如前面所述当前仅支持订单整体售后,因此目前设计的退款金额是
订单实际付款-订单运费。
#### 2.4.4 商品评价
在litemall_order表中存在`comments`字段,表示有几个订单商品没有评价;
而在litemall_order_goods表中存在`comment`字段,表示当前订单商品的评论ID。
* 当用户确认收货以后,`comments`设置当前订单中未评价的商品数量。而`comment`设置0;
* 当用户评价一个订单商品,`comments`会减一,而`comment`指向新创建的评论;
* 如果用户不评论超期,`comments`会设置0,而`comment`设置-1;
### 2.5 评论设计
评论表litemall_comment保存评论相关的信息,其中最关键的是`type`字段和`value_id`字段。
这里`type`字段表示当前评论类型,目前存在两种类型:
* 如果type=0,则当前评论是订单商品评论,value_id是订单商品ID;
* 如果type=1,则当前评论是专题评论,value_id是专题ID;
`admin_content`字段则拥有记录管理后台管理员对用户评论的回复。
### 2.6 团购设计
团购是由团购规则表litemall_groupon_rules和团购活动表litemall_groupon组成。
管理员在管理后台对一些商品配置团购规则,保存在litemall_groupon_rules表中。
用户在小商场中则看到团购规则给出的优惠信息。
接下来用户存在两种操作:
第一种是,用户开团,保存在litemall_groupon中,用户主动分享商品团购页面给朋友;
第二张是,用户参团,也保存在litemall_groupon中。
只有开团人数符合团购规则条件,创建的订单才会有效,否则管理员需要退款取消当前团购。
### 2.7 优惠券设计
优惠券由litemall_coupon表和litemall_coupon_user表组成:
* litemall_coupon表,是优惠券基本信息及使用规则。
* litemall_coupon_user表,是用户优惠券领取和使用的记录。
#### 2.7.1 type
type字段,标识优惠券发送的方式,目前支持:
* 通用券,即在首页或者优惠券列表页,用户可以看到优惠券信息并且点击领取;
* 注册券,即用户注册成功以后即系统自动发送给用户,无需领取;
* 兑换券,即用户在个人优惠券页面输入兑换码来兑换一张优惠券。
#### 2.7.2 goods_type
goods_type字段,标识优惠券所能使用的商品范围:
* 全场通用,即所有商品都能使用;
* 类目限制,**目前不支持**,即某个类目的商品才能使用;
* 商品限制,**目前不支持**,即部分商品才能使用优惠券。
#### 2.7.3 time_type
time_type字段,标识优惠券有效期;
* 用户领券日期的相对天数,即用户领券以后开始几天内有效;
* 管理员设置的绝对时间,即优惠券的开始使用时间和截至使用时间。
#### 2.7.4 status
status字段,标识优惠券的当前状态。
这里需要指出的是,litemall_coupon表和litemall_coupon_user表都有status字段。
litemall_coupon表的status字段,包含以后三种状态:
* 正常可用,
* 已过期,
* 已下架,
litemall_coupon_user表的status字段,包含以后三种状态:
* 未使用,
* 已使用,
* 已过期,
* 已下架,
### 2.8 系统配置设计
系统配置表litemall_system保存系统的配置信息。
这里需要注意的是,在Java代码层系统配置表只能执行更新操作,
不能执行创建和删除操作。也就是说,系统配置数据都应该是开发者
基于系统的配置需求在数据库中手动创建。
### 2.9 存储对象设计
存储对象表litemall_storage保存上传文件信息。
当用户或者管理员上传图像时,图像文件会保存到本地或者第三方云存储服务器中,
同时在存储对象表中记录一下。
### 2.10 操作日志设计
业务日志表litemall_log记录管理员的关键性操作。
需要讨论的是,很多项目的业务日志模块采用注解方式,即加上方法注解,因此可以自动捕获
用户的操作行为。虽然这样做很方便且不会影响业务代码,但是实际上最终是粗颗粒地记录,反而记录意义不大。
因此本项目采用在方法内手写业务日志代码方式记录业务操作行为及结果。
虽然比较繁琐,但是可以保证记录是细颗粒的。而且,如果管理员最终关心的操作较少,那么
实际上需要写的代码不是很多。
考虑到语义,操作业务应该是“谁做了什么操作,结果成功还是失败,失败原因是什么,补充信息是什么”,
因此这里设计的业务日志表关键字段如下:
* 管理员
* IP地址
* 操作分类
* 操作动作
* 操作状态
* 操作结果
* 补充信息
#### 2.10.1 操作类别
这里的日志类型设计成四种(当然开发者需要可以扩展)
* 一般日志:用户觉得需要查看的一般操作日志,建议是默认的日志级别
* 安全日志:用户安全相关的操作日志,例如登录、删除管理员
* 订单日志:用户交易相关的操作日志,例如订单发货、退款
* 其他日志:如果以上三种不合适,可以选择其他日志,建议是优先级最低的日志级别
当然建议开发者应该和最终用户讨论交流,记录真正关键性的业务操作,例如登录相关或订单相关等。
#### 2.10.2 操作结果
如果操作成功,可以使用操作结果字段记录被操作的对象。
当然,有些操作没有具体对象,那么可以省略。
如果操作失败,也可以使用操作结果字段记录失败的原因。
#### 2.10.3 操作失败
虽然这里有操作状态字段和操作结果字段,可以记录操作失败的状态。
但是通常失败操作不会对系统或者数据库带来影响,因此实际上开发者其实不需要
记录太多操作失败的日志,而是记录操作成功的日志,告诉系统管理员当前状态的变化。
当然,是否记录操作失败取决于开发者或者最终用户是否需要。
例如,登录这里应该记录用户登录失败的日志,因为保存的IP地址可以帮助管理员了解
系统被访问的情况。
### 2.11 通用设计
除了以上表,数据库还存在其他一些业务表,例如专题表litemall_topic,
但是都很直观,不需要多讨论。
以下是一些表设计中无具体业务意义可通用的字段。
#### 2.11.1 deleted
除极少数表,其他所有表都存在`deleted`字段,支持逻辑删除。
因此目前删除数据时,不会直接删除数据,而是修改`deleted`字段。
当然,数据库管理员可以连接到数据库直接删除数据,或者开发者
可以修改这里的逻辑采用物理删除。
#### 2.11.2 add_time
除极少数表,其他所有表都存在`add_time`字段,记录数据创建时间。
#### 2.11.3 update_time
除极少数表,其他所有表都存在`update_time`字段,记录数据修改时间。
此外,此外开发者可以利用update_time来实现乐观锁更新机制。
================================================
FILE: doc/how to implement best admin.md
================================================
# 最佳管理后台开发实践
很多开源项目和商业项目本质上就是一个业务管理后台,因此开源项目或者商业项目都会开发一个剥离业务的通用管理后台。
但是从本人开发和使用经验出发,希望解决以下问题:
1. 什么是最佳管理后台
目前有很多优秀的开源管理后台项目,文档都写了如何使用、如何开发,但是没有文档详细讨论为什么需要这个功能、
这个功能到底完成什么功能。当然,很多功能其实的确是不言自明的,但是本节希望从管理后台的使用者和管理员角度
来系统性地阐述讨论通用的管理后台的一些需求分析。
2. 如何开发最佳管理后台
对于一个功能,不能的开源项目给出了不同的解决方案,有的解决方案基本是一样的,有的还是有些出入,不同的实现方案
中是否能够有最佳方案,以及不同的方案如何来评判优劣。本节希望从管理后台的入门开发者角度来讨论如何开发一个
最佳管理后台。
注意:
1. 当然,在没有限定条件下来讨论最佳管理后台,最后可能是被人各种喷。本人也的确没有参与过大型项目或者互联网项目的管理后台开发,
给不出业界企业级的管理后台开发经验。因此本节仅仅给出一个中、小、微规模的最佳基础通用管理后台的纸上谈兵文档。
2. 本节不讨论任何技术细节,不限定具体的技术框架,而是讨论管理后台的业务需求。
## 1. 最佳管理后台是什么?
* 用户管理(管理员管理)
* 部门管理
* 角色管理
* 权限管理
* 配置管理
* 定时任务
* 消息管理
* 操作日志
* 系统日志
* 菜单管理
* 国际化
* 代码生成
* 字典管理
* 上传下载
### 1.1 用户管理
1. 不要以性能指标来评判管理后台
2.
## 权限管理
权限管理是一个管理后台的核心功能,不同的人员存在不同的权限。
但是具体应该呈现什么效果?
有没有遇到过这种场景:
> 某天业务人员找你授权,说别人存在某个页面“AA”或者某个按钮“BB”,他现在也需要;
> 作为系统管理员,你点击打开授权页面,然后看到了各种权限。
> 然后问题来了,各种权限没有任何名字是和“AA”、“BB”相关的,请问系统管理员如何授权?
> 最后系统管理员只能从管理后台的开发或者维护工程师才能问到。
从功能上来说,这个管理后台的确实现了权限功能,但是从实际场景出发,这里的权限管理
实现的非常糟糕。开发工程师或者产品经理根本没有从使用者角度出发来考虑权限管理。
原则1:
> 假定权限列表的每一项是(AA,BB),则AA是权限所对应的页面,BB是权限所对应页面的操作按钮。
管理员授权时看到(AA,BB),就非常直观地了解当前权限会产生的效果,即授权BB则AA页面的
BB按钮出现,回收BB则AA页面的BB按钮会消失。
## 代码生产
## 参数管理
## 字典管理
字典是什么
## 菜单管理
很多管理后台都实现了菜单管理,从个人管理后台的使用角度出发,其实不是很理解菜单管理的意义。
也许来一个调查,多少管理后台的管理员会使用或者使用过菜单管理功能。
当然,菜单管理可能想实现的功能是分配不同的角色不能的前端操作页面。
## 定时任务
定时任务需要吗?
当然需要,很多功能都依赖定时任务定时完成。
但是管理后台的前端页面真的需要定时任务吗?
很奇怪,很多项目都存在定时任务菜单,而具体的页面则提供定时任务的创建、修改、删除等功能。
仔细看一下定时任务的创建效果,需要管理员设置CLASS方法、cron表达式。
让我们思考一下,
一个普通的业务管理员能看懂这个页面是做什么的吗,CLASS方法?,cron表达式?
好吧,换成懂点技术的系统管理员,也许看的懂这个页面,只是他需要这个页面做什么?他怎么设置CLASS方法?
个人觉得,如果从使用者角度来考虑,定时任务的设计有点伪需求,这个功能根本没有使用场景,或者说
定时任务的创建、删除等功能没有使用场景。
进一步考虑,如果设计定时任务,那么管理后台应该如何设计,以下是个人的一些想法:
1. 和需求方交流是否需要定时操作的一些使用场景,是否需要控制定时任务。
2.
## 国际化
国际化看起来似乎是必要的,毕竟说不定开发的管理后台有可能要被全世界的人使用。
不过个人觉得这个概率是较小的,因此开发初期似乎是没有必要支持国际化。
此外,为了支持国际化,通常做法是代码中使用key,然后创建对应value的多个资源文件,最后根据配置
动态解析国际化文字。这种两步骤的开发方式可以很好地支持国际化。但是,如果项目使用场景真的不需要
国际化,那么默认内置国际化支持的管理后台其实反而降低了开发体验和速度。
* 开发时需要考虑key怎么合理化命名(有可能有上百个),
* 开发需要写一点包装key的代码,例如前端页面可能是`$t(key)`
* 调试也不直观,代码和页面中都是key
因此,个人觉得一个最佳管理后台默认不支持国际化可能是最佳的。
## 代码生成
因此,经过以上讨论,
* 用户管理:需开发
* 部门管理:需开发
* 角色管理:需开发
* 权限管理:需开发
* 配置管理:需开发
* 定时任务:不开发
* 消息管理:可开发
* 操作日志:需开发
* 系统日志:需开发
* 菜单管理:不开发
* 字典管理:不开发
* 上传下载:需开发
## 2. 管理后台后端开发
* 文件上传下载
* 事务管理
* 分页管理
* 异常处理
* 操作权限
* 数据权限
## 2.1 性能
首先提出的第一条规则就是:
不要过早优化性能,也不要追求性能极限,或者说理解管理员的需求极限。
从一个管理平台的使用者角度出发,点击页面以后如果在秒级响应,本人是可以接收的,极限容忍时间可以是十秒(当然这样的页面不能太多)。
也就是和京东、天猫这些面向大众用户的系统不同,一个普通的业务管理系统使用者在使用时对系统的可容忍度较高。
当然,这里不是说性能不重要,而是觉得对性能的开发时间和精力可以分配较小。
##
## 3. 管理后台前端开发
* 文件预览
* 图片预览
## 4. 业务管理模块
* 列表展示
* 增删改查
* 分页
* Excel导入导出
* 业务统计
================================================
FILE: doc/mobmall.md
================================================
# 5 litemall轻商城
litemall轻商城,是商城移动版本。
技术:
* 轻商城前端,即litemall-vue模块
* vue-cli3
* Vue + Vue-router + Vant + Sass
* axios
* fastclick
* babel-polyfill
* @xkeshi/vue-countdown
* Vant
* 轻商城后端,即litemall-wx-api模块,也就是和小商城后端是一样的。
* Spring Boot 2.x
* Spring MVC
* [weixin-java-tools](https://gitee.com/binary/weixin-java-tools)
## 5.1 litemall-wx-api
可以阅读3.1
## 5.2 litemall-vue
这里的代码基于[vant--mobile-mall](https://github.com/qianzhaoy/vant--mobile-mall)
文档未完成。
================================================
FILE: doc/note.md
================================================
# 项目笔记
记录本项目开发中一些关键技术点。
注意:
> 这些技术并不是绝对正确或者唯一,而是目前项目所采用。
## 1. 前后端交互技术
## 2. 错误码
================================================
FILE: doc/performance.md
================================================
# 性能
## 1 小程序性能
## 2 VUE性能
## 3 Spring Boot性能
### 3.1 gzip压缩
在litemall-all模块中配置gzip压缩
```
server:
compression:
enabled: true
min-response-size: 2048
mime-types: application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain
```
## 4 数据库性能
## 5 其他
================================================
FILE: doc/platform.md
================================================
# 2 litemall基础系统
目前litemall基础系统由以下部分组成:
* litemall-core模块
* litemall-db模块
* litemall-all模块
* litemall-all-war模块
litemall-db模块提供数据库访问服务。
litemall-core模块提供通用服务。
litemall-all模块则只是一个包裹模块,几乎没有任何代码。该模块的作用是融合两个spring boot模块
和litemall-admin模块静态文件到一个单独Spring Boot可执行jar包中。
litemall-all-war模块和litemall-all模块是一样的作用,只是采用war打包方式。
## 2.2 litemall-db
litemall-db模块是一个普通的Spring Boot应用,基于mybatis框架实现数据库访问操作,对外提供业务数据访问服务。
此外,litemall-db最终是作为一个类库被其他模块所依赖使用,因此并不对外
直接服务,没有使用Spring MVC技术。
技术:
* Spring Boot 2.x
* MySQL
* Druid
* Mybatis
* PageHelper
* Mybatis Generator
* Mybatis Generator非官方插件mybatis-generator-plugin

这里litemall-db模块可以分成以下几种代码:
* mybatis数据库访问代码
* generator生成代码
* 非generator手动代码
* 业务代码
* mybatis generator支持代码
### 2.2.1 mybatis数据库访问代码
mybatis数据库访问代码是指dao接口代码、dao数据库XML文件和domain代码:
* dao接口代码,声明了数据库访问接口
* dao数据库XML文件,实现了数据库访问操作
* domain代码,则是保存数据库返回数据。
此外,这里的数据库访问代码又进一步分成
* mybatis generator自动生成代码,即基于mybatis generator相关插件自动生成上述三种代码或文件;
* 非mybatis generator手动代码,则是需要开发者自己编写上述三种代码。
#### 2.2.1.1 自动生成代码

如上图所示,双击`mybatis-generator:generate`,则mybatis generator插件会:
1. 读取`mybatis-generator`文件夹下的`generatorConfig.xml`文件
2. 根据`jdbcConnection`访问数据库
3. 根据`table`, 自动生成三种代码:
* src文件夹`org.linlinjava.litemall.db.dao` 包内的Java代码
* src文件夹`org.linlinjava.litemall.db.domain` 包内的Java代码
* resources文件夹`org.linlinjava.litemall.db.domain.dao` 内的XML文件
以上三种代码即可封装对数据库的操作,开发者无需直接操作sql代码,
而是直接操作Java代码来完成对数据库的访问处理。
关于如何基于mybatis的Example代码来访问数据库,请查阅相关资料,
或者参考本模块`org.linlinjava.litemall.db.service` 包内的Java代码。
当然,为了达到数据库访问效率,开发者也可以手动自定义mapper文件和对应的Java代码。
例如,当需要访问两个表的数据时,这里是在业务层通过Java代码遍历的形式来访问两个表,
也可以通过自定义的mapper文件来实现。
接下来,以`litemall_brand`表举例说明如何自动生成代码:
1. mybatis generator插件会读取`table`标签
```
<generatorConfiguration>
<table tableName="litemall_brand">
<generatedKey column="id" sqlStatement="MySql" identity="true" />
</table>
</generatorConfiguration>
```
2. 自动生产src文件夹下domain包内的LitemallBrand.java类、LitemallBrandExample.java类、
dao包内的LitemallBrandMapper.java接口和resources文件夹下dao包内的LitemallBrandMapper.xml文件。
3. 手动在service包内创建LitemallBrandService.java来对外提供具体的服务。
例如,为了得到Brand列表,那么创建list方法,基于前面创建的三个Java来来实现。
```java
@Service
public class LitemallBrandService {
@Resource
private LitemallBrandMapper brandMapper;
public List<LitemallBrand> query(int offset, int limit) {
LitemallBrandExample example = new LitemallBrandExample();
example.or().andDeletedEqualTo(false);
PageHelper.startPage(offset, limit);
return brandMapper.selectByExample(example);
}
}
```
关于mybatis generator的用法,可以自行查阅官网或文档。
#### 2.2.1.2 手动代码
虽然mybatis generator可以自动生产代码,帮助开发者简化开发工作,但是在涉及到多表操作或特殊数据库操作时,
仍然需要开发者自己手动编写基于mybatis框架的相关代码。
具体如何基于mybatis框架编写代码,请开发者自己查找资料。
这里,以统计功能举例说明:
1. dao代码
在src文件夹`org.linlinjava.litemall.db.domain` 包内的StatMapper.java代码定义了数据库访问的接口
2. domain代码
如果希望数据库操作返回数据模型,可以在src文件夹`org.linlinjava.litemall.db.domain` 包内创建相应代码。
而这里统计功能是采用简化的`List<Map>`保存数据,没有定义domain代码。
3. XML文件
在resources文件夹`org.linlinjava.litemall.db.domain.dao` 内的StatMapper.xml文件则是实现真正的数据库访问操作。
4. service代码
这里可以在`org.linlinjava.litemall.db.service` 内定义一个StatServie.java代码,调用底层mapper代码,对外服务。
```
@Service
public class StatService {
@Resource
private StatMapper statMapper;
public List<Map> statUser() {
return statMapper.statUser();
}
public List<Map> statOrder(){
return statMapper.statOrder();
}
public List<Map> statGoods(){
return statMapper.statGoods();
}
}
```
### 2.2.2 业务代码
虽然2.2.1节所述代码已经能够提供数据库访问操作,但是这里需要进一步地抽象出业务访问层代码,
即基于2.2.1所述代码和实际业务需求实现一些具体业务相关的操作,对其他模块提供便捷业务数据服务。
需要指出的是,这里的业务代码往往是单表相关的业务代码,而涉及到多表操作的java代码通常是在其他高层模块中实现。
这里的业务分层并不是绝对的。例如,开发者可以取消这里的业务代码,而在其他模块中直接调用2.2.1所述代码。
通常业务层代码在src文件夹`org.linlinjava.litemall.db.service` 包中。
### 2.2.3 mybatis generator支持代码
mybatis generator自动生成代码时,通过内置类型转换器自动把数据库类型转换成Java类。
例如数据库类型`varchar`自动转化成`java.lang.String`。
但是某些情况下,可以通过自定义TypeHandler的方式来采用自定义的类型转换器。
开发者可以自行阅读相关资料了解。
本项目中,为了简化数据表的设计,某些字段采用`varchar`来存储Json格式的数据。
例如商品的图片列表可以直接采用`[url0, url1, ...]`来存储,而不需要设计一个专门商品图片表。
这里通过自定义TypeHandler,可以实现Java的`String[]`和数据库类型`varchar`的自动转换。
1. 实现JsonStringArrayTypeHandler类;
2. 在mybatis generator配置文件中,配置需要的字段;
```
<table tableName="litemall_goods">
<columnOverride column="gallery" javaType="java.lang.String[]"
typeHandler="org.linlinjava.litemall.db.mybatis.JsonStringArrayTypeHandler"/>
</table>
```
3. 使用mybatis generator自动生成代码,可以看到LitemallGoods的gallery是`String[]`类型。
目前只实现了两个自定义TypeHandler:
* JsonStringArrayTypeHandler类,实现`String[]`和`varchar`的转换,保存的JSON数据格式是`[string0, string1, ...]`
* JsonIntegerArrayTypeHandler类,实现`Integer[]`和`varchar`的转换,保存的JSON数据格式是`[integer0, integer1, ...]`
如果开发者需要保存其他格式的JSON数据或者自定义格式的数据,请自行开发。
### 2.2.4 新服务组件
本节介绍如果基于一个表创建新的服务组件。
1. 在数据库里面创建一个表,例如`litemall_demo`:
```sql
CREATE TABLE `litemall`.`litemall_demo` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NULL,
`address` VARCHAR(45) NULL,
PRIMARY KEY (`id`));
INSERT INTO `litemall`.`litemall_demo` (`id`, `name`, `address`)
VALUES ('1', 'hello', 'world');
```
2. 在generatorConfig.xml中增加一个新的table标签
```
<generatorConfiguration>
<table tableName="litemall_demo">
<generatedKey column="id" sqlStatement="MySql" identity="true" />
</table>
</generatorConfiguration>
```
3. 双击mybatis generator插件,检查LitemallDemo.java类、LitemallDemoExample.java类、
LitemallDemoMapper.java接口和LitemallDemoMapper.xml是否生产。
4. 在service里面新建LitemallDemoService.java类,
```java
@Service
public class LitemallDemoService {
@Resource
private LitemallDemoMapper demoMapper;
public List<LitemallDemo> list() {
LitemallDemoExample example = new LitemallDemoExample();
return demoMapper.selectByExample(example);
}
}
```
5. 可以在`src/test/java/org.linlinjava.litemall.db`包里面创建LitemallDemoTest.java类,
使用Junit进行测试。
```java
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class LitemallDemoTest {
@Autowired
private LitemallDemoService demoService;
@Test
public void test() {
List<LitemallDemo> litemallDemoList = demoService.list();
Assert.assertTrue(litemallDemoList.size() != 0);
}
}
```
6. 同样地,可以在Controller中使用LitemallDemoService来对外提供服务。
```java
@RestController
@RequestMapping("/demo")
public class DemoController {
@Autowired
private LitemallDemoService demoService;
@RequestMapping("/list")
public Object list(){
List<LitemallDemo> demoList = demoService.list();
return demoList;
}
}
```
### 2.2.5 逻辑删除
数据删除可以直接进行物理删除,也可以采用设置删除字段进行逻辑删除。
根据具体业务,也有可能部分数据可以物理删除,部分数据只能逻辑删除。
目前本项目所有删除操作都是逻辑删除。
开发者可以自行修改代码进行真正的物理删除,来避免数据库保存无用数据。
### 2.2.6 并发访问
由于服务是多线程并发的,因此这带来了多线程同时操作数据库中同一数据的问题。
由于数据极少删除或者是逻辑删除,因此操作数据,可以简化成更新数据。
也就是说,需要解决多线程更新数据库同一数据的并发问题。
* https://blog.csdn.net/qq315737546/article/details/76850173
* http://baijiahao.baidu.com/s?id=1571172971189129
* https://blog.csdn.net/speedme/article/details/48525119
例如,下单操作中,用户A购买商品G的数量是1个,而用户B同一时间也购买商品G的
数量也是1个,那么如果没有很好地并发控制,有可能商品G的数量仅仅是减1,而不是
设想的2。
通常采用悲观锁或者乐观锁来处理并发更新问题,
本项目目前采用基于`update_time`字段的乐观锁机制。
原理是:
1. 每个表都存在update_time字段
2. 更新前,先查询数据,得到表的业务数据和update_time字段
3. 更新时,通过where条件查询当前update_time字段和数据库中当前update_time字段是否相同。
* 如果相同,说明数据没有改变则可以更新,数据更新同时update_time设置当前更新时间;
* 如果不相同,则说明数据改变了则更新失败,不能修改数据。
当然,由于采用乐观锁,这里也会带来另外一个问题:
数据库有可能更新失败,那么如何处理更新失败的情况?
目前只是简单地报错更新失败。
### 2.2.7 事务管理
litemall-db模块中不涉及到事务管理,而是在其他后台服务模块中涉及。
但是其他后台服务模块因为依赖litemall-db模块,因此这里列出。
事务管理的问题出现在多个表的修改操作中。
例如用户A修改表1,再修改表2,而如果修改表2的时候出现错误推出,
此时如果没有引入事务管理,那么这里会存在表1数据已更新,表2数据
未更新的问题。
解决的方案是采用spring自带的事务管理机制。
当事务管理中的任何SQL操作出现错误而抛出异常时,则回滚之前的操作。
注意:
> 并发访问是多个用户同时操作单个表时可能出现的问题;
> 而事务管理是单个用户操作多个表时可能出现的问题。
### 2.2.8 mybatis增强框架
通过mybatis-generator已经自动生成了很多代码,而且具有一定的功能,
但是开发者仍然需要基于生成的代码写一些固定的CRUD代码。
目前发现已经有两个mybatis增强的框架可以进一步简化代码和功能增强:
* [mybatis-plus](https://github.com/baomidou/mybatis-plus)
* [Mapper](https://github.com/abel533/Mapper)
目前没有采用,以后可能会基于其中之一重构数据库访问代码。
开发者感兴趣的可以自行研究使用。
## 2.3 litemall-core
litemall-core模块是本项目通用的代码:
* config
通用配置,例如开启Spring Boot异步功能。
* util
工具代码。
* qcode
本项目定制的分享二维码图片。
* storage
存储功能,支持本地存储、腾讯云存储、阿里云存储和七牛云存储。
* notify
通知提醒功能,支持邮件通知、短信通知和微信通知。
* express
物流服务,查询订单物流信息。
* system
通过litemall-db模块的数据库访问,读取本项目系统配置信息。
* validator
提供两个校验注解,帮助后端验证请求参数。
### 2.3.1 config
#### 2.3.1.1 CorsConfig
目前开发过程中,CORS配置是允许所有请求。
真正部署时,开发者需要做一些调整,来保证当前的服务只接受来自所设置域名的请求。
#### 2.3.1.2 GlobalExceptionHandler
如果系统内部产生了异常而开发者没有catch,那么异常的内容会发送到前端。
这里通过提供全局异常处理器,来处理所有开发者没有处理的异常,返回
“系统内部错误”之类的信息给前端从而达到保护系统的效果。
#### 2.3.1.3 JacksonConfig
Jackson做一些设置。
### 2.3.2 util
注意
> 这里的util代码不会涉及具体业务,例如litemall-db模块中存在一个
> OrderUtil类处理数据库中litemall_order表的一些转换工作。
#### 2.3.2.1 ResponseUtil
这里是用于设置response中body的内容格式。
如果是成功则是 :
```json
{
errno: 0,
errmsg: '成功',
data: XXX
}
```
如果失败则是:
```json
{
errno: 非0的XXX,
errmsg: XXX
}
```
#### 2.3.2.2 JacksonUtil
当请求时POST时,请求的json内容在body。
通常存在存在两种方式取出数据:
* 如果json内容正好对应一个POJO,那么在方法中使用POJO时,spring会自动解析填充数据;
* 或者开发者自己采用jackson或者其他json处理库手动解析数据。
这里JacksonUtil简化解析工作。这里代码有局限性,开发者请谨慎使用,或者熟悉Jackson
使用的开发者欢迎优化代码。
#### 2.3.2.3 CharUtil
生成固定长度的随机字母字符串或者随机数字字符串。
#### 2.3.2.4 bcypt
这里是用于对用户密码或者管理员密码加密存储。
bcypt代码本质上是spring里面的代码。
### 2.3.3 二维码
见QCodeService类。
### 2.3.4 对象存储
对象存储服务目前的目标是支持图片的上传下载。
对象存储服务会自动读取配置配置,然后实例化服务。
对象存储接口:
```
public interface Storage {
void store(InputStream inputStream, long contentLength, String contentType, String keyName);
Stream<Path> loadAll();
Path load(String keyName);
Resource loadAsResource(String keyName);
void delete(String keyName);
String generateUrl(String keyName);
}
```
#### 2.3.4.1 本地存储服务
见LocalStorage类。
#### 2.3.4.2 腾讯云存储服务
见TencentStorage类。
#### 2.3.4.3 阿里云存储服务
见AliyunStorage类。
#### 2.3.4.4 七牛云存储服务
见QiniuStorage类。
### 2.3.5 消息通知
消息通知用于通知用户或者管理员。
注意:
> 目前这里实现比较粗糙,以后会完善细节。
#### 2.3.5.1 邮件通知
见NotifyService类的`notifyMail`方法。
#### 2.3.5.2 短信通知
见NotifyService类的`notifySms`和`notifySmsTemplate`方法。
而短信通知实现类见`TencentSmsSender`类。
也就是目前仅支持腾讯云短信服务,其他短信服务不支持。
此外,开发者必须先在腾讯云短信平台申请模板才能使用。
#### 2.3.5.3 微信通知
见NotifyService类的`notifySms`和`notifyWxTemplate`方法。
而微信通知实现类见`WxTemplateSender`类。
开发者必须在微信平台申请模板才能使用。
### 2.3.6 物流跟踪
物流跟踪是基于第三方服务快鸟物流查询服务。
开发者需要申请才能使用。
见`ExpressService`类。
### 2.3.7 系统设置
### 2.3.8 校验注解
自定了两个校验注解,帮助开发者校验HTTP参数。
#### 2.3.8.1 Order
校验用户请求参数值只能是`desc`或者`asc`。
注意,这里的Order不是订单的意思,而是排序的意思。
1. 定义注解Order
```
@Target({METHOD, FIELD, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = OrderValidator.class)
public @interface Order {
String message() default "排序类型不支持";
String[] accepts() default {"desc", "asc"};
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
```
2. 实现OrderValidator
```
public class OrderValidator implements ConstraintValidator<Order, String> {
private List<String> valueList;
@Override
public void initialize(Order order) {
valueList = new ArrayList<String>();
for (String val : order.accepts()) {
valueList.add(val.toUpperCase());
}
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if (!valueList.contains(s.toUpperCase())) {
return false;
}
return true;
}
}
```
3. 使用注解
```
@RestController
@RequestMapping("/wx/topic")
@Validated
public class WxTopicController {
@GetMapping("list")
public Object list(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
...
}
```
#### 2.3.8.2 Sort
校验用户请求参数值只能是`add_time`或者`id`。
1. 定义注解Sort
```
@Target({METHOD, FIELD, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = SortValidator.class)
public @interface Sort {
String message() default "排序字段不支持";
String[] accepts() default {"add_time", "id"};
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
```
2. 实现SortValidator
```
public class SortValidator implements ConstraintValidator<Sort, String> {
private List<String> valueList;
@Override
public void initialize(Sort sort) {
valueList = new ArrayList<String>();
for (String val : sort.accepts()) {
valueList.add(val.toUpperCase());
}
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if (!valueList.contains(s.toUpperCase())) {
return false;
}
return true;
}
}
```
3. 使用注解
```
@RestController
@RequestMapping("/wx/topic")
@Validated
public class WxTopicController {
@GetMapping("list")
public Object list(@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit,
@Sort @RequestParam(defaultValue = "add_time") String sort,
@Order @RequestParam(defaultValue = "desc") String order) {
...
}
```
## 2.4 litemall-all
在章节1.5中讨论的部署方案中设计了一种单服务器单服务方案,
也就是说两个后台服务和静态文件都部署在一个Spring Boot可执行jar包中。
查看litemall-all模块,代码仅仅只有一个Application类。
实际的原理是litemall-all模块内的pom.xml文件:
1. 打包方式是`jar`,因此最后会打包可执行jar格式;
2. 对litemall-wx-api模块和litemall-admin-api模块依赖,
因此打包时会作为依赖库而打包到litemall-all模块的输出中;
3. 使用copy-resources插件,在打包时把litemall-admin模块的dist
文件夹拷贝到litemall-all模块的static文件夹中;而这个文件夹
正是Spring Boot应用的默认静态文件路径。
注意:
> 这个插件只是简单的拷贝操作;因此开发者应该在打包litemall-all
> 之前确保先编译litemall-admin模块得到最终静态文件。
## 2.5 litemall-all-war
litemall-all-war模块就是对litemall-all模块进行少量调整,
最后打包时会在target目录下面生成litemall.war,用于tomcat部署。
================================================
FILE: doc/project.md
================================================
# 1 litemall系统
## 1.1 简介
litemall是一个简单的商场系统,基于现有的开源项目,重新实现一个完整的前后端项目,包含小程序客户端、移动客户端和网页管理端。

项目的架构是四个系统和九个模块:
* 基础系统子系统(platform)
由数据库、litemall-core模块、litemall-db模块和litemall-all模块组成;
* 小商场子系统(wxmall,即weixin mall)
由litemall-wx-api模块、litemall-wx模块和renard-wx模块组成;
* 轻商城子系统(mobmall,即mobile mall)
由litemall-wx-api模块和litemall-vue模块组成。
注意,目前这里移动商城子系统的后端和小商场子系统是一样的。
* 管理后台子系统(admin)
由litemall-admin-api模块和litemall-admin模块组成。
而九个模块的开发设计到三种技术栈:
* Spring Boot技术栈
采用IDEA开发工具,开发litemall-core、litemall-db、litemall-admin-api、
litemall-wx-api和litemall-all共五个模块;
* miniprogram(微信小程序)技术栈
采用微信小程序开发工具,开发litemall-wx模块和renard-wx模块;
* Vue技术栈
采用VSC开发工具,开发litemall-admin模块和litemall-vue模块。
### 1.1.1 项目特点
项目存在以下特点:
* 数据库方面,只是简单的表,表和表之间的依赖关系没有采用外键设计,而是依赖Java代码在service层面或者业务层面保证。这样做的好处是数据库频繁改动很方便,不会因为外键而导致数据库难以修改;
* 涉及三种技术栈,但是每种技术栈仅涉及最基础的技术;
* 后端技术栈,仅涉及 Spring,Spring Boot, Spring MVC和Mybatis技术,其他后端技术暂时不采用;
* 小程序技术栈,仅涉及miniprogram官方文档;
* 前端技术栈,仅涉及vue, vuex, vue-route和element技术;
* 安全方面,仅采用最基本的代码,提供简单基本的安全服务;
* 性能方面,没有涉及内存数据库缓存功能,而是完全依赖MySQL;
* 对象存储服务方面,支持本地存储和第三方云存储方案。
* 消息通知方面,支持邮件通知、第三方云短信通知和微信模板通知;
* 部署方便,支持多服务部署和一键部署脚本;
* 文档全面,虽然还在开发中,但是规划中文档和代码注释一定会完成,帮助开发者理解项目。
总之,目前的系统只是为了学习技术和业务而开发的一个简单商场原型系统。虽然缺失很多企业级功能,但是是完整和合理的原型系统。
注意:
> 以上特点并不一定是优点。
## 1.2 系统功能
从业务功能上,目前由六个业务模块组成:
* 会员业务模块
* 商场业务模块
* 商品业务模块
* 推广业务模块
* 系统业务模块
* 配置业务模块
### 1.2.1 小商城功能
* 首页
* 专题列表、专题详情
* 分类列表、分类详情
* 品牌列表、品牌详情
* 新品首发、人气推荐
* 团购
* 搜索
* 商品详情
* 商品评价列表、商品评价
* 购物车
* 下单
* 个人
* 订单列表、订单详情、订单售后
* 地址列表、地址添加、地址删除
* 收藏、足迹、关于
### 1.2.2 轻商城功能
**目前还在开发中,不稳定**
以下是准备完成的功能:
* 首页
* 专题列表、专题详情
* 分类列表、分类详情
* 品牌列表、品牌详情
* 新品首发、人气推荐
* 团购
* 搜索
* 商品详情
* 商品评价列表、商品评价
* 购物车
* 下单
* 个人
* 订单列表、订单详情
* 地址列表、地址添加、地址删除
* 收藏、足迹、关于
### 1.2.3 管理平台功能
* 会员管理
* 会员管理
* 收货地址
* 会员收藏
* 会员足迹
* 搜索历史
* 意见反馈
* 商城管理
* 行政区域
* 品牌制造商
* 订单管理
* 商品类目
* 通用问题
* 关键词
* 渠道管理(待定)
* 商品管理
* 商品列表
* 商品上架
* 商品编辑
* 用户评论
* 推广管理
* 广告管理
* 专题管理
* 团购规则
* 团购活动
* 系统管理
* 管理员
* 通知管理
* 对象存储
* 权限管理
* 定时任务(待定)
* 操作日志
* 配置管理
* 商场配置
* 小程序配置
* 运费配置
* 订单配置
* 统计报表
* 用户统计
* 订单统计
* 商品统计
* 个人
* 通知中心
* 密码修改
## 1.3 项目技术
### 1.3.1 技术参考
#### 1.3.1.1 Spring Boot技术
Spring Boot技术栈参考以下文档或者项目:
1. MySQL
了解创建数据库和表、添加、查询、更新和删除即可。
2. Spring Boot 2.x
* https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#getting-started-introducing-spring-boot
* https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#using-boot-maven
这里需要了解RestController, Service等注解,以及如何使用自动化配置。
Spring Boot支持很多功能,开发者使用时查阅。
3. Mybatis
* http://www.mybatis.org/mybatis-3/
* http://www.mybatis.org/mybatis-3/java-api.html
* http://www.mybatis.org/mybatis-3/sqlmap-xml.html
这里可以简单了解,而使用Mybatis Generator来生成Java代码使用即可。
4. Mybatis Generator
* http://www.mybatis.org/generator/running/runningWithMaven.html
* http://www.mybatis.org/generator/generatedobjects/results.html
* http://www.mybatis.org/generator/generatedobjects/exampleClassUsage.html
5. Mybatis PageHelper
* https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/en/HowToUse.md
#### 1.3.1.2 小程序技术
1. 小程序
* https://developers.weixin.qq.com/miniprogram/dev/index.html
* https://developers.weixin.qq.com/miniprogram/dev/component/
* https://developers.weixin.qq.com/miniprogram/dev/api/
* https://developers.weixin.qq.com/community/develop
建议小程序方面遇到问题,可以到官方社区查找。
2. 微信支付
* https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1
#### 1.3.1.3 Vue技术
1. Vue
* https://cn.vuejs.org/index.html
2. Vant
* https://youzan.github.io/vant/#/zh-CN/intro
3. Element
* https://element.eleme.cn/#/zh-CN/component/installation
4. vue-element-admin
* https://github.com/PanJiaChen/vue-element-admin
* https://panjiachen.github.io/vue-element-admin-site/zh/
### 1.3.2 项目阶段
接下来,从项目的开发、部署(测试)和上线三个阶段介绍litemall。

首先需要明确的是三个不同阶段:
* dev
即develop或者development, 这里指开发阶段,通常代码是直接在本地编译、运行和测试。
此外,这里服务访问地址通常是localhost。这里的“用户”主要是指开发者本身。
* dep
即deploy或者deployment,这里指部署(测试阶段),通常代码已经编译打包运行在远程服务器中,
可以对外服务。此外,这里服务访问地址通常是IP地址。如果IP是公网IP,那么
部署以后就可以对外服务;如果是内网地址,那么只能内网访问。这里的“用户”主要是
指开发者本身、测试者;当然,如果是局域网或者不介意IP访问的,那么这里的“用户”
也可能是最终使用者用户。
* prod
即product或者production,这里指上线阶段,通常也是代码编译打包运行在远处服务器中可以对外服务。
此外,这里服务访问地址通常是域名地址,同时端口是80web端口。上线以后直接面向的是最终用户。
虽然服务的代码本身和dep是完全一样的,但是考虑到场景的不同,上线阶段可能在运行环境方面需要做
调整,例如采用反向代理屏蔽内部实际项目结构。此外,最大的不同应该是上线环境下要使用域名和80端口,
而部署阶段则更为自由。
其次,需要明确的是,这里划分三种阶段不是简单的文档说明,还直接影响项目本身的行为
和代码编译结果,因此开发者需要清晰的了解;
最后,其实dep和prod不存在先后关系。例如,如果开发者已经存在域名和生产环境,可以直接
跳过dep阶段,而直接部署在线上环境中。因此有些时候,这里部署和上线是一个阶段。
当然,这里仍然建议先dep后prod,是因为对于第一次开发而言,先dep阶段可以避免对域名、https证书等非业务相关工作的干扰。
此外,有些业务功能(例如微信支付)必须是域名访问,那么开发和部署阶段可以先采用模拟或跳过的形式,
先不开发和测试这样业务功能,等其他功能开发完毕和部署测试成功以后,再来开发这些线上环境才能
运行的功能,此时会有一个好的基础。
接下来,分别从开发阶段、部署阶段和上线阶段三种阶段,分别介绍不同的方案实践要点。
## 1.4 开发方案

如图所示,当前开发阶段的方案:
* MySQL数据访问地址`jdbc:mysql://localhost:3306/litemall`
* litemall-wx-api后端服务地址`http://localhost:8080/wx`,数据则来自MySQL
* litemall-admin-api后端服务地址`http://localhost:8080/admin`,数据则来自MySQL
* litemall-admin前端访问地址`http://localhost:9527`, 数据来自litemall-admin-api
* litemall-wx没有前端访问地址,而是直接在微信小程序工具上编译测试开发,最终会部署到微信官方平台(即不需要自己部署web服务器),而数据则来自litemall-wx-api
### 1.4.1 数据库
数据库环境设置过程如下:
1. 安装MySQL;
2. 创建数据库、用户权限、数据库表和测试数据;
数据库文件存放在litemall-db/sql文件夹中,请开发者在MySQL中
按照顺序运行以下脚本:
* litemall_schema.sql,用于创建数据库、用户和权限;
* litemall_table.sql,用于创建表;
* litemall_data.sql,用于导入测试数据。
注意:
> 建议采用命令行或者MySQL Workbench。如果采用Navicat可能导入失败。
如果开发者运行litemall_schema.sql失败,可以打开该文件:
```
drop database if exists litemall;
drop user if exists 'litemall'@'%';
create database litemall default character set utf8mb4 collate utf8mb4_unicode_ci;
use litemall;
create user 'litemall'@'%' identified by 'litemall123456';
grant all privileges on litemall.* to 'litemall'@'%';
flush privilege
```
可以看到几个命令,用于创建数据库、用户和访问权限,因此开发者可以利用
命令或者工具完成这里的功能即可。
### 1.4.2 Spring Boot开发环境
1. 安装JDK8(可以是Oracle JDK或者OpenJDK)
2. 安装Maven
3. 安装Git(可选)
4. 安装IDEA Community,建议安装Maven插件和Git插件。
这里IDEA社区版即可,不要求IDEA商业版。
Eclipse没有试过,但应该也是可行的。
5. IDEA导入本项目
6. 采用Maven命令安装依赖库
例如:
```
cd litemall
mvn install
```
或者采用IDEA的Maven插件安装本项目依赖库,点击`install`

7. 采用Maven命令编译本项目
例如:
```
cd litemall
mvn compile
```
此时可以看到,litemall-wx-api等模块多了target文件夹,里面是编译出的文件。
或者采用IDEA的Maven插件编译本项目,点击`compile`
如果采用IDEA也可以跳过当前步骤,直接步骤8(因为运行时会自动编译再运行)。
8. 采用Maven命令运行本项目的litemall-all
例如:
```
cd litemall/litemall-all
mvn spring-boot:run
```
如果采用IDEA,则litemall-all模块的Application类
右键` Run Application.main()`方式运行该模块,

打开浏览器,输入
```
http://localhost:8080/wx/index/index
http://localhost:8080/admin/index/index
```
如果出现JSON数据,则litemall-all模块运行正常。
注意:
> 1. 上述步骤中,既介绍了Maven命令方式,也介绍了IDEA方式,
> 但是建议开发者开发阶段采用IDEA。
> 2. 上述步骤只是一种实践方式,开发者可不拘泥于这些步骤,多实践。
> 当然,如果开发者不采用这里步骤而出现问题,请自行解决。
> 3. 开发者使用IDEA导入项目或者运行项目时可能会出现**软件卡顿**的现象,这通常是litemall-admin或者litemall-vue的
> node_modules文件夹内自动下载了大量的依赖库,当IDEA尝试索引该文件夹内的大量文件时
> 则出现IDEA卡顿的现象,具体解决方式可以参见[FAQ](./FAQ.md)
### 1.4.3 微信小程序开发环境
1. 安装微信小程序开发工具;
2. 导入本项目的litemall-wx模块(或者renard-wx模块)文件夹;
3. 编译前,请确定litemall-all模块已经运行,而litemall-wx模块的config文件夹中的api.js已经设置正确的后端数据服务地址;
4. 点击`编译`,如果出现数据和图片,则运行正常
注意:
> 开发者编译以后,可以看到图片和数据,但是采用微信登录或者微信支付是肯定会失败的。
> 原因是这里的配置信息没有正确设置,例如appid,具体详细配置见1.4.5节。
### 1.4.4 Vue开发环境
1. 安装[nodejs](https://nodejs.org/en/)
2. 安装依赖库
```
cd litemall/litemall-admin
npm install --registry=https://registry.npm.taobao.org
```
3. 编译并运行
```
npm run dev
```
然后,打开浏览器,输入`http://localhost:9527`。
如果出现管理后台登录页面,则表明管理后台的前端运行正常;
4. 请确定litemall-all模块已经运行,然后点击`登录`,如果能够成功登录,则表明管理后台的前端和后端对接成功,运行正常。
本项目采用VSC(Visual Studio Code)开发litemall-admin模块,开发者也可以采用其他熟悉的IDE。
### 1.4.5 项目配置
当安装好Spring Boot开发环境、Vue开发环境和小程序开发环境以后,启动相应的模块,已经可以看到一些数据或者效果。
但是还有一些特性或者功能没有启动,这是因为需要开发者进行配置才能正确启用。
**项目配置结构**
1. 管理后台前端,即litemall-admin模块,配置文件在litemall-admin中,存在三个配置文件`env.development`,`env.deployment`
和`.env.production`。这里面配置信息都是一样,最主要的配置是`VUE_APP_BASE_API`,即管理后台的服务根地址。
* 开发阶段,开发者运行命令`npm run dev`,这里就会采用`env.development`配置文件;
* 部署阶段,当开发者运行命令`npm run build:dep`,这里就会采用`env.deployment`配置文件;
* 上线阶段,当开发者运行命令`npm run build:prod`,这里就会采用`.env.production`配置文件。
2. 小商场前端,即litemall-wx模块,配置文件是`litemall-wx/project.config.json`和`litemall-wx/api.js`。
这里面最主要的配置信息是`project.config.json`中的`appid`,开发者需要设置自己申请的appid;
以及`apis.js`中的`WxApiRoot`,即小商场服务根地址。
```
// 本机开发时使用
var WxApiRoot = 'http://localhost:8080/wx/';
// 局域网测试使用
// var WxApiRoot = 'http://192.168.0.101:8080/wx/';
// 云平台部署时使用
// var WxApiRoot = 'http://122.51.199.160:8080/wx/';
// 云平台上线时使用
// var WxApiRoot = 'https://www.menethil.com.cn/wx/';
```
3. 管理后台后端和小商城后端,即多个Spring Boot模块,配置文件是每个模块的`litemall-xx/src/main/java/resources`的
`application.yml`和`application-xx.yml`配置文件。这里会发现每个模块都会有两个配置文件,但是实际上当前模块的配置信息
都是在`application-xx.yml`文件中,而`application.yml`文件仅仅用于引入其他模块的配置文件。
例如litemall-all模块的`application.yml`的内容是
```
spring:
profiles:
active: db, core, admin, wx
message:
encoding: UTF-8
```
因此启动litemall-all模块时,程序首先加载litemall-all的`application.yml`,然后通过`spring.profiles.active`信息
再次依次加载`application-db.yml`,`application-core.yml`,`application-admin.yml`和`application.yml-wx`四个配置文件。
这里后端服务模块的配置如下所示。
#### 1.4.5.1 日志配置
如果开发者启动litemall-all模块,则需要配置该模块的`logback-spring.xml`文件
```
<logger name="org.mybatis" level="ERROR" />
<logger name="org.springframework" level="ERROR" />
<logger name="org.linlinjava.litemall.core" level="DEBUG" />
<logger name="org.linlinjava.litemall.db" level="DEBUG" />
<logger name="org.linlinjava.litemall.admin" level="DEBUG" />
<logger name="org.linlinjava.litemall.wx" level="DEBUG" />
<logger name="org.linlinjava.litemall" level="DEBUG" />
```
具体如何配置,请自行学习Spring Boot的日志配置和logback日志配置。
`org.linlinjava.litemall.core`定义litemall-core模块的日志级别
`org.linlinjava.litemall.db`定义litemall-db模块的日志级别
`org.linlinjava.litemall.wx`定义litemall-wx-api模块的日志级别
`org.linlinjava.litemall.admin`定义litemall-admin-api模块的日志级别
`org.linlinjava.litemall`而定义litemall所有后端模块的日志级别
当然,如果开发者这里启动litemall后端模块级别是DEBUG时,可能会发现并没有很多日志,
这是因为代码内部没有写很多日志,开发者可以根据需要添加。
注意:
> 如果开发者独立启动litemall-wx-api模块,那么则需要配置litemall-wx-api模块的
> 日志配置方式。
#### 1.4.5.2 数据库连接配置
在litemall-db模块的`application-db.yml`文件中配置数据库连接和druid:
```
spring:
datasource:
druid:
url: jdbc:mysql://localhost:3306/litemall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&verifyServerCertificate=false&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: litemall
password: litemall123456
initial-size: 10
max-active: 50
min-idle: 10
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
validation-query: SELECT 1 FROM DUAL
test-on-borrow: false
test-on-return: false
test-while-idle: true
time-between-eviction-runs-millis: 60000
filters: stat,wall
```
#### 1.4.5.3 微信登录配置
微信登录需要配置两个地方,
首先是小商场前端litemall-wx模块(或renard-wx模块)中`project.config.json`文件的appid
其次是小商场后端litemall-core模块的`application-core.yml`文件:
```bash
litemall:
wx:
app-id: wxa5b486c6b918ecfb
app-secret: e04004829d4c383b4db7769d88dfbca1
```
这里的`app-id`和`app-secret`需要开发者在[微信公众平台](https://mp.weixin.qq.com/)注册获取。
注意
> 这里开发者可能会疑惑:小商场后端应该配置在litemall-wx-api模块的`application-wx.yml`文件更合适。
> 这里放置在`application-core.yml`文件中是因为litemall-core模块也依赖小程序appid配置信息。
#### 1.4.5.4 微信支付配置
在litemall-core模块的`application-core.yml`文件中配置微信支付:
```
litemall:
wx:
mch-id: 111111
mch-key: xxxxxx
notify-url: https://www.example.com/wx/order/pay-notify
```
这里的`mch-id`和`mch-key`需要开发者在[微信商户平台](https://pay.weixin.qq.com/)注册获取。
而这里的`notify-url`则应该是项目上线以后微信支付回调地址,当微信支付成功或者失败,
微信商户平台将向回调地址发生成功或者失败的数据,因此需要确保该地址是
litemall-wx-api模块的WxOrderController类的payNotify方法所服务的API地址。
开发阶段可以采用一些技术实现临时外网地址映射本地,开发者可以百度关键字“微信 内网穿透”自行学习。
#### 1.4.5.5 邮件通知配置
在litemall-core模块的`application-core.yml`文件中配置邮件通知服务:
```
litemall:
notify:
mail:
# 邮件通知配置,邮箱一般用于接收业务通知例如收到新的订单,sendto 定义邮件接收者,通常为商城运营人员
enable: false
host: smtp.exmail.qq.com
username: ex@ex.com.cn
password: XXXXXXXXXXXXX
sendfrom: ex@ex.com.cn
sendto: ex@qq.com
```
配置方式:
1. 邮件服务器开启smtp服务
2. 开发者在配置文件中设置`enable`的值`true`,然后其他信息设置相应的值。
这里只测试过QQ邮箱,开发者需要自行测试其他邮箱。
应用场景:
目前邮件通知场景也很简单,就是用户下单以后系统会自动向`sendto`用户发送一封邮件,告知用户下单的订单信息。
以后可能需要继续优化扩展。当然,如果不需要邮件通知订单信息,可以默认关闭即可。
验证配置成功:
当配置好信息以后,开发者可以运行litemall-core模块的`MailTest`测试类,
独立发送邮件,然后登录邮箱查看邮件是否成功接收。
#### 1.4.5.6 短信通知配置
在litemall-core模块的`application-core.yml`文件中配置短信通知服务:
```
litemall:
notify:
# 短消息模版通知配置
# 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
sms:
enable: false
# 如果是腾讯云短信,则设置active的值tencent
# 如果是阿里云短信,则设置active的值aliyun
active: tencent
sign: litemall
template:
- name: paySucceed
templateId: 156349
- name: captcha
templateId: 156433
- name: ship
templateId: 158002
- name: refund
templateId: 159447
tencent:
appid: 111111111
appkey: xxxxxxxxxxxxxx
aliyun:
regionId: xxx
accessKeyId: xxx
accessKeySecret: xxx
```
配置方式:
1. 腾讯云短信平台或者阿里云短信平台申请,然后设置四个场景的短信模板;
2. 开发者在配置文件设置`enable`的值`true`,设置`active`的值`tencent`或`aliyun`
3. 然后配置其他信息,例如腾讯云短信平台申请的appid等值。
这里只测试过腾讯云短信平台和阿里云短信平台,开发者需要自行测试其他短信云平台。
应用场景:
目前短信通知场景只支持支付成功、验证码、订单发送、退款成功四种情况。
以后可能需要继续优化扩展。
验证配置成功:
当配置好信息以后,开发者可以litemall-core模块的`SmsTest`测试类中设置手机号和
模板所需要的参数值,独立启动`SmsTest`测试类发送短信,然后查看手机是否成功接收短信。
短信模板参数命名:
这里存在一个问题,即腾讯云短信的官方平台中申请短信模板格式的模板参数是数组,
例如“你好,验证码是{0},时间是{1}";
而阿里云短信的官方平台中申请短信模板的模板参数是JSON,
例如“你好,验证码是{param1},时间是{param2}"。
为了保持当前代码的通用性,本项目采用数组传递参数,而对阿里云申请模板的参数做了一定的假设:
1. 腾讯云模块参数,申请模板时按照官方设置即可,例如“你好,验证码是{0},时间是{1}";
2. 阿里云模板参数,本项目假定开发者在官方申请的参数格式应该采用"{ code: xxx, code1: xxx, code2: xxx }",
例如“你好,验证码是{code},时间是{code1}"。开发者可以查看`AliyunSmsSender`类的`sendWithTemplate`方法的
源代码即可理解。如果觉得不合理,可以自行调整相关代码。
#### 1.4.5.8 物流配置
物流配置是查询商品物流信息,这里主要是基于[第三方快递鸟服务](http://www.kdniao.com/api-track)。
在litemall-core模块的`application-core.yml`文件中配置快递鸟物流服务:
```
litemall:
notify:
# 快鸟物流查询配置
express:
enable: false
appId: "XXXXXXXXX"
appKey: "XXXXXXXXXXXXXXXXXXXXXXXXX"
vendors:
- code: "ZTO"
name: "中通快递"
- code: "YTO"
name: "圆通速递"
- code: "YD"
name: "韵达速递"
- code: "YZPY"
name: "邮政快递包裹"
- code: "EMS"
name: "EMS"
- code: "DBL"
name: "德邦快递"
- code: "FAST"
name: "快捷快递"
- code: "ZJS"
name: "宅急送"
- code: "TNT"
name: "TNT快递"
- code: "UPS"
name: "UPS"
- code: "DHL"
name: "DHL"
- code: "FEDEX"
name: "FEDEX联邦(国内件)"
- code: "FEDEX_GJ"
name: "FEDEX联邦(国际件)"
```
配置方式:
1. [快递鸟平台](http://www.kdniao.com/)申请;
2. 开发者在配置文件设置`enable`的值`true`,然后其他信息设置
快递鸟平台中的appId和appKey。
应用场景:
小商场查询订单详情时,如果商品已发货,小商城后端会返回详细物流信息。
验证配置成功:
当配置好信息以后,开发者可以litemall-core模块的`ExpressTest`测试类中设置快递公司编码和
真实测试快递单号,独立启动`ExpressTest`测试类查询物流信息。
注意:
> 一部分快递公司(例如顺丰速运、申通快递等)的轨迹查询在开发环境下不支持,
> 具体支持情况或者使用限制请阅读[官方资料](http://www.kdniao.com/UserCenter/v2/UserHome.aspx)
#### 1.4.5.9 对象存储配置
对象存储,即存储和下载文件。
在litemall-core模块的`application-core.yml`文件中配置对象存储服务:
* 本地对象存储配置
如果开发者采用当前服务器保存上传的文件,则需要配置:
```
litemall:
storage:
# 当前工作的对象存储模式,分别是local、aliyun、tencent、qiniu
active: local
# 本地对象存储配置信息
local:
storagePath: storage
# 这个地方应该是wx模块的WxStorageController的fetch方法对应的地址
address: http://localhost:8080/wx/storage/fetch/
```
配置方式:
配置文件设置`active`的值`local`,表示当前对象存储模式是本地对象存储;
而`storagePath`是上传文件保存的路径;`address`则是访问文件的对外路径。
* 阿里云对象存储配置
```
litemall:
storage:
# 当前工作的对象存储模式,分别是local、aliyun、tencent、qiniu
active: aliyun
aliyun:
endpoint: oss-cn-shenzhen.aliyuncs.com
accessKeyId: 111111
accessKeySecret: xxxxxx
bucketName: litemall
```
配置方式:
1. 阿里云官网注册
2. 配置文件设置`active`的值`aliyun`,表示当前对象存储模式是阿里云对象存储;
* 腾讯云对象存储配置
```
litemall:
storage:
# 当前工作的对象存储模式,分别是local、aliyun、tencent、qiniu
active: tencent
# 腾讯对象存储配置信息
# 请参考 https://cloud.tencent.com/document/product/436/6249
tencent:
secretId: 111111
secretKey: xxxxxx
region: xxxxxx
bucketName: litemall
```
配置方式:
1. 腾讯云官网注册
2. 配置文件设置`active`的值`tencent`,表示当前对象存储模式是腾讯云对象存储;
* 七牛云对象存储配置
```
litemall:
storage:
# 当前工作的对象存储模式,分别是local、aliyun、tencent、qiniu
active: qiniu
# 七牛云对象存储配置信息
qiniu:
endpoint: http://pd5cb6ulu.bkt.clouddn.com
accessKey: 111111
secretKey: xxxxxx
bucketName: litemall
```
配置方式:
1. 七牛云官网注册
2. 配置文件设置`active`的值`qiniu`,表示当前对象存储模式是七牛云对象存储;
#### 1.4.5.10 其他配置
除上述配置信息,本项目还存在其他配置。
目前仅采用默认值即可,开发者可以自己实践或者扩展新的配置信息。
## 1.5 部署方案
在1.4节中介绍的是开发阶段时一些关键性开发流程。本节将介绍代码开发成功以后开始部署项目时一些关键性流程。
首先,需要明确的是开发时项目使用的服务地址是本地地址,即localhost;而部署时则应该根据具体情况设置合理的服务器地址和端口。
其次,需要明确的是各模块之间的关系:
* litemall-wx-api模块会包含litemall-core模块和litemall-db模块,部署在服务器中
* litemall-admin-api模块会包含litemall-core模块和litemall-db模块,部署在服务器中
* litemall-all模块则会包装litemall-wx-api模块和litemall-admin-api模块;
* litemall-wx模块部署在微信开发者工具中,此外数据API地址指向litemall-wx-api所在服务qi地址
* litemall-admin编译出的静态文件放在web服务器或者tomcat服务器,此外服务器地址设置指向3中litemall-admin-api所在地址
最后,**如果项目部署云服务器,则根据开发者的部署环境在以下文件中或代码中修改相应的配置。**
1. MySQL数据库设置合适的用户名和密码信息;
2. 后端服务模块设置合适的配置信息;
3. 小商场前端litemall-wx模块`config/api.js`的`WxApiRoot`设置小商场后端服务的服务地址;
4. 管理后台前端litemall-admin模块`.env.deployment`中的`VUE_APP_BASE_API`设置管理后台后端服务的服务地址。
实际上,最终的部署方案是灵活的:
* 可以是同一云服务器中安装一个Spring Boot服务,同时提供litemall-admin、litemall-admin-api和litemall-wx-api三种服务
* 可以单一云服务器中仅安装一个tomcat/nginx服务器部署litemall-admin静态页面分发服务,
然后部署两个Spring Boot的后端服务;
* 也可以把litemall-admin静态页面托管第三方cdn,然后开发者部署两个后端服务
* 当然,甚至多个服务器,采用集群式并发提供服务。
注意
> 1. `本机`指的是是当前的开发机
> 2. `云服务器`指的是开发者购买并部署的远程服务器
以下简单列举几种方案。
### 1.5.1 单机单服务部署方案
本节介绍基于腾讯云的单机单服务部署方案,面向的是服务器数据和应用部署在云服务器单机中用于演示的场景。
其他云应该也是可行的。
主要流程是:创建云服务器,安装ubuntu操作系统,按照JDK和MySQL应用运行环境,部署单一Spring Boot服务。

#### 1.5.1.1 云服务器
1. 创建云服务器
请参考腾讯云、阿里云或者其他云平台的官方文档进行相关操作。
建议最低配置是**1核2G**。
2. 安装操作系统
本项目采用ubuntu 16.04.1,但是并不限制其他操作系统。
3. 创建安全组

目前允许的端口:8080,80,443,22,3306
注意:
这里其实只需要8080端口,允许其他端口只是方便开发阶段的测试和调试。
特别是3306端口,作为MySQL的远程访问端口,请在上线阶段关闭。
4. 设置SSH密钥(可选)
建议开发者设置SSH密钥,可以免密码登录云服务器,以及用于脚本自动上传应用。
5. 使用PuTTY远程登录云服务器
如果开发者设置SSH密钥,可以采用免密码登录;否则采用账号和密码登录。
#### 1.5.1.2 OpenJDK8
这里可以安装openjdk-8-jre
```bash
sudo apt-get update
sudo apt-get install openjdk-8-jre
```
如果希望采用jdk,而不是jre,则可以运行
```bash
sudo apt-get update
sudo apt-get install openjdk-8-jdk
```
注意
> 如果用户想采用Oracle JDK8或者其他JDK环境,请查阅相关资料安装。
#### 1.5.1.3 MySQL
```
sudo apt-get update
sudo apt-get install mysql-server
sudo apt-get install mysql-client
```
如果配置MySQL,可以运行命令
```
sudo mysql_secure_installation
```
#### 1.5.1.4 项目打包
1. 在服务器或者开发机打包项目到deploy;
```
cd litemall
cat ./litemall-db/sql/litemall_schema.sql > ./deploy/db/litemall.sql
cat ./litemall-db/sql/litemall_table.sql >> ./deploy/db/litemall.sql
cat ./litemall-db/sql/litemall_data.sql >> ./deploy/db/litemall.sql
cd ./litemall-admin
npm install --registry=https://registry.npm.taobao.org
npm run build:dep
cd ..
mvn clean package
cp -f ./litemall-all/target/litemall-all-*-exec.jar ./deploy/litemall/litemall.jar
```
这里脚本的作用是:
1. 把数据库文件拷贝到deploy/db文件夹;
2. 编译litemall-admin项目;
3. 编译litemall-all模块,同时把litemall-admin编译得到的静态文件拷贝到
litemall-all模块的static目录。
2. 修改litemall文件夹下面的*.yml外部配置文件,当litemall-all模块启动时会
加载外部配置文件,而覆盖默认jar包内部的配置文件。
例如,配置文件中一些地方需要设置成远程服务器的IP地址
此时deploy部署包结构如下:
* bin
存放远程服务器运行的脚本,包括deploy.sh脚本和reset.sh脚本
* db
存放litemall数据库文件
* litemall
存放远程服务器运行的代码,包括litemall-all二进制可执行包和litemall外部配置文件
* util
存放开发服务器运行的脚本,包括package.sh脚本和lazy.sh脚本。
由于是本地开发服务器运行,因此开发者可以不用上传到远程服务器。
#### 1.5.1.5 项目部署
1. 远程服务器环境(MySQL和JDK1.8)已经安装好,请确保云服务器的安全组已经允许相应的端口。
2. 导入db/litemall.sql
```bash
cd /home/ubuntu/deploy/db
mysql -h localhost -u $ROOT -p$PASSWORD < litemall.sql
```
3. 启动服务
```bash
sudo service litemall stop
sudo ln -f -s /home/ubuntu/deploy/litemall/litemall.jar /etc/init.d/litemall
sudo service litemall start
```
4. 测试是否部署成功(xxx.xxx.xxx.xxx是云服务器IP):
```
http://xxx.xxx.xxx.xxx:8080/wx/index/index
http://xxx.xxx.xxx.xxx:8080/admin/index/index
http://xxx.xxx.xxx.xxx:8080/#/login
```
注意:
> 开发者访问以上三个地址都能成功,但是管理后台点击登录时会报错网络连接不成功。
> 这里很可能是开发者litemall-admin模块的`config/dep.env.js`或者`condig/prod.env.js`
> 没有设置正确的管理后台后端地址,例如这里的`http://xxx.xxx.xxx.xxx:8080/admin`
#### 1.5.1.6 deploy部署脚本
在前面的项目打包和项目部署中都是采用手动命令来部署。
这里可以写一些脚本简化:
* util/packet.sh
在开发服务器运行可以自动项目打包
* util/lazy.sh
在开发服务器运行可以自动项目打包、项目上传远程服务器、自动登录系统执行项目部署脚本。
注意:
> 1. 开发者需要在util/lazy.sh中设置相应的远程服务器登录账号和密钥文件路径。
> 2. 开发者需要在bin/reset.sh设置远程服务器的MySQL的root登录账户。
* bin/deploy.sh
在远程服务器运行可以自动部署服务
* bin/reset.sh
在远程服务器运行可以自动项目导入数据、删除本地上传图片、再执行bin/deploy.sh部署服务。
注意:
> 开发者需要在bin/reset.sh设置远程服务器的MySQL的root登录账户。
总结,当开发者设置好配置信息以后,可以在本地运行lazy.sh脚本自动一键部署:
```bash
cd litemall
./deploy/util/lazy.sh
```
不过由于需要设置的信息会包含敏感安全信息,强烈建议开发者参考这里的deploy文件夹,
然后实现自己的deploy文件夹,妥善处置外部配置文件和脚本中的敏感安全信息!!!
#### 1.5.1.7 docker部署脚本
本项目也简单实现了docker部署方案,具体可以看docker文件夹。
### 1.5.2 单机多服务部署方案
### 1.5.3 集群式云部署方案
由于本项目是面向微小型企业的小商城系统,因此预期的分布式部署方案是
1. 专门的云数据库部署数据
2. 专门的云存储方案
3. 专门的CDN分发管理后台的静态文件
4. 一台云服务器部署管理后台的后端服务
5. 一台或多台云服务器部署小商场的后端服务
虽然由于环境原因没有正式测试过,但是这种简单的集群式场景应该是可行的。
在1.5.2节中所演示的三个服务是独立的,因此延伸到这里分布式是非常容易的。
但是,如果需要实现互联网式分布式云部署,目前的项目架构和方案不支持。
至少每个功能模块应该是独立服务系统。此外,需要引入单点登录系统、集群、缓存
和消息队列等多种技术。因此如果开发者需要这种形式的分布式方案,请参考其他项目。
## 1.6 上线方案
在1.5节部署方案中,我们介绍了多种部署的方案,但是实际上这些方案都不能立即用于正式环境:
1. 正式环境需要域名和HTTPS证书
2. 小商场的小程序端对服务器域名存在接入要求。
本节采用`www.example.com`域名作为示例。
注意
> `www.example.com`仅作为实例,不是真实环境下的域名。
这里列举一种基于1.5.1的单机单服务上线方案,即一个all后端服务,同时提供三种数据:
* 提供管理后台的前端文件;
* 提供管理后台前端所需要的数据;
* 提供小商城前端所需要的数据。

开发者可以基于自身业务采用其他上线方案。
### 1.6.1 域名
1. 注册域名,通常商业性的网站采用`.com`
2. 解析域名到服务器公网IP,采用`ping`命令查看是否解析成功
3. 备案
### 1.6.2 nginx
https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-16-04
#### 1.6.2.1 nginx安装
采用命令
```bash
sudo apt-get update
sudo apt-get install nginx
```
有的文档会指出需要防火墙设置,但是腾讯云服务器防火墙默认没有开启。
开发者这里自己可以开启设置,或者直接不开启。
打开浏览器,输入以下地址:
```
http://www.example.com
```
此时,如果看到nginx的欢迎页面,则安装成功。
安装以后:
* `/var/www/html`:默认静态web文件目录
* `/etc/nginx`:
* `/etc/nginx/nginx.conf`:
* `/etc/nginx/sites-avaiable`:
* `/etc/nginx/sites-enabled`:
* `/etc/nginx/snippets`:
* `/var/log/nginx/access.log`:
* `/var/log/nginx/error.log`:
#### 1.6.2.2 https
1. 申请证书
可以参考[腾讯云 域名型证书申请流程](https://cloud.tencent.com/document/product/400/6814)
2. 下载证书
这里使用nginx文件夹下面的密钥文件,例如`1_www.example.com_bundle.crt`和`2_www.example.com.key`
3. 部署证书到nginx
可以参考[腾讯云 证书安装指引](https://cloud.tencent.com/document/product/400/4143)
把两个密钥文件保存的`/etc/nginx`文件夹,然后修改`/etc/nginx/nginx.conf`文件:
```
server {
listen 443;
server_name www.example.com;
ssl on;
ssl_certificate /etc/nginx/1_www.example.com_bundle.crt;
ssl_certificate_key /etc/nginx/2_www.example.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
}
```
4. 重启nginx
打开浏览器,输入以下地址:
```
https://www.example.com
```
此时,可以看到https协议的nginx欢迎页面。
#### 1.6.2.3 反向代理Spring Boot后端
修改`/etc/nginx/nginx.conf`文件,配置nginx静态web文件目录
```
server {
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
```
打开浏览器,输入以下地址:
```
https://www.example.com/wx/index/index
https://www.example.com/admin/index/index
https://www.example.com/admin/index/index
```
此时,看到后端数据说明反向代理配置成功。
#### 1.6.2.4 全站加密
服务器自动把http的请求重定向到https
```
server {
listen 80;
server_name www.example.com;
rewrite https://$server_name$request_uri? permanent;
}
```
打开浏览器,输入以下地址:
```
http://www.example.com
```
总结,经过以上不同方面的配置,nginx这里最终的配置是如下:
1. 证书`1_www.example.com_bundle.crt`和`2_www.example.com.key`放置在
`/etc/nginx/`文件夹内。
2. 把`/etc/nginx/nginx.conf`文件进行修改,具体可以参考[本项目的nginx.conf](./conf/nginx.conf)
3. 重启nginx
注意:
> 更多配置方法和功能,请开发者自行学习。
### 1.6.3 小商场上线
在1.6.2.3节"反向代理Spring Boot后端"成功以后,其实小商场的后端已经上线成功。
这里介绍小商场的前端上线过程:
上线之前需要修改代码或者配置文件:
1. litemall-wx-api模块的WxOrderController类的payNotify方法的链接换成合适的地址。
注意:
> 换成什么地址都可以,但是这里不应该暴露出来。也就是说这个地址是微信商户平台
> 和这里的小商场后端服务之间的交互API,对外公开会存在安全隐患。
2. litemall-core模块需要配置application-core.yml
```
litemall:
wx:
app-id: wxa5b486c6b918ecfb
app-secret: e04004829d4c383b4db7769d88dfbca1
mch-id: 111111
mch-key: xxxxxx
notify-url: http://www.example.com/wx/order/pay-notify
```
这里的`litemall.wx.notify-url`就是前面开发者自定义的地址。
3. litemall-wx模块的`project.config.json`文件调整相应的值,
特别是`appid`要设置成开发者申请的appid。
### 1.6.4 管理后台上线
在1.6.2.3节"反向代理Spring Boot后端"成功以后,其实管理后台已经上线成功,
包括管理后台的前端和后端,会同时对外提供管理后台的前端文件和后端数据。
当然,这里开发者需要自己的线上环境在以下文件中或代码中修改相应的配置。
1. MySQL数据库设置合适的用户名和密码信息;
2. 管理后台后端服务模块设置合适的配置信息,建议开发者参考deploy/litemall的外部配置文件,
这样可以避免开发者对模块内部的开发配置文件造成修改;
3. 管理后台前端litemall-admin模块`.env.production`中的`VUE_APP_BASE_API`设置管理后台后端服务的服务地址。
### 1.6.5 项目评估
本项目只是参考项目,项目代码质量和功能不可能符合开发者的最终需求,
因此开发者**请务必仔细评估项目代码**。
特别提醒,上线前管理员用户名和密码请更改,不能采用这里的默认值。
### 1.6.6 项目优化
以下是部署方案中出现而在上线方案中可以优化的一些步骤。
#### 1.6.6.1 管理后台前端文件启动优化
litemall-admin编译得到的前端文件在第一次加载时相当耗时,这里需要一些措施来优化启动速度
* 静态文件托管CDN
在上节中,采用Spring Boot来分发管理后台的静态文件。
这里可以进一步地,把静态文件托管到CDN,当然这里是需要收费。
* gzip压缩
* 动态加载
#### 1.6.6.2 后端服务内部访问
原来后端服务(包括小商城的后端服务和管理后台的后端服务)可以通过域名或者IP直接对外服务,而这里采用nginx反向代理后可以
通过80端口访问后端服务。因此,会存在这样一种结果:
* 用户可以https协议的80端口访问后端服务(nginx反向代理)
* 用户也可以通过http协议的8080访问后端服务(spring boot)
由于http不是安全的,这里可能存在安全隐患
而如果取消后端服务的对外访问,这样可以保证用户只能采用安全的https协议访问后端服务。
同时,对外也能屏蔽内部具体技术架构细节。
#### 1.6.6.4 nginx优化
建议开发者根据自己业务或架构情况优化。
### 1.6.7 项目安全
项目一旦正式上线,即对外正式服务。但是服务同时,可能会存在安全隐患甚至黑客攻击。
本节仅列举一些注意事项,欢迎开发者补充和完善。
#### 1.6.7.1 账户安全
这里的账号安全,既包括商城端用户账户,也包括管理后台端管理员账户。
目前账号安全还缺乏一点的保护措施,例如
* 用户密码失败超过阈值,则显示验证码;
* 用户密码失败超过阈值,则取消登录;
* 用户密码失败超过阈值,则需要手机验证码;
#### 1.6.7.2 关键业务记录
有关订单或者金钱相关的操作,建议开发者尽可能记录在数据库中,以便以后回溯。
#### 1.6.7.3 API统一调整
本项目公布了参考API接口,如果出现BUG可能会被黑客作为入口。
建议开发者上线之前可以统一调整接口,以减少安全隐患。
#### 1.6.7.4 对账
本项目管理后台没有对账功能,建议开发者可以开发对账比对商场的状态是否正常。
#### 1.6.7.5 取消或者限制退款
本项目不支持自动退款功能,而是在管理后台通过管理员点击退款按钮来人工退款。
但是仍然可能存在隐患,例如黑客通过漏洞进入管理后台从而进行不合理的退款操作。
因此建议开发者可以取消管理后台的退款按钮,而仅仅保持退款信息,管理员可以登录
微信官方支付平台进行退款操作。
或者建议开发者基于一定的业务逻辑或场景限制管理后台的退款功能。例如,设置当天
退款限额从而保证不会产生无限退款操作。
#### 1.6.7.6 资源限制访问
一些API操作涉及到后端服务器资源,因此需要做一定的限制,防止有限资源被恶意消耗。
有限资源可能包括:
* 验证码
* 图片上传
一些限制措施可能包括:
* 限制单个IP的访问频率
* 限制用户上传图片数量
#### 1.6.7.n 跟踪本项目进展
一旦有开发者反馈BUG,本项目会优先解决并及时上传补丁。
因此建议开发者跟踪本项目进展,留意每次BUG修复的commit。
同时也希望开发者发现任何BUG都及时反馈。
目前还不存在LTS版本,未来业务稳定后可能会发布。
## 1.7 项目管理
这里简述一些当前项目开发的要点。
### 1.7.1 项目.gitignore
当前项目的.gitignore不是单一文件,而是多个模块都存在:
* deploy/.gitignore
* litemall-admin/.gitignore
* litemall-admin-api/.gitignore
* litemall-core/.gitignore
* litemall-db/.gitignore
* litemall-wx-api/.gitignore
* litemall-all/.gitignore
* .gitignore
开发者可以采用单一.gitignore文件。
### 1.7.2 项目自动部署
#### 1.7.2.1 deploy部署
当前项目存在deploy部署文件夹,这个是上述1.5.1节部署腾讯云服务器所采取的一些脚本。
流程如下:
1. util脚本是当前开发服务器运行,用来打包项目和上传腾讯云服务器;
2. 打包项目时,会编译打包项目相关模块到litemall和db文件夹中;
3. bin脚本是云服务器运行,用来安装数据库、导入数据、启动项目服务。
这里deploy部署方式比较简单不灵活,开发者可以参考开发自己的项目脚本。
#### 1.7.2.2 docker部署
当前项目存在docker部署文件夹,这个是上述1.5.1节部署腾讯云服务器所采取的一些脚本。
#### 1.7.2.3 .gitlab-ci.yml部署
目前不支持
### 1.7.3 项目代码风格
由于本项目涉及三种技术栈,因此针对这三种技术栈也存在三种代码风格。
如果开发者想要贡献代码,建议尽可能保证代码符合这里的规范。
#### 1.7.3.1 Spring Boot技术栈代码风格
这里的代码风格采用IDEA默认代码风格。
修改代码后,利用`Code`菜单的`Reformat Code`即可格式化代码。
#### 1.7.3.2 小程序技术栈代码风格
这里的代码风格采用微信开发者工具默认代码风格。
修改代码以后,利用`编辑`菜单的`格式化代码`即可格式化代码。
#### 1.7.3.3 Vue技术栈代码风格
这里的代码风格采用ESLint配置代码风格,具体参考vue-element-admin下项目的
[ESLint文档](https://panjiachen.github.io/vue-element-admin-site/zh/guide/advanced/eslint.html),
特别是`vscode 配置 ESLint`内容。
注意:
> Visual Studio Code编辑器中右键存在`格式化代码`的选项,但是请不要使用这种方式,
> 因为VSC自带的格式化代码风格和ESLint代码风格可能不完全一致。
### 1.7.4 Spring Boot多模块多阶段配置
目前后端服务采用Spring Boot多模块方案,结构清晰、易于测试。
但是存在一个问题,即多模块配置依赖。
例如,litemall-db模块存在数据库配置信息,那么其他模块如何引入
litemall-db模块的配置信息呢?
最简单的方式,就是其他模块把litemall-db模块的配置信息拷贝到自己的
application配置文件中,但是问题就是数据库信息一旦改变则其他模块又要
再次手动修改,非常不方便。
目前本项目采用一种基于`spring.profiles.active`的方式,细节如下:
1. litemall-db模块存在application.yml和application-db.yml两个配置文件,
在application-db.yml配置文件中存放数据库配置信息;
2. litemall-core模块也存在application.yml和application-core.yml两个配置文件,
在application-core.yml配置文件中存放core模块的一些配置信息,而在application.yml
中存在这样一个配置:
```
spring:
profiles:
active: core, db
```
因此,如果单独启动litemall-core模块,则会先读取application.yml配置文件,然后基于
系统会根据`spring.profiles.active`读取application-db.yml和application-core.yml配置文件,
因此就会自动读取litemall-db模块的配置文件。
3. 以此类推,在litemall-all模块中存在application.yml配置文件,其中内容是
```
spring:
profiles:
active: db, core, admin, wx
```
因此,系统启动litemall-all模块以后,则会先读取application.yml配置文件,然后基于
`spring.profiles.active`进一步读取application-db.yml、application-core.yml、
application-admin.yml和application-wx.yml四个模块的配置文件。
但是,虽然以上方案解决了多模块配置依赖问题,但是又会导致另外一个问题,如何支持不同profile,
也就是开发阶段、测试阶段和上线阶段配置不同。
这里介绍本项目的思路,就是基于Spring Boot的配置加载顺序,采用外部配置文件覆盖jar包内部配置文件。
1. 开发阶段,系统的配置信息在模块的resources目录配置文件中;
2. 测试或者部署阶段,系统打包成一个litemall.jar二进制jar包,jar包内部配置文件是之前
开发阶段的配置文件,此时在litemall.jar的同级目录创建相同的配置文件,在这些配置文件则
保存了测试或者部署阶段的配置信息。启动litemall.jar时,系统会读取当前目录的配置文件,而
不再读取jar包内部的配置文件。
3. 上线阶段,同样地,在litemall.jar包同级目录创建上线配置文件。
此外,这里还可以采用另外一种思路,如下图:



其实原理也很简单,就是配置文件采用application-{module}-{profile}.yml来支持不同模块不同阶段的配置需求。
### 1.7.5 前后端校验
本项目是前后端分离项目,当用户或者管理员在系统中输入数据时,
数据需要进行两层校验。
* 第一层是前端校验,是对参数格式校验。
* 第二层是后端校验,不仅对参数校验,还会根据业务场景进行校验。
注意
> 目前项目校验思路是这样,但是实际代码的校验还不完善,
> 例如前端校验代码不完善,导致用户体验较差。
### 1.7.6 后端响应错误码
后端服务的响应结果是:
```
{
errno: 错误码,
errmsg:错误消息,
data: 响应数据
}
```
当errno是0时,则data保存业务数据;
当error是非0时,则业务失败,errmsg保存具体错误信息。
目前,errno存在四种形式:
* 4xx,前端错误,说明前端开发者需要重新了解后端接口使用规范:
* 401,参数错误,即前端没有传递后端需要的参数;
* 402,参数值错误,即前端传递的参数值不符合后端接收范围。
* 5xx,后端系统错误,除501外,说明后端开发者应该继续优化代码,尽量避免返回后端系统错误码:
* 501,验证失败,即后端要求用户登录;
* 502,系统内部错误,即没有合适命名的后端内部错误;
* 503,业务不支持,即后端虽然定义了接口,但是还没有实现功能;
* 504,更新数据失效,即后端采用了乐观锁更新,而并发更新时存在数据更新失效;
* 505,更新数据失败,即后端数据库更新失败(正常情况应该更新成功)。
* 6xx,管理后台后端业务错误码,具体见litemall-admin-api模块的`AdminResponseCode`类。
* 7xx,小商城后端业务错误码,具体见litemall-wx-api模块的`WxResponseCode`类。
需要指出的是,小商场后端可能返回4xx、5xx和6xx错误码;管理后台后端则可能返回4xx、5xx和7xx错误码。
这样设计原因是方便小商场前端和管理后台前端区别对待。
小商城前端处理后端响应错误码,存在三种处理方式:
* 如果是4xx,说明前端开发者请求后端API时使用方式存在问题。
例如,后端需要参数“name”,但是前端却没有传值,这个时候后端返回”用户名不对“
没有任何意义,因为这里前端使用错误。相反,简单地返回“参数不对”反而会及早提醒
前端开发者使用出现了问题。
* 如果是5xx,(除501外)说明后端系统出现错误,后端开发者应该修复或者优化,此外
前端可以在请求响应处统一处理5xx错误,而不是把错误信息返回到具体页面。
例如,后端返回“更新数据失败”,说明数据库更新时出现异常,因此前端请求响应处
统一简单报错“系统出错,联系管理员”,这样管理员可以及时联系后端开发者。而后端开发者
则需要评估具体错误码和错误信息,例如这里的“更新数据失败”很可能是数据表调整字段
导致Java代码的模型对象和数据库表不一致,此时后端开发者就可以及时修复。
此外,对于501验证失败,则前端请求响应处可以统一处理跳转登录页面。
* 如果是6xx,则说明是具体业务错误,此时前端需要在业务具体页面显示错误信息即可,同时
这里也要求后端开发者书写良好友好的业务错误信息,因为会向最终用户显示。
和小商场前端类似,管理后台前端处理后端响应错误码也存在三种类似的处理方式。
注意:
> 这里的4xx和5xx错误码,和HTTP中的4xx和5xx状态码不是一个概念。
### 1.7.7 TODO
本项目存在一些TODO,**强烈建议**开发者上线前仔细审阅是否存在问题和做相应调整。
开发者可以使用IDE找到这些TODO。
下面列出一些重要的TODO:
#### 1.7.7.1 微信退款TODO
管理后台管理员点击退款按钮时,管理后台会通过微信退款API请求微信商户平台退款。
但是从安全角度考虑,**强烈建议**开发者删除微信退款代码,而登录微信商户平台手动退款。
或者开发者添加安全相关代码,例如实现短信验证码。
见`AdminOrderController`类
再次提醒,本项目不承担任何使用后果。
#### 1.7.7.2 未完善TODO
有些业务只是实现基本功能,因此这里TODO提醒开发者自行思考。
#### 1.7.7.3 重构TODO
有些业务需求不是很清晰,导致实现时可能存在不合理地方,这里TODO提醒
开发者审阅代码逻辑。
================================================
FILE: doc/wxmall.md
================================================
# 3 litemall小商城
技术:
* 小商城前端,即litemall-wx模块和renard-wx模块
* 微信小程序
* 小商城后端,即litemall-wx-api模块
* Spring Boot 2.x
* Spring MVC
* [weixin-java-tools](https://gitee.com/binary/weixin-java-tools)
目前发现存在的一些问题:
* `缺失`后台服务返回的token存在有效期,小商场应该自动刷新
* `缺失`账号多次登录失败,应该小商城出现图片验证码限制,或者后台账号锁定
* `改善`商品搜索中采用更好的搜索机制
* `改善`商品搜索中,支持热门搜索"换一批"
* `改善`地址优化,目前每一次点击都会请求后台,应该缓存已有的数据
* `改善`商品数量和规格中,如果货品数量不足,则显示效果,通常是是两种效果
* 某个规格选择以后,另外规格的某些规格是实线,而某些是虚线,
* 商品的都规格选择以后,“立即购买”和“加入购物车显示”灰色
* `改善`商品好评计算与显示,例如90%好评
* `改善`商品的评论列表中显示评价的评论分数、商品规格
* `改善`商品的评论列表中的图片点击可放大,同时用户评价的多个图片可以选择左右滑动查看。
* `改善`商品的订单中支持订单号搜索功能
* `改善`在一些内容比较多的页面中支持“顶部”功能
## 3.0 小商场环境
按照项目README文档中的“快速启动”一节,开发者可以快速启动小商场项目。
但是小程序端只可以显示数据和图片,而微信登录会失败、微信支付也会失败,
因为appid不是开发者自己的,
这里进一步介绍开发者需要设置的小商场环境。
### 3.0.1 微信登录配置
开发者在微信小程序官网申请以后,可以有app-id和app-secret信息。
1. 在litemall-core模块的src/main/resources的application-core.yml资源文件中设置
```
litemall
wx
app-id: 开发者申请的app-id
app-secret: 开发者申请的app-secret
```
2. 在litemall-wx模块的project.config.json文件中设置
```
"appid": "开发者申请的app-id",
```
3. 启动后台服务
4. 建议开发者关闭当前项目或者直接关闭微信开发者工具,重新打开(因为此时litemall-wx模块的appid可能未更新)。
编译运行,尝试微信登录
### 3.0.2 微信支付配置
开发者在微信商户平台申请以后,可以有app-id和app-secret信息。
1. 在litemall-core-api模块的src/main/resources的application-core.yml资源文件中设置
```
litemall
wx
mch-id: 开发者申请的mch-id
mch-key: 开发者申请的mch-key
notify-url: 开发者部署服务的微信支付成功回调地址
```
注意
> * notify-url是微信商户平台向小商场后台服务发送支付结果的地址。
> 因此这就要求该地址是可访问的。
> * 目前小商场后台服务的默认request mapping是`/wx/order/pay-notify`(见WxOrderController类的payNotify),
> 因此notify-url应该设置的地址类似于`http://www.example.com/wx/order/pay-notify`
> * 当开发者真正上线后台服务时,强烈建议默认request mapping要重新命名,不能对外公开。
2. 启动后台服务
3. 部署后台服务到云服务器
4. litemall-wx的api.js设置云服务器的域名。
编译运行,尝试微信支付。
### 3.0.3 微信退款配置
目前管理平台的退款功能需要进行微信商户退款配置
1. 从微信商户平台下载商户证书(或者叫做API证书),保存到合适位置,
请阅读[文档](https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3)
2. 在litemall-core-api模块的src/main/resources的application-core.yml资源文件中设置
```
litemall
wx
key-path: 证书文件访问路径
```
3. 启动小程序前端和后端,进行下单、支付、申请退款操作
4. 启动管理后台前端和后端,进行订单退款操作,然后验证手机是否收到退款。
注意:
> 虽然这里管理后台退款接入了微信退款API,但是从安全角度考虑,**强烈建议**
> 开发者删除管理后台微信退款代码,然后分成两个步骤实现管理员退款操作:
> * 首先,管理员登录微信平台进行退款操作;
> * 然后,管理员登陆管理后台点击退款按钮,进行订单退款状态变更和商品库存回库。
## 3.1 litemall-wx-api
本节介绍小商场的后台服务模块。
### 3.1.1 授权服务
见WxAuthController类。
### 3.1.2 首页服务
见WxHomeController类。
### 3.1.3 类目服务
见WxCatelogController类。
### 3.1.4 商品服务
见WxGoodsController类。
### 3.1.5 品牌服务
见WxBrandController类。
### 3.1.6 专题服务
见WxTopicController类。
### 3.1.7 搜索服务
见WxSearchController类。
### 3.1.8 购物车服务
见WxCartController类。
### 3.1.9 订单服务
见WxOrderController类。
### 3.1.10 评价服务
见WxCommentController类。
注意:
> 订单商品评价功能见WxOrderController类的comment方法。
### 3.1.11 团购服务
见WxGrouponController类。
### 3.1.12 收藏服务
见WxCollectController类。
### 3.1.13 足迹服务
见WxFootprintController类。
### 3.1.14 收货地址服务
见WxAddressController类。
### 3.1.15 区域服务
见WxRegionController类。
### 3.1.16 安全
#### 3.1.16.1 Token
用户登录成功以后,后端会返回`token`,之后用户请求都会携带token。
见WxWebMvcConfiguration类、LoginUser和LoginUserHandlerMethodArgumentResolver类。
小商城后端服务每一次请求都会检测是否存在HTTP头部域`X-Litemall-Token`。
如果存在,则内部查询转换成LoginUser,然后作为请求参数。
如果不存在,则作为null请求参数。
而具体的后端服务controller中,则可以利用LoginUser来检查。
例如用户地址服务中:
```
@RestController
@RequestMapping("/wx/address")
@Validated
public class WxAddressController {
@GetMapping("list")
public Object list(@LoginUser Integer userId) {
if (userId == null) {
return ResponseUtil.unlogin();
}
...
}
```
如果检测`userId`是null,则返回错误信息“用户未登录”。
## 3.2 litemall-wx
这里的代码基于[nideshop-mini-program](https://gitee.com/tumobi/nideshop-mini-program),但是做了一定的修改:
* 数据属性名称调整,原项目中数据属性名称是下划线法命名(例如goods_id),而这里采用骆驼式命名法(例如goodsId),因此代码中需要进行相应调整;
* 代码清理重构,删除了一些目前不必要的文件,梳理一些逻辑功能;
* BUG修补,修改了一些错误;
* 功能完善拓展,例如商品立即购买功能、商品评价功能;
具体变化可以采用工具进行对比。
注意
> litemall-wx模块代码基于nideshop-mini-program的commit版本[acbf6276eb27abc6a48887cddd223d7261f0088e](https://github.com/tumobi/nideshop-mini-program/commit/acbf6276eb27abc6a48887cddd223d7261f0088e)。
> 由于改动变化较大,因此之后litemall-wx将独立开发,不会合并nideshop-mini-program的更新。
### 3.2.1 业务API设置
业务API存放在`config/api.js`。
但是可以发现这样的代码:
```
// 本机开发时使用
var WxApiRoot = 'http://localhost:8082/wx/';
// 局域网测试使用
// var WxApiRoot = 'http://192.168.0.101:8082/wx/';
// 云平台部署时使用
// var WxApiRoot = 'http://122.51.199.160:8082/wx/';
```
也就是说这里存在三种类型的API服务地址,这里是考虑到开发存在三种情况:
1. 本机开发时,localhost是当前开发机的地址;
2. 手机预览时,192.168.0.101是开发机的IP地址;
3. 当后台部署在云服务器中时,122.51.199.160是云服务器的IP地址;
4. 此外,更最重要的是,如果小程序正式部署时,这里的地址必须是域名,
而不能是IP地址。
因此,开发阶段开发者可以按照具体情况切换1,2或3的选项。
### 3.2.2 页面
* 首页
* 专题页
* 专题详情页
* 专题评论页
* 专题评论添加页
* 品牌页
* 品牌详情页
* 人气推荐页
* 新品首发页
* 分类页
* 分类详情页
* 查找页
* 商品详情页
* 商品评论页
* 购物车页
* 下单页
* 下单地址页
* 下单地址添加页
* 支付结果页
* 个人页
* 订单列表页
* 订单详情页
* 优惠券页
* 收藏页
* 足迹页
* 收货地址页
* 收货地址添加页
* 登录页
* 注册页
* 找回密码页
### 3.2.3 登录设计
按照官方文档,开发者采用`wx.login`方法即可实现登录操作;
然而,由于`wx.login`只能返回临时登录凭证`code`,从服务器也只能返回对应的sessionId,
因此虽然已经可以视作登录,但是在小程序中不能显示有意义的登录状态,
因此实际很多小程序是继续采用`wx.getUserInfo`来进一步请求用户信息。
因此本模块中,用户的登录状态也是由`wx.login`和`wx.getUserInfo`组成。
#### 3.2.3.1 登录检测
开发者可以采用`user.checkLogin`来检查是否`已登录`,而其检测逻辑是:
1. 可以从storage获取`userInfo`和`token`
2. 同时`wx.checkSession`也成功。
但是如果每次都使用`checkLogin`可能也不太好,因此目前机制是:
1. 应用启动时检测一次,如果登录则设置app.globalData.hasLogin为已登录状态;
之后,其他页面只要查看这个状态即可知道目前是否已登录;
2. 如果后端token过期返回501错误码时,则前端清理`userInfo`和`token`;
3. 用户执行退出操作,则清理`userInfo`和`token`,同时设置hasLogin未登录状态。
注意:
> 这里的逻辑可能有点乱。。。,但是目前实际效果看没有问题。
#### 3.2.3.2 登录时机
登录请求用户信息的时机存在两种设计:
1. 一种是小程序加载时,即申请用户信息,这种实现较简单,但是用户体验可能不是很好;
2. 另外一种是小程序加载时不需要,但是小程序用户需要真正用户信息时才请求用户登录,
而这种实现较复杂。
目前采用第二种方式实现,这里又可以进一步分成两种情况:
* 用户主动登录
用户主动登录,指的是`个人`页面中用户没有登录显示`点击登录`的效果。
* 用户被动登录
用户被动登录,指的是用户想购买商品或者需要用户登录才能操作的行为,
此时因为向服务器请求时token没有设置,因此服务器拒绝用户的请求,同时返回`501`业务代码。
以上无论哪种情况,都会导致用户被重定向到`登录`页面来进行登录操作。
#### 3.2.3.3 登录操作
如前面讨论,这里的登录操作实际包含两个操作`wx.login`和`wx.getUserInfo`。
开发者可以采用`user.loginByWeixin`来进行登录操作。
按照小程序官网文档,用户登录前应该检测以下,来避免频繁无意义的登录操作,
因此较合适的做法如下所示:
```
user.checkLogin().catch(() => {
user.loginByWeixin().then(res => {
this.setData({
userInfo: res.data.userInfo,
});
}).catch((err) => {
util.showErrorToast('登录失败');
});
});
```
#### 3.2.3.4 登出操作
在`个人`页面,如果用户已经登录,则会出现`退出登录`按钮,支持用户退出当前登录状态。
退出逻辑如下所示:
```
util.request(api.AuthLogout, {}, 'POST');
app.globalData.hasLogin = false;
wx.removeStorageSync('token');
wx.removeStorageSync('userInfo');
wx.reLaunch({
url: '/pages/index/index'
});
```
### 3.2.4 storage
litemall-wx模块采用storage来存储一些数据,以及支持组件间数据通信。
#### 3.2.4.1 userInfo和token
#### 3.2.4.2 cartId
#### 3.2.4.3 addressId
### 3.2.5 加入购物车和立即购买
### 3.2.6 团购
## 3.3 renard-wx
renard-wx是另外一个小程序前端,其后端API也是litemall-wx-api。
和litemall-wx的区别是:
1. 界面样式有所调整;
2. 功能进一步简化。
## 3.4 开发新组件
本章节介绍如何开发新的微信小程序功能。
### 3.4.1 小商场前端页面
### 3.4.2 前后端交互服务API
### 3.4.3 小商场后端服务
### 3.4.4 数据库
================================================
FILE: docker/.gitignore
================================================
/litemall/litemall.jar
/db/init-sql/litemall.sql
================================================
FILE: docker/README.md
================================================
## docker
### 项目打包
1. 在服务器或者开发机打包项目到docker;
```
cd litemall
cat ./litemall-db/sql/litemall_schema.sql > ./docker/db/init-sql/litemall.sql
cat ./litemall-db/sql/litemall_table.sql >> ./docker/db/init-sql/litemall.sql
cat ./litemall-db/sql/litemall_data.sql >> ./docker/db/init-sql/litemall.sql
cd ./litemall-admin
npm install --registry=https://registry.npm.taobao.org
npm run build:dep
cd ..
mvn clean package
cp -f ./litemall-all/target/litemall-all-*-exec.jar ./docker/litemall/litemall.jar
```
这里的工作是:
1. 把数据库文件拷贝到docker/db文件夹
2. 编译litemall-admin项目
3. 编译litemall-all模块,同时把litemall-admin编译得到的静态文件拷贝到
litemall-all模块的static目录
2. 修改litemall文件夹下面的*.yml外部配置文件,当litemall-all模块启动时会
加载外部配置文件,而覆盖默认jar包内部的配置文件。
例如,配置文件中一些地方需要设置成远程服务器的IP地址
此时docker部署包结构如下:
* bin
存放远程服务器运行的脚本,包括deploy.sh脚本和reset.sh脚本
* db
存放litemall数据库文件
* litemall
存放远程服务器运行的代码,包括litemall-all二进制可执行包和litemall外部配置文件
* util
存放开发服务器运行的脚本,包括package.sh脚本和lazy.sh脚本。
由于是本地开发服务器运行,因此开发者可以不用上传到远程服务器。
* docker-compose.yml
docker-compose配置脚本,运行docker-compose命令会
### 项目部署
1. 云服务器环境安装docker和docker-compose(MySQL和JDK1.8无需安装,因为使用docker自动安装)。
此外请确保云服务器的安全组已经允许相应的端口。
2. 运行docker-compose
```bash
cd /home/ubuntu/docker
sudo docker-compose
```
3. 测试是否部署成功(xxx.xxx.xxx.xxx是云服务器IP):
```
http://xxx.xxx.xxx.xxx:8080/wx/index/index
http://xxx.xxx.xxx.xxx:8080/admin/index/index
http://xxx.xxx.xxx.xxx:8080/#/login
```
### 项目辅助脚本
在前面的项目打包和项目部署中都是采用手动命令来部署。
这里可以写一些脚本简化:
* util/packet.sh
在开发服务器运行可以自动项目打包
* util/lazy.sh
在开发服务器运行可以自动项目打包、项目上传远程服务器、自动登录系统执行项目部署脚本。
注意:
> 1. 开发者需要在util/lazy.sh中设置相应的远程服务器登录账号和密钥文件路径。
> 2. 开发者需要在bin/reset.sh设置远程服务器的MySQL的root登录账户。
* bin/deploy.sh
在远程服务器运行可以自动部署服务
* bin/reset.sh
在远程服务器运行可以自动项目导入数据、删除本地上传图片、再执行bin/deploy.sh部署服务。
注意:
> 开发者需要在bin/reset.sh设置远程服务器的MySQL的root登录账户。
总结,当开发者设置好配置信息以后,可以在本地运行lazy.sh脚本自动一键部署:
```bash
cd litemall
./docker/util/lazy.sh
```
不过由于需要设置的信息会包含敏感安全信息,强烈建议开发者参考这里的docker文件夹,
然后实现自己的docker文件夹,妥善处置外部配置文件和脚本中的敏感安全信息!!!
================================================
FILE: docker/bin/deploy.sh
================================================
#!/bin/bash
cd /home/ubuntu/docker
sudo docker-compose down
sudo docker-compose build
sudo docker image prune -f
sudo docker-compose up -d
================================================
FILE: docker/bin/reset.sh
================================================
#!/bin/bash
# 本脚本的作用是重置部署环境
# 1.重置数据库
# 2.删除storage文件夹内文件
# 3.调用deploy.sh启动服务
# 注意:由于1和2的原因,请仅在开发测试阶段使用本脚本!
# 重置数据库
# i. 请在`XXXXXX`处设置相应的root密码
# ii. 同时请注意root密码放在脚本是非常危险的,因此这里仅仅是用于开发测试阶段。
ROOT=root
PASSWORD=litemall123456
if test -z "$PASSWORD"
then
echo "请设置云服务器MySQL的root账号密码"
exit 1
fi
# 删除storage文件夹内文件
cd /home/ubuntu/docker/litemall/storage || exit 2
sudo rm -f ./**
cd /home/ubuntu/docker || exit 3
sudo docker-compose down
sudo docker-compose build
sudo docker image prune -f
# 删除db/data文件夹内文件重置数据
# 这样docker启动时会自动运行db/init-sql脚本,导入新的数据
cd /home/ubuntu/docker/db/data || exit 1
sudo rm -rf ./**
cd /home/ubuntu/docker || exit 3
sudo docker-compose up -d
================================================
FILE: docker/db/conf.d/my.cnf
================================================
[mysqld]
wait_timeout=1814400
max_allowed_packet = 100M
default-time_zone = '+8:00'
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
================================================
FILE: docker/db/data/.gitkeep
================================================
================================================
FILE: docker/db/init-sql/.gitkeep
================================================
================================================
FILE: docker/docker-compose.yml
================================================
version: '3'
services:
mysql57:
image: mysql:5.7
container_name: mysql
ports:
- "3306:3306"
command:
--character-set-server=utf8
--collation-server=utf8_general_ci
--default-authentication-plugin=mysql_native_password
volumes:
- ./db/conf.d:/etc/mysql/conf.d
- ./db/data:/var/lib/mysql
- ./db/init-sql:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: litemall123456
restart: always
litemall:
build:
context: litemall
dockerfile: Dockerfile
container_name: litemall
ports:
- "8080:8080"
volumes:
- ./litemall/storage:/storage
- ./litemall/logs:/logs
- ./litemall/backup:/backup
- /etc/localtime:/etc/localtime
environment:
- TZ=Asia/Shanghai
depends_on:
- mysql57
restart: always
================================================
FILE: docker/litemall/.gitkeep
================================================
================================================
FILE: docker/litemall/Dockerfile
================================================
FROM openjdk:8-jre
COPY application.yml application.yml
COPY litemall.jar litemall.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","litemall.jar"]
================================================
FILE: docker/litemall/application.yml
================================================
spring:
profiles:
active: none
message:
encoding: UTF-8
datasource:
druid:
url: jdbc:mysql://mysql:3306/litemall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&verifyServerCertificate=false&useSSL=true
driver-class-name: com.mysql.cj.jdbc.Driver
username: litemall
password: litemall123456
initial-size: 10
max-active: 50
min-idle: 10
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
validation-query: SELECT 1 FROM DUAL
test-on-borrow: false
test-on-return: false
test-while-idle: true
time-between-eviction-runs-millis: 60000
filters: stat,wall
server:
port: 8080
logging:
config: classpath:logback-spring.xml
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
litemall:
# 开发者应该设置成自己的wx相关信息
wx:
app-id: wxa5b486c6b918ecfb
app-secret: e04004829d4c383b4db7769d88dfbca1
mch-id: 111111
mch-key: xxxxxx
notify-url: http://122.51.199.160:8080/wx/order/pay-notify
# 商户证书文件路径
# 请参考“商户证书”一节 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3
key-path: xxxxx
#通知相关配置
notify:
mail:
# 邮件通知配置,邮箱一般用于接收业务通知例如收到新的订单,sendto 定义邮件接收者,通常为商城运营人员
enable: false
host: smtp.exmail.qq.com
username: ex@ex.com.cn
password: XXXXXXXXXXXXX
sendfrom: ex@ex.com.cn
sendto: ex@qq.com
port: 465
# 短消息模版通知配置
# 短信息用于通知客户,例如发货短信通知,注意配置格式;template-name,template-templateId 请参考 NotifyType 枚举值
sms:
enable: false
# 如果是腾讯云短信,则设置active的值tencent
# 如果是阿里云短信,则设置active的值aliyun
active: tencent
sign: litemall
template:
- name: paySucceed
templateId: 156349
- name: captcha
templateId: 156433
- name: ship
templateId: 158002
- name: refund
templateId: 159447
tencent:
appid: 111111111
appkey: xxxxxxxxxxxxxx
aliyun:
regionId: xxx
accessKeyId: xxx
accessKeySecret: xxx
# 快鸟物流查询配置
express:
enable: false
appId: "XXXXXXXXX"
appKey: "XXXXXXXXXXXXXXXXXXXXXXXXX"
vendors:
- code: "ZTO"
name: "中通快递"
- code: "YTO"
name: "圆通速递"
- code: "YD"
name: "韵达速递"
- code: "YZPY"
name: "邮政快递包裹"
- code: "EMS"
name: "EMS"
- code: "DBL"
name: "德邦快递"
- code: "FAST"
name: "快捷快递"
- code: "ZJS"
name: "宅急送"
- code: "TNT"
name: "TNT快递"
- code: "UPS"
name: "UPS"
- code: "DHL"
name: "DHL"
- code: "FEDEX"
name: "FEDEX联邦(国内件)"
- code: "FEDEX_GJ"
name: "FEDEX联邦(国际件)"
# 对象存储配置
storage:
# 当前工作的对象存储模式,分别是local、aliyun、tencent
active: local
# 本地对象存储配置信息
local:
storagePath: storage
address: http://122.51.199.160:8080/wx/storage/fetch/
# 阿里云对象存储配置信息
aliyun:
endpoint: oss-cn-shenzhen.aliyuncs.com
accessKeyId: 111111
accessKeySecret: xxxxxx
bucketName: xxxxxx
# 腾讯对象存储配置信息
# 请参考 https://cloud.tencent.com/document/product/436/6249
tencent:
secretId: 111111
secretKey: xxxxxx
region: xxxxxx
bucketName: xxxxxx
# 七牛云对象存储配置信息
qiniu:
endpoint: http://pd5cb6ulu.bkt.clouddn.com
accessKey: 111111
secretKey: xxxxxx
bucketName: litemall
swagger:
production: true
================================================
FILE: docker/util/lazy.sh
================================================
#!/bin/bash
# 本脚本的作用是
# 1. 项目打包
# 2. 上传云服务器
# 3. 远程登录云服务器并执行reset脚本
# 请设置云服务器的IP地址和账户
# 例如 ubuntu@122.51.199.160
REMOTE=ubuntu@122.51.199.160
# 请设置本地SSH私钥文件id_rsa路径
# 例如 /home/litemall/id_rsa
ID_RSA=/d/00/cloud/litemall.txt
if test -z "$REMOTE"
then
echo "请设置云服务器登录IP地址和账户"
exit 1
fi
if test -z "$ID_RSA"
then
echo "请设置云服务器登录IP地址和账户"
exit 1
fi
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
cd $DIR/../.. || exit 2
LITEMALL_HOME=$PWD
echo "LITEMALL_HOME $LITEMALL_HOME"
# 项目打包
cd $LITEMALL_HOME || exit 2
./docker/util/package.sh
# 上传云服务器
cd $LITEMALL_HOME || exit 2
scp -i $ID_RSA -r ./docker $REMOTE:/home/ubuntu/
# 远程登录云服务器并执行reset脚本
# 这里使用tr命令,因为有可能deploy.sh和reset.sh的换行格式是CRLF,而LINUX环境应该是LF
ssh $REMOTE -i $ID_RSA << eeooff
cd /home/ubuntu/docker/bin
cat deploy.sh | tr -d '\r' > deploy2.sh
mv deploy2.sh deploy.sh
chmod +x deploy.sh
cat reset.sh | tr -d '\r' > reset2.sh
mv reset2.sh reset.sh
chmod +x reset.sh
sudo ./reset.sh
exit
eeooff
================================================
FILE: docker/util/package.sh
================================================
#!/bin/bash
# 请注意
# 本脚本的作用是把本项目编译的结果保存到deploy文件夹中
# 1. 把项目数据库文件拷贝到docker/db/init-sql
# 2. 编译litemall-admin
# 3. 编译litemall-all模块,然后拷贝到docker/litemall
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
cd $DIR/../..
LITEMALL_HOME=$PWD
echo "LITEMALL_HOME $LITEMALL_HOME"
# 复制数据库
cat $LITEMALL_HOME/litemall-db/sql/litemall_schema.sql > $LITEMALL_HOME/docker/db/init-sql/litemall.sql
cat $LITEMALL_HOME/litemall-db/sql/litemall_table.sql >> $LITEMALL_HOME/docker/db/init-sql/litemall.sql
cat $LITEMALL_HOME/litemall-db/sql/litemall_data.sql >> $LITEMALL_HOME/docker/db/init-sql/litemall.sql
# 打包litemall-admin
cd $LITEMALL_HOME/litemall-admin
npm install --registry=https://registry.npm.taobao.org
npm run build:dep
# 打包litemall-vue
cd $LITEMALL_HOME/litemall-vue
npm install --registry=https://registry.npm.taobao.org
npm run build:dep
cd $LITEMALL_HOME
mvn clean package
cp -f $LITEMALL_HOME/litemall-all/target/litemall-all-*-exec.jar $LITEMALL_HOME/docker/litemall/litemall.jar
================================================
FILE: litemall-admin/.editorconfig
================================================
# https://editorconfig.org
root = true
[*]
charset = utf-8
inden
gitextract_gl0yirf4/
├── .gitbook.yaml
├── .github/
│ └── workflows/
│ └── main.yml
├── .gitignore
├── .workflow/
│ ├── BranchPipeline.yml
│ ├── MasterPipeline.yml
│ └── PRPipeline.yml
├── CHANGELOG.md
├── CONTRIBUTE.md
├── LICENSE
├── README.md
├── SECURITY.md
├── deploy/
│ ├── .gitignore
│ ├── README.md
│ ├── bin/
│ │ ├── deploy.sh
│ │ ├── reset.sh
│ │ └── stop.sh
│ ├── db/
│ │ └── .gitkeep
│ ├── litemall/
│ │ └── application.yml
│ └── util/
│ ├── lazy.sh
│ └── package.sh
├── doc/
│ ├── FAQ.md
│ ├── README.md
│ ├── admin.md
│ ├── api.md
│ ├── conf/
│ │ └── nginx.conf
│ ├── database.md
│ ├── how to implement best admin.md
│ ├── mobmall.md
│ ├── note.md
│ ├── performance.md
│ ├── platform.md
│ ├── project.md
│ └── wxmall.md
├── docker/
│ ├── .gitignore
│ ├── README.md
│ ├── bin/
│ │ ├── deploy.sh
│ │ └── reset.sh
│ ├── db/
│ │ ├── conf.d/
│ │ │ └── my.cnf
│ │ ├── data/
│ │ │ └── .gitkeep
│ │ └── init-sql/
│ │ └── .gitkeep
│ ├── docker-compose.yml
│ ├── litemall/
│ │ ├── .gitkeep
│ │ ├── Dockerfile
│ │ └── application.yml
│ └── util/
│ ├── lazy.sh
│ └── package.sh
├── litemall-admin/
│ ├── .editorconfig
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── babel.config.js
│ ├── build/
│ │ └── index.js
│ ├── jest.config.js
│ ├── jsconfig.json
│ ├── package.json
│ ├── postcss.config.js
│ ├── public/
│ │ ├── index.html
│ │ └── tinymce4.7.5/
│ │ ├── langs/
│ │ │ └── zh_CN.js
│ │ └── plugins/
│ │ ├── codesample/
│ │ │ └── css/
│ │ │ └── prism.css
│ │ └── visualblocks/
│ │ └── css/
│ │ └── visualblocks.css
│ ├── src/
│ │ ├── App.vue
│ │ ├── api/
│ │ │ ├── ad.js
│ │ │ ├── admin.js
│ │ │ ├── aftersale.js
│ │ │ ├── brand.js
│ │ │ ├── category.js
│ │ │ ├── comment.js
│ │ │ ├── config.js
│ │ │ ├── coupon.js
│ │ │ ├── dashboard.js
│ │ │ ├── goods.js
│ │ │ ├── groupon.js
│ │ │ ├── issue.js
│ │ │ ├── keyword.js
│ │ │ ├── log.js
│ │ │ ├── login.js
│ │ │ ├── notice.js
│ │ │ ├── order.js
│ │ │ ├── profile.js
│ │ │ ├── region.js
│ │ │ ├── role.js
│ │ │ ├── stat.js
│ │ │ ├── storage.js
│ │ │ ├── topic.js
│ │ │ └── user.js
│ │ ├── components/
│ │ │ ├── BackToTop/
│ │ │ │ └── index.vue
│ │ │ ├── Breadcrumb/
│ │ │ │ └── index.vue
│ │ │ ├── Hamburger/
│ │ │ │ └── index.vue
│ │ │ ├── LocaleChanger/
│ │ │ │ └── index.vue
│ │ │ ├── Notice/
│ │ │ │ └── index.vue
│ │ │ ├── Pagination/
│ │ │ │ └── index.vue
│ │ │ ├── Screenfull/
│ │ │ │ └── index.vue
│ │ │ ├── ScrollPane/
│ │ │ │ └── index.vue
│ │ │ ├── SizeSelect/
│ │ │ │ └── index.vue
│ │ │ └── SvgIcon/
│ │ │ └── index.vue
│ │ ├── directive/
│ │ │ ├── clipboard/
│ │ │ │ ├── clipboard.js
│ │ │ │ └── index.js
│ │ │ └── permission/
│ │ │ ├── index.js
│ │ │ └── permission.js
│ │ ├── filters/
│ │ │ └── index.js
│ │ ├── icons/
│ │ │ ├── index.js
│ │ │ └── svgo.yml
│ │ ├── locales/
│ │ │ ├── en.js
│ │ │ └── zh-Hans.js
│ │ ├── main.js
│ │ ├── permission.js
│ │ ├── router/
│ │ │ └── index.js
│ │ ├── store/
│ │ │ ├── getters.js
│ │ │ ├── index.js
│ │ │ └── modules/
│ │ │ ├── app.js
│ │ │ ├── permission.js
│ │ │ ├── tagsView.js
│ │ │ └── user.js
│ │ ├── styles/
│ │ │ ├── btn.scss
│ │ │ ├── element-ui.scss
│ │ │ ├── element-variables.scss
│ │ │ ├── index.scss
│ │ │ ├── mixin.scss
│ │ │ ├── sidebar.scss
│ │ │ ├── transition.scss
│ │ │ └── variables.scss
│ │ ├── utils/
│ │ │ ├── auth.js
│ │ │ ├── clipboard.js
│ │ │ ├── index.js
│ │ │ ├── openWindow.js
│ │ │ ├── permission.js
│ │ │ ├── print.js
│ │ │ ├── request.js
│ │ │ ├── scrollTo.js
│ │ │ └── validate.js
│ │ ├── vendor/
│ │ │ └── Export2Excel.js
│ │ └── views/
│ │ ├── config/
│ │ │ ├── express.vue
│ │ │ ├── mall.vue
│ │ │ ├── order.vue
│ │ │ └── wx.vue
│ │ ├── dashboard/
│ │ │ └── index.vue
│ │ ├── errorPage/
│ │ │ ├── 401.vue
│ │ │ └── 404.vue
│ │ ├── goods/
│ │ │ ├── comment.vue
│ │ │ ├── create.vue
│ │ │ ├── edit.vue
│ │ │ └── list.vue
│ │ ├── layout/
│ │ │ ├── Layout.vue
│ │ │ ├── components/
│ │ │ │ ├── AppMain.vue
│ │ │ │ ├── Navbar.vue
│ │ │ │ ├── Sidebar/
│ │ │ │ │ ├── FixiOSBug.js
│ │ │ │ │ ├── Item.vue
│ │ │ │ │ ├── Link.vue
│ │ │ │ │ ├── SidebarItem.vue
│ │ │ │ │ └── index.vue
│ │ │ │ ├── TagsView/
│ │ │ │ │ ├── ScrollPane.vue
│ │ │ │ │ └── index.vue
│ │ │ │ └── index.js
│ │ │ └── mixin/
│ │ │ └── ResizeHandler.js
│ │ ├── login/
│ │ │ ├── authredirect.vue
│ │ │ └── index.vue
│ │ ├── mall/
│ │ │ ├── aftersale.vue
│ │ │ ├── brand.vue
│ │ │ ├── category.vue
│ │ │ ├── issue.vue
│ │ │ ├── keyword.vue
│ │ │ ├── order.vue
│ │ │ └── region.vue
│ │ ├── profile/
│ │ │ ├── notice.vue
│ │ │ └── password.vue
│ │ ├── promotion/
│ │ │ ├── ad.vue
│ │ │ ├── coupon.vue
│ │ │ ├── couponDetail.vue
│ │ │ ├── grouponActivity.vue
│ │ │ ├── grouponRule.vue
│ │ │ ├── topic.vue
│ │ │ ├── topicCreate.vue
│ │ │ └── topicEdit.vue
│ │ ├── redirect/
│ │ │ └── index.vue
│ │ ├── stat/
│ │ │ ├── goods.vue
│ │ │ ├── order.vue
│ │ │ └── user.vue
│ │ ├── sys/
│ │ │ ├── admin.vue
│ │ │ ├── log.vue
│ │ │ ├── notice.vue
│ │ │ ├── os.vue
│ │ │ └── role.vue
│ │ └── user/
│ │ ├── address.vue
│ │ ├── collect.vue
│ │ ├── feedback.vue
│ │ ├── footprint.vue
│ │ ├── history.vue
│ │ └── user.vue
│ └── vue.config.js
├── litemall-admin-api/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── org/
│ │ │ └── linlinjava/
│ │ │ └── litemall/
│ │ │ └── admin/
│ │ │ ├── Application.java
│ │ │ ├── annotation/
│ │ │ │ └── RequiresPermissionsDesc.java
│ │ │ ├── config/
│ │ │ │ ├── AdminSwagger2Configuration.java
│ │ │ │ ├── KaptchaConfig.java
│ │ │ │ ├── ShiroConfig.java
│ │ │ │ └── ShiroExceptionHandler.java
│ │ │ ├── dto/
│ │ │ │ └── GoodsAllinone.java
│ │ │ ├── job/
│ │ │ │ ├── CouponJob.java
│ │ │ │ ├── DbJob.java
│ │ │ │ └── OrderJob.java
│ │ │ ├── service/
│ │ │ │ ├── AdminGoodsService.java
│ │ │ │ ├── AdminOrderService.java
│ │ │ │ └── LogHelper.java
│ │ │ ├── shiro/
│ │ │ │ ├── AdminAuthorizingRealm.java
│ │ │ │ └── AdminWebSessionManager.java
│ │ │ ├── task/
│ │ │ │ ├── AdminTaskStartupRunner.java
│ │ │ │ └── GrouponRuleExpiredTask.java
│ │ │ ├── util/
│ │ │ │ ├── AdminResponseCode.java
│ │ │ │ ├── Permission.java
│ │ │ │ └── PermissionUtil.java
│ │ │ ├── vo/
│ │ │ │ ├── CatVo.java
│ │ │ │ ├── CategoryVo.java
│ │ │ │ ├── PermVo.java
│ │ │ │ ├── RegionVo.java
│ │ │ │ └── StatVo.java
│ │ │ └── web/
│ │ │ ├── AdminAdController.java
│ │ │ ├── AdminAddressController.java
│ │ │ ├── AdminAdminController.java
│ │ │ ├── AdminAftersaleController.java
│ │ │ ├── AdminAuthController.java
│ │ │ ├── AdminBrandController.java
│ │ │ ├── AdminCategoryController.java
│ │ │ ├── AdminCollectController.java
│ │ │ ├── AdminCommentController.java
│ │ │ ├── AdminConfigController.java
│ │ │ ├── AdminCouponController.java
│ │ │ ├── AdminDashbordController.java
│ │ │ ├── AdminFeedbackController.java
│ │ │ ├── AdminFootprintController.java
│ │ │ ├── AdminGoodsController.java
│ │ │ ├── AdminGrouponController.java
│ │ │ ├── AdminHistoryController.java
│ │ │ ├── AdminIndexController.java
│ │ │ ├── AdminIssueController.java
│ │ │ ├── AdminKeywordController.java
│ │ │ ├── AdminLogController.java
│ │ │ ├── AdminNoticeController.java
│ │ │ ├── AdminOrderController.java
│ │ │ ├── AdminProfileController.java
│ │ │ ├── AdminRegionController.java
│ │ │ ├── AdminRoleController.java
│ │ │ ├── AdminStatController.java
│ │ │ ├── AdminStorageController.java
│ │ │ ├── AdminTopicController.java
│ │ │ └── AdminUserController.java
│ │ └── resources/
│ │ ├── application-admin.yml
│ │ └── application.yml
│ └── test/
│ └── java/
│ └── org/
│ └── linlinjava/
│ └── litemall/
│ └── admin/
│ ├── AdminConfigTest.java
│ ├── BcryptTest.java
│ ├── CreateShareImageTest.java
│ ├── DbTest.java
│ └── PermissionTest.java
├── litemall-all/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── org/
│ │ │ └── linlinjava/
│ │ │ └── litemall/
│ │ │ └── Application.java
│ │ └── resources/
│ │ ├── application.yml
│ │ └── logback-spring.xml
│ └── test/
│ └── java/
│ └── org/
│ └── linlinjava/
│ └── litemall/
│ └── allinone/
│ └── AllinoneConfigTest.java
├── litemall-all-war/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ └── main/
│ ├── java/
│ │ └── org/
│ │ └── linlinjava/
│ │ └── litemall/
│ │ └── Application.java
│ └── resources/
│ ├── application.yml
│ └── logback-spring.xml
├── litemall-core/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── org/
│ │ │ └── linlinjava/
│ │ │ └── litemall/
│ │ │ └── core/
│ │ │ ├── config/
│ │ │ │ ├── AsyncConfig.java
│ │ │ │ ├── CorsConfig.java
│ │ │ │ ├── GlobalExceptionHandler.java
│ │ │ │ ├── JacksonConfig.java
│ │ │ │ ├── ValidatorConfiguration.java
│ │ │ │ ├── WxConfig.java
│ │ │ │ └── WxProperties.java
│ │ │ ├── express/
│ │ │ │ ├── ExpressService.java
│ │ │ │ ├── config/
│ │ │ │ │ ├── ExpressAutoConfiguration.java
│ │ │ │ │ └── ExpressProperties.java
│ │ │ │ └── dao/
│ │ │ │ ├── ExpressInfo.java
│ │ │ │ └── Traces.java
│ │ │ ├── notify/
│ │ │ │ ├── AliyunSmsSender.java
│ │ │ │ ├── NotifyService.java
│ │ │ │ ├── NotifyType.java
│ │ │ │ ├── SmsResult.java
│ │ │ │ ├── SmsSender.java
│ │ │ │ ├── TencentSmsSender.java
│ │ │ │ └── config/
│ │ │ │ ├── NotifyAutoConfiguration.java
│ │ │ │ └── NotifyProperties.java
│ │ │ ├── qcode/
│ │ │ │ └── QCodeService.java
│ │ │ ├── storage/
│ │ │ │ ├── AliyunStorage.java
│ │ │ │ ├── LocalStorage.java
│ │ │ │ ├── QiniuStorage.java
│ │ │ │ ├── Storage.java
│ │ │ │ ├── StorageService.java
│ │ │ │ ├── TencentStorage.java
│ │ │ │ └── config/
│ │ │ │ ├── StorageAutoConfiguration.java
│ │ │ │ └── StorageProperties.java
│ │ │ ├── system/
│ │ │ │ ├── SystemConfig.java
│ │ │ │ └── SystemInistService.java
│ │ │ ├── task/
│ │ │ │ ├── Task.java
│ │ │ │ └── TaskService.java
│ │ │ ├── util/
│ │ │ │ ├── BeanUtil.java
│ │ │ │ ├── CharUtil.java
│ │ │ │ ├── DateTimeUtil.java
│ │ │ │ ├── HttpUtil.java
│ │ │ │ ├── IpUtil.java
│ │ │ │ ├── JacksonUtil.java
│ │ │ │ ├── RegexUtil.java
│ │ │ │ ├── ResponseUtil.java
│ │ │ │ ├── SystemInfoPrinter.java
│ │ │ │ └── bcrypt/
│ │ │ │ ├── BCrypt.java
│ │ │ │ └── BCryptPasswordEncoder.java
│ │ │ └── validator/
│ │ │ ├── Order.java
│ │ │ ├── OrderValidator.java
│ │ │ ├── Sort.java
│ │ │ └── SortValidator.java
│ │ └── resources/
│ │ ├── application-core.yml
│ │ └── application.yml
│ └── test/
│ └── java/
│ └── org/
│ └── linlinjava/
│ └── litemall/
│ └── core/
│ ├── AliyunStorageTest.java
│ ├── Application.java
│ ├── AsyncTask.java
│ ├── AsyncTest.java
│ ├── CoreConfigTest.java
│ ├── ExpressTest.java
│ ├── IntegerTest.java
│ ├── LocalStorageTest.java
│ ├── MailTest.java
│ ├── QiniuStorageTest.java
│ ├── SmsTest.java
│ ├── TaskTest.java
│ ├── TencentStorageTest.java
│ └── util/
│ └── bcrypt/
│ └── BCryptTest.java
├── litemall-db/
│ ├── .gitignore
│ ├── mybatis-generator/
│ │ └── generatorConfig.xml
│ ├── pom.xml
│ ├── sql/
│ │ ├── README.md
│ │ ├── litemall_data.sql
│ │ ├── litemall_schema.sql
│ │ └── litemall_table.sql
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── org/
│ │ │ └── linlinjava/
│ │ │ └── litemall/
│ │ │ └── db/
│ │ │ ├── dao/
│ │ │ │ ├── GoodsProductMapper.java
│ │ │ │ ├── LitemallAdMapper.java
│ │ │ │ ├── LitemallAddressMapper.java
│ │ │ │ ├── LitemallAdminMapper.java
│ │ │ │ ├── LitemallAftersaleMapper.java
│ │ │ │ ├── LitemallBrandMapper.java
│ │ │ │ ├── LitemallCartMapper.java
│ │ │ │ ├── LitemallCategoryMapper.java
│ │ │ │ ├── LitemallCollectMapper.java
│ │ │ │ ├── LitemallCommentMapper.java
│ │ │ │ ├── LitemallCouponMapper.java
│ │ │ │ ├── LitemallCouponUserMapper.java
│ │ │ │ ├── LitemallFeedbackMapper.java
│ │ │ │ ├── LitemallFootprintMapper.java
│ │ │ │ ├── LitemallGoodsAttributeMapper.java
│ │ │ │ ├── LitemallGoodsMapper.java
│ │ │ │ ├── LitemallGoodsProductMapper.java
│ │ │ │ ├── LitemallGoodsSpecificationMapper.java
│ │ │ │ ├── LitemallGrouponMapper.java
│ │ │ │ ├── LitemallGrouponRulesMapper.java
│ │ │ │ ├── LitemallIssueMapper.java
│ │ │ │ ├── LitemallKeywordMapper.java
│ │ │ │ ├── LitemallLogMapper.java
│ │ │ │ ├── LitemallNoticeAdminMapper.java
│ │ │ │ ├── LitemallNoticeMapper.java
│ │ │ │ ├── LitemallOrderGoodsMapper.java
│ │ │ │ ├── LitemallOrderMapper.java
│ │ │ │ ├── LitemallPermissionMapper.java
│ │ │ │ ├── LitemallRegionMapper.java
│ │ │ │ ├── LitemallRoleMapper.java
│ │ │ │ ├── LitemallSearchHistoryMapper.java
│ │ │ │ ├── LitemallStorageMapper.java
│ │ │ │ ├── LitemallSystemMapper.java
│ │ │ │ ├── LitemallTopicMapper.java
│ │ │ │ ├── LitemallUserMapper.java
│ │ │ │ ├── OrderMapper.java
│ │ │ │ └── StatMapper.java
│ │ │ ├── domain/
│ │ │ │ ├── LitemallAd.java
│ │ │ │ ├── LitemallAdExample.java
│ │ │ │ ├── LitemallAddress.java
│ │ │ │ ├── LitemallAddressExample.java
│ │ │ │ ├── LitemallAdmin.java
│ │ │ │ ├── LitemallAdminExample.java
│ │ │ │ ├── LitemallAftersale.java
│ │ │ │ ├── LitemallAftersaleExample.java
│ │ │ │ ├── LitemallBrand.java
│ │ │ │ ├── LitemallBrandExample.java
│ │ │ │ ├── LitemallCart.java
│ │ │ │ ├── LitemallCartExample.java
│ │ │ │ ├── LitemallCategory.java
│ │ │ │ ├── LitemallCategoryExample.java
│ │ │ │ ├── LitemallCollect.java
│ │ │ │ ├── LitemallCollectExample.java
│ │ │ │ ├── LitemallComment.java
│ │ │ │ ├── LitemallCommentExample.java
│ │ │ │ ├── LitemallCoupon.java
│ │ │ │ ├── LitemallCouponExample.java
│ │ │ │ ├── LitemallCouponUser.java
│ │ │ │ ├── LitemallCouponUserExample.java
│ │ │ │ ├── LitemallFeedback.java
│ │ │ │ ├── LitemallFeedbackExample.java
│ │ │ │ ├── LitemallFootprint.java
│ │ │ │ ├── LitemallFootprintExample.java
│ │ │ │ ├── LitemallGoods.java
│ │ │ │ ├── LitemallGoodsAttribute.java
│ │ │ │ ├── LitemallGoodsAttributeExample.java
│ │ │ │ ├── LitemallGoodsExample.java
│ │ │ │ ├── LitemallGoodsProduct.java
│ │ │ │ ├── LitemallGoodsProductExample.java
│ │ │ │ ├── LitemallGoodsSpecification.java
│ │ │ │ ├── LitemallGoodsSpecificationExample.java
│ │ │ │ ├── LitemallGroupon.java
│ │ │ │ ├── LitemallGrouponExample.java
│ │ │ │ ├── LitemallGrouponRules.java
│ │ │ │ ├── LitemallGrouponRulesExample.java
│ │ │ │ ├── LitemallIssue.java
│ │ │ │ ├── LitemallIssueExample.java
│ │ │ │ ├── LitemallKeyword.java
│ │ │ │ ├── LitemallKeywordExample.java
│ │ │ │ ├── LitemallLog.java
│ │ │ │ ├── LitemallLogExample.java
│ │ │ │ ├── LitemallNotice.java
│ │ │ │ ├── LitemallNoticeAdmin.java
│ │ │ │ ├── LitemallNoticeAdminExample.java
│ │ │ │ ├── LitemallNoticeExample.java
│ │ │ │ ├── LitemallOrder.java
│ │ │ │ ├── LitemallOrderExample.java
│ │ │ │ ├── LitemallOrderGoods.java
│ │ │ │ ├── LitemallOrderGoodsExample.java
│ │ │ │ ├── LitemallPermission.java
│ │ │ │ ├── LitemallPermissionExample.java
│ │ │ │ ├── LitemallRegion.java
│ │ │ │ ├── LitemallRegionExample.java
│ │ │ │ ├── LitemallRole.java
│ │ │ │ ├── LitemallRoleExample.java
│ │ │ │ ├── LitemallSearchHistory.java
│ │ │ │ ├── LitemallSearchHistoryExample.java
│ │ │ │ ├── LitemallStorage.java
│ │ │ │ ├── LitemallStorageExample.java
│ │ │ │ ├── LitemallSystem.java
│ │ │ │ ├── LitemallSystemExample.java
│ │ │ │ ├── LitemallTopic.java
│ │ │ │ ├── LitemallTopicExample.java
│ │ │ │ ├── LitemallUser.java
│ │ │ │ ├── LitemallUserExample.java
│ │ │ │ ├── OrderGoodsVo.java
│ │ │ │ ├── OrderVo.java
│ │ │ │ └── UserVo.java
│ │ │ ├── mybatis/
│ │ │ │ ├── JsonIntegerArrayTypeHandler.java
│ │ │ │ ├── JsonNodeTypeHandler.java
│ │ │ │ └── JsonStringArrayTypeHandler.java
│ │ │ ├── service/
│ │ │ │ ├── CouponAssignService.java
│ │ │ │ ├── CouponVerifyService.java
│ │ │ │ ├── LitemallAdService.java
│ │ │ │ ├── LitemallAddressService.java
│ │ │ │ ├── LitemallAdminService.java
│ │ │ │ ├── LitemallAftersaleService.java
│ │ │ │ ├── LitemallBrandService.java
│ │ │ │ ├── LitemallCartService.java
│ │ │ │ ├── LitemallCategoryService.java
│ │ │ │ ├── LitemallCollectService.java
│ │ │ │ ├── LitemallCommentService.java
│ │ │ │ ├── LitemallCouponService.java
│ │ │ │ ├── LitemallCouponUserService.java
│ │ │ │ ├── LitemallFeedbackService.java
│ │ │ │ ├── LitemallFootprintService.java
│ │ │ │ ├── LitemallGoodsAttributeService.java
│ │ │ │ ├── LitemallGoodsProductService.java
│ │ │ │ ├── LitemallGoodsService.java
│ │ │ │ ├── LitemallGoodsSpecificationService.java
│ │ │ │ ├── LitemallGrouponRulesService.java
│ │ │ │ ├── LitemallGrouponService.java
│ │ │ │ ├── LitemallIssueService.java
│ │ │ │ ├── LitemallKeywordService.java
│ │ │ │ ├── LitemallLogService.java
│ │ │ │ ├── LitemallNoticeAdminService.java
│ │ │ │ ├── LitemallNoticeService.java
│ │ │ │ ├── LitemallOrderGoodsService.java
│ │ │ │ ├── LitemallOrderService.java
│ │ │ │ ├── LitemallPermissionService.java
│ │ │ │ ├── LitemallRegionService.java
│ │ │ │ ├── LitemallRoleService.java
│ │ │ │ ├── LitemallSearchHistoryService.java
│ │ │ │ ├── LitemallStorageService.java
│ │ │ │ ├── LitemallSystemConfigService.java
│ │ │ │ ├── LitemallTopicService.java
│ │ │ │ ├── LitemallUserService.java
│ │ │ │ └── StatService.java
│ │ │ └── util/
│ │ │ ├── AftersaleConstant.java
│ │ │ ├── CouponConstant.java
│ │ │ ├── CouponUserConstant.java
│ │ │ ├── DbUtil.java
│ │ │ ├── GrouponConstant.java
│ │ │ ├── OrderHandleOption.java
│ │ │ └── OrderUtil.java
│ │ └── resources/
│ │ ├── application-db.yml
│ │ ├── application.yml
│ │ └── org/
│ │ └── linlinjava/
│ │ └── litemall/
│ │ └── db/
│ │ └── dao/
│ │ ├── GoodsProductMapper.xml
│ │ ├── LitemallAdMapper.xml
│ │ ├── LitemallAddressMapper.xml
│ │ ├── LitemallAdminMapper.xml
│ │ ├── LitemallAftersaleMapper.xml
│ │ ├── LitemallBrandMapper.xml
│ │ ├── LitemallCartMapper.xml
│ │ ├── LitemallCategoryMapper.xml
│ │ ├── LitemallCollectMapper.xml
│ │ ├── LitemallCommentMapper.xml
│ │ ├── LitemallCouponMapper.xml
│ │ ├── LitemallCouponUserMapper.xml
│ │ ├── LitemallFeedbackMapper.xml
│ │ ├── LitemallFootprintMapper.xml
│ │ ├── LitemallGoodsAttributeMapper.xml
│ │ ├── LitemallGoodsMapper.xml
│ │ ├── LitemallGoodsProductMapper.xml
│ │ ├── LitemallGoodsSpecificationMapper.xml
│ │ ├── LitemallGrouponMapper.xml
│ │ ├── LitemallGrouponRulesMapper.xml
│ │ ├── LitemallIssueMapper.xml
│ │ ├── LitemallKeywordMapper.xml
│ │ ├── LitemallLogMapper.xml
│ │ ├── LitemallNoticeAdminMapper.xml
│ │ ├── LitemallNoticeMapper.xml
│ │ ├── LitemallOrderGoodsMapper.xml
│ │ ├── LitemallOrderMapper.xml
│ │ ├── LitemallPermissionMapper.xml
│ │ ├── LitemallRegionMapper.xml
│ │ ├── LitemallRoleMapper.xml
│ │ ├── LitemallSearchHistoryMapper.xml
│ │ ├── LitemallStorageMapper.xml
│ │ ├── LitemallSystemMapper.xml
│ │ ├── LitemallTopicMapper.xml
│ │ ├── LitemallUserMapper.xml
│ │ ├── OrderMapper.xml
│ │ └── StatMapper.xml
│ └── test/
│ └── java/
│ └── org/
│ └── linlinjava/
│ └── litemall/
│ └── db/
│ ├── Application.java
│ ├── DbConfigTest.java
│ ├── DbTest.java
│ ├── DbUtilTest.java
│ ├── MapperReturnTest.java
│ ├── StatMapperTest.java
│ └── StockTest.java
├── litemall-vue/
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── .postcssrc.js
│ ├── .prettierrc.js
│ ├── babel.config.js
│ ├── package.json
│ ├── public/
│ │ └── index.html
│ ├── src/
│ │ ├── App.vue
│ │ ├── api/
│ │ │ └── api.js
│ │ ├── assets/
│ │ │ └── scss/
│ │ │ ├── _mixin.scss
│ │ │ ├── _vant-theme.scss
│ │ │ ├── _var.scss
│ │ │ ├── common.scss
│ │ │ ├── global.scss
│ │ │ ├── iconfont/
│ │ │ │ └── iconfont.css
│ │ │ └── mixin/
│ │ │ └── _one-border.scss
│ │ ├── components/
│ │ │ ├── Header/
│ │ │ │ └── index.vue
│ │ │ ├── Tabbar/
│ │ │ │ └── index.vue
│ │ │ ├── field/
│ │ │ │ └── index.vue
│ │ │ ├── field-group/
│ │ │ │ └── index.vue
│ │ │ └── is-empty/
│ │ │ └── index.vue
│ │ ├── filter/
│ │ │ └── index.js
│ │ ├── main.js
│ │ ├── mixin/
│ │ │ └── scroll-fixed.js
│ │ ├── router/
│ │ │ ├── home.js
│ │ │ ├── index.js
│ │ │ ├── items.js
│ │ │ ├── login.js
│ │ │ ├── order.js
│ │ │ └── user.js
│ │ ├── store/
│ │ │ ├── getters.js
│ │ │ ├── index.js
│ │ │ ├── mutation-types.js
│ │ │ └── mutations.js
│ │ ├── utils/
│ │ │ ├── auth.js
│ │ │ ├── local-storage.js
│ │ │ ├── location-param.js
│ │ │ ├── request.js
│ │ │ ├── scroll.js
│ │ │ └── validate.js
│ │ └── views/
│ │ ├── home/
│ │ │ └── tabbar-home.vue
│ │ ├── items/
│ │ │ ├── brand/
│ │ │ │ └── index.vue
│ │ │ ├── brand-list/
│ │ │ │ └── index.vue
│ │ │ ├── category/
│ │ │ │ └── index.vue
│ │ │ ├── detail/
│ │ │ │ ├── index.vue
│ │ │ │ └── popup-props.vue
│ │ │ ├── groupon/
│ │ │ │ └── index.vue
│ │ │ ├── hot/
│ │ │ │ └── index.vue
│ │ │ ├── new/
│ │ │ │ └── index.vue
│ │ │ ├── search/
│ │ │ │ └── index.vue
│ │ │ ├── tabbar-catalog.vue
│ │ │ ├── topic/
│ │ │ │ └── index.vue
│ │ │ └── topic-list/
│ │ │ └── index.vue
│ │ ├── login/
│ │ │ ├── forget/
│ │ │ │ └── index.vue
│ │ │ ├── forget-reset/
│ │ │ │ └── index.vue
│ │ │ ├── forget-status/
│ │ │ │ └── index.vue
│ │ │ ├── login.vue
│ │ │ ├── register-getCode/
│ │ │ │ └── index.vue
│ │ │ ├── register-status/
│ │ │ │ └── index.vue
│ │ │ └── register-submit/
│ │ │ └── index.vue
│ │ ├── order/
│ │ │ ├── checkout.vue
│ │ │ ├── order-detail/
│ │ │ │ └── index.vue
│ │ │ ├── payment/
│ │ │ │ └── index.vue
│ │ │ ├── payment-status/
│ │ │ │ └── index.vue
│ │ │ └── tabbar-cart.vue
│ │ └── user/
│ │ ├── coupon-list/
│ │ │ └── index.vue
│ │ ├── module-address/
│ │ │ └── index.vue
│ │ ├── module-address-edit/
│ │ │ ├── area.json
│ │ │ └── index.vue
│ │ ├── module-collect/
│ │ │ └── index.vue
│ │ ├── module-feedback/
│ │ │ └── index.vue
│ │ ├── module-help/
│ │ │ └── index.vue
│ │ ├── module-server/
│ │ │ └── index.vue
│ │ ├── order-list/
│ │ │ └── index.vue
│ │ ├── refund-list/
│ │ │ └── index.vue
│ │ ├── tabbar-user-coupon.vue
│ │ ├── tabbar-user-header.vue
│ │ ├── tabbar-user-module.vue
│ │ ├── tabbar-user-order.vue
│ │ ├── tabbar-user.vue
│ │ └── user-information-set/
│ │ ├── index.vue
│ │ ├── set-mobile/
│ │ │ └── index.vue
│ │ ├── set-nickname/
│ │ │ └── index.vue
│ │ └── set-password/
│ │ └── index.vue
│ └── vue.config.js
├── litemall-wx/
│ ├── app.js
│ ├── app.json
│ ├── app.wxss
│ ├── config/
│ │ └── api.js
│ ├── lib/
│ │ ├── vant-weapp/
│ │ │ ├── action-sheet/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── area/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── button/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── card/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── cell/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── cell-group/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── checkbox/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── checkbox-group/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── circle/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── col/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── collapse/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── collapse-item/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── common/
│ │ │ │ ├── color.d.ts
│ │ │ │ ├── color.js
│ │ │ │ ├── component.d.ts
│ │ │ │ ├── component.js
│ │ │ │ ├── index.wxss
│ │ │ │ ├── style/
│ │ │ │ │ ├── clearfix.wxss
│ │ │ │ │ ├── ellipsis.wxss
│ │ │ │ │ ├── hairline.wxss
│ │ │ │ │ ├── mixins/
│ │ │ │ │ │ ├── clearfix.wxss
│ │ │ │ │ │ ├── ellipsis.wxss
│ │ │ │ │ │ └── hairline.wxss
│ │ │ │ │ ├── theme.wxss
│ │ │ │ │ └── var.wxss
│ │ │ │ ├── utils.d.ts
│ │ │ │ └── utils.js
│ │ │ ├── count-down/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxss
│ │ │ │ ├── utils.d.ts
│ │ │ │ └── utils.js
│ │ │ ├── datetime-picker/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── definitions/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── weapp.d.ts
│ │ │ │ └── weapp.js
│ │ │ ├── dialog/
│ │ │ │ ├── dialog.d.ts
│ │ │ │ ├── dialog.js
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── divider/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── dropdown-item/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── dropdown-menu/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxs
│ │ │ │ └── index.wxss
│ │ │ ├── field/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── goods-action/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── goods-action-button/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── goods-action-icon/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── grid/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── grid-item/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── icon/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── image/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── index-anchor/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── index-bar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── info/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── loading/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── mixins/
│ │ │ │ ├── basic.d.ts
│ │ │ │ ├── basic.js
│ │ │ │ ├── button.d.ts
│ │ │ │ ├── button.js
│ │ │ │ ├── link.d.ts
│ │ │ │ ├── link.js
│ │ │ │ ├── observer/
│ │ │ │ │ ├── behavior.d.ts
│ │ │ │ │ ├── behavior.js
│ │ │ │ │ ├── index.d.ts
│ │ │ │ │ └── index.js
│ │ │ │ ├── open-type.d.ts
│ │ │ │ ├── open-type.js
│ │ │ │ ├── touch.d.ts
│ │ │ │ ├── touch.js
│ │ │ │ ├── transition.d.ts
│ │ │ │ └── transition.js
│ │ │ ├── nav-bar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── notice-bar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── notify/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxss
│ │ │ │ ├── notify.d.ts
│ │ │ │ └── notify.js
│ │ │ ├── overlay/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── panel/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── picker/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxss
│ │ │ │ ├── shared.d.ts
│ │ │ │ └── shared.js
│ │ │ ├── picker-column/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxs
│ │ │ │ └── index.wxss
│ │ │ ├── popup/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── progress/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxs
│ │ │ │ └── index.wxss
│ │ │ ├── radio/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── radio-group/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── rate/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── row/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── search/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── sidebar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── sidebar-item/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── skeleton/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── slider/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── stepper/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── steps/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── sticky/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── submit-bar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── swipe-cell/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── switch/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── tab/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── tabbar/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── tabbar-item/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── tabs/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxs
│ │ │ │ └── index.wxss
│ │ │ ├── tag/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── toast/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxss
│ │ │ │ ├── toast.d.ts
│ │ │ │ └── toast.js
│ │ │ ├── transition/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ └── index.wxss
│ │ │ ├── tree-select/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxs
│ │ │ │ └── index.wxss
│ │ │ ├── uploader/
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── index.js
│ │ │ │ ├── index.json
│ │ │ │ ├── index.wxml
│ │ │ │ ├── index.wxss
│ │ │ │ ├── utils.d.ts
│ │ │ │ └── utils.js
│ │ │ └── wxs/
│ │ │ ├── array.wxs
│ │ │ ├── bem.wxs
│ │ │ ├── memoize.wxs
│ │ │ ├── object.wxs
│ │ │ └── utils.wxs
│ │ └── wxParse/
│ │ ├── html2json.js
│ │ ├── htmlparser.js
│ │ ├── showdown.js
│ │ ├── wxDiscode.js
│ │ ├── wxParse.js
│ │ ├── wxParse.wxml
│ │ └── wxParse.wxss
│ ├── pages/
│ │ ├── about/
│ │ │ ├── about.js
│ │ │ ├── about.json
│ │ │ ├── about.wxml
│ │ │ └── about.wxss
│ │ ├── auth/
│ │ │ ├── accountLogin/
│ │ │ │ ├── accountLogin.js
│ │ │ │ ├── accountLogin.json
│ │ │ │ ├── accountLogin.wxml
│ │ │ │ └── accountLogin.wxss
│ │ │ ├── login/
│ │ │ │ ├── login.js
│ │ │ │ ├── login.json
│ │ │ │ ├── login.wxml
│ │ │ │ └── login.wxss
│ │ │ ├── register/
│ │ │ │ ├── register.js
│ │ │ │ ├── register.json
│ │ │ │ ├── register.wxml
│ │ │ │ └── register.wxss
│ │ │ └── reset/
│ │ │ ├── reset.js
│ │ │ ├── reset.json
│ │ │ ├── reset.wxml
│ │ │ └── reset.wxss
│ │ ├── brand/
│ │ │ ├── brand.js
│ │ │ ├── brand.json
│ │ │ ├── brand.wxml
│ │ │ └── brand.wxss
│ │ ├── brandDetail/
│ │ │ ├── brandDetail.js
│ │ │ ├── brandDetail.json
│ │ │ ├── brandDetail.wxml
│ │ │ └── brandDetail.wxss
│ │ ├── cart/
│ │ │ ├── cart.js
│ │ │ ├── cart.json
│ │ │ ├── cart.wxml
│ │ │ └── cart.wxss
│ │ ├── catalog/
│ │ │ ├── catalog.js
│ │ │ ├── catalog.json
│ │ │ ├── catalog.wxml
│ │ │ └── catalog.wxss
│ │ ├── category/
│ │ │ ├── category.js
│ │ │ ├── category.json
│ │ │ ├── category.wxml
│ │ │ └── category.wxss
│ │ ├── checkout/
│ │ │ ├── checkout.js
│ │ │ ├── checkout.json
│ │ │ ├── checkout.wxml
│ │ │ └── checkout.wxss
│ │ ├── comment/
│ │ │ ├── comment.js
│ │ │ ├── comment.json
│ │ │ ├── comment.wxml
│ │ │ └── comment.wxss
│ │ ├── commentPost/
│ │ │ ├── commentPost.js
│ │ │ ├── commentPost.json
│ │ │ ├── commentPost.wxml
│ │ │ └── commentPost.wxss
│ │ ├── coupon/
│ │ │ ├── coupon.js
│ │ │ ├── coupon.json
│ │ │ ├── coupon.wxml
│ │ │ └── coupon.wxss
│ │ ├── goods/
│ │ │ ├── goods.js
│ │ │ ├── goods.json
│ │ │ ├── goods.wxml
│ │ │ └── goods.wxss
│ │ ├── groupon/
│ │ │ ├── grouponDetail/
│ │ │ │ ├── grouponDetail.js
│ │ │ │ ├── grouponDetail.json
│ │ │ │ ├── grouponDetail.wxml
│ │ │ │ └── grouponDetail.wxss
│ │ │ ├── grouponList/
│ │ │ │ ├── grouponList.js
│ │ │ │ ├── grouponList.json
│ │ │ │ ├── grouponList.wxml
│ │ │ │ └── grouponList.wxss
│ │ │ └── myGroupon/
│ │ │ ├── myGroupon.js
│ │ │ ├── myGroupon.json
│ │ │ ├── myGroupon.wxml
│ │ │ └── myGroupon.wxss
│ │ ├── help/
│ │ │ ├── help.js
│ │ │ ├── help.json
│ │ │ ├── help.wxml
│ │ │ └── help.wxss
│ │ ├── hotGoods/
│ │ │ ├── hotGoods.js
│ │ │ ├── hotGoods.json
│ │ │ ├── hotGoods.wxml
│ │ │ └── hotGoods.wxss
│ │ ├── index/
│ │ │ ├── index.js
│ │ │ ├── index.json
│ │ │ ├── index.wxml
│ │ │ └── index.wxss
│ │ ├── newGoods/
│ │ │ ├── newGoods.js
│ │ │ ├── newGoods.json
│ │ │ ├── newGoods.wxml
│ │ │ └── newGoods.wxss
│ │ ├── payResult/
│ │ │ ├── payResult.js
│ │ │ ├── payResult.json
│ │ │ ├── payResult.wxml
│ │ │ └── payResult.wxss
│ │ ├── search/
│ │ │ ├── search.js
│ │ │ ├── search.json
│ │ │ ├── search.wxml
│ │ │ └── search.wxss
│ │ ├── topic/
│ │ │ ├── topic.js
│ │ │ ├── topic.json
│ │ │ ├── topic.wxml
│ │ │ └── topic.wxss
│ │ ├── topicComment/
│ │ │ ├── topicComment.js
│ │ │ ├── topicComment.json
│ │ │ ├── topicComment.wxml
│ │ │ └── topicComment.wxss
│ │ ├── topicCommentPost/
│ │ │ ├── topicCommentPost.js
│ │ │ ├── topicCommentPost.json
│ │ │ ├── topicCommentPost.wxml
│ │ │ └── topicCommentPost.wxss
│ │ ├── topicDetail/
│ │ │ ├── topicDetail.js
│ │ │ ├── topicDetail.json
│ │ │ ├── topicDetail.wxml
│ │ │ └── topicDetail.wxss
│ │ └── ucenter/
│ │ ├── address/
│ │ │ ├── address.js
│ │ │ ├── address.json
│ │ │ ├── address.wxml
│ │ │ └── address.wxss
│ │ ├── addressAdd/
│ │ │ ├── addressAdd.js
│ │ │ ├── addressAdd.json
│ │ │ ├── addressAdd.wxml
│ │ │ └── addressAdd.wxss
│ │ ├── aftersale/
│ │ │ ├── aftersale.js
│ │ │ ├── aftersale.json
│ │ │ ├── aftersale.wxml
│ │ │ └── aftersale.wxss
│ │ ├── aftersaleDetail/
│ │ │ ├── aftersaleDetail.js
│ │ │ ├── aftersaleDetail.json
│ │ │ ├── aftersaleDetail.wxml
│ │ │ └── aftersaleDetail.wxss
│ │ ├── aftersaleList/
│ │ │ ├── aftersaleList.js
│ │ │ ├── aftersaleList.json
│ │ │ ├── aftersaleList.wxml
│ │ │ └── aftersaleList.wxss
│ │ ├── collect/
│ │ │ ├── collect.js
│ │ │ ├── collect.json
│ │ │ ├── collect.wxml
│ │ │ └── collect.wxss
│ │ ├── couponList/
│ │ │ ├── couponList.js
│ │ │ ├── couponList.json
│ │ │ ├── couponList.wxml
│ │ │ └── couponList.wxss
│ │ ├── couponSelect/
│ │ │ ├── couponSelect.js
│ │ │ ├── couponSelect.json
│ │ │ ├── couponSelect.wxml
│ │ │ └── couponSelect.wxss
│ │ ├── feedback/
│ │ │ ├── feedback.js
│ │ │ ├── feedback.json
│ │ │ ├── feedback.wxml
│ │ │ └── feedback.wxss
│ │ ├── footprint/
│ │ │ ├── footprint.js
│ │ │ ├── footprint.json
│ │ │ ├── footprint.wxml
│ │ │ └── footprint.wxss
│ │ ├── index/
│ │ │ ├── index.js
│ │ │ ├── index.json
│ │ │ ├── index.wxml
│ │ │ └── index.wxss
│ │ ├── order/
│ │ │ ├── order.js
│ │ │ ├── order.json
│ │ │ ├── order.wxml
│ │ │ └── order.wxss
│ │ └── orderDetail/
│ │ ├── orderDetail.js
│ │ ├── orderDetail.json
│ │ ├── orderDetail.wxml
│ │ └── orderDetail.wxss
│ ├── project.config.json
│ ├── project.private.config.json
│ ├── sitemap.json
│ └── utils/
│ ├── area.js
│ ├── check.js
│ ├── user.js
│ └── util.js
├── litemall-wx-api/
│ ├── .gitignore
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── org/
│ │ │ └── linlinjava/
│ │ │ └── litemall/
│ │ │ └── wx/
│ │ │ ├── Application.java
│ │ │ ├── annotation/
│ │ │ │ ├── LoginUser.java
│ │ │ │ └── support/
│ │ │ │ └── LoginUserHandlerMethodArgumentResolver.java
│ │ │ ├── config/
│ │ │ │ ├── WxSwagger2Configuration.java
│ │ │ │ └── WxWebMvcConfiguration.java
│ │ │ ├── dto/
│ │ │ │ ├── CaptchaItem.java
│ │ │ │ ├── UserInfo.java
│ │ │ │ ├── UserToken.java
│ │ │ │ └── WxLoginInfo.java
│ │ │ ├── service/
│ │ │ │ ├── CaptchaCodeManager.java
│ │ │ │ ├── GetRegionService.java
│ │ │ │ ├── HomeCacheManager.java
│ │ │ │ ├── UserInfoService.java
│ │ │ │ ├── UserTokenManager.java
│ │ │ │ ├── WxGrouponRuleService.java
│ │ │ │ └── WxOrderService.java
│ │ │ ├── task/
│ │ │ │ ├── OrderUnpaidTask.java
│ │ │ │ └── TaskStartupRunner.java
│ │ │ ├── util/
│ │ │ │ ├── JwtHelper.java
│ │ │ │ └── WxResponseCode.java
│ │ │ ├── vo/
│ │ │ │ ├── CouponVo.java
│ │ │ │ └── GrouponRuleVo.java
│ │ │ └── web/
│ │ │ ├── WxAddressController.java
│ │ │ ├── WxAftersaleController.java
│ │ │ ├── WxAuthController.java
│ │ │ ├── WxBrandController.java
│ │ │ ├── WxCartController.java
│ │ │ ├── WxCatalogController.java
│ │ │ ├── WxCollectController.java
│ │ │ ├── WxCommentController.java
│ │ │ ├── WxCouponController.java
│ │ │ ├── WxFeedbackController.java
│ │ │ ├── WxFootprintController.java
│ │ │ ├── WxGoodsController.java
│ │ │ ├── WxGrouponController.java
│ │ │ ├── WxHomeController.java
│ │ │ ├── WxIndexController.java
│ │ │ ├── WxIssueController.java
│ │ │ ├── WxMsgController.java
│ │ │ ├── WxOrderController.java
│ │ │ ├── WxSearchController.java
│ │ │ ├── WxStorageController.java
│ │ │ ├── WxTopicController.java
│ │ │ └── WxUserController.java
│ │ └── resources/
│ │ ├── application-wx.yml
│ │ └── application.yml
│ └── test/
│ └── java/
│ └── org/
│ └── linlinjava/
│ └── litemall/
│ └── wx/
│ ├── BigDecimalTest.java
│ └── WxConfigTest.java
├── pom.xml
└── renard-wx/
├── app.js
├── app.json
├── app.wxss
├── components/
│ ├── capsule/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── good/
│ │ ├── good.js
│ │ ├── good.json
│ │ ├── good.wxml
│ │ └── good.wxss
│ ├── goodList/
│ │ ├── goodList.js
│ │ ├── goodList.json
│ │ ├── goodList.wxml
│ │ └── goodList.wxss
│ ├── icon/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── notice-bar/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── notify/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ └── sharePop/
│ ├── sharePop.js
│ ├── sharePop.json
│ ├── sharePop.wxml
│ └── sharePop.wxss
├── config/
│ └── api.js
├── lib/
│ └── wxParse/
│ ├── html2json.js
│ ├── htmlparser.js
│ ├── showdown.js
│ ├── wxDiscode.js
│ ├── wxParse.js
│ ├── wxParse.wxml
│ └── wxParse.wxss
├── pages/
│ ├── auth/
│ │ └── login/
│ │ ├── login.js
│ │ ├── login.json
│ │ ├── login.wxml
│ │ └── login.wxss
│ ├── brand/
│ │ ├── brand.js
│ │ ├── brand.json
│ │ ├── brand.wxml
│ │ └── brand.wxss
│ ├── brandDetail/
│ │ ├── brandDetail.js
│ │ ├── brandDetail.json
│ │ ├── brandDetail.wxml
│ │ └── brandDetail.wxss
│ ├── cart/
│ │ ├── cart.js
│ │ ├── cart.json
│ │ ├── cart.wxml
│ │ └── cart.wxss
│ ├── catalog/
│ │ ├── catalog.js
│ │ ├── catalog.json
│ │ ├── catalog.wxml
│ │ └── catalog.wxss
│ ├── category/
│ │ ├── category.js
│ │ ├── category.json
│ │ ├── category.wxml
│ │ └── category.wxss
│ ├── commentPost/
│ │ ├── commentPost.js
│ │ ├── commentPost.json
│ │ ├── commentPost.wxml
│ │ └── commentPost.wxss
│ ├── goods/
│ │ ├── goods.js
│ │ ├── goods.json
│ │ ├── goods.wxml
│ │ └── goods.wxss
│ ├── groupon/
│ │ ├── grouponDetail/
│ │ │ ├── grouponDetail.js
│ │ │ ├── grouponDetail.json
│ │ │ ├── grouponDetail.wxml
│ │ │ └── grouponDetail.wxss
│ │ ├── grouponList/
│ │ │ ├── grouponList.js
│ │ │ ├── grouponList.json
│ │ │ ├── grouponList.wxml
│ │ │ └── grouponList.wxss
│ │ └── myGroupon/
│ │ ├── myGroupon.js
│ │ ├── myGroupon.json
│ │ ├── myGroupon.wxml
│ │ └── myGroupon.wxss
│ ├── hotGoods/
│ │ ├── hotGoods.js
│ │ ├── hotGoods.json
│ │ ├── hotGoods.wxml
│ │ └── hotGoods.wxss
│ ├── index/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── newGoods/
│ │ ├── newGoods.js
│ │ ├── newGoods.json
│ │ ├── newGoods.wxml
│ │ └── newGoods.wxss
│ ├── payResult/
│ │ ├── payResult.js
│ │ ├── payResult.json
│ │ ├── payResult.wxml
│ │ └── payResult.wxss
│ ├── search/
│ │ ├── search.js
│ │ ├── search.json
│ │ ├── search.wxml
│ │ └── search.wxss
│ ├── shopping/
│ │ └── checkout/
│ │ ├── checkout.js
│ │ ├── checkout.json
│ │ ├── checkout.wxml
│ │ └── checkout.wxss
│ ├── topic/
│ │ ├── topic.js
│ │ ├── topic.json
│ │ ├── topic.wxml
│ │ └── topic.wxss
│ ├── topicDetail/
│ │ ├── topicDetail.js
│ │ ├── topicDetail.json
│ │ ├── topicDetail.wxml
│ │ └── topicDetail.wxss
│ └── ucenter/
│ ├── address/
│ │ ├── address.js
│ │ ├── address.json
│ │ ├── address.wxml
│ │ └── address.wxss
│ ├── addressAdd/
│ │ ├── addressAdd.js
│ │ ├── addressAdd.json
│ │ ├── addressAdd.wxml
│ │ └── addressAdd.wxss
│ ├── coupon/
│ │ ├── coupon.js
│ │ ├── coupon.json
│ │ ├── coupon.wxml
│ │ └── coupon.wxss
│ ├── index/
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── order/
│ │ ├── order.js
│ │ ├── order.json
│ │ ├── order.wxml
│ │ └── order.wxss
│ └── orderDetail/
│ ├── orderDetail.js
│ ├── orderDetail.json
│ ├── orderDetail.wxml
│ └── orderDetail.wxss
├── project.config.json
├── sitemap.json
└── utils/
├── area.js
├── check.js
├── user.js
└── util.js
Showing preview only (1,295K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (13455 symbols across 528 files)
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/Application.java
class Application (line 9) | @SpringBootApplication(scanBasePackages = {"org.linlinjava.litemall.db",...
method main (line 16) | public static void main(String[] args) {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/config/AdminSwagger2Configuration.java
class AdminSwagger2Configuration (line 23) | @Configuration
method adminDocket (line 27) | @Bean
method adminApiInfo (line 39) | private ApiInfo adminApiInfo() {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/config/KaptchaConfig.java
class KaptchaConfig (line 11) | @Configuration
method kaptchaProducer (line 14) | @Bean
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/config/ShiroConfig.java
class ShiroConfig (line 19) | @Configuration
method realm (line 22) | @Bean
method shiroFilterFactoryBean (line 27) | @Bean
method sessionManager (line 47) | @Bean
method defaultWebSecurityManager (line 53) | @Bean
method authorizationAttributeSourceAdvisor (line 61) | @Bean
method defaultAdvisorAutoProxyCreator (line 69) | @Bean
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/config/ShiroExceptionHandler.java
class ShiroExceptionHandler (line 14) | @ControllerAdvice
method unauthenticatedHandler (line 20) | @ExceptionHandler(AuthenticationException.class)
method unauthorizedHandler (line 27) | @ExceptionHandler(AuthorizationException.class)
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/dto/GoodsAllinone.java
class GoodsAllinone (line 8) | public class GoodsAllinone {
method getGoods (line 14) | public LitemallGoods getGoods() {
method setGoods (line 18) | public void setGoods(LitemallGoods goods) {
method getProducts (line 22) | public LitemallGoodsProduct[] getProducts() {
method setProducts (line 26) | public void setProducts(LitemallGoodsProduct[] products) {
method getSpecifications (line 30) | public LitemallGoodsSpecification[] getSpecifications() {
method setSpecifications (line 34) | public void setSpecifications(LitemallGoodsSpecification[] specificati...
method getAttributes (line 38) | public LitemallGoodsAttribute[] getAttributes() {
method setAttributes (line 42) | public void setAttributes(LitemallGoodsAttribute[] attributes) {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/job/CouponJob.java
class CouponJob (line 20) | @Component
method checkCouponExpired (line 34) | @Scheduled(fixedDelay = 60 * 60 * 1000)
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/job/DbJob.java
class DbJob (line 19) | @Component
method backup (line 29) | @Scheduled(cron = "0 0 5 * * ?")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/job/OrderJob.java
class OrderJob (line 20) | @Component
method checkOrderUnconfirm (line 44) | @Scheduled(cron = "0 0 3 * * ?")
method checkOrderComment (line 73) | @Scheduled(cron = "0 0 4 * * ?")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/service/AdminGoodsService.java
class AdminGoodsService (line 24) | @Service
method list (line 45) | public Object list(Integer goodsId, String goodsSn, String name,
method validate (line 51) | private Object validate(GoodsAllinone goodsAllinone) {
method update (line 143) | @Transactional
method delete (line 216) | @Transactional
method create (line 231) | @Transactional
method list2 (line 290) | public Object list2() {
method detail (line 331) | public Object detail(Integer id) {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/service/AdminOrderService.java
class AdminOrderService (line 34) | @Service
method list (line 58) | public Object list(String nickname, String consignee, String orderSn, ...
method detail (line 64) | public Object detail(Integer id) {
method refund (line 92) | @Transactional
method ship (line 194) | public Object ship(String body) {
method delete (line 239) | public Object delete(String body) {
method reply (line 269) | public Object reply(String body) {
method pay (line 293) | public Object pay(String body) {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/service/LogHelper.java
class LogHelper (line 25) | @Component
method logGeneralSucceed (line 35) | public void logGeneralSucceed(String action) {
method logGeneralSucceed (line 39) | public void logGeneralSucceed(String action, String result) {
method logGeneralFail (line 43) | public void logGeneralFail(String action, String error) {
method logAuthSucceed (line 47) | public void logAuthSucceed(String action) {
method logAuthSucceed (line 51) | public void logAuthSucceed(String action, String result) {
method logAuthFail (line 55) | public void logAuthFail(String action, String error) {
method logOrderSucceed (line 59) | public void logOrderSucceed(String action) {
method logOrderSucceed (line 63) | public void logOrderSucceed(String action, String result) {
method logOrderFail (line 67) | public void logOrderFail(String action, String error) {
method logOtherSucceed (line 71) | public void logOtherSucceed(String action) {
method logOtherSucceed (line 75) | public void logOtherSucceed(String action, String result) {
method logOtherFail (line 80) | public void logOtherFail(String action, String error) {
method logAdmin (line 84) | public void logAdmin(Integer type, String action, Boolean succeed, Str...
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/shiro/AdminAuthorizingRealm.java
class AdminAuthorizingRealm (line 27) | public class AdminAuthorizingRealm extends AuthorizingRealm {
method doGetAuthorizationInfo (line 39) | @Override
method doGetAuthenticationInfo (line 55) | @Override
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/shiro/AdminWebSessionManager.java
class AdminWebSessionManager (line 12) | public class AdminWebSessionManager extends DefaultWebSessionManager {
method AdminWebSessionManager (line 18) | public AdminWebSessionManager() {
method getSessionId (line 25) | @Override
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/task/AdminTaskStartupRunner.java
class AdminTaskStartupRunner (line 16) | @Component
method run (line 24) | @Override
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/task/GrouponRuleExpiredTask.java
class GrouponRuleExpiredTask (line 16) | public class GrouponRuleExpiredTask extends Task {
method GrouponRuleExpiredTask (line 20) | public GrouponRuleExpiredTask(Integer grouponRuleId, long delayInMilli...
method run (line 25) | @Override
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/util/AdminResponseCode.java
class AdminResponseCode (line 3) | public class AdminResponseCode {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/util/Permission.java
class Permission (line 6) | public class Permission {
method getRequiresPermissions (line 11) | public RequiresPermissions getRequiresPermissions() {
method getRequiresPermissionsDesc (line 15) | public RequiresPermissionsDesc getRequiresPermissionsDesc() {
method setRequiresPermissions (line 19) | public void setRequiresPermissions(RequiresPermissions requiresPermiss...
method setRequiresPermissionsDesc (line 23) | public void setRequiresPermissionsDesc(RequiresPermissionsDesc require...
method getApi (line 27) | public String getApi() {
method setApi (line 31) | public void setApi(String api) {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/util/PermissionUtil.java
class PermissionUtil (line 19) | public class PermissionUtil {
method listPermVo (line 21) | public static List<PermVo> listPermVo(List<Permission> permissions) {
method listPermission (line 88) | public static List<Permission> listPermission(ApplicationContext conte...
method listPermissionString (line 145) | public static Set<String> listPermissionString(List<Permission> permis...
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/vo/CatVo.java
class CatVo (line 5) | public class CatVo {
method getValue (line 10) | public Integer getValue() {
method setValue (line 14) | public void setValue(Integer value) {
method getLabel (line 18) | public String getLabel() {
method setLabel (line 22) | public void setLabel(String label) {
method getChildren (line 26) | public List getChildren() {
method setChildren (line 30) | public void setChildren(List children) {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/vo/CategoryVo.java
class CategoryVo (line 5) | public class CategoryVo {
method getChildren (line 16) | public List<CategoryVo> getChildren() {
method setChildren (line 20) | public void setChildren(List<CategoryVo> children) {
method getId (line 24) | public Integer getId() {
method setId (line 28) | public void setId(Integer id) {
method getName (line 32) | public String getName() {
method setName (line 36) | public void setName(String name) {
method getKeywords (line 40) | public String getKeywords() {
method setKeywords (line 44) | public void setKeywords(String keywords) {
method getDesc (line 48) | public String getDesc() {
method setDesc (line 52) | public void setDesc(String desc) {
method getIconUrl (line 56) | public String getIconUrl() {
method setIconUrl (line 60) | public void setIconUrl(String iconUrl) {
method getPicUrl (line 64) | public String getPicUrl() {
method setPicUrl (line 68) | public void setPicUrl(String picUrl) {
method getLevel (line 72) | public String getLevel() {
method setLevel (line 76) | public void setLevel(String level) {
method getPid (line 80) | public Integer getPid() {
method setPid (line 84) | public void setPid(Integer pid) {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/vo/PermVo.java
class PermVo (line 5) | public class PermVo {
method getId (line 11) | public String getId() {
method setId (line 15) | public void setId(String id) {
method getLabel (line 19) | public String getLabel() {
method setLabel (line 23) | public void setLabel(String label) {
method setApi (line 27) | public void setApi(String api) {
method getApi (line 31) | public String getApi() {
method getChildren (line 35) | public List<PermVo> getChildren() {
method setChildren (line 39) | public void setChildren(List<PermVo> children) {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/vo/RegionVo.java
class RegionVo (line 5) | public class RegionVo {
method getId (line 13) | public Integer getId() {
method setId (line 17) | public void setId(Integer id) {
method getChildren (line 21) | public List<RegionVo> getChildren() {
method getName (line 25) | public String getName() {
method setName (line 29) | public void setName(String name) {
method getType (line 33) | public Byte getType() {
method setType (line 37) | public void setType(Byte type) {
method getCode (line 41) | public Integer getCode() {
method setCode (line 45) | public void setCode(Integer code) {
method setChildren (line 49) | public void setChildren(List<RegionVo> children) {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/vo/StatVo.java
class StatVo (line 8) | public class StatVo {
method getColumns (line 12) | public String[] getColumns() {
method setColumns (line 16) | public void setColumns(String[] columns) {
method getRows (line 20) | public List<Map> getRows() {
method setRows (line 24) | public void setRows(List<Map> rows) {
method add (line 28) | public void add(Map... r) {
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminAdController.java
class AdminAdController (line 20) | @RestController
method list (line 29) | @RequiresPermissions("admin:ad:list")
method validate (line 41) | private Object validate(LitemallAd ad) {
method create (line 53) | @RequiresPermissions("admin:ad:create")
method read (line 65) | @RequiresPermissions("admin:ad:read")
method update (line 73) | @RequiresPermissions("admin:ad:update")
method delete (line 88) | @RequiresPermissions("admin:ad:delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminAddressController.java
class AdminAddressController (line 22) | @RestController
method list (line 33) | @RequiresPermissions("admin:address:list")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminAdminController.java
class AdminAdminController (line 27) | @RestController
method list (line 38) | @RequiresPermissions("admin:admin:list")
method validate (line 50) | private Object validate(LitemallAdmin admin) {
method create (line 65) | @RequiresPermissions("admin:admin:create")
method read (line 89) | @RequiresPermissions("admin:admin:read")
method update (line 97) | @RequiresPermissions("admin:admin:update")
method delete (line 122) | @RequiresPermissions("admin:admin:delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminAftersaleController.java
class AdminAftersaleController (line 36) | @RestController
method list (line 57) | @RequiresPermissions("admin:aftersale:list")
method recept (line 69) | @RequiresPermissions("admin:aftersale:recept")
method batchRecept (line 91) | @RequiresPermissions("admin:aftersale:batch-recept")
method reject (line 119) | @RequiresPermissions("admin:aftersale:reject")
method batchReject (line 141) | @RequiresPermissions("admin:aftersale:batch-reject")
method refund (line 165) | @RequiresPermissions("admin:aftersale:refund")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminAuthController.java
class AdminAuthController (line 40) | @RestController
method kaptcha (line 58) | @GetMapping("/kaptcha")
method doKaptcha (line 67) | private String doKaptcha(HttpServletRequest request) {
method login (line 87) | @PostMapping("/login")
method logout (line 143) | @RequiresAuthentication
method info (line 154) | @RequiresAuthentication
method toApi (line 178) | private Collection<String> toApi(Set<String> permissions) {
method page401 (line 206) | @GetMapping("/401")
method pageIndex (line 211) | @GetMapping("/index")
method page403 (line 216) | @GetMapping("/403")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminBrandController.java
class AdminBrandController (line 21) | @RestController
method list (line 30) | @RequiresPermissions("admin:brand:list")
method validate (line 42) | private Object validate(LitemallBrand brand) {
method create (line 60) | @RequiresPermissions("admin:brand:create")
method read (line 72) | @RequiresPermissions("admin:brand:read")
method update (line 80) | @RequiresPermissions("admin:brand:update")
method delete (line 94) | @RequiresPermissions("admin:brand:delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminCategoryController.java
class AdminCategoryController (line 22) | @RestController
method list (line 31) | @RequiresPermissions("admin:category:list")
method validate (line 71) | private Object validate(LitemallCategory category) {
method create (line 93) | @RequiresPermissions("admin:category:create")
method read (line 105) | @RequiresPermissions("admin:category:read")
method update (line 113) | @RequiresPermissions("admin:category:update")
method delete (line 128) | @RequiresPermissions("admin:category:delete")
method catL1 (line 140) | @RequiresPermissions("admin:category:list")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminCollectController.java
class AdminCollectController (line 21) | @RestController
method list (line 31) | @RequiresPermissions("admin:collect:list")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminCommentController.java
class AdminCommentController (line 18) | @RestController
method list (line 27) | @RequiresPermissions("admin:comment:list")
method delete (line 39) | @RequiresPermissions("admin:comment:delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminConfigController.java
class AdminConfigController (line 17) | @RestController
method listMall (line 26) | @RequiresPermissions("admin:config:mall:list")
method updateMall (line 34) | @RequiresPermissions("admin:config:mall:updateConfigs")
method listExpress (line 44) | @RequiresPermissions("admin:config:express:list")
method updateExpress (line 52) | @RequiresPermissions("admin:config:express:updateConfigs")
method lisOrder (line 62) | @RequiresPermissions("admin:config:order:list")
method updateOrder (line 70) | @RequiresPermissions("admin:config:order:updateConfigs")
method listWx (line 79) | @RequiresPermissions("admin:config:wx:list")
method updateWx (line 87) | @RequiresPermissions("admin:config:wx:updateConfigs")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminCouponController.java
class AdminCouponController (line 23) | @RestController
method list (line 34) | @RequiresPermissions("admin:coupon:list")
method listuser (line 46) | @RequiresPermissions("admin:coupon:listuser")
method validate (line 59) | private Object validate(LitemallCoupon coupon) {
method create (line 67) | @RequiresPermissions("admin:coupon:create")
method read (line 86) | @RequiresPermissions("admin:coupon:read")
method update (line 94) | @RequiresPermissions("admin:coupon:update")
method delete (line 108) | @RequiresPermissions("admin:coupon:delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminDashbordController.java
class AdminDashbordController (line 19) | @RestController
method info (line 34) | @GetMapping("")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminFeedbackController.java
class AdminFeedbackController (line 25) | @RestController
method list (line 34) | @RequiresPermissions("admin:feedback:list")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminFootprintController.java
class AdminFootprintController (line 21) | @RestController
method list (line 30) | @RequiresPermissions("admin:footprint:list")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGoodsController.java
class AdminGoodsController (line 18) | @RestController
method list (line 39) | @RequiresPermissions("admin:goods:list")
method list2 (line 50) | @GetMapping("/catAndBrand")
method update (line 61) | @RequiresPermissions("admin:goods:update")
method delete (line 74) | @RequiresPermissions("admin:goods:delete")
method create (line 87) | @RequiresPermissions("admin:goods:create")
method detail (line 100) | @RequiresPermissions("admin:goods:read")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminGrouponController.java
class AdminGrouponController (line 33) | @RestController
method listRecord (line 48) | @RequiresPermissions("admin:groupon:read")
method list (line 80) | @RequiresPermissions("admin:groupon:list")
method validate (line 92) | private Object validate(LitemallGrouponRules grouponRules) {
method update (line 113) | @RequiresPermissions("admin:groupon:update")
method create (line 146) | @RequiresPermissions("admin:groupon:create")
method delete (line 178) | @RequiresPermissions("admin:groupon:delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminHistoryController.java
class AdminHistoryController (line 20) | @RestController
method list (line 28) | @RequiresPermissions("admin:history:list")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminIndexController.java
class AdminIndexController (line 13) | @RestController
method index (line 18) | @RequestMapping("/index")
method guest (line 23) | @RequiresGuest
method authn (line 29) | @RequiresAuthentication
method user (line 35) | @RequiresUser
method admin (line 41) | @RequiresRoles("admin")
method admin2 (line 47) | @RequiresRoles("admin2")
method read (line 53) | @RequiresPermissions("index:permission:read")
method write (line 60) | @RequiresPermissions("index:permission:write")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminIssueController.java
class AdminIssueController (line 20) | @RestController
method list (line 29) | @RequiresPermissions("admin:issue:list")
method validate (line 41) | private Object validate(LitemallIssue issue) {
method create (line 53) | @RequiresPermissions("admin:issue:create")
method read (line 65) | @RequiresPermissions("admin:issue:read")
method update (line 72) | @RequiresPermissions("admin:issue:update")
method delete (line 87) | @RequiresPermissions("admin:issue:delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminKeywordController.java
class AdminKeywordController (line 20) | @RestController
method list (line 29) | @RequiresPermissions("admin:keyword:list")
method validate (line 41) | private Object validate(LitemallKeyword keywords) {
method create (line 49) | @RequiresPermissions("admin:keyword:create")
method read (line 61) | @RequiresPermissions("admin:keyword:read")
method update (line 69) | @RequiresPermissions("admin:keyword:update")
method delete (line 83) | @RequiresPermissions("admin:keyword:delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminLogController.java
class AdminLogController (line 21) | @RestController
method list (line 30) | @RequiresPermissions("admin:log:list")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminNoticeController.java
class AdminNoticeController (line 29) | @RestController
method list (line 42) | @RequiresPermissions("admin:notice:list")
method validate (line 54) | private Object validate(LitemallNotice notice) {
method getAdminId (line 62) | private Integer getAdminId(){
method create (line 68) | @RequiresPermissions("admin:notice:create")
method read (line 91) | @RequiresPermissions("admin:notice:read")
method update (line 103) | @RequiresPermissions("admin:notice:update")
method delete (line 131) | @RequiresPermissions("admin:notice:delete")
method batchDelete (line 142) | @RequiresPermissions("admin:notice:batch-delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminOrderController.java
class AdminOrderController (line 22) | @RestController
method list (line 44) | @RequiresPermissions("admin:order:list")
method channel (line 63) | @GetMapping("/channel")
method detail (line 74) | @RequiresPermissions("admin:order:read")
method refund (line 87) | @RequiresPermissions("admin:order:refund")
method ship (line 100) | @RequiresPermissions("admin:order:ship")
method pay (line 107) | @RequiresPermissions("admin:order:pay")
method delete (line 120) | @RequiresPermissions("admin:order:delete")
method reply (line 133) | @RequiresPermissions("admin:order:reply")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminProfileController.java
class AdminProfileController (line 34) | @RestController
method create (line 47) | @RequiresAuthentication
method getAdminId (line 74) | private Integer getAdminId(){
method nNotice (line 80) | @RequiresAuthentication
method lsNotice (line 87) | @RequiresAuthentication
method catNotice (line 98) | @RequiresAuthentication
method bcatNotice (line 132) | @RequiresAuthentication
method rmNotice (line 140) | @RequiresAuthentication
method brmNotice (line 151) | @RequiresAuthentication
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminRegionController.java
class AdminRegionController (line 21) | @RestController
method clist (line 30) | @GetMapping("/clist")
method list (line 36) | @GetMapping("/list")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminRoleController.java
class AdminRoleController (line 36) | @RestController
method list (line 49) | @RequiresPermissions("admin:role:list")
method options (line 61) | @GetMapping("/options")
method read (line 76) | @RequiresPermissions("admin:role:read")
method validate (line 85) | private Object validate(LitemallRole role) {
method create (line 94) | @RequiresPermissions("admin:role:create")
method update (line 112) | @RequiresPermissions("admin:role:update")
method delete (line 125) | @RequiresPermissions("admin:role:delete")
method getSystemPermissions (line 155) | private List<PermVo> getSystemPermissions() {
method getAssignedPermissions (line 165) | private Set<String> getAssignedPermissions(List<Integer> roleIds) {
method getPermissions (line 184) | @RequiresPermissions("admin:role:permission:get")
method updatePermissions (line 224) | @RequiresPermissions("admin:role:permission:update")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminStatController.java
class AdminStatController (line 19) | @RestController
method statUser (line 28) | @RequiresPermissions("admin:stat:user")
method statOrder (line 40) | @RequiresPermissions("admin:stat:order")
method statGoods (line 53) | @RequiresPermissions("admin:stat:goods")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminStorageController.java
class AdminStorageController (line 23) | @RestController
method list (line 34) | @RequiresPermissions("admin:storage:list")
method create (line 46) | @RequiresPermissions("admin:storage:create")
method read (line 56) | @RequiresPermissions("admin:storage:read")
method update (line 67) | @RequiresPermissions("admin:storage:update")
method delete (line 77) | @RequiresPermissions("admin:storage:delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminTopicController.java
class AdminTopicController (line 28) | @RestController
method list (line 39) | @RequiresPermissions("admin:topic:list")
method validate (line 51) | private Object validate(LitemallTopic topic) {
method create (line 67) | @RequiresPermissions("admin:topic:create")
method read (line 79) | @RequiresPermissions("admin:topic:read")
method update (line 97) | @RequiresPermissions("admin:topic:update")
method delete (line 111) | @RequiresPermissions("admin:topic:delete")
method batchDelete (line 119) | @RequiresPermissions("admin:topic:batch-delete")
FILE: litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/web/AdminUserController.java
class AdminUserController (line 25) | @RestController
method list (line 34) | @RequiresPermissions("admin:user:list")
method userDetail (line 45) | @RequiresPermissions("admin:user:list")
method userUpdate (line 52) | @RequiresPermissions("admin:user:list")
FILE: litemall-admin-api/src/test/java/org/linlinjava/litemall/admin/AdminConfigTest.java
class AdminConfigTest (line 11) | @WebAppConfiguration
method test (line 18) | @Test
FILE: litemall-admin-api/src/test/java/org/linlinjava/litemall/admin/BcryptTest.java
class BcryptTest (line 10) | @RunWith(SpringJUnit4ClassRunner.class)
method test (line 14) | @Test
FILE: litemall-admin-api/src/test/java/org/linlinjava/litemall/admin/CreateShareImageTest.java
class CreateShareImageTest (line 13) | @WebAppConfiguration
method test (line 22) | @Test
FILE: litemall-admin-api/src/test/java/org/linlinjava/litemall/admin/DbTest.java
class DbTest (line 15) | @WebAppConfiguration
method test (line 22) | @Test
method testFileCreate (line 35) | @Test
method testFileDelete (line 46) | @Test
FILE: litemall-admin-api/src/test/java/org/linlinjava/litemall/admin/PermissionTest.java
class PermissionTest (line 16) | @WebAppConfiguration
method test (line 24) | @Test
FILE: litemall-admin/src/api/ad.js
function listAd (line 3) | function listAd(query) {
function createAd (line 11) | function createAd(data) {
function readAd (line 19) | function readAd(data) {
function updateAd (line 27) | function updateAd(data) {
function deleteAd (line 35) | function deleteAd(data) {
FILE: litemall-admin/src/api/admin.js
function listAdmin (line 3) | function listAdmin(query) {
function createAdmin (line 11) | function createAdmin(data) {
function readminAdmin (line 19) | function readminAdmin(data) {
function updateAdmin (line 27) | function updateAdmin(data) {
function deleteAdmin (line 35) | function deleteAdmin(data) {
FILE: litemall-admin/src/api/aftersale.js
function listAftersale (line 3) | function listAftersale(query) {
function receptAftersale (line 11) | function receptAftersale(data) {
function batchReceptAftersale (line 19) | function batchReceptAftersale(data) {
function rejectAftersale (line 27) | function rejectAftersale(data) {
function batchRejectAftersale (line 35) | function batchRejectAftersale(data) {
function refundAftersale (line 43) | function refundAftersale(data) {
FILE: litemall-admin/src/api/brand.js
function listBrand (line 3) | function listBrand(query) {
function createBrand (line 11) | function createBrand(data) {
function readBrand (line 19) | function readBrand(data) {
function updateBrand (line 27) | function updateBrand(data) {
function deleteBrand (line 35) | function deleteBrand(data) {
FILE: litemall-admin/src/api/category.js
function listCategory (line 3) | function listCategory(query) {
function listCatL1 (line 11) | function listCatL1() {
function createCategory (line 18) | function createCategory(data) {
function readCategory (line 26) | function readCategory(data) {
function updateCategory (line 34) | function updateCategory(data) {
function deleteCategory (line 42) | function deleteCategory(data) {
FILE: litemall-admin/src/api/comment.js
function listComment (line 3) | function listComment(query) {
function deleteComment (line 11) | function deleteComment(data) {
FILE: litemall-admin/src/api/config.js
function listMall (line 3) | function listMall() {
function updateMall (line 10) | function updateMall(data) {
function listExpress (line 18) | function listExpress() {
function updateExpress (line 25) | function updateExpress(data) {
function listOrder (line 33) | function listOrder() {
function updateOrder (line 40) | function updateOrder(data) {
function listWx (line 48) | function listWx() {
function updateWx (line 55) | function updateWx(data) {
FILE: litemall-admin/src/api/coupon.js
function listCoupon (line 3) | function listCoupon(query) {
function createCoupon (line 11) | function createCoupon(data) {
function readCoupon (line 19) | function readCoupon(id) {
function updateCoupon (line 27) | function updateCoupon(data) {
function deleteCoupon (line 35) | function deleteCoupon(data) {
function listCouponUser (line 43) | function listCouponUser(query) {
FILE: litemall-admin/src/api/dashboard.js
function info (line 3) | function info(query) {
FILE: litemall-admin/src/api/goods.js
function listGoods (line 3) | function listGoods(query) {
function deleteGoods (line 11) | function deleteGoods(data) {
function publishGoods (line 19) | function publishGoods(data) {
function detailGoods (line 27) | function detailGoods(id) {
function editGoods (line 35) | function editGoods(data) {
function listCatAndBrand (line 43) | function listCatAndBrand() {
FILE: litemall-admin/src/api/groupon.js
function listRecord (line 3) | function listRecord(query) {
function listGroupon (line 11) | function listGroupon(query) {
function deleteGroupon (line 19) | function deleteGroupon(data) {
function publishGroupon (line 27) | function publishGroupon(data) {
function editGroupon (line 35) | function editGroupon(data) {
FILE: litemall-admin/src/api/issue.js
function listIssue (line 3) | function listIssue(query) {
function createIssue (line 11) | function createIssue(data) {
function readIssue (line 19) | function readIssue(data) {
function updateIssue (line 27) | function updateIssue(data) {
function deleteIssue (line 35) | function deleteIssue(data) {
FILE: litemall-admin/src/api/keyword.js
function listKeyword (line 3) | function listKeyword(query) {
function createKeyword (line 11) | function createKeyword(data) {
function readKeyword (line 19) | function readKeyword(data) {
function updateKeyword (line 27) | function updateKeyword(data) {
function deleteKeyword (line 35) | function deleteKeyword(data) {
FILE: litemall-admin/src/api/log.js
function listLog (line 3) | function listLog(query) {
FILE: litemall-admin/src/api/login.js
function loginByUsername (line 3) | function loginByUsername(username, password, code) {
function logout (line 16) | function logout() {
function getUserInfo (line 23) | function getUserInfo(token) {
function getKaptcha (line 31) | function getKaptcha() {
FILE: litemall-admin/src/api/notice.js
function listNotice (line 3) | function listNotice(query) {
function createNotice (line 11) | function createNotice(data) {
function readNotice (line 19) | function readNotice(query) {
function updateNotice (line 27) | function updateNotice(data) {
function deleteNotice (line 35) | function deleteNotice(data) {
function batchDeleteNotice (line 43) | function batchDeleteNotice(data) {
FILE: litemall-admin/src/api/order.js
function listOrder (line 4) | function listOrder(query) {
function detailOrder (line 15) | function detailOrder(id) {
function shipOrder (line 23) | function shipOrder(data) {
function refundOrder (line 31) | function refundOrder(data) {
function payOrder (line 39) | function payOrder(data) {
function deleteOrder (line 47) | function deleteOrder(data) {
function replyComment (line 55) | function replyComment(data) {
function listChannel (line 63) | function listChannel(id) {
FILE: litemall-admin/src/api/profile.js
function changePassword (line 3) | function changePassword(data) {
function nNotice (line 11) | function nNotice() {
function listNotice (line 18) | function listNotice(query) {
function catNotice (line 26) | function catNotice(data) {
function bcatNotice (line 34) | function bcatNotice(data) {
function rmotice (line 42) | function rmotice(data) {
function brmNotice (line 50) | function brmNotice(data) {
FILE: litemall-admin/src/api/region.js
function listRegion (line 3) | function listRegion() {
function listSubRegion (line 10) | function listSubRegion(query) {
FILE: litemall-admin/src/api/role.js
function listRole (line 3) | function listRole(query) {
function createRole (line 11) | function createRole(data) {
function readRole (line 19) | function readRole(data) {
function updateRole (line 27) | function updateRole(data) {
function deleteRole (line 35) | function deleteRole(data) {
function getPermission (line 43) | function getPermission(query) {
function updatePermission (line 51) | function updatePermission(data) {
function roleOptions (line 59) | function roleOptions(query) {
FILE: litemall-admin/src/api/stat.js
function statUser (line 3) | function statUser(query) {
function statOrder (line 11) | function statOrder(query) {
function statGoods (line 19) | function statGoods(query) {
FILE: litemall-admin/src/api/storage.js
function listStorage (line 3) | function listStorage(query) {
function createStorage (line 11) | function createStorage(data) {
function readStorage (line 19) | function readStorage(data) {
function updateStorage (line 27) | function updateStorage(data) {
function deleteStorage (line 35) | function deleteStorage(data) {
FILE: litemall-admin/src/api/topic.js
function listTopic (line 3) | function listTopic(query) {
function createTopic (line 11) | function createTopic(data) {
function readTopic (line 19) | function readTopic(query) {
function updateTopic (line 27) | function updateTopic(data) {
function deleteTopic (line 35) | function deleteTopic(data) {
function batchDeleteTopic (line 43) | function batchDeleteTopic(data) {
FILE: litemall-admin/src/api/user.js
function fetchList (line 3) | function fetchList(query) {
function userDetail (line 11) | function userDetail(id) {
function updateUser (line 19) | function updateUser(data) {
function listAddress (line 27) | function listAddress(query) {
function listCollect (line 35) | function listCollect(query) {
function listFeedback (line 43) | function listFeedback(query) {
function listFootprint (line 51) | function listFootprint(query) {
function listHistory (line 59) | function listHistory(query) {
FILE: litemall-admin/src/directive/clipboard/clipboard.js
method bind (line 8) | bind(el, binding) {
method update (line 29) | update(el, binding) {
method unbind (line 39) | unbind(el, binding) {
FILE: litemall-admin/src/directive/permission/permission.js
method inserted (line 5) | inserted(el, binding, vnode) {
FILE: litemall-admin/src/filters/index.js
function pluralize (line 10) | function pluralize(time, label) {
function timeAgo (line 20) | function timeAgo(time) {
function numberFormatter (line 37) | function numberFormatter(num, digits) {
function toThousandFilter (line 58) | function toThousandFilter(num) {
function uppercaseFirst (line 66) | function uppercaseFirst(string) {
FILE: litemall-admin/src/main.js
function loadMessages (line 31) | function loadMessages() {
FILE: litemall-admin/src/permission.js
function hasPermission (line 11) | function hasPermission(perms, permissions) {
FILE: litemall-admin/src/router/index.js
function resetRouter (line 619) | function resetRouter() {
FILE: litemall-admin/src/store/modules/app.js
method toggleSideBar (line 41) | toggleSideBar({ commit }) {
method closeSideBar (line 44) | closeSideBar({ commit }, { withoutAnimation }) {
method toggleDevice (line 47) | toggleDevice({ commit }, device) {
method setLanguage (line 50) | setLanguage({ commit }, language) {
method setSize (line 53) | setSize({ commit }, size) {
FILE: litemall-admin/src/store/modules/permission.js
function hasPermission (line 8) | function hasPermission(perms, route) {
function filterAsyncRoutes (line 21) | function filterAsyncRoutes(routes, perms) {
method GenerateRoutes (line 53) | GenerateRoutes({ commit }, data) {
FILE: litemall-admin/src/store/modules/tagsView.js
method addView (line 70) | addView({ dispatch }, view) {
method addVisitedView (line 74) | addVisitedView({ commit }, view) {
method addCachedView (line 77) | addCachedView({ commit }, view) {
method delView (line 81) | delView({ dispatch, state }, view) {
method delVisitedView (line 91) | delVisitedView({ commit, state }, view) {
method delCachedView (line 97) | delCachedView({ commit, state }, view) {
method delOthersViews (line 104) | delOthersViews({ dispatch, state }, view) {
method delOthersVisitedViews (line 114) | delOthersVisitedViews({ commit, state }, view) {
method delOthersCachedViews (line 120) | delOthersCachedViews({ commit, state }, view) {
method delAllViews (line 127) | delAllViews({ dispatch, state }, view) {
method delAllVisitedViews (line 137) | delAllVisitedViews({ commit, state }) {
method delAllCachedViews (line 143) | delAllCachedViews({ commit, state }) {
method updateVisitedView (line 150) | updateVisitedView({ commit }, view) {
FILE: litemall-admin/src/store/modules/user.js
method LoginByUsername (line 35) | LoginByUsername({ commit }, userInfo) {
method GetUserInfo (line 50) | GetUserInfo({ commit, state }) {
method LogOut (line 72) | LogOut({ commit, state, dispatch }) {
method FedLogOut (line 93) | FedLogOut({ commit }) {
method ChangeRoles (line 103) | ChangeRoles({ commit, dispatch }, role) {
FILE: litemall-admin/src/utils/auth.js
function getToken (line 5) | function getToken() {
function setToken (line 9) | function setToken(token) {
function removeToken (line 13) | function removeToken() {
FILE: litemall-admin/src/utils/clipboard.js
function clipboardSuccess (line 4) | function clipboardSuccess() {
function clipboardError (line 12) | function clipboardError() {
function handleClipboard (line 19) | function handleClipboard(text, event) {
FILE: litemall-admin/src/utils/index.js
function parseTime (line 5) | function parseTime(time, cFormat) {
function thumbnail (line 40) | function thumbnail(src) {
function toPreview (line 44) | function toPreview(item, url) {
function formatTime (line 49) | function formatTime(time, option) {
function getQueryObject (line 84) | function getQueryObject(url) {
function getByteLen (line 104) | function getByteLen(val) {
function cleanArray (line 116) | function cleanArray(actual) {
function param (line 126) | function param(json) {
function param2Obj (line 136) | function param2Obj(url) {
function html2Text (line 151) | function html2Text(val) {
function objectMerge (line 157) | function objectMerge(target, source) {
function toggleClass (line 178) | function toggleClass(element, className) {
method onClick (line 197) | onClick(picker) {
method onClick (line 206) | onClick(picker) {
method onClick (line 215) | onClick(picker) {
method onClick (line 224) | onClick(picker) {
function getTime (line 233) | function getTime(type) {
function debounce (line 241) | function debounce(func, wait, immediate) {
function deepClone (line 281) | function deepClone(source) {
function uniqueArr (line 296) | function uniqueArr(arr) {
function isExternal (line 300) | function isExternal(path) {
FILE: litemall-admin/src/utils/openWindow.js
function openWindow (line 9) | function openWindow(url, title, w, h) {
FILE: litemall-admin/src/utils/permission.js
function checkPermission (line 8) | function checkPermission(value) {
FILE: litemall-admin/src/utils/scrollTo.js
function move (line 16) | function move(amount) {
function position (line 22) | function position() {
function scrollTo (line 26) | function scrollTo(to, duration, callback) {
FILE: litemall-admin/src/utils/validate.js
function isExternal (line 9) | function isExternal(path) {
function validUsername (line 17) | function validUsername(str) {
function validURL (line 26) | function validURL(url) {
function validLowerCase (line 35) | function validLowerCase(str) {
function validUpperCase (line 44) | function validUpperCase(str) {
function validAlphabets (line 53) | function validAlphabets(str) {
function validEmail (line 62) | function validEmail(email) {
function isString (line 71) | function isString(str) {
function isArray (line 82) | function isArray(arg) {
FILE: litemall-admin/src/vendor/Export2Excel.js
function generateArray (line 5) | function generateArray(table) {
function datenum (line 55) | function datenum(v, date1904) {
function sheet_from_array_of_arrays (line 61) | function sheet_from_array_of_arrays(data, opts) {
function Workbook (line 103) | function Workbook() {
function s2ab (line 109) | function s2ab(s) {
function export_table_to_excel (line 116) | function export_table_to_excel(id) {
function export_json_to_excel (line 147) | function export_json_to_excel({
function formatJson (line 222) | function formatJson(jsonSource, jsonFillter) {
function export_json_to_excel2 (line 228) | function export_json_to_excel2(th, jsonSource, jsonFillter, name) {
FILE: litemall-admin/src/views/layout/components/Sidebar/FixiOSBug.js
method device (line 3) | device() {
method mounted (line 7) | mounted() {
method fixBugIniOS (line 13) | fixBugIniOS() {
FILE: litemall-admin/src/views/layout/mixin/ResizeHandler.js
constant WIDTH (line 4) | const WIDTH = 1024
constant RATIO (line 5) | const RATIO = 3
method $route (line 9) | $route(route) {
method beforeMount (line 15) | beforeMount() {
method mounted (line 18) | mounted() {
method isMobile (line 26) | isMobile() {
method resizeHandler (line 30) | resizeHandler() {
FILE: litemall-admin/vue.config.js
function resolve (line 4) | function resolve(dir) {
method chainWebpack (line 54) | chainWebpack(config) {
FILE: litemall-all-war/src/main/java/org/linlinjava/litemall/Application.java
class Application (line 11) | @SpringBootApplication(scanBasePackages = {"org.linlinjava.litemall"})
method main (line 17) | public static void main(String[] args) throws Exception {
method configure (line 21) | @Override
FILE: litemall-all/src/main/java/org/linlinjava/litemall/Application.java
class Application (line 9) | @SpringBootApplication(scanBasePackages = {"org.linlinjava.litemall"})
method main (line 15) | public static void main(String[] args) throws Exception {
FILE: litemall-all/src/test/java/org/linlinjava/litemall/allinone/AllinoneConfigTest.java
class AllinoneConfigTest (line 11) | @WebAppConfiguration
method test (line 18) | @Test
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/config/AsyncConfig.java
class AsyncConfig (line 6) | @Configuration
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/config/CorsConfig.java
class CorsConfig (line 9) | @Configuration
method buildConfig (line 14) | private CorsConfiguration buildConfig() {
method corsFilter (line 24) | @Bean
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/config/GlobalExceptionHandler.java
class GlobalExceptionHandler (line 20) | @ControllerAdvice
method badArgumentHandler (line 26) | @ExceptionHandler(IllegalArgumentException.class)
method badArgumentHandler (line 33) | @ExceptionHandler(MethodArgumentTypeMismatchException.class)
method badArgumentHandler (line 40) | @ExceptionHandler(MissingServletRequestParameterException.class)
method badArgumentHandler (line 47) | @ExceptionHandler(HttpMessageNotReadableException.class)
method badArgumentHandler (line 54) | @ExceptionHandler(ValidationException.class)
method seriousHandler (line 69) | @ExceptionHandler(Exception.class)
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/config/JacksonConfig.java
class JacksonConfig (line 23) | @Configuration
method customJackson (line 26) | @Bean
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/config/ValidatorConfiguration.java
class ValidatorConfiguration (line 11) | @Configuration
method validator (line 13) | @Bean
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/config/WxConfig.java
class WxConfig (line 14) | @Configuration
method wxMaConfig (line 19) | @Bean
method wxMaService (line 30) | @Bean
method wxPayConfig (line 37) | @Bean
method wxPayService (line 51) | @Bean
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/config/WxProperties.java
class WxProperties (line 6) | @Configuration
method getToken (line 26) | public String getToken() {
method setToken (line 30) | public void setToken(String token) {
method getAesKey (line 34) | public String getAesKey() {
method setAesKey (line 38) | public void setAesKey(String aesKey) {
method getNotifyUrl (line 42) | public String getNotifyUrl() {
method setNotifyUrl (line 46) | public void setNotifyUrl(String notifyUrl) {
method getMchKey (line 50) | public String getMchKey() {
method setMchKey (line 54) | public void setMchKey(String mchKey) {
method getAppId (line 58) | public String getAppId() {
method setAppId (line 62) | public void setAppId(String appId) {
method getAppSecret (line 66) | public String getAppSecret() {
method setAppSecret (line 70) | public void setAppSecret(String appSecret) {
method getMchId (line 74) | public String getMchId() {
method setMchId (line 78) | public void setMchId(String mchId) {
method getKeyPath (line 82) | public String getKeyPath() {
method setKeyPath (line 86) | public void setKeyPath(String keyPath) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/express/ExpressService.java
class ExpressService (line 22) | public class ExpressService {
method getProperties (line 30) | public ExpressProperties getProperties() {
method setProperties (line 34) | public void setProperties(ExpressProperties properties) {
method getVendorName (line 44) | public String getVendorName(String vendorCode) {
method getVendors (line 52) | public List<Map<String, String>> getVendors() {
method getExpressInfo (line 63) | public ExpressInfo getExpressInfo(String expCode, String expNo) {
method getOrderTracesByJson (line 86) | private String getOrderTracesByJson(String expCode, String expNo) thro...
method MD5 (line 111) | private String MD5(String str, String charset) throws Exception {
method encrypt (line 134) | private String encrypt(String content, String keyValue, String charset) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/express/config/ExpressAutoConfiguration.java
class ExpressAutoConfiguration (line 8) | @Configuration
method ExpressAutoConfiguration (line 14) | public ExpressAutoConfiguration(ExpressProperties properties) {
method expressService (line 18) | @Bean
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/express/config/ExpressProperties.java
class ExpressProperties (line 9) | @ConfigurationProperties(prefix = "litemall.express")
method isEnable (line 16) | public boolean isEnable() {
method setEnable (line 20) | public void setEnable(boolean enable) {
method getVendors (line 24) | public List<Map<String, String>> getVendors() {
method setVendors (line 28) | public void setVendors(List<Map<String, String>> vendors) {
method getAppKey (line 32) | public String getAppKey() {
method setAppKey (line 36) | public void setAppKey(String appKey) {
method getAppId (line 40) | public String getAppId() {
method setAppId (line 44) | public void setAppId(String appId) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/express/dao/ExpressInfo.java
class ExpressInfo (line 16) | public class ExpressInfo {
method getLogisticCode (line 35) | public String getLogisticCode() {
method setLogisticCode (line 39) | public void setLogisticCode(String LogisticCode) {
method getShipperCode (line 43) | public String getShipperCode() {
method setShipperCode (line 47) | public void setShipperCode(String ShipperCode) {
method getTraces (line 51) | public List<Traces> getTraces() {
method setTraces (line 55) | public void setTraces(List<Traces> Traces) {
method getState (line 59) | public String getState() {
method setState (line 63) | public void setState(String State) {
method getEBusinessID (line 67) | public String getEBusinessID() {
method setEBusinessID (line 71) | public void setEBusinessID(String EBusinessID) {
method getSuccess (line 75) | public boolean getSuccess() {
method setSuccess (line 79) | public void setSuccess(boolean Success) {
method getReason (line 83) | public String getReason() {
method setReason (line 87) | public void setReason(String Reason) {
method getShipperName (line 91) | public String getShipperName() {
method setShipperName (line 95) | public void setShipperName(String shipperName) {
method toString (line 99) | @Override
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/express/dao/Traces.java
class Traces (line 14) | public class Traces {
method getAcceptStation (line 21) | public String getAcceptStation() {
method setAcceptStation (line 25) | public void setAcceptStation(String AcceptStation) {
method getAcceptTime (line 29) | public String getAcceptTime() {
method setAcceptTime (line 33) | public void setAcceptTime(String AcceptTime) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/notify/AliyunSmsSender.java
class AliyunSmsSender (line 22) | public class AliyunSmsSender implements SmsSender {
method getRegionId (line 32) | public String getRegionId() {
method setRegionId (line 36) | public void setRegionId(String regionId) {
method getAccessKeyId (line 40) | public String getAccessKeyId() {
method setAccessKeyId (line 44) | public void setAccessKeyId(String accessKeyId) {
method getAccessKeySecret (line 48) | public String getAccessKeySecret() {
method setAccessKeySecret (line 52) | public void setAccessKeySecret(String accessKeySecret) {
method getSign (line 56) | public String getSign() {
method setSign (line 60) | public void setSign(String sign) {
method send (line 64) | @Override
method sendWithTemplate (line 71) | @Override
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyService.java
class NotifyService (line 14) | public class NotifyService {
method isMailEnable (line 24) | public boolean isMailEnable() {
method isSmsEnable (line 28) | public boolean isSmsEnable() {
method notifySms (line 38) | @Async
method notifySmsTemplate (line 53) | @Async
method notifySmsTemplateSync (line 75) | public SmsResult notifySmsTemplateSync(String phoneNumber, NotifyType ...
method notifyMail (line 89) | @Async
method getTemplateId (line 102) | private String getTemplateId(NotifyType notifyType, List<Map<String, S...
method setMailSender (line 112) | public void setMailSender(MailSender mailSender) {
method setSendFrom (line 116) | public void setSendFrom(String sendFrom) {
method setSendTo (line 120) | public void setSendTo(String sendTo) {
method setSmsSender (line 124) | public void setSmsSender(SmsSender smsSender) {
method setSmsTemplate (line 128) | public void setSmsTemplate(List<Map<String, String>> smsTemplate) {
method setWxTemplate (line 132) | public void setWxTemplate(List<Map<String, String>> wxTemplate) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/notify/NotifyType.java
type NotifyType (line 3) | public enum NotifyType {
method NotifyType (line 11) | NotifyType(String type) {
method getType (line 15) | public String getType() {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/notify/SmsResult.java
class SmsResult (line 6) | public class SmsResult {
method isSuccessful (line 15) | public boolean isSuccessful() {
method setSuccessful (line 19) | public void setSuccessful(boolean successful) {
method getResult (line 23) | public Object getResult() {
method setResult (line 27) | public void setResult(Object result) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/notify/SmsSender.java
type SmsSender (line 3) | public interface SmsSender {
method send (line 11) | SmsResult send(String phone, String content);
method sendWithTemplate (line 20) | SmsResult sendWithTemplate(String phone, String templateId, String[] p...
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/notify/TencentSmsSender.java
class TencentSmsSender (line 14) | public class TencentSmsSender implements SmsSender {
method getSender (line 20) | public SmsSingleSender getSender() {
method setSender (line 24) | public void setSender(SmsSingleSender sender) {
method send (line 28) | @Override
method sendWithTemplate (line 47) | @Override
method setSign (line 66) | public void setSign(String sign) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/notify/config/NotifyAutoConfiguration.java
class NotifyAutoConfiguration (line 15) | @Configuration
method NotifyAutoConfiguration (line 21) | public NotifyAutoConfiguration(NotifyProperties properties) {
method notifyService (line 25) | @Bean
method mailSender (line 51) | public JavaMailSender mailSender() {
method tencentSmsSender (line 71) | public TencentSmsSender tencentSmsSender() {
method aliyunSmsSender (line 80) | public AliyunSmsSender aliyunSmsSender() {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/notify/config/NotifyProperties.java
class NotifyProperties (line 9) | @ConfigurationProperties(prefix = "litemall.notify")
method getMail (line 14) | public Mail getMail() {
method setMail (line 18) | public void setMail(Mail mail) {
method getSms (line 22) | public Sms getSms() {
method setSms (line 26) | public void setSms(Sms sms) {
class Mail (line 30) | public static class Mail {
method isEnable (line 38) | public boolean isEnable() {
method setEnable (line 42) | public void setEnable(boolean enable) {
method getHost (line 46) | public String getHost() {
method setHost (line 50) | public void setHost(String host) {
method getUsername (line 54) | public String getUsername() {
method setUsername (line 58) | public void setUsername(String username) {
method getPassword (line 62) | public String getPassword() {
method setPassword (line 66) | public void setPassword(String password) {
method getSendfrom (line 70) | public String getSendfrom() {
method setSendfrom (line 74) | public void setSendfrom(String sendfrom) {
method getSendto (line 78) | public String getSendto() {
method setSendto (line 82) | public void setSendto(String sendto) {
method getPort (line 86) | public Integer getPort() {
method setPort (line 90) | public void setPort(Integer port) {
class Sms (line 95) | public static class Sms {
method isEnable (line 103) | public boolean isEnable() {
method setEnable (line 107) | public void setEnable(boolean enable) {
method getTemplate (line 111) | public List<Map<String, String>> getTemplate() {
method setTemplate (line 115) | public void setTemplate(List<Map<String, String>> template) {
method getActive (line 119) | public String getActive() {
method setActive (line 123) | public void setActive(String active) {
method getSign (line 127) | public String getSign() {
method setSign (line 131) | public void setSign(String sign) {
method getTencent (line 135) | public Tencent getTencent() {
method setTencent (line 139) | public void setTencent(Tencent tencent) {
method getAliyun (line 143) | public Aliyun getAliyun() {
method setAliyun (line 147) | public void setAliyun(Aliyun aliyun) {
class Tencent (line 151) | public static class Tencent {
method getAppid (line 155) | public int getAppid() {
method setAppid (line 159) | public void setAppid(int appid) {
method getAppkey (line 163) | public String getAppkey() {
method setAppkey (line 167) | public void setAppkey(String appkey) {
class Aliyun (line 172) | public static class Aliyun {
method getRegionId (line 177) | public String getRegionId() {
method setRegionId (line 181) | public void setRegionId(String regionId) {
method getAccessKeyId (line 185) | public String getAccessKeyId() {
method setAccessKeyId (line 189) | public void setAccessKeyId(String accessKeyId) {
method getAccessKeySecret (line 193) | public String getAccessKeySecret() {
method setAccessKeySecret (line 197) | public void setAccessKeySecret(String accessKeySecret) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/qcode/QCodeService.java
class QCodeService (line 21) | @Service
method createGrouponShareImage (line 31) | public String createGrouponShareImage(String goodName, String goodPicU...
method createGoodShareImage (line 64) | public String createGoodShareImage(String goodId, String goodPicUrl, S...
method getKeyName (line 91) | private String getKeyName(String goodId) {
method drawPicture (line 104) | private byte[] drawPicture(InputStream qrCodeImg, String goodPicUrl, S...
method drawTextInImgCenter (line 149) | private void drawTextInImgCenter(BufferedImage baseImage, String textT...
method drawTextInImg (line 170) | private void drawTextInImg(BufferedImage baseImage, String textToWrite...
method drawImgInImg (line 182) | private void drawImgInImg(BufferedImage baseImage, BufferedImage image...
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/storage/AliyunStorage.java
class AliyunStorage (line 23) | public class AliyunStorage implements Storage {
method getEndpoint (line 32) | public String getEndpoint() {
method setEndpoint (line 36) | public void setEndpoint(String endpoint) {
method getAccessKeyId (line 40) | public String getAccessKeyId() {
method setAccessKeyId (line 44) | public void setAccessKeyId(String accessKeyId) {
method getAccessKeySecret (line 48) | public String getAccessKeySecret() {
method setAccessKeySecret (line 52) | public void setAccessKeySecret(String accessKeySecret) {
method getBucketName (line 56) | public String getBucketName() {
method setBucketName (line 60) | public void setBucketName(String bucketName) {
method getOSSClient (line 69) | private OSSClient getOSSClient() {
method getBaseUrl (line 73) | private String getBaseUrl() {
method store (line 80) | @Override
method loadAll (line 96) | @Override
method load (line 101) | @Override
method loadAsResource (line 106) | @Override
method delete (line 122) | @Override
method generateUrl (line 132) | @Override
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/storage/LocalStorage.java
class LocalStorage (line 21) | public class LocalStorage implements Storage {
method getStoragePath (line 31) | public String getStoragePath() {
method setStoragePath (line 35) | public void setStoragePath(String storagePath) {
method getAddress (line 46) | public String getAddress() {
method setAddress (line 50) | public void setAddress(String address) {
method store (line 54) | @Override
method loadAll (line 63) | @Override
method load (line 75) | @Override
method loadAsResource (line 80) | @Override
method delete (line 96) | @Override
method generateUrl (line 106) | @Override
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/storage/QiniuStorage.java
class QiniuStorage (line 19) | public class QiniuStorage implements Storage {
method getEndpoint (line 31) | public String getEndpoint() {
method setEndpoint (line 35) | public void setEndpoint(String endpoint) {
method getAccessKey (line 39) | public String getAccessKey() {
method setAccessKey (line 43) | public void setAccessKey(String accessKey) {
method getSecretKey (line 47) | public String getSecretKey() {
method setSecretKey (line 51) | public void setSecretKey(String secretKey) {
method getBucketName (line 55) | public String getBucketName() {
method setBucketName (line 59) | public void setBucketName(String bucketName) {
method store (line 66) | @Override
method loadAll (line 83) | @Override
method load (line 88) | @Override
method loadAsResource (line 93) | @Override
method delete (line 107) | @Override
method generateUrl (line 122) | @Override
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/storage/Storage.java
type Storage (line 12) | public interface Storage {
method store (line 22) | void store(InputStream inputStream, long contentLength, String content...
method loadAll (line 24) | Stream<Path> loadAll();
method load (line 26) | Path load(String keyName);
method loadAsResource (line 28) | Resource loadAsResource(String keyName);
method delete (line 30) | void delete(String keyName);
method generateUrl (line 32) | String generateUrl(String keyName);
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/storage/StorageService.java
class StorageService (line 16) | public class StorageService {
method getActive (line 22) | public String getActive() {
method setActive (line 26) | public void setActive(String active) {
method getStorage (line 30) | public Storage getStorage() {
method setStorage (line 34) | public void setStorage(Storage storage) {
method store (line 46) | public LitemallStorage store(InputStream inputStream, long contentLeng...
method generateKey (line 62) | private String generateKey(String originalFilename) {
method loadAll (line 78) | public Stream<Path> loadAll() {
method load (line 82) | public Path load(String keyName) {
method loadAsResource (line 86) | public Resource loadAsResource(String keyName) {
method delete (line 90) | public void delete(String keyName) {
method generateUrl (line 94) | private String generateUrl(String keyName) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/storage/TencentStorage.java
class TencentStorage (line 24) | public class TencentStorage implements Storage {
method getSecretId (line 35) | public String getSecretId() {
method setSecretId (line 39) | public void setSecretId(String secretId) {
method getSecretKey (line 43) | public String getSecretKey() {
method setSecretKey (line 47) | public void setSecretKey(String secretKey) {
method getRegion (line 51) | public String getRegion() {
method setRegion (line 55) | public void setRegion(String region) {
method getBucketName (line 59) | public String getBucketName() {
method setBucketName (line 63) | public void setBucketName(String bucketName) {
method getCOSClient (line 67) | private COSClient getCOSClient() {
method getBaseUrl (line 79) | private String getBaseUrl() {
method store (line 83) | @Override
method loadAll (line 99) | @Override
method load (line 104) | @Override
method loadAsResource (line 109) | @Override
method delete (line 123) | @Override
method generateUrl (line 133) | @Override
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/storage/config/StorageAutoConfiguration.java
class StorageAutoConfiguration (line 8) | @Configuration
method StorageAutoConfiguration (line 14) | public StorageAutoConfiguration(StorageProperties properties) {
method storageService (line 18) | @Bean
method localStorage (line 38) | @Bean
method aliyunStorage (line 47) | @Bean
method tencentStorage (line 58) | @Bean
method qiniuStorage (line 69) | @Bean
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/storage/config/StorageProperties.java
class StorageProperties (line 5) | @ConfigurationProperties(prefix = "litemall.storage")
method getActive (line 13) | public String getActive() {
method setActive (line 17) | public void setActive(String active) {
method getLocal (line 21) | public Local getLocal() {
method setLocal (line 25) | public void setLocal(Local local) {
method getAliyun (line 29) | public Aliyun getAliyun() {
method setAliyun (line 33) | public void setAliyun(Aliyun aliyun) {
method getTencent (line 37) | public Tencent getTencent() {
method setTencent (line 41) | public void setTencent(Tencent tencent) {
method getQiniu (line 45) | public Qiniu getQiniu() {
method setQiniu (line 49) | public void setQiniu(Qiniu qiniu) {
class Local (line 53) | public static class Local {
method getAddress (line 57) | public String getAddress() {
method setAddress (line 61) | public void setAddress(String address) {
method getStoragePath (line 65) | public String getStoragePath() {
method setStoragePath (line 69) | public void setStoragePath(String storagePath) {
class Tencent (line 74) | public static class Tencent {
method getSecretId (line 80) | public String getSecretId() {
method setSecretId (line 84) | public void setSecretId(String secretId) {
method getSecretKey (line 88) | public String getSecretKey() {
method setSecretKey (line 92) | public void setSecretKey(String secretKey) {
method getRegion (line 96) | public String getRegion() {
method setRegion (line 100) | public void setRegion(String region) {
method getBucketName (line 104) | public String getBucketName() {
method setBucketName (line 108) | public void setBucketName(String bucketName) {
class Aliyun (line 113) | public static class Aliyun {
method getEndpoint (line 119) | public String getEndpoint() {
method setEndpoint (line 123) | public void setEndpoint(String endpoint) {
method getAccessKeyId (line 127) | public String getAccessKeyId() {
method setAccessKeyId (line 131) | public void setAccessKeyId(String accessKeyId) {
method getAccessKeySecret (line 135) | public String getAccessKeySecret() {
method setAccessKeySecret (line 139) | public void setAccessKeySecret(String accessKeySecret) {
method getBucketName (line 143) | public String getBucketName() {
method setBucketName (line 147) | public void setBucketName(String bucketName) {
class Qiniu (line 152) | public static class Qiniu {
method getEndpoint (line 158) | public String getEndpoint() {
method setEndpoint (line 162) | public void setEndpoint(String endpoint) {
method getAccessKey (line 166) | public String getAccessKey() {
method setAccessKey (line 170) | public void setAccessKey(String accessKey) {
method getSecretKey (line 174) | public String getSecretKey() {
method setSecretKey (line 178) | public void setSecretKey(String secretKey) {
method getBucketName (line 182) | public String getBucketName() {
method setBucketName (line 186) | public void setBucketName(String bucketName) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/system/SystemConfig.java
class SystemConfig (line 10) | public class SystemConfig {
method getConfig (line 37) | private static String getConfig(String keyName) {
method getConfigInt (line 41) | private static Integer getConfigInt(String keyName) {
method getConfigBoolean (line 45) | private static Boolean getConfigBoolean(String keyName) {
method getConfigBigDec (line 49) | private static BigDecimal getConfigBigDec(String keyName) {
method getNewLimit (line 53) | public static Integer getNewLimit() {
method getHotLimit (line 57) | public static Integer getHotLimit() {
method getBrandLimit (line 61) | public static Integer getBrandLimit() {
method getTopicLimit (line 65) | public static Integer getTopicLimit() {
method getCatlogListLimit (line 69) | public static Integer getCatlogListLimit() {
method getCatlogMoreLimit (line 73) | public static Integer getCatlogMoreLimit() {
method isAutoCreateShareImage (line 77) | public static boolean isAutoCreateShareImage() {
method getFreight (line 81) | public static BigDecimal getFreight() {
method getFreightLimit (line 85) | public static BigDecimal getFreightLimit() {
method getOrderUnpaid (line 89) | public static Integer getOrderUnpaid() {
method getOrderUnconfirm (line 93) | public static Integer getOrderUnconfirm() {
method getOrderComment (line 97) | public static Integer getOrderComment() {
method getMallName (line 101) | public static String getMallName() {
method getMallAddress (line 105) | public static String getMallAddress() {
method getMallPhone (line 109) | public static String getMallPhone() {
method getMallQQ (line 113) | public static String getMallQQ() {
method getMallLongitude (line 117) | public static String getMallLongitude() {
method getMallLatitude (line 121) | public static String getMallLatitude() {
method setConfigs (line 125) | public static void setConfigs(Map<String, String> configs) {
method updateConfigs (line 129) | public static void updateConfigs(Map<String, String> data) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/system/SystemInistService.java
class SystemInistService (line 17) | @Component
method inist (line 25) | @PostConstruct
method initConfigs (line 63) | private void initConfigs() {
method getSystemInfo (line 80) | private Map<String, String> getSystemInfo() {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/task/Task.java
class Task (line 9) | public abstract class Task implements Delayed, Runnable{
method Task (line 13) | public Task(String id, long delayInMilliseconds){
method getId (line 18) | public String getId() {
method getDelay (line 22) | @Override
method compareTo (line 28) | @Override
method equals (line 33) | @Override
method hashCode (line 44) | @Override
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/task/TaskService.java
class TaskService (line 8) | @Component
method init (line 13) | @PostConstruct
method addTask (line 32) | public void addTask(Task task){
method removeTask (line 39) | public void removeTask(Task task){
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/BeanUtil.java
class BeanUtil (line 8) | @Component
method setApplicationContext (line 12) | @Override
method getBean (line 17) | public static Object getBean(String name) {
method getBean (line 21) | public static <T> T getBean(Class<T> c){
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/CharUtil.java
class CharUtil (line 5) | public class CharUtil {
method getRandomString (line 7) | public static String getRandomString(Integer num) {
method getRandomNum (line 18) | public static String getRandomNum(Integer num) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/DateTimeUtil.java
class DateTimeUtil (line 9) | public class DateTimeUtil {
method getDateTimeDisplayString (line 17) | public static String getDateTimeDisplayString(LocalDateTime dateTime) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/HttpUtil.java
class HttpUtil (line 19) | public class HttpUtil {
method sendPost (line 30) | @SuppressWarnings("unused")
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/IpUtil.java
class IpUtil (line 13) | public class IpUtil {
method getIpAddr (line 17) | public static String getIpAddr(HttpServletRequest request) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/JacksonUtil.java
class JacksonUtil (line 14) | public class JacksonUtil {
method parseString (line 18) | public static String parseString(String body, String field) {
method parseStringList (line 33) | public static List<String> parseStringList(String body, String field) {
method parseInteger (line 49) | public static Integer parseInteger(String body, String field) {
method parseIntegerList (line 63) | public static List<Integer> parseIntegerList(String body, String field) {
method parseBoolean (line 80) | public static Boolean parseBoolean(String body, String field) {
method parseShort (line 94) | public static Short parseShort(String body, String field) {
method parseByte (line 110) | public static Byte parseByte(String body, String field) {
method parseObject (line 126) | public static <T> T parseObject(String body, String field, Class<T> cl...
method toNode (line 139) | public static Object toNode(String json) {
method toMap (line 154) | public static Map<String, String> toMap(String data) {
method toJson (line 165) | public static String toJson(Object data) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/RegexUtil.java
class RegexUtil (line 15) | public class RegexUtil {
method RegexUtil (line 124) | private RegexUtil() {
method isMobileSimple (line 138) | public static boolean isMobileSimple(final CharSequence input) {
method isMobileExact (line 148) | public static boolean isMobileExact(final CharSequence input) {
method isTel (line 158) | public static boolean isTel(final CharSequence input) {
method isIDCard15 (line 168) | public static boolean isIDCard15(final CharSequence input) {
method isIDCard18 (line 178) | public static boolean isIDCard18(final CharSequence input) {
method isEmail (line 188) | public static boolean isEmail(final CharSequence input) {
method isURL (line 198) | public static boolean isURL(final CharSequence input) {
method isZh (line 208) | public static boolean isZh(final CharSequence input) {
method isUsername (line 221) | public static boolean isUsername(final CharSequence input) {
method isDate (line 231) | public static boolean isDate(final CharSequence input) {
method isIP (line 241) | public static boolean isIP(final CharSequence input) {
method isMatch (line 252) | public static boolean isMatch(final String regex, final CharSequence i...
method getMatches (line 263) | public static List<String> getMatches(final String regex, final CharSe...
method getSplits (line 282) | public static String[] getSplits(final String input, final String rege...
method getReplaceFirst (line 299) | public static String getReplaceFirst(final String input,
method getReplaceAll (line 318) | public static String getReplaceAll(final String input,
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/ResponseUtil.java
class ResponseUtil (line 42) | public class ResponseUtil {
method ok (line 43) | public static Object ok() {
method ok (line 50) | public static Object ok(Object data) {
method okList (line 58) | public static Object okList(List list) {
method okList (line 78) | public static Object okList(List list, List pagedList) {
method fail (line 98) | public static Object fail() {
method fail (line 105) | public static Object fail(int errno, String errmsg) {
method fail (line 112) | public static Object fail(int errno, String errmsg, String data) {
method badArgument (line 120) | public static Object badArgument() {
method badArgumentValue (line 124) | public static Object badArgumentValue() {
method unlogin (line 128) | public static Object unlogin() {
method serious (line 132) | public static Object serious() {
method unsupport (line 136) | public static Object unsupport() {
method updatedDateExpired (line 140) | public static Object updatedDateExpired() {
method updatedDataFailed (line 144) | public static Object updatedDataFailed() {
method unauthz (line 148) | public static Object unauthz() {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/SystemInfoPrinter.java
class SystemInfoPrinter (line 8) | public class SystemInfoPrinter {
method printInfo (line 15) | public static void printInfo(String title, Map<String, String> infos) {
method setMaxSize (line 27) | private static void setMaxSize(Map<String, String> infos) {
method printHeader (line 41) | private static void printHeader(String title) {
method printEnd (line 48) | private static void printEnd() {
method getLineCopper (line 53) | private static String getLineCopper() {
method printLine (line 62) | private static void printLine(String head, String line) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/bcrypt/BCrypt.java
class BCrypt (line 59) | public class BCrypt {
method encode_base64 (line 275) | static void encode_base64(byte d[], int len, StringBuilder rs)
method char64 (line 314) | private static byte char64(char x) {
method decode_base64 (line 330) | static byte[] decode_base64(String s, int maxolen) throws IllegalArgum...
method streamtoword (line 378) | private static int streamtoword(byte data[], int offp[]) {
method roundsForLogRounds (line 392) | static long roundsForLogRounds(int log_rounds) {
method hashpw (line 407) | public static String hashpw(String password, String salt) throws Illeg...
method gensalt (line 483) | public static String gensalt(int log_rounds, SecureRandom random) {
method gensalt (line 509) | public static String gensalt(int log_rounds) {
method gensalt (line 519) | public static String gensalt() {
method checkpw (line 530) | public static boolean checkpw(String plaintext, String hashed) {
method equalsNoEarlyReturn (line 534) | static boolean equalsNoEarlyReturn(String a, String b) {
method encipher (line 555) | private final void encipher(int lr[], int off) {
method init_key (line 581) | private void init_key() {
method key (line 591) | private void key(byte key[]) {
method ekskey (line 621) | private void ekskey(byte data[], byte key[]) {
method crypt_raw (line 656) | private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) {
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/util/bcrypt/BCryptPasswordEncoder.java
class BCryptPasswordEncoder (line 32) | public class BCryptPasswordEncoder {
method BCryptPasswordEncoder (line 39) | public BCryptPasswordEncoder() {
method BCryptPasswordEncoder (line 46) | public BCryptPasswordEncoder(int strength) {
method BCryptPasswordEncoder (line 54) | public BCryptPasswordEncoder(int strength, SecureRandom random) {
method encode (line 62) | public String encode(CharSequence rawPassword) {
method matches (line 76) | public boolean matches(CharSequence rawPassword, String encodedPasswor...
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/validator/OrderValidator.java
class OrderValidator (line 9) | public class OrderValidator implements ConstraintValidator<Order, String> {
method initialize (line 12) | @Override
method isValid (line 20) | @Override
FILE: litemall-core/src/main/java/org/linlinjava/litemall/core/validator/SortValidator.java
class SortValidator (line 9) | public class SortValidator implements ConstraintValidator<Sort, String> {
method initialize (line 12) | @Override
method isValid (line 20) | @Override
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/AliyunStorageTest.java
class AliyunStorageTest (line 18) | @WebAppConfiguration
method test (line 27) | @Test
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/Application.java
class Application (line 7) | @SpringBootApplication(scanBasePackages = {"org.linlinjava.litemall.db",...
method main (line 11) | public static void main(String[] args) {
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/AsyncTask.java
class AsyncTask (line 8) | @Service
method asyncMethod (line 12) | @Async
method nonasyncMethod (line 18) | public void nonasyncMethod() {
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/AsyncTest.java
class AsyncTest (line 14) | @WebAppConfiguration
method test (line 22) | @Test
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/CoreConfigTest.java
class CoreConfigTest (line 14) | @WebAppConfiguration
method test (line 22) | @Test
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/ExpressTest.java
class ExpressTest (line 15) | @WebAppConfiguration
method test (line 24) | @Test
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/IntegerTest.java
class IntegerTest (line 5) | public class IntegerTest {
method test (line 6) | @Test
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/LocalStorageTest.java
class LocalStorageTest (line 19) | @WebAppConfiguration
method test (line 28) | @Test
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/MailTest.java
class MailTest (line 29) | @WebAppConfiguration
method testMail (line 37) | @Test
class ContextConfiguration (line 42) | @Configuration
method executor (line 45) | @Bean
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/QiniuStorageTest.java
class QiniuStorageTest (line 19) | @WebAppConfiguration
method test (line 28) | @Test
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/SmsTest.java
class SmsTest (line 31) | @WebAppConfiguration
method testCaptcha (line 39) | @Test
method testPaySucceed (line 47) | @Test
method testShip (line 55) | @Test
method testRefund (line 63) | @Test
class ContextConfiguration (line 71) | @Configuration
method executor (line 74) | @Bean
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/TaskTest.java
class TaskTest (line 29) | @WebAppConfiguration
class DemoTask (line 37) | private class DemoTask extends Task {
method DemoTask (line 39) | DemoTask(String id, long delayInMilliseconds){
method run (line 42) | @Override
method test (line 51) | @Test
method test1 (line 72) | @Test
method test2 (line 93) | @Test
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/TencentStorageTest.java
class TencentStorageTest (line 19) | @WebAppConfiguration
method test (line 28) | @Test
FILE: litemall-core/src/test/java/org/linlinjava/litemall/core/util/bcrypt/BCryptTest.java
class BCryptTest (line 14) | @RunWith(PowerMockRunner.class)
method testHashpwSaltIsNull (line 20) | @Test
method testHashpwSaltTooShort (line 26) | @Test
method testHashpwInvalidSaltVersion (line 32) | @Test
method testHashpwInvalidSaltVersion2 (line 38) | @Test
method testHashpwInvalidSaltRevision (line 44) | @Test
method testHashpwInvalidSaltRevision2 (line 50) | @Test
method testHashpwSaltTooShort2 (line 56) | @Test
method testHashpwMissingSaltRounds (line 62) | @Test
method testHashpwTooLittleRounds (line 68) | @Test
method testHashpwTooManyRounds (line 74) | @Test
method testHashpw (line 80) | @Test
method testGensalt (line 91) | @PrepareForTest({BCrypt.class, SecureRandom.class})
method testGensaltTooLittleRounds (line 100) | @Test
method testGensaltTooManyRounds (line 106) | @Test
method testCheckpw (line 112) | @Test
FILE: litemall-db/sql/litemall_table.sql
type `litemall_ad` (line 25) | CREATE TABLE `litemall_ad` (
type `litemall_address` (line 50) | CREATE TABLE `litemall_address` (
type `litemall_admin` (line 77) | CREATE TABLE `litemall_admin` (
type `litemall_aftersale` (line 99) | CREATE TABLE `litemall_aftersale` (
type `litemall_brand` (line 125) | CREATE TABLE `litemall_brand` (
type `litemall_cart` (line 146) | CREATE TABLE `litemall_cart` (
type `litemall_category` (line 172) | CREATE TABLE `litemall_category` (
type `litemall_collect` (line 197) | CREATE TABLE `litemall_collect` (
type `litemall_comment` (line 218) | CREATE TABLE `litemall_comment` (
type `litemall_coupon` (line 243) | CREATE TABLE `litemall_coupon` (
type `litemall_coupon_user` (line 276) | CREATE TABLE `litemall_coupon_user` (
type `litemall_feedback` (line 299) | CREATE TABLE `litemall_feedback` (
type `litemall_footprint` (line 324) | CREATE TABLE `litemall_footprint` (
type `litemall_goods` (line 342) | CREATE TABLE `litemall_goods` (
type `litemall_goods_attribute` (line 379) | CREATE TABLE `litemall_goods_attribute` (
type `litemall_goods_product` (line 399) | CREATE TABLE `litemall_goods_product` (
type `litemall_goods_specification` (line 421) | CREATE TABLE `litemall_goods_specification` (
type `litemall_groupon` (line 442) | CREATE TABLE `litemall_groupon` (
type `litemall_groupon_rules` (line 466) | CREATE TABLE `litemall_groupon_rules` (
type `litemall_issue` (line 490) | CREATE TABLE `litemall_issue` (
type `litemall_keyword` (line 508) | CREATE TABLE `litemall_keyword` (
type `litemall_log` (line 529) | CREATE TABLE `litemall_log` (
type `litemall_notice` (line 552) | CREATE TABLE `litemall_notice` (
type `litemall_notice_admin` (line 571) | CREATE TABLE `litemall_notice_admin` (
type `litemall_order` (line 591) | CREATE TABLE `litemall_order` (
type `litemall_order_goods` (line 634) | CREATE TABLE `litemall_order_goods` (
type `litemall_permission` (line 662) | CREATE TABLE `litemall_permission` (
type `litemall_region` (line 680) | CREATE TABLE `litemall_region` (
type `litemall_role` (line 700) | CREATE TABLE `litemall_role` (
type `litemall_search_history` (line 720) | CREATE TABLE `litemall_search_history` (
type `litemall_storage` (line 739) | CREATE TABLE `litemall_storage` (
type `litemall_system` (line 761) | CREATE TABLE `litemall_system` (
type `litemall_topic` (line 779) | CREATE TABLE `litemall_topic` (
type `litemall_user` (line 804) | CREATE TABLE `litemall_user` (
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/GoodsProductMapper.java
type GoodsProductMapper (line 5) | public interface GoodsProductMapper {
method addStock (line 6) | int addStock(@Param("id") Integer id, @Param("num") Short num);
method reduceStock (line 7) | int reduceStock(@Param("id") Integer id, @Param("num") Short num);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallAdMapper.java
type LitemallAdMapper (line 8) | public interface LitemallAdMapper {
method countByExample (line 15) | long countByExample(LitemallAdExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallAdExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallAd record);
method insertSelective (line 47) | int insertSelective(LitemallAd record);
method selectOneByExample (line 55) | LitemallAd selectOneByExample(LitemallAdExample example);
method selectOneByExampleSelective (line 63) | LitemallAd selectOneByExampleSelective(@Param("example") LitemallAdExa...
method selectByExampleSelective (line 71) | List<LitemallAd> selectByExampleSelective(@Param("example") LitemallAd...
method selectByExample (line 79) | List<LitemallAd> selectByExample(LitemallAdExample example);
method selectByPrimaryKeySelective (line 87) | LitemallAd selectByPrimaryKeySelective(@Param("id") Integer id, @Param...
method selectByPrimaryKey (line 95) | LitemallAd selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallAd selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer id...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallAd record, @Para...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallAd record, @Param("exampl...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallAd record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallAd record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallAdExample example);
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallAddressMapper.java
type LitemallAddressMapper (line 8) | public interface LitemallAddressMapper {
method countByExample (line 15) | long countByExample(LitemallAddressExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallAddressExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallAddress record);
method insertSelective (line 47) | int insertSelective(LitemallAddress record);
method selectOneByExample (line 55) | LitemallAddress selectOneByExample(LitemallAddressExample example);
method selectOneByExampleSelective (line 63) | LitemallAddress selectOneByExampleSelective(@Param("example") Litemall...
method selectByExampleSelective (line 71) | List<LitemallAddress> selectByExampleSelective(@Param("example") Litem...
method selectByExample (line 79) | List<LitemallAddress> selectByExample(LitemallAddressExample example);
method selectByPrimaryKeySelective (line 87) | LitemallAddress selectByPrimaryKeySelective(@Param("id") Integer id, @...
method selectByPrimaryKey (line 95) | LitemallAddress selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallAddress selectByPrimaryKeyWithLogicalDelete(@Param("id") Integ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallAddress record, ...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallAddress record, @Param("e...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallAddress record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallAddress record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallAddressExample ex...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallAdminMapper.java
type LitemallAdminMapper (line 8) | public interface LitemallAdminMapper {
method countByExample (line 15) | long countByExample(LitemallAdminExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallAdminExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallAdmin record);
method insertSelective (line 47) | int insertSelective(LitemallAdmin record);
method selectOneByExample (line 55) | LitemallAdmin selectOneByExample(LitemallAdminExample example);
method selectOneByExampleSelective (line 63) | LitemallAdmin selectOneByExampleSelective(@Param("example") LitemallAd...
method selectByExampleSelective (line 71) | List<LitemallAdmin> selectByExampleSelective(@Param("example") Litemal...
method selectByExample (line 79) | List<LitemallAdmin> selectByExample(LitemallAdminExample example);
method selectByPrimaryKeySelective (line 87) | LitemallAdmin selectByPrimaryKeySelective(@Param("id") Integer id, @Pa...
method selectByPrimaryKey (line 95) | LitemallAdmin selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallAdmin selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallAdmin record, @P...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallAdmin record, @Param("exa...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallAdmin record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallAdmin record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallAdminExample exam...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallAftersaleMapper.java
type LitemallAftersaleMapper (line 8) | public interface LitemallAftersaleMapper {
method countByExample (line 15) | long countByExample(LitemallAftersaleExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallAftersaleExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallAftersale record);
method insertSelective (line 47) | int insertSelective(LitemallAftersale record);
method selectOneByExample (line 55) | LitemallAftersale selectOneByExample(LitemallAftersaleExample example);
method selectOneByExampleSelective (line 63) | LitemallAftersale selectOneByExampleSelective(@Param("example") Litema...
method selectByExampleSelective (line 71) | List<LitemallAftersale> selectByExampleSelective(@Param("example") Lit...
method selectByExample (line 79) | List<LitemallAftersale> selectByExample(LitemallAftersaleExample examp...
method selectByPrimaryKeySelective (line 87) | LitemallAftersale selectByPrimaryKeySelective(@Param("id") Integer id,...
method selectByPrimaryKey (line 95) | LitemallAftersale selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallAftersale selectByPrimaryKeyWithLogicalDelete(@Param("id") Int...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallAftersale record...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallAftersale record, @Param(...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallAftersale record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallAftersale record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallAftersaleExample ...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallBrandMapper.java
type LitemallBrandMapper (line 8) | public interface LitemallBrandMapper {
method countByExample (line 15) | long countByExample(LitemallBrandExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallBrandExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallBrand record);
method insertSelective (line 47) | int insertSelective(LitemallBrand record);
method selectOneByExample (line 55) | LitemallBrand selectOneByExample(LitemallBrandExample example);
method selectOneByExampleSelective (line 63) | LitemallBrand selectOneByExampleSelective(@Param("example") LitemallBr...
method selectByExampleSelective (line 71) | List<LitemallBrand> selectByExampleSelective(@Param("example") Litemal...
method selectByExample (line 79) | List<LitemallBrand> selectByExample(LitemallBrandExample example);
method selectByPrimaryKeySelective (line 87) | LitemallBrand selectByPrimaryKeySelective(@Param("id") Integer id, @Pa...
method selectByPrimaryKey (line 95) | LitemallBrand selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallBrand selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallBrand record, @P...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallBrand record, @Param("exa...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallBrand record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallBrand record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallBrandExample exam...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallCartMapper.java
type LitemallCartMapper (line 8) | public interface LitemallCartMapper {
method countByExample (line 15) | long countByExample(LitemallCartExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallCartExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallCart record);
method insertSelective (line 47) | int insertSelective(LitemallCart record);
method selectOneByExample (line 55) | LitemallCart selectOneByExample(LitemallCartExample example);
method selectOneByExampleSelective (line 63) | LitemallCart selectOneByExampleSelective(@Param("example") LitemallCar...
method selectByExampleSelective (line 71) | List<LitemallCart> selectByExampleSelective(@Param("example") Litemall...
method selectByExample (line 79) | List<LitemallCart> selectByExample(LitemallCartExample example);
method selectByPrimaryKeySelective (line 87) | LitemallCart selectByPrimaryKeySelective(@Param("id") Integer id, @Par...
method selectByPrimaryKey (line 95) | LitemallCart selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallCart selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallCart record, @Pa...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallCart record, @Param("exam...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallCart record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallCart record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallCartExample examp...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallCategoryMapper.java
type LitemallCategoryMapper (line 8) | public interface LitemallCategoryMapper {
method countByExample (line 15) | long countByExample(LitemallCategoryExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallCategoryExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallCategory record);
method insertSelective (line 47) | int insertSelective(LitemallCategory record);
method selectOneByExample (line 55) | LitemallCategory selectOneByExample(LitemallCategoryExample example);
method selectOneByExampleSelective (line 63) | LitemallCategory selectOneByExampleSelective(@Param("example") Litemal...
method selectByExampleSelective (line 71) | List<LitemallCategory> selectByExampleSelective(@Param("example") Lite...
method selectByExample (line 79) | List<LitemallCategory> selectByExample(LitemallCategoryExample example);
method selectByPrimaryKeySelective (line 87) | LitemallCategory selectByPrimaryKeySelective(@Param("id") Integer id, ...
method selectByPrimaryKey (line 95) | LitemallCategory selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallCategory selectByPrimaryKeyWithLogicalDelete(@Param("id") Inte...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallCategory record,...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallCategory record, @Param("...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallCategory record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallCategory record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallCategoryExample e...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallCollectMapper.java
type LitemallCollectMapper (line 8) | public interface LitemallCollectMapper {
method countByExample (line 15) | long countByExample(LitemallCollectExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallCollectExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallCollect record);
method insertSelective (line 47) | int insertSelective(LitemallCollect record);
method selectOneByExample (line 55) | LitemallCollect selectOneByExample(LitemallCollectExample example);
method selectOneByExampleSelective (line 63) | LitemallCollect selectOneByExampleSelective(@Param("example") Litemall...
method selectByExampleSelective (line 71) | List<LitemallCollect> selectByExampleSelective(@Param("example") Litem...
method selectByExample (line 79) | List<LitemallCollect> selectByExample(LitemallCollectExample example);
method selectByPrimaryKeySelective (line 87) | LitemallCollect selectByPrimaryKeySelective(@Param("id") Integer id, @...
method selectByPrimaryKey (line 95) | LitemallCollect selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallCollect selectByPrimaryKeyWithLogicalDelete(@Param("id") Integ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallCollect record, ...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallCollect record, @Param("e...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallCollect record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallCollect record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallCollectExample ex...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallCommentMapper.java
type LitemallCommentMapper (line 8) | public interface LitemallCommentMapper {
method countByExample (line 15) | long countByExample(LitemallCommentExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallCommentExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallComment record);
method insertSelective (line 47) | int insertSelective(LitemallComment record);
method selectOneByExample (line 55) | LitemallComment selectOneByExample(LitemallCommentExample example);
method selectOneByExampleSelective (line 63) | LitemallComment selectOneByExampleSelective(@Param("example") Litemall...
method selectByExampleSelective (line 71) | List<LitemallComment> selectByExampleSelective(@Param("example") Litem...
method selectByExample (line 79) | List<LitemallComment> selectByExample(LitemallCommentExample example);
method selectByPrimaryKeySelective (line 87) | LitemallComment selectByPrimaryKeySelective(@Param("id") Integer id, @...
method selectByPrimaryKey (line 95) | LitemallComment selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallComment selectByPrimaryKeyWithLogicalDelete(@Param("id") Integ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallComment record, ...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallComment record, @Param("e...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallComment record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallComment record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallCommentExample ex...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallCouponMapper.java
type LitemallCouponMapper (line 8) | public interface LitemallCouponMapper {
method countByExample (line 15) | long countByExample(LitemallCouponExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallCouponExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallCoupon record);
method insertSelective (line 47) | int insertSelective(LitemallCoupon record);
method selectOneByExample (line 55) | LitemallCoupon selectOneByExample(LitemallCouponExample example);
method selectOneByExampleSelective (line 63) | LitemallCoupon selectOneByExampleSelective(@Param("example") LitemallC...
method selectByExampleSelective (line 71) | List<LitemallCoupon> selectByExampleSelective(@Param("example") Litema...
method selectByExample (line 79) | List<LitemallCoupon> selectByExample(LitemallCouponExample example);
method selectByPrimaryKeySelective (line 87) | LitemallCoupon selectByPrimaryKeySelective(@Param("id") Integer id, @P...
method selectByPrimaryKey (line 95) | LitemallCoupon selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallCoupon selectByPrimaryKeyWithLogicalDelete(@Param("id") Intege...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallCoupon record, @...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallCoupon record, @Param("ex...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallCoupon record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallCoupon record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallCouponExample exa...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallCouponUserMapper.java
type LitemallCouponUserMapper (line 8) | public interface LitemallCouponUserMapper {
method countByExample (line 15) | long countByExample(LitemallCouponUserExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallCouponUserExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallCouponUser record);
method insertSelective (line 47) | int insertSelective(LitemallCouponUser record);
method selectOneByExample (line 55) | LitemallCouponUser selectOneByExample(LitemallCouponUserExample example);
method selectOneByExampleSelective (line 63) | LitemallCouponUser selectOneByExampleSelective(@Param("example") Litem...
method selectByExampleSelective (line 71) | List<LitemallCouponUser> selectByExampleSelective(@Param("example") Li...
method selectByExample (line 79) | List<LitemallCouponUser> selectByExample(LitemallCouponUserExample exa...
method selectByPrimaryKeySelective (line 87) | LitemallCouponUser selectByPrimaryKeySelective(@Param("id") Integer id...
method selectByPrimaryKey (line 95) | LitemallCouponUser selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallCouponUser selectByPrimaryKeyWithLogicalDelete(@Param("id") In...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallCouponUser recor...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallCouponUser record, @Param...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallCouponUser record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallCouponUser record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallCouponUserExample...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallFeedbackMapper.java
type LitemallFeedbackMapper (line 8) | public interface LitemallFeedbackMapper {
method countByExample (line 15) | long countByExample(LitemallFeedbackExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallFeedbackExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallFeedback record);
method insertSelective (line 47) | int insertSelective(LitemallFeedback record);
method selectOneByExample (line 55) | LitemallFeedback selectOneByExample(LitemallFeedbackExample example);
method selectOneByExampleSelective (line 63) | LitemallFeedback selectOneByExampleSelective(@Param("example") Litemal...
method selectByExampleSelective (line 71) | List<LitemallFeedback> selectByExampleSelective(@Param("example") Lite...
method selectByExample (line 79) | List<LitemallFeedback> selectByExample(LitemallFeedbackExample example);
method selectByPrimaryKeySelective (line 87) | LitemallFeedback selectByPrimaryKeySelective(@Param("id") Integer id, ...
method selectByPrimaryKey (line 95) | LitemallFeedback selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallFeedback selectByPrimaryKeyWithLogicalDelete(@Param("id") Inte...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallFeedback record,...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallFeedback record, @Param("...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallFeedback record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallFeedback record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallFeedbackExample e...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallFootprintMapper.java
type LitemallFootprintMapper (line 8) | public interface LitemallFootprintMapper {
method countByExample (line 15) | long countByExample(LitemallFootprintExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallFootprintExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallFootprint record);
method insertSelective (line 47) | int insertSelective(LitemallFootprint record);
method selectOneByExample (line 55) | LitemallFootprint selectOneByExample(LitemallFootprintExample example);
method selectOneByExampleSelective (line 63) | LitemallFootprint selectOneByExampleSelective(@Param("example") Litema...
method selectByExampleSelective (line 71) | List<LitemallFootprint> selectByExampleSelective(@Param("example") Lit...
method selectByExample (line 79) | List<LitemallFootprint> selectByExample(LitemallFootprintExample examp...
method selectByPrimaryKeySelective (line 87) | LitemallFootprint selectByPrimaryKeySelective(@Param("id") Integer id,...
method selectByPrimaryKey (line 95) | LitemallFootprint selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallFootprint selectByPrimaryKeyWithLogicalDelete(@Param("id") Int...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallFootprint record...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallFootprint record, @Param(...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallFootprint record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallFootprint record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallFootprintExample ...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallGoodsAttributeMapper.java
type LitemallGoodsAttributeMapper (line 8) | public interface LitemallGoodsAttributeMapper {
method countByExample (line 15) | long countByExample(LitemallGoodsAttributeExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallGoodsAttributeExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallGoodsAttribute record);
method insertSelective (line 47) | int insertSelective(LitemallGoodsAttribute record);
method selectOneByExample (line 55) | LitemallGoodsAttribute selectOneByExample(LitemallGoodsAttributeExampl...
method selectOneByExampleSelective (line 63) | LitemallGoodsAttribute selectOneByExampleSelective(@Param("example") L...
method selectByExampleSelective (line 71) | List<LitemallGoodsAttribute> selectByExampleSelective(@Param("example"...
method selectByExample (line 79) | List<LitemallGoodsAttribute> selectByExample(LitemallGoodsAttributeExa...
method selectByPrimaryKeySelective (line 87) | LitemallGoodsAttribute selectByPrimaryKeySelective(@Param("id") Intege...
method selectByPrimaryKey (line 95) | LitemallGoodsAttribute selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallGoodsAttribute selectByPrimaryKeyWithLogicalDelete(@Param("id"...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallGoodsAttribute r...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallGoodsAttribute record, @P...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallGoodsAttribute record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallGoodsAttribute record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallGoodsAttributeExa...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallGoodsMapper.java
type LitemallGoodsMapper (line 8) | public interface LitemallGoodsMapper {
method countByExample (line 15) | long countByExample(LitemallGoodsExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallGoodsExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallGoods record);
method insertSelective (line 47) | int insertSelective(LitemallGoods record);
method selectOneByExample (line 55) | LitemallGoods selectOneByExample(LitemallGoodsExample example);
method selectOneByExampleSelective (line 63) | LitemallGoods selectOneByExampleSelective(@Param("example") LitemallGo...
method selectOneByExampleWithBLOBs (line 71) | LitemallGoods selectOneByExampleWithBLOBs(LitemallGoodsExample example);
method selectByExampleSelective (line 79) | List<LitemallGoods> selectByExampleSelective(@Param("example") Litemal...
method selectByExampleWithBLOBs (line 87) | List<LitemallGoods> selectByExampleWithBLOBs(LitemallGoodsExample exam...
method selectByExample (line 95) | List<LitemallGoods> selectByExample(LitemallGoodsExample example);
method selectByPrimaryKeySelective (line 103) | LitemallGoods selectByPrimaryKeySelective(@Param("id") Integer id, @Pa...
method selectByPrimaryKey (line 111) | LitemallGoods selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 119) | LitemallGoods selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer...
method updateByExampleSelective (line 127) | int updateByExampleSelective(@Param("record") LitemallGoods record, @P...
method updateByExampleWithBLOBs (line 135) | int updateByExampleWithBLOBs(@Param("record") LitemallGoods record, @P...
method updateByExample (line 143) | int updateByExample(@Param("record") LitemallGoods record, @Param("exa...
method updateByPrimaryKeySelective (line 151) | int updateByPrimaryKeySelective(LitemallGoods record);
method updateByPrimaryKeyWithBLOBs (line 159) | int updateByPrimaryKeyWithBLOBs(LitemallGoods record);
method updateByPrimaryKey (line 167) | int updateByPrimaryKey(LitemallGoods record);
method logicalDeleteByExample (line 175) | int logicalDeleteByExample(@Param("example") LitemallGoodsExample exam...
method logicalDeleteByPrimaryKey (line 183) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallGoodsProductMapper.java
type LitemallGoodsProductMapper (line 8) | public interface LitemallGoodsProductMapper {
method countByExample (line 15) | long countByExample(LitemallGoodsProductExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallGoodsProductExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallGoodsProduct record);
method insertSelective (line 47) | int insertSelective(LitemallGoodsProduct record);
method selectOneByExample (line 55) | LitemallGoodsProduct selectOneByExample(LitemallGoodsProductExample ex...
method selectOneByExampleSelective (line 63) | LitemallGoodsProduct selectOneByExampleSelective(@Param("example") Lit...
method selectByExampleSelective (line 71) | List<LitemallGoodsProduct> selectByExampleSelective(@Param("example") ...
method selectByExample (line 79) | List<LitemallGoodsProduct> selectByExample(LitemallGoodsProductExample...
method selectByPrimaryKeySelective (line 87) | LitemallGoodsProduct selectByPrimaryKeySelective(@Param("id") Integer ...
method selectByPrimaryKey (line 95) | LitemallGoodsProduct selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallGoodsProduct selectByPrimaryKeyWithLogicalDelete(@Param("id") ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallGoodsProduct rec...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallGoodsProduct record, @Par...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallGoodsProduct record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallGoodsProduct record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallGoodsProductExamp...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallGoodsSpecificationMapper.java
type LitemallGoodsSpecificationMapper (line 8) | public interface LitemallGoodsSpecificationMapper {
method countByExample (line 15) | long countByExample(LitemallGoodsSpecificationExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallGoodsSpecificationExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallGoodsSpecification record);
method insertSelective (line 47) | int insertSelective(LitemallGoodsSpecification record);
method selectOneByExample (line 55) | LitemallGoodsSpecification selectOneByExample(LitemallGoodsSpecificati...
method selectOneByExampleSelective (line 63) | LitemallGoodsSpecification selectOneByExampleSelective(@Param("example...
method selectByExampleSelective (line 71) | List<LitemallGoodsSpecification> selectByExampleSelective(@Param("exam...
method selectByExample (line 79) | List<LitemallGoodsSpecification> selectByExample(LitemallGoodsSpecific...
method selectByPrimaryKeySelective (line 87) | LitemallGoodsSpecification selectByPrimaryKeySelective(@Param("id") In...
method selectByPrimaryKey (line 95) | LitemallGoodsSpecification selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallGoodsSpecification selectByPrimaryKeyWithLogicalDelete(@Param(...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallGoodsSpecificati...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallGoodsSpecification record...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallGoodsSpecification record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallGoodsSpecification record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallGoodsSpecificatio...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallGrouponMapper.java
type LitemallGrouponMapper (line 8) | public interface LitemallGrouponMapper {
method countByExample (line 15) | long countByExample(LitemallGrouponExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallGrouponExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallGroupon record);
method insertSelective (line 47) | int insertSelective(LitemallGroupon record);
method selectOneByExample (line 55) | LitemallGroupon selectOneByExample(LitemallGrouponExample example);
method selectOneByExampleSelective (line 63) | LitemallGroupon selectOneByExampleSelective(@Param("example") Litemall...
method selectByExampleSelective (line 71) | List<LitemallGroupon> selectByExampleSelective(@Param("example") Litem...
method selectByExample (line 79) | List<LitemallGroupon> selectByExample(LitemallGrouponExample example);
method selectByPrimaryKeySelective (line 87) | LitemallGroupon selectByPrimaryKeySelective(@Param("id") Integer id, @...
method selectByPrimaryKey (line 95) | LitemallGroupon selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallGroupon selectByPrimaryKeyWithLogicalDelete(@Param("id") Integ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallGroupon record, ...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallGroupon record, @Param("e...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallGroupon record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallGroupon record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallGrouponExample ex...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallGrouponRulesMapper.java
type LitemallGrouponRulesMapper (line 8) | public interface LitemallGrouponRulesMapper {
method countByExample (line 15) | long countByExample(LitemallGrouponRulesExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallGrouponRulesExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallGrouponRules record);
method insertSelective (line 47) | int insertSelective(LitemallGrouponRules record);
method selectOneByExample (line 55) | LitemallGrouponRules selectOneByExample(LitemallGrouponRulesExample ex...
method selectOneByExampleSelective (line 63) | LitemallGrouponRules selectOneByExampleSelective(@Param("example") Lit...
method selectByExampleSelective (line 71) | List<LitemallGrouponRules> selectByExampleSelective(@Param("example") ...
method selectByExample (line 79) | List<LitemallGrouponRules> selectByExample(LitemallGrouponRulesExample...
method selectByPrimaryKeySelective (line 87) | LitemallGrouponRules selectByPrimaryKeySelective(@Param("id") Integer ...
method selectByPrimaryKey (line 95) | LitemallGrouponRules selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallGrouponRules selectByPrimaryKeyWithLogicalDelete(@Param("id") ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallGrouponRules rec...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallGrouponRules record, @Par...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallGrouponRules record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallGrouponRules record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallGrouponRulesExamp...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallIssueMapper.java
type LitemallIssueMapper (line 8) | public interface LitemallIssueMapper {
method countByExample (line 15) | long countByExample(LitemallIssueExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallIssueExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallIssue record);
method insertSelective (line 47) | int insertSelective(LitemallIssue record);
method selectOneByExample (line 55) | LitemallIssue selectOneByExample(LitemallIssueExample example);
method selectOneByExampleSelective (line 63) | LitemallIssue selectOneByExampleSelective(@Param("example") LitemallIs...
method selectByExampleSelective (line 71) | List<LitemallIssue> selectByExampleSelective(@Param("example") Litemal...
method selectByExample (line 79) | List<LitemallIssue> selectByExample(LitemallIssueExample example);
method selectByPrimaryKeySelective (line 87) | LitemallIssue selectByPrimaryKeySelective(@Param("id") Integer id, @Pa...
method selectByPrimaryKey (line 95) | LitemallIssue selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallIssue selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallIssue record, @P...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallIssue record, @Param("exa...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallIssue record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallIssue record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallIssueExample exam...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallKeywordMapper.java
type LitemallKeywordMapper (line 8) | public interface LitemallKeywordMapper {
method countByExample (line 15) | long countByExample(LitemallKeywordExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallKeywordExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallKeyword record);
method insertSelective (line 47) | int insertSelective(LitemallKeyword record);
method selectOneByExample (line 55) | LitemallKeyword selectOneByExample(LitemallKeywordExample example);
method selectOneByExampleSelective (line 63) | LitemallKeyword selectOneByExampleSelective(@Param("example") Litemall...
method selectByExampleSelective (line 71) | List<LitemallKeyword> selectByExampleSelective(@Param("example") Litem...
method selectByExample (line 79) | List<LitemallKeyword> selectByExample(LitemallKeywordExample example);
method selectByPrimaryKeySelective (line 87) | LitemallKeyword selectByPrimaryKeySelective(@Param("id") Integer id, @...
method selectByPrimaryKey (line 95) | LitemallKeyword selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallKeyword selectByPrimaryKeyWithLogicalDelete(@Param("id") Integ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallKeyword record, ...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallKeyword record, @Param("e...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallKeyword record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallKeyword record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallKeywordExample ex...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallLogMapper.java
type LitemallLogMapper (line 8) | public interface LitemallLogMapper {
method countByExample (line 15) | long countByExample(LitemallLogExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallLogExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallLog record);
method insertSelective (line 47) | int insertSelective(LitemallLog record);
method selectOneByExample (line 55) | LitemallLog selectOneByExample(LitemallLogExample example);
method selectOneByExampleSelective (line 63) | LitemallLog selectOneByExampleSelective(@Param("example") LitemallLogE...
method selectByExampleSelective (line 71) | List<LitemallLog> selectByExampleSelective(@Param("example") LitemallL...
method selectByExample (line 79) | List<LitemallLog> selectByExample(LitemallLogExample example);
method selectByPrimaryKeySelective (line 87) | LitemallLog selectByPrimaryKeySelective(@Param("id") Integer id, @Para...
method selectByPrimaryKey (line 95) | LitemallLog selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallLog selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer i...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallLog record, @Par...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallLog record, @Param("examp...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallLog record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallLog record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallLogExample example);
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallNoticeAdminMapper.java
type LitemallNoticeAdminMapper (line 8) | public interface LitemallNoticeAdminMapper {
method countByExample (line 15) | long countByExample(LitemallNoticeAdminExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallNoticeAdminExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallNoticeAdmin record);
method insertSelective (line 47) | int insertSelective(LitemallNoticeAdmin record);
method selectOneByExample (line 55) | LitemallNoticeAdmin selectOneByExample(LitemallNoticeAdminExample exam...
method selectOneByExampleSelective (line 63) | LitemallNoticeAdmin selectOneByExampleSelective(@Param("example") Lite...
method selectByExampleSelective (line 71) | List<LitemallNoticeAdmin> selectByExampleSelective(@Param("example") L...
method selectByExample (line 79) | List<LitemallNoticeAdmin> selectByExample(LitemallNoticeAdminExample e...
method selectByPrimaryKeySelective (line 87) | LitemallNoticeAdmin selectByPrimaryKeySelective(@Param("id") Integer i...
method selectByPrimaryKey (line 95) | LitemallNoticeAdmin selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallNoticeAdmin selectByPrimaryKeyWithLogicalDelete(@Param("id") I...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallNoticeAdmin reco...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallNoticeAdmin record, @Para...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallNoticeAdmin record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallNoticeAdmin record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallNoticeAdminExampl...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallNoticeMapper.java
type LitemallNoticeMapper (line 8) | public interface LitemallNoticeMapper {
method countByExample (line 15) | long countByExample(LitemallNoticeExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallNoticeExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallNotice record);
method insertSelective (line 47) | int insertSelective(LitemallNotice record);
method selectOneByExample (line 55) | LitemallNotice selectOneByExample(LitemallNoticeExample example);
method selectOneByExampleSelective (line 63) | LitemallNotice selectOneByExampleSelective(@Param("example") LitemallN...
method selectByExampleSelective (line 71) | List<LitemallNotice> selectByExampleSelective(@Param("example") Litema...
method selectByExample (line 79) | List<LitemallNotice> selectByExample(LitemallNoticeExample example);
method selectByPrimaryKeySelective (line 87) | LitemallNotice selectByPrimaryKeySelective(@Param("id") Integer id, @P...
method selectByPrimaryKey (line 95) | LitemallNotice selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallNotice selectByPrimaryKeyWithLogicalDelete(@Param("id") Intege...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallNotice record, @...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallNotice record, @Param("ex...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallNotice record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallNotice record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallNoticeExample exa...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallOrderGoodsMapper.java
type LitemallOrderGoodsMapper (line 8) | public interface LitemallOrderGoodsMapper {
method countByExample (line 15) | long countByExample(LitemallOrderGoodsExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallOrderGoodsExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallOrderGoods record);
method insertSelective (line 47) | int insertSelective(LitemallOrderGoods record);
method selectOneByExample (line 55) | LitemallOrderGoods selectOneByExample(LitemallOrderGoodsExample example);
method selectOneByExampleSelective (line 63) | LitemallOrderGoods selectOneByExampleSelective(@Param("example") Litem...
method selectByExampleSelective (line 71) | List<LitemallOrderGoods> selectByExampleSelective(@Param("example") Li...
method selectByExample (line 79) | List<LitemallOrderGoods> selectByExample(LitemallOrderGoodsExample exa...
method selectByPrimaryKeySelective (line 87) | LitemallOrderGoods selectByPrimaryKeySelective(@Param("id") Integer id...
method selectByPrimaryKey (line 95) | LitemallOrderGoods selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallOrderGoods selectByPrimaryKeyWithLogicalDelete(@Param("id") In...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallOrderGoods recor...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallOrderGoods record, @Param...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallOrderGoods record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallOrderGoods record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallOrderGoodsExample...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallOrderMapper.java
type LitemallOrderMapper (line 8) | public interface LitemallOrderMapper {
method countByExample (line 15) | long countByExample(LitemallOrderExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallOrderExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallOrder record);
method insertSelective (line 47) | int insertSelective(LitemallOrder record);
method selectOneByExample (line 55) | LitemallOrder selectOneByExample(LitemallOrderExample example);
method selectOneByExampleSelective (line 63) | LitemallOrder selectOneByExampleSelective(@Param("example") LitemallOr...
method selectByExampleSelective (line 71) | List<LitemallOrder> selectByExampleSelective(@Param("example") Litemal...
method selectByExample (line 79) | List<LitemallOrder> selectByExample(LitemallOrderExample example);
method selectByPrimaryKeySelective (line 87) | LitemallOrder selectByPrimaryKeySelective(@Param("id") Integer id, @Pa...
method selectByPrimaryKey (line 95) | LitemallOrder selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallOrder selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallOrder record, @P...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallOrder record, @Param("exa...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallOrder record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallOrder record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallOrderExample exam...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallPermissionMapper.java
type LitemallPermissionMapper (line 8) | public interface LitemallPermissionMapper {
method countByExample (line 15) | long countByExample(LitemallPermissionExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallPermissionExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallPermission record);
method insertSelective (line 47) | int insertSelective(LitemallPermission record);
method selectOneByExample (line 55) | LitemallPermission selectOneByExample(LitemallPermissionExample example);
method selectOneByExampleSelective (line 63) | LitemallPermission selectOneByExampleSelective(@Param("example") Litem...
method selectByExampleSelective (line 71) | List<LitemallPermission> selectByExampleSelective(@Param("example") Li...
method selectByExample (line 79) | List<LitemallPermission> selectByExample(LitemallPermissionExample exa...
method selectByPrimaryKeySelective (line 87) | LitemallPermission selectByPrimaryKeySelective(@Param("id") Integer id...
method selectByPrimaryKey (line 95) | LitemallPermission selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallPermission selectByPrimaryKeyWithLogicalDelete(@Param("id") In...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallPermission recor...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallPermission record, @Param...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallPermission record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallPermission record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallPermissionExample...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallRegionMapper.java
type LitemallRegionMapper (line 8) | public interface LitemallRegionMapper {
method countByExample (line 15) | long countByExample(LitemallRegionExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallRegionExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallRegion record);
method insertSelective (line 47) | int insertSelective(LitemallRegion record);
method selectOneByExample (line 55) | LitemallRegion selectOneByExample(LitemallRegionExample example);
method selectOneByExampleSelective (line 63) | LitemallRegion selectOneByExampleSelective(@Param("example") LitemallR...
method selectByExampleSelective (line 71) | List<LitemallRegion> selectByExampleSelective(@Param("example") Litema...
method selectByExample (line 79) | List<LitemallRegion> selectByExample(LitemallRegionExample example);
method selectByPrimaryKeySelective (line 87) | LitemallRegion selectByPrimaryKeySelective(@Param("id") Integer id, @P...
method selectByPrimaryKey (line 95) | LitemallRegion selectByPrimaryKey(Integer id);
method updateByExampleSelective (line 103) | int updateByExampleSelective(@Param("record") LitemallRegion record, @...
method updateByExample (line 111) | int updateByExample(@Param("record") LitemallRegion record, @Param("ex...
method updateByPrimaryKeySelective (line 119) | int updateByPrimaryKeySelective(LitemallRegion record);
method updateByPrimaryKey (line 127) | int updateByPrimaryKey(LitemallRegion record);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallRoleMapper.java
type LitemallRoleMapper (line 8) | public interface LitemallRoleMapper {
method countByExample (line 15) | long countByExample(LitemallRoleExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallRoleExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallRole record);
method insertSelective (line 47) | int insertSelective(LitemallRole record);
method selectOneByExample (line 55) | LitemallRole selectOneByExample(LitemallRoleExample example);
method selectOneByExampleSelective (line 63) | LitemallRole selectOneByExampleSelective(@Param("example") LitemallRol...
method selectByExampleSelective (line 71) | List<LitemallRole> selectByExampleSelective(@Param("example") Litemall...
method selectByExample (line 79) | List<LitemallRole> selectByExample(LitemallRoleExample example);
method selectByPrimaryKeySelective (line 87) | LitemallRole selectByPrimaryKeySelective(@Param("id") Integer id, @Par...
method selectByPrimaryKey (line 95) | LitemallRole selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallRole selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallRole record, @Pa...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallRole record, @Param("exam...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallRole record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallRole record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallRoleExample examp...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallSearchHistoryMapper.java
type LitemallSearchHistoryMapper (line 8) | public interface LitemallSearchHistoryMapper {
method countByExample (line 15) | long countByExample(LitemallSearchHistoryExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallSearchHistoryExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallSearchHistory record);
method insertSelective (line 47) | int insertSelective(LitemallSearchHistory record);
method selectOneByExample (line 55) | LitemallSearchHistory selectOneByExample(LitemallSearchHistoryExample ...
method selectOneByExampleSelective (line 63) | LitemallSearchHistory selectOneByExampleSelective(@Param("example") Li...
method selectByExampleSelective (line 71) | List<LitemallSearchHistory> selectByExampleSelective(@Param("example")...
method selectByExample (line 79) | List<LitemallSearchHistory> selectByExample(LitemallSearchHistoryExamp...
method selectByPrimaryKeySelective (line 87) | LitemallSearchHistory selectByPrimaryKeySelective(@Param("id") Integer...
method selectByPrimaryKey (line 95) | LitemallSearchHistory selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallSearchHistory selectByPrimaryKeyWithLogicalDelete(@Param("id")...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallSearchHistory re...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallSearchHistory record, @Pa...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallSearchHistory record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallSearchHistory record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallSearchHistoryExam...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallStorageMapper.java
type LitemallStorageMapper (line 8) | public interface LitemallStorageMapper {
method countByExample (line 15) | long countByExample(LitemallStorageExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallStorageExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallStorage record);
method insertSelective (line 47) | int insertSelective(LitemallStorage record);
method selectOneByExample (line 55) | LitemallStorage selectOneByExample(LitemallStorageExample example);
method selectOneByExampleSelective (line 63) | LitemallStorage selectOneByExampleSelective(@Param("example") Litemall...
method selectByExampleSelective (line 71) | List<LitemallStorage> selectByExampleSelective(@Param("example") Litem...
method selectByExample (line 79) | List<LitemallStorage> selectByExample(LitemallStorageExample example);
method selectByPrimaryKeySelective (line 87) | LitemallStorage selectByPrimaryKeySelective(@Param("id") Integer id, @...
method selectByPrimaryKey (line 95) | LitemallStorage selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallStorage selectByPrimaryKeyWithLogicalDelete(@Param("id") Integ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallStorage record, ...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallStorage record, @Param("e...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallStorage record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallStorage record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallStorageExample ex...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallSystemMapper.java
type LitemallSystemMapper (line 8) | public interface LitemallSystemMapper {
method countByExample (line 15) | long countByExample(LitemallSystemExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallSystemExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallSystem record);
method insertSelective (line 47) | int insertSelective(LitemallSystem record);
method selectOneByExample (line 55) | LitemallSystem selectOneByExample(LitemallSystemExample example);
method selectOneByExampleSelective (line 63) | LitemallSystem selectOneByExampleSelective(@Param("example") LitemallS...
method selectByExampleSelective (line 71) | List<LitemallSystem> selectByExampleSelective(@Param("example") Litema...
method selectByExample (line 79) | List<LitemallSystem> selectByExample(LitemallSystemExample example);
method selectByPrimaryKeySelective (line 87) | LitemallSystem selectByPrimaryKeySelective(@Param("id") Integer id, @P...
method selectByPrimaryKey (line 95) | LitemallSystem selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallSystem selectByPrimaryKeyWithLogicalDelete(@Param("id") Intege...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallSystem record, @...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallSystem record, @Param("ex...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallSystem record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallSystem record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallSystemExample exa...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallTopicMapper.java
type LitemallTopicMapper (line 8) | public interface LitemallTopicMapper {
method countByExample (line 15) | long countByExample(LitemallTopicExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallTopicExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallTopic record);
method insertSelective (line 47) | int insertSelective(LitemallTopic record);
method selectOneByExample (line 55) | LitemallTopic selectOneByExample(LitemallTopicExample example);
method selectOneByExampleSelective (line 63) | LitemallTopic selectOneByExampleSelective(@Param("example") LitemallTo...
method selectOneByExampleWithBLOBs (line 71) | LitemallTopic selectOneByExampleWithBLOBs(LitemallTopicExample example);
method selectByExampleSelective (line 79) | List<LitemallTopic> selectByExampleSelective(@Param("example") Litemal...
method selectByExampleWithBLOBs (line 87) | List<LitemallTopic> selectByExampleWithBLOBs(LitemallTopicExample exam...
method selectByExample (line 95) | List<LitemallTopic> selectByExample(LitemallTopicExample example);
method selectByPrimaryKeySelective (line 103) | LitemallTopic selectByPrimaryKeySelective(@Param("id") Integer id, @Pa...
method selectByPrimaryKey (line 111) | LitemallTopic selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 119) | LitemallTopic selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer...
method updateByExampleSelective (line 127) | int updateByExampleSelective(@Param("record") LitemallTopic record, @P...
method updateByExampleWithBLOBs (line 135) | int updateByExampleWithBLOBs(@Param("record") LitemallTopic record, @P...
method updateByExample (line 143) | int updateByExample(@Param("record") LitemallTopic record, @Param("exa...
method updateByPrimaryKeySelective (line 151) | int updateByPrimaryKeySelective(LitemallTopic record);
method updateByPrimaryKeyWithBLOBs (line 159) | int updateByPrimaryKeyWithBLOBs(LitemallTopic record);
method updateByPrimaryKey (line 167) | int updateByPrimaryKey(LitemallTopic record);
method logicalDeleteByExample (line 175) | int logicalDeleteByExample(@Param("example") LitemallTopicExample exam...
method logicalDeleteByPrimaryKey (line 183) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/LitemallUserMapper.java
type LitemallUserMapper (line 8) | public interface LitemallUserMapper {
method countByExample (line 15) | long countByExample(LitemallUserExample example);
method deleteByExample (line 23) | int deleteByExample(LitemallUserExample example);
method deleteByPrimaryKey (line 31) | int deleteByPrimaryKey(Integer id);
method insert (line 39) | int insert(LitemallUser record);
method insertSelective (line 47) | int insertSelective(LitemallUser record);
method selectOneByExample (line 55) | LitemallUser selectOneByExample(LitemallUserExample example);
method selectOneByExampleSelective (line 63) | LitemallUser selectOneByExampleSelective(@Param("example") LitemallUse...
method selectByExampleSelective (line 71) | List<LitemallUser> selectByExampleSelective(@Param("example") Litemall...
method selectByExample (line 79) | List<LitemallUser> selectByExample(LitemallUserExample example);
method selectByPrimaryKeySelective (line 87) | LitemallUser selectByPrimaryKeySelective(@Param("id") Integer id, @Par...
method selectByPrimaryKey (line 95) | LitemallUser selectByPrimaryKey(Integer id);
method selectByPrimaryKeyWithLogicalDelete (line 103) | LitemallUser selectByPrimaryKeyWithLogicalDelete(@Param("id") Integer ...
method updateByExampleSelective (line 111) | int updateByExampleSelective(@Param("record") LitemallUser record, @Pa...
method updateByExample (line 119) | int updateByExample(@Param("record") LitemallUser record, @Param("exam...
method updateByPrimaryKeySelective (line 127) | int updateByPrimaryKeySelective(LitemallUser record);
method updateByPrimaryKey (line 135) | int updateByPrimaryKey(LitemallUser record);
method logicalDeleteByExample (line 143) | int logicalDeleteByExample(@Param("example") LitemallUserExample examp...
method logicalDeleteByPrimaryKey (line 151) | int logicalDeleteByPrimaryKey(Integer id);
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/OrderMapper.java
type OrderMapper (line 11) | public interface OrderMapper {
method updateWithOptimisticLocker (line 12) | int updateWithOptimisticLocker(@Param("lastUpdateTime") LocalDateTime ...
method getOrderIds (line 13) | List<Map> getOrderIds(@Param("query") String query, @Param("orderByCla...
method getOrderList (line 14) | List<OrderVo> getOrderList(@Param("query") String query, @Param("order...
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/dao/StatMapper.java
type StatMapper (line 6) | public interface StatMapper {
method statUser (line 7) | List<Map> statUser();
method statOrder (line 9) | List<Map> statOrder();
method statGoods (line 11) | List<Map> statGoods();
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallAd.java
class LitemallAd (line 7) | public class LitemallAd {
method getId (line 140) | public Integer getId() {
method setId (line 152) | public void setId(Integer id) {
method getName (line 164) | public String getName() {
method setName (line 176) | public void setName(String name) {
method getLink (line 188) | public String getLink() {
method setLink (line 200) | public void setLink(String link) {
method getUrl (line 212) | public String getUrl() {
method setUrl (line 224) | public void setUrl(String url) {
method getPosition (line 236) | public Byte getPosition() {
method setPosition (line 248) | public void setPosition(Byte position) {
method getContent (line 260) | public String getContent() {
method setContent (line 272) | public void setContent(String content) {
method getStartTime (line 284) | public LocalDateTime getStartTime() {
method setStartTime (line 296) | public void setStartTime(LocalDateTime startTime) {
method getEndTime (line 308) | public LocalDateTime getEndTime() {
method setEndTime (line 320) | public void setEndTime(LocalDateTime endTime) {
method getEnabled (line 332) | public Boolean getEnabled() {
method setEnabled (line 344) | public void setEnabled(Boolean enabled) {
method getAddTime (line 356) | public LocalDateTime getAddTime() {
method setAddTime (line 368) | public void setAddTime(LocalDateTime addTime) {
method getUpdateTime (line 380) | public LocalDateTime getUpdateTime() {
method setUpdateTime (line 392) | public void setUpdateTime(LocalDateTime updateTime) {
method andLogicalDeleted (line 402) | public void andLogicalDeleted(boolean deleted) {
method getDeleted (line 414) | public Boolean getDeleted() {
method setDeleted (line 426) | public void setDeleted(Boolean deleted) {
method toString (line 436) | @Override
method equals (line 466) | @Override
method hashCode (line 498) | @Override
type Deleted (line 523) | public enum Deleted {
method Deleted (line 549) | Deleted(Boolean value, String name) {
method getValue (line 560) | public Boolean getValue() {
method value (line 570) | public Boolean value() {
method getName (line 580) | public String getName() {
type Column (line 591) | public enum Column {
method value (line 659) | public String value() {
method getValue (line 669) | public String getValue() {
method getJavaProperty (line 679) | public String getJavaProperty() {
method getJdbcType (line 689) | public String getJdbcType() {
method Column (line 699) | Column(String column, String javaProperty, String jdbcType, boolean ...
method desc (line 712) | public String desc() {
method asc (line 722) | public String asc() {
method excludes (line 732) | public static Column[] excludes(Column ... excludes) {
method getEscapedColumnName (line 746) | public String getEscapedColumnName() {
method getAliasedEscapedColumnName (line 760) | public String getAliasedEscapedColumnName() {
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallAdExample.java
class LitemallAdExample (line 7) | public class LitemallAdExample {
method LitemallAdExample (line 38) | public LitemallAdExample() {
method setOrderByClause (line 48) | public void setOrderByClause(String orderByClause) {
method getOrderByClause (line 58) | public String getOrderByClause() {
method setDistinct (line 68) | public void setDistinct(boolean distinct) {
method isDistinct (line 78) | public boolean isDistinct() {
method getOredCriteria (line 88) | public List<Criteria> getOredCriteria() {
method or (line 98) | public void or(Criteria criteria) {
method or (line 108) | public Criteria or() {
method orderBy (line 120) | public LitemallAdExample orderBy(String orderByClause) {
method orderBy (line 131) | public LitemallAdExample orderBy(String ... orderByClauses) {
method createCriteria (line 149) | public Criteria createCriteria() {
method createCriteriaInternal (line 163) | protected Criteria createCriteriaInternal() {
method clear (line 174) | public void clear() {
method newAndCreateCriteria (line 186) | public static Criteria newAndCreateCriteria() {
method when (line 197) | public LitemallAdExample when(boolean condition, IExampleWhen then) {
method when (line 210) | public LitemallAdExample when(boolean condition, IExampleWhen then, IE...
class GeneratedCriteria (line 225) | protected abstract static class GeneratedCriteria {
method GeneratedCriteria (line 228) | protected GeneratedCriteria() {
method isValid (line 233) | public boolean isValid() {
method getAllCriteria (line 237) | public List<Criterion> getAllCriteria() {
method getCriteria (line 241) | public List<Criterion> getCriteria() {
method addCriterion (line 245) | protected void addCriterion(String condition) {
method addCriterion (line 252) | protected void addCriterion(String condition, Object value, String p...
method addCriterion (line 259) | protected void addCriterion(String condition, Object value1, Object ...
method andIdIsNull (line 266) | public Criteria andIdIsNull() {
method andIdIsNotNull (line 271) | public Criteria andIdIsNotNull() {
method andIdEqualTo (line 276) | public Criteria andIdEqualTo(Integer value) {
method andIdEqualToColumn (line 287) | public Criteria andIdEqualToColumn(LitemallAd.Column column) {
method andIdNotEqualTo (line 292) | public Criteria andIdNotEqualTo(Integer value) {
method andIdNotEqualToColumn (line 303) | public Criteria andIdNotEqualToColumn(LitemallAd.Column column) {
method andIdGreaterThan (line 308) | public Criteria andIdGreaterThan(Integer value) {
method andIdGreaterThanColumn (line 319) | public Criteria andIdGreaterThanColumn(LitemallAd.Column column) {
method andIdGreaterThanOrEqualTo (line 324) | public Criteria andIdGreaterThanOrEqualTo(Integer value) {
method andIdGreaterThanOrEqualToColumn (line 335) | public Criteria andIdGreaterThanOrEqualToColumn(LitemallAd.Column co...
method andIdLessThan (line 340) | public Criteria andIdLessThan(Integer value) {
method andIdLessThanColumn (line 351) | public Criteria andIdLessThanColumn(LitemallAd.Column column) {
method andIdLessThanOrEqualTo (line 356) | public Criteria andIdLessThanOrEqualTo(Integer value) {
method andIdLessThanOrEqualToColumn (line 367) | public Criteria andIdLessThanOrEqualToColumn(LitemallAd.Column colum...
method andIdIn (line 372) | public Criteria andIdIn(List<Integer> values) {
method andIdNotIn (line 377) | public Criteria andIdNotIn(List<Integer> values) {
method andIdBetween (line 382) | public Criteria andIdBetween(Integer value1, Integer value2) {
method andIdNotBetween (line 387) | public Criteria andIdNotBetween(Integer value1, Integer value2) {
method andNameIsNull (line 392) | public Criteria andNameIsNull() {
method andNameIsNotNull (line 397) | public Criteria andNameIsNotNull() {
method andNameEqualTo (line 402) | public Criteria andNameEqualTo(String value) {
method andNameEqualToColumn (line 413) | public Criteria andNameEqualToColumn(LitemallAd.Column column) {
method andNameNotEqualTo (line 418) | public Criteria andNameNotEqualTo(String value) {
method andNameNotEqualToColumn (line 429) | public Criteria andNameNotEqualToColumn(LitemallAd.Column column) {
method andNameGreaterThan (line 434) | public Criteria andNameGreaterThan(String value) {
method andNameGreaterThanColumn (line 445) | public Criteria andNameGreaterThanColumn(LitemallAd.Column column) {
method andNameGreaterThanOrEqualTo (line 450) | public Criteria andNameGreaterThanOrEqualTo(String value) {
method andNameGreaterThanOrEqualToColumn (line 461) | public Criteria andNameGreaterThanOrEqualToColumn(LitemallAd.Column ...
method andNameLessThan (line 466) | public Criteria andNameLessThan(String value) {
method andNameLessThanColumn (line 477) | public Criteria andNameLessThanColumn(LitemallAd.Column column) {
method andNameLessThanOrEqualTo (line 482) | public Criteria andNameLessThanOrEqualTo(String value) {
method andNameLessThanOrEqualToColumn (line 493) | public Criteria andNameLessThanOrEqualToColumn(LitemallAd.Column col...
method andNameLike (line 498) | public Criteria andNameLike(String value) {
method andNameNotLike (line 503) | public Criteria andNameNotLike(String value) {
method andNameIn (line 508) | public Criteria andNameIn(List<String> values) {
method andNameNotIn (line 513) | public Criteria andNameNotIn(List<String> values) {
method andNameBetween (line 518) | public Criteria andNameBetween(String value1, String value2) {
method andNameNotBetween (line 523) | public Criteria andNameNotBetween(String value1, String value2) {
method andLinkIsNull (line 528) | public Criteria andLinkIsNull() {
method andLinkIsNotNull (line 533) | public Criteria andLinkIsNotNull() {
method andLinkEqualTo (line 538) | public Criteria andLinkEqualTo(String value) {
method andLinkEqualToColumn (line 549) | public Criteria andLinkEqualToColumn(LitemallAd.Column column) {
method andLinkNotEqualTo (line 554) | public Criteria andLinkNotEqualTo(String value) {
method andLinkNotEqualToColumn (line 565) | public Criteria andLinkNotEqualToColumn(LitemallAd.Column column) {
method andLinkGreaterThan (line 570) | public Criteria andLinkGreaterThan(String value) {
method andLinkGreaterThanColumn (line 581) | public Criteria andLinkGreaterThanColumn(LitemallAd.Column column) {
method andLinkGreaterThanOrEqualTo (line 586) | public Criteria andLinkGreaterThanOrEqualTo(String value) {
method andLinkGreaterThanOrEqualToColumn (line 597) | public Criteria andLinkGreaterThanOrEqualToColumn(LitemallAd.Column ...
method andLinkLessThan (line 602) | public Criteria andLinkLessThan(String value) {
method andLinkLessThanColumn (line 613) | public Criteria andLinkLessThanColumn(LitemallAd.Column column) {
method andLinkLessThanOrEqualTo (line 618) | public Criteria andLinkLessThanOrEqualTo(String value) {
method andLinkLessThanOrEqualToColumn (line 629) | public Criteria andLinkLessThanOrEqualToColumn(LitemallAd.Column col...
method andLinkLike (line 634) | public Criteria andLinkLike(String value) {
method andLinkNotLike (line 639) | public Criteria andLinkNotLike(String value) {
method andLinkIn (line 644) | public Criteria andLinkIn(List<String> values) {
method andLinkNotIn (line 649) | public Criteria andLinkNotIn(List<String> values) {
method andLinkBetween (line 654) | public Criteria andLinkBetween(String value1, String value2) {
method andLinkNotBetween (line 659) | public Criteria andLinkNotBetween(String value1, String value2) {
method andUrlIsNull (line 664) | public Criteria andUrlIsNull() {
method andUrlIsNotNull (line 669) | public Criteria andUrlIsNotNull() {
method andUrlEqualTo (line 674) | public Criteria andUrlEqualTo(String value) {
method andUrlEqualToColumn (line 685) | public Criteria andUrlEqualToColumn(LitemallAd.Column column) {
method andUrlNotEqualTo (line 690) | public Criteria andUrlNotEqualTo(String value) {
method andUrlNotEqualToColumn (line 701) | public Criteria andUrlNotEqualToColumn(LitemallAd.Column column) {
method andUrlGreaterThan (line 706) | public Criteria andUrlGreaterThan(String value) {
method andUrlGreaterThanColumn (line 717) | public Criteria andUrlGreaterThanColumn(LitemallAd.Column column) {
method andUrlGreaterThanOrEqualTo (line 722) | public Criteria andUrlGreaterThanOrEqualTo(String value) {
method andUrlGreaterThanOrEqualToColumn (line 733) | public Criteria andUrlGreaterThanOrEqualToColumn(LitemallAd.Column c...
method andUrlLessThan (line 738) | public Criteria andUrlLessThan(String value) {
method andUrlLessThanColumn (line 749) | public Criteria andUrlLessThanColumn(LitemallAd.Column column) {
method andUrlLessThanOrEqualTo (line 754) | public Criteria andUrlLessThanOrEqualTo(String value) {
method andUrlLessThanOrEqualToColumn (line 765) | public Criteria andUrlLessThanOrEqualToColumn(LitemallAd.Column colu...
method andUrlLike (line 770) | public Criteria andUrlLike(String value) {
method andUrlNotLike (line 775) | public Criteria andUrlNotLike(String value) {
method andUrlIn (line 780) | public Criteria andUrlIn(List<String> values) {
method andUrlNotIn (line 785) | public Criteria andUrlNotIn(List<String> values) {
method andUrlBetween (line 790) | public Criteria andUrlBetween(String value1, String value2) {
method andUrlNotBetween (line 795) | public Criteria andUrlNotBetween(String value1, String value2) {
method andPositionIsNull (line 800) | public Criteria andPositionIsNull() {
method andPositionIsNotNull (line 805) | public Criteria andPositionIsNotNull() {
method andPositionEqualTo (line 810) | public Criteria andPositionEqualTo(Byte value) {
method andPositionEqualToColumn (line 821) | public Criteria andPositionEqualToColumn(LitemallAd.Column column) {
method andPositionNotEqualTo (line 826) | public Criteria andPositionNotEqualTo(Byte value) {
method andPositionNotEqualToColumn (line 837) | public Criteria andPositionNotEqualToColumn(LitemallAd.Column column) {
method andPositionGreaterThan (line 842) | public Criteria andPositionGreaterThan(Byte value) {
method andPositionGreaterThanColumn (line 853) | public Criteria andPositionGreaterThanColumn(LitemallAd.Column colum...
method andPositionGreaterThanOrEqualTo (line 858) | public Criteria andPositionGreaterThanOrEqualTo(Byte value) {
method andPositionGreaterThanOrEqualToColumn (line 869) | public Criteria andPositionGreaterThanOrEqualToColumn(LitemallAd.Col...
method andPositionLessThan (line 874) | public Criteria andPositionLessThan(Byte value) {
method andPositionLessThanColumn (line 885) | public Criteria andPositionLessThanColumn(LitemallAd.Column column) {
method andPositionLessThanOrEqualTo (line 890) | public Criteria andPositionLessThanOrEqualTo(Byte value) {
method andPositionLessThanOrEqualToColumn (line 901) | public Criteria andPositionLessThanOrEqualToColumn(LitemallAd.Column...
method andPositionIn (line 906) | public Criteria andPositionIn(List<Byte> values) {
method andPositionNotIn (line 911) | public Criteria andPositionNotIn(List<Byte> values) {
method andPositionBetween (line 916) | public Criteria andPositionBetween(Byte value1, Byte value2) {
method andPositionNotBetween (line 921) | public Criteria andPositionNotBetween(Byte value1, Byte value2) {
method andContentIsNull (line 926) | public Criteria andContentIsNull() {
method andContentIsNotNull (line 931) | public Criteria andContentIsNotNull() {
method andContentEqualTo (line 936) | public Criteria andContentEqualTo(String value) {
method andContentEqualToColumn (line 947) | public Criteria andContentEqualToColumn(LitemallAd.Column column) {
method andContentNotEqualTo (line 952) | public Criteria andContentNotEqualTo(String value) {
method andContentNotEqualToColumn (line 963) | public Criteria andContentNotEqualToColumn(LitemallAd.Column column) {
method andContentGreaterThan (line 968) | public Criteria andContentGreaterThan(String value) {
method andContentGreaterThanColumn (line 979) | public Criteria andContentGreaterThanColumn(LitemallAd.Column column) {
method andContentGreaterThanOrEqualTo (line 984) | public Criteria andContentGreaterThanOrEqualTo(String value) {
method andContentGreaterThanOrEqualToColumn (line 995) | public Criteria andContentGreaterThanOrEqualToColumn(LitemallAd.Colu...
method andContentLessThan (line 1000) | public Criteria andContentLessThan(String value) {
method andContentLessThanColumn (line 1011) | public Criteria andContentLessThanColumn(LitemallAd.Column column) {
method andContentLessThanOrEqualTo (line 1016) | public Criteria andContentLessThanOrEqualTo(String value) {
method andContentLessThanOrEqualToColumn (line 1027) | public Criteria andContentLessThanOrEqualToColumn(LitemallAd.Column ...
method andContentLike (line 1032) | public Criteria andContentLike(String value) {
method andContentNotLike (line 1037) | public Criteria andContentNotLike(String value) {
method andContentIn (line 1042) | public Criteria andContentIn(List<String> values) {
method andContentNotIn (line 1047) | public Criteria andContentNotIn(List<String> values) {
method andContentBetween (line 1052) | public Criteria andContentBetween(String value1, String value2) {
method andContentNotBetween (line 1057) | public Criteria andContentNotBetween(String value1, String value2) {
method andStartTimeIsNull (line 1062) | public Criteria andStartTimeIsNull() {
method andStartTimeIsNotNull (line 1067) | public Criteria andStartTimeIsNotNull() {
method andStartTimeEqualTo (line 1072) | public Criteria andStartTimeEqualTo(LocalDateTime value) {
method andStartTimeEqualToColumn (line 1083) | public Criteria andStartTimeEqualToColumn(LitemallAd.Column column) {
method andStartTimeNotEqualTo (line 1088) | public Criteria andStartTimeNotEqualTo(LocalDateTime value) {
method andStartTimeNotEqualToColumn (line 1099) | public Criteria andStartTimeNotEqualToColumn(LitemallAd.Column colum...
method andStartTimeGreaterThan (line 1104) | public Criteria andStartTimeGreaterThan(LocalDateTime value) {
method andStartTimeGreaterThanColumn (line 1115) | public Criteria andStartTimeGreaterThanColumn(LitemallAd.Column colu...
method andStartTimeGreaterThanOrEqualTo (line 1120) | public Criteria andStartTimeGreaterThanOrEqualTo(LocalDateTime value) {
method andStartTimeGreaterThanOrEqualToColumn (line 1131) | public Criteria andStartTimeGreaterThanOrEqualToColumn(LitemallAd.Co...
method andStartTimeLessThan (line 1136) | public Criteria andStartTimeLessThan(LocalDateTime value) {
method andStartTimeLessThanColumn (line 1147) | public Criteria andStartTimeLessThanColumn(LitemallAd.Column column) {
method andStartTimeLessThanOrEqualTo (line 1152) | public Criteria andStartTimeLessThanOrEqualTo(LocalDateTime value) {
method andStartTimeLessThanOrEqualToColumn (line 1163) | public Criteria andStartTimeLessThanOrEqualToColumn(LitemallAd.Colum...
method andStartTimeIn (line 1168) | public Criteria andStartTimeIn(List<LocalDateTime> values) {
method andStartTimeNotIn (line 1173) | public Criteria andStartTimeNotIn(List<LocalDateTime> values) {
method andStartTimeBetween (line 1178) | public Criteria andStartTimeBetween(LocalDateTime value1, LocalDateT...
method andStartTimeNotBetween (line 1183) | public Criteria andStartTimeNotBetween(LocalDateTime value1, LocalDa...
method andEndTimeIsNull (line 1188) | public Criteria andEndTimeIsNull() {
method andEndTimeIsNotNull (line 1193) | public Criteria andEndTimeIsNotNull() {
method andEndTimeEqualTo (line 1198) | public Criteria andEndTimeEqualTo(LocalDateTime value) {
method andEndTimeEqualToColumn (line 1209) | public Criteria andEndTimeEqualToColumn(LitemallAd.Column column) {
method andEndTimeNotEqualTo (line 1214) | public Criteria andEndTimeNotEqualTo(LocalDateTime value) {
method andEndTimeNotEqualToColumn (line 1225) | public Criteria andEndTimeNotEqualToColumn(LitemallAd.Column column) {
method andEndTimeGreaterThan (line 1230) | public Criteria andEndTimeGreaterThan(LocalDateTime value) {
method andEndTimeGreaterThanColumn (line 1241) | public Criteria andEndTimeGreaterThanColumn(LitemallAd.Column column) {
method andEndTimeGreaterThanOrEqualTo (line 1246) | public Criteria andEndTimeGreaterThanOrEqualTo(LocalDateTime value) {
method andEndTimeGreaterThanOrEqualToColumn (line 1257) | public Criteria andEndTimeGreaterThanOrEqualToColumn(LitemallAd.Colu...
method andEndTimeLessThan (line 1262) | public Criteria andEndTimeLessThan(LocalDateTime value) {
method andEndTimeLessThanColumn (line 1273) | public Criteria andEndTimeLessThanColumn(LitemallAd.Column column) {
method andEndTimeLessThanOrEqualTo (line 1278) | public Criteria andEndTimeLessThanOrEqualTo(LocalDateTime value) {
method andEndTimeLessThanOrEqualToColumn (line 1289) | public Criteria andEndTimeLessThanOrEqualToColumn(LitemallAd.Column ...
method andEndTimeIn (line 1294) | public Criteria andEndTimeIn(List<LocalDateTime> values) {
method andEndTimeNotIn (line 1299) | public Criteria andEndTimeNotIn(List<LocalDateTime> values) {
method andEndTimeBetween (line 1304) | public Criteria andEndTimeBetween(LocalDateTime value1, LocalDateTim...
method andEndTimeNotBetween (line 1309) | public Criteria andEndTimeNotBetween(LocalDateTime value1, LocalDate...
method andEnabledIsNull (line 1314) | public Criteria andEnabledIsNull() {
method andEnabledIsNotNull (line 1319) | public Criteria andEnabledIsNotNull() {
method andEnabledEqualTo (line 1324) | public Criteria andEnabledEqualTo(Boolean value) {
method andEnabledEqualToColumn (line 1335) | public Criteria andEnabledEqualToColumn(LitemallAd.Column column) {
method andEnabledNotEqualTo (line 1340) | public Criteria andEnabledNotEqualTo(Boolean value) {
method andEnabledNotEqualToColumn (line 1351) | public Criteria andEnabledNotEqualToColumn(LitemallAd.Column column) {
method andEnabledGreaterThan (line 1356) | public Criteria andEnabledGreaterThan(Boolean value) {
method andEnabledGreaterThanColumn (line 1367) | public Criteria andEnabledGreaterThanColumn(LitemallAd.Column column) {
method andEnabledGreaterThanOrEqualTo (line 1372) | public Criteria andEnabledGreaterThanOrEqualTo(Boolean value) {
method andEnabledGreaterThanOrEqualToColumn (line 1383) | public Criteria andEnabledGreaterThanOrEqualToColumn(LitemallAd.Colu...
method andEnabledLessThan (line 1388) | public Criteria andEnabledLessThan(Boolean value) {
method andEnabledLessThanColumn (line 1399) | public Criteria andEnabledLessThanColumn(LitemallAd.Column column) {
method andEnabledLessThanOrEqualTo (line 1404) | public Criteria andEnabledLessThanOrEqualTo(Boolean value) {
method andEnabledLessThanOrEqualToColumn (line 1415) | public Criteria andEnabledLessThanOrEqualToColumn(LitemallAd.Column ...
method andEnabledIn (line 1420) | public Criteria andEnabledIn(List<Boolean> values) {
method andEnabledNotIn (line 1425) | public Criteria andEnabledNotIn(List<Boolean> values) {
method andEnabledBetween (line 1430) | public Criteria andEnabledBetween(Boolean value1, Boolean value2) {
method andEnabledNotBetween (line 1435) | public Criteria andEnabledNotBetween(Boolean value1, Boolean value2) {
method andAddTimeIsNull (line 1440) | public Criteria andAddTimeIsNull() {
method andAddTimeIsNotNull (line 1445) | public Criteria andAddTimeIsNotNull() {
method andAddTimeEqualTo (line 1450) | public Criteria andAddTimeEqualTo(LocalDateTime value) {
method andAddTimeEqualToColumn (line 1461) | public Criteria andAddTimeEqualToColumn(LitemallAd.Column column) {
method andAddTimeNotEqualTo (line 1466) | public Criteria andAddTimeNotEqualTo(LocalDateTime value) {
method andAddTimeNotEqualToColumn (line 1477) | public Criteria andAddTimeNotEqualToColumn(LitemallAd.Column column) {
method andAddTimeGreaterThan (line 1482) | public Criteria andAddTimeGreaterThan(LocalDateTime value) {
method andAddTimeGreaterThanColumn (line 1493) | public Criteria andAddTimeGreaterThanColumn(LitemallAd.Column column) {
method andAddTimeGreaterThanOrEqualTo (line 1498) | public Criteria andAddTimeGreaterThanOrEqualTo(LocalDateTime value) {
method andAddTimeGreaterThanOrEqualToColumn (line 1509) | public Criteria andAddTimeGreaterThanOrEqualToColumn(LitemallAd.Colu...
method andAddTimeLessThan (line 1514) | public Criteria andAddTimeLessThan(LocalDateTime value) {
method andAddTimeLessThanColumn (line 1525) | public Criteria andAddTimeLessThanColumn(LitemallAd.Column column) {
method andAddTimeLessThanOrEqualTo (line 1530) | public Criteria andAddTimeLessThanOrEqualTo(LocalDateTime value) {
method andAddTimeLessThanOrEqualToColumn (line 1541) | public Criteria andAddTimeLessThanOrEqualToColumn(LitemallAd.Column ...
method andAddTimeIn (line 1546) | public Criteria andAddTimeIn(List<LocalDateTime> values) {
method andAddTimeNotIn (line 1551) | public Criteria andAddTimeNotIn(List<LocalDateTime> values) {
method andAddTimeBetween (line 1556) | public Criteria andAddTimeBetween(LocalDateTime value1, LocalDateTim...
method andAddTimeNotBetween (line 1561) | public Criteria andAddTimeNotBetween(LocalDateTime value1, LocalDate...
method andUpdateTimeIsNull (line 1566) | public Criteria andUpdateTimeIsNull() {
method andUpdateTimeIsNotNull (line 1571) | public Criteria andUpdateTimeIsNotNull() {
method andUpdateTimeEqualTo (line 1576) | public Criteria andUpdateTimeEqualTo(LocalDateTime value) {
method andUpdateTimeEqualToColumn (line 1587) | public Criteria andUpdateTimeEqualToColumn(LitemallAd.Column column) {
method andUpdateTimeNotEqualTo (line 1592) | public Criteria andUpdateTimeNotEqualTo(LocalDateTime value) {
method andUpdateTimeNotEqualToColumn (line 1603) | public Criteria andUpdateTimeNotEqualToColumn(LitemallAd.Column colu...
method andUpdateTimeGreaterThan (line 1608) | public Criteria andUpdateTimeGreaterThan(LocalDateTime value) {
method andUpdateTimeGreaterThanColumn (line 1619) | public Criteria andUpdateTimeGreaterThanColumn(LitemallAd.Column col...
method andUpdateTimeGreaterThanOrEqualTo (line 1624) | public Criteria andUpdateTimeGreaterThanOrEqualTo(LocalDateTime valu...
method andUpdateTimeGreaterThanOrEqualToColumn (line 1635) | public Criteria andUpdateTimeGreaterThanOrEqualToColumn(LitemallAd.C...
method andUpdateTimeLessThan (line 1640) | public Criteria andUpdateTimeLessThan(LocalDateTime value) {
method andUpdateTimeLessThanColumn (line 1651) | public Criteria andUpdateTimeLessThanColumn(LitemallAd.Column column) {
method andUpdateTimeLessThanOrEqualTo (line 1656) | public Criteria andUpdateTimeLessThanOrEqualTo(LocalDateTime value) {
method andUpdateTimeLessThanOrEqualToColumn (line 1667) | public Criteria andUpdateTimeLessThanOrEqualToColumn(LitemallAd.Colu...
method andUpdateTimeIn (line 1672) | public Criteria andUpdateTimeIn(List<LocalDateTime> values) {
method andUpdateTimeNotIn (line 1677) | public Criteria andUpdateTimeNotIn(List<LocalDateTime> values) {
method andUpdateTimeBetween (line 1682) | public Criteria andUpdateTimeBetween(LocalDateTime value1, LocalDate...
method andUpdateTimeNotBetween (line 1687) | public Criteria andUpdateTimeNotBetween(LocalDateTime value1, LocalD...
method andDeletedIsNull (line 1692) | public Criteria andDeletedIsNull() {
method andDeletedIsNotNull (line 1697) | public Criteria andDeletedIsNotNull() {
method andDeletedEqualTo (line 1702) | public Criteria andDeletedEqualTo(Boolean value) {
method andDeletedEqualToColumn (line 1713) | public Criteria andDeletedEqualToColumn(LitemallAd.Column column) {
method andDeletedNotEqualTo (line 1718) | public Criteria andDeletedNotEqualTo(Boolean value) {
method andDeletedNotEqualToColumn (line 1729) | public Criteria andDeletedNotEqualToColumn(LitemallAd.Column column) {
method andDeletedGreaterThan (line 1734) | public Criteria andDeletedGreaterThan(Boolean value) {
method andDeletedGreaterThanColumn (line 1745) | public Criteria andDeletedGreaterThanColumn(LitemallAd.Column column) {
method andDeletedGreaterThanOrEqualTo (line 1750) | public Criteria andDeletedGreaterThanOrEqualTo(Boolean value) {
method andDeletedGreaterThanOrEqualToColumn (line 1761) | public Criteria andDeletedGreaterThanOrEqualToColumn(LitemallAd.Colu...
method andDeletedLessThan (line 1766) | public Criteria andDeletedLessThan(Boolean value) {
method andDeletedLessThanColumn (line 1777) | public Criteria andDeletedLessThanColumn(LitemallAd.Column column) {
method andDeletedLessThanOrEqualTo (line 1782) | public Criteria andDeletedLessThanOrEqualTo(Boolean value) {
method andDeletedLessThanOrEqualToColumn (line 1793) | public Criteria andDeletedLessThanOrEqualToColumn(LitemallAd.Column ...
method andDeletedIn (line 1798) | public Criteria andDeletedIn(List<Boolean> values) {
method andDeletedNotIn (line 1803) | public Criteria andDeletedNotIn(List<Boolean> values) {
method andDeletedBetween (line 1808) | public Criteria andDeletedBetween(Boolean value1, Boolean value2) {
method andDeletedNotBetween (line 1813) | public Criteria andDeletedNotBetween(Boolean value1, Boolean value2) {
class Criteria (line 1825) | public static class Criteria extends GeneratedCriteria {
method Criteria (line 1840) | protected Criteria(LitemallAdExample example) {
method example (line 1851) | public LitemallAdExample example() {
method andIf (line 1861) | @Deprecated
method when (line 1875) | public Criteria when(boolean condition, ICriteriaWhen then) {
method when (line 1888) | public Criteria when(boolean condition, ICriteriaWhen then, ICriteri...
method andLogicalDeleted (line 1903) | public Criteria andLogicalDeleted(boolean deleted) {
type ICriteriaAdd (line 1907) | @Deprecated
method add (line 1915) | Criteria add(Criteria add);
class Criterion (line 1925) | public static class Criterion {
method getCondition (line 1942) | public String getCondition() {
method getValue (line 1946) | public Object getValue() {
method getSecondValue (line 1950) | public Object getSecondValue() {
method isNoValue (line 1954) | public boolean isNoValue() {
method isSingleValue (line 1958) | public boolean isSingleValue() {
method isBetweenValue (line 1962) | public boolean isBetweenValue() {
method isListValue (line 1966) | public boolean isListValue() {
method getTypeHandler (line 1970) | public String getTypeHandler() {
method Criterion (line 1974) | protected Criterion(String condition) {
method Criterion (line 1981) | protected Criterion(String condition, Object value, String typeHandl...
method Criterion (line 1993) | protected Criterion(String condition, Object value) {
method Criterion (line 1997) | protected Criterion(String condition, Object value, Object secondVal...
method Criterion (line 2006) | protected Criterion(String condition, Object value, Object secondVal...
type ICriteriaWhen (line 2011) | public interface ICriteriaWhen {
method criteria (line 2018) | void criteria(Criteria criteria);
type IExampleWhen (line 2021) | public interface IExampleWhen {
method example (line 2028) | void example(org.linlinjava.litemall.db.domain.LitemallAdExample exa...
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallAddress.java
class LitemallAddress (line 7) | public class LitemallAddress {
method getId (line 158) | public Integer getId() {
method setId (line 170) | public void setId(Integer id) {
method getName (line 182) | public String getName() {
method setName (line 194) | public void setName(String name) {
method getUserId (line 206) | public Integer getUserId() {
method setUserId (line 218) | public void setUserId(Integer userId) {
method getProvince (line 230) | public String getProvince() {
method setProvince (line 242) | public void setProvince(String province) {
method getCity (line 254) | public String getCity() {
method setCity (line 266) | public void setCity(String city) {
method getCounty (line 278) | public String getCounty() {
method setCounty (line 290) | public void setCounty(String county) {
method getAddressDetail (line 302) | public String getAddressDetail() {
method setAddressDetail (line 314) | public void setAddressDetail(String addressDetail) {
method getAreaCode (line 326) | public String getAreaCode() {
method setAreaCode (line 338) | public void setAreaCode(String areaCode) {
method getPostalCode (line 350) | public String getPostalCode() {
method setPostalCode (line 362) | public void setPostalCode(String postalCode) {
method getTel (line 374) | public String getTel() {
method setTel (line 386) | public void setTel(String tel) {
method getIsDefault (line 398) | public Boolean getIsDefault() {
method setIsDefault (line 410) | public void setIsDefault(Boolean isDefault) {
method getAddTime (line 422) | public LocalDateTime getAddTime() {
method setAddTime (line 434) | public void setAddTime(LocalDateTime addTime) {
method getUpdateTime (line 446) | public LocalDateTime getUpdateTime() {
method setUpdateTime (line 458) | public void setUpdateTime(LocalDateTime updateTime) {
method andLogicalDeleted (line 468) | public void andLogicalDeleted(boolean deleted) {
method getDeleted (line 480) | public Boolean getDeleted() {
method setDeleted (line 492) | public void setDeleted(Boolean deleted) {
method toString (line 502) | @Override
method equals (line 534) | @Override
method hashCode (line 568) | @Override
type Deleted (line 595) | public enum Deleted {
method Deleted (line 621) | Deleted(Boolean value, String name) {
method getValue (line 632) | public Boolean getValue() {
method value (line 642) | public Boolean value() {
method getName (line 652) | public String getName() {
type Column (line 663) | public enum Column {
method value (line 733) | public String value() {
method getValue (line 743) | public String getValue() {
method getJavaProperty (line 753) | public String getJavaProperty() {
method getJdbcType (line 763) | public String getJdbcType() {
method Column (line 773) | Column(String column, String javaProperty, String jdbcType, boolean ...
method desc (line 786) | public String desc() {
method asc (line 796) | public String asc() {
method excludes (line 806) | public static Column[] excludes(Column ... excludes) {
method getEscapedColumnName (line 820) | public String getEscapedColumnName() {
method getAliasedEscapedColumnName (line 834) | public String getAliasedEscapedColumnName() {
FILE: litemall-db/src/main/java/org/linlinjava/litemall/db/domain/LitemallAddressExample.java
class LitemallAddressExample (line 7) | public class LitemallAddressExample {
method LitemallAddressExample (line 38) | public LitemallAddressExample() {
method setOrderByClause (line 48) | public void setOrderByClause(String orderByClause) {
method getOrderByClause (line 58) | public String getOrderByClause() {
method setDistinct (line 68) | public void setDistinct(boolean distinct) {
method isDistinct (line 78) | public boolean isDistinct() {
method getOredCriteria (line 88) | public List<Criteria> getOredCriteria() {
method or (line 98) | public void or(Criteria criteria) {
method or (line 108) | public Criteria or() {
method orderBy (line 120) | public LitemallAddressExample orderBy(String orderByClause) {
method orderBy (line 131) | public LitemallAddressExample orderBy(String ... orderByClauses) {
method createCriteria (line 149) | public Criteria createCriteria() {
method createCriteriaInternal (line 163) | protected Criteria createCriteriaInternal() {
method clear (line 174) | public void clear() {
method newAndCreateCriteria (line 186) | public static Criteria newAndCreateCriteria() {
method when (line 197) | public LitemallAddressExample when(boolean condition, IExampleWhen the...
method when (line 210) | public LitemallAddressExample when(boolean condition, IExampleWhen the...
class GeneratedCriteria (line 225) | protected abstract static class GeneratedCriteria {
method GeneratedCriteria (line 228) | protected GeneratedCriteria() {
method isValid (line 233) | public boolean isValid() {
method getAllCriteria (line 237) | public List<Criterion> getAllCriteria() {
method getCriteria (line 241) | public List<Criterion> getCriteria() {
method addCriterion (line 245) | protected void addCriterion(String condition) {
method addCriterion (line 252) | protected void addCriterion(String condition, Object value, String p...
method addCriterion (line 259) | protected void addCriterion(String condition, Object value1, Object ...
method andIdIsNull (line 266) | public Criteria andIdIsNull() {
method andIdIsNotNull (line 271) | public Criteria andIdIsNotNull() {
method andIdEqualTo (line 276) | public Criteria andIdEqualTo(Integer value) {
method andIdEqualToColumn (line 287) | public Criteria andIdEqualToColumn(LitemallAddress.Column column) {
method andIdNotEqualTo (line 292) | public Criteria andIdNotEqualTo(Integer value) {
method andIdNotEqualToColumn (line 303) | public Criteria andIdNotEqualToColumn(LitemallAddress.Column column) {
method andIdGreaterThan (line 308) | public Criteria andIdGreaterThan(Integer value) {
method andIdGreaterThanColumn (line 319) | public Criteria andIdGreaterThanColumn(LitemallAddress.Column column) {
method andIdGreaterThanOrEqualTo (line 324) | public Criteria andIdGreaterThanOrEqualTo(Integer value) {
method andIdGreaterThanOrEqualToColumn (line 335) | public Criteria andIdGreaterThanOrEqualToColumn(LitemallAddress.Colu...
method andIdLessThan (line 340) | public Criteria andIdLessThan(Integer value) {
method andIdLessThanColumn (line 351) | public Criteria andIdLessThanColumn(LitemallAddress.Column column) {
method andIdLessThanOrEqualTo (line 356) | public Criteria andIdLessThanOrEqualTo(Integer value) {
method andIdLessThanOrEqualToColumn (line 367) | public Criteria andIdLessThanOrEqualToColumn(LitemallAddress.Column ...
method andIdIn (line 372) | public Criteria andIdIn(List<Integer> values) {
method andIdNotIn (line 377) | public Criteria andIdNotIn(List<Integer> values) {
method andIdBetween (line 382) | public Criteria andIdBetween(Integer value1, Integer value2) {
method andIdNotBetween (line 387) | public Criteria andIdNotBetween(Integer value1, Integer value2) {
method andNameIsNull (line 392) | public Criteria andNameIsNull() {
method andNameIsNotNull (line 397) | public Criteria andNameIsNotNull() {
method andNameEqualTo (line 402) | public Criteria andNameEqualTo(String value) {
method andNameEqualToColumn (line 413) | public Criteria andNameEqualToColumn(LitemallAddress.Column column) {
method andNameNotEqualTo (line
Condensed preview — 1373 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (9,433K chars).
[
{
"path": ".gitbook.yaml",
"chars": 35,
"preview": "structure:\n summary: doc/README.md"
},
{
"path": ".github/workflows/main.yml",
"chars": 1807,
"preview": "name: Actions\n\non: [push, pull_request]\n\njobs:\n # Building and testing Java with Maven\n # https://docs.github.com/en/a"
},
{
"path": ".gitignore",
"chars": 512,
"preview": "### gradle ###\n.gradle\n/build/\n!gradle/wrapper/gradle-wrapper.jar\n\n### STS ###\n.settings/\n.apt_generated\n.classpath\n.fac"
},
{
"path": ".workflow/BranchPipeline.yml",
"chars": 1448,
"preview": "version: '1.0'\nname: branch-pipeline\ndisplayName: BranchPipeline\nstages:\n - stage: \n name: compile\n displayName: "
},
{
"path": ".workflow/MasterPipeline.yml",
"chars": 1420,
"preview": "version: '1.0'\nname: master-pipeline\ndisplayName: MasterPipeline\nstages:\n - stage: \n name: compile\n displayName: "
},
{
"path": ".workflow/PRPipeline.yml",
"chars": 1163,
"preview": "version: '1.0'\nname: pr-pipeline\ndisplayName: PRPipeline\nstages:\n - stage: \n name: compile\n displayName: 编译\n s"
},
{
"path": "CHANGELOG.md",
"chars": 5460,
"preview": "# 更新日志\n\n## V 1.8.0\n\n*2021-01-10* 一些完善。。。\n\n## V 1.7.0\n \n*2020-02-15* 支持docker部署、售后管理、通知管理、数据库七天备份。\n\n#### Bug 修复\n\n * `小商城"
},
{
"path": "CONTRIBUTE.md",
"chars": 1747,
"preview": "# 贡献指南\n\n任何形式的贡献都欢迎,包括:\n\n* Issue里面报告的BUG\n* Issue里面对业务或技术的讨论\n* Pull Request\n* 对文档的意见或补充\n* 其他任何有意义本项目的行为\n\n个人能力有限,欢迎一起开发。\n\n目"
},
{
"path": "LICENSE",
"chars": 1087,
"preview": "MIT License\n\nCopyright (c) 2018 linlinjava(linlinjava@163.com)\n\nPermission is hereby granted, free of charge, to any per"
},
{
"path": "README.md",
"chars": 3707,
"preview": "# litemall\n\n又一个小商场系统。\n\nlitemall = Spring Boot后端 + Vue管理员前端 + 微信小程序用户前端 + Vue用户移动端\n\n* [文档](https://linlinjava.gitbook.io/"
},
{
"path": "SECURITY.md",
"chars": 384,
"preview": "# Security Policy\n\n## Supported Versions\n\nUse this section to tell people about which versions of your project are\ncurre"
},
{
"path": "deploy/.gitignore",
"chars": 41,
"preview": "\n/db/litemall.sql\n/litemall/litemall.jar\n"
},
{
"path": "deploy/README.md",
"chars": 2173,
"preview": "## deploy\n\n### 项目打包\n\n1. 在服务器或者开发机打包项目到deploy;\n ```\n cd litemall\n cat ./litemall-db/sql/litemall_schema.sql > ./"
},
{
"path": "deploy/bin/deploy.sh",
"chars": 247,
"preview": "#!/bin/bash\n\n# 本脚本的作用是停止当前Spring Boot应用,然后再次部署\nPID=$(ps -ef | grep litemall.jar | grep -v grep | awk '{ print $2 }')\n\nif"
},
{
"path": "deploy/bin/reset.sh",
"chars": 540,
"preview": "#!/bin/bash\n\n# 本脚本的作用是重置部署环境\n# 1.重置数据库\n# 2.删除storage文件夹内文件\n# 3.调用deploy.sh启动服务\n# 注意:由于1和2的原因,请仅在开发测试阶段使用本脚本!\n\n# 重置数据库\n# "
},
{
"path": "deploy/bin/stop.sh",
"chars": 124,
"preview": "#!/bin/bash\n\nPID=$(ps -ef | grep litemall.jar | grep -v grep | awk '{ print $2 }')\n\nif [ ! -z \"$PID\" ]\nthen\n kill $PI"
},
{
"path": "deploy/db/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "deploy/litemall/application.yml",
"chars": 3598,
"preview": "spring:\n profiles:\n active: none\n message:\n encoding: UTF-8\n datasource:\n druid:\n url: jdbc:mysql://lo"
},
{
"path": "deploy/util/lazy.sh",
"chars": 936,
"preview": "#!/bin/bash\n\n# 本脚本的作用是\n# 1. 项目打包\n# 2. 上传云服务器\n# 3. 远程登录云服务器并执行reset脚本\n\n# 请设置云服务器的IP地址和账户\n# 例如 ubuntu@122.51.199.160\nREMOT"
},
{
"path": "deploy/util/package.sh",
"chars": 965,
"preview": "#!/bin/bash\n\n# 请注意\n# 本脚本的作用是把本项目编译的结果保存到deploy文件夹中\n# 1. 把项目数据库文件拷贝到deploy/db\n# 2. 编译litemall-admin\n# 3. 编译litemall-all模块"
},
{
"path": "doc/FAQ.md",
"chars": 4770,
"preview": "# 常见问题\n\n## 1 小商城\n\n这里主要是指litemall-wx-api、litemall-wx和renard-wx三个模块的相关问题。\n\n### 1.1 小程序微信登录失败\n\n现象:\n\n小程序微信登录失败\n\n原因:\n\n小程序未上线之"
},
{
"path": "doc/README.md",
"chars": 279,
"preview": "# Table of Contents\n\n* [介绍](../README.md)\n* [更新日志](../CHANGELOG.md)\n* [贡献指南](../CONTRIBUTE.md)\n* [FAQ](./FAQ.md)\n* [API]"
},
{
"path": "doc/admin.md",
"chars": 10111,
"preview": "# 4 litemall管理后台\n\n项目技术架构:\n\n* 管理后台前端,即litemall-admin模块\n * vue\n * vuex\n * vue-router\n * axios\n * element\n * vue-elem"
},
{
"path": "doc/api.md",
"chars": 71101,
"preview": "# 前后端接口文档\n\n本项目前后端接口规范和接口文档。\n\n注意:\n> 1. 以下API部分基于nideshop开源项目的API设计;\n> 2. 以下API是参考API,可能不是很合理,欢迎开发者交流。\n> 3. 接口文档处于开发中,如果发现"
},
{
"path": "doc/conf/nginx.conf",
"chars": 2209,
"preview": "user www-data;\nworker_processes auto;\npid /run/nginx.pid;\n\nevents {\n\tworker_connections 768;\n\t# multi_accept on;\n}\n\nhttp"
},
{
"path": "doc/database.md",
"chars": 11177,
"preview": "# 数据库\n\nlitemall数据库基于nideshop中的[nideshop.sql](https://github.com/tumobi/nideshop/blob/master/nideshop.sql)数据库,\n然后在实际开发过程中"
},
{
"path": "doc/how to implement best admin.md",
"chars": 2593,
"preview": "# 最佳管理后台开发实践\n\n很多开源项目和商业项目本质上就是一个业务管理后台,因此开源项目或者商业项目都会开发一个剥离业务的通用管理后台。\n但是从本人开发和使用经验出发,希望解决以下问题:\n\n1. 什么是最佳管理后台\n\n 目前有很多优秀"
},
{
"path": "doc/mobmall.md",
"chars": 479,
"preview": "# 5 litemall轻商城\n\nlitemall轻商城,是商城移动版本。\n\n技术:\n\n* 轻商城前端,即litemall-vue模块\n * vue-cli3 \n * Vue + Vue-router + Vant + Sass\n *"
},
{
"path": "doc/note.md",
"chars": 84,
"preview": "# 项目笔记\n\n记录本项目开发中一些关键技术点。\n\n注意:\n> 这些技术并不是绝对正确或者唯一,而是目前项目所采用。\n\n## 1. 前后端交互技术\n\n## 2. 错误码"
},
{
"path": "doc/performance.md",
"chars": 299,
"preview": "# 性能\n\n## 1 小程序性能\n\n## 2 VUE性能\n\n## 3 Spring Boot性能\n\n### 3.1 gzip压缩\n\n在litemall-all模块中配置gzip压缩\n```\nserver:\n compression:\n "
},
{
"path": "doc/platform.md",
"chars": 14676,
"preview": "# 2 litemall基础系统\n\n目前litemall基础系统由以下部分组成:\n\n* litemall-core模块\n* litemall-db模块\n* litemall-all模块\n* litemall-all-war模块\n\nlitem"
},
{
"path": "doc/project.md",
"chars": 32159,
"preview": "# 1 litemall系统\n\n## 1.1 简介\n\nlitemall是一个简单的商场系统,基于现有的开源项目,重新实现一个完整的前后端项目,包含小程序客户端、移动客户端和网页管理端。\n\n\nconst chalk = require('chalk')\nconst rawArgv = process.argv.slice(2)\nconst args = rawAr"
},
{
"path": "litemall-admin/jest.config.js",
"chars": 766,
"preview": "module.exports = {\n moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],\n transform: {\n '^.+\\\\.vue$': 'vue-jest',\n "
},
{
"path": "litemall-admin/jsconfig.json",
"chars": 137,
"preview": "{ \n \"compilerOptions\": {\n \"baseUrl\": \"./\",\n \"paths\": {\n \"@/*\": [\"src/*\"]\n }\n },\n \"exclude\": [\"node_mo"
},
{
"path": "litemall-admin/package.json",
"chars": 2752,
"preview": "{\n \"name\": \"litemall-admin\",\n \"version\": \"1.0.0\",\n \"description\": \"litemall-admin basing on vue-element-admin 4.3.0\","
},
{
"path": "litemall-admin/postcss.config.js",
"chars": 59,
"preview": "module.exports = {\n plugins: {\n autoprefixer: {}\n }\n}\n"
},
{
"path": "litemall-admin/public/index.html",
"chars": 558,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrom"
},
{
"path": "litemall-admin/public/tinymce4.7.5/langs/zh_CN.js",
"chars": 9928,
"preview": "tinymce.addI18n('zh_CN',{\n\"Cut\": \"\\u526a\\u5207\",\n\"Heading 5\": \"\\u6807\\u98985\",\n\"Header 2\": \"\\u6807\\u98982\",\n\"Your browse"
},
{
"path": "litemall-admin/public/tinymce4.7.5/plugins/codesample/css/prism.css",
"chars": 2334,
"preview": "/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */\n/**\n * prism.js default theme "
},
{
"path": "litemall-admin/public/tinymce4.7.5/plugins/visualblocks/css/visualblocks.css",
"chars": 5473,
"preview": ".mce-visualblocks p {\n padding-top: 10px;\n border: 1px dashed #BBB;\n margin-left: 3px;\n background-image: url(data:i"
},
{
"path": "litemall-admin/src/App.vue",
"chars": 120,
"preview": "<template>\n <div id=\"app\">\n <router-view/>\n </div>\n</template>\n\n<script>\nexport default{\n name: 'App'\n}\n</script>\n"
},
{
"path": "litemall-admin/src/api/ad.js",
"chars": 598,
"preview": "import request from '@/utils/request'\n\nexport function listAd(query) {\n return request({\n url: '/ad/list',\n metho"
},
{
"path": "litemall-admin/src/api/admin.js",
"chars": 634,
"preview": "import request from '@/utils/request'\n\nexport function listAdmin(query) {\n return request({\n url: '/admin/list',\n "
},
{
"path": "litemall-admin/src/api/aftersale.js",
"chars": 821,
"preview": "import request from '@/utils/request'\n\nexport function listAftersale(query) {\n return request({\n url: '/aftersale/li"
},
{
"path": "litemall-admin/src/api/brand.js",
"chars": 628,
"preview": "import request from '@/utils/request'\n\nexport function listBrand(query) {\n return request({\n url: '/brand/list',\n "
},
{
"path": "litemall-admin/src/api/category.js",
"chars": 758,
"preview": "import request from '@/utils/request'\n\nexport function listCategory(query) {\n return request({\n url: '/category/list"
},
{
"path": "litemall-admin/src/api/comment.js",
"chars": 287,
"preview": "import request from '@/utils/request'\n\nexport function listComment(query) {\n return request({\n url: '/comment/list',"
},
{
"path": "litemall-admin/src/api/config.js",
"chars": 906,
"preview": "import request from '@/utils/request'\n\nexport function listMall() {\n return request({\n url: '/config/mall',\n meth"
},
{
"path": "litemall-admin/src/api/coupon.js",
"chars": 779,
"preview": "import request from '@/utils/request'\n\nexport function listCoupon(query) {\n return request({\n url: '/coupon/list',\n "
},
{
"path": "litemall-admin/src/api/dashboard.js",
"chars": 155,
"preview": "import request from '@/utils/request'\n\nexport function info(query) {\n return request({\n url: '/dashboard',\n metho"
},
{
"path": "litemall-admin/src/api/goods.js",
"chars": 751,
"preview": "import request from '@/utils/request'\n\nexport function listGoods(query) {\n return request({\n url: '/goods/list',\n "
},
{
"path": "litemall-admin/src/api/groupon.js",
"chars": 662,
"preview": "import request from '@/utils/request'\n\nexport function listRecord(query) {\n return request({\n url: '/groupon/listRec"
},
{
"path": "litemall-admin/src/api/issue.js",
"chars": 628,
"preview": "import request from '@/utils/request'\n\nexport function listIssue(query) {\n return request({\n url: '/issue/list',\n "
},
{
"path": "litemall-admin/src/api/keyword.js",
"chars": 648,
"preview": "import request from '@/utils/request'\n\nexport function listKeyword(query) {\n return request({\n url: '/keyword/list',"
},
{
"path": "litemall-admin/src/api/log.js",
"chars": 157,
"preview": "import request from '@/utils/request'\n\nexport function listLog(query) {\n return request({\n url: '/log/list',\n met"
},
{
"path": "litemall-admin/src/api/login.js",
"chars": 564,
"preview": "import request from '@/utils/request'\n\nexport function loginByUsername(username, password, code) {\n const data = {\n "
},
{
"path": "litemall-admin/src/api/notice.js",
"chars": 779,
"preview": "import request from '@/utils/request'\n\nexport function listNotice(query) {\n return request({\n url: '/notice/list',\n "
},
{
"path": "litemall-admin/src/api/order.js",
"chars": 1100,
"preview": "import request from '@/utils/request'\nimport Qs from 'qs'\n\nexport function listOrder(query) {\n return request({\n url"
},
{
"path": "litemall-admin/src/api/profile.js",
"chars": 879,
"preview": "import request from '@/utils/request'\n\nexport function changePassword(data) {\n return request({\n url: '/profile/pass"
},
{
"path": "litemall-admin/src/api/region.js",
"chars": 268,
"preview": "import request from '@/utils/request'\n\nexport function listRegion() {\n return request({\n url: '/region/list',\n me"
},
{
"path": "litemall-admin/src/api/role.js",
"chars": 1005,
"preview": "import request from '@/utils/request'\n\nexport function listRole(query) {\n return request({\n url: '/role/list',\n m"
},
{
"path": "litemall-admin/src/api/stat.js",
"chars": 405,
"preview": "import request from '@/utils/request'\n\nexport function statUser(query) {\n return request({\n url: '/stat/user',\n m"
},
{
"path": "litemall-admin/src/api/storage.js",
"chars": 739,
"preview": "import request from '@/utils/request'\n\nexport function listStorage(query) {\n return request({\n url: '/storage/list',"
},
{
"path": "litemall-admin/src/api/topic.js",
"chars": 767,
"preview": "import request from '@/utils/request'\n\nexport function listTopic(query) {\n return request({\n url: '/topic/list',\n "
},
{
"path": "litemall-admin/src/api/user.js",
"chars": 1038,
"preview": "import request from '@/utils/request'\n\nexport function fetchList(query) {\n return request({\n url: '/user/list',\n "
},
{
"path": "litemall-admin/src/components/BackToTop/index.vue",
"chars": 2773,
"preview": "<template>\n <transition :name=\"transitionName\">\n <div v-show=\"visible\" :style=\"customStyle\" class=\"back-to-ceiling\" "
},
{
"path": "litemall-admin/src/components/Breadcrumb/index.vue",
"chars": 2250,
"preview": "<template>\n <el-breadcrumb class=\"app-breadcrumb\" separator=\"/\">\n <transition-group name=\"breadcrumb\">\n <el-bre"
},
{
"path": "litemall-admin/src/components/Hamburger/index.vue",
"chars": 1825,
"preview": "<template>\n <div>\n <svg\n :class=\"{'is-active':isActive}\"\n t=\"1492500959545\"\n class=\"hamburger\"\n "
},
{
"path": "litemall-admin/src/components/LocaleChanger/index.vue",
"chars": 588,
"preview": "<!-- https://kazupon.github.io/vue-i18n/guide/locale.html -->\n<template>\n <el-select v-model=\"$i18n.locale\" size=\"mini\""
},
{
"path": "litemall-admin/src/components/Notice/index.vue",
"chars": 897,
"preview": "<template>\n <div>\n <el-badge :is-dot=\"hasNotice\">\n <i class=\"el-icon-bell\" @click=\"click\" />\n </el-badge>\n "
},
{
"path": "litemall-admin/src/components/Pagination/index.vue",
"chars": 1846,
"preview": "<template>\n <div :class=\"{'hidden':hidden}\" class=\"pagination-container\">\n <el-pagination\n :background=\"backgro"
},
{
"path": "litemall-admin/src/components/Screenfull/index.vue",
"chars": 827,
"preview": "<template>\n <div>\n <i class=\"el-icon-full-screen\" @click=\"click\" />\n </div>\n</template>\n\n<script>\nimport screenfull"
},
{
"path": "litemall-admin/src/components/ScrollPane/index.vue",
"chars": 2654,
"preview": "<template>\n <el-scrollbar ref=\"scrollContainer\" :vertical=\"false\" class=\"scroll-container\" @wheel.native.prevent=\"handl"
},
{
"path": "litemall-admin/src/components/SizeSelect/index.vue",
"chars": 1298,
"preview": "<template>\n <el-dropdown trigger=\"click\" @command=\"handleSetSize\">\n <div>\n <i class=\"el-icon-rank\" />\n </div"
},
{
"path": "litemall-admin/src/components/SvgIcon/index.vue",
"chars": 1310,
"preview": "<template>\n <div v-if=\"isExternal\" :style=\"styleExternalIcon\" class=\"svg-external-icon svg-icon\" v-on=\"$listeners\" />\n "
},
{
"path": "litemall-admin/src/directive/clipboard/clipboard.js",
"chars": 1546,
"preview": "// Inspired by https://github.com/Inndy/vue-clipboard2\nconst Clipboard = require('clipboard')\nif (!Clipboard) {\n throw "
},
{
"path": "litemall-admin/src/directive/clipboard/index.js",
"chars": 260,
"preview": "import Clipboard from './clipboard'\n\nconst install = function(Vue) {\n Vue.directive('Clipboard', Clipboard)\n}\n\nif (wind"
},
{
"path": "litemall-admin/src/directive/permission/index.js",
"chars": 271,
"preview": "import permission from './permission'\n\nconst install = function(Vue) {\n Vue.directive('permission', permission)\n}\n\nif ("
},
{
"path": "litemall-admin/src/directive/permission/permission.js",
"chars": 682,
"preview": "\nimport store from '@/store'\n\nexport default{\n inserted(el, binding, vnode) {\n const { value } = binding\n const p"
},
{
"path": "litemall-admin/src/filters/index.js",
"chars": 1603,
"preview": "// import parseTime, formatTime and set to filter\nexport { parseTime, formatTime } from '@/utils'\n\n/**\n * Show plural la"
},
{
"path": "litemall-admin/src/icons/index.js",
"chars": 280,
"preview": "import Vue from 'vue'\nimport SvgIcon from '@/components/SvgIcon'// svg组件\n\n// register globally\nVue.component('svg-icon',"
},
{
"path": "litemall-admin/src/icons/svgo.yml",
"chars": 248,
"preview": "# replace default config\n\n# multipass: true\n# full: true\n\nplugins:\n\n # - name\n #\n # or:\n # - name: false\n # - name:"
},
{
"path": "litemall-admin/src/locales/en.js",
"chars": 23955,
"preview": "// https://element.eleme.cn/#/en-US/component/i18n\nimport el from 'element-ui/lib/locale/lang/en'\n\nexport default {\n .."
},
{
"path": "litemall-admin/src/locales/zh-Hans.js",
"chars": 21003,
"preview": "// https://element.eleme.cn/#/en-US/component/i18n\nimport el from 'element-ui/lib/locale/lang/zh-CN'\n\nexport default {\n "
},
{
"path": "litemall-admin/src/main.js",
"chars": 2271,
"preview": "import Vue from 'vue'\nimport VueI18n from 'vue-i18n' // translations\n\nimport Cookies from 'js-cookie'\n\nimport 'normalize"
},
{
"path": "litemall-admin/src/permission.js",
"chars": 2398,
"preview": "import router from './router'\nimport store from './store'\nimport { Message } from 'element-ui'\nimport NProgress from 'np"
},
{
"path": "litemall-admin/src/router/index.js",
"chars": 17558,
"preview": "import Vue from 'vue'\nimport Router from 'vue-router'\n\nVue.use(Router)\n\n/* Layout */\nimport Layout from '@/views/layout/"
},
{
"path": "litemall-admin/src/store/getters.js",
"chars": 583,
"preview": "const getters = {\n sidebar: state => state.app.sidebar,\n language: state => state.app.language,\n size: state => state"
},
{
"path": "litemall-admin/src/store/index.js",
"chars": 380,
"preview": "import Vue from 'vue'\nimport Vuex from 'vuex'\nimport app from './modules/app'\nimport permission from './modules/permissi"
},
{
"path": "litemall-admin/src/store/modules/app.js",
"chars": 1496,
"preview": "import Cookies from 'js-cookie'\n\nconst app = {\n state: {\n sidebar: {\n opened: !+Cookies.get('sidebarStatus'),\n "
},
{
"path": "litemall-admin/src/store/modules/permission.js",
"chars": 1431,
"preview": "import { asyncRoutes, constantRoutes } from '@/router'\n\n/**\n * 通过meta.perms判断是否与当前用户权限匹配\n * @param perms\n * @param route"
},
{
"path": "litemall-admin/src/store/modules/tagsView.js",
"chars": 4075,
"preview": "const state = {\n visitedViews: [],\n cachedViews: []\n}\n\nconst mutations = {\n ADD_VISITED_VIEW: (state, view) => {\n "
},
{
"path": "litemall-admin/src/store/modules/user.js",
"chars": 3161,
"preview": "import { loginByUsername, logout, getUserInfo } from '@/api/login'\nimport { getToken, setToken, removeToken } from '@/ut"
},
{
"path": "litemall-admin/src/styles/btn.scss",
"chars": 1370,
"preview": "@import './variables.scss';\n\n@mixin colorBtn($color) {\n background: $color;\n\n &:hover {\n color: $color;\n\n &:befo"
},
{
"path": "litemall-admin/src/styles/element-ui.scss",
"chars": 1137,
"preview": "// cover some element-ui styles\n\n.el-breadcrumb__inner,\n.el-breadcrumb__inner a {\n font-weight: 400 !important;\n}\n\n.el-"
},
{
"path": "litemall-admin/src/styles/element-variables.scss",
"chars": 790,
"preview": "/**\n* I think element-ui's default theme color is too light for long-term use.\n* So I modified the default color and you"
},
{
"path": "litemall-admin/src/styles/index.scss",
"chars": 2837,
"preview": "@import './variables.scss';\n@import './mixin.scss';\n@import './transition.scss';\n@import './element-ui.scss';\n@import '."
},
{
"path": "litemall-admin/src/styles/mixin.scss",
"chars": 1311,
"preview": "@mixin clearfix {\n &:after {\n content: \"\";\n display: table;\n clear: both;\n }\n}\n\n@mixin scrollBar {\n &::-webk"
},
{
"path": "litemall-admin/src/styles/sidebar.scss",
"chars": 4052,
"preview": "#app {\n\n .main-container {\n min-height: 100%;\n transition: margin-left .28s;\n margin-left: $sideBarWidth;\n "
},
{
"path": "litemall-admin/src/styles/transition.scss",
"chars": 714,
"preview": "// global transition css\n\n/* fade */\n.fade-enter-active,\n.fade-leave-active {\n transition: opacity 0.28s;\n}\n\n.fade-ente"
},
{
"path": "litemall-admin/src/styles/variables.scss",
"chars": 771,
"preview": "// base color\n$blue:#324157;\n$light-blue:#3A71A8;\n$red:#C03639;\n$pink: #E65D6E;\n$green: #30B08F;\n$tiffany: #4AB7BD;\n$yel"
},
{
"path": "litemall-admin/src/utils/auth.js",
"chars": 282,
"preview": "import Cookies from 'js-cookie'\n\nconst TokenKey = 'X-Litemall-Admin-Token'\n\nexport function getToken() {\n return Cookie"
},
{
"path": "litemall-admin/src/utils/clipboard.js",
"chars": 725,
"preview": "import Vue from 'vue'\nimport Clipboard from 'clipboard'\n\nfunction clipboardSuccess() {\n Vue.prototype.$message({\n me"
},
{
"path": "litemall-admin/src/utils/index.js",
"chars": 7010,
"preview": "/**\n * Created by jiachenpan on 16/11/18.\n */\n\nexport function parseTime(time, cFormat) {\n if (arguments.length === 0) "
},
{
"path": "litemall-admin/src/utils/openWindow.js",
"chars": 1174,
"preview": "/**\n *Created by jiachenpan on 16/11/29.\n * @param {Sting} url\n * @param {Sting} title\n * @param {Number} w\n * @param {N"
},
{
"path": "litemall-admin/src/utils/permission.js",
"chars": 714,
"preview": "import store from '@/store'\n\n/**\n * @param {Array} value\n * @returns {Boolean}\n * @example see @/views/permission/direct"
},
{
"path": "litemall-admin/src/utils/print.js",
"chars": 3743,
"preview": "// 打印类属性、方法定义\n/* eslint-disable */\nconst Print = function (dom, options) {\n if (!(this instanceof Print)) return new Pr"
},
{
"path": "litemall-admin/src/utils/request.js",
"chars": 2460,
"preview": "import axios from 'axios'\nimport { Message, MessageBox } from 'element-ui'\nimport store from '@/store'\nimport { getToken"
},
{
"path": "litemall-admin/src/utils/scrollTo.js",
"chars": 1592,
"preview": "Math.easeInOutQuad = function(t, b, c, d) {\n t /= d / 2\n if (t < 1) {\n return c / 2 * t * t + b\n }\n t--\n return "
},
{
"path": "litemall-admin/src/utils/validate.js",
"chars": 1807,
"preview": "/**\n * Created by PanJiaChen on 16/11/18.\n */\n\n/**\n * @param {string} path\n * @returns {Boolean}\n */\nexport function isE"
},
{
"path": "litemall-admin/src/vendor/Export2Excel.js",
"chars": 6514,
"preview": "/* eslint-disable */\nimport { saveAs } from 'file-saver'\nimport { utils, SSF, write } from 'xlsx'\n\nfunction generateArra"
},
{
"path": "litemall-admin/src/views/config/express.vue",
"chars": 1980,
"preview": "<template>\n <div class=\"app-container\">\n <el-form ref=\"dataForm\" :rules=\"rules\" :model=\"dataForm\" status-icon label-"
},
{
"path": "litemall-admin/src/views/config/mall.vue",
"chars": 3100,
"preview": "<template>\n <div class=\"app-container\">\n <el-form ref=\"dataForm\" :rules=\"rules\" :model=\"dataForm\" status-icon label-"
},
{
"path": "litemall-admin/src/views/config/order.vue",
"chars": 2943,
"preview": "<template>\n <div class=\"app-container\">\n <el-form ref=\"dataForm\" :rules=\"rules\" :model=\"dataForm\" status-icon label-"
},
{
"path": "litemall-admin/src/views/config/wx.vue",
"chars": 3835,
"preview": "<template>\n <div class=\"app-container\">\n <el-form\n ref=\"dataForm\"\n :rules=\"rules\"\n :model=\"dataForm\"\n"
},
{
"path": "litemall-admin/src/views/dashboard/index.vue",
"chars": 4775,
"preview": "<template>\n <div class=\"dashboard-editor-container\">\n\n <el-row :gutter=\"40\" class=\"panel-group\">\n <el-col :xs=\""
},
{
"path": "litemall-admin/src/views/errorPage/401.vue",
"chars": 2214,
"preview": "<template>\n <div class=\"errPage-container\">\n <el-button icon=\"el-icon-arrow-left\" class=\"pan-back-btn\" @click=\"back\""
},
{
"path": "litemall-admin/src/views/errorPage/404.vue",
"chars": 5109,
"preview": "<template>\n <div class=\"wscn-http404-container\">\n <div class=\"wscn-http404\">\n <div class=\"pic-404\">\n <im"
},
{
"path": "litemall-admin/src/views/goods/comment.vue",
"chars": 5396,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/goods/create.vue",
"chars": 22863,
"preview": "<template>\n <div class=\"app-container\">\n\n <el-card class=\"box-card\">\n <h3>{{ $t('goods_edit.section.goods') }}<"
},
{
"path": "litemall-admin/src/views/goods/edit.vue",
"chars": 21881,
"preview": "<template>\n <div class=\"app-container\">\n\n <el-card class=\"box-card\">\n <h3>{{ $t('goods_edit.section.goods') }}<"
},
{
"path": "litemall-admin/src/views/goods/list.vue",
"chars": 9627,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/layout/Layout.vue",
"chars": 1497,
"preview": "<template>\n <div :class=\"classObj\" class=\"app-wrapper\">\n <div v-if=\"device==='mobile'&&sidebar.opened\" class=\"drawer"
},
{
"path": "litemall-admin/src/views/layout/components/AppMain.vue",
"chars": 971,
"preview": "<template>\n <section class=\"app-main\">\n <transition name=\"fade-transform\" mode=\"out-in\">\n <keep-alive :include="
},
{
"path": "litemall-admin/src/views/layout/components/Navbar.vue",
"chars": 3844,
"preview": "<template>\n <div class=\"navbar\">\n <hamburger :toggle-click=\"toggleSideBar\" :is-active=\"sidebar.opened\" class=\"hambur"
},
{
"path": "litemall-admin/src/views/layout/components/Sidebar/FixiOSBug.js",
"chars": 634,
"preview": "export default {\n computed: {\n device() {\n return this.$store.state.app.device\n }\n },\n mounted() {\n // "
},
{
"path": "litemall-admin/src/views/layout/components/Sidebar/Item.vue",
"chars": 682,
"preview": "<script>\nexport default {\n name: 'MenuItem',\n functional: true,\n props: {\n icon: {\n type: String,\n defau"
},
{
"path": "litemall-admin/src/views/layout/components/Sidebar/Link.vue",
"chars": 656,
"preview": "<template>\n <component :is=\"type\" v-bind=\"linkProps(to)\">\n <slot />\n </component>\n</template>\n\n<script>\nimport { is"
},
{
"path": "litemall-admin/src/views/layout/components/Sidebar/SidebarItem.vue",
"chars": 2681,
"preview": "<template>\n <div v-if=\"!item.hidden\" class=\"menu-wrapper\">\n <template v-if=\"hasOneShowingChild(item.children,item) &"
},
{
"path": "litemall-admin/src/views/layout/components/Sidebar/index.vue",
"chars": 737,
"preview": "<template>\n <el-scrollbar wrap-class=\"scrollbar-wrapper\">\n <el-menu\n :show-timeout=\"200\"\n :default-active="
},
{
"path": "litemall-admin/src/views/layout/components/TagsView/ScrollPane.vue",
"chars": 2626,
"preview": "<template>\n <el-scrollbar ref=\"scrollContainer\" :vertical=\"false\" class=\"scroll-container\" @wheel.native.prevent=\"handl"
},
{
"path": "litemall-admin/src/views/layout/components/TagsView/index.vue",
"chars": 7719,
"preview": "<template>\n <div id=\"tags-view-container\" class=\"tags-view-container\">\n <scroll-pane ref=\"scrollPane\" class=\"tags-vi"
},
{
"path": "litemall-admin/src/views/layout/components/index.js",
"chars": 208,
"preview": "export { default as AppMain } from './AppMain'\nexport { default as Navbar } from './Navbar'\nexport { default as Sidebar "
},
{
"path": "litemall-admin/src/views/layout/mixin/ResizeHandler.js",
"chars": 976,
"preview": "import store from '@/store'\n\nconst { body } = document\nconst WIDTH = 1024\nconst RATIO = 3\n\nexport default {\n watch: {\n "
},
{
"path": "litemall-admin/src/views/login/authredirect.vue",
"chars": 224,
"preview": "<script>\nexport default {\n name: 'AuthRedirect',\n created() {\n const hash = window.location.search.slice(1)\n win"
},
{
"path": "litemall-admin/src/views/login/index.vue",
"chars": 6589,
"preview": "<template>\n <div class=\"login-container\">\n <div class=\"locale-changer\">\n <locale-changer />\n </div>\n <el-"
},
{
"path": "litemall-admin/src/views/mall/aftersale.vue",
"chars": 12304,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/mall/brand.vue",
"chars": 9291,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/mall/category.vue",
"chars": 9733,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-button v-per"
},
{
"path": "litemall-admin/src/views/mall/issue.vue",
"chars": 6960,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/mall/keyword.vue",
"chars": 8704,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/mall/order.vue",
"chars": 22265,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/mall/region.vue",
"chars": 1286,
"preview": "<template>\n <div class=\"app-container\">\n\n <el-table v-loading=\"listLoading\" :data=\"list\" :element-loading-text=\"$t('"
},
{
"path": "litemall-admin/src/views/profile/notice.vue",
"chars": 6088,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/profile/password.vue",
"chars": 2814,
"preview": "<template>\n <div class=\"app-container\">\n <el-form ref=\"dataForm\" :rules=\"rules\" :model=\"dataForm\" status-icon label-"
},
{
"path": "litemall-admin/src/views/promotion/ad.vue",
"chars": 11123,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/promotion/coupon.vue",
"chars": 23120,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/promotion/couponDetail.vue",
"chars": 8075,
"preview": "<template>\n <div class=\"app-container\">\n\n <div class=\"table-layout\">\n <el-row>\n <el-col :span=\"4\" class="
},
{
"path": "litemall-admin/src/views/promotion/grouponActivity.vue",
"chars": 4613,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/promotion/grouponRule.vue",
"chars": 9180,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/promotion/topic.vue",
"chars": 7759,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/promotion/topicCreate.vue",
"chars": 10310,
"preview": "<template>\n <div class=\"app-container\">\n\n <el-form ref=\"topic\" :rules=\"rules\" :model=\"topic\" status-icon label-posit"
},
{
"path": "litemall-admin/src/views/promotion/topicEdit.vue",
"chars": 10801,
"preview": "<template>\n <div class=\"app-container\">\n\n <el-form ref=\"topic\" :rules=\"rules\" :model=\"topic\" status-icon label-posit"
},
{
"path": "litemall-admin/src/views/redirect/index.vue",
"chars": 249,
"preview": "<script>\nexport default {\n created() {\n const { params, query } = this.$route\n const { path } = params\n this.$"
},
{
"path": "litemall-admin/src/views/stat/goods.vue",
"chars": 720,
"preview": "<template>\n <div class=\"app-container\">\n <ve-line :extend=\"chartExtend\" :data=\"chartData\" :settings=\"chartSettings\"/"
},
{
"path": "litemall-admin/src/views/stat/order.vue",
"chars": 740,
"preview": "<template>\n <div class=\"app-container\">\n <ve-line :extend=\"chartExtend\" :data=\"chartData\" :settings=\"chartSettings\"/"
},
{
"path": "litemall-admin/src/views/stat/user.vue",
"chars": 755,
"preview": "<template>\n <div class=\"app-container\">\n <ve-histogram :extend=\"chartExtend\" :data=\"chartData\" :settings=\"chartSetti"
},
{
"path": "litemall-admin/src/views/sys/admin.vue",
"chars": 9786,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/sys/log.vue",
"chars": 3038,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/sys/notice.vue",
"chars": 10661,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/sys/os.vue",
"chars": 7029,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/sys/role.vue",
"chars": 8872,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/user/address.vue",
"chars": 3577,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/user/collect.vue",
"chars": 3012,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/user/feedback.vue",
"chars": 3368,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/user/footprint.vue",
"chars": 2966,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/src/views/user/history.vue",
"chars": 2974,
"preview": "<template>\n <div class=\"app-container calendar-list-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\""
},
{
"path": "litemall-admin/src/views/user/user.vue",
"chars": 7448,
"preview": "<template>\n <div class=\"app-container\">\n\n <!-- 查询和其他操作 -->\n <div class=\"filter-container\">\n <el-input v-mode"
},
{
"path": "litemall-admin/vue.config.js",
"chars": 3902,
"preview": "'use strict'\nconst path = require('path')\n\nfunction resolve(dir) {\n return path.join(__dirname, dir)\n}\n\nconst name = 'l"
},
{
"path": "litemall-admin-api/.gitignore",
"chars": 34,
"preview": "\n/target/\n/litemall-admin-api.iml\n"
},
{
"path": "litemall-admin-api/pom.xml",
"chars": 2521,
"preview": "<project xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://maven.apache.org/POM/4.0.0\"\n xsi:sc"
},
{
"path": "litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/Application.java",
"chars": 733,
"preview": "package org.linlinjava.litemall.admin;\n\nimport org.mybatis.spring.annotation.MapperScan;\nimport org.springframework.boot"
},
{
"path": "litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/annotation/RequiresPermissionsDesc.java",
"chars": 386,
"preview": "package org.linlinjava.litemall.admin.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation."
},
{
"path": "litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/config/AdminSwagger2Configuration.java",
"chars": 1679,
"preview": "package org.linlinjava.litemall.admin.config;\n\nimport com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBo"
},
{
"path": "litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/config/KaptchaConfig.java",
"chars": 1192,
"preview": "package org.linlinjava.litemall.admin.config;\n\nimport com.google.code.kaptcha.Producer;\nimport com.google.code.kaptcha.i"
},
{
"path": "litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/config/ShiroConfig.java",
"chars": 3222,
"preview": "package org.linlinjava.litemall.admin.config;\n\nimport org.apache.shiro.mgt.SecurityManager;\nimport org.apache.shiro.real"
},
{
"path": "litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/config/ShiroExceptionHandler.java",
"chars": 1209,
"preview": "package org.linlinjava.litemall.admin.config;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging."
},
{
"path": "litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/dto/GoodsAllinone.java",
"chars": 1254,
"preview": "package org.linlinjava.litemall.admin.dto;\n\nimport org.linlinjava.litemall.db.domain.LitemallGoods;\nimport org.linlinjav"
},
{
"path": "litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/job/CouponJob.java",
"chars": 1742,
"preview": "package org.linlinjava.litemall.admin.job;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.Log"
},
{
"path": "litemall-admin-api/src/main/java/org/linlinjava/litemall/admin/job/DbJob.java",
"chars": 1826,
"preview": "package org.linlinjava.litemall.admin.job;\n\nimport org.apache.commons.logging.Log;\nimport org.apache.commons.logging.Log"
}
]
// ... and 1173 more files (download for full content)
About this extraction
This page contains the full source code of the linlinjava/litemall GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1373 files (8.5 MB), approximately 2.3M tokens, and a symbol index with 13455 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.