Sfoglia il codice sorgente

Merge remote-tracking branch 'origin/dev' into dev

baolei 7 mesi fa
parent
commit
8fc8e1e41a
70 ha cambiato i file con 1092 aggiunte e 130 eliminazioni
  1. 31 0
      08.src/Xingxi-mp/.eslintrc.js
  2. 2 0
      08.src/Xingxi-mp/app.js
  3. 57 0
      08.src/Xingxi-mp/app.json
  4. 1 0
      08.src/Xingxi-mp/app.wxss
  5. 105 0
      08.src/Xingxi-mp/components/navigation-bar/navigation-bar.js
  6. 5 0
      08.src/Xingxi-mp/components/navigation-bar/navigation-bar.json
  7. 64 0
      08.src/Xingxi-mp/components/navigation-bar/navigation-bar.wxml
  8. 96 0
      08.src/Xingxi-mp/components/navigation-bar/navigation-bar.wxss
  9. BIN
      08.src/Xingxi-mp/images/index/add-cart.png
  10. BIN
      08.src/Xingxi-mp/images/index/brand-item.png
  11. BIN
      08.src/Xingxi-mp/images/index/buy-now.png
  12. BIN
      08.src/Xingxi-mp/images/index/cart.png
  13. BIN
      08.src/Xingxi-mp/images/index/category-item.png
  14. BIN
      08.src/Xingxi-mp/images/index/hot-item.png
  15. BIN
      08.src/Xingxi-mp/images/index/logo.png
  16. BIN
      08.src/Xingxi-mp/images/index/search.png
  17. 1 0
      08.src/Xingxi-mp/pages/all/all.js
  18. 4 0
      08.src/Xingxi-mp/pages/all/all.json
  19. 3 0
      08.src/Xingxi-mp/pages/all/all.wxml
  20. 0 0
      08.src/Xingxi-mp/pages/all/all.wxss
  21. 1 0
      08.src/Xingxi-mp/pages/cart/cart.js
  22. 4 0
      08.src/Xingxi-mp/pages/cart/cart.json
  23. 3 0
      08.src/Xingxi-mp/pages/cart/cart.wxml
  24. 0 0
      08.src/Xingxi-mp/pages/cart/cart.wxss
  25. 1 0
      08.src/Xingxi-mp/pages/detail/detail.js
  26. 4 0
      08.src/Xingxi-mp/pages/detail/detail.json
  27. 3 0
      08.src/Xingxi-mp/pages/detail/detail.wxml
  28. 0 0
      08.src/Xingxi-mp/pages/detail/detail.wxss
  29. 84 0
      08.src/Xingxi-mp/pages/index/index.js
  30. 3 0
      08.src/Xingxi-mp/pages/index/index.json
  31. 68 0
      08.src/Xingxi-mp/pages/index/index.wxml
  32. 132 0
      08.src/Xingxi-mp/pages/index/index.wxss
  33. 1 0
      08.src/Xingxi-mp/pages/login/login.js
  34. 4 0
      08.src/Xingxi-mp/pages/login/login.json
  35. 3 0
      08.src/Xingxi-mp/pages/login/login.wxml
  36. 0 0
      08.src/Xingxi-mp/pages/login/login.wxss
  37. 1 0
      08.src/Xingxi-mp/pages/my/my.js
  38. 4 0
      08.src/Xingxi-mp/pages/my/my.json
  39. 3 0
      08.src/Xingxi-mp/pages/my/my.wxml
  40. 0 0
      08.src/Xingxi-mp/pages/my/my.wxss
  41. 28 0
      08.src/Xingxi-mp/project.config.json
  42. 7 0
      08.src/Xingxi-mp/project.private.config.json
  43. 7 0
      08.src/Xingxi-mp/sitemap.json
  44. 20 43
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/monitor/SysUserOnlineController.java
  45. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysCaptchaController.java
  46. 2 2
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysConfigController.java
  47. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysDeptController.java
  48. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysDictDataController.java
  49. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysDictTypeController.java
  50. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysFileUploadController.java
  51. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysIndexController.java
  52. 19 27
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysLoginController.java
  53. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysMenuController.java
  54. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysNoticeController.java
  55. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysPostController.java
  56. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysProfileController.java
  57. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysRegisterController.java
  58. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysRoleController.java
  59. 1 1
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysUserController.java
  60. 13 0
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/service/ISysConfigVoService.java
  61. 13 0
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/service/ISysDictTypeVoService.java
  62. 55 0
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/service/impl/SysConfigVoServiceImpl.java
  63. 46 0
      08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/service/impl/SysDictTypeVoServiceImpl.java
  64. 13 0
      08.src/Xingxi/xingxi-admin/src/main/resources/application-local.yml
  65. 44 0
      08.src/Xingxi/xingxi-admin/src/main/resources/templates/master/product/prodAttr/add.html
  66. 26 0
      08.src/Xingxi/xingxi-admin/src/main/resources/templates/master/product/prodAttr/edit.html
  67. 58 0
      08.src/Xingxi/xingxi-admin/src/main/resources/templates/master/product/prodAttr/prodAttr.html
  68. 5 0
      08.src/Xingxi/xingxi-admin/src/main/resources/templates/master/tag/tag.html
  69. 20 45
      08.src/Xingxi/xingxi-framework/src/main/java/com/xingxi/framework/shiro/realm/UserRealm.java
  70. 15 0
      08.src/Xingxi/xingxi-system/src/main/java/com/xingxi/master/tag/service/impl/TagServiceImpl.java

+ 31 - 0
08.src/Xingxi-mp/.eslintrc.js

@@ -0,0 +1,31 @@
+/*
+ * Eslint config file
+ * Documentation: https://eslint.org/docs/user-guide/configuring/
+ * Install the Eslint extension before using this feature.
+ */
+module.exports = {
+  env: {
+    es6: true,
+    browser: true,
+    node: true,
+  },
+  ecmaFeatures: {
+    modules: true,
+  },
+  parserOptions: {
+    ecmaVersion: 2018,
+    sourceType: 'module',
+  },
+  globals: {
+    wx: true,
+    App: true,
+    Page: true,
+    getCurrentPages: true,
+    getApp: true,
+    Component: true,
+    requirePlugin: true,
+    requireMiniProgram: true,
+  },
+  // extends: 'eslint:recommended',
+  rules: {},
+}

+ 2 - 0
08.src/Xingxi-mp/app.js

@@ -0,0 +1,2 @@
+// app.js
+App({})

+ 57 - 0
08.src/Xingxi-mp/app.json

@@ -0,0 +1,57 @@
+{
+  "pages": [
+    "pages/index/index",
+    "pages/all/all",
+    "pages/cart/cart",
+    "pages/my/my",
+    "pages/detail/detail",
+    "pages/login/login"
+  ],
+  "window": {
+    "backgroundColor": "#FFFFFF",
+    "backgroundTextStyle": "dark",
+    "navigationBarBackgroundColor": "#dfefec",
+    "navigationBarTitleText": "谷鹿鹿Q",
+    "navigationBarTextStyle": "black",
+    "pageOrientation": "portrait"
+  },
+  "style": "v2",
+  "renderer": "skyline",
+  "rendererOptions": {
+    "skyline": {
+      "defaultDisplayBlock": true,
+      "defaultContentBox": true,
+      "tagNameStyleIsolation": "legacy",
+      "disableABTest": true,
+      "sdkVersionBegin": "3.0.0",
+      "sdkVersionEnd": "15.255.255"
+    }
+  },
+  "componentFramework": "glass-easel",
+  "sitemapLocation": "sitemap.json",
+  "lazyCodeLoading": "requiredComponents",
+  "tabBar": {
+    "color": "#333333",
+    "selectedColor": "#8dbbb8",
+    "borderStyle": "white",
+    "backgroundColor": "#dfefec",
+    "list": [
+      {
+        "pagePath": "pages/index/index",
+        "text": "主页"
+      },
+      {
+        "pagePath": "pages/all/all",
+        "text": "全部商品"
+      },
+      {
+        "pagePath": "pages/cart/cart",
+        "text": "购物车"
+      },
+      {
+        "pagePath": "pages/my/my",
+        "text": "我的"
+      }
+    ]
+  }
+}

+ 1 - 0
08.src/Xingxi-mp/app.wxss

@@ -0,0 +1 @@
+/**app.wxss**/

+ 105 - 0
08.src/Xingxi-mp/components/navigation-bar/navigation-bar.js

@@ -0,0 +1,105 @@
+Component({
+  options: {
+    multipleSlots: true // 在组件定义时的选项中启用多slot支持
+  },
+  /**
+   * 组件的属性列表
+   */
+  properties: {
+    extClass: {
+      type: String,
+      value: ''
+    },
+    title: {
+      type: String,
+      value: ''
+    },
+    background: {
+      type: String,
+      value: ''
+    },
+    color: {
+      type: String,
+      value: ''
+    },
+    back: {
+      type: Boolean,
+      value: true
+    },
+    loading: {
+      type: Boolean,
+      value: false
+    },
+    homeButton: {
+      type: Boolean,
+      value: false,
+    },
+    animated: {
+      // 显示隐藏的时候opacity动画效果
+      type: Boolean,
+      value: true
+    },
+    show: {
+      // 显示隐藏导航,隐藏的时候navigation-bar的高度占位还在
+      type: Boolean,
+      value: true,
+      observer: '_showChange'
+    },
+    // back为true的时候,返回的页面深度
+    delta: {
+      type: Number,
+      value: 1
+    },
+  },
+  /**
+   * 组件的初始数据
+   */
+  data: {
+    displayStyle: ''
+  },
+  lifetimes: {
+    attached() {
+      const rect = wx.getMenuButtonBoundingClientRect()
+      wx.getSystemInfo({
+        success: (res) => {
+          const isAndroid = res.platform === 'android'
+          const isDevtools = res.platform === 'devtools'
+          this.setData({
+            ios: !isAndroid,
+            innerPaddingRight: `padding-right: ${res.windowWidth - rect.left}px`,
+            leftWidth: `width: ${res.windowWidth - rect.left }px`,
+            safeAreaTop: isDevtools || isAndroid ? `height: calc(var(--height) + ${res.safeArea.top}px); padding-top: ${res.safeArea.top}px` : ``
+          })
+        }
+      })
+    },
+  },
+  /**
+   * 组件的方法列表
+   */
+  methods: {
+    _showChange(show) {
+      const animated = this.data.animated
+      let displayStyle = ''
+      if (animated) {
+        displayStyle = `opacity: ${
+          show ? '1' : '0'
+        };transition:opacity 0.5s;`
+      } else {
+        displayStyle = `display: ${show ? '' : 'none'}`
+      }
+      this.setData({
+        displayStyle
+      })
+    },
+    back() {
+      const data = this.data
+      if (data.delta) {
+        wx.navigateBack({
+          delta: data.delta
+        })
+      }
+      this.triggerEvent('back', { delta: data.delta }, {})
+    }
+  },
+})

+ 5 - 0
08.src/Xingxi-mp/components/navigation-bar/navigation-bar.json

@@ -0,0 +1,5 @@
+{
+  "component": true,
+  "styleIsolation": "apply-shared",
+  "usingComponents": {}
+}

+ 64 - 0
08.src/Xingxi-mp/components/navigation-bar/navigation-bar.wxml

@@ -0,0 +1,64 @@
+<view class="weui-navigation-bar {{extClass}}">
+  <view class="weui-navigation-bar__inner {{ios ? 'ios' : 'android'}}" style="color: {{color}}; background: {{background}}; {{displayStyle}}; {{innerPaddingRight}}; {{safeAreaTop}};">
+
+    <!-- 左侧按钮 -->
+    <view class='weui-navigation-bar__left' style="{{leftWidth}};">
+      <block wx:if="{{back || homeButton}}">
+        <!-- 返回上一页 -->
+        <block wx:if="{{back}}">
+          <view class="weui-navigation-bar__buttons weui-navigation-bar__buttons_goback">
+            <view
+              bindtap="back"
+              class="weui-navigation-bar__btn_goback_wrapper"
+              hover-class="weui-active"
+              hover-stay-time="100"
+              aria-role="button"
+              aria-label="返回"
+            >
+              <view class="weui-navigation-bar__button weui-navigation-bar__btn_goback"></view>
+            </view>
+          </view>
+        </block>
+        <!-- 返回首页 -->
+        <block wx:if="{{homeButton}}">
+          <view class="weui-navigation-bar__buttons weui-navigation-bar__buttons_home">
+            <view
+              bindtap="home"
+              class="weui-navigation-bar__btn_home_wrapper"
+              hover-class="weui-active"
+              aria-role="button"
+              aria-label="首页"
+            >
+              <view class="weui-navigation-bar__button weui-navigation-bar__btn_home"></view>
+            </view>
+          </view>
+        </block>
+      </block>
+      <block wx:else>
+        <slot name="left"></slot>
+      </block>
+    </view>
+
+    <!-- 标题 -->
+    <view class='weui-navigation-bar__center'>
+      <view wx:if="{{loading}}" class="weui-navigation-bar__loading" aria-role="alert">
+        <view
+          class="weui-loading"
+          aria-role="img"
+          aria-label="加载中"
+        ></view>
+      </view>
+      <block wx:if="{{title}}">
+        <text>{{title}}</text>
+      </block>
+      <block wx:else>
+        <slot name="center"></slot>
+      </block>
+    </view>
+    
+    <!-- 右侧留空 -->
+    <view class='weui-navigation-bar__right'>
+      <slot name="right"></slot>
+    </view>
+  </view>
+</view>

+ 96 - 0
08.src/Xingxi-mp/components/navigation-bar/navigation-bar.wxss

@@ -0,0 +1,96 @@
+.weui-navigation-bar {
+  --weui-FG-0:rgba(0,0,0,.9);
+  --height: 44px;
+  --left: 16px;
+}
+.weui-navigation-bar .android {
+  --height: 48px;
+}
+
+.weui-navigation-bar {
+  overflow: hidden;
+  color: var(--weui-FG-0);
+  flex: none;
+}
+
+.weui-navigation-bar__inner {
+  position: relative;
+  top: 0;
+  left: 0;
+  height: calc(var(--height) + env(safe-area-inset-top));
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  padding-top: env(safe-area-inset-top);
+  width: 100%;
+  box-sizing: border-box;
+}
+
+.weui-navigation-bar__left {
+  position: relative;
+  padding-left: var(--left);
+  display: flex;
+  flex-direction: row;
+  align-items: flex-start;
+  height: 100%;
+  box-sizing: border-box;
+}
+
+.weui-navigation-bar__btn_goback_wrapper {
+  padding: 11px 18px 11px 16px;
+  margin: -11px -18px -11px -16px;
+}
+
+.weui-navigation-bar__btn_goback_wrapper.weui-active {
+  opacity: 0.5;
+}
+
+.weui-navigation-bar__btn_goback {
+  font-size: 12px;
+  width: 12px;
+  height: 24px;
+  -webkit-mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E  %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
+  mask: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E  %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
+  -webkit-mask-size: cover;
+  mask-size: cover;
+  background-color: var(--weui-FG-0);
+}
+
+.weui-navigation-bar__center {
+  font-size: 17px;
+  text-align: center;
+  position: relative;
+  display: flex;
+  flex-direction: row;
+  align-items: center;
+  justify-content: center;
+  font-weight: bold;
+  flex: 1;
+  height: 100%;
+}
+
+.weui-navigation-bar__loading {
+  margin-right: 4px;
+  align-items: center;
+}
+
+.weui-loading {
+  font-size: 16px;
+  width: 16px;
+  height: 16px;
+  display: block;
+  background: transparent url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg width='80px' height='80px' viewBox='0 0 80 80' version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E%3Ctitle%3Eloading%3C/title%3E%3Cdefs%3E%3ClinearGradient x1='94.0869141%25' y1='0%25' x2='94.0869141%25' y2='90.559082%25' id='linearGradient-1'%3E%3Cstop stop-color='%23606060' stop-opacity='0' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3ClinearGradient x1='100%25' y1='8.67370605%25' x2='100%25' y2='90.6286621%25' id='linearGradient-2'%3E%3Cstop stop-color='%23606060' offset='0%25'%3E%3C/stop%3E%3Cstop stop-color='%23606060' stop-opacity='0.3' offset='100%25'%3E%3C/stop%3E%3C/linearGradient%3E%3C/defs%3E%3Cg stroke='none' stroke-width='1' fill='none' fill-rule='evenodd' opacity='0.9'%3E%3Cg%3E%3Cpath d='M40,0 C62.09139,0 80,17.90861 80,40 C80,62.09139 62.09139,80 40,80 L40,73 C58.2253967,73 73,58.2253967 73,40 C73,21.7746033 58.2253967,7 40,7 L40,0 Z' fill='url(%23linearGradient-1)'%3E%3C/path%3E%3Cpath d='M40,0 L40,7 C21.7746033,7 7,21.7746033 7,40 C7,58.2253967 21.7746033,73 40,73 L40,80 C17.90861,80 0,62.09139 0,40 C0,17.90861 17.90861,0 40,0 Z' fill='url(%23linearGradient-2)'%3E%3C/path%3E%3Ccircle id='Oval' fill='%23606060' cx='40.5' cy='3.5' r='3.5'%3E%3C/circle%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A") no-repeat;
+  background-size: 100%;
+  margin-left: 0;
+  animation: loading linear infinite 1s;
+}
+
+@keyframes loading {
+  from {
+    transform: rotate(0);
+  }
+  to {
+    transform: rotate(360deg);
+  }
+}

BIN
08.src/Xingxi-mp/images/index/add-cart.png


BIN
08.src/Xingxi-mp/images/index/brand-item.png


BIN
08.src/Xingxi-mp/images/index/buy-now.png


BIN
08.src/Xingxi-mp/images/index/cart.png


BIN
08.src/Xingxi-mp/images/index/category-item.png


BIN
08.src/Xingxi-mp/images/index/hot-item.png


BIN
08.src/Xingxi-mp/images/index/logo.png


BIN
08.src/Xingxi-mp/images/index/search.png


+ 1 - 0
08.src/Xingxi-mp/pages/all/all.js

@@ -0,0 +1 @@
+Page({})

+ 4 - 0
08.src/Xingxi-mp/pages/all/all.json

@@ -0,0 +1,4 @@
+{
+  "navigationStyle": "custom",
+  "usingComponents": {}
+}

+ 3 - 0
08.src/Xingxi-mp/pages/all/all.wxml

@@ -0,0 +1,3 @@
+<view>
+  all
+</view>

+ 0 - 0
08.src/Xingxi-mp/pages/all/all.wxss


+ 1 - 0
08.src/Xingxi-mp/pages/cart/cart.js

@@ -0,0 +1 @@
+Page({})

+ 4 - 0
08.src/Xingxi-mp/pages/cart/cart.json

@@ -0,0 +1,4 @@
+{
+  "navigationStyle": "custom",
+  "usingComponents": {}
+}

+ 3 - 0
08.src/Xingxi-mp/pages/cart/cart.wxml

@@ -0,0 +1,3 @@
+<view>
+  cart
+</view>

+ 0 - 0
08.src/Xingxi-mp/pages/cart/cart.wxss


+ 1 - 0
08.src/Xingxi-mp/pages/detail/detail.js

@@ -0,0 +1 @@
+Page({})

+ 4 - 0
08.src/Xingxi-mp/pages/detail/detail.json

@@ -0,0 +1,4 @@
+{
+  "navigationStyle": "custom",
+  "usingComponents": {}
+}

+ 3 - 0
08.src/Xingxi-mp/pages/detail/detail.wxml

@@ -0,0 +1,3 @@
+<view>
+  detail
+</view>

+ 0 - 0
08.src/Xingxi-mp/pages/detail/detail.wxss


+ 84 - 0
08.src/Xingxi-mp/pages/index/index.js

@@ -0,0 +1,84 @@
+// index.js
+Component({
+  data: {
+    brandList: [
+      {
+        name: "全部IP",
+      },
+      {
+        name: "火影忍者",
+      },
+      {
+        name: "原神",
+      },
+      {
+        name: "柯南",
+      },
+      {
+        name: "非人哉",
+      },
+      {
+        name: "海贼王",
+      },
+      {
+        name: "初音",
+      },
+      {
+        name: "千与千寻",
+      },
+      {
+        name: "樱木花道",
+      },
+      {
+        name: "原神",
+      },
+    ],
+    categoryList: [
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+      {
+        name: "立绘",
+      },
+    ],
+    goodsList: [
+      {
+        name: "哪吒魔童闹海周边",
+        price: 49.5
+      },
+      {
+        name: "若来十二生肖盲盒 桌面手办",
+        price: 49.5
+      },
+      {
+        name: "官方正版姜子牙电影四不像",
+        price: 49.5
+      },
+      {
+        name: "若来十二生肖盲盒 十二节气祖国版",
+        price: 49.5
+      },
+    ],
+  },
+
+  methods: {
+  },
+})

+ 3 - 0
08.src/Xingxi-mp/pages/index/index.json

@@ -0,0 +1,3 @@
+{
+  "usingComponents": {}
+}

+ 68 - 0
08.src/Xingxi-mp/pages/index/index.wxml

@@ -0,0 +1,68 @@
+<!--index.wxml-->
+<view class="container">
+  <view class="header">
+    <view class="header-bg"></view>
+    <view class="logo logo-at-left">
+      <image src="/images/index/logo.png" class="logo-image"></image>
+    </view>
+    <view class="search-and-cart">
+      <view class="search">
+        <image src="/images/index/search.png" class="search-icon"></image>
+      </view>
+      <view class="cart">
+        <image src="/images/index/cart.png" class="cart-icon"></image>
+      </view>
+    </view>
+  </view>
+  <view class="banner">
+    <view class="banner-item">
+      banner
+    </view>
+  </view>
+  <view class="hot-bar">
+    <view class="hot-A">
+      <image src="/images/index/hot-item.png" class="hot-image"></image>
+    </view>
+    <view class="hot-B">
+      <image src="/images/index/hot-item.png" class="hot-image"></image>
+    </view>
+    <view class="hot-C">
+      <image src="/images/index/hot-item.png" class="hot-image"></image>
+    </view>
+  </view>
+  <view class="brand-bar">
+    <view wx:for="{{brandList}}" wx:key="index" class="brand-item">
+      <image src="/images/index/brand-item.png" class="brand-image"></image>
+      <!-- <text class="brand-name">{{item.name}}</text> -->
+    </view>
+  </view>
+  <view class="slider">
+    <view class="slider-item">
+      slider
+    </view>
+  </view>
+  <view class="category">
+    <view wx:for="{{categoryList}}" wx:key="index" class="category-item">
+      <image src="/images/index/category-item.png" class="category-image"></image>
+    </view>
+  </view>
+  <view class="goods">
+    <view wx:for="{{goodsList}}" wx:key="index" class="goods-item">
+      <view class="goods-image">
+        <!-- <image src="{{item.imageUrl}}" class="goods-image"></image> -->
+      </view>
+      <view class="goods-info">
+        <text class="goods-name">{{item.name}}</text>
+        <text class="goods-price">{{item.price}}</text>
+      </view>
+      <view class="goods-action">
+        <view class="favorite">
+          <!-- <image src="{{item.favoriteIcon}}" class="favorite-icon"></image> -->
+          fav
+        </view>
+        <button class="add-to-cart">Add to Cart</button>
+        <button class="buy-now">Buy Now</button>
+      </view>
+    </view>
+  </view>
+</view>

+ 132 - 0
08.src/Xingxi-mp/pages/index/index.wxss

@@ -0,0 +1,132 @@
+/**index.wxss**/
+page {
+  overflow-x: hidden;
+  overflow-y: scroll;
+  display: flex;
+  flex-direction: column;
+}
+
+.header {
+  height: 330rpx;
+  position: relative;
+}
+.header .header-bg {
+  z-index: 1;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 295rpx;
+  background: #dfefec;
+}
+.header .logo {
+  width: 150rpx;
+  height: 150rpx;
+  z-index: 99;
+}
+.header .logo.logo-at-left {
+  position: absolute;
+  top: 96rpx;
+  left: 36rpx;
+}
+.header .logo-image {
+  width: 100%;
+  height: 100%;
+}
+.header .search-icon {
+  position: absolute;
+  z-index: 99;
+  top: 260rpx;
+  left: 30rpx;
+  height: 65rpx;
+  width: 530rpx;
+}
+.header .cart-icon {
+  position: absolute;
+  z-index: 99;
+  top: 260rpx;
+  right: 30rpx;
+  height: 65rpx;
+  width: 146rpx;
+}
+
+.banner {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 24rpx 0 10rpx;
+}
+.banner .banner-item {
+  border: 1px solid #dfefec;
+  width: 690rpx;
+  height: 310rpx;
+  display: block;
+  border-radius: 25rpx;
+}
+.hot-bar {
+  padding: 14rpx 30rpx 10rpx;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: nowrap;
+  justify-content: space-between;
+  align-items: center;
+}
+.hot-bar .hot-image {
+  width: 220rpx;
+  height: 300rpx;
+}
+.brand-bar {
+  padding: 14rpx 30rpx 10rpx;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  justify-content: space-between;
+  align-items: center;
+}
+.brand-bar .brand-item {
+  width: 120rpx;
+  height: 120rpx;
+  margin-bottom: 20rpx;
+}
+.brand-bar .brand-item .brand-image {
+  width: 100%;
+  height: 100%;
+}
+.slider {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  padding: 24rpx 0 10rpx;
+}
+.slider .slider-item {
+  border: 1px solid #dfefec;
+  width: 690rpx;
+  height: 220rpx;
+  display: block;
+  border-radius: 25rpx;
+}
+.category {
+  height: 300rpx;
+  margin: 14rpx 30rpx 10rpx 30rpx;
+  border: 1px solid #dfefec;
+  border-radius: 25rpx;
+  padding: 20rpx;
+  display: flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+  justify-content: space-between;
+  align-items: center;
+}
+.category .category-item {
+  width: 144rpx;
+  height: 144rpx;
+  margin-bottom: 20rpx;
+}
+.category .category-item .category-image {
+  width: 100%;
+  height: 100%;
+}
+.goods {
+  min-height: 800rpx;
+  
+}

+ 1 - 0
08.src/Xingxi-mp/pages/login/login.js

@@ -0,0 +1 @@
+Page({})

+ 4 - 0
08.src/Xingxi-mp/pages/login/login.json

@@ -0,0 +1,4 @@
+{
+  "navigationStyle": "custom",
+  "usingComponents": {}
+}

+ 3 - 0
08.src/Xingxi-mp/pages/login/login.wxml

@@ -0,0 +1,3 @@
+<view>
+  login
+</view>

+ 0 - 0
08.src/Xingxi-mp/pages/login/login.wxss


+ 1 - 0
08.src/Xingxi-mp/pages/my/my.js

@@ -0,0 +1 @@
+Page({})

+ 4 - 0
08.src/Xingxi-mp/pages/my/my.json

@@ -0,0 +1,4 @@
+{
+  "navigationStyle": "custom",
+  "usingComponents": {}
+}

+ 3 - 0
08.src/Xingxi-mp/pages/my/my.wxml

@@ -0,0 +1,3 @@
+<view>
+  my
+</view>

+ 0 - 0
08.src/Xingxi-mp/pages/my/my.wxss


+ 28 - 0
08.src/Xingxi-mp/project.config.json

@@ -0,0 +1,28 @@
+{
+  "appid": "wx004d7a30f91ef286",
+  "compileType": "miniprogram",
+  "libVersion": "3.8.0",
+  "packOptions": {
+    "ignore": [],
+    "include": []
+  },
+  "setting": {
+    "coverView": true,
+    "es6": true,
+    "postcss": true,
+    "minified": true,
+    "enhance": true,
+    "showShadowRootInWxmlPanel": true,
+    "packNpmRelationList": [],
+    "babelSetting": {
+      "ignore": [],
+      "disablePlugins": [],
+      "outputPath": ""
+    }
+  },
+  "condition": {},
+  "editorSetting": {
+    "tabIndent": "insertSpaces",
+    "tabSize": 2
+  }
+}

+ 7 - 0
08.src/Xingxi-mp/project.private.config.json

@@ -0,0 +1,7 @@
+{
+  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
+  "projectname": "wx-mp-1",
+  "setting": {
+    "compileHotReLoad": true
+  }
+}

+ 7 - 0
08.src/Xingxi-mp/sitemap.json

@@ -0,0 +1,7 @@
+{
+    "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
+    "rules": [{
+    "action": "allow",
+    "page": "*"
+    }]
+}

+ 20 - 43
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/monitor/SysUserOnlineController.java

@@ -48,43 +48,30 @@ public class SysUserOnlineController extends BaseController {
     @RequiresPermissions("monitor:online:list")
     @PostMapping("/list")
     @ResponseBody
-    public TableDataInfo list(SysUserOnline userOnline)
-    {
+    public TableDataInfo list(SysUserOnline userOnline) {
         String ipaddr = userOnline.getIpaddr();
         String loginName = userOnline.getLoginName();
         TableDataInfo rspData = new TableDataInfo();
         Collection<Session> sessions = redisSessionDAO.getActiveSessions();
         Iterator<Session> it = sessions.iterator();
         List<SysUserOnline> sessionList = new ArrayList<SysUserOnline>();
-        while (it.hasNext())
-        {
+        while (it.hasNext()) {
             SysUserOnline user = getSession(it.next());
-            if (StringUtils.isNotNull(user))
-            {
-                if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(loginName))
-                {
+            if (StringUtils.isNotNull(user)) {
+                if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(loginName)) {
                     if (StringUtils.equals(ipaddr, user.getIpaddr())
-                            && StringUtils.equals(loginName, user.getLoginName()))
-                    {
+                            && StringUtils.equals(loginName, user.getLoginName())) {
                         sessionList.add(user);
                     }
-                }
-                else if (StringUtils.isNotEmpty(ipaddr))
-                {
-                    if (StringUtils.equals(ipaddr, user.getIpaddr()))
-                    {
+                } else if (StringUtils.isNotEmpty(ipaddr)) {
+                    if (StringUtils.equals(ipaddr, user.getIpaddr())) {
                         sessionList.add(user);
                     }
-                }
-                else if (StringUtils.isNotEmpty(loginName))
-                {
-                    if (StringUtils.equals(loginName, user.getLoginName()))
-                    {
+                } else if (StringUtils.isNotEmpty(loginName)) {
+                    if (StringUtils.equals(loginName, user.getLoginName())) {
                         sessionList.add(user);
                     }
-                }
-                else
-                {
+                } else {
                     sessionList.add(user);
                 }
             }
@@ -98,14 +85,11 @@ public class SysUserOnlineController extends BaseController {
     @Log(title = "在线用户", businessType = BusinessType.FORCE)
     @PostMapping("/batchForceLogout")
     @ResponseBody
-    public AjaxResult batchForceLogout(@RequestBody List<SysUserOnline> sysUserOnlines)
-    {
-        for (SysUserOnline userOnline : sysUserOnlines)
-        {
+    public AjaxResult batchForceLogout(@RequestBody List<SysUserOnline> sysUserOnlines) {
+        for (SysUserOnline userOnline : sysUserOnlines) {
             String sessionId = userOnline.getSessionId();
             String loginName = userOnline.getLoginName();
-            if (sessionId.equals(ShiroUtils.getSessionId()))
-            {
+            if (sessionId.equals(ShiroUtils.getSessionId())) {
                 return error("当前登录用户无法强退");
             }
             redisSessionDAO.delete(redisSessionDAO.readSession(sessionId));
@@ -114,25 +98,20 @@ public class SysUserOnlineController extends BaseController {
         return success();
     }
 
-    private SysUserOnline getSession(Session session)
-    {
+    private SysUserOnline getSession(Session session) {
         Object obj = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
-        if (null == obj)
-        {
+        if (null == obj) {
             return null;
         }
-        if (obj instanceof SimplePrincipalCollection)
-        {
+        if (obj instanceof SimplePrincipalCollection) {
             SimplePrincipalCollection spc = (SimplePrincipalCollection) obj;
             obj = spc.getPrimaryPrincipal();
-            if (null != obj && obj instanceof SysUser)
-            {
+            if (obj instanceof SysUser) {
                 SysUser sysUser = (SysUser) obj;
                 SysUserOnline userOnline = new SysUserOnline();
                 userOnline.setSessionId(session.getId().toString());
                 userOnline.setLoginName(sysUser.getLoginName());
-                if (StringUtils.isNotNull(sysUser.getDept()) && StringUtils.isNotEmpty(sysUser.getDept().getDeptName()))
-                {
+                if (StringUtils.isNotNull(sysUser.getDept()) && StringUtils.isNotEmpty(sysUser.getDept().getDeptName())) {
                     userOnline.setDeptName(sysUser.getDept().getDeptName());
                 }
                 userOnline.setIpaddr(session.getHost());
@@ -144,12 +123,10 @@ public class SysUserOnlineController extends BaseController {
         return null;
     }
 
-    public void removeUserCache(String loginName, String sessionId)
-    {
+    public void removeUserCache(String loginName, String sessionId) {
         Cache<String, Deque<Serializable>> cache = SpringUtils.getBean(RedisCacheManager.class).getCache(ShiroConstants.SYS_USERCACHE);
         Deque<Serializable> deque = cache.get(loginName);
-        if (StringUtils.isEmpty(deque) || deque.size() == 0)
-        {
+        if (StringUtils.isEmpty(deque) || deque.size() == 0) {
             return;
         }
         deque.remove(sessionId);

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysCaptchaController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysCaptchaController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.awt.image.BufferedImage;
 import java.io.IOException;

+ 2 - 2
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysConfigController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysConfigController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.util.List;
 
@@ -130,7 +130,7 @@ public class SysConfigController extends BaseController {
     @GetMapping("/refreshCache")
     @ResponseBody
     public AjaxResult refreshCache() {
-//        configService.resetConfigCache();
+        configService.resetConfigCache();
         return success();
     }
 

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysDeptController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysDeptController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.util.List;
 

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysDictDataController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysDictDataController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.util.List;
 

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysDictTypeController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysDictTypeController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.util.List;
 

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysFileUploadController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysFileUploadController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import com.xingxi.common.core.controller.BaseController;
 import com.xingxi.common.core.domain.AjaxResult;

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysIndexController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysIndexController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.util.Date;
 import java.util.List;

+ 19 - 27
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysLoginController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysLoginController.java

@@ -1,7 +1,11 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import com.xingxi.common.core.controller.BaseController;
+import com.xingxi.common.core.domain.AjaxResult;
+import com.xingxi.common.core.text.Convert;
+import com.xingxi.common.utils.ServletUtils;
+import com.xingxi.common.utils.StringUtils;
+import com.xingxi.framework.web.service.ConfigService;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.UsernamePasswordToken;
@@ -13,21 +17,17 @@ import org.springframework.ui.ModelMap;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
-import com.xingxi.common.core.controller.BaseController;
-import com.xingxi.common.core.domain.AjaxResult;
-import com.xingxi.common.core.text.Convert;
-import com.xingxi.common.utils.ServletUtils;
-import com.xingxi.common.utils.StringUtils;
-import com.xingxi.framework.web.service.ConfigService;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 
 /**
  * 登录验证
- * 
+ *
  * @author ruoyi
  */
 @Controller
-public class SysLoginController extends BaseController
-{
+public class SysLoginController extends BaseController {
     /**
      * 是否开启记住我功能
      */
@@ -38,11 +38,9 @@ public class SysLoginController extends BaseController
     private ConfigService configService;
 
     @GetMapping("/login")
-    public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap)
-    {
+    public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap) {
         // 如果是Ajax请求,返回Json字符串。
-        if (ServletUtils.isAjaxRequest(request))
-        {
+        if (ServletUtils.isAjaxRequest(request)) {
             return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
         }
         // 是否开启记住我
@@ -54,20 +52,15 @@ public class SysLoginController extends BaseController
 
     @PostMapping("/login")
     @ResponseBody
-    public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe)
-    {
+    public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe) {
         UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
         Subject subject = SecurityUtils.getSubject();
-        try
-        {
+        try {
             subject.login(token);
             return success();
-        }
-        catch (AuthenticationException e)
-        {
+        } catch (AuthenticationException e) {
             String msg = "用户或密码错误";
-            if (StringUtils.isNotEmpty(e.getMessage()))
-            {
+            if (StringUtils.isNotEmpty(e.getMessage())) {
                 msg = e.getMessage();
             }
             return error(msg);
@@ -75,8 +68,7 @@ public class SysLoginController extends BaseController
     }
 
     @GetMapping("/unauth")
-    public String unauth()
-    {
+    public String unauth() {
         return "error/unauth";
     }
 }

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysMenuController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysMenuController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.util.List;
 

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysNoticeController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysNoticeController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.util.List;
 

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysPostController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysPostController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.util.List;
 

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysProfileController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysProfileController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysRegisterController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysRegisterController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysRoleController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysRoleController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.util.List;
 

+ 1 - 1
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/SysUserController.java → 08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/controller/SysUserController.java

@@ -1,4 +1,4 @@
-package com.xingxi.web.controller.system;
+package com.xingxi.web.controller.system.controller;
 
 import java.util.List;
 import java.util.stream.Collectors;

+ 13 - 0
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/service/ISysConfigVoService.java

@@ -0,0 +1,13 @@
+package com.xingxi.web.controller.system.service;
+
+/**
+ * 参数配置 服务层
+ *
+ * @author xingxi
+ */
+public interface ISysConfigVoService {
+    /**
+     * 加载参数缓存数据
+     */
+    void loadingConfigCache();
+}

+ 13 - 0
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/service/ISysDictTypeVoService.java

@@ -0,0 +1,13 @@
+package com.xingxi.web.controller.system.service;
+
+/**
+ * 字典 业务层
+ *
+ * @author xingxi
+ */
+public interface ISysDictTypeVoService {
+    /**
+     * 加载字典缓存数据
+     */
+    void loadingDictCache();
+}

+ 55 - 0
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/service/impl/SysConfigVoServiceImpl.java

@@ -0,0 +1,55 @@
+package com.xingxi.web.controller.system.service.impl;
+
+import com.xingxi.common.constant.Constants;
+import com.xingxi.common.core.redis.RedisCache;
+import com.xingxi.system.domain.SysConfig;
+import com.xingxi.system.mapper.SysConfigMapper;
+import com.xingxi.web.controller.system.service.ISysConfigVoService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 参数配置 服务层实现
+ *
+ * @author biandan
+ */
+@Service
+public class SysConfigVoServiceImpl implements ISysConfigVoService {
+    @Resource
+    private SysConfigMapper configMapper;
+
+    @Resource
+    private RedisCache redisCache;
+
+    /**
+     * 项目启动时,初始化参数到缓存
+     */
+    @PostConstruct
+    public void init() {
+        loadingConfigCache();
+    }
+
+    /**
+     * 加载参数缓存数据
+     */
+    @Override
+    public void loadingConfigCache() {
+        List<SysConfig> configsList = configMapper.selectConfigList(new SysConfig());
+        for (SysConfig config : configsList) {
+            redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
+        }
+    }
+
+    /**
+     * 设置cache key
+     *
+     * @param configKey 参数键
+     * @return 缓存键key
+     */
+    private String getCacheKey(String configKey) {
+        return Constants.SYS_CONFIG_KEY + configKey;
+    }
+}

+ 46 - 0
08.src/Xingxi/xingxi-admin/src/main/java/com/xingxi/web/controller/system/service/impl/SysDictTypeVoServiceImpl.java

@@ -0,0 +1,46 @@
+package com.xingxi.web.controller.system.service.impl;
+
+import com.xingxi.common.core.domain.entity.SysDictData;
+import com.xingxi.common.utils.DictUtils;
+import com.xingxi.system.mapper.SysDictDataMapper;
+import com.xingxi.web.controller.system.service.ISysDictTypeVoService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 字典 业务层处理
+ *
+ * @author xingxi
+ */
+@Service
+public class SysDictTypeVoServiceImpl implements ISysDictTypeVoService {
+    @Resource
+    private SysDictDataMapper dictDataMapper;
+
+    /**
+     * 项目启动时,初始化字典到缓存
+     */
+    @PostConstruct
+    public void init() {
+        loadingDictCache();
+    }
+
+    /**
+     * 加载字典缓存数据
+     */
+    @Override
+    public void loadingDictCache() {
+        SysDictData dictData = new SysDictData();
+        dictData.setStatus("0");
+        Map<String, List<SysDictData>> dictDataMap = dictDataMapper.selectDictDataList(dictData).stream().collect(Collectors.groupingBy(SysDictData::getDictType));
+        for (Map.Entry<String, List<SysDictData>> entry : dictDataMap.entrySet()) {
+            DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList()));
+        }
+    }
+}

+ 13 - 0
08.src/Xingxi/xingxi-admin/src/main/resources/application-local.yml

@@ -66,6 +66,19 @@ spring:
                 wall:
                     config:
                         multi-statement-allow: true
+    # redis配置
+    redis:
+        database: 0
+        host: redis.njnet.vip
+        port: 6379
+        password: Biandan123
+        timeout: 6000ms           # 连接超时时长(毫秒)
+        lettuce:
+            pool:
+                max-active: 1000  # 连接池最大连接数(使用负值表示没有限制)
+                max-wait: -1ms    # 连接池最大阻塞等待时间(使用负值表示没有限制)
+                max-idle: 10      # 连接池中的最大空闲连接
+                min-idle: 5       # 连接池中的最小空闲连接
 idworkcfg:
     workerId: "2"
     dataCenterId: "2"

+ 44 - 0
08.src/Xingxi/xingxi-admin/src/main/resources/templates/master/product/prodAttr/add.html

@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
+<head>
+    <th:block th:include="include :: header(#{prodProp.header})" />
+</head>
+<body class="white-bg">
+    <div class="wrapper wrapper-content animated fadeInRight ibox-content">
+        <form class="form-horizontal m" id="form-prodProp-add">
+            <div class="tabs-container">
+                <ul class="nav nav-tabs">
+                    <li class="active" id="selectProp"><a data-toggle="tab" href="#tab-1" aria-expanded="true"> 选择属性</a>
+                    </li>
+                    <li class="" id="inputProp"><a data-toggle="tab" href="#tab-2" aria-expanded="false"> 手工增加</a>
+                    </li>
+                </ul>
+                <div class="tab-content">
+                    <div id="tab-1" class="tab-pane active">
+                        <div class="panel-body">
+                            <div class="col-sm-12 select-table table-striped">
+                                <table id="bootstrap-table"></table>
+                            </div>
+                        </div>
+                    </div>
+                    <div id="tab-2" class="tab-pane">
+                        <div class="panel-body">
+                            <div class="form-group">
+                                <label class="col-sm-3 control-label is-required">[[#{prop.propName}]]:</label>
+                                <div class="col-sm-8">
+                                    <textarea rows = "6" style="OVERFLOW:visible" class="form-control" id="propName" name="propName" placeholder="属性名称" required></textarea>
+                                    <label class="control-label">如有多个,请每行写一个。请勿输入“/”,“/”会被自动转换为“-”</label>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+    <th:block th:include="include :: footer" />
+    <script th:src="@{/biandan/product/prodProp/add.js?v=2.0}"></script>
+    <script th:inline="javascript">
+    </script>
+</body>
+</html>

+ 26 - 0
08.src/Xingxi/xingxi-admin/src/main/resources/templates/master/product/prodAttr/edit.html

@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html lang="zh" xmlns:th="http://www.thymeleaf.org" >
+<head>
+    <th:block th:include="include :: header(#{prodProp.header.edit})" />
+</head>
+<body class="white-bg">
+    <div class="wrapper wrapper-content animated fadeInRight ibox-content">
+        <form class="form-horizontal m" id="form-prodProp-edit" th:object="${prodProp}">
+            <input name="propId" th:field="*{propId}" type="hidden">
+            <div class="form-group">    
+                <label class="col-sm-3 control-label is-required">[[#{prodProp.propName}]]:</label>
+                <div class="col-sm-8">
+                    <input name="propName" th:field="*{propName}" class="form-control" type="text" required>
+                </div>
+            </div>
+            <input name="updateTime" th:value="${#dates.format(prodProp.updateTime, 'yyyy-MM-dd HH:mm:ss')}" type="hidden">
+        </form>
+    </div>
+    <th:block th:include="include :: footer" />
+    <script th:src="@{/biandan/product/prodProp/edit.js?v=2.0}"></script>
+
+    <script th:inline="javascript">
+
+    </script>
+</body>
+</html>

+ 58 - 0
08.src/Xingxi/xingxi-admin/src/main/resources/templates/master/product/prodAttr/prodAttr.html

@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html lang="zh" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
+<head>
+    <th:block th:include="include :: header(#{prodProp.header.list})" />
+</head>
+<body class="gray-bg">
+     <div class="container-div">
+        <div class="row">
+            <div class="col-sm-12 search-collapse">
+                <form id="formId">
+                    <div class="select-list">
+                        <ul>
+                            <li>
+                                <label>[[#{prodProp.prodId}]]:</label>
+                                <input type="text" name="prodId"/>
+                            </li>
+                            <li>
+                                <label>[[#{prodProp.propName}]]:</label>
+                                <input type="text" name="propName"/>
+                            </li>
+                            <li>
+                                <label>[[#{prodProp.sort}]]:</label>
+                                <input type="text" name="sort"/>
+                            </li>
+                            <li>
+                                <label>[[#{prodProp.delFlag}]]:</label>
+                                <input type="text" name="delFlag"/>
+                            </li>
+                            <li>
+                                <a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;[[#{btn.search}]]</a>
+                                <a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;[[#{btn.reset}]]</a>
+                            </li>
+                        </ul>
+                    </div>
+                </form>
+            </div>
+
+            <div class="btn-group-sm" id="toolbar" role="group">
+                <a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="product:prodProp:add">
+                    <i class="fa fa-plus"></i> [[#{btn.add}]]
+                </a>
+                <a class="btn btn-primary single disabled" onclick="$.operate.edit()" shiro:hasPermission="product:prodProp:edit">
+                    <i class="fa fa-edit"></i> [[#{btn.modify}]]
+                </a>
+            </div>
+            <div class="col-sm-12 select-table table-striped">
+                <table id="bootstrap-table"></table>
+            </div>
+        </div>
+    </div>
+    <th:block th:include="include :: footer" />
+    <script th:inline="javascript">
+        var editFlag = [[${@permission.hasPermi('product:prodProp:edit')}]];
+        var removeFlag = [[${@permission.hasPermi('product:prodProp:remove')}]];
+        var prefix = ctx + "master/product/prodAttr";
+    </script>
+</body>
+</html>

+ 5 - 0
08.src/Xingxi/xingxi-admin/src/main/resources/templates/master/tag/tag.html

@@ -36,8 +36,13 @@
                 removeUrl: prefix + "/remove",
                 exportUrl: prefix + "/export",
                 modalName: "用户避雷标签",
+                showSearch: false,
+                showToggle: false,
                 columns: [
                     {
+                        checkbox: true
+                    },
+                    {
                         field: 'tagName',
                         title: '标签名称'
                     },

+ 20 - 45
08.src/Xingxi/xingxi-framework/src/main/java/com/xingxi/framework/shiro/realm/UserRealm.java

@@ -2,6 +2,7 @@ package com.xingxi.framework.shiro.realm;
 
 import java.util.HashSet;
 import java.util.Set;
+
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
@@ -34,11 +35,10 @@ import com.xingxi.system.service.ISysRoleService;
 
 /**
  * 自定义Realm 处理登录 权限
- * 
+ *
  * @author ruoyi
  */
-public class UserRealm extends AuthorizingRealm
-{
+public class UserRealm extends AuthorizingRealm {
     private static final Logger log = LoggerFactory.getLogger(UserRealm.class);
 
     @Autowired
@@ -54,8 +54,7 @@ public class UserRealm extends AuthorizingRealm
      * 授权
      */
     @Override
-    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0)
-    {
+    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
         SysUser user = ShiroUtils.getSysUser();
         // 角色列表
         Set<String> roles = new HashSet<String>();
@@ -63,13 +62,10 @@ public class UserRealm extends AuthorizingRealm
         Set<String> menus = new HashSet<String>();
         SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
         // 管理员拥有所有权限
-        if (user.isAdmin())
-        {
+        if (user.isAdmin()) {
             info.addRole("admin");
             info.addStringPermission("*:*:*");
-        }
-        else
-        {
+        } else {
             roles = roleService.selectRoleKeys(user.getUserId());
             menus = menuService.selectPermsByUserId(user.getUserId());
             // 角色加入AuthorizationInfo认证对象
@@ -84,47 +80,30 @@ public class UserRealm extends AuthorizingRealm
      * 登录认证
      */
     @Override
-    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
-    {
+    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
         UsernamePasswordToken upToken = (UsernamePasswordToken) token;
         String username = upToken.getUsername();
         String password = "";
-        if (upToken.getPassword() != null)
-        {
+        if (upToken.getPassword() != null) {
             password = new String(upToken.getPassword());
         }
 
         SysUser user = null;
-        try
-        {
+        try {
             user = loginService.login(username, password);
-        }
-        catch (CaptchaException e)
-        {
+        } catch (CaptchaException e) {
             throw new AuthenticationException(e.getMessage(), e);
-        }
-        catch (UserNotExistsException e)
-        {
+        } catch (UserNotExistsException e) {
             throw new UnknownAccountException(e.getMessage(), e);
-        }
-        catch (UserPasswordNotMatchException e)
-        {
+        } catch (UserPasswordNotMatchException e) {
             throw new IncorrectCredentialsException(e.getMessage(), e);
-        }
-        catch (UserPasswordRetryLimitExceedException e)
-        {
+        } catch (UserPasswordRetryLimitExceedException e) {
             throw new ExcessiveAttemptsException(e.getMessage(), e);
-        }
-        catch (UserBlockedException e)
-        {
+        } catch (UserBlockedException e) {
             throw new LockedAccountException(e.getMessage(), e);
-        }
-        catch (RoleBlockedException e)
-        {
+        } catch (RoleBlockedException e) {
             throw new LockedAccountException(e.getMessage(), e);
-        }
-        catch (Exception e)
-        {
+        } catch (Exception e) {
             log.info("对用户[" + username + "]进行登录验证..验证未通过{}", e.getMessage());
             throw new AuthenticationException(e.getMessage(), e);
         }
@@ -135,8 +114,7 @@ public class UserRealm extends AuthorizingRealm
     /**
      * 清理指定用户授权信息缓存
      */
-    public void clearCachedAuthorizationInfo(Object principal)
-    {
+    public void clearCachedAuthorizationInfo(Object principal) {
         SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
         this.clearCachedAuthorizationInfo(principals);
     }
@@ -144,13 +122,10 @@ public class UserRealm extends AuthorizingRealm
     /**
      * 清理所有用户授权信息缓存
      */
-    public void clearAllCachedAuthorizationInfo()
-    {
+    public void clearAllCachedAuthorizationInfo() {
         Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
-        if (cache != null)
-        {
-            for (Object key : cache.keys())
-            {
+        if (cache != null) {
+            for (Object key : cache.keys()) {
                 cache.remove(key);
             }
         }

+ 15 - 0
08.src/Xingxi/xingxi-system/src/main/java/com/xingxi/master/tag/service/impl/TagServiceImpl.java

@@ -2,8 +2,11 @@ package com.xingxi.master.tag.service.impl;
 
 import com.xingxi.common.core.text.Convert;
 import com.xingxi.common.enums.EDelFlag;
+import com.xingxi.common.exception.BusinessException;
 import com.xingxi.common.utils.DateUtils;
 import com.xingxi.common.utils.ShiroUtils;
+import com.xingxi.master.product.domain.ProdTag;
+import com.xingxi.master.product.mapper.ProdTagMapper;
 import com.xingxi.master.tag.domain.Tag;
 import com.xingxi.master.tag.mapper.TagMapper;
 import com.xingxi.master.tag.service.ITagService;
@@ -22,6 +25,8 @@ import java.util.List;
 public class TagServiceImpl implements ITagService {
     @Resource
     private TagMapper tagMapper;
+    @Resource
+    private ProdTagMapper prodTagMapper;
 
     /**
      * 查询标签
@@ -125,6 +130,16 @@ public class TagServiceImpl implements ITagService {
      */
     @Override
     public int logicDeleteTagByTagIds(String tagIds) {
+        String[] ids = Convert.toStrArray(tagIds);
+        for (String id : ids) {
+            ProdTag cond = new ProdTag();
+            cond.setTagId(Long.parseLong(id));
+            cond.setDelFlag(EDelFlag.NO.getVal());
+            List<ProdTag> prodTagList = prodTagMapper.selectProdTagList(cond);
+            if (prodTagList.size() > 0) {
+                throw new BusinessException("标签使用中,不能删除");
+            }
+        }
         return tagMapper.logicDeleteTagByTagIds(Convert.toStrArray(tagIds));
     }