guhongwei 3 rokov pred
rodič
commit
12918e73e4
48 zmenil súbory, kde vykonal 2384 pridanie a 148 odobranie
  1. 3 0
      .env
  2. 33 0
      .eslintrc.js
  3. 352 17
      package-lock.json
  4. 13 1
      package.json
  5. 14 22
      src/App.vue
  6. 13 55
      src/components/HelloWorld.vue
  7. 69 0
      src/components/c-select.vue
  8. 74 0
      src/components/footers.vue
  9. 17 0
      src/components/vForm.md
  10. 103 0
      src/components/vForm.vue
  11. 61 0
      src/components/vcheckbox.vue
  12. 67 0
      src/components/vdate.vue
  13. 61 0
      src/components/vselect copy.vue
  14. 62 0
      src/components/vselect.vue
  15. 55 0
      src/components/vupload.vue
  16. 88 0
      src/layout/common/admin-frame.vue
  17. 42 0
      src/layout/common/footers.vue
  18. 47 0
      src/layout/common/page.vue
  19. 7 0
      src/layout/common/top.md
  20. 127 0
      src/layout/common/top.vue
  21. 20 6
      src/main.js
  22. 19 0
      src/plugins/axios.js
  23. 37 0
      src/plugins/check-res.js
  24. 11 0
      src/plugins/components.js
  25. 63 0
      src/plugins/couindex.js
  26. 5 0
      src/plugins/element.js
  27. 27 0
      src/plugins/loading.js
  28. 4 0
      src/plugins/meta.js
  29. 20 0
      src/plugins/setting.js
  30. 65 0
      src/plugins/stomp.js
  31. 5 0
      src/plugins/vant.js
  32. 3 0
      src/plugins/weixin.js
  33. 59 19
      src/router/index.js
  34. 116 5
      src/store/index.js
  35. 46 0
      src/store/live/cashing.js
  36. 43 0
      src/store/live/coupons.js
  37. 43 0
      src/store/live/couponsApply.js
  38. 43 0
      src/store/live/declare.js
  39. 58 0
      src/store/live/mechanism.js
  40. 43 0
      src/store/live/reward.js
  41. 25 0
      src/store/upload.js
  42. 117 0
      src/util/axios-wrapper.js
  43. 50 0
      src/util/methods-util.js
  44. 69 0
      src/util/user-util.js
  45. 0 5
      src/views/About.vue
  46. 0 18
      src/views/Home.vue
  47. 36 0
      src/views/index.vue
  48. 49 0
      vue.config.js

+ 3 - 0
.env

@@ -0,0 +1,3 @@
+VUE_APP_AXIOS_BASE_URL = ''
+VUE_APP_ROUTER="jlstpatent"
+VUE_APP_HOST="http://broadcast.kqyjy.com"

+ 33 - 0
.eslintrc.js

@@ -0,0 +1,33 @@
+// https://eslint.org/docs/user-guide/configuring
+
+module.exports = {
+  root: true,
+  env: {
+    node: true,
+  },
+  extends: ['plugin:vue/essential', '@vue/prettier'],
+  plugins: ['vue'],
+  rules: {
+    'max-len': [
+      'warn',
+      {
+        code: 500,
+      },
+    ],
+    'no-unused-vars': 'off',
+    'no-console': 'off',
+    'prettier/prettier': [
+      'warn',
+      {
+        singleQuote: true,
+        trailingComma: 'es5',
+        bracketSpacing: true,
+        jsxBracketSameLine: true,
+        printWidth: 160,
+      },
+    ],
+  },
+  parserOptions: {
+    parser: 'babel-eslint',
+  },
+};

+ 352 - 17
package-lock.json

@@ -1061,7 +1061,6 @@
       "version": "7.15.4",
       "resolved": "https://registry.npmmirror.com/@babel/runtime/download/@babel/runtime-7.15.4.tgz",
       "integrity": "sha1-/RfRa/34eObdAtGXU6OfqKjZyEo=",
-      "dev": true,
       "requires": {
         "regenerator-runtime": "^0.13.4"
       }
@@ -1170,6 +1169,11 @@
       "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=",
       "dev": true
     },
+    "@popperjs/core": {
+      "version": "2.10.2",
+      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz",
+      "integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ=="
+    },
     "@soda/friendly-errors-webpack-plugin": {
       "version": "1.8.0",
       "resolved": "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.8.0.tgz?cache=0&sync_timestamp=1607927406873&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40soda%2Ffriendly-errors-webpack-plugin%2Fdownload%2F%40soda%2Ffriendly-errors-webpack-plugin-1.8.0.tgz",
@@ -1240,6 +1244,11 @@
       "integrity": "sha1-pTUV2yXYA4N0OBtzryC7Ty5QjYc=",
       "dev": true
     },
+    "@stomp/stompjs": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@stomp/stompjs/-/stompjs-6.1.2.tgz",
+      "integrity": "sha512-FHDTrIFM5Ospi4L3Xhj6v2+NzCVAeNDcBe95YjUWhWiRMrBF6uN3I7AUOlRgT6jU/2WQvvYK8ZaIxFfxFp+uHQ=="
+    },
     "@types/body-parser": {
       "version": "1.19.1",
       "resolved": "https://registry.nlark.com/@types/body-parser/download/@types/body-parser-1.19.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fbody-parser%2Fdownload%2F%40types%2Fbody-parser-1.19.1.tgz",
@@ -1458,11 +1467,23 @@
         }
       }
     },
+    "@vant/icons": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/@vant/icons/-/icons-1.7.1.tgz",
+      "integrity": "sha512-66LPEq89w4kl258nALZcRNd14eUJC8VajvTJwvZKOaZawz6CUeVZ6ybhedTUhQhRjeA8SyWD7dFt4ALf33Sabw=="
+    },
+    "@vant/popperjs": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@vant/popperjs/-/popperjs-1.1.0.tgz",
+      "integrity": "sha512-8MD1gz146awV/uPxYjz4pet22f7a9YVKqk7T+gFkWFwT9mEcrIUEg/xPrdOnWKLP9puXyYtm7oVfSDSefZ/p/w==",
+      "requires": {
+        "@popperjs/core": "^2.9.2"
+      }
+    },
     "@vue/babel-helper-vue-jsx-merge-props": {
       "version": "1.2.1",
       "resolved": "https://registry.npm.taobao.org/@vue/babel-helper-vue-jsx-merge-props/download/@vue/babel-helper-vue-jsx-merge-props-1.2.1.tgz",
-      "integrity": "sha1-MWJKelBfsU2h1YAjclpMXycOaoE=",
-      "dev": true
+      "integrity": "sha1-MWJKelBfsU2h1YAjclpMXycOaoE="
     },
     "@vue/babel-helper-vue-transform-on": {
       "version": "1.0.2",
@@ -2330,6 +2351,14 @@
       "integrity": "sha1-3TeelPDbgxCwgpH51kwyCXZmF/0=",
       "dev": true
     },
+    "async-validator": {
+      "version": "1.8.5",
+      "resolved": "https://registry.nlark.com/async-validator/download/async-validator-1.8.5.tgz?cache=0&sync_timestamp=1630393311783&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fasync-validator%2Fdownload%2Fasync-validator-1.8.5.tgz",
+      "integrity": "sha1-3D4I7B/Q3dtn5ghC8CwM0c7G1/A=",
+      "requires": {
+        "babel-runtime": "6.x"
+      }
+    },
     "asynckit": {
       "version": "0.4.0",
       "resolved": "https://registry.npm.taobao.org/asynckit/download/asynckit-0.4.0.tgz",
@@ -2369,6 +2398,14 @@
       "integrity": "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk=",
       "dev": true
     },
+    "axios": {
+      "version": "0.22.0",
+      "resolved": "https://registry.npmmirror.com/axios/download/axios-0.22.0.tgz?cache=0&sync_timestamp=1633067673292&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Faxios%2Fdownload%2Faxios-0.22.0.tgz",
+      "integrity": "sha1-v3AsQftQ+8pFOVidg5oHcRe3myU=",
+      "requires": {
+        "follow-redirects": "^1.14.4"
+      }
+    },
     "babel-eslint": {
       "version": "10.1.0",
       "resolved": "https://registry.npm.taobao.org/babel-eslint/download/babel-eslint-10.1.0.tgz?cache=0&sync_timestamp=1611946213770&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-eslint%2Fdownload%2Fbabel-eslint-10.1.0.tgz",
@@ -2383,6 +2420,11 @@
         "resolve": "^1.12.0"
       }
     },
+    "babel-helper-vue-jsx-merge-props": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npm.taobao.org/babel-helper-vue-jsx-merge-props/download/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
+      "integrity": "sha1-Iq69OzOQIyjlEyk6jkmSs4T58bY="
+    },
     "babel-loader": {
       "version": "8.2.2",
       "resolved": "https://registry.npm.taobao.org/babel-loader/download/babel-loader-8.2.2.tgz?cache=0&sync_timestamp=1615270018746&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbabel-loader%2Fdownload%2Fbabel-loader-8.2.2.tgz",
@@ -2434,6 +2476,27 @@
         "@babel/helper-define-polyfill-provider": "^0.2.2"
       }
     },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npm.taobao.org/babel-runtime/download/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.6.12",
+          "resolved": "https://registry.npmmirror.com/core-js/download/core-js-2.6.12.tgz",
+          "integrity": "sha1-2TM9+nsGXjR8xWgiGdb2kIWcwuw="
+        },
+        "regenerator-runtime": {
+          "version": "0.11.1",
+          "resolved": "https://registry.nlark.com/regenerator-runtime/download/regenerator-runtime-0.11.1.tgz",
+          "integrity": "sha1-vgWtf5v30i4Fb5cmzuUBf78Z4uk="
+        }
+      }
+    },
     "balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npm.taobao.org/balanced-match/download/balanced-match-1.0.2.tgz?cache=0&sync_timestamp=1617714298273&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbalanced-match%2Fdownload%2Fbalanced-match-1.0.2.tgz",
@@ -2793,6 +2856,11 @@
         "isarray": "^1.0.0"
       }
     },
+    "buffer-equal-constant-time": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+      "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
+    },
     "buffer-from": {
       "version": "1.1.2",
       "resolved": "https://registry.nlark.com/buffer-from/download/buffer-from-1.1.2.tgz",
@@ -4082,8 +4150,7 @@
     "deepmerge": {
       "version": "1.5.2",
       "resolved": "https://registry.npm.taobao.org/deepmerge/download/deepmerge-1.5.2.tgz?cache=0&sync_timestamp=1606805746825&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdeepmerge%2Fdownload%2Fdeepmerge-1.5.2.tgz",
-      "integrity": "sha1-EEmdhohEza1P7ghC34x/bwyVp1M=",
-      "dev": true
+      "integrity": "sha1-EEmdhohEza1P7ghC34x/bwyVp1M="
     },
     "default-gateway": {
       "version": "5.0.5",
@@ -4259,6 +4326,11 @@
         }
       }
     },
+    "defined": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz",
+      "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4="
+    },
     "del": {
       "version": "4.1.1",
       "resolved": "https://registry.npm.taobao.org/del/download/del-4.1.1.tgz",
@@ -4514,6 +4586,30 @@
         "safer-buffer": "^2.1.0"
       }
     },
+    "ecdsa-sig-formatter": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+      "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "echarts": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.2.1.tgz",
+      "integrity": "sha512-OJ79b22eqRfbSV8vYmDKmA+XWfNbr0Uk/OafWcFNIGDWti2Uw9A6eVCiJLmqPa9Sk+EWL+t5v26aak0z3gxiZw==",
+      "requires": {
+        "tslib": "2.3.0",
+        "zrender": "5.2.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+        }
+      }
+    },
     "ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npm.taobao.org/ee-first/download/ee-first-1.1.1.tgz",
@@ -4532,6 +4628,36 @@
       "integrity": "sha1-Tgq8kY4cIrMGuhO0w2SfeClfWTc=",
       "dev": true
     },
+    "element": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/element/-/element-0.1.4.tgz",
+      "integrity": "sha1-FkInkGEyildKaS4OUYTmLBgKZoU=",
+      "requires": {
+        "ent": "0.0.5",
+        "global": "~2.0.7",
+        "lru-cache": "~2.3.0"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.3.1.tgz",
+          "integrity": "sha1-s632s9hW6VTiw5DmzvIggSRaU9Y="
+        }
+      }
+    },
+    "element-ui": {
+      "version": "2.15.6",
+      "resolved": "https://registry.nlark.com/element-ui/download/element-ui-2.15.6.tgz?cache=0&sync_timestamp=1630566711394&other_urls=https%3A%2F%2Fregistry.nlark.com%2Felement-ui%2Fdownload%2Felement-ui-2.15.6.tgz",
+      "integrity": "sha1-yWCa3TWvWmhqS3aF3B11fHXgHfM=",
+      "requires": {
+        "async-validator": "~1.8.1",
+        "babel-helper-vue-jsx-merge-props": "^2.0.0",
+        "deepmerge": "^1.2.0",
+        "normalize-wheel": "^1.0.1",
+        "resize-observer-polyfill": "^1.5.0",
+        "throttle-debounce": "^1.0.1"
+      }
+    },
     "elliptic": {
       "version": "6.5.4",
       "resolved": "https://registry.npm.taobao.org/elliptic/download/elliptic-6.5.4.tgz?cache=0&sync_timestamp=1612290836352&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Felliptic%2Fdownload%2Felliptic-6.5.4.tgz",
@@ -4605,6 +4731,11 @@
         }
       }
     },
+    "ent": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/ent/-/ent-0.0.5.tgz",
+      "integrity": "sha1-mLRJjYqJ17jXiveqoHFGdXg8e04="
+    },
     "entities": {
       "version": "2.2.0",
       "resolved": "https://registry.nlark.com/entities/download/entities-2.2.0.tgz",
@@ -5450,8 +5581,7 @@
     "follow-redirects": {
       "version": "1.14.4",
       "resolved": "https://registry.nlark.com/follow-redirects/download/follow-redirects-1.14.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.14.4.tgz",
-      "integrity": "sha1-g4/fSKi73XnlLuUfsclOPtmLk3k=",
-      "dev": true
+      "integrity": "sha1-g4/fSKi73XnlLuUfsclOPtmLk3k="
     },
     "for-in": {
       "version": "1.0.2",
@@ -5647,6 +5777,22 @@
       "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
       "dev": true
     },
+    "global": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/global/-/global-2.0.7.tgz",
+      "integrity": "sha1-1DqcPR7HkV9kXY4OsKxgAQ6eBs0=",
+      "requires": {
+        "min-document": "~0.2.2",
+        "process": "~0.5.1"
+      },
+      "dependencies": {
+        "process": {
+          "version": "0.5.2",
+          "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+          "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
+        }
+      }
+    },
     "globals": {
       "version": "11.12.0",
       "resolved": "https://registry.nlark.com/globals/download/globals-11.12.0.tgz",
@@ -6956,6 +7102,35 @@
         "graceful-fs": "^4.1.6"
       }
     },
+    "jsonify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
+    },
+    "jsonwebtoken": {
+      "version": "8.5.1",
+      "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+      "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+      "requires": {
+        "jws": "^3.2.2",
+        "lodash.includes": "^4.3.0",
+        "lodash.isboolean": "^3.0.3",
+        "lodash.isinteger": "^4.0.4",
+        "lodash.isnumber": "^3.0.3",
+        "lodash.isplainobject": "^4.0.6",
+        "lodash.isstring": "^4.0.1",
+        "lodash.once": "^4.0.0",
+        "ms": "^2.1.1",
+        "semver": "^5.6.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+        }
+      }
+    },
     "jsprim": {
       "version": "1.4.1",
       "resolved": "https://registry.npm.taobao.org/jsprim/download/jsprim-1.4.1.tgz",
@@ -6968,6 +7143,25 @@
         "verror": "1.10.0"
       }
     },
+    "jwa": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+      "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+      "requires": {
+        "buffer-equal-constant-time": "1.0.1",
+        "ecdsa-sig-formatter": "1.0.11",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "jws": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+      "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+      "requires": {
+        "jwa": "^1.4.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "killable": {
       "version": "1.0.1",
       "resolved": "https://registry.npm.taobao.org/killable/download/killable-1.0.1.tgz",
@@ -7164,6 +7358,11 @@
         }
       }
     },
+    "loadsh": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npm.taobao.org/loadsh/download/loadsh-0.0.4.tgz",
+      "integrity": "sha1-UxS6vRK7EzFd3gJKTKcHWMVInS0="
+    },
     "locate-path": {
       "version": "5.0.0",
       "resolved": "https://registry.nlark.com/locate-path/download/locate-path-5.0.0.tgz?cache=0&sync_timestamp=1629895702340&other_urls=https%3A%2F%2Fregistry.nlark.com%2Flocate-path%2Fdownload%2Flocate-path-5.0.0.tgz",
@@ -7176,8 +7375,7 @@
     "lodash": {
       "version": "4.17.21",
       "resolved": "https://registry.npm.taobao.org/lodash/download/lodash-4.17.21.tgz",
-      "integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=",
-      "dev": true
+      "integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw="
     },
     "lodash.debounce": {
       "version": "4.0.8",
@@ -7191,6 +7389,36 @@
       "integrity": "sha1-US6b1yHSctlOPTpjZT+hdRZ0HKY=",
       "dev": true
     },
+    "lodash.includes": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+      "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
+    },
+    "lodash.isboolean": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+      "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
+    },
+    "lodash.isinteger": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+      "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
+    },
+    "lodash.isnumber": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+      "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
+    },
+    "lodash.isplainobject": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+      "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
+    },
+    "lodash.isstring": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+      "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
+    },
     "lodash.kebabcase": {
       "version": "4.1.1",
       "resolved": "https://registry.npm.taobao.org/lodash.kebabcase/download/lodash.kebabcase-4.1.1.tgz",
@@ -7209,6 +7437,11 @@
       "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
       "dev": true
     },
+    "lodash.once": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+      "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
+    },
     "lodash.transform": {
       "version": "4.6.0",
       "resolved": "https://registry.npm.taobao.org/lodash.transform/download/lodash.transform-4.6.0.tgz",
@@ -7415,6 +7648,14 @@
       "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=",
       "dev": true
     },
+    "min-document": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmjs.org/min-document/-/min-document-0.2.8.tgz",
+      "integrity": "sha1-82IM9WA2ERVcuUFtCrVXaxbVPeM=",
+      "requires": {
+        "tape": "~1.0.2"
+      }
+    },
     "mini-css-extract-plugin": {
       "version": "0.9.0",
       "resolved": "https://registry.nlark.com/mini-css-extract-plugin/download/mini-css-extract-plugin-0.9.0.tgz",
@@ -7544,6 +7785,11 @@
         "minimist": "^1.2.5"
       }
     },
+    "moment": {
+      "version": "2.29.1",
+      "resolved": "https://registry.npm.taobao.org/moment/download/moment-2.29.1.tgz",
+      "integrity": "sha1-sr52n6MZQL6e7qZGnAdeNQBvo9M="
+    },
     "move-concurrently": {
       "version": "1.0.1",
       "resolved": "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz",
@@ -7561,8 +7807,7 @@
     "ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmmirror.com/ms/download/ms-2.1.2.tgz?cache=0&sync_timestamp=1632788163669&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fms%2Fdownload%2Fms-2.1.2.tgz",
-      "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=",
-      "dev": true
+      "integrity": "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk="
     },
     "multicast-dns": {
       "version": "6.2.3",
@@ -7597,6 +7842,14 @@
         "thenify-all": "^1.0.0"
       }
     },
+    "naf-core": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npm.taobao.org/naf-core/download/naf-core-0.1.2.tgz",
+      "integrity": "sha1-0UetT3+BTsnSvYGPWCOVHgWAsJU=",
+      "requires": {
+        "lodash": "^4.17.11"
+      }
+    },
     "nan": {
       "version": "2.15.0",
       "resolved": "https://registry.nlark.com/nan/download/nan-2.15.0.tgz?cache=0&sync_timestamp=1628093719696&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fnan%2Fdownload%2Fnan-2.15.0.tgz",
@@ -7763,6 +8016,11 @@
       "integrity": "sha1-suHE3E98bVd0PfczpPWXjRhlBVk=",
       "dev": true
     },
+    "normalize-wheel": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npm.taobao.org/normalize-wheel/download/normalize-wheel-1.0.1.tgz",
+      "integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
+    },
     "npm-run-path": {
       "version": "2.0.2",
       "resolved": "https://registry.npmmirror.com/npm-run-path/download/npm-run-path-2.0.2.tgz",
@@ -9198,8 +9456,7 @@
     "regenerator-runtime": {
       "version": "0.13.9",
       "resolved": "https://registry.nlark.com/regenerator-runtime/download/regenerator-runtime-0.13.9.tgz",
-      "integrity": "sha1-iSV0Kpj/2QgUmI11Zq0wyjsmO1I=",
-      "dev": true
+      "integrity": "sha1-iSV0Kpj/2QgUmI11Zq0wyjsmO1I="
     },
     "regenerator-transform": {
       "version": "0.14.5",
@@ -9429,6 +9686,11 @@
       "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
       "dev": true
     },
+    "resize-observer-polyfill": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npm.taobao.org/resize-observer-polyfill/download/resize-observer-polyfill-1.5.1.tgz",
+      "integrity": "sha1-DpAg3T0hAkRY1OvSfiPkAmmBBGQ="
+    },
     "resolve": {
       "version": "1.20.0",
       "resolved": "https://registry.npm.taobao.org/resolve/download/resolve-1.20.0.tgz",
@@ -9540,8 +9802,7 @@
     "safe-buffer": {
       "version": "5.1.2",
       "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.1.2.tgz",
-      "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=",
-      "dev": true
+      "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0="
     },
     "safe-regex": {
       "version": "1.1.0",
@@ -10470,6 +10731,24 @@
       "integrity": "sha1-ofzMBrWNth/XpF2i2kT186Pme6I=",
       "dev": true
     },
+    "tape": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/tape/-/tape-1.0.4.tgz",
+      "integrity": "sha1-4ujlxt0/AP3CpeRRT2L8Ih5Z+cQ=",
+      "requires": {
+        "deep-equal": "~0.0.0",
+        "defined": "~0.0.0",
+        "jsonify": "~0.0.0",
+        "through": "~2.3.4"
+      },
+      "dependencies": {
+        "deep-equal": {
+          "version": "0.0.0",
+          "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.0.0.tgz",
+          "integrity": "sha1-mWedO70EcVb81FDT0B7rkGhpHoM="
+        }
+      }
+    },
     "terser": {
       "version": "4.8.0",
       "resolved": "https://registry.nlark.com/terser/download/terser-4.8.0.tgz?cache=0&sync_timestamp=1632229914828&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fterser%2Fdownload%2Fterser-4.8.0.tgz",
@@ -10630,11 +10909,15 @@
         "neo-async": "^2.6.0"
       }
     },
+    "throttle-debounce": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npm.taobao.org/throttle-debounce/download/throttle-debounce-1.1.0.tgz",
+      "integrity": "sha1-UYU9o3vmihVctugns1FKPEIuic0="
+    },
     "through": {
       "version": "2.3.8",
       "resolved": "https://registry.npm.taobao.org/through/download/through-2.3.8.tgz",
-      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
-      "dev": true
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
     },
     "through2": {
       "version": "2.0.5",
@@ -11127,6 +11410,18 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
+    "vant": {
+      "version": "2.12.29",
+      "resolved": "https://registry.npmjs.org/vant/-/vant-2.12.29.tgz",
+      "integrity": "sha512-LFLShCM6TFGv2yfDqBDQRuTd7vS7LjmsHpdJLbmyt1rqtGU1yOamtIgMVvvjKluqg5FoIvcBjaO94p6lKAf9NQ==",
+      "requires": {
+        "@babel/runtime": "7.x",
+        "@vant/icons": "^1.7.1",
+        "@vant/popperjs": "^1.1.0",
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
+        "vue-lazyload": "1.2.3"
+      }
+    },
     "vary": {
       "version": "1.1.2",
       "resolved": "https://registry.npm.taobao.org/vary/download/vary-1.1.2.tgz",
@@ -11194,6 +11489,11 @@
       "integrity": "sha1-UylVzB6yCKPZkLOp+acFdGV+CPI=",
       "dev": true
     },
+    "vue-lazyload": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/vue-lazyload/-/vue-lazyload-1.2.3.tgz",
+      "integrity": "sha512-DC0ZwxanbRhx79tlA3zY5OYJkH8FYp3WBAnAJbrcuoS8eye1P73rcgAZhyxFSPUluJUTelMB+i/+VkNU/qVm7g=="
+    },
     "vue-loader": {
       "version": "15.9.8",
       "resolved": "https://registry.npmmirror.com/vue-loader/download/vue-loader-15.9.8.tgz?cache=0&sync_timestamp=1632349895587&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fvue-loader%2Fdownload%2Fvue-loader-15.9.8.tgz",
@@ -11296,6 +11596,21 @@
         }
       }
     },
+    "vue-meta": {
+      "version": "2.4.0",
+      "resolved": "https://registry.nlark.com/vue-meta/download/vue-meta-2.4.0.tgz?cache=0&sync_timestamp=1623026709800&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvue-meta%2Fdownload%2Fvue-meta-2.4.0.tgz",
+      "integrity": "sha1-pBn7S0E1zpZdqzLsZB0ZicLuSEU=",
+      "requires": {
+        "deepmerge": "^4.2.2"
+      },
+      "dependencies": {
+        "deepmerge": {
+          "version": "4.2.2",
+          "resolved": "https://registry.npm.taobao.org/deepmerge/download/deepmerge-4.2.2.tgz?cache=0&sync_timestamp=1606805746825&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdeepmerge%2Fdownload%2Fdeepmerge-4.2.2.tgz",
+          "integrity": "sha1-RNLqNnm49NT/ujPwPYZfwee/SVU="
+        }
+      }
+    },
     "vue-router": {
       "version": "3.5.2",
       "resolved": "https://registry.nlark.com/vue-router/download/vue-router-3.5.2.tgz",
@@ -11998,6 +12313,11 @@
       "integrity": "sha1-f4RzvIOd/YdgituV1+sHUhFXikI=",
       "dev": true
     },
+    "weixin-js-sdk": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/weixin-js-sdk/-/weixin-js-sdk-1.6.0.tgz",
+      "integrity": "sha512-3IYQH7aalJGFJrwdT3epvTdR1MboMiH7vIZ5BRL2eYOJ12BNah7csoMkmSZzkq1+l92sSq29XdTCVjCJoK2sBQ=="
+    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.npm.taobao.org/which/download/which-1.3.1.tgz",
@@ -12227,6 +12547,21 @@
           "dev": true
         }
       }
+    },
+    "zrender": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.2.1.tgz",
+      "integrity": "sha512-M3bPGZuyLTNBC6LiNKXJwSCtglMp8XUEqEBG+2MdICDI3d1s500Y4P0CzldQGsqpRVB7fkvf3BKQQRxsEaTlsw==",
+      "requires": {
+        "tslib": "2.3.0"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
+          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+        }
+      }
     }
   }
 }

+ 13 - 1
package.json

@@ -8,10 +8,22 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@stomp/stompjs": "^6.1.2",
+    "axios": "^0.22.0",
     "core-js": "^3.6.5",
+    "echarts": "^5.2.1",
+    "element": "^0.1.4",
+    "element-ui": "^2.15.6",
+    "jsonwebtoken": "^8.5.1",
+    "loadsh": "0.0.4",
+    "moment": "^2.29.1",
+    "naf-core": "^0.1.2",
+    "vant": "^2.12.29",
     "vue": "^2.6.11",
+    "vue-meta": "^2.4.0",
     "vue-router": "^3.2.0",
-    "vuex": "^3.4.0"
+    "vuex": "^3.4.0",
+    "weixin-js-sdk": "^1.6.0"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "~4.5.0",

+ 14 - 22
src/App.vue

@@ -1,32 +1,24 @@
 <template>
   <div id="app">
-    <div id="nav">
-      <router-link to="/">Home</router-link> |
-      <router-link to="/about">About</router-link>
-    </div>
     <router-view />
   </div>
 </template>
 
+<script>
+export default {
+  created() {},
+  methods: {},
+};
+</script>
+
 <style lang="less">
-#app {
-  font-family: Avenir, Helvetica, Arial, sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  text-align: center;
-  color: #2c3e50;
+p {
+  padding: 0;
+  margin: 0;
 }
-
-#nav {
-  padding: 30px;
-
-  a {
-    font-weight: bold;
-    color: #2c3e50;
-
-    &.router-link-exact-active {
-      color: #42b983;
-    }
-  }
+.textOver {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 </style>

+ 13 - 55
src/components/HelloWorld.vue

@@ -4,43 +4,21 @@
     <p>
       For a guide and recipes on how to configure / customize this project,<br />
       check out the
-      <a href="https://cli.vuejs.org" target="_blank" rel="noopener"
-        >vue-cli documentation</a
-      >.
+      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
     </p>
     <h3>Installed CLI Plugins</h3>
     <ul>
       <li>
-        <a
-          href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
-          target="_blank"
-          rel="noopener"
-          >babel</a
-        >
+        <a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a>
       </li>
       <li>
-        <a
-          href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router"
-          target="_blank"
-          rel="noopener"
-          >router</a
-        >
+        <a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a>
       </li>
       <li>
-        <a
-          href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex"
-          target="_blank"
-          rel="noopener"
-          >vuex</a
-        >
+        <a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a>
       </li>
       <li>
-        <a
-          href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
-          target="_blank"
-          rel="noopener"
-          >eslint</a
-        >
+        <a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a>
       </li>
     </ul>
     <h3>Essential Links</h3>
@@ -49,19 +27,13 @@
         <a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
       </li>
       <li>
-        <a href="https://forum.vuejs.org" target="_blank" rel="noopener"
-          >Forum</a
-        >
+        <a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a>
       </li>
       <li>
-        <a href="https://chat.vuejs.org" target="_blank" rel="noopener"
-          >Community Chat</a
-        >
+        <a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a>
       </li>
       <li>
-        <a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
-          >Twitter</a
-        >
+        <a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a>
       </li>
       <li>
         <a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
@@ -70,33 +42,19 @@
     <h3>Ecosystem</h3>
     <ul>
       <li>
-        <a href="https://router.vuejs.org" target="_blank" rel="noopener"
-          >vue-router</a
-        >
+        <a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a>
       </li>
       <li>
         <a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
       </li>
       <li>
-        <a
-          href="https://github.com/vuejs/vue-devtools#vue-devtools"
-          target="_blank"
-          rel="noopener"
-          >vue-devtools</a
-        >
+        <a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a>
       </li>
       <li>
-        <a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener"
-          >vue-loader</a
-        >
+        <a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a>
       </li>
       <li>
-        <a
-          href="https://github.com/vuejs/awesome-vue"
-          target="_blank"
-          rel="noopener"
-          >awesome-vue</a
-        >
+        <a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a>
       </li>
     </ul>
   </div>
@@ -104,7 +62,7 @@
 
 <script>
 export default {
-  name: "HelloWorld",
+  name: 'HelloWorld',
   props: {
     msg: String,
   },

+ 69 - 0
src/components/c-select.vue

@@ -0,0 +1,69 @@
+<template>
+  <div id="c-select">
+    <van-cell :title="label" @click="show = true">
+      <span v-if="mval" style="color: #000">{{ mval }}</span>
+      <span v-else>{{ `请选择${label}` }}</span>
+    </van-cell>
+    <van-popup v-model="show" show-toolbar position="bottom">
+      <van-picker v-if="type === 'select'" :value-key="valueKey" :title="label" show-toolbar :columns="list" @confirm="onConfirm" @cancel="show = false" />
+      <van-checkbox-group v-model="multi" v-else>
+        <van-picker :title="label" :show-toolbar="true" :columns="list" @confirm="onConfirm" @cancel="show = false">
+          <template #option="item">
+            <van-checkbox :name="item">{{ item }}</van-checkbox>
+          </template>
+        </van-picker>
+      </van-checkbox-group>
+    </van-popup>
+  </div>
+</template>
+
+<script>
+const _ = require('lodash');
+export default {
+  name: 'c-select',
+  props: {
+    label: { type: String },
+    mval: { type: String },
+    list: { type: Array, default: () => [] },
+    type: { type: String },
+    valueKey: { type: String },
+  },
+  model: {
+    prop: 'mval',
+    event: 'change',
+  },
+  components: {},
+  data: function () {
+    return {
+      show: false,
+      selectList: [],
+      multi: [],
+    };
+  },
+  created() {},
+  methods: {
+    onConfirm(value) {
+      if (this.type === 'select') this.$emit('change', value);
+      else {
+        const str = this.multi.join(',');
+        this.$emit('change', str);
+      }
+      this.show = false;
+    },
+  },
+  computed: {
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.van-cell__value {
+  text-align: left;
+}
+</style>

+ 74 - 0
src/components/footers.vue

@@ -0,0 +1,74 @@
+<template>
+  <div id="footers">
+    <van-grid :column-num="list.length" clickable>
+      <van-grid-item v-for="(i, index) in list" :key="`menu-${index}`" :text="i.label" :to="i.router" />
+    </van-grid>
+  </div>
+</template>
+
+<script>
+import { mapState, mapGetters, mapMutations, createNamespacedHelpers } from 'vuex';
+const { mapActions: column } = createNamespacedHelpers('column');
+export default {
+  name: 'footers',
+  props: {},
+  components: {},
+  data: function () {
+    return {
+      list: [],
+    };
+  },
+  mounted() {
+    this.initMenu();
+  },
+  methods: {
+    ...column(['query']),
+    ...mapMutations(['setMenu']),
+    async initMenu() {
+      let columns = sessionStorage.getItem('columns');
+      if (!columns) {
+        let res = await this.getColumns();
+        columns = res;
+      }
+      columns = JSON.parse(columns);
+      this.setMenu(columns);
+      this.$set(this, `list`, this.getMenu(this.keyWord));
+    },
+    async getColumns() {
+      const res = await this.query();
+      if (this.$checkRes(res)) {
+        sessionStorage.setItem('columns', JSON.stringify(res.data));
+        return JSON.stringify(res.data);
+      }
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    ...mapGetters(['getMenu']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    keyWord() {
+      return this.$route.meta.key;
+    },
+  },
+  watch: {
+    $route: {
+      handler(to, form) {
+        this.initMenu();
+      },
+      deep: true,
+      immediate: true,
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.van-grid-item__content {
+  padding: 11px 8px;
+}
+</style>

+ 17 - 0
src/components/vForm.md

@@ -0,0 +1,17 @@
+# vForm
+
+|属性名|数据类型|默认值|是否必要|描述|
+|:--:|:--:|:--:|:--:|:--:|
+|v-model|Object|`-`|true|存放值的地方(不知道咋解释好,┓( ´∀` )┏)|
+|fields|Array|`[]`|`-`|字段|
+
+### fields
+|属性名|数据类型|默认值|是否必要|描述|
+|:--:|:--:|:--:|:--:|:--:|
+|label|String|`-`|false|字段中文/XX文|
+|model|String|`-`|true|字段在数据库的key,不写就别用了,(╯‵□′)╯︵┻━┻|
+|rules|Array|`[]`|false|输入类型的验证,validator写法,不懂百度|
+|required|Boolean|`-`|false|是否必填/选|
+|type|String|`-`|false|本字段类型:input,select,date....|
+|selectKey|String|`-`|=>|若type为select类型,必填,表示在选择的时候,看哪个字段的内容|
+|selectProp|String|`-`|=>|若type为select类型,表示在选择的时候,选择哪个字段,若没有值,则选择这个object|

+ 103 - 0
src/components/vForm.vue

@@ -0,0 +1,103 @@
+<template>
+  <div id="vForm">
+    <van-form @submit="onSubmit">
+      <template v-for="(f, fi) in fields">
+        <template v-if="!f.type || f.type === 'input'">
+          <van-field
+            :key="`${fi}.${f.model}`"
+            v-model="value[f.model]"
+            :label="f.label"
+            :placeholder="`${f.label}`"
+            :rules="f.rules ? f.rules : []"
+            :required="f.required"
+          />
+        </template>
+        <template v-if="f.type === 'date'">
+          <v-date :key="`${fi}.${f.model}`" v-model="value[f.model]" :label="f.label" :required="f.required"></v-date>
+        </template>
+        <template v-if="f.type === 'select'">
+          <v-select
+            :key="`${fi}.${f.model}`"
+            v-model="value[f.model]"
+            :label="f.label"
+            :list="getSelectList(f.model)"
+            :labelKey="f.selectKey"
+            :prop="f.selectProp"
+            :required="f.required"
+          ></v-select>
+        </template>
+        <template v-if="f.type === 'textarea'">
+          <van-field
+            :key="`${fi}.${f.model}`"
+            v-model="value[f.model]"
+            :label="f.label"
+            rows="2"
+            autosize
+            type="textarea"
+            :placeholder="`请输入${f.label}`"
+            :required="f.required"
+          />
+        </template>
+      </template>
+      <div style="margin: 16px">
+        <van-button round block type="info" native-type="submit">提交</van-button>
+      </div>
+    </van-form>
+  </div>
+</template>
+
+<script>
+const _ = require('lodash');
+import vDate from '@/components/vdate.vue';
+import vSelect from '@/components/vselect.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'vForm',
+  props: {
+    value: { type: Object, required: true },
+    fields: { type: Array, default: () => [] },
+  },
+
+  components: { vDate, vSelect },
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    onSubmit() {
+      // 进入submit后,只能说明,有rules的是按要求输入的,其余的select,date还未验证,需要此处验证
+      const needCheck = this.fields.filter((f) => f.required);
+      const checkResult = this.checkRequired(needCheck);
+      if (!checkResult) return;
+      this.$emit('submit', _.cloneDeep(this.value));
+    },
+    checkRequired(checkList) {
+      let res = true;
+      for (const field of checkList) {
+        const { model, label } = field;
+        if (!this.value[model]) {
+          this.$toast({ type: 'fail', message: `请完善${label}项` });
+          res = false;
+          break;
+        }
+      }
+      return res;
+    },
+    getSelectList(model) {
+      const selectList = _.get(this.$attrs, `${model}List`, []);
+      return selectList;
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 61 - 0
src/components/vcheckbox.vue

@@ -0,0 +1,61 @@
+<template>
+  <div id="vcheckbox">
+    <van-field :value="display" :label="label" :placeholder="`请选择${label}`" readonly @click="show = true" />
+    <van-popup v-model="show" show-toolbar position="bottom">
+      <van-picker :title="label" show-toolbar :value-key="labelKey" :columns="list" @confirm="onConfirm" @cancel="show = false" />
+    </van-popup>
+  </div>
+</template>
+
+<script>
+const _ = require('lodash');
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'vcheckbox',
+  props: {
+    label: { type: String }, //字段中文
+    mval: { type: String }, //v-model
+    list: { type: Array }, //选择的列表
+    labelKey: { type: String, default: 'name' }, //如果选项为object,选择哪个字段作为显示的选项
+    prop: { type: String }, // 如果选项为object,选择哪个字段作为v-model的值,没有的话就把该项作为值给v-model
+  },
+  model: {
+    prop: 'mval',
+    event: 'change',
+  },
+  components: {},
+  data: function () {
+    return {
+      show: false,
+    };
+  },
+  created() {},
+  methods: {
+    onConfirm(value) {
+      if (this.prop) this.$emit('change', _.get(value, this.prop));
+      else this.$emit('change', value);
+      this.show = false;
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    display() {
+      let value = '';
+      if (this.mval) value = this.mval;
+      if (this.prop) {
+        const r = this.list.find((f) => f[this.prop] === value);
+        if (r) value = r[this.labelKey];
+      }
+      return value;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 67 - 0
src/components/vdate.vue

@@ -0,0 +1,67 @@
+<template>
+  <div id="vdate">
+    <van-field :value="mval" :label="label" :placeholder="`请选择${label}`" readonly @click="show = true" :required="required" />
+    <van-popup v-model="show" show-toolbar position="bottom">
+      <van-datetime-picker
+        :value="cdate"
+        type="date"
+        :title="`请选择${label}`"
+        :min-date="minDate"
+        :max-date="maxDate"
+        @cancel="show = false"
+        @confirm="toConfirm"
+      />
+    </van-popup>
+  </div>
+</template>
+
+<script>
+const _ = require('lodash');
+const moment = require('moment');
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'vdate',
+  props: {
+    label: { type: String }, //字段中文
+    mval: { type: String }, //v-model
+    required: { type: Boolean, default: false },
+  },
+  model: {
+    prop: 'mval',
+    event: 'change',
+  },
+  components: {},
+  data: function () {
+    return {
+      show: false,
+      minDate: new Date(1990, 0, 1),
+      maxDate: new Date(),
+    };
+  },
+  created() {},
+  methods: {
+    toConfirm(val) {
+      this.$emit('change', moment(val).format('YYYY-MM-DD'));
+      this.show = false;
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    cdate() {
+      let date = '';
+      if (this.mval) {
+        date = new Date(this.mval);
+      }
+      return date;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 61 - 0
src/components/vselect copy.vue

@@ -0,0 +1,61 @@
+<template>
+  <div id="vselect">
+    <van-field :value="display" :label="label" :placeholder="`请选择${label}`" readonly @click="show = true" />
+    <van-popup v-model="show" show-toolbar position="bottom">
+      <van-picker :title="label" show-toolbar :value-key="labelKey" :columns="list" @confirm="onConfirm" @cancel="show = false" />
+    </van-popup>
+  </div>
+</template>
+
+<script>
+const _ = require('lodash');
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'vselect',
+  props: {
+    label: { type: String }, //字段中文
+    mval: { type: String }, //v-model
+    list: { type: Array }, //选择的列表
+    labelKey: { type: String, default: 'name' }, //如果选项为object,选择哪个字段作为显示的选项
+    prop: { type: String }, // 如果选项为object,选择哪个字段作为v-model的值,没有的话就把该项作为值给v-model
+  },
+  model: {
+    prop: 'mval',
+    event: 'change',
+  },
+  components: {},
+  data: function () {
+    return {
+      show: false,
+    };
+  },
+  created() {},
+  methods: {
+    onConfirm(value) {
+      if (this.prop) this.$emit('change', _.get(value, this.prop));
+      else this.$emit('change', value);
+      this.show = false;
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    display() {
+      let value = '';
+      if (this.mval) value = this.mval;
+      if (this.prop) {
+        const r = this.list.find((f) => f[this.prop] === value);
+        if (r) value = r[this.labelKey];
+      }
+      return value;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 62 - 0
src/components/vselect.vue

@@ -0,0 +1,62 @@
+<template>
+  <div id="vselect">
+    <van-field :value="display" :label="label" :placeholder="`请选择${label}`" readonly @click="show = true" :required="required" />
+    <van-popup v-model="show" show-toolbar position="bottom">
+      <van-picker :title="label" show-toolbar :value-key="labelKey" :columns="list" @confirm="onConfirm" @cancel="show = false" />
+    </van-popup>
+  </div>
+</template>
+
+<script>
+const _ = require('lodash');
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'vselect',
+  props: {
+    label: { type: String }, //字段中文
+    mval: { type: String }, //v-model
+    list: { type: Array }, //选择的列表
+    labelKey: { type: String, default: 'name' }, //如果选项为object,选择哪个字段作为显示的选项
+    prop: { type: String }, // 如果选项为object,选择哪个字段作为v-model的值,没有的话就把该项作为值给v-model
+    required: { type: Boolean, default: false },
+  },
+  model: {
+    prop: 'mval',
+    event: 'change',
+  },
+  components: {},
+  data: function () {
+    return {
+      show: false,
+    };
+  },
+  created() {},
+  methods: {
+    onConfirm(value) {
+      if (this.prop) this.$emit('change', _.get(value, this.prop));
+      else this.$emit('change', value);
+      this.show = false;
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+    display() {
+      let value = '';
+      if (this.mval) value = this.mval;
+      if (this.prop) {
+        const r = this.list.find((f) => f[this.prop] === value);
+        if (r) value = r[this.labelKey];
+      }
+      return value;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 55 - 0
src/components/vupload.vue

@@ -0,0 +1,55 @@
+<template>
+  <div id="vupload">
+    <van-uploader :fileList="fileList" :after-read="upload" accept="*" @delete="toDelete" />
+  </div>
+</template>
+
+<script>
+const _ = require('lodash');
+import axios from 'axios';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'vupload',
+  props: {
+    fileList: { type: Array },
+    url: { type: String, required: true },
+  },
+  model: {
+    prop: 'fileList',
+    event: 'change',
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {
+    async upload({ file }) {
+      let formdata = new FormData();
+      formdata.append('file', file, file.name);
+      const res = await axios.post(this.url, formdata, { headers: { 'Content-Type': 'multipart/form-data' } });
+      if (res.status === 200 && res.data.errcode == 0) {
+        const { id, name, uri } = res.data;
+        const obj = { name, url: uri };
+        this.fileList.push(obj);
+      }
+    },
+    toDelete(file) {
+      console.log(file);
+      const index = this.fileList.findIndex((f) => _.isEqual(f, file));
+      if (index > -1) this.fileList.splice(index, 1);
+    },
+  },
+  computed: {
+    ...mapState(['user', 'menuParams']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 88 - 0
src/layout/common/admin-frame.vue

@@ -0,0 +1,88 @@
+<template>
+  <div id="admin-frame">
+    <van-row>
+      <van-col span="24" class="main" :style="{ height: client.height + 'px' }">
+        <van-col span="24" class="top" style="height: 40px" v-if="useTop">
+          <top :topType="topType" @search="search" :leftArrow="leftArrow" @back="back"></top>
+        </van-col>
+        <van-col span="24" class="info" :style="{ height: getHeight() }"><slot name="info"></slot></van-col>
+        <van-col span="24" class="page" style="height: 40px" v-if="usePage"><page :limit="limit" :total="total" @search="search"></page></van-col>
+      </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import top from './top.vue';
+import page from './page.vue';
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'admin-frame',
+  props: {
+    // 头部信息
+    useTop: { type: Boolean, default: () => true },
+    topType: { type: String, default: () => '1' },
+    leftArrow: { type: Boolean, default: () => true },
+    // 分页
+    usePage: { type: Boolean, default: () => true },
+    limit: { type: Number, default: () => 10 },
+    total: { type: Number, default: () => 0 },
+  },
+  components: {
+    top,
+    page,
+  },
+  data: function () {
+    return {
+      client: {},
+    };
+  },
+  created() {},
+  methods: {
+    back() {
+      this.$emit('back');
+    },
+    search(skip) {
+      this.$emit('search', skip);
+    },
+    // 计算高度
+    getHeight() {
+      let top = 0;
+      let page = 0;
+      if (this.useTop) top = 40;
+      if (this.usePage) page = 40;
+      return this.client.height - top - page + 'px';
+    },
+  },
+  mounted() {
+    let client = {
+      height: document.documentElement.clientHeight || document.body.clientHeight,
+      width: document.documentElement.clientWidth || document.body.clientWidth,
+    };
+    this.$set(this, `client`, client);
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.main {
+  .info {
+    overflow-x: hidden;
+    overflow-y: auto;
+    background-color: #f9f9f9;
+  }
+}
+</style>

+ 42 - 0
src/layout/common/footers.vue

@@ -0,0 +1,42 @@
+<template>
+  <div id="footers">
+    <div class="footers">
+      <van-grid :column-num="list.length" clickable>
+        <van-grid-item v-for="(i, index) in list" :key="`menu-${index}`" :text="i.label" :to="i.router" />
+      </van-grid>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'footers',
+  props: {
+    list: { type: Array, default: () => [] },
+  },
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+    pageTitle() {
+      return `${this.$route.meta.title}`;
+    },
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.footers {
+  position: fixed;
+  bottom: 0px;
+  width: 100%;
+}
+</style>

+ 47 - 0
src/layout/common/page.vue

@@ -0,0 +1,47 @@
+<template>
+  <div id="page">
+    <el-row>
+      <el-col :span="24" class="main">
+        <van-pagination v-model="currentPage" @change="changePage" :total-items="total" :items-per-page="limit" :show-page-size="5" force-ellipses />
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'page',
+  props: {
+    total: { type: Number },
+    limit: { type: Number, default: () => 6 },
+  },
+  components: {},
+  data: function () {
+    return {
+      currentPage: 1,
+    };
+  },
+  created() {},
+  methods: {
+    changePage(page) {
+      this.$emit('search', { skip: (page - 1) * this.limit });
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 7 - 0
src/layout/common/top.md

@@ -0,0 +1,7 @@
+<!-- 头部类型 -->
+# topType
+## topType=="1" 带有查询,查询方法:search
+
+## topType=="2" 带有标题和返回,返回方法:back
+
+## topType=="3" 带有返回和查询,返回方法:back,查询方法:search

+ 127 - 0
src/layout/common/top.vue

@@ -0,0 +1,127 @@
+<template>
+  <div id="top">
+    <el-col :span="24" class="one" v-if="topType == '1'">
+      <van-search v-model="searchName" placeholder="请输入信息标题" @search="search" />
+    </el-col>
+    <el-col :span="24" class="two" v-else-if="topType == '2'">
+      <van-nav-bar :title="this.$route.meta.title" :left-arrow="leftArrow" @click-left="upBack">
+        <template #left>
+          <span v-if="leftArrow">
+            <van-icon name="arrow-left" />
+            <span style="color: #409eff">返回</span>
+          </span>
+        </template>
+      </van-nav-bar>
+    </el-col>
+    <el-col :span="24" class="thr" v-else-if="topType == '3'">
+      <el-col :span="4" class="back" @click.native="upBack"> <van-icon name="arrow-left" />返回 </el-col>
+      <el-col :span="20" class="search">
+        <van-search v-model="searchName" placeholder="请输入信息" @search="search" />
+      </el-col>
+    </el-col>
+    <el-col :span="24" class="four" v-else-if="topType == '4'">
+      <el-col :span="4" class="back" @click.native="upBack"> <van-icon name="arrow-left" />返回 </el-col>
+      <el-col :span="16" class="title">
+        {{ $route.meta.title }}
+      </el-col>
+      <el-col :span="4" class="add">
+        <van-button icon="plus" size="small" type="info" round @click="add" />
+      </el-col>
+    </el-col>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'top',
+  props: {
+    topType: { type: String, default: () => '1' },
+    // 只有类型为2时,有用
+    leftArrow: { type: Boolean, default: () => true },
+  },
+  components: {},
+  data: function () {
+    return {
+      searchName: '',
+    };
+  },
+  created() {},
+  methods: {
+    // 查询
+    search() {
+      this.$emit('search', { searchName: this.searchName });
+    },
+    // 返回
+    upBack() {
+      this.$emit('back');
+    },
+    // 添加
+    add() {
+      this.$emit('add');
+    },
+  },
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.one {
+  /deep/.van-search {
+    padding: 3px 5px;
+  }
+}
+.two {
+  /deep/.van-nav-bar__content {
+    height: 40px;
+  }
+  /deep/.van-icon {
+    top: 2px;
+  }
+}
+.thr {
+  .back {
+    color: #409eff;
+    padding: 8px 0;
+    text-align: center;
+    .van-icon {
+      top: 3px;
+    }
+  }
+  .search {
+    /deep/.van-search {
+      padding: 2px 5px 2px 0px;
+    }
+  }
+}
+.four {
+  .back {
+    color: #409eff;
+    padding: 8px 0;
+    text-align: center;
+    .van-icon {
+      top: 3px;
+    }
+  }
+  .title {
+    text-align: center;
+    padding: 9px 0;
+  }
+  .add {
+    text-align: center;
+    padding: 4px 0;
+  }
+}
+</style>

+ 20 - 6
src/main.js

@@ -1,12 +1,26 @@
-import Vue from "vue";
-import App from "./App.vue";
-import router from "./router";
-import store from "./store";
-
+import Vue from 'vue';
+import App from './App.vue';
+import '@/plugins/weixin';
+import router from './router';
+import store from './store';
+import '@/plugins/element.js';
+import '@/plugins/vant';
+import '@/plugins/axios';
+import '@/plugins/check-res';
+import '@/plugins/meta';
+import '@/plugins/loading';
+import '@/plugins/setting';
+import InitStomp from '@/plugins/stomp';
+import '@/plugins/components';
+import '@frame/src/assets/icon/iconfont.css';
 Vue.config.productionTip = false;
 
 new Vue({
   router,
   store,
   render: (h) => h(App),
-}).$mount("#app");
+}).$mount('#app');
+InitStomp();
+window.vm = new Vue({
+  router,
+});

+ 19 - 0
src/plugins/axios.js

@@ -0,0 +1,19 @@
+import Vue from 'vue';
+import AxiosWrapper from '@/util/axios-wrapper';
+
+const Plugin = {
+  install(vue, options) {
+    // 3. 注入组件
+    vue.mixin({
+      created() {
+        if (this.$store && !this.$store.$axios) {
+          this.$store.$axios = this.$axios;
+        }
+      },
+    });
+    // 4. 添加实例方法
+    vue.prototype.$axios = new AxiosWrapper(options);
+  },
+};
+
+Vue.use(Plugin, { baseUrl: process.env.VUE_APP_AXIOS_BASE_URL });

+ 37 - 0
src/plugins/check-res.js

@@ -0,0 +1,37 @@
+/* eslint-disable no-underscore-dangle */
+/* eslint-disable no-param-reassign */
+/* eslint-disable no-unused-vars */
+/* eslint-disable no-shadow */
+import Vue from 'vue';
+import _ from 'lodash';
+import { Toast } from 'vant';
+const vm = new Vue({});
+const Plugin = {
+  install(Vue, options) {
+    // 4. 添加实例方法
+    Vue.prototype.$checkRes = (res, okText, errText) => {
+      let _okText = okText;
+      let _errText = errText;
+      if (!_.isFunction(okText) && _.isObject(okText) && okText != null) {
+        ({ okText: _okText, errText: _errText } = okText);
+      }
+      const { errcode = 0, errmsg } = res || {};
+      if (errcode === 0) {
+        if (_.isFunction(_okText)) {
+          return _okText();
+        }
+        if (_okText) {
+          Toast({ type: 'success', message: _okText });
+        }
+        return true;
+      }
+      if (_.isFunction(_errText)) {
+        return _errText();
+      }
+      Toast({ type: 'danger', message: errText });
+      return false;
+    };
+  },
+};
+
+Vue.use(Plugin);

+ 11 - 0
src/plugins/components.js

@@ -0,0 +1,11 @@
+import Vue from 'vue';
+import footers from '@/components/footers.vue';
+import top from '@/layout/common/top.vue';
+import page from '@/layout/common/page.vue';
+const Plugin = (vue) => {
+  vue.component('footers', footers);
+  vue.component('top', top);
+  vue.component('page', page);
+};
+
+Vue.use(Plugin);

+ 63 - 0
src/plugins/couindex.js

@@ -0,0 +1,63 @@
+// 创新券
+// 类型
+export const couponsType = ['科技创新券', '研发补贴', '奖励兑现'];
+// 折扣类型
+export const discounTtype = ['全额折扣券', '折扣券', '定额券'];
+// 适用服务类型
+export const useType = ['服务类型1', '服务类型2', '服务类型3'];
+// 所属分类
+export const classify = ['分类1', '分类2', '分类3'];
+// 状态
+export const couponsStatus = [
+  { label: '待上架', value: '0' },
+  { label: '上架', value: '1' },
+  { label: '下架', value: '-1' },
+];
+// 创新券申领
+// 状态
+export const couponsapplyStatus = [
+  { label: '待审中', value: '0' },
+  { label: '通过', value: '1' },
+  { label: '拒绝', value: '-1' },
+];
+// 是否使用
+export const isuse = [
+  { label: '未使用', value: '0' },
+  { label: '已使用', value: '1' },
+];
+// 高企申报
+// 是否使用
+export const iscashing = [
+  { label: '未兑付', value: '0' },
+  { label: '已兑付', value: '1' },
+  // { label: '已兑付', value: '2' },
+];
+// 状态
+export const declareStatus = [
+  { label: '企业信息审核审核中', value: '0' },
+  { label: '企业信息审核拒绝', value: '-1' },
+  { label: '上传合同', value: '1' },
+  { label: '上传合同', value: '2' },
+  { label: '高企申报成功', value: '3' },
+];
+// 状态
+export const declareapplyStatus = [
+  { label: '待审中', value: '0' },
+  { label: '通过', value: '1' },
+  { label: '拒绝', value: '-1' },
+];
+// 研发补贴,奖励兑现
+// 状态
+export const rewardStatus = [
+  { label: '待审中', value: '0' },
+  { label: '通过', value: '1' },
+  { label: '拒绝', value: '-1' },
+];
+
+// 兑付
+// 状态
+export const cashStatus = [
+  { label: '待审中', value: '0' },
+  { label: '通过', value: '1' },
+  { label: '拒绝', value: '-1' },
+];

+ 5 - 0
src/plugins/element.js

@@ -0,0 +1,5 @@
+import Vue from 'vue';
+import Element from 'element-ui';
+import 'element-ui/lib/theme-chalk/index.css';
+
+Vue.use(Element);

+ 27 - 0
src/plugins/loading.js

@@ -0,0 +1,27 @@
+/* eslint-disable no-console */
+/* eslint-disable no-param-reassign */
+
+import Vue from 'vue';
+
+const Plugin = {
+  // eslint-disable-next-line no-unused-vars
+  install(vue, options) {
+    // 3. 注入组件
+    vue.mixin({
+      created() {
+        // eslint-disable-next-line no-underscore-dangle
+        const isRoot = this.constructor === Vue;
+        // console.log(`rootId:${rootVue_uid}; thisId:${this._uid}`);
+        // if (rootVue_uid !== 3) {
+        //   console.log(this);
+        // }
+        if (isRoot) {
+          const el = document.getElementById('loading');
+          if (el) el.style.display = 'none';
+        }
+      },
+    });
+  },
+};
+
+Vue.use(Plugin, { baseUrl: process.env.VUE_APP_AXIOS_BASE_URL });

+ 4 - 0
src/plugins/meta.js

@@ -0,0 +1,4 @@
+import Vue from 'vue';
+import Meta from 'vue-meta';
+
+Vue.use(Meta);

+ 20 - 0
src/plugins/setting.js

@@ -0,0 +1,20 @@
+import Vue from 'vue';
+
+Vue.config.weixin = {
+  // baseUrl: process.env.BASE_URL + 'weixin',
+  // baseUrl: 'http://10.16.8.209:9005',
+};
+
+Vue.config.stomp = {
+  // brokerURL: 'ws://http://free.liaoningdoupo.com/ws',
+  brokerURL: '/ws', // ws://${location.host}/ws
+  connectHeaders: {
+    host: 'visit',
+    login: 'visit', //visit
+    passcode: 'visit', //visit123
+  },
+  // debug: true,
+  reconnectDelay: 5000,
+  heartbeatIncoming: 4000,
+  heartbeatOutgoing: 4000,
+};

+ 65 - 0
src/plugins/stomp.js

@@ -0,0 +1,65 @@
+/**
+ * 基于WebStomp的消息处理插件
+ */
+
+import Vue from 'vue';
+import _ from 'lodash';
+import assert from 'assert';
+import { Client } from '@stomp/stompjs/esm6/client';
+
+const Plugin = {
+  install(Vue, options) {
+    assert(_.isObject(options));
+    if (options.debug && !_.isFunction(options.debug)) {
+      options.debug = (str) => {
+        console.log(str);
+      };
+    }
+    assert(_.isString(options.brokerURL));
+    if (!options.brokerURL.startsWith('ws://')) {
+      options.brokerURL = `ws://${location.host}${options.brokerURL}`;
+    }
+
+    // 3. 注入组件
+    Vue.mixin({
+      beforeDestroy: function () {
+        if (this.$stompClient) {
+          this.$stompClient.deactivate();
+          delete this.$stompClient;
+        }
+      },
+    });
+
+    // 4. 添加实例方法
+    Vue.prototype.$stomp = function (subscribes = {}) {
+      // connect to mq
+      const client = new Client(options);
+      client.onConnect = (frame) => {
+        // Do something, all subscribes must be done is this callback
+        // This is needed because this will be executed after a (re)connect
+        console.log('[stomp] connected');
+        Object.keys(subscribes)
+          .filter((p) => _.isFunction(subscribes[p]))
+          .forEach((key) => {
+            client.subscribe(key, subscribes[key]);
+          });
+      };
+
+      client.onStompError = (frame) => {
+        // Will be invoked in case of error encountered at Broker
+        // Bad login/passcode typically will cause an error
+        // Complaint brokers will set `message` header with a brief message. Body may contain details.
+        // Compliant brokers will terminate the connection after any error
+        console.log('Broker reported error: ' + frame.headers['message']);
+        console.log('Additional details: ' + frame.body);
+      };
+
+      client.activate();
+
+      this.$stompClient = client;
+    };
+  },
+};
+export default () => {
+  Vue.use(Plugin, Vue.config.stomp);
+};

+ 5 - 0
src/plugins/vant.js

@@ -0,0 +1,5 @@
+import Vue from 'vue';
+import Vant from 'vant';
+import 'vant/lib/index.css';
+
+Vue.use(Vant);

+ 3 - 0
src/plugins/weixin.js

@@ -0,0 +1,3 @@
+import Vue from 'vue';
+const wx = require('weixin-js-sdk');
+Vue.prototype.$wx = wx;

+ 59 - 19
src/router/index.js

@@ -1,28 +1,68 @@
-import Vue from "vue";
-import VueRouter from "vue-router";
-import Home from "../views/Home.vue";
-
+import Vue from 'vue';
+import VueRouter from 'vue-router';
+import store from '@/store/index';
+const jwt = require('jsonwebtoken');
+const originalPush = VueRouter.prototype.push;
+VueRouter.prototype.push = function push(location) {
+  return originalPush.call(this, location).catch((err) => err);
+};
 Vue.use(VueRouter);
-
-const routes = [
-  {
-    path: "/",
-    name: "Home",
-    component: Home,
-  },
+const web = [
   {
-    path: "/about",
-    name: "About",
-    // route level code-splitting
-    // this generates a separate chunk (about.[hash].js) for this route
-    // which is lazy-loaded when the route is visited.
-    component: () =>
-      import(/* webpackChunkName: "about" */ "../views/About.vue"),
+    path: '/',
+    name: 'index',
+    meta: { title: '网站首页' },
+    component: () => import('../views/index.vue'),
   },
+  // {
+  //   path: '/login',
+  //   name: 'login',
+  //   meta: { title: '登录', key: 'login' },
+  //   component: () => import('../views/login.vue'),
+  // },
+  // {
+  //   path: '/register',
+  //   name: 'register',
+  //   meta: { title: '账户注册', key: 'register' },
+  //   component: () => import('../views/register.vue'),
+  // },
 ];
-
+const routes = [...web];
 const router = new VueRouter({
+  mode: 'history',
+  base: process.env.VUE_APP_ROUTER,
   routes,
 });
+router.beforeEach((to, from, next) => {
+  // let openid = 'oFqNO6VHEEwnMB_l1AD3pooBAkHk';
+  let openid = to.query.openid;
+  sessionStorage.setItem('openid', openid);
+  document.title = `${to.meta.title} `;
+  const token = localStorage.getItem('token');
+  // 不带参数
+  if (to.path == '/exchange/center/index') {
+    if (!token) {
+      next(`/login?path=${to.path}&&type=1`);
+    } else {
+      let user = jwt.decode(token);
+      store.commit('setUser', user, { root: true });
+      next();
+    }
+    // 带参数
+    // } else if (to.path == '/finance/apply') {
+    //   if (!token) {
+    //     next(`/login?path=${to.fullPath}`);
+    //   } else {
+    //     let user = jwt.decode(token);
+    //     store.commit('setUser', user, { root: true });
+    //     next();
+    //   }
+    //   // 已登录
+  } else {
+    let user = jwt.decode(token);
+    store.commit('setUser', user, { root: true });
+    next();
+  }
+});
 
 export default router;

+ 116 - 5
src/store/index.js

@@ -1,11 +1,122 @@
-import Vue from "vue";
-import Vuex from "vuex";
+import Vue from 'vue';
+import Vuex from 'vuex';
+import * as ustate from '@common/src/store/user/state';
+import * as umutations from '@common/src/store/user/mutations';
+import statistics from '@common/src/store/statistics';
+import upload from './upload';
+import news from '@common/src/store/news';
+import column from '@common/src/store/column';
+import viewPoint from '@common/src/store/viewPoint';
+import questionnaire from '@common/src/store/question/questionnaire';
+import answer from '@common/src/store/question/answer';
+import question from '@common/src/store/question';
+import projectsolic from '@common/src/store/projectsolic';
+import organization from '@common/src/store/organization';
+import personal from '@common/src/store/personal';
+import expert from '@common/src/store/expert';
+import product from '@common/src/store/product';
+import patent from '@common/src/store/patent';
+import disclosure from '@common/src/store/patent/disclosure';
+import report from '@common/src/store/patent/report';
+import notice from '@common/src/store/patent/notice';
+import sell from '@common/src/store/patent/sell';
+import purchase from '@common/src/store/patent/purchase';
+import tradeorder from '@common/src/store/patent/tradeorder';
+// 直播平台
+import mechanism from './live/mechanism';
+import coupons from './live/coupons';
+import couponsApply from './live/couponsApply';
+import declare from './live/declare';
+import cashing from './live/cashing';
+import reward from './live/reward';
+// 成果评价
+import achieveApply from '@common/src/store/achieve/achieve_apply.js';
+
+// 管理员
+import adminLogin from '@common/src/store/adminLogin';
+// 邀请码
+import inviteCode from '@common/src/store/inviteCode';
+// 2021-08-21
+// 聊天
+import patentchat from '@common/src/store/patent/patentchat';
+// 审核通知
+import patentexamine from '@common/src/store/patent/patentexamine';
+// 通知
+import patentnotice from '@common/src/store/patent/patentnotice';
+// 专利申请
+import patentapply from '@common/src/store/patent/patentapply';
+// 专利申请预警表
+import patentwarning from '@common/src/store/patent/patentwarning';
+// 专利分析
+import patentanalysis from '@common/src/store/patent/patentanalysis';
+// 专利评估
+import patentassess from '@common/src/store/patent/patentassess';
+// 专利信息
+import patentinfo from '@common/src/store/patent/patentinfo';
+// 已授权专利预警表
+import patentearly from '@common/src/store/patent/patentearly';
+
+// 专利交易
+import patenttrans from '@common/src/store/patent/patenttrans';
+import mission from '@common/src/store/mission';
+const _ = require('lodash');
 
 Vue.use(Vuex);
 
 export default new Vuex.Store({
-  state: {},
-  mutations: {},
+  state: {
+    ...ustate,
+  },
+  mutations: {
+    ...umutations,
+  },
   actions: {},
-  modules: {},
+  modules: {
+    statistics,
+    upload,
+    column,
+    news,
+    viewPoint,
+    questionnaire,
+    answer,
+    question,
+    projectsolic,
+    organization,
+    personal,
+    expert,
+    product,
+    patent,
+    // 直播平台
+    mechanism,
+    coupons,
+    couponsApply,
+    declare,
+    cashing,
+    reward,
+    // 成果评价
+    achieveApply,
+    // 交底书
+    disclosure,
+    report,
+    notice,
+    // 管理员
+    adminLogin,
+    inviteCode,
+    // 专利交易
+    sell,
+    purchase,
+    tradeorder,
+    // 专利运营
+    patentchat,
+    patentexamine,
+    patentnotice,
+    patentapply,
+    patentwarning,
+    patentanalysis,
+    patentassess,
+    patentinfo,
+    patentearly,
+    patenttrans,
+    mission,
+  },
 });

+ 46 - 0
src/store/live/cashing.js

@@ -0,0 +1,46 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  cashing: `/api/live/v0/cysci/cashing`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.cashing}`, {
+      skip,
+      limit,
+      ...info,
+    });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.cashing}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.cashing}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.cashing}/update/${id}`, data);
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.cashing}/${payload}`);
+    return res;
+  },
+  async fromFetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.cashing}/from/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 43 - 0
src/store/live/coupons.js

@@ -0,0 +1,43 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  coupons: `/api/live/v0/cysci/coupons`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.coupons}`, {
+      skip,
+      limit,
+      ...info,
+    });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.coupons}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.coupons}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.coupons}/update/${id}`, data);
+    return res;
+  },
+
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.coupons}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 43 - 0
src/store/live/couponsApply.js

@@ -0,0 +1,43 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  couponsApply: `/api/live/v0/cysci/couponsApply`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.couponsApply}`, {
+      skip,
+      limit,
+      ...info,
+    });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.couponsApply}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.couponsApply}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.couponsApply}/update/${id}`, data);
+    return res;
+  },
+
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.couponsApply}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 43 - 0
src/store/live/declare.js

@@ -0,0 +1,43 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+import { registerCoordinateSystem } from 'echarts';
+Vue.use(Vuex);
+const api = {
+  declare: `/api/live/v0/cysci/declare`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.declare}`, {
+      skip,
+      limit,
+      ...info,
+    });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.declare}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.declare}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.declare}/update/${id}`, data);
+    return res;
+  },
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.declare}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 58 - 0
src/store/live/mechanism.js

@@ -0,0 +1,58 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  mechanism: `/api/live/v0/cysci/mechanism`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.mechanism}`, {
+      skip,
+      limit,
+      ...info,
+    });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.mechanism}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.mechanism}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.mechanism}/update/${id}`, data);
+    return res;
+  },
+
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.mechanism}/${payload}`);
+    return res;
+  },
+  async password({ commit }, { id, passwd }) {
+    const res = await this.$axios.$post(`${api.mechanism}/password/${id}`, { passwd });
+    return res;
+  },
+  async login({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.mechanism}/login`, payload);
+    const jwt = require('jsonwebtoken');
+    if (res.errcode === 0) {
+      localStorage.setItem('token', res.data);
+      localStorage.setItem('type', 'ZJJG');
+      const user = jwt.decode(res.data);
+      commit('setUser', user, { root: true });
+    }
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 43 - 0
src/store/live/reward.js

@@ -0,0 +1,43 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+Vue.use(Vuex);
+const api = {
+  reward: `/api/live/v0/cysci/reward`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async query({ commit }, { skip = 0, limit, ...info } = {}) {
+    const res = await this.$axios.$get(`${api.reward}`, {
+      skip,
+      limit,
+      ...info,
+    });
+    return res;
+  },
+  async create({ commit }, payload) {
+    const res = await this.$axios.$post(`${api.reward}`, payload);
+    return res;
+  },
+  async fetch({ commit }, payload) {
+    const res = await this.$axios.$get(`${api.reward}/${payload}`);
+    return res;
+  },
+  async update({ commit }, { id, ...data }) {
+    const res = await this.$axios.$post(`${api.reward}/update/${id}`, data);
+    return res;
+  },
+
+  async delete({ commit }, payload) {
+    const res = await this.$axios.$delete(`${api.reward}/${payload}`);
+    return res;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 25 - 0
src/store/upload.js

@@ -0,0 +1,25 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import _ from 'lodash';
+import axios from 'axios';
+Vue.use(Vuex);
+const api = {
+  upload: (dir) => `/files/jlstcompany/${dir}/upload`,
+};
+const state = () => ({});
+const mutations = {};
+
+const actions = {
+  async upload({ commit }, { file, dir }) {
+    var formdata = new FormData();
+    formdata.append('file', file, file.name);
+    const res = await axios.post(api.upload(dir), formdata, { headers: { 'Content-Type': 'multipart/form-data' } });
+    return res.data;
+  },
+};
+export default {
+  namespaced: true,
+  state,
+  mutations,
+  actions,
+};

+ 117 - 0
src/util/axios-wrapper.js

@@ -0,0 +1,117 @@
+/* eslint-disable no-console */
+/* eslint-disable no-param-reassign */
+
+import _ from 'lodash';
+import Axios from 'axios';
+import { Util, Error } from 'naf-core';
+// import { Indicator } from 'mint-ui';
+import util from './user-util';
+
+const { trimData, isNullOrUndefined } = Util;
+const { ErrorCode } = Error;
+
+let currentRequests = 0;
+
+export default class AxiosWrapper {
+  constructor({ baseUrl = '', unwrap = true } = {}) {
+    this.baseUrl = baseUrl;
+    this.unwrap = unwrap;
+  }
+
+  // 替换uri中的参数变量
+  static merge(uri, query = {}) {
+    if (!uri.includes(':')) {
+      return uri;
+    }
+    const keys = [];
+    const regexp = /\/:([a-z0-9_]+)/gi;
+    let res;
+    // eslint-disable-next-line no-cond-assign
+    while ((res = regexp.exec(uri)) != null) {
+      keys.push(res[1]);
+    }
+    keys.forEach((key) => {
+      if (!isNullOrUndefined(query[key])) {
+        uri = uri.replace(`:${key}`, query[key]);
+      }
+    });
+    return uri;
+  }
+
+  $get(uri, query, options) {
+    return this.$request(uri, null, query, options);
+  }
+
+  $post(uri, data = {}, query, options) {
+    return this.$request(uri, data, query, options);
+  }
+  $delete(uri, data = {}, router, query, options = {}) {
+    options = { ...options, method: 'delete' };
+    return this.$request(uri, data, query, options, router);
+  }
+  async $request(uri, data, query, options) {
+    // TODO: 合并query和options
+    if (_.isObject(query) && _.isObject(options)) {
+      options = { ...options, params: query, method: 'get' };
+    } else if (_.isObject(query) && !query.params) {
+      options = { params: query };
+    } else if (_.isObject(query) && query.params) {
+      options = query;
+    }
+    if (!options) options = {};
+    if (options.params) options.params = trimData(options.params);
+    const url = AxiosWrapper.merge(uri, options.params);
+    currentRequests += 1;
+    // Indicator.open({
+    //   spinnerType: 'fading-circle',
+    // });
+
+    try {
+      const axios = Axios.create({
+        baseURL: this.baseUrl,
+      });
+      axios.defaults.headers.common.Authorization = util.token;
+      let res = await axios.request({
+        method: isNullOrUndefined(data) ? 'get' : 'post',
+        url,
+        data,
+        responseType: 'json',
+        ...options,
+      });
+      res = res.data;
+      const { errcode, errmsg, details } = res;
+      if (errcode) {
+        console.warn(`[${uri}] fail: ${errcode}-${errmsg} ${details}`);
+        return res;
+      }
+      // unwrap data
+      if (this.unwrap) {
+        res = _.omit(res, ['errmsg', 'details']);
+        const keys = Object.keys(res);
+        if (keys.length === 1 && keys.includes('data')) {
+          res = res.data;
+        }
+      }
+      return res;
+    } catch (err) {
+      let errmsg = '接口请求失败,请稍后重试';
+      if (err.response) {
+        const { status } = err.response;
+        if (status === 401) errmsg = '用户认证失败,请重新登录';
+        if (status === 403) errmsg = '当前用户不允许执行该操作';
+      }
+      console.error(
+        `[AxiosWrapper] 接口请求失败: ${err.config && err.config.url} - 
+        ${err.message}`
+      );
+      return { errcode: ErrorCode.SERVICE_FAULT, errmsg, details: err.message };
+    } finally {
+      /* eslint-disable */
+      currentRequests -= 1;
+      if (currentRequests <= 0) {
+        currentRequests = 0;
+        // Indicator.close();
+      }
+    }
+  }
+}

+ 50 - 0
src/util/methods-util.js

@@ -0,0 +1,50 @@
+import { Util } from 'naf-core';
+
+const { isNullOrUndefined } = Util;
+
+export default {
+  //判断信息是否过期
+  isDateOff(dataDate) {
+    const now = new Date(new Date().getTime() - 24 * 60 * 60 * 1000);
+    dataDate = new Date(dataDate);
+    return now.getTime() <= dataDate.getTime();
+  },
+  //判断企业是否可以执行此动作/显示
+  checkCorp(data) {
+    const { role, unit, selfUnit, status, displayType, userid } = data;
+    if (!isNullOrUndefined(selfUnit) && !isNullOrUndefined(status)) {
+      return role === 'corp' && selfUnit === unit && status === '0';
+    } else if (!isNullOrUndefined(displayType)) {
+      if (role === 'corp') {
+        return role === displayType;
+      } else {
+        return role === displayType && !isNullOrUndefined(userid);
+      }
+    }
+  },
+  //获取url的参数params
+  getParams() {
+    let str = location.href;
+    let num = str.indexOf('?');
+    const param = {};
+    str = str.substr(num + 1);
+    let num2 = str.indexOf('#');
+    let str2 = '';
+    if (num2 > 0) {
+      str2 = str.substr(0, num2);
+    } else {
+      num2 = str.indexOf('/');
+      str2 = str.substr(0, num2);
+    }
+    const arr = str2.split('&');
+    for (let i = 0; i < arr.length; i++) {
+      num = arr[i].indexOf('=');
+      if (num > 0) {
+        const name = arr[i].substring(0, num);
+        const value = arr[i].substr(num + 1);
+        param[name] = decodeURI(value);
+      }
+    }
+    return param;
+  },
+};

+ 69 - 0
src/util/user-util.js

@@ -0,0 +1,69 @@
+/* eslint-disable no-console */
+export default {
+  get user() {
+    const val = sessionStorage.getItem('user');
+    try {
+      if (val) return JSON.parse(val);
+    } catch (err) {
+      console.error(err);
+    }
+    return null;
+  },
+  set user(userinfo) {
+    sessionStorage.setItem('user', JSON.stringify(userinfo));
+  },
+  get token() {
+    return sessionStorage.getItem('token');
+  },
+  set token(token) {
+    sessionStorage.setItem('token', token);
+  },
+  get openid() {
+    return sessionStorage.getItem('openid');
+  },
+  set openid(openid) {
+    sessionStorage.setItem('openid', openid);
+  },
+  get isGuest() {
+    return !this.user || this.user.role === 'guest';
+  },
+  save({ userinfo, token }) {
+    sessionStorage.setItem('user', JSON.stringify(userinfo));
+    sessionStorage.setItem('token', token);
+  },
+
+  get corpInfo() {
+    const val = sessionStorage.getItem('corpInfo');
+    if (val) return JSON.parse(val);
+    return null;
+  },
+  set corpInfo(corpInfo) {
+    sessionStorage.setItem('corpInfo', JSON.stringify(corpInfo));
+  },
+  saveCorpInfo(corpInfo) {
+    sessionStorage.setItem('corpInfo', JSON.stringify(corpInfo));
+  },
+
+  get unit() {
+    const val = sessionStorage.getItem('unit');
+    if (val) return JSON.parse(val);
+    return null;
+  },
+  set unit(unitList) {
+    sessionStorage.setItem('unit', JSON.stringify(unitList));
+  },
+  saveUnit(unitList) {
+    sessionStorage.setItem('unit', JSON.stringify(unitList));
+  },
+  get userInfo() {
+    const val = sessionStorage.getItem('userInfo');
+    if (val) return JSON.parse(val);
+    return null;
+  },
+  set userInfo(userInfo) {
+    sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
+  },
+  saveUserInfo(userInfo) {
+    sessionStorage.setItem('userInfo', JSON.stringify(userInfo));
+  },
+};

+ 0 - 5
src/views/About.vue

@@ -1,5 +0,0 @@
-<template>
-  <div class="about">
-    <h1>This is an about page</h1>
-  </div>
-</template>

+ 0 - 18
src/views/Home.vue

@@ -1,18 +0,0 @@
-<template>
-  <div class="home">
-    <img alt="Vue logo" src="../assets/logo.png" />
-    <HelloWorld msg="Welcome to Your Vue.js App" />
-  </div>
-</template>
-
-<script>
-// @ is an alias to /src
-import HelloWorld from "@/components/HelloWorld.vue";
-
-export default {
-  name: "Home",
-  components: {
-    HelloWorld,
-  },
-};
-</script>

+ 36 - 0
src/views/index.vue

@@ -0,0 +1,36 @@
+<template>
+  <div id="index">
+    <van-row>
+      <van-col span="24" class="main"> test </van-col>
+    </van-row>
+  </div>
+</template>
+
+<script>
+import { mapState, createNamespacedHelpers } from 'vuex';
+export default {
+  name: 'index',
+  props: {},
+  components: {},
+  data: function () {
+    return {};
+  },
+  created() {},
+  methods: {},
+  computed: {
+    ...mapState(['user']),
+  },
+  metaInfo() {
+    return { title: this.$route.meta.title };
+  },
+  watch: {
+    test: {
+      deep: true,
+      immediate: true,
+      handler(val) {},
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>

+ 49 - 0
vue.config.js

@@ -0,0 +1,49 @@
+const path = require('path');
+const common = path.resolve(__dirname, '../common');
+const frame = path.resolve(__dirname, '../frame');
+module.exports = {
+  publicPath: `/${process.env.VUE_APP_ROUTER}`,
+  outputDir: 'jlstpatent',
+  productionSourceMap: false,
+  configureWebpack: (config) => {
+    Object.assign(config, {
+      resolve: {
+        alias: {
+          '@': path.resolve(__dirname, './src'),
+          '@c': path.resolve(__dirname, './src/components'),
+          '@a': path.resolve(__dirname, './src/assets'),
+          '@common': common,
+          '@frame': frame,
+        },
+      },
+    });
+  },
+  devServer: {
+    port: '8001',
+    proxy: {
+      '/files': {
+        target: 'http://broadcast.kqyjy.com',
+      },
+      '/api/mission': {
+        target: 'http://broadcast.kqyjy.com',
+        changeOrigin: true,
+        ws: false,
+      },
+      '/api/question': {
+        target: 'http://broadcast.kqyjy.com', //http://192.168.1.19:9101
+        changeOrigin: true,
+        ws: false,
+      },
+      '/api/achieve': {
+        target: 'http://broadcast.kqyjy.com', //http://192.168.1.19:9101
+        changeOrigin: true,
+        ws: false,
+      },
+      '/api/live': {
+        target: 'http://broadcast.kqyjy.com', //http://192.168.1.19:9200
+        changeOrigin: true,
+        ws: false,
+      },
+    },
+  },
+};