wang_xy 1 سال پیش
والد
کامیت
593292f488
34فایلهای تغییر یافته به همراه497 افزوده شده و 16906 حذف شده
  1. 0 21
      node_modules/sortablejs/LICENSE
  2. 0 813
      node_modules/sortablejs/README.md
  3. 0 3709
      node_modules/sortablejs/Sortable.js
  4. 0 2
      node_modules/sortablejs/Sortable.min.js
  5. 0 3701
      node_modules/sortablejs/modular/sortable.complete.esm.js
  6. 0 3698
      node_modules/sortablejs/modular/sortable.core.esm.js
  7. 0 3699
      node_modules/sortablejs/modular/sortable.esm.js
  8. 0 91
      node_modules/sortablejs/package.json
  9. 0 21
      node_modules/vuedraggable/LICENSE
  10. 0 387
      node_modules/vuedraggable/README.md
  11. 0 123
      node_modules/vuedraggable/package.json
  12. 0 36
      node_modules/vuedraggable/src/util/helper.js
  13. 0 75
      node_modules/vuedraggable/src/vuedraggable.d.ts
  14. 0 485
      node_modules/vuedraggable/src/vuedraggable.js
  15. 7 0
      pom.xml
  16. 5 0
      ruoyi-admin/pom.xml
  17. 2 2
      ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
  18. 21 8
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
  19. 1 1
      ruoyi-admin/src/main/resources/application.yml
  20. 79 0
      ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/WxUser.java
  21. 14 4
      ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java
  22. 5 1
      ruoyi-framework/pom.xml
  23. 4 4
      ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
  24. 7 4
      ruoyi-framework/src/main/java/com/ruoyi/framework/db/factory/CustomMetaObjectHandler.java
  25. 64 16
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java
  26. 15 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
  27. 1 5
      ruoyi-quartz/pom.xml
  28. 14 0
      sooka-jnb/src/main/java/com/sooka/jnb/mapper/WxUserMapper.java
  29. 5 0
      sooka-jnb/src/main/java/com/sooka/jnb/service/WxUserService.java
  30. 12 0
      sooka-jnb/src/main/java/com/sooka/jnb/service/impl/WxUserServiceImpl.java
  31. 178 0
      sooka-jnb/src/main/java/com/sooka/jnb/utils/HttpClientUtil.java
  32. 26 0
      sooka-jnb/src/main/java/com/sooka/jnb/utils/PayUtils.java
  33. 27 0
      sooka-jnb/src/main/java/com/sooka/jnb/utils/WechatUtil.java
  34. 10 0
      sooka-jnb/src/main/resources/mapper/WxUserMapper.xml

+ 0 - 21
node_modules/sortablejs/LICENSE

@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019 All contributors to Sortable
-
-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.

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 813
node_modules/sortablejs/README.md


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 3709
node_modules/sortablejs/Sortable.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 2
node_modules/sortablejs/Sortable.min.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 3701
node_modules/sortablejs/modular/sortable.complete.esm.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 3698
node_modules/sortablejs/modular/sortable.core.esm.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 3699
node_modules/sortablejs/modular/sortable.esm.js


+ 0 - 91
node_modules/sortablejs/package.json

@@ -1,91 +0,0 @@
-{
-  "_from": "sortablejs@1.10.2",
-  "_id": "sortablejs@1.10.2",
-  "_inBundle": false,
-  "_integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A==",
-  "_location": "/sortablejs",
-  "_phantomChildren": {},
-  "_requested": {
-    "type": "version",
-    "registry": true,
-    "raw": "sortablejs@1.10.2",
-    "name": "sortablejs",
-    "escapedName": "sortablejs",
-    "rawSpec": "1.10.2",
-    "saveSpec": null,
-    "fetchSpec": "1.10.2"
-  },
-  "_requiredBy": [
-    "/vuedraggable"
-  ],
-  "_resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
-  "_shasum": "6e40364d913f98b85a14f6678f92b5c1221f5290",
-  "_spec": "sortablejs@1.10.2",
-  "_where": "D:\\sjkj\\sooka_internal_oa\\node_modules\\vuedraggable",
-  "bugs": {
-    "url": "https://github.com/SortableJS/Sortable/issues"
-  },
-  "bundleDependencies": false,
-  "deprecated": false,
-  "description": "JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices. No jQuery required. Supports Meteor, AngularJS, React, Polymer, Vue, Knockout and any CSS library, e.g. Bootstrap.",
-  "devDependencies": {
-    "@babel/core": "^7.4.4",
-    "@babel/plugin-transform-object-assign": "^7.2.0",
-    "@babel/preset-env": "^7.4.4",
-    "rollup": "^1.11.3",
-    "rollup-plugin-babel": "^4.3.2",
-    "rollup-plugin-json": "^4.0.0",
-    "rollup-plugin-node-resolve": "^5.0.0",
-    "testcafe": "^1.3.1",
-    "testcafe-browser-provider-saucelabs": "^1.7.0",
-    "testcafe-reporter-xunit": "^2.1.0",
-    "uglify-js": "^3.5.12"
-  },
-  "exportName": "Sortable",
-  "files": [
-    "Sortable.js",
-    "Sortable.min.js",
-    "modular/"
-  ],
-  "homepage": "https://github.com/SortableJS/Sortable#readme",
-  "keywords": [
-    "sortable",
-    "reorder",
-    "drag",
-    "meteor",
-    "angular",
-    "ng-sortable",
-    "react",
-    "vue",
-    "mixin"
-  ],
-  "license": "MIT",
-  "main": "./Sortable.js",
-  "maintainers": [
-    {
-      "name": "Konstantin Lebedev",
-      "email": "ibnRubaXa@gmail.com"
-    },
-    {
-      "name": "Owen Mills",
-      "email": "owen23355@gmail.com"
-    }
-  ],
-  "module": "modular/sortable.esm.js",
-  "name": "sortablejs",
-  "repository": {
-    "type": "git",
-    "url": "git://github.com/SortableJS/Sortable.git"
-  },
-  "scripts": {
-    "build": "npm run build:es && npm run build:umd && npm run minify",
-    "build:es": "set NODE_ENV=es&& rollup -c ./scripts/esm-build.js",
-    "build:es:watch": "set NODE_ENV=es&& rollup -w -c ./scripts/esm-build.js",
-    "build:umd": "NODE_ENV=umd rollup -c ./scripts/umd-build.js",
-    "build:umd:watch": "set NODE_ENV=umd&& rollup -w -c ./scripts/umd-build.js",
-    "minify": "node ./scripts/minify.js",
-    "test": "node ./scripts/test.js",
-    "test:compat": "node ./scripts/test-compat.js"
-  },
-  "version": "1.10.2"
-}

+ 0 - 21
node_modules/vuedraggable/LICENSE

@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2016-2019 David Desmaisons
-
-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.

+ 0 - 387
node_modules/vuedraggable/README.md

@@ -1,387 +0,0 @@
-<p align="center"><img width="140"src="https://raw.githubusercontent.com/SortableJS/Vue.Draggable/master/logo.svg?sanitize=true"></p>
-<h1 align="center">Vue.Draggable</h1>
-
-[![CircleCI](https://circleci.com/gh/SortableJS/Vue.Draggable.svg?style=shield)](https://circleci.com/gh/SortableJS/Vue.Draggable)
-[![Coverage](https://codecov.io/gh/SortableJS/Vue.Draggable/branch/master/graph/badge.svg)](https://codecov.io/gh/SortableJS/Vue.Draggable)
-[![codebeat badge](https://codebeat.co/badges/7a6c27c8-2d0b-47b9-af55-c2eea966e713)](https://codebeat.co/projects/github-com-sortablejs-vue-draggable-master)
-[![GitHub open issues](https://img.shields.io/github/issues/SortableJS/Vue.Draggable.svg)](https://github.com/SortableJS/Vue.Draggable/issues?q=is%3Aopen+is%3Aissue)
-[![npm download](https://img.shields.io/npm/dt/vuedraggable.svg?maxAge=30)](https://www.npmjs.com/package/vuedraggable)
-[![npm download per month](https://img.shields.io/npm/dm/vuedraggable.svg)](https://www.npmjs.com/package/vuedraggable)
-[![npm version](https://img.shields.io/npm/v/vuedraggable.svg)](https://www.npmjs.com/package/vuedraggable)
-[![MIT License](https://img.shields.io/github/license/SortableJS/Vue.Draggable.svg)](https://github.com/SortableJS/Vue.Draggable/blob/master/LICENSE)
-
-
-Vue component (Vue.js 2.0) or directive (Vue.js 1.0) allowing drag-and-drop and synchronization with view model array.
-
-Based on and offering all features of [Sortable.js](https://github.com/RubaXa/Sortable)
-
-## Demo
-
-![demo gif](https://raw.githubusercontent.com/SortableJS/Vue.Draggable/master/example.gif)
-
-## Live Demos
-
-https://sortablejs.github.io/Vue.Draggable/
-
-https://david-desmaisons.github.io/draggable-example/
-
-## Features
-
-* Full support of [Sortable.js](https://github.com/RubaXa/Sortable) features:
-    * Supports touch devices
-    * Supports drag handles and selectable text
-    * Smart auto-scrolling
-    * Support drag and drop between different lists
-    * No jQuery dependency
-* Keeps in sync HTML and view model list
-* Compatible with Vue.js 2.0 transition-group
-* Cancellation support
-* Events reporting any changes when full control is needed
-* Reuse existing UI library components (such as [vuetify](https://vuetifyjs.com), [element](http://element.eleme.io/), or [vue material](https://vuematerial.io) etc...) and make them draggable using `tag` and `componentData` props
-
-## Backers
-
- <a href="https://flatlogic.com/admin-dashboards">
- <img width="190" style="margin-top: 10px;" src="https://flatlogic.com/assets/logo-d9e7751df5fddd11c911945a75b56bf72bcfe809a7f6dca0e32d7b407eacedae.svg">
- </a>
-
-Admin Dashboard Templates made with Vue, React and Angular.
-
-
-## Donate
-
-Find this project useful? You can buy me a :coffee: or a :beer:
-
-[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=GYAEKQZJ4FQT2&currency_code=USD&source=url)
-
-
-## Installation
-
-### With npm or yarn 
-
-```bash
-yarn add vuedraggable
-
-npm i -S vuedraggable
-```
-
-**Beware it is vuedraggable for Vue 2.0 and not vue-draggable which is for version 1.0**
-
-### with direct link 
-```html
-
-<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
-<!-- CDNJS :: Sortable (https://cdnjs.com/) -->
-<script src="//cdn.jsdelivr.net/npm/sortablejs@1.8.4/Sortable.min.js"></script>
-<!-- CDNJS :: Vue.Draggable (https://cdnjs.com/) -->
-<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.20.0/vuedraggable.umd.min.js"></script>
-
-```
-
-[cf example section](https://github.com/SortableJS/Vue.Draggable/tree/master/example)
-
-## For Vue.js 2.0
-
-Use draggable component:
-
-### Typical use:
-``` html
-<draggable v-model="myArray" group="people" @start="drag=true" @end="drag=false">
-   <div v-for="element in myArray" :key="element.id">{{element.name}}</div>
-</draggable>
-```
-.vue file:
-``` js
-  import draggable from 'vuedraggable'
-  ...
-  export default {
-        components: {
-            draggable,
-        },
-  ...
-```
-
-### With `transition-group`:
-``` html
-<draggable v-model="myArray">
-    <transition-group>
-        <div v-for="element in myArray" :key="element.id">
-            {{element.name}}
-        </div>
-    </transition-group>
-</draggable>
-```
-
-Draggable component should directly wrap the draggable elements, or a `transition-component` containing the draggable elements.
-
-
-### With footer slot:
-``` html
-<draggable v-model="myArray" draggable=".item">
-    <div v-for="element in myArray" :key="element.id" class="item">
-        {{element.name}}
-    </div>
-    <button slot="footer" @click="addPeople">Add</button>
-</draggable>
-```
-### With header slot:
-``` html
-<draggable v-model="myArray" draggable=".item">
-    <div v-for="element in myArray" :key="element.id" class="item">
-        {{element.name}}
-    </div>
-    <button slot="header" @click="addPeople">Add</button>
-</draggable>
-```
-
-### With Vuex:
-
-```html
-<draggable v-model='myList'>
-``` 
-
-```javascript
-computed: {
-    myList: {
-        get() {
-            return this.$store.state.myList
-        },
-        set(value) {
-            this.$store.commit('updateList', value)
-        }
-    }
-}
-```
-
-
-### Props
-#### value
-Type: `Array`<br>
-Required: `false`<br>
-Default: `null`
-
-Input array to draggable component. Typically same array as referenced by inner element v-for directive.<br>
-This is the preferred way to use Vue.draggable as it is compatible with Vuex.<br>
-It should not be used directly but only though the `v-model` directive:
-```html
-<draggable v-model="myArray">
-```
-
-#### list
-Type: `Array`<br>
-Required: `false`<br>
-Default: `null`
-
-Alternative to the `value` prop, list is an array to be synchronized with drag-and-drop.<br>
-The main difference is that `list` prop is updated by draggable component using splice method, whereas `value` is immutable.<br>
-**Do not use in conjunction with value prop.**
-
-#### All sortable options
-New in version 2.19
-
-Sortable options can be set directly as vue.draggable props since version 2.19.
-
-This means that all [sortable option](https://github.com/RubaXa/Sortable#options) are valid sortable props with the notable exception of all the method starting by "on" as draggable component expose the same API via events.
-
-kebab-case propery are supported: for example `ghost-class` props will be converted to `ghostClass` sortable option.
-
-Example setting handle, sortable and a group option:
-```HTML
-<draggable
-        v-model="list"
-        handle=".handle"
-        :group="{ name: 'people', pull: 'clone', put: false }"
-        ghost-class="ghost"
-        :sort="false"
-        @change="log"
-      >
-      <!-- -->
-</draggable>
-```
-
-#### tag
-Type: `String`<br>
-Default: `'div'`
-
-HTML node type of the element that draggable component create as outer element for the included slot.<br>
-It is also possible to pass the name of vue component as element. In this case, draggable attribute will be passed to the create component.<br>
-See also [componentData](#componentdata) if you need to set props or event to the created component.
-
-#### clone
-Type: `Function`<br>
-Required: `false`<br>
-Default: `(original) => { return original;}`<br>
-
-Function called on the source component to clone element when clone option is true. The unique argument is the viewModel element to be cloned and the returned value is its cloned version.<br>
-By default vue.draggable reuses the viewModel element, so you have to use this hook if you want to clone or deep clone it.
-
-#### move
-Type: `Function`<br>
-Required: `false`<br>
-Default: `null`<br>
-
-If not null this function will be called in a similar way as [Sortable onMove callback](https://github.com/RubaXa/Sortable#move-event-object).
-Returning false will cancel the drag operation.
-
-```javascript
-function onMoveCallback(evt, originalEvent){
-   ...
-    // return false; — for cancel
-}
-```
-evt object has same property as [Sortable onMove event](https://github.com/RubaXa/Sortable#move-event-object), and 3 additional properties:
- - `draggedContext`:  context linked to dragged element
-   - `index`: dragged element index
-   - `element`: dragged element underlying view model element
-   - `futureIndex`:  potential index of the dragged element if the drop operation is accepted
- - `relatedContext`: context linked to current drag operation
-   - `index`: target element index
-   - `element`: target element view model element
-   - `list`: target list
-   - `component`: target VueComponent
-
-HTML:
-```HTML
-<draggable :list="list" :move="checkMove">
-```
-javascript:
-```javascript
-checkMove: function(evt){
-    return (evt.draggedContext.element.name!=='apple');
-}
-```
-See complete example: [Cancel.html](https://github.com/SortableJS/Vue.Draggable/blob/master/examples/Cancel.html), [cancel.js](https://github.com/SortableJS/Vue.Draggable/blob/master/examples/script/cancel.js)
-
-#### componentData
-Type: `Object`<br>
-Required: `false`<br>
-Default: `null`<br>
-
-This props is used to pass additional information to child component declared by [tag props](#tag).<br>
-Value:
-* `props`: props to be passed to the child component
-* `attrs`: attrs to be passed to the child component
-* `on`: events to be subscribe in the child component
-
-Example (using [element UI library](http://element.eleme.io/#/en-US)):
-```HTML
-<draggable tag="el-collapse" :list="list" :component-data="getComponentData()">
-    <el-collapse-item v-for="e in list" :title="e.title" :name="e.name" :key="e.name">
-        <div>{{e.description}}</div>
-     </el-collapse-item>
-</draggable>
-```
-```javascript
-methods: {
-    handleChange() {
-      console.log('changed');
-    },
-    inputChanged(value) {
-      this.activeNames = value;
-    },
-    getComponentData() {
-      return {
-        on: {
-          change: this.handleChange,
-          input: this.inputChanged
-        },
-        attrs:{
-          wrap: true
-        },
-        props: {
-          value: this.activeNames
-        }
-      };
-    }
-  }
-```
-
-### Events
-
-* Support for Sortable events:
-
-  `start`, `add`, `remove`, `update`, `end`, `choose`, `unchoose`, `sort`, `filter`, `clone`<br>
-  Events are called whenever onStart, onAdd, onRemove, onUpdate, onEnd, onChoose, onUnchoose, onSort, onClone are fired by Sortable.js with the same argument.<br>
-  [See here for reference](https://github.com/RubaXa/Sortable#event-object-demo)
-
-  Note that SortableJS OnMove callback is mapped with the [move prop](https://github.com/SortableJS/Vue.Draggable/blob/master/README.md#move)
-
-HTML:
-```HTML
-<draggable :list="list" @end="onEnd">
-```
-
-* change event
-
-  `change` event is triggered when list prop is not null and the corresponding array is altered due to drag-and-drop operation.<br>
-  This event is called with one argument containing one of the following properties:
-  - `added`:  contains information of an element added to the array
-    - `newIndex`: the index of the added element
-    - `element`: the added element
-  - `removed`:  contains information of an element removed from to the array
-    - `oldIndex`: the index of the element before remove
-    - `element`: the removed element
-  - `moved`:  contains information of an element moved within the array
-    - `newIndex`: the current index of the moved element
-    - `oldIndex`: the old index of the moved element
-    - `element`: the moved element
-
-### Slots
-
-Limitation: neither header or footer slot works in conjunction with transition-group.
-
-#### Header
-Use the `header` slot to add none-draggable element inside the vuedraggable component.
-Important: it should be used in conjunction with draggable option to tag draggable element.
-Note that header slot will always be added before the default slot regardless its position in the template.
-Ex:
-
-``` html
-<draggable v-model="myArray" draggable=".item">
-    <div v-for="element in myArray" :key="element.id" class="item">
-        {{element.name}}
-    </div>
-    <button slot="header" @click="addPeople">Add</button>
-</draggable>
-```
-
-#### Footer
-Use the `footer` slot to add none-draggable element inside the vuedraggable component.
-Important: it should be used in conjunction with draggable option to tag draggable elements.
-Note that footer slot will always be added after the default slot regardless its position in the template.
-Ex:
-
-``` html
-<draggable v-model="myArray" draggable=".item">
-    <div v-for="element in myArray" :key="element.id" class="item">
-        {{element.name}}
-    </div>
-    <button slot="footer" @click="addPeople">Add</button>
-</draggable>
-```
- ### Gotchas
- 
- - Vue.draggable children should always map the list or value prop using a v-for directive
-   * You may use [header](https://github.com/SortableJS/Vue.Draggable#header) and [footer](https://github.com/SortableJS/Vue.Draggable#footer) slot to by-pass this limitation.
- 
- - Children elements inside v-for should be keyed as any element in Vue.js. Be carefull to provide revelant key values in particular:
-    * typically providing array index as keys won't work as key should be linked to the items content
-    * cloned elements should provide updated keys, it is doable using the [clone props](#clone) for example
-
-
- ### Example 
-  * [Clone](https://sortablejs.github.io/Vue.Draggable/#/custom-clone)
-  * [Handle](https://sortablejs.github.io/Vue.Draggable/#/handle)
-  * [Transition](https://sortablejs.github.io/Vue.Draggable/#/transition-example-2)
-  * [Nested](https://sortablejs.github.io/Vue.Draggable/#/nested-example)
-  * [Table](https://sortablejs.github.io/Vue.Draggable/#/table-example)
- 
- ### Full demo example
-
-[draggable-example](https://github.com/David-Desmaisons/draggable-example)
-
-## For Vue.js 1.0
-
-[See here](documentation/Vue.draggable.for.ReadME.md)
-
-```

+ 0 - 123
node_modules/vuedraggable/package.json

@@ -1,123 +0,0 @@
-{
-  "_from": "vuedraggable",
-  "_id": "vuedraggable@2.24.3",
-  "_inBundle": false,
-  "_integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
-  "_location": "/vuedraggable",
-  "_phantomChildren": {},
-  "_requested": {
-    "type": "tag",
-    "registry": true,
-    "raw": "vuedraggable",
-    "name": "vuedraggable",
-    "escapedName": "vuedraggable",
-    "rawSpec": "",
-    "saveSpec": null,
-    "fetchSpec": "latest"
-  },
-  "_requiredBy": [
-    "#USER",
-    "/"
-  ],
-  "_resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
-  "_shasum": "43c93849b746a24ce503e123d5b259c701ba0d19",
-  "_spec": "vuedraggable",
-  "_where": "D:\\sjkj\\sooka_internal_oa",
-  "browserslist": [
-    "> 1%",
-    "last 2 versions",
-    "not ie <= 8"
-  ],
-  "bugs": {
-    "url": "https://github.com/SortableJS/Vue.Draggable/issues"
-  },
-  "bundleDependencies": false,
-  "dependencies": {
-    "sortablejs": "1.10.2"
-  },
-  "deprecated": false,
-  "description": "draggable component for vue",
-  "devDependencies": {
-    "@vue/cli-plugin-babel": "^3.11.0",
-    "@vue/cli-plugin-eslint": "^3.11.0",
-    "@vue/cli-plugin-unit-jest": "^3.11.0",
-    "@vue/cli-service": "^3.11.0",
-    "@vue/eslint-config-prettier": "^4.0.1",
-    "@vue/test-utils": "^1.1.0",
-    "babel-core": "7.0.0-bridge.0",
-    "babel-eslint": "^10.0.1",
-    "babel-jest": "^23.6.0",
-    "bootstrap": "^4.3.1",
-    "codecov": "^3.2.0",
-    "component-fixture": "^0.4.1",
-    "element-ui": "^2.5.4",
-    "eslint": "^5.8.0",
-    "eslint-plugin-vue": "^5.0.0",
-    "font-awesome": "^4.7.0",
-    "jquery": "^3.5.1",
-    "vue": "^2.6.12",
-    "vue-cli-plugin-component": "^1.10.5",
-    "vue-router": "^3.0.2",
-    "vue-server-renderer": "^2.6.12",
-    "vue-template-compiler": "^2.6.12",
-    "vuetify": "^1.5.16",
-    "vuex": "^3.1.1"
-  },
-  "eslintConfig": {
-    "root": true,
-    "env": {
-      "node": true
-    },
-    "extends": [
-      "plugin:vue/essential",
-      "@vue/prettier"
-    ],
-    "rules": {},
-    "parserOptions": {
-      "parser": "babel-eslint"
-    }
-  },
-  "files": [
-    "dist/*.css",
-    "dist/*.map",
-    "dist/*.js",
-    "src/*"
-  ],
-  "homepage": "https://github.com/SortableJS/Vue.Draggable#readme",
-  "keywords": [
-    "vue",
-    "vuejs",
-    "drag",
-    "and",
-    "drop",
-    "list",
-    "Sortable.js",
-    "component",
-    "nested"
-  ],
-  "license": "MIT",
-  "main": "dist/vuedraggable.umd.min.js",
-  "module": "dist/vuedraggable.umd.js",
-  "name": "vuedraggable",
-  "postcss": {
-    "plugins": {
-      "autoprefixer": {}
-    }
-  },
-  "private": false,
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/SortableJS/Vue.Draggable.git"
-  },
-  "scripts": {
-    "build": "vue-cli-service build --name vuedraggable --entry ./src/vuedraggable.js --target lib",
-    "build:doc": "vue-cli-service build ./example/main.js --dest docs --mode development",
-    "lint": "vue-cli-service lint src example",
-    "prepublishOnly": "npm run lint && npm run test:unit && npm run build:doc && npm run build",
-    "serve": "vue-cli-service serve ./example/main.js --open --mode local",
-    "test:coverage": "vue-cli-service test:unit --coverage --verbose && codecov",
-    "test:unit": "vue-cli-service test:unit --coverage"
-  },
-  "types": "src/vuedraggable.d.ts",
-  "version": "2.24.3"
-}

+ 0 - 36
node_modules/vuedraggable/src/util/helper.js

@@ -1,36 +0,0 @@
-function getConsole() {
-  if (typeof window !== "undefined") {
-    return window.console;
-  }
-  return global.console;
-}
-const console = getConsole();
-
-function cached(fn) {
-  const cache = Object.create(null);
-  return function cachedFn(str) {
-    const hit = cache[str];
-    return hit || (cache[str] = fn(str));
-  };
-}
-
-const regex = /-(\w)/g;
-const camelize = cached(str =>
-  str.replace(regex, (_, c) => (c ? c.toUpperCase() : ""))
-);
-
-function removeNode(node) {
-  if (node.parentElement !== null) {
-    node.parentElement.removeChild(node);
-  }
-}
-
-function insertNodeAt(fatherNode, node, position) {
-  const refNode =
-    position === 0
-      ? fatherNode.children[0]
-      : fatherNode.children[position - 1].nextSibling;
-  fatherNode.insertBefore(node, refNode);
-}
-
-export { insertNodeAt, camelize, console, removeNode };

+ 0 - 75
node_modules/vuedraggable/src/vuedraggable.d.ts

@@ -1,75 +0,0 @@
-declare module 'vuedraggable' {
-  import Vue, { VueConstructor } from 'vue';
-
-  type CombinedVueInstance<
-    Instance extends Vue,
-    Data,
-    Methods,
-    Computed,
-    Props
-  > = Data & Methods & Computed & Props & Instance;
-
-  type ExtendedVue<
-    Instance extends Vue,
-    Data,
-    Methods,
-    Computed,
-    Props
-  > = VueConstructor<
-    CombinedVueInstance<Instance, Data, Methods, Computed, Props> & Vue
-  >;
-
-  export type DraggedContext<T> = {
-    index: number;
-    futureIndex: number;
-    element: T;
-  };
-
-  export type DropContext<T> = {
-    index: number;
-    component: Vue;
-    element: T;
-  };
-
-  export type Rectangle = {
-    top: number;
-    right: number;
-    bottom: number;
-    left: number;
-    width: number;
-    height: number;
-  };
-
-  export type MoveEvent<T> = {
-    originalEvent: DragEvent;
-    dragged: Element;
-    draggedContext: DraggedContext<T>;
-    draggedRect: Rectangle;
-    related: Element;
-    relatedContext: DropContext<T>;
-    relatedRect: Rectangle;
-    from: Element;
-    to: Element;
-    willInsertAfter: boolean;
-    isTrusted: boolean;
-  };
-
-  const draggable: ExtendedVue<
-    Vue,
-    {},
-    {},
-    {},
-    {
-      options: any;
-      list: any[];
-      value: any[];
-      noTransitionOnDrag?: boolean;
-      clone: any;
-      tag?: string | null;
-      move: any;
-      componentData: any;
-    }
-  >;
-
-  export default draggable;
-}

+ 0 - 485
node_modules/vuedraggable/src/vuedraggable.js

@@ -1,485 +0,0 @@
-import Sortable from "sortablejs";
-import { insertNodeAt, camelize, console, removeNode } from "./util/helper";
-
-function buildAttribute(object, propName, value) {
-  if (value === undefined) {
-    return object;
-  }
-  object = object || {};
-  object[propName] = value;
-  return object;
-}
-
-function computeVmIndex(vnodes, element) {
-  return vnodes.map(elt => elt.elm).indexOf(element);
-}
-
-function computeIndexes(slots, children, isTransition, footerOffset) {
-  if (!slots) {
-    return [];
-  }
-
-  const elmFromNodes = slots.map(elt => elt.elm);
-  const footerIndex = children.length - footerOffset;
-  const rawIndexes = [...children].map((elt, idx) =>
-    idx >= footerIndex ? elmFromNodes.length : elmFromNodes.indexOf(elt)
-  );
-  return isTransition ? rawIndexes.filter(ind => ind !== -1) : rawIndexes;
-}
-
-function emit(evtName, evtData) {
-  this.$nextTick(() => this.$emit(evtName.toLowerCase(), evtData));
-}
-
-function delegateAndEmit(evtName) {
-  return evtData => {
-    if (this.realList !== null) {
-      this["onDrag" + evtName](evtData);
-    }
-    emit.call(this, evtName, evtData);
-  };
-}
-
-function isTransitionName(name) {
-  return ["transition-group", "TransitionGroup"].includes(name);
-}
-
-function isTransition(slots) {
-  if (!slots || slots.length !== 1) {
-    return false;
-  }
-  const [{ componentOptions }] = slots;
-  if (!componentOptions) {
-    return false;
-  }
-  return isTransitionName(componentOptions.tag);
-}
-
-function getSlot(slot, scopedSlot, key) {
-  return slot[key] || (scopedSlot[key] ? scopedSlot[key]() : undefined);
-}
-
-function computeChildrenAndOffsets(children, slot, scopedSlot) {
-  let headerOffset = 0;
-  let footerOffset = 0;
-  const header = getSlot(slot, scopedSlot, "header");
-  if (header) {
-    headerOffset = header.length;
-    children = children ? [...header, ...children] : [...header];
-  }
-  const footer = getSlot(slot, scopedSlot, "footer");
-  if (footer) {
-    footerOffset = footer.length;
-    children = children ? [...children, ...footer] : [...footer];
-  }
-  return { children, headerOffset, footerOffset };
-}
-
-function getComponentAttributes($attrs, componentData) {
-  let attributes = null;
-  const update = (name, value) => {
-    attributes = buildAttribute(attributes, name, value);
-  };
-  const attrs = Object.keys($attrs)
-    .filter(key => key === "id" || key.startsWith("data-"))
-    .reduce((res, key) => {
-      res[key] = $attrs[key];
-      return res;
-    }, {});
-  update("attrs", attrs);
-
-  if (!componentData) {
-    return attributes;
-  }
-  const { on, props, attrs: componentDataAttrs } = componentData;
-  update("on", on);
-  update("props", props);
-  Object.assign(attributes.attrs, componentDataAttrs);
-  return attributes;
-}
-
-const eventsListened = ["Start", "Add", "Remove", "Update", "End"];
-const eventsToEmit = ["Choose", "Unchoose", "Sort", "Filter", "Clone"];
-const readonlyProperties = ["Move", ...eventsListened, ...eventsToEmit].map(
-  evt => "on" + evt
-);
-var draggingElement = null;
-
-const props = {
-  options: Object,
-  list: {
-    type: Array,
-    required: false,
-    default: null
-  },
-  value: {
-    type: Array,
-    required: false,
-    default: null
-  },
-  noTransitionOnDrag: {
-    type: Boolean,
-    default: false
-  },
-  clone: {
-    type: Function,
-    default: original => {
-      return original;
-    }
-  },
-  element: {
-    type: String,
-    default: "div"
-  },
-  tag: {
-    type: String,
-    default: null
-  },
-  move: {
-    type: Function,
-    default: null
-  },
-  componentData: {
-    type: Object,
-    required: false,
-    default: null
-  }
-};
-
-const draggableComponent = {
-  name: "draggable",
-
-  inheritAttrs: false,
-
-  props,
-
-  data() {
-    return {
-      transitionMode: false,
-      noneFunctionalComponentMode: false
-    };
-  },
-
-  render(h) {
-    const slots = this.$slots.default;
-    this.transitionMode = isTransition(slots);
-    const { children, headerOffset, footerOffset } = computeChildrenAndOffsets(
-      slots,
-      this.$slots,
-      this.$scopedSlots
-    );
-    this.headerOffset = headerOffset;
-    this.footerOffset = footerOffset;
-    const attributes = getComponentAttributes(this.$attrs, this.componentData);
-    return h(this.getTag(), attributes, children);
-  },
-
-  created() {
-    if (this.list !== null && this.value !== null) {
-      console.error(
-        "Value and list props are mutually exclusive! Please set one or another."
-      );
-    }
-
-    if (this.element !== "div") {
-      console.warn(
-        "Element props is deprecated please use tag props instead. See https://github.com/SortableJS/Vue.Draggable/blob/master/documentation/migrate.md#element-props"
-      );
-    }
-
-    if (this.options !== undefined) {
-      console.warn(
-        "Options props is deprecated, add sortable options directly as vue.draggable item, or use v-bind. See https://github.com/SortableJS/Vue.Draggable/blob/master/documentation/migrate.md#options-props"
-      );
-    }
-  },
-
-  mounted() {
-    this.noneFunctionalComponentMode =
-      this.getTag().toLowerCase() !== this.$el.nodeName.toLowerCase() &&
-      !this.getIsFunctional();
-    if (this.noneFunctionalComponentMode && this.transitionMode) {
-      throw new Error(
-        `Transition-group inside component is not supported. Please alter tag value or remove transition-group. Current tag value: ${this.getTag()}`
-      );
-    }
-    const optionsAdded = {};
-    eventsListened.forEach(elt => {
-      optionsAdded["on" + elt] = delegateAndEmit.call(this, elt);
-    });
-
-    eventsToEmit.forEach(elt => {
-      optionsAdded["on" + elt] = emit.bind(this, elt);
-    });
-
-    const attributes = Object.keys(this.$attrs).reduce((res, key) => {
-      res[camelize(key)] = this.$attrs[key];
-      return res;
-    }, {});
-
-    const options = Object.assign({}, this.options, attributes, optionsAdded, {
-      onMove: (evt, originalEvent) => {
-        return this.onDragMove(evt, originalEvent);
-      }
-    });
-    !("draggable" in options) && (options.draggable = ">*");
-    this._sortable = new Sortable(this.rootContainer, options);
-    this.computeIndexes();
-  },
-
-  beforeDestroy() {
-    if (this._sortable !== undefined) this._sortable.destroy();
-  },
-
-  computed: {
-    rootContainer() {
-      return this.transitionMode ? this.$el.children[0] : this.$el;
-    },
-
-    realList() {
-      return this.list ? this.list : this.value;
-    }
-  },
-
-  watch: {
-    options: {
-      handler(newOptionValue) {
-        this.updateOptions(newOptionValue);
-      },
-      deep: true
-    },
-
-    $attrs: {
-      handler(newOptionValue) {
-        this.updateOptions(newOptionValue);
-      },
-      deep: true
-    },
-
-    realList() {
-      this.computeIndexes();
-    }
-  },
-
-  methods: {
-    getIsFunctional() {
-      const { fnOptions } = this._vnode;
-      return fnOptions && fnOptions.functional;
-    },
-
-    getTag() {
-      return this.tag || this.element;
-    },
-
-    updateOptions(newOptionValue) {
-      for (var property in newOptionValue) {
-        const value = camelize(property);
-        if (readonlyProperties.indexOf(value) === -1) {
-          this._sortable.option(value, newOptionValue[property]);
-        }
-      }
-    },
-
-    getChildrenNodes() {
-      if (this.noneFunctionalComponentMode) {
-        return this.$children[0].$slots.default;
-      }
-      const rawNodes = this.$slots.default;
-      return this.transitionMode ? rawNodes[0].child.$slots.default : rawNodes;
-    },
-
-    computeIndexes() {
-      this.$nextTick(() => {
-        this.visibleIndexes = computeIndexes(
-          this.getChildrenNodes(),
-          this.rootContainer.children,
-          this.transitionMode,
-          this.footerOffset
-        );
-      });
-    },
-
-    getUnderlyingVm(htmlElt) {
-      const index = computeVmIndex(this.getChildrenNodes() || [], htmlElt);
-      if (index === -1) {
-        //Edge case during move callback: related element might be
-        //an element different from collection
-        return null;
-      }
-      const element = this.realList[index];
-      return { index, element };
-    },
-
-    getUnderlyingPotencialDraggableComponent({ __vue__: vue }) {
-      if (
-        !vue ||
-        !vue.$options ||
-        !isTransitionName(vue.$options._componentTag)
-      ) {
-        if (
-          !("realList" in vue) &&
-          vue.$children.length === 1 &&
-          "realList" in vue.$children[0]
-        )
-          return vue.$children[0];
-
-        return vue;
-      }
-      return vue.$parent;
-    },
-
-    emitChanges(evt) {
-      this.$nextTick(() => {
-        this.$emit("change", evt);
-      });
-    },
-
-    alterList(onList) {
-      if (this.list) {
-        onList(this.list);
-        return;
-      }
-      const newList = [...this.value];
-      onList(newList);
-      this.$emit("input", newList);
-    },
-
-    spliceList() {
-      const spliceList = list => list.splice(...arguments);
-      this.alterList(spliceList);
-    },
-
-    updatePosition(oldIndex, newIndex) {
-      const updatePosition = list =>
-        list.splice(newIndex, 0, list.splice(oldIndex, 1)[0]);
-      this.alterList(updatePosition);
-    },
-
-    getRelatedContextFromMoveEvent({ to, related }) {
-      const component = this.getUnderlyingPotencialDraggableComponent(to);
-      if (!component) {
-        return { component };
-      }
-      const list = component.realList;
-      const context = { list, component };
-      if (to !== related && list && component.getUnderlyingVm) {
-        const destination = component.getUnderlyingVm(related);
-        if (destination) {
-          return Object.assign(destination, context);
-        }
-      }
-      return context;
-    },
-
-    getVmIndex(domIndex) {
-      const indexes = this.visibleIndexes;
-      const numberIndexes = indexes.length;
-      return domIndex > numberIndexes - 1 ? numberIndexes : indexes[domIndex];
-    },
-
-    getComponent() {
-      return this.$slots.default[0].componentInstance;
-    },
-
-    resetTransitionData(index) {
-      if (!this.noTransitionOnDrag || !this.transitionMode) {
-        return;
-      }
-      var nodes = this.getChildrenNodes();
-      nodes[index].data = null;
-      const transitionContainer = this.getComponent();
-      transitionContainer.children = [];
-      transitionContainer.kept = undefined;
-    },
-
-    onDragStart(evt) {
-      this.context = this.getUnderlyingVm(evt.item);
-      evt.item._underlying_vm_ = this.clone(this.context.element);
-      draggingElement = evt.item;
-    },
-
-    onDragAdd(evt) {
-      const element = evt.item._underlying_vm_;
-      if (element === undefined) {
-        return;
-      }
-      removeNode(evt.item);
-      const newIndex = this.getVmIndex(evt.newIndex);
-      this.spliceList(newIndex, 0, element);
-      this.computeIndexes();
-      const added = { element, newIndex };
-      this.emitChanges({ added });
-    },
-
-    onDragRemove(evt) {
-      insertNodeAt(this.rootContainer, evt.item, evt.oldIndex);
-      if (evt.pullMode === "clone") {
-        removeNode(evt.clone);
-        return;
-      }
-      const oldIndex = this.context.index;
-      this.spliceList(oldIndex, 1);
-      const removed = { element: this.context.element, oldIndex };
-      this.resetTransitionData(oldIndex);
-      this.emitChanges({ removed });
-    },
-
-    onDragUpdate(evt) {
-      removeNode(evt.item);
-      insertNodeAt(evt.from, evt.item, evt.oldIndex);
-      const oldIndex = this.context.index;
-      const newIndex = this.getVmIndex(evt.newIndex);
-      this.updatePosition(oldIndex, newIndex);
-      const moved = { element: this.context.element, oldIndex, newIndex };
-      this.emitChanges({ moved });
-    },
-
-    updateProperty(evt, propertyName) {
-      evt.hasOwnProperty(propertyName) &&
-        (evt[propertyName] += this.headerOffset);
-    },
-
-    computeFutureIndex(relatedContext, evt) {
-      if (!relatedContext.element) {
-        return 0;
-      }
-      const domChildren = [...evt.to.children].filter(
-        el => el.style["display"] !== "none"
-      );
-      const currentDOMIndex = domChildren.indexOf(evt.related);
-      const currentIndex = relatedContext.component.getVmIndex(currentDOMIndex);
-      const draggedInList = domChildren.indexOf(draggingElement) !== -1;
-      return draggedInList || !evt.willInsertAfter
-        ? currentIndex
-        : currentIndex + 1;
-    },
-
-    onDragMove(evt, originalEvent) {
-      const onMove = this.move;
-      if (!onMove || !this.realList) {
-        return true;
-      }
-
-      const relatedContext = this.getRelatedContextFromMoveEvent(evt);
-      const draggedContext = this.context;
-      const futureIndex = this.computeFutureIndex(relatedContext, evt);
-      Object.assign(draggedContext, { futureIndex });
-      const sendEvt = Object.assign({}, evt, {
-        relatedContext,
-        draggedContext
-      });
-      return onMove(sendEvt, originalEvent);
-    },
-
-    onDragEnd() {
-      this.computeIndexes();
-      draggingElement = null;
-    }
-  }
-};
-
-if (typeof window !== "undefined" && "Vue" in window) {
-  window.Vue.component("draggable", draggableComponent);
-}
-
-export default draggableComponent;

+ 7 - 0
pom.xml

@@ -170,6 +170,12 @@
                 <version>${ruoyi.version}</version>
             </dependency>
 
+            <dependency>
+                <groupId>com.ruoyi</groupId>
+                <artifactId>sooka-jnb</artifactId>
+                <version>${ruoyi.version}</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 
@@ -180,6 +186,7 @@
         <module>ruoyi-quartz</module>
         <module>ruoyi-generator</module>
         <module>ruoyi-common</module>
+        <module>sooka-jnb</module>
     </modules>
     <packaging>pom</packaging>
 

+ 5 - 0
ruoyi-admin/pom.xml

@@ -60,6 +60,11 @@
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-generator</artifactId>
         </dependency>
+        <!-- 业务模块-->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>sooka-jnb</artifactId>
+        </dependency>
 
     </dependencies>
 

+ 2 - 2
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java

@@ -8,10 +8,10 @@ import org.springframework.scheduling.annotation.EnableAsync;
 
 /**
  * 启动程序
- * 
+ *
  * @author ruoyi
  */
-@SpringBootApplication(scanBasePackages = {"com.ruoyi","com.sooka.oa"})
+@SpringBootApplication(scanBasePackages = {"com.ruoyi","com.sooka.jnb"})
 @EnableScheduling
 @EnableAsync
 public class RuoYiApplication

+ 21 - 8
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java

@@ -3,10 +3,7 @@ package com.ruoyi.web.controller.system;
 import java.util.List;
 import java.util.Set;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.entity.SysMenu;
@@ -19,7 +16,7 @@ import com.ruoyi.system.service.ISysMenuService;
 
 /**
  * 登录验证
- * 
+ *
  * @author ruoyi
  */
 @RestController
@@ -35,8 +32,24 @@ public class SysLoginController
     private SysPermissionService permissionService;
 
     /**
+     * 登录方法(小程序登录)
+     *
+     * @param code 登录信息
+     * @return 结果
+     */
+    @PostMapping("/wxLogin")
+    public AjaxResult wxLogin(@RequestParam(value = "code", required = false) String code)
+    {
+        AjaxResult ajax = AjaxResult.success();
+        // 生成令牌
+        String token = loginService.wxlogin(code);
+        ajax.put(Constants.TOKEN, token);
+        return ajax;
+    }
+
+    /**
      * 登录方法
-     * 
+     *
      * @param loginBody 登录信息
      * @return 结果
      */
@@ -53,7 +66,7 @@ public class SysLoginController
 
     /**
      * 获取用户信息
-     * 
+     *
      * @return 用户信息
      */
     @GetMapping("getInfo")
@@ -73,7 +86,7 @@ public class SysLoginController
 
     /**
      * 获取路由信息
-     * 
+     *
      * @return 路由信息
      */
     @GetMapping("getRouters")

+ 1 - 1
ruoyi-admin/src/main/resources/application.yml

@@ -22,7 +22,7 @@ fileServer:
 # 开发环境配置
 server:
   # 服务器的HTTP端口,默认为8080
-  port: 31000
+  port: 8080
   servlet:
     # 应用的访问路径
     context-path: /

+ 79 - 0
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/WxUser.java

@@ -0,0 +1,79 @@
+package com.ruoyi.common.core.domain.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+@TableName("jnb_wx_user")
+public class WxUser extends BaseEntity {
+
+    private static final long serialVersionUID=1L;
+
+    /** 微信openid */
+    private Long id;
+    private String openid;
+
+    /** 微信名称(支付后可查看) */
+    @Excel(name = "微信名称")
+    private String wechatName;
+
+    /** 真实姓名(支付后可查看) */
+    @Excel(name = "真实姓名")
+    private String name;
+
+    /** 身份证号 */
+    @Excel(name = "身份证号")
+    private String idCard;
+
+    /** 手机号(支付后可查看) */
+    @Excel(name = "手机号" )
+    private String phone;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getOpenid() {
+        return openid;
+    }
+
+    public void setOpenid(String openid) {
+        this.openid = openid;
+    }
+
+    public String getWechatName() {
+        return wechatName;
+    }
+
+    public void setWechatName(String wechatName) {
+        this.wechatName = wechatName;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getIdCard() {
+        return idCard;
+    }
+
+    public void setIdCard(String idCard) {
+        this.idCard = idCard;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+}

+ 14 - 4
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java

@@ -2,6 +2,7 @@ package com.ruoyi.common.core.domain.model;
 
 import com.alibaba.fastjson2.annotation.JSONField;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.entity.WxUser;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.userdetails.UserDetails;
 import java.util.Collection;
@@ -9,7 +10,7 @@ import java.util.Set;
 
 /**
  * 登录用户身份权限
- * 
+ *
  * @author ruoyi
  */
 public class LoginUser implements UserDetails
@@ -71,6 +72,9 @@ public class LoginUser implements UserDetails
      */
     private SysUser user;
 
+    private String openid;
+    private WxUser wxUser;
+
     public LoginUser()
     {
     }
@@ -88,6 +92,12 @@ public class LoginUser implements UserDetails
         this.user = user;
         this.permissions = permissions;
     }
+    public LoginUser(Long id,String openid ,WxUser wxUser)
+    {
+        this.userId = id;
+        this.openid = openid;
+        this.wxUser = wxUser;
+    }
 
     public Long getUserId()
     {
@@ -144,7 +154,7 @@ public class LoginUser implements UserDetails
 
     /**
      * 指定用户是否解锁,锁定的用户无法进行身份验证
-     * 
+     *
      * @return
      */
     @JSONField(serialize = false)
@@ -156,7 +166,7 @@ public class LoginUser implements UserDetails
 
     /**
      * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
-     * 
+     *
      * @return
      */
     @JSONField(serialize = false)
@@ -168,7 +178,7 @@ public class LoginUser implements UserDetails
 
     /**
      * 是否可用 ,禁用的用户不能身份验证
-     * 
+     *
      * @return
      */
     @JSONField(serialize = false)

+ 5 - 1
ruoyi-framework/pom.xml

@@ -58,7 +58,11 @@
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-system</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>sooka-jnb</artifactId>
+        </dependency>
 
     </dependencies>
 
-</project>
+</project>

+ 4 - 4
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java

@@ -22,7 +22,7 @@ import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl;
 
 /**
  * spring security配置
- * 
+ *
  * @author ruoyi
  */
 @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
@@ -33,7 +33,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      */
     @Autowired
     private UserDetailsService userDetailsService;
-    
+
     /**
      * 认证失败处理类
      */
@@ -51,7 +51,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      */
     @Autowired
     private JwtAuthenticationTokenFilter authenticationTokenFilter;
-    
+
     /**
      * 跨域过滤器
      */
@@ -111,7 +111,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 // 过滤请求
                 .authorizeRequests()
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                .antMatchers("/login", "/register", "/captchaImage").permitAll()
+                .antMatchers("/login", "/register", "/captchaImage","/wxLogin").permitAll()
                 // 静态资源,可匿名访问
                 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                 .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

+ 7 - 4
ruoyi-framework/src/main/java/com/ruoyi/framework/db/factory/CustomMetaObjectHandler.java

@@ -23,11 +23,14 @@ public class CustomMetaObjectHandler implements MetaObjectHandler {
         this.strictInsertFill(metaObject, "delFlag", String.class, "0");
         // 版本号
         this.strictInsertFill(metaObject, "version", Integer.class, 1);
-        // 创建人、创建时间
-        this.strictInsertFill(metaObject, createBy, String.class, String.valueOf(SecurityUtils.getUserId()));
+        // 创建人、修改人
+        if(!"com.ruoyi.common.core.domain.entity.WxUser".equals(metaObject.getOriginalObject().getClass().getName())){
+            this.strictInsertFill(metaObject, createBy, String.class, String.valueOf(SecurityUtils.getUserId()));
+            this.strictInsertFill(metaObject, updateBy, String.class, String.valueOf(SecurityUtils.getUserId()));
+        }
+
         this.strictInsertFill(metaObject, createTime, DateUtils::getNowDate, Date.class);
-        // 修改人、修改时间
-        this.strictInsertFill(metaObject, updateBy, String.class, String.valueOf(SecurityUtils.getUserId()));
+        // 创建时间、修改时间
         this.strictInsertFill(metaObject, updateTime, DateUtils::getNowDate, Date.class);
     }
 

+ 64 - 16
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java

@@ -1,24 +1,17 @@
 package com.ruoyi.framework.web.service;
 
-import javax.annotation.Resource;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.BadCredentialsException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.stereotype.Component;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.constant.UserConstants;
 import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.core.domain.entity.WxUser;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.exception.ServiceException;
-import com.ruoyi.common.exception.user.BlackListException;
-import com.ruoyi.common.exception.user.CaptchaException;
-import com.ruoyi.common.exception.user.CaptchaExpireException;
-import com.ruoyi.common.exception.user.UserNotExistsException;
-import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
+import com.ruoyi.common.exception.user.*;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.MessageUtils;
 import com.ruoyi.common.utils.StringUtils;
@@ -28,10 +21,21 @@ import com.ruoyi.framework.manager.factory.AsyncFactory;
 import com.ruoyi.framework.security.context.AuthenticationContextHolder;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.service.ISysUserService;
+import com.sooka.jnb.mapper.WxUserMapper;
+import com.sooka.jnb.utils.WechatUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
 
 /**
  * 登录校验方法
- * 
+ *
  * @author ruoyi
  */
 @Component
@@ -45,16 +49,55 @@ public class SysLoginService
 
     @Autowired
     private RedisCache redisCache;
-    
+
     @Autowired
     private ISysUserService userService;
 
     @Autowired
     private ISysConfigService configService;
 
+    @Autowired
+    private WxUserMapper wxUserMapper;
+
+    /**
+     * 登录验证
+     *
+     * @param username 用户名
+     * @param password 密码
+     * @param code 验证码
+     * @param uuid 唯一标识
+     * @return 结果
+     */
+    public String wxlogin(String code)
+    {
+        Authentication authentication = null;
+        // 1.接收小程序发送的code
+        // 2.开发者服务器 登录凭证校验接口 appi + appsecret + code
+        JSONObject SessionKeyOpenId = WechatUtil.getSessionKeyOrOpenId(code);
+        // 3.接收微信接口服务 获取返回的参数
+        String openid = SessionKeyOpenId.getString("openid");
+        String sessionKey = SessionKeyOpenId.getString("session_key");
+
+        // 4.根据返回的User实体类,判断用户是否是新用户,是的话,将用户信息存到数据库;
+        QueryWrapper<WxUser> wrapper = Wrappers.query();
+        wrapper.eq("openid",openid);
+        WxUser user = wxUserMapper.selectOne(wrapper);
+        if (user == null) {
+            // 用户信息入库
+            user = new WxUser();
+            user.setOpenid(openid);
+            user.setWechatName("微信用户");
+            user.setCreateBy(openid);
+            user.setUpdateBy(openid);
+            wxUserMapper.insert(user);
+        }
+        LoginUser loginUser = createLoginWxUser(user);
+        // 生成token
+        return tokenService.createWxToken(loginUser);
+    }
     /**
      * 登录验证
-     * 
+     *
      * @param username 用户名
      * @param password 密码
      * @param code 验证码
@@ -102,7 +145,7 @@ public class SysLoginService
 
     /**
      * 校验验证码
-     * 
+     *
      * @param username 用户名
      * @param code 验证码
      * @param uuid 唯一标识
@@ -178,4 +221,9 @@ public class SysLoginService
         sysUser.setLoginDate(DateUtils.getNowDate());
         userService.updateUserProfile(sysUser);
     }
+
+    public LoginUser createLoginWxUser(WxUser wxUser)
+    {
+        return new LoginUser(wxUser.getId(), wxUser.getOpenid(),wxUser);
+    }
 }

+ 15 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java

@@ -122,6 +122,21 @@ public class TokenService
         claims.put(Constants.LOGIN_USER_KEY, token);
         return createToken(claims);
     }
+    /**
+     * 创建令牌
+     *
+     * @param loginUser 用户信息
+     * @return 令牌
+     */
+    public String createWxToken(LoginUser loginUser)
+    {
+        String token = IdUtils.fastUUID();
+        loginUser.setToken(token);
+
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(Constants.LOGIN_USER_KEY, token);
+        return createToken(claims);
+    }
 
     /**
      * 验证令牌有效期,相差不足20分钟,自动刷新缓存

+ 1 - 5
ruoyi-quartz/pom.xml

@@ -34,11 +34,7 @@
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-common</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.ruoyi</groupId>
-            <artifactId>sooka-pm</artifactId>
-        </dependency>
 
     </dependencies>
 
-</project>
+</project>

+ 14 - 0
sooka-jnb/src/main/java/com/sooka/jnb/mapper/WxUserMapper.java

@@ -0,0 +1,14 @@
+package com.sooka.jnb.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.common.core.domain.entity.WxUser;
+
+/**
+ * 参数配置 数据层
+ *
+ * @author ruoyi
+ */
+public interface WxUserMapper extends BaseMapper<WxUser> {
+
+    void registerWxUser(WxUser entity);
+}

+ 5 - 0
sooka-jnb/src/main/java/com/sooka/jnb/service/WxUserService.java

@@ -0,0 +1,5 @@
+package com.sooka.jnb.service;
+
+public interface WxUserService {
+
+}

+ 12 - 0
sooka-jnb/src/main/java/com/sooka/jnb/service/impl/WxUserServiceImpl.java

@@ -0,0 +1,12 @@
+package com.sooka.jnb.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.domain.entity.WxUser;
+import com.sooka.jnb.mapper.WxUserMapper;
+import com.sooka.jnb.service.WxUserService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class WxUserServiceImpl extends ServiceImpl<WxUserMapper, WxUser> implements WxUserService {
+
+}

+ 178 - 0
sooka-jnb/src/main/java/com/sooka/jnb/utils/HttpClientUtil.java

@@ -0,0 +1,178 @@
+package com.sooka.jnb.utils;
+
+import com.ruoyi.common.exception.ServiceException;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.*;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class HttpClientUtil {
+	private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class);
+	private static final HttpClient client = HttpClients.createDefault();
+
+	public static String doGet(String url, Map<String, String> param) {
+
+		// 创建Httpclient对象
+		CloseableHttpClient httpclient = HttpClients.createDefault();
+
+		String resultString = "";
+		CloseableHttpResponse response = null;
+		try {
+			// 创建uri
+			URIBuilder builder = new URIBuilder(url);
+			if (param != null) {
+				for (String key : param.keySet()) {
+					builder.addParameter(key, param.get(key));
+				}
+			}
+			URI uri = builder.build();
+
+			// 创建http GET请求
+			HttpGet httpGet = new HttpGet(uri);
+
+			// 执行请求
+			response = httpclient.execute(httpGet);
+			// 判断返回状态是否为200
+			if (response.getStatusLine().getStatusCode() == 200) {
+				resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				if (response != null) {
+					response.close();
+				}
+				httpclient.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+		return resultString;
+	}
+
+	public static String doGet(String url) {
+		return doGet(url, null);
+	}
+
+	public static String doPost(String url, Map<String, String> param) {
+		// 创建Httpclient对象
+		CloseableHttpClient httpClient = HttpClients.createDefault();
+		CloseableHttpResponse response = null;
+		String resultString = "";
+		try {
+			// 创建Http Post请求
+			HttpPost httpPost = new HttpPost(url);
+			// 创建参数列表
+			if (param != null) {
+				List<NameValuePair> paramList = new ArrayList<>();
+				for (String key : param.keySet()) {
+					paramList.add(new BasicNameValuePair(key, param.get(key)));
+				}
+				// 模拟表单
+				UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
+				httpPost.setEntity(entity);
+			}
+			// 执行http请求
+			response = httpClient.execute(httpPost);
+			resultString = EntityUtils.toString(response.getEntity(), "utf-8");
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				response.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+
+		return resultString;
+	}
+
+	public static String doPost(String url) {
+		return doPost(url, null);
+	}
+
+	public static String doPostJson(String url, String json) {
+		// 创建Httpclient对象
+		CloseableHttpClient httpClient = HttpClients.createDefault();
+		CloseableHttpResponse response = null;
+		String resultString = "";
+		try {
+			// 创建Http Post请求
+			HttpPost httpPost = new HttpPost(url);
+			// 创建请求内容
+			StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
+			httpPost.setEntity(entity);
+			// 执行http请求
+			response = httpClient.execute(httpPost);
+			resultString = EntityUtils.toString(response.getEntity(), "utf-8");
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				response.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+
+		return resultString;
+	}
+
+	/**
+	 * get请求
+	 *
+	 * @param get get
+	 * @return 响应的数据(json)
+	 */
+	public static String get(HttpGet get, String cookie) {
+		String data = "";
+		get.addHeader("Content-type", "application/json; charset=utf-8");
+		get.setHeader("Accept", "application/json");
+		if (StringUtils.isNotEmpty(cookie)) {
+			get.setHeader("Cookie", cookie);
+		}
+		try {
+			HttpResponse resp = client.execute(get);
+			//获取HTTP状态码
+			int statusCode = resp.getStatusLine().getStatusCode();
+			if (statusCode != 200) {
+				throw new ServiceException("网络错误,状态码:" + statusCode);
+			}
+			HttpEntity httpEntity = resp.getEntity();
+			data = EntityUtils.toString(httpEntity, "UTF-8");
+		} catch (Exception e) {
+			LOGGER.error("get获取数据异常", e);
+		} finally {
+			get.releaseConnection();
+		}
+		return data;
+	}
+
+}
+

+ 26 - 0
sooka-jnb/src/main/java/com/sooka/jnb/utils/PayUtils.java

@@ -0,0 +1,26 @@
+package com.sooka.jnb.utils;
+
+/**
+ * @author wang_xy
+ * @description
+ * @Version 1.0
+ * @params
+ * @return
+ * @since 2022/11/24 11:02
+ */
+public class PayUtils {
+
+    /**
+     * APPID
+     */
+    public static String APPID = "wxf75b34dd1f737174";
+    /**
+     * secret
+     */
+    public static String SECRET = "7918ea657e4143248beef3cc8718d339";
+    /**
+     * 微信服务器地址
+     */
+    public static String DOMAIN="https://api.weixin.qq.com";
+
+}

+ 27 - 0
sooka-jnb/src/main/java/com/sooka/jnb/utils/WechatUtil.java

@@ -0,0 +1,27 @@
+package com.sooka.jnb.utils;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class WechatUtil {
+
+    public static JSONObject getSessionKeyOrOpenId(String code) {
+        String requestUrl = PayUtils.DOMAIN+"/sns/jscode2session";
+        Map<String, String> requestUrlParam = new HashMap<>();
+        //小程序appId
+        requestUrlParam.put("appid", PayUtils.APPID);
+        //小程序secret
+        requestUrlParam.put("secret", PayUtils.SECRET);
+        //小程序端返回的code
+        requestUrlParam.put("js_code", code);
+        //默认参数
+        requestUrlParam.put("grant_type", "authorization_code");
+        //发送post请求读取调用微信接口获取openid用户唯一标识
+        JSONObject jsonObject = JSON.parseObject(HttpClientUtil.doPost(requestUrl, requestUrlParam));
+        return jsonObject;
+    }
+}
+

+ 10 - 0
sooka-jnb/src/main/resources/mapper/WxUserMapper.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sooka.jnb.mapper.WxUserMapper">
+
+    <insert id="registerWxUser" parameterType="com.ruoyi.common.core.domain.entity.WxUser">
+        insert into jnb_wx_user (openid,wechat_name) values (#{openid},#{wechatName})
+    </insert>
+</mapper>