Browse Source

杰森仓储重构,仓库创建,代码拷贝

asd26269546 2 years ago
commit
008a73f6c2
100 changed files with 6607 additions and 0 deletions
  1. 5 0
      .babelrc
  2. 9 0
      .editorconfig
  3. 0 0
      .eslintignore
  4. 21 0
      .eslintrc.js
  5. 29 0
      .gitignore
  6. 5 0
      .postcssrc.js
  7. 5 0
      .travis.yml
  8. 21 0
      LICENSE
  9. 90 0
      README.md
  10. 3 0
      cypress.json
  11. 79 0
      package.json
  12. 19 0
      public/index.html
  13. BIN
      public/logo.png
  14. 40 0
      src/App.vue
  15. 389 0
      src/api/applyPurchase.js
  16. 433 0
      src/api/baseData.js
  17. 51 0
      src/api/data.js
  18. 656 0
      src/api/stock.js
  19. 159 0
      src/api/storageHome.js
  20. 113 0
      src/api/supplierShip.js
  21. 19 0
      src/api/upload.js
  22. 244 0
      src/api/user.js
  23. 87 0
      src/assets/icons/iconfont.css
  24. BIN
      src/assets/icons/iconfont.eot
  25. 135 0
      src/assets/icons/iconfont.json
  26. 56 0
      src/assets/icons/iconfont.svg
  27. BIN
      src/assets/icons/iconfont.ttf
  28. BIN
      src/assets/icons/iconfont.woff
  29. BIN
      src/assets/icons/iconfont.woff2
  30. BIN
      src/assets/images/B242C181-9C94-46bc-98C6-0DE6A1CC6A7F.txt
  31. BIN
      src/assets/images/avatar.png
  32. BIN
      src/assets/images/avator.png
  33. BIN
      src/assets/images/dck.png
  34. BIN
      src/assets/images/dsp.png
  35. BIN
      src/assets/images/dun.png
  36. 0 0
      src/assets/images/error-page/error-401.svg
  37. 0 0
      src/assets/images/error-page/error-404.svg
  38. 0 0
      src/assets/images/error-page/error-500.svg
  39. BIN
      src/assets/images/exit.png
  40. BIN
      src/assets/images/gaojin.png
  41. BIN
      src/assets/images/gwq-sign.png
  42. BIN
      src/assets/images/img.png
  43. BIN
      src/assets/images/kcyj.png
  44. BIN
      src/assets/images/log-new-login.png
  45. BIN
      src/assets/images/log-new-nav.png
  46. BIN
      src/assets/images/login-bg.png
  47. BIN
      src/assets/images/login-icon.20420174.png
  48. BIN
      src/assets/images/login-icon.png
  49. BIN
      src/assets/images/login-image.png
  50. BIN
      src/assets/images/login-left.png
  51. BIN
      src/assets/images/login-logo.png
  52. BIN
      src/assets/images/logo-title.png
  53. BIN
      src/assets/images/nav-logo.png
  54. BIN
      src/assets/images/over.png
  55. BIN
      src/assets/images/qipao.png
  56. BIN
      src/assets/images/zlwl.png
  57. BIN
      src/assets/images/组 577.png
  58. 796 0
      src/components/board/board.vue
  59. 111 0
      src/components/board/chart-pie.vue
  60. 58 0
      src/components/charts/bar.vue
  61. 3 0
      src/components/charts/index.js
  62. 70 0
      src/components/charts/pie.vue
  63. 491 0
      src/components/charts/theme.json
  64. 48 0
      src/components/common-icon/common-icon.vue
  65. 2 0
      src/components/common-icon/index.js
  66. 8 0
      src/components/common/common.less
  67. 3 0
      src/components/common/util.js
  68. 174 0
      src/components/count-to/count-to.vue
  69. 2 0
      src/components/count-to/index.js
  70. 10 0
      src/components/count-to/index.less
  71. 2 0
      src/components/cropper/index.js
  72. 35 0
      src/components/cropper/index.less
  73. 139 0
      src/components/cropper/index.vue
  74. 404 0
      src/components/dateSelect/dateSelect.vue
  75. 18 0
      src/components/drag-drawer/drag-drawer-trigger.vue
  76. 156 0
      src/components/drag-drawer/drag-drawer.vue
  77. 2 0
      src/components/drag-drawer/index.js
  78. 70 0
      src/components/drag-drawer/index.less
  79. 7 0
      src/components/drag-drawer/mixin.js
  80. 92 0
      src/components/drag-list/drag-list.vue
  81. 2 0
      src/components/drag-list/index.js
  82. 75 0
      src/components/editor/editor.vue
  83. 2 0
      src/components/editor/index.js
  84. 178 0
      src/components/form/select-input.vue
  85. 35 0
      src/components/icons/icons.vue
  86. 2 0
      src/components/icons/index.js
  87. 2 0
      src/components/login-form/index.js
  88. 85 0
      src/components/login-form/login-form.vue
  89. 2 0
      src/components/main/components/a-back-top/index.js
  90. 90 0
      src/components/main/components/a-back-top/index.vue
  91. 49 0
      src/components/main/components/error-store/error-store.vue
  92. 2 0
      src/components/main/components/error-store/index.js
  93. 84 0
      src/components/main/components/fullscreen/fullscreen.vue
  94. 2 0
      src/components/main/components/fullscreen/index.js
  95. 4 0
      src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less
  96. 46 0
      src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue
  97. 2 0
      src/components/main/components/header-bar/custom-bread-crumb/index.js
  98. 16 0
      src/components/main/components/header-bar/header-bar.less
  99. 558 0
      src/components/main/components/header-bar/header-bar.vue
  100. 2 0
      src/components/main/components/header-bar/index.js

+ 5 - 0
.babelrc

@@ -0,0 +1,5 @@
+{
+  "presets": [
+    "@vue/app"
+  ]
+}

+ 9 - 0
.editorconfig

@@ -0,0 +1,9 @@
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true

+ 0 - 0
.eslintignore


+ 21 - 0
.eslintrc.js

@@ -0,0 +1,21 @@
+module.exports = {
+  root: true,
+  'extends': [
+    'plugin:vue/essential',
+    // '@vue/standard'
+  ],
+  rules: {
+    // allow async-await
+    'generator-star-spacing': 'off',
+    // allow debugger during development
+    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
+    'vue/no-parsing-error': [2, {
+      'x-invalid-end-tag': false
+    }],
+    'no-undef': 'off',
+    'camelcase': 'off'
+  },
+  parserOptions: {
+    parser: 'babel-eslint'
+  }
+}

+ 29 - 0
.gitignore

@@ -0,0 +1,29 @@
+.DS_Store
+node_modules
+/dist
+
+package-lock.json
+
+/tests/e2e/videos/
+/tests/e2e/screenshots/
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw*
+
+build/env.js
+/vue.config.js

+ 5 - 0
.postcssrc.js

@@ -0,0 +1,5 @@
+module.exports = {
+  plugins: {
+    autoprefixer: {}
+  }
+}

+ 5 - 0
.travis.yml

@@ -0,0 +1,5 @@
+language: node_js
+node_js: stable
+script: npm run lint
+notifications:
+  email: false

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 TalkingData
+
+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.

+ 90 - 0
README.md

@@ -0,0 +1,90 @@
+<p align="center">
+    <a href="https://www.iviewui.com">
+        <img width="200" src="https://file.iviewui.com/logo-new.svg">
+    </a>
+</p>
+
+<h1>
+iView Admin
+    <h3>Vue.js 2.0 admin management system template based on iView.</h3>
+</h1>
+
+[![](https://img.shields.io/github/release/iview/iview-admin.svg)](https://github.com/iview/iview-admin/releases)
+[![](https://img.shields.io/travis/iview/iview-admin.svg?style=flat-square)](https://travis-ci.org/iview/iview-admin)
+[![vue](https://img.shields.io/badge/vue-2.5.17-brightgreen.svg?style=flat-square)](https://github.com/vuejs/vue)
+[![iview ui](https://img.shields.io/badge/iview-3.2.2-brightgreen.svg?style=flat-square)](https://github.com/iview/iview)
+[![npm](https://img.shields.io/npm/l/express.svg)]()
+
+## Introduction
+
+iView Admin is a front-end management background integration solution. It based on [Vue.js](https://github.com/vuejs/vue) and use the UI Toolkit [iView](https://github.com/iview/iview).
+
+- [Document](https://lison16.github.io/iview-admin-doc/)
+- [Preview](https://admin.iviewui.com/)
+- [Base template recommends using](https://github.com/iview/iview-admin/tree/template)
+
+![image](https://file.iviewui.com/admin-dist/admin-preview.png)
+
+## Features
+
+- Login / Logout
+- Permission Authentication
+    - A list of filters
+    - Permission to switch
+- i18n
+- Components
+    - Rich Text Editor
+    - Markdown Editor
+    - City Cascader
+    - Photos preview and edit
+    - Draggable list
+    - File upload
+    - Digital gradient
+    - split-pane
+- Form
+    - The article published
+    - Workflow
+- Table
+    - Drag-and-drop sort
+    - Searchable form
+    - Table export data
+        - Export to Csv file
+        - Export to Xls file
+    - Table to picture
+- Error Page
+    - 403
+    - 404
+    - 500
+- Router
+    - Dynamic routing
+    - With reference page
+- Theme
+- Shrink the sidebar
+- Tag navigation
+- Breadcrumb navigation
+- Full screen / exit full screen
+- Lock screen
+- The message center
+- Personal center
+
+## Getting started
+```bush
+# clone the project
+git clone https://github.com/iview/iview-admin.git
+
+// install dependencies
+npm install
+
+// develop
+npm run dev
+```
+
+## Build
+```bush
+npm run build
+```
+
+## License
+[MIT](http://opensource.org/licenses/MIT)
+
+Copyright (c) 2016-present, TalkingData

+ 3 - 0
cypress.json

@@ -0,0 +1,3 @@
+{
+  "pluginsFile": "tests/e2e/plugins/index.js"
+}

+ 79 - 0
package.json

@@ -0,0 +1,79 @@
+{
+  "name": "iview-admin",
+  "version": "2.0.0",
+  "author": "Lison<lison16new@163.com>",
+  "private": false,
+  "scripts": {
+    "dev": "vue-cli-service serve --open",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint",
+    "test:unit": "vue-cli-service test:unit",
+    "test:e2e": "vue-cli-service test:e2e"
+  },
+  "dependencies": {
+    "@microsoft/signalr": "^5.0.10",
+    "@microsoft/signalr-protocol-msgpack": "^5.0.10",
+    "axios": "^0.18.0",
+    "clipboard": "^2.0.0",
+    "codemirror": "^5.38.0",
+    "compression-webpack-plugin": "^5.0.1",
+    "countup": "^1.8.2",
+    "cropperjs": "^1.2.2",
+    "dayjs": "^1.10.6",
+    "echarts": "^4.0.4",
+    "html2canvas": "^1.0.0-alpha.12",
+    "iview": "^3.2.2",
+    "iview-area": "^1.5.17",
+    "jquery": "^3.6.0",
+    "print-js": "^1.6.0",
+    "signalr": "^2.4.2",
+    "simplemde": "^1.11.2",
+    "sortablejs": "^1.7.0",
+    "tree-table-vue": "^1.1.0",
+    "v-org-tree": "^1.0.6",
+    "v-viewer": "^1.6.4",
+    "vue": "^2.5.10",
+    "vue-easy-print": "0.0.8",
+    "vue-i18n": "^7.8.0",
+    "vue-qr": "^2.5.0",
+    "vue-router": "^3.0.1",
+    "vuedraggable": "^2.16.0",
+    "vuex": "^3.0.1",
+    "wangeditor": "^3.1.1",
+    "xlsx": "^0.13.5"
+  },
+  "devDependencies": {
+    "@vue/cli-plugin-babel": "^3.0.1",
+    "@vue/cli-plugin-eslint": "^3.0.1",
+    "@vue/cli-plugin-unit-mocha": "^3.0.1",
+    "@vue/cli-service": "^3.0.1",
+    "@vue/eslint-config-standard": "^3.0.0-beta.10",
+    "@vue/test-utils": "^1.0.0-beta.10",
+    "chai": "^4.1.2",
+    "eslint-plugin-cypress": "^2.0.1",
+    "generate-asset-webpack-plugin": "^0.3.0",
+    "less": "^2.7.3",
+    "less-loader": "^4.0.5",
+    "lint-staged": "^6.0.0",
+    "mockjs": "^1.0.1-beta3",
+    "vue-template-compiler": "^2.5.13"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 8"
+  ],
+  "gitHooks": {
+    "pre-commit": "lint-staged"
+  },
+  "lint-staged": {
+    "*.js": [
+      "vue-cli-service lint",
+      "git add"
+    ],
+    "*.vue": [
+      "vue-cli-service lint",
+      "git add"
+    ]
+  }
+}

+ 19 - 0
public/index.html

@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+    <meta http-equiv="pragram" content="no-cache">
+    <meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
+    <link rel="icon" href="<%= BASE_URL %>logo.png">
+    <title></title>
+  </head>
+  <body>
+    <noscript>
+      <strong>We're sorry but iview-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+    </noscript>
+    <div id="app"></div>
+    <!-- built files will be auto injected -->
+  </body>
+</html>

BIN
public/logo.png


+ 40 - 0
src/App.vue

@@ -0,0 +1,40 @@
+<template>
+  <div id="app">
+    <router-view/>
+  </div>
+</template>
+
+<script>
+import { checkVersion } from '@/libs/util'
+
+export default {
+  name: 'App',
+  methods: {
+  },
+  mounted () {
+    /* 轮询监听是否发布新版本 */
+    if (process.env.NODE_ENV !== 'development') {
+      checkVersion()
+      setInterval(() => {
+        checkVersion()
+      }, 10000)
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.size{
+  width: 100%;
+  height: 100%;
+}
+html,body{
+  .size;
+  overflow: hidden;
+  margin: 0;
+  padding: 0;
+}
+#app {
+  .size;
+}
+</style>

+ 389 - 0
src/api/applyPurchase.js

@@ -0,0 +1,389 @@
+import axios from '@/libs/api.request'
+
+// 申购详情分页
+export const GetApplyPurchasePageList = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 申购详新增
+export const ApplyPurchaseAdd = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/Add',
+    data,
+    method: 'post'
+  })
+}
+
+// 采购合同详情分页
+export const GetPurContractPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPurContractPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 合同付款详情分页
+export const GetContractPayPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetContractPayPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增申购单
+export const AddApplyPurchase = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/Add',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取申购审批流程
+export const GetApplyPurchaseFlows = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetApplyPurchaseFlows',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取采购合同入库记录
+export const GetPurchaseInStockRecord = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPurchaseInStockRecord',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取合同/票据
+export const GetContractBills = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetContractBills',
+    data,
+    method: 'post'
+  })
+}
+
+// 上传合同/票据
+export const UploadContractBills = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/UploadContractBills',
+    data,
+    method: 'post'
+  })
+}
+
+//  获取转账付款凭证列表
+export const GetPaymentVouchers = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPaymentVouchers',
+    data,
+    method: 'post'
+  })
+}
+
+//  获取采购合同决策辅助
+export const GetPurContractPolicy = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPurContractPolicy',
+    data,
+    method: 'post'
+  })
+}
+
+//  获取付款申请决策辅助
+export const GetContractPayPolicy = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetContractPayPolicy',
+    data,
+    method: 'post'
+  })
+}
+
+//  流程审批 同意/驳回
+export const ApprovalBillFlow = (data = {}) => {
+  return axios.request({
+    url: '/api/ApprovalFlow/ApprovalBillFlow',
+    data,
+    method: 'post'
+  })
+}
+
+//  采购合同提交
+export const PurcherUpdate = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/PurcherUpdate',
+    data,
+    method: 'post'
+  })
+}
+
+//  获取付款合同供应商分类列表
+export const GetContractSupplier = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetContractSupplier',
+    data,
+    method: 'post'
+  })
+}
+
+//  获取付款账单
+export const GetPaymentBill = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPaymentBill',
+    data,
+    method: 'post'
+  })
+}
+
+//  获取付款账单详情
+export const GetPaymentBillDetail = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPaymentBillDetail',
+    data,
+    method: 'post'
+  })
+}
+
+//  获取付款申请(待办事项审批)
+export const GetApplyPurchasePay = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetApplyPurchasePay',
+    data,
+    method: 'post'
+  })
+}
+
+//  到货通知
+export const PurContractArrivalNotice = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/PurContractArrivalNotice',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取代付运费记录
+export const GetPurExpressFee = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPurExpressFee',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增代付运费记录
+export const AddPurchaseExpressFee = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/AddPurchaseExpressFee',
+    data,
+    method: 'post'
+  })
+}
+
+// 上传转账付款凭证
+export const SavePaymentVoucher = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/SavePaymentVoucher',
+    data,
+    method: 'post'
+  })
+}
+
+// 特批付款数据
+export const AddApplyPurchasePay = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/AddApplyPurchasePay',
+    data,
+    method: 'post'
+  })
+}
+
+// 采购发起付款/报销
+export const SavePayContractBill = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/SavePayContractBills',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取质检短少记录
+export const GetQuantityCheckLake = (data = {}) => {
+  return axios.request({
+    url: '/api/StockQuantityCheck/GetQuantityCheckLake',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取质检记录
+export const GetStockCheckList = (data = {}) => {
+  return axios.request({
+    url: '/api/StockQuantityCheck/GetStockCheckList',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取申购明细
+export const ApplyPurchaseGetPageDetailList = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPageDetailList',
+    data,
+    method: 'post'
+  })
+}
+
+// 合同付款统计
+export const GetContractPayTotal = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetContractPayTotal',
+    data,
+    method: 'post'
+  })
+}
+
+// 合同付款汇总(按工艺)
+export const GetContractPayTechSum = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetContractPayTechSum',
+    data,
+    method: 'post'
+  })
+}
+
+// 采购合同合计(按照工艺类型)
+export const GetPurContractTotal = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPurContractTotal',
+    data,
+    method: 'post'
+  })
+}
+
+// 完成入库记录
+export const FinishStockIn = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/FinishStockIn',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取付款单打印数据
+export const GetContractPrintData = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetContractPrintData',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取合同付款统计
+export const GetContractPayBillTotal = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetContractPayBillTotal',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取付款单列表
+export const GetPurContractPayBill = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPurContractPayBill',
+    data,
+    method: 'post'
+  })
+}
+
+// 付款详情汇总(按工艺)
+export const GetContractPayBillTechSum = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetContractPayBillTechSum',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取质检单
+export const GetContractQtyCheckBill = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetContractQtyCheckBill',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取合同相关联的付款单
+export const GetApplyPayBill = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetApplyPayBill',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增合同删除审批单
+export const AddPurchaseContractDel = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/AddPurchaseContractDel',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取合同删除审批单
+export const GetPurchaseContractDel = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetPurchaseContractDel',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取历史付款记录(供应商汇总)
+export const GetHistoryPaymentSum = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetHistoryPaymentSum',
+    data,
+    method: 'post'
+  })
+}
+
+// 历史付款记录
+export const GetHistoryPaymentRecord = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetHistoryPaymentRecord',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取历史付款物料
+export const GetHistoryPaymentMaterial = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyPurchase/GetHistoryPaymentMaterial',
+    data,
+    method: 'post'
+  })
+}
+
+
+// 获取历史付款物料
+export const selectDetails = (data = {}) => {
+  return axios.request({
+    url: '/api/vo/selectDetails',
+    data,
+    method: 'post'
+  })
+}

+ 433 - 0
src/api/baseData.js

@@ -0,0 +1,433 @@
+import axios from '@/libs/api.request'
+
+// 物料分类列表
+export const GetMaterialCategory = (data = {}) => {
+  return axios.request({
+    url: '/api/MaterialCategory/GetPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取物料分类树
+export const GetMaterialCategoryZTree = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetMaterialCategoryZTree',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增物料分类
+export const AddMaterialCategory = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/MaterialCategoryAdd',
+    data,
+    method: 'post'
+  })
+}
+
+// 修改物料分类
+export const UpdateMaterialCategory = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/MaterialCategoryUpdate',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除物料分类
+export const DeleteMaterialCategory = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/MaterialCategoryDelete',
+    data,
+    method: 'post'
+  })
+}
+
+// 仓库维护列表
+export const GetStockHousePageList = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetStockHousePageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增仓库
+export const StockHouseAdd = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/StockHouseAdd',
+    data,
+    method: 'post'
+  })
+}
+
+// 修改仓库
+export const StockHouseUpdate = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/StockHouseUpdate',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除仓库
+export const StockHouseDelete = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/StockHouseDelete',
+    data,
+    method: 'post'
+  })
+}
+
+// 分区分页
+export const GetStockHouseAreaPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetStockHouseAreaPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增分区
+export const StockHouseAreaAdd = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/StockHouseAreaAdd',
+    data,
+    method: 'post'
+  })
+}
+
+// 修改分区
+export const StockHouseAreaUpdate = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/StockHouseAreaUpdate',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除分区
+export const StockHouseAreaDelete = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/StockHouseAreaDelete',
+    data,
+    method: 'post'
+  })
+}
+
+// 面料列表
+export const GetMaterialPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetMaterialPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增面料
+export const MaterialAdd = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/MaterialAdd',
+    data,
+    method: 'post'
+  })
+}
+
+// 修改面料
+export const MaterialUpdate = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/MaterialUpdate',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除面料
+export const MaterialDelete = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/MaterialDelete',
+    data,
+    method: 'post'
+  })
+}
+
+// 供应商列表
+export const GetFactoryPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetFactoryPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 供应商下拉
+export const GetFactorySelectItem = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetFactorySelectItem',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增供应商
+export const FactoryAdd = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/FactoryAdd',
+    data,
+    method: 'post'
+  })
+}
+
+// 编辑供应商
+export const FactoryUpdate = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/FactoryUpdate',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除供应商
+export const FactoryDelete = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/FactoryDelete',
+    data,
+    method: 'post'
+  })
+}
+
+// 供应商价格列表
+export const GetFacPricePageList = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetFacPricePageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增供应商价格
+export const FacPriceAdd = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/FacPriceAdd',
+    data,
+    method: 'post'
+  })
+}
+
+// 编辑供应商价格
+export const FacPriceChange = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/FacPriceChange',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除供应商价格
+export const FacPriceDelete = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/FacPriceDelete',
+    data,
+    method: 'post'
+  })
+}
+
+// 面料设置
+export const SaveMaterialSet = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/SaveMaterialSet',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取面料设置
+export const GetMaterialSet = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetMaterialSet',
+    data,
+    method: 'post'
+  })
+}
+
+// 供应商维护记录
+export const GetFacKeepRecordPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetFacKeepRecordPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 供应商维护记录新增
+export const EditFacKeepRecord = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/EditFacKeepRecord',
+    data,
+    method: 'post'
+  })
+}
+
+// 供应商统计
+export const FactoryStat = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/FactoryStat',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取物料审批数据
+export const GetMaterialEditCheckData = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetMaterialEditCheckData',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取价格变更合同列表
+export const GetChangePriceContractList = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetChangePriceContractList',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取供应商价格变更审批数据
+export const GetChangePriceCheck = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetChangePriceCheck',
+    data,
+    method: 'post'
+  })
+}
+
+// 选择仓库下拉
+export const GetStockHouse = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetStockHouse',
+    data,
+    method: 'post'
+  })
+}
+
+// 字典列表
+export const DataDictionary = (data = {}) => {
+  return axios.request({
+    url: '/api/DataDictionary/GetPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 字典新增
+export const AddDataDictionary = (data = {}) => {
+  return axios.request({
+    url: '/api/DataDictionary/Add',
+    data,
+    method: 'post'
+  })
+}
+
+// 字典修改
+export const UpdateDataDictionary = (data = {}) => {
+  return axios.request({
+    url: '/api/DataDictionary/Update',
+    data,
+    method: 'post'
+  })
+}
+
+// 字典删除
+export const DeleteDataDictionary = (data = {}) => {
+  return axios.request({
+    url: '/api/DataDictionary/Delete',
+    data,
+    method: 'post'
+  })
+}
+
+// 后台管理 开关
+export const EditConfig = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/EditConfig',
+    data,
+    method: 'post'
+  })
+}
+
+// 后台管理 开关
+export const GetConfig = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetConfig',
+    data,
+    method: 'post'
+  })
+}
+
+// 枚举类型列表
+export const GetGroupCodeList = (data = {}) => {
+  return axios.request({
+    url: '/api/DataDictionary/GetGroupCodeList',
+    data,
+    method: 'post'
+  })
+}
+
+// 工艺类型列表
+export const GetTechnologyTypList = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetTechnologyTypList',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取供应商收款账户
+export const GetSupplierBank = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetSupplierBank',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增供应商收款账户
+export const AddSupplierBank = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/AddSupplierBank',
+    data,
+    method: 'post'
+  })
+}
+
+// 编辑供应商收款账户
+export const EditSupplierBank = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/EditSupplierBank',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除供应商收款账户
+export const DeleteSupplierBank = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/DeleteSupplierBank',
+    data,
+    method: 'post'
+  })
+}
+
+// 合同批次
+export const GetContractBatchPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/GetContractBatchPageList',
+    data,
+    method: 'post'
+  })
+}

+ 51 - 0
src/api/data.js

@@ -0,0 +1,51 @@
+import axios from '@/libs/api.request'
+
+export const getTableData = () => {
+  return axios.request({
+    url: 'get_table_data',
+    method: 'get'
+  })
+}
+
+export const getDragList = () => {
+  return axios.request({
+    url: 'get_drag_list',
+    method: 'get'
+  })
+}
+
+export const errorReq = () => {
+  return axios.request({
+    url: 'error_url',
+    method: 'post'
+  })
+}
+
+export const saveErrorLogger = info => {
+  return axios.request({
+    url: 'save_error_logger',
+    data: info,
+    method: 'post'
+  })
+}
+
+export const uploadImg = formData => {
+  return axios.request({
+    url: 'image/upload',
+    data: formData
+  })
+}
+
+export const getOrgData = () => {
+  return axios.request({
+    url: 'get_org_data',
+    method: 'get'
+  })
+}
+
+export const getTreeSelectData = () => {
+  return axios.request({
+    url: 'get_tree_select_data',
+    method: 'get'
+  })
+}

+ 656 - 0
src/api/stock.js

@@ -0,0 +1,656 @@
+import axios from '@/libs/api.request'
+
+// 获取库存管理列表
+export const GetStockPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetStockPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 出入库记录
+export const GetStockWaterPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetStockWaterPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 盘点记录
+export const GetCheckRecordPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetCheckRecordPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 盘点记录明细
+export const GetCheckDetailPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetCheckDetailPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 每日库存盘点列表
+export const EveryDayStorageCheckList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/EveryDayStorageCheckList',
+    data,
+    method: 'post'
+  })
+}
+
+// 人工库存盘点列表
+export const PeopleStorageCheckList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/PeopleStorageCheckList',
+    data,
+    method: 'post'
+  })
+}
+
+// 单个Rfid完成库存盘点
+export const RfidCompleteCheck = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/RfidCompleteCheck',
+    data,
+    method: 'post'
+  })
+}
+
+// 申领单详情分页
+export const GetApplyTakePageList = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/GetPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增领料申请单
+export const AddApplyTake = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/Add',
+    data,
+    method: 'post'
+  })
+}
+
+// 领料申请审批或驳回
+export const ApprovalTake = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/ApprovalTake',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取领料单审批流程
+export const GetApprovalFlows = (data = {}) => {
+  return axios.request({
+    url: '/api/ApprovalFlow/GetApprovalFlows',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取出库记录
+export const GetOutStockPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetOutStockPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取出库记录明细
+export const GetOutBillDetail = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetOutBillDetail',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取入库记录
+export const GetInStockPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetInStockPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 采购申请单
+export const GetApplyBill = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetApplyBill',
+    data,
+    method: 'post'
+  })
+}
+
+// 入库单
+export const GetInStockBill = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetInStockBill',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取质检记录
+export const GetQuantityCheckRecordList = (data = {}) => {
+  return axios.request({
+    url: '/api/StockQuantityCheck/GetQuantityCheckRecordList',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取质检记录(新)
+export const GetQuantityCheckRecord = (data = {}) => {
+  return axios.request({
+    url: '/api/StockQuantityCheck/GetQuantityCheckRecord',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取其他出库详情(待办事项审批)
+export const GetApplyStockOutBill = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/GetApplyStockOutBill',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取归还入库申请
+export const GetApplyStockInBackRequestDto = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetApplyStockInBackRequestDto',
+    data,
+    method: 'post'
+  })
+}
+
+// 盘盈亏单
+export const GetMonthStockCheck = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetMonthStockCheck',
+    data,
+    method: 'post'
+  })
+}
+
+// 入库单序时簿
+export const GetStockInDocumentList = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetStockInDocumentList',
+    data,
+    method: 'post'
+  })
+}
+
+// 领料序时簿
+export const GetStockTakeDocumentList = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetStockTakeDocumentList',
+    data,
+    method: 'post'
+  })
+}
+
+// 物料收发汇总
+export const GetMaterialStockInOutSum = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetMaterialStockInOutSum',
+    data,
+    method: 'post'
+  })
+}
+
+// 物料月汇总
+export const GetMaterialMonthSum = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetMaterialMonthSum',
+    data,
+    method: 'post'
+  })
+}
+
+// 物料进出信息
+export const GetStockWaterInOut = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetStockWaterInOut',
+    data,
+    method: 'post'
+  })
+}
+
+// 库存列表
+export const GetStockDataPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetStockDataPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 出入库
+export const DoStorageDataInOut = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/DoStorageDataInOut',
+    data,
+    method: 'post'
+  })
+}
+
+// 新建标签
+export const CreateStockTagWeb = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/CreateStockTagWeb',
+    data,
+    method: 'post'
+  })
+}
+
+// 新建标签
+export const GetStockTagData = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/GetStockTagData',
+    data,
+    method: 'post'
+  })
+}
+
+// 出库明细
+export const GetStockTagDetialPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetStockTagDetialPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 修改库存标签数量
+export const UpdateStockTagQty = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/UpdateStockTagQty',
+    data,
+    method: 'post'
+  })
+}
+
+// 标签出库
+export const StockTagOut = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/StockTagOut',
+    data,
+    method: 'post'
+  })
+}
+
+// 取消领料神奇
+export const CancelApplyTake = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/CancelApplyTake',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取技术员报表
+export const TechnicianReport = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/TechnicianReport',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取技术员列表
+export const TechnicianReportUser = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/TechnicianReportUser',
+    data,
+    method: 'post'
+  })
+}
+
+// 盘点记录明细
+export const GetAllCheckResultPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetAllCheckResultPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 盘点记录获取审批数据
+export const GetFlowCheckDataPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetFlowCheckDataPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 库存汇总(按照工艺类型/用途)
+export const GetStockDetailSum = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetStockDetailSum',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取面料用途
+export const GetStockMaterialPurpose = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetStockMaterialPurpose',
+    data,
+    method: 'post'
+  })
+}
+
+// 提交指定用户盘点
+export const SubmitUserCheck = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/SubmitUserCheck',
+    data,
+    method: 'post'
+  })
+}
+
+// 错误标签明细查询
+export const GetAllErrorTag = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetAllErrorTag',
+    data,
+    method: 'post'
+  })
+}
+
+// 错误标签列表查询
+export const GetErrorTagDateList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetErrorTagDateList',
+    data,
+    method: 'post'
+  })
+}
+
+// 手动发起整仓盘点
+export const BeginPlcAllStorageCheck = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/BeginPlcAllStorageCheck',
+    data,
+    method: 'post'
+  })
+}
+
+// 个人库存统计数据
+export const GetUserStockStat = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetUserStockStat',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取个人库存列表
+export const GetUserStockList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetUserStockList',
+    data,
+    method: 'post'
+  })
+}
+
+// 编辑个人库存
+export const EditUserStock = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/EditUserStock',
+    data,
+    method: 'post'
+  })
+}
+
+// 编辑个人工盘点记录
+export const GetUserCheckTaskList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetUserCheckTaskList',
+    data,
+    method: 'post'
+  })
+}
+
+// 批量单新增
+export const AddMaterialUse = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/AddMaterialUse',
+    data,
+    method: 'post'
+  })
+}
+
+// 批量单删除
+export const DelMaterialUse = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/DelMaterialUse',
+    data,
+    method: 'post'
+  })
+}
+
+// 批量单列表
+export const GetMaterialUseList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetMaterialUseList',
+    data,
+    method: 'post'
+  })
+}
+
+// 盘点记录月份统计
+export const GetCheckRecordMonthStat = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetCheckRecordMonthStat',
+    data,
+    method: 'post'
+  })
+}
+
+// 盘点人数(月份统计明细)
+export const GetMonthCheckUserList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetMonthCheckUserList',
+    data,
+    method: 'post'
+  })
+}
+
+// 盘点记录明细(盘点记录/月统计明细)
+export const GetCheckRecordDetailList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetCheckRecordDetailList',
+    data,
+    method: 'post'
+  })
+}
+
+// 盘点标签(库存列表/月统计明细)
+export const GetSingleMaterialCTList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetCheckTagList',
+    data,
+    method: 'post'
+  })
+}
+
+// 盘盈亏期初期末统计(月份统计明细)
+export const GetMonthBeginEndStat = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetMonthBeginEndStat',
+    data,
+    method: 'post'
+  })
+}
+
+// 按面料获取盘点记录(库存列表)
+export const GetSingleMaterialCRList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetSingleMaterialCRList',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取盘点审批分页数据
+export const GetErrorTagPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetErrorTagPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 库存管理展开数据
+export const GetStockTagDetailList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetStockTagDetailList',
+    data,
+    method: 'post'
+  })
+}
+
+// 添加个人仓库
+export const AddUserStock = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/AddUserStock',
+    data,
+    method: 'post'
+  })
+}
+
+// 转移个人仓库
+export const TransferUserStock = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/TransferUserStock',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除指定用户盘点
+export const DelUserCheck = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/DelUserCheck',
+    data,
+    method: 'post'
+  })
+}
+
+// 查询指定用户盘点
+export const GetUserCheck = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetUserCheck',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取标签
+export const GetStockTagPage = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetStockTagPage',
+    data,
+    method: 'post'
+  })
+}
+
+// 免检申请
+export const GetStockExemptCheck = (data = {}) => {
+  return axios.request({
+    url: '/api/StockQuantityCheck/GetStockExemptCheck',
+    data,
+    method: 'post'
+  })
+}
+
+// 绑定rfid
+export const BandingStockInRfidCode = (data = {}) => {
+  return axios.request({
+    url: '/api/StockInOut/BandingStockInRfidCode',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取退料分页列表
+export const GetStockBackPage = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/GetStockBackPage',
+    data,
+    method: 'post'
+  })
+}
+// 退料 获取质检/获取现场退料申请
+export const GetApplySceneBack = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/GetApplySceneBack',
+    data,
+    method: 'post'
+  })
+}
+// 质检员判定退料申请
+export const CheckApplySceneBack = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/CheckApplySceneBack',
+    data,
+    method: 'post'
+  })
+}
+
+// 退料相关
+export const GetApplySceneBackData = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/GetApplySceneBackData',
+    data,
+    method: 'post'
+  })
+}
+
+// 报废
+export const DestroyStockBack = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/DestroyStockBack',
+    data,
+    method: 'post'
+  })
+}
+
+// 退款
+export const RefundsStockBack = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/RefundsStockBack',
+    data,
+    method: 'post'
+  })
+}
+
+// 退货
+export const PurchaserDealWithStockBack = (data = {}) => {
+  return axios.request({
+    url: '/api/ApplyTake/PurchaserDealWithStockBack',
+    data,
+    method: 'post'
+  })
+}

+ 159 - 0
src/api/storageHome.js

@@ -0,0 +1,159 @@
+import axios from '@/libs/api.request'
+
+/* 实时库存 */
+export const GetRealTimeStockOut = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetRealTimeStockOut',
+    data,
+    method: 'post'
+  })
+}
+
+/* 最新申购 */
+export const GetLatestApplyPurchase = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetLatestApplyPurchase',
+    data,
+    method: 'post'
+  })
+}
+
+/* 核心面料消耗量 */
+export const GetCoreMateriaConsume = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetCoreMateriaConsume',
+    data,
+    method: 'post'
+  })
+}
+
+/* 采购进度(首页) */
+export const GetPurchaseProgress = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetPurchaseProgress',
+    data,
+    method: 'post'
+  })
+}
+
+/* 获取消息提醒列表(子页面) */
+export const GetMessageRemindPage = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetMessageRemindPage',
+    data,
+    method: 'post'
+  })
+}
+
+/* 阅读消息提醒 */
+export const ReadMessageRemind = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/ReadMessageRemind',
+    data,
+    method: 'post'
+  })
+}
+
+/* 获取总览 */
+export const GetTotalView = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetTotalView',
+    data,
+    method: 'post'
+  })
+}
+
+/* 获取库存监控 */
+export const GetStockMonitor = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetStockMonitor',
+    data,
+    method: 'post'
+  })
+}
+
+/* 库存滞留数据 */
+export const GetStockDetailDelay = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetStockDetailDelay',
+    data,
+    method: 'post'
+  })
+}
+
+/* 今日消耗合计 */
+export const GetTodayConsumeTotal = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetTodayConsumeTotal',
+    data,
+    method: 'post'
+  })
+}
+
+/* 今日消耗排名 */
+export const GetTodayConsumeRank = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetTodayConsumeRank',
+    data,
+    method: 'post'
+  })
+}
+/* 今日消耗用户列表 */
+export const GetTodayConsumeUser = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetTodayConsumeUser',
+    data,
+    method: 'post'
+  })
+}
+/* 今日消耗详情 */
+export const GetTodayConsumeDetail = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetTodayConsumeDetail',
+    data,
+    method: 'post'
+  })
+}
+/* 滞留物料详情 */
+export const GetStockDelayMaterial = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetStockDelayMaterial',
+    data,
+    method: 'post'
+  })
+}
+/* 库存预警 */
+export const GetStockWarning = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetStockWarning',
+    data,
+    method: 'post'
+  })
+}
+
+/* 库存合计(按照工艺类型) */
+export const GetStockDetailTotal = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/GetStockDetailTotal',
+    data,
+    method: 'post'
+  })
+}
+
+/* 异常出库列表 */
+export const AbnormalOutStockPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/AbnormalOutStockPageList',
+    data,
+    method: 'post'
+  })
+}
+
+/* 异常出库处理 */
+export const AbnormalOutStockDeal = (data = {}) => {
+  return axios.request({
+    url: '/api/StorageHome/AbnormalOutStockDeal',
+    data,
+    method: 'post'
+  })
+}

+ 113 - 0
src/api/supplierShip.js

@@ -0,0 +1,113 @@
+import axios from '@/libs/api.request'
+
+// 获取采购合同分页列表
+export const GetPurContractPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/GetPurContractPageList',
+    data,
+    method: 'post'
+  })
+}
+// 获取物料二维码标签列表
+export const GetSupplierQRCode = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/GetSupplierQRCode',
+    data,
+    method: 'post'
+  })
+}
+// 添加供应商二维码
+export const AddSupplierQRCode = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/AddSupplierQRCode',
+    data,
+    method: 'post'
+  })
+}
+// 供应商出货
+export const AddSupplierShipOut = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/AddSupplierShipOut',
+    data,
+    method: 'post'
+  })
+}
+// 删除供应商二维码标签
+export const DeleteSupplierQRCode = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/DeleteSupplierQRCode',
+    data,
+    method: 'post'
+  })
+}
+// 打印供应商二维码标签
+export const PrinterSupplierQRCode = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/PrinterSupplierQRCode',
+    data,
+    method: 'post'
+  })
+}
+
+// 临时测试打印列表
+export const GetSupplierQRCodeTest = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/GetSupplierQRCodeTest',
+    data,
+    method: 'post'
+  })
+}
+
+// 临时测试打印列表
+export const CompletePurchase = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/CompletePurchase',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取出货批次
+export const GetPurBatchShip = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/GetPurBatchShip',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增出货批次
+export const AddPurBatchShip = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/AddPurBatchShip',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除出货批次
+export const DeletePurBatchShip = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/DeletePurBatchShip',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取在途金额
+export const GetPurchaseOnWay = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/GetPurchaseOnWay',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取供应商出货审批数据
+export const GetSupplierShipFlow = (data = {}) => {
+  return axios.request({
+    url: '/api/SupplierShip/GetSupplierShipFlow',
+    data,
+    method: 'post'
+  })
+}

+ 19 - 0
src/api/upload.js

@@ -0,0 +1,19 @@
+import axios from '@/libs/api.request'
+
+/* 上传图片 */
+export const UploadBase64 = (data = {}) => {
+  return axios.request({
+    url: '/api/Upload/UploadBase64',
+    data,
+    method: 'post'
+  })
+}
+
+/* 上传运营执照 */
+export const UploadBusinessLicense = (data = {}) => {
+  return axios.request({
+    url: '/api/BaseData/UploadBusinessLicense',
+    data,
+    method: 'post'
+  })
+}

+ 244 - 0
src/api/user.js

@@ -0,0 +1,244 @@
+import axios from '@/libs/api.request'
+
+export const login = (data = {}) => {
+  return axios.request({
+    url: '/api/Account/Login',
+    data,
+    method: 'post'
+  })
+}
+
+export const getUserInfo = (data = {}) => {
+  return axios.request({
+    url: '/api/User/GetUserInfo',
+    data,
+    method: 'post'
+  })
+}
+
+// 退出
+export const logout = (token, roleKey) => {
+  return axios.request({
+    url: '/api/User/loginQuit',
+    data: {
+      roleKey: roleKey
+    },
+    method: 'post'
+  })
+}
+
+// 角色列表
+export const GetRolePageList = (data = {}) => {
+  return axios.request({
+    url: '/api/System/GetRolePageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增角色
+export const AddRole = (data = {}) => {
+  return axios.request({
+    url: '/api/System/RoleAdd',
+    data,
+    method: 'post'
+  })
+}
+
+// 编辑角色
+export const UpdateRole = (data = {}) => {
+  return axios.request({
+    url: '/api/System/RoleUpdate',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除角色
+export const DeleteRole = (data = {}) => {
+  return axios.request({
+    url: '/api/System/RoleDelete',
+    data,
+    method: 'post'
+  })
+}
+
+// 部门树形下拉数据
+export const GetDeptZTreeChildren = (data = {}) => {
+  return axios.request({
+    url: '/api/System/GetZTreeChildren',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增部门
+export const DepartmentAdd = (data = {}) => {
+  return axios.request({
+    url: '/api/System/DepartmentAdd',
+    data,
+    method: 'post'
+  })
+}
+
+// 编辑部门
+export const DepartmentUpdate = (data = {}) => {
+  return axios.request({
+    url: '/api/System/DepartmentUpdate',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除部门
+export const DepartmentDelete = (data = {}) => {
+  return axios.request({
+    url: '/api/System/DepartmentDelete',
+    data,
+    method: 'post'
+  })
+}
+
+// 用户列表
+export const GetUserPageList = (data = {}) => {
+  return axios.request({
+    url: '/api/User/GetPageList',
+    data,
+    method: 'post'
+  })
+}
+
+// 发起盘点用户列表
+export const GetUserList = (data = {}) => {
+  return axios.request({
+    url: '/api/Stock/GetUserList',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增用户
+export const UserAdd = (data = {}) => {
+  return axios.request({
+    url: '/api/User/Add',
+    data,
+    method: 'post'
+  })
+}
+
+// 编辑用户
+export const UserUpdate = (data = {}) => {
+  return axios.request({
+    url: '/api/User/Update',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除用户
+export const UserDelete = (data = {}) => {
+  return axios.request({
+    url: '/api/User/Delete',
+    data,
+    method: 'post'
+  })
+}
+
+// 重置密码
+export const ResetPassword = (data = {}) => {
+  return axios.request({
+    url: '/api/User/ResetPassword',
+    data,
+    method: 'post'
+  })
+}
+
+// 获取用户菜单
+export const GetMenuOperateList = (data = {}) => {
+  return axios.request({
+    url: '/api/System/GetMenuOperateList',
+    data,
+    method: 'post'
+  })
+}
+
+// 编辑用户菜单
+export const EditRoleMenu = (data = {}) => {
+  return axios.request({
+    url: '/api/System/EditRoleMenu',
+    data,
+    method: 'post'
+  })
+}
+
+// 用户列表
+export const GetMenuZTreeChildren = (data = {}) => {
+  return axios.request({
+    url: '/api/System/GetMenuZTreeChildren',
+    data,
+    method: 'post'
+  })
+}
+
+// 新增菜单
+export const MenuAdd = (data = {}) => {
+  return axios.request({
+    url: '/api/System/MenuAdd',
+    data,
+    method: 'post'
+  })
+}
+
+// 编辑菜单
+export const MenuUpdate = (data = {}) => {
+  return axios.request({
+    url: '/api/System/MenuUpdate',
+    data,
+    method: 'post'
+  })
+}
+
+// 删除菜单
+export const MenuDelete = (data = {}) => {
+  return axios.request({
+    url: '/api/System/MenuDelete',
+    data,
+    method: 'post'
+  })
+}
+
+// 首页待办事项
+export const GetDealWithItem = (data = {}) => {
+  return axios.request({
+    url: '/api/ApprovalFlow/GetDealWithItem',
+    data,
+    method: 'post'
+  })
+}
+
+// 修改密码
+export const ChangePassword = (data = {}) => {
+  return axios.request({
+    url: '/api/User/ChangePassword',
+    data,
+    method: 'post'
+  })
+}
+
+// 上传app版本
+export const UploadApkFile = (data = {}) => {
+  return axios.request({
+    url: '/api/User/UploadApkFile',
+    data,
+    method: 'post'
+  })
+}
+
+// 上传app版本
+export const DownloadApkFile = (data = {}) => {
+  return axios.request({
+    url: '/api/User/DownloadApkFile',
+    data,
+    method: 'post'
+  })
+}

+ 87 - 0
src/assets/icons/iconfont.css

@@ -0,0 +1,87 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 2850235 */
+  src: url('iconfont.woff2?t=1633765104387') format('woff2'),
+       url('iconfont.woff?t=1633765104387') format('woff'),
+       url('iconfont.ttf?t=1633765104387') format('truetype');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-fix-full:before {
+  content: "\e9b9";
+}
+
+.icon-chukuguanli:before {
+  content: "\e7e8";
+}
+
+.icon-jichufuwupingtai:before {
+  content: "\e69b";
+}
+
+.icon-gongnengleixing1:before {
+  content: "\e61e";
+}
+
+.icon-quanbudingdan:before {
+  content: "\e602";
+}
+
+.icon-kucun:before {
+  content: "\e61a";
+}
+
+.icon-jichuguanli:before {
+  content: "\e779";
+}
+
+.icon-tubiaozhizuomoban-01:before {
+  content: "\e636";
+}
+
+.icon-gouwuchekong:before {
+  content: "\e601";
+}
+
+.icon-querenhetongquerenhetongqueding:before {
+  content: "\e690";
+}
+
+.icon-edit1:before {
+  content: "\e638";
+}
+
+.icon-shezhi:before {
+  content: "\e63a";
+}
+
+.icon-icon_function_chuku:before {
+  content: "\e889";
+}
+
+.icon-icon_function_ruku:before {
+  content: "\e88b";
+}
+
+.icon-chakan:before {
+  content: "\e600";
+}
+
+.icon-edit:before {
+  content: "\e61f";
+}
+
+.icon-shuaxin:before {
+  content: "\e87e";
+}
+
+.icon-delete:before {
+  content: "\e668";
+}
+

BIN
src/assets/icons/iconfont.eot


+ 135 - 0
src/assets/icons/iconfont.json

@@ -0,0 +1,135 @@
+{
+  "id": "2850235",
+  "name": "杰生智能仓储",
+  "font_family": "iconfont",
+  "css_prefix_text": "icon-",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "18170418",
+      "name": "解除固定,图钉",
+      "font_class": "fix-full",
+      "unicode": "e9b9",
+      "unicode_decimal": 59833
+    },
+    {
+      "icon_id": "16158855",
+      "name": "出库管理",
+      "font_class": "chukuguanli",
+      "unicode": "e7e8",
+      "unicode_decimal": 59368
+    },
+    {
+      "icon_id": "21591046",
+      "name": "基础服务平台",
+      "font_class": "jichufuwupingtai",
+      "unicode": "e69b",
+      "unicode_decimal": 59035
+    },
+    {
+      "icon_id": "22760538",
+      "name": "功能类型1",
+      "font_class": "gongnengleixing1",
+      "unicode": "e61e",
+      "unicode_decimal": 58910
+    },
+    {
+      "icon_id": "162881",
+      "name": "全部订单",
+      "font_class": "quanbudingdan",
+      "unicode": "e602",
+      "unicode_decimal": 58882
+    },
+    {
+      "icon_id": "14293994",
+      "name": "库存",
+      "font_class": "kucun",
+      "unicode": "e61a",
+      "unicode_decimal": 58906
+    },
+    {
+      "icon_id": "15668833",
+      "name": "基础管理",
+      "font_class": "jichuguanli",
+      "unicode": "e779",
+      "unicode_decimal": 59257
+    },
+    {
+      "icon_id": "17620090",
+      "name": "销售出库",
+      "font_class": "tubiaozhizuomoban-01",
+      "unicode": "e636",
+      "unicode_decimal": 58934
+    },
+    {
+      "icon_id": "1306",
+      "name": "购物车空",
+      "font_class": "gouwuchekong",
+      "unicode": "e601",
+      "unicode_decimal": 58881
+    },
+    {
+      "icon_id": "783687",
+      "name": "确认合同 确认 合同 确定",
+      "font_class": "querenhetongquerenhetongqueding",
+      "unicode": "e690",
+      "unicode_decimal": 59024
+    },
+    {
+      "icon_id": "1011816",
+      "name": "edit",
+      "font_class": "edit1",
+      "unicode": "e638",
+      "unicode_decimal": 58936
+    },
+    {
+      "icon_id": "8679527",
+      "name": "设置",
+      "font_class": "shezhi",
+      "unicode": "e63a",
+      "unicode_decimal": 58938
+    },
+    {
+      "icon_id": "10088924",
+      "name": "出库",
+      "font_class": "icon_function_chuku",
+      "unicode": "e889",
+      "unicode_decimal": 59529
+    },
+    {
+      "icon_id": "10088945",
+      "name": "入库",
+      "font_class": "icon_function_ruku",
+      "unicode": "e88b",
+      "unicode_decimal": 59531
+    },
+    {
+      "icon_id": "2815705",
+      "name": "查看",
+      "font_class": "chakan",
+      "unicode": "e600",
+      "unicode_decimal": 58880
+    },
+    {
+      "icon_id": "1185453",
+      "name": "edit",
+      "font_class": "edit",
+      "unicode": "e61f",
+      "unicode_decimal": 58911
+    },
+    {
+      "icon_id": "9626938",
+      "name": "刷新",
+      "font_class": "shuaxin",
+      "unicode": "e87e",
+      "unicode_decimal": 59518
+    },
+    {
+      "icon_id": "11770174",
+      "name": "delete",
+      "font_class": "delete",
+      "unicode": "e668",
+      "unicode_decimal": 58984
+    }
+  ]
+}

+ 56 - 0
src/assets/icons/iconfont.svg

@@ -0,0 +1,56 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<!--
+2013-9-30: Created.
+-->
+<svg>
+<metadata>
+Created by iconfont
+</metadata>
+<defs>
+
+<font id="iconfont" horiz-adv-x="1024" >
+  <font-face
+    font-family="iconfont"
+    font-weight="500"
+    font-stretch="normal"
+    units-per-em="1024"
+    ascent="896"
+    descent="-128"
+  />
+    <missing-glyph />
+    
+    <glyph glyph-name="bear" unicode="&#58880;" d="M1024 683.008q0-70.656-46.08-121.856 46.08-89.088 46.08-193.536 0-96.256-39.936-181.248t-109.568-147.968-162.816-99.328-199.68-36.352-199.68 36.352-162.304 99.328-109.568 147.968-40.448 181.248q0 104.448 46.08 193.536-46.08 51.2-46.08 121.856 0 37.888 13.824 71.168t37.376 58.368 55.808 39.424 68.096 14.336q43.008 0 78.848-18.432t59.392-50.176q46.08 17.408 96.256 26.624t102.4 9.216 102.4-9.216 96.256-26.624q24.576 31.744 59.904 50.176t78.336 18.432q36.864 0 68.608-14.336t55.296-39.424 37.376-58.368 13.824-71.168zM205.824 268.288q10.24 0 18.944 10.24t15.36 28.672 10.24 42.496 3.584 51.712-3.584 51.712-10.24 41.984-15.36 28.16-18.944 10.24q-9.216 0-17.92-10.24t-15.36-28.16-10.752-41.984-4.096-51.712 4.096-51.712 10.752-42.496 15.36-28.672 17.92-10.24zM512-31.744000000000028q53.248 0 99.84 13.312t81.408 35.84 54.784 52.736 19.968 65.024q0 33.792-19.968 64t-54.784 52.736-81.408 35.84-99.84 13.312-99.84-13.312-81.408-35.84-54.784-52.736-19.968-64q0-34.816 19.968-65.024t54.784-52.736 81.408-35.84 99.84-13.312zM818.176 268.288q10.24 0 18.944 10.24t15.36 28.672 10.24 42.496 3.584 51.712-3.584 51.712-10.24 41.984-15.36 28.16-18.944 10.24q-9.216 0-17.92-10.24t-15.36-28.16-10.752-41.984-4.096-51.712 4.096-51.712 10.752-42.496 15.36-28.672 17.92-10.24zM512 235.51999999999998q39.936 0 68.096-9.728t28.16-24.064-28.16-24.064-68.096-9.728-68.096 9.728-28.16 24.064 28.16 24.064 68.096 9.728z"  horiz-adv-x="1024" />
+
+    
+    <glyph glyph-name="resize-vertical" unicode="&#59331;" d="M512 896C229.248 896 0 666.752 0 384s229.248-512 512-512 512 229.248 512 512S794.752 896 512 896zM576 192l64 0-128-128-128 128 64 0L448 576l-64 0 128 128 128-128-64 0L576 192z"  horiz-adv-x="1024" />
+
+    
+    <glyph glyph-name="chuizhifanzhuan" unicode="&#58977;" d="M286.01856 645.08416l472.4224 0 0-146.2784-472.4224 0 0 146.2784ZM87.19872 420.37248l885.80096 0 0-70.87104-885.80096 0 0 70.87104ZM773.55008 268.05248l0-31.0016L270.6688 237.05088l0 31.0016L773.55008 268.05248zM773.55008 121.4208l0-31.0016L270.6688 90.4192l0 31.0016L773.55008 121.4208zM742.54848 240.75776l31.0016 0 0-123.04896-31.0016 0L742.54848 240.75776zM270.70464 240.57856l31.0016 0 0-123.04896-31.0016 0L270.70464 240.57856z"  horiz-adv-x="1024" />
+
+    
+    <glyph glyph-name="shuipingfanzhuan" unicode="&#58978;" d="M252.76928 596.096l146.2784 0 0-472.42752-146.2784 0 0 472.42752ZM477.48096 810.65472l70.87104 0 0-885.80608-70.87104 0 0 885.80608ZM629.80096 611.2l31.0016 0 0-502.88128-31.0016 0L629.80096 611.2zM776.42752 611.2l31.0016 0 0-502.88128-31.0016 0L776.42752 611.2zM657.09056 580.1984l0 31.0016 123.04896 0 0-31.0016L657.09056 580.1984zM657.27488 108.35456l0 31.0016 123.04896 0 0-31.0016L657.27488 108.35456z"  horiz-adv-x="1024" />
+
+    
+    <glyph glyph-name="qq" unicode="&#58889;" d="M147.372058 491.394284c-5.28997-13.909921 2.431986-22.698872 0-75.732573-0.682996-14.25092-62.165649-78.762555-86.569511-145.791177-24.192863-66.517625-27.519845-135.978232 9.811944-163.285078 37.419789-27.305846 72.191593 90.879487 76.757567 73.685584 1.961989-7.509958 4.436975-15.317914 7.423958-23.338868a331.945126 331.945126 0 0 1 61.140655-101.162429c5.929967-6.783962-36.009797-19.199892-61.140655-61.99365-25.173858-42.751759 7.209959-120.49032 132.223254-120.49032 161.27909 0 197.288886 56.70368 200.574868 56.447681 12.031932-0.895995 12.841928 0 25.599855 0 15.572912 0 9.129948-1.279993 23.593867 0 7.807956 0.682996 86.186514-67.839617 194.686901-56.447681 184.873956 19.45589 156.586116 81.40754 142.079198 120.48932-15.103915 40.83277-68.692612 59.946662-66.303626 62.549647 44.28775 48.938724 51.285711 79.018554 66.346626 123.9463 6.143965 18.473896 49.066723-101.674426 82.089537-73.685584 13.781922 11.690934 41.301767 60.24566 13.781922 163.285078-27.519845 102.996419-80.767544 126.505286-79.615551 145.791177 2.389987 40.191773 1.023994 68.436614-1.023994 75.732573-9.812945 35.4128-30.378829 27.604844-30.378829 35.4128C858.450044 730.752933 705.10691 896 515.966978 896s-342.398067-165.289067-342.398068-369.192916c0-16.169909-14.378919-4.223976-26.154852-35.4128z"  horiz-adv-x="1024" />
+
+    
+    <glyph glyph-name="frown" unicode="&#59262;" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM512 363c-85.5 0-155.6-67.3-160-151.6-0.2-4.6 3.4-8.4 8-8.4h48.1c4.2 0 7.8 3.2 8.1 7.4C420 259.9 461.5 299 512 299s92.1-39.1 95.8-88.6c0.3-4.2 3.9-7.4 8.1-7.4H664c4.6 0 8.2 3.8 8 8.4-4.4 84.3-74.5 151.6-160 151.6z"  horiz-adv-x="1024" />
+
+    
+    <glyph glyph-name="meh" unicode="&#59264;" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM664 331H360c-4.4 0-8-3.6-8-8v-48c0-4.4 3.6-8 8-8h304c4.4 0 8 3.6 8 8v48c0 4.4-3.6 8-8 8z"  horiz-adv-x="1024" />
+
+    
+    <glyph glyph-name="smile" unicode="&#59267;" d="M336 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM688 475m-48 0a48 48 0 1 1 96 0 48 48 0 1 1-96 0ZM512 832C264.6 832 64 631.4 64 384s200.6-448 448-448 448 200.6 448 448S759.4 832 512 832z m263-711c-34.2-34.2-74-61-118.3-79.8C611 21.8 562.3 12 512 12c-50.3 0-99 9.8-144.8 29.2-44.3 18.7-84.1 45.6-118.3 79.8-34.2 34.2-61 74-79.8 118.3C149.8 285 140 333.7 140 384s9.8 99 29.2 144.8c18.7 44.3 45.6 84.1 79.8 118.3 34.2 34.2 74 61 118.3 79.8C413 746.2 461.7 756 512 756c50.3 0 99-9.8 144.8-29.2 44.3-18.7 84.1-45.6 118.3-79.8 34.2-34.2 61-74 79.8-118.3C874.2 483 884 434.3 884 384s-9.8-99-29.2-144.8c-18.7-44.3-45.6-84.1-79.8-118.2zM664 363h-48.1c-4.2 0-7.8-3.2-8.1-7.4C604 306.1 562.5 267 512 267s-92.1 39.1-95.8 88.6c-0.3 4.2-3.9 7.4-8.1 7.4H360c-4.6 0-8.2-3.8-8-8.4 4.4-84.3 74.5-151.6 160-151.6s155.6 67.3 160 151.6c0.2 4.6-3.4 8.4-8 8.4z"  horiz-adv-x="1024" />
+
+    
+    <glyph glyph-name="man" unicode="&#59362;" d="M874 776H622c-3.3 0-6-2.7-6-6v-56c0-3.3 2.7-6 6-6h160.4L583.1 508.7c-50 38.5-111 59.3-175.1 59.3-76.9 0-149.3-30-203.6-84.4S120 356.9 120 280s30-149.3 84.4-203.6C258.7 22 331.1-8 408-8s149.3 30 203.6 84.4C666 130.7 696 203.1 696 280c0 64.1-20.8 124.9-59.2 174.9L836 654.1V494c0-3.3 2.7-6 6-6h56c3.3 0 6 2.7 6 6V746c0 16.5-13.5 30-30 30zM408 68c-116.9 0-212 95.1-212 212s95.1 212 212 212 212-95.1 212-212-95.1-212-212-212z"  horiz-adv-x="1024" />
+
+    
+    <glyph glyph-name="woman" unicode="&#59365;" d="M909.7 739.4l-42.2 42.2c-3.1 3.1-8.2 3.1-11.3 0L764 689.4l-84.2 84.2c-3.1 3.1-8.2 3.1-11.3 0l-42.1-42.1c-3.1-3.1-3.1-8.1 0-11.3l84.2-84.2-135.5-135.3c-50 38.5-111 59.3-175.1 59.3-76.9 0-149.3-30-203.6-84.4S112 348.9 112 272s30-149.3 84.4-203.6C250.7 14 323.1-16 400-16s149.3 30 203.6 84.4C658 122.7 688 195.1 688 272c0 64.2-20.9 125.1-59.3 175.1l135.4 135.4 84.2-84.2c3.1-3.1 8.2-3.1 11.3 0l42.1 42.1c3.1 3.1 3.1 8.1 0 11.3l-84.2 84.2 92.2 92.2c3.1 3.1 3.1 8.2 0 11.3zM400 60c-116.9 0-212 95.1-212 212s95.1 212 212 212 212-95.1 212-212-95.1-212-212-212z"  horiz-adv-x="1024" />
+
+    
+
+
+  </font>
+</defs></svg>

BIN
src/assets/icons/iconfont.ttf


BIN
src/assets/icons/iconfont.woff


BIN
src/assets/icons/iconfont.woff2


BIN
src/assets/images/B242C181-9C94-46bc-98C6-0DE6A1CC6A7F.txt


BIN
src/assets/images/avatar.png


BIN
src/assets/images/avator.png


BIN
src/assets/images/dck.png


BIN
src/assets/images/dsp.png


BIN
src/assets/images/dun.png


File diff suppressed because it is too large
+ 0 - 0
src/assets/images/error-page/error-401.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/images/error-page/error-404.svg


File diff suppressed because it is too large
+ 0 - 0
src/assets/images/error-page/error-500.svg


BIN
src/assets/images/exit.png


BIN
src/assets/images/gaojin.png


BIN
src/assets/images/gwq-sign.png


BIN
src/assets/images/img.png


BIN
src/assets/images/kcyj.png


BIN
src/assets/images/log-new-login.png


BIN
src/assets/images/log-new-nav.png


BIN
src/assets/images/login-bg.png


BIN
src/assets/images/login-icon.20420174.png


BIN
src/assets/images/login-icon.png


BIN
src/assets/images/login-image.png


BIN
src/assets/images/login-left.png


BIN
src/assets/images/login-logo.png


BIN
src/assets/images/logo-title.png


BIN
src/assets/images/nav-logo.png


BIN
src/assets/images/over.png


BIN
src/assets/images/qipao.png


BIN
src/assets/images/zlwl.png


BIN
src/assets/images/组 577.png


+ 796 - 0
src/components/board/board.vue

@@ -0,0 +1,796 @@
+<template>
+  <div class="container-wrap">
+    <div class="container">
+      <div class="top">
+        <div class="top-left">
+          <div class="top-left-top">
+            <div class="card">
+              <div class="content" style="height: 100%;">
+                <div class="over-view">
+                  <div class="over-view-item" @click="toHandle('schedule')">
+                    <div class="item-icon">
+                      <img :src="dspPic" alt="">
+                    </div>
+                    <div class="item-info">
+                      <p class="item-info-title">待审批</p>
+                      <p>
+                        <span class="num">{{ zlData.waitCheck }}</span>
+<!--                        <span>同比</span>-->
+<!--                        <Icon :type="zlData.isDown? 'md-arrow-down' : 'md-arrow-up'" :color="zlData.isDown? '#ff635f' : '#5cd9b4'"/>-->
+<!--                        <span>0%</span>-->
+                      </p>
+                    </div>
+                  </div>
+                  <div class="over-view-item" @click="toHandle('apply_manage')">
+                    <div class="item-icon">
+                      <img :src="dckPic" alt="">
+                    </div>
+                    <div class="item-info">
+                      <p class="item-info-title">待出库</p>
+                      <p>
+                        <span class="num">{{ zlData.waitOutStock }}</span>
+<!--                        <span>同比</span>-->
+<!--                        <Icon :type="zlData.isDown? 'md-arrow-down' : 'md-arrow-up'" :color="zlData.isDown? '#ff635f' : '#5cd9b4'"/>-->
+<!--                        <span>0%</span>-->
+                      </p>
+                    </div>
+                  </div>
+                  <div class="over-view-item" @click="toHandle('store_warning')">
+                    <div class="item-icon">
+                      <img :src="kcyjPic" alt="">
+                    </div>
+                    <div class="item-info">
+                      <p class="item-info-title">库存预警</p>
+                      <p>
+                        <span class="num">{{ zlData.stockwarning }}</span>
+<!--                        <span>同比</span>-->
+<!--                        <Icon :type="zlData.isDown? 'md-arrow-down' : 'md-arrow-up'" :color="zlData.isDown? '#ff635f' : '#5cd9b4'"/>-->
+<!--                        <span>0%</span>-->
+                      </p>
+                    </div>
+                  </div>
+                  <div class="over-view-item" @click="toHandle('material_stranded')">
+                    <div class="item-icon">
+                      <img :src="zlwlPic" alt="">
+                    </div>
+                    <div class="item-info">
+                      <p class="item-info-title">滞留物料</p>
+                      <p>
+                        <span class="num">{{ zlData.delayMaterial }}</span>
+<!--                        <span>同比</span>-->
+<!--                        <Icon :type="zlData.isDown? 'md-arrow-down' : 'md-arrow-up'" :color="zlData.isDown? '#ff635f' : '#5cd9b4'"/>-->
+<!--                        <span>0%</span>-->
+                      </p>
+                    </div>
+<!--                    <div class="label"></div>-->
+<!--                    <div class="value">{{ zlData.delayMaterial }}</div>-->
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="top-left-bottom">
+            <div class="top-left-bottom-left">
+              <!-- 最新申购 -->
+              <div class="card">
+                <div class="title" @click="toHandle('material_apply')">
+                  <span>最新申购(实时滚动)</span>
+                </div>
+                <div class="content">
+                  <div class="row">
+                    <div class="col-5 th">物料名称</div>
+                    <div class="col-3 th">库存数量</div>
+                    <div class="col-3 th">申购数量</div>
+                    <div class="col-3 th">申购人</div>
+                  </div>
+                  <div class="row-wrap">
+                    <div class="row"  v-for="(item, index) in zxsgData" :key="index">
+                      <div class="col-5">{{ item.materialName }}</div>
+                      <div class="col-3">{{ item.stockQty }}</div>
+                      <div class="col-3">{{ item.applyPurQty }}</div>
+                      <div class="col-3">{{ item.userName }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="top-left-bottom-right">
+              <!-- 实时出库 -->
+              <div class="card">
+                <div class="title">
+                  <span>
+                    实时出库监控(北京时间{{ $dayjs(nowTime).format('hh:mm') }})
+                  </span>
+                  <div style="display: flex">
+                    <span class="normal">
+                      <span class="idot"></span>
+                      正常出库
+                    </span>
+                    <span class="err" @click="toErrorOut">
+                      <span class="idot"></span>
+                      异常出库{{ abnormalNum || 0 }}条
+                    </span>
+                  </div>
+                </div>
+                <div class="content">
+                  <div class="row">
+                    <div class="col-1"></div>
+                    <div class="col-3 th">时间</div>
+                    <div class="col-5 th">物料名称</div>
+                    <div class="col-3 th">数量</div>
+                    <div class="col-3 th">操作员</div>
+                  </div>
+                  <div class="row-wrap">
+                    <div class="row"
+                         :class="item.abnormalOut? 'err' : ''"
+                         v-for="(item, index) in sskcData" :key="index">
+                      <div class="col-1 center"><Icon type="md-warning" v-if="item.abnormalOut" /></div>
+                      <div class="col-3">{{ item.stockOutTime }}</div>
+                      <div class="col-5">{{ item.materialName }}</div>
+                      <div class="col-3">{{ item.quantity }}</div>
+                      <div class="col-3">{{ item.userName }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="top-left-bottom">
+            <div class="top-left-bottom-left">
+              <!-- 核心品类出库排名(24小时/30日切换) -->
+              <div class="card">
+                <div class="title" style="justify-content: space-between;">
+                  <span @click="toHandle('store_out_record')" style="margin-right: 10px;">核心品类出库排名</span>
+<!--                  <i-switch size="large" true-color="#2db7f5" false-color="#19be6b">-->
+<!--                    <span slot="open">30日</span>-->
+<!--                    <span slot="close">24h</span>-->
+<!--                  </i-switch>-->
+                  <RadioGroup v-model="hxmlModel1" @on-change="hxmlToggle" type="button" button-style="solid" size="small">
+                    <Radio :label="0">24h</Radio>
+                    <Radio :label="1">30日</Radio>
+                  </RadioGroup>
+                </div>
+                <div class="content">
+                  <div class="row">
+                    <div class="col-5 th">物料名称</div>
+                    <div class="col-3 th">库存数量</div>
+                    <div class="col-3 th">出库数量</div>
+                  </div>
+                  <div class="row-wrap">
+                    <div class="row" v-for="(item, index) in hxml1Data" :key="index">
+                      <div class="col-5">{{ item.materialName }}</div>
+                      <div class="col-3">{{ item.stockQty }}</div>
+                      <div class="col-3">{{ item.consumeQty }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="top-left-bottom-right">
+              <!-- 库存滞留排名(24小时/30日切换) -->
+              <div class="card">
+                <div class="title" style="justify-content: space-between;">
+                  <span style="margin-right: 10px;">库存滞留排名</span>
+<!--                  <i-switch size="large" true-color="#2db7f5" false-color="#19be6b">-->
+<!--                    <span slot="open">30日</span>-->
+<!--                    <span slot="close">24h</span>-->
+<!--                  </i-switch>-->
+                  <RadioGroup v-model="kczlModel" @on-change="kczlToggle" type="button" button-style="solid" size="small">
+                    <Radio :label="0">24h</Radio>
+                    <Radio :label="1">30日</Radio>
+                  </RadioGroup>
+                </div>
+                <div class="content">
+                  <div class="row">
+                    <div class="col-5 th">物料名称</div>
+                    <div class="col-3 th">数量</div>
+                    <div class="col-3 th">滞留时间</div>
+                    <div class="col-3 th">周转率</div>
+                  </div>
+                  <div class="row-wrap">
+                    <div class="row" v-for="(item, index) in kczlData" :key="index">
+                      <div class="col-5">{{ item.materialName }}</div>
+                      <div class="col-3">{{ item.quantity }}</div>
+                      <div class="col-3">{{ item.delayDay }}</div>
+                      <div class="col-3">{{ item.turnoverRate }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="top-right" >
+            <!-- 实时库存盘点和ROI监控 -->
+              <div class="card">
+                <div class="title" @click="toHandle('use_today')">
+                  <span>实时库存盘点和ROI监控</span>
+                  <span class="err">
+                    <span style="color: #a5c4ff;">当前总价值:{{ kcjkData.totalValue }}万元 </span>
+                  </span>
+                </div>
+                <div class="content" style="overflow: auto">
+                  <div class="row">
+                    <div class="col-5 th">物料名称</div>
+                    <div class="col-3 th">库存数量</div>
+                    <div class="col-3 th">周转率</div>
+<!--                    <div class="col-3 th">回报率</div>-->
+                  </div>
+                  <div class="row" v-for="(item, index) in kcjkData.stockMaterials" :key="index">
+                    <div class="col-5">{{ item.materialName }}</div>
+                    <div class="col-3">{{ item.quantity }}</div>
+                    <div class="col-3">{{ item.rate }}</div>
+<!--                    <div class="col-3">{{ item.rate }}</div>-->
+                  </div>
+                  <div class="charts">
+                    <chart-pie style="height: 300px" :value="kcjkData.pieVal" :name="kcjkData.pieName"></chart-pie>
+                  </div>
+                </div>
+              </div>
+        </div>
+      </div>
+      <!-- 供应链管理实时监控系统 -->
+      <div class="bottom">
+        <div class="card">
+          <div class="title">
+            <span @click="toPaySite">供应链管理实时监控系统</span>
+          </div>
+          <div class="content">
+            <div class="row" style="height: 100%;overflow: hidden">
+              <div class="col-1">
+                <div class="card">
+                  <div class="sub-title">
+                    <Icon custom="iconfont icon-fix-full" :size="16" color="#0066ff" style="margin-right: 10px;"/>
+                    <span>供应商货物贴码</span>
+                  </div>
+                  <div class="content">
+                    <div class="row" v-for="(item, index) in cgjdData.printerItems" :key="index">
+                      <div style="padding: 0 10px">{{ $dayjs(item.dateTime).format('YYYY-MM-DD') }}</div>
+                      <div class="col-5">{{ item.materialName }}</div>
+                      <div class="col-5">{{ item.supplierName }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="col-1">
+                <div class="card">
+                  <div class="sub-title">
+                    <Icon custom="iconfont icon-fix-full" :size="16" color="#0066ff" style="margin-right: 10px;"/>
+                    <span>供应商发货监控 </span>
+                  </div>
+                  <div class="content">
+                    <div class="row" v-for="(item, index) in cgjdData.shipItems" :key="index">
+                      <div style="padding: 0 10px">{{ $dayjs(item.dateTime).format('YYYY-MM-DD') }}</div>
+                      <div class="col-5">{{ item.materialName }}</div>
+                      <div class="col-3">{{ item.arriveInfo }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="col-1">
+                <div class="card">
+                  <div class="sub-title">
+                    <Icon custom="iconfont icon-fix-full" :size="16" color="#0066ff" style="margin-right: 10px;"/>
+                    <span>到货换贴RFID监控 </span>
+                  </div>
+                  <div class="content">
+                    <div class="row" v-for="(item, index) in cgjdData.labelItems" :key="index">
+                      <div style="padding: 0 10px">{{ $dayjs(item.dateTime).format('YYYY-MM-DD') }}</div>
+                      <div class="col-5">{{ item.materialName }}</div>
+                      <div class="col-3">{{ item.userName }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="col-1">
+                <div class="card">
+                  <div class="sub-title">
+                    <Icon custom="iconfont icon-fix-full" :size="16" color="#0066ff" style="margin-right: 10px;"/>
+                    <span>货物RFID实时入库监控 </span>
+                  </div>
+                  <div class="content">
+                    <div class="row" v-for="(item, index) in cgjdData.inStockItems" :key="index">
+                      <div style="padding: 0 10px">{{ $dayjs(item.dateTime).format('HH:mm:ss') }}</div>
+                      <div class="col-5">{{ item.materialName }}</div>
+                      <div class="col-3">{{ item.userName }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import * as signalR from '@microsoft/signalr'
+import { MessagePackHubProtocol } from '@microsoft/signalr-protocol-msgpack'
+import {
+  GetRealTimeStockOut,
+  GetLatestApplyPurchase,
+  GetCoreMateriaConsume,
+  GetPurchaseProgress,
+  GetTotalView,
+  GetStockMonitor,
+  GetStockDetailDelay
+} from '@/api/storageHome'
+import ChartPie from './chart-pie'
+import dspPic from '@/assets/images/dsp.png'
+import dckPic from '@/assets/images/dck.png'
+import kcyjPic from '@/assets/images/kcyj.png'
+import zlwlPic from '@/assets/images/zlwl.png'
+import config from '@/config'
+const baseUrl = process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro
+export default {
+  name: 'board',
+  data () {
+    return {
+      connection: null,
+      hxmlModel1: 0,
+      kczlModel: 0,
+      nowTime: '',
+      nowTimer: null,
+      lxTimer: null,
+      dspPic,
+      dckPic,
+      kcyjPic,
+      zlwlPic,
+      abnormalNum: 0,
+      sskcData: [],
+      zlData: [],
+      zxsgData: [],
+      cgjdData: [],
+      hxml1Data: [],
+      kczlData: [],
+      kcjkData: [],
+      pieData: [
+        { value: 335, name: '涤纶布' },
+        { value: 310, name: '弹力布' },
+        { value: 234, name: '针织布' },
+        { value: 135, name: '篷布' }
+      ]
+    }
+  },
+  components: {
+    ChartPie
+  },
+  methods: {
+    toErrorOut () {
+      this.$router.push({
+        name: 'error_out'
+      })
+    },
+    toPaySite () {
+      this.$router.push({
+        name: 'pay_transit'
+      })
+    },
+    // SignalR长连接
+    SRConnection () {
+      console.log('???????????????')
+      console.log(baseUrl)
+      let _this = this
+      this.connection = new signalR.HubConnectionBuilder()
+        .withUrl(`${baseUrl}/plcHub`)
+        .withAutomaticReconnect()
+        .withHubProtocol(new MessagePackHubProtocol())
+        .build()
+      // // 监听扫码
+      // this.connection.on('inStorageDataCheck', res => {
+      //   console.log('入库----------------')
+      //   console.log(res)
+      //   this.connection.invoke('ReturnSureMes', res.MesId)
+      //   this.getList()
+      // })
+      this.connection.start().then(() => {
+        console.log('连接成功--')
+      }).catch(err => {
+        console.log('err--')
+        console.log(err)
+        re_start()
+      })
+      // 监听网络断开
+      this.connection.onclose(() => {
+        this.connection = null
+        console.log('网络已断开!')
+        // this.$Message.error('网络连接断开')
+        // this.$router.go(0)
+      })
+      // 异常重启
+      async function re_start () {
+        try {
+          await _this.connection.start()
+        } catch (err) {
+          setTimeout(() => re_start(), 5000)
+        }
+      }
+    },
+    /* 核心品类切换 */
+    kczlToggle () {
+      this.getStockDetailDelay()
+    },
+    /* 核心品类切换 */
+    hxmlToggle () {
+      this.getCoreMateriaConsume()
+    },
+    /* 获取库存滞留 */
+    getStockDetailDelay () {
+      GetStockDetailDelay({
+        isHiddenSpin: true,
+        showNum: 10,
+        stockDelayType: this.kczlModel
+      }).then(res => {
+        if (res.code === 0) {
+          this.kczlData = res.result
+        }
+      })
+    },
+    /* 获取核心品类 */
+    getCoreMateriaConsume () {
+      GetCoreMateriaConsume({
+        isHiddenSpin: true,
+        showNum: 10,
+        consumeType: this.hxmlModel1
+      }).then(res => {
+        if (res.code === 0) {
+          this.hxml1Data = res.result.consumeItems
+        }
+      })
+    },
+    /* 通用页面跳转 */
+    toHandle (name) {
+      this.$router.push({
+        name
+      })
+    },
+    getList () {
+      GetRealTimeStockOut({
+        isHiddenSpin: true,
+        showNum: 10
+      }).then(res => {
+        if (res.code === 0) {
+          this.sskcData = res.result.stockOutItems
+          this.abnormalNum = res.result.abnormalNum
+        }
+      })
+      GetTotalView({
+        isHiddenSpin: true
+      }).then(res => {
+        if (res.code === 0) {
+          this.zlData = res.result
+        }
+      })
+      GetLatestApplyPurchase({
+        isHiddenSpin: true,
+        showNum: 10
+      }).then(res => {
+        if (res.code === 0) {
+          this.zxsgData = res.result
+        }
+      })
+      GetStockMonitor({
+        isHiddenSpin: true,
+        showNum: 10
+      }).then(res => {
+        if (res.code === 0) {
+          this.kcjkData = res.result
+        }
+      })
+      GetPurchaseProgress({
+        isHiddenSpin: true,
+        showNum: 10
+      }).then(res => {
+        if (res.code === 0) {
+          this.cgjdData = res.result
+        }
+      })
+      this.getCoreMateriaConsume()
+      this.getStockDetailDelay()
+    },
+    getTime () {
+      this.nowTimer = setInterval(() => {
+        this.nowTime = new Date()
+      }, 1000)
+    }
+  },
+  mounted () {
+    this.getList()
+    // this.SRConnection()
+    /* 10秒轮询一次 */
+    this.lxTimer = setInterval(() => {
+      this.getList()
+    }, 5000)
+    this.getTime()
+  },
+  destroyed () {
+    clearInterval(this.nowTimer)
+    clearInterval(this.lxTimer)
+    // this.connection.stop()
+  }
+}
+</script>
+
+<style lang="less" scoped>
+  .container-wrap {
+    height: 100%;
+    min-width: 780px;
+    overflow: auto;
+    .container {
+      height: 100%;
+      display: flex;
+      flex-direction: column;
+      div {
+        flex-shrink: 0;
+        flex-grow: 0;
+      }
+      .card {
+        position: relative;
+        padding: 0 10px;
+        height: 100%;
+        background-color: #2c3034;
+        color: #d7d7d7;
+        border-radius: 4px;
+        .title {
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+          padding: 0 7px;
+          padding-left: 12px;
+          position: relative;
+          height: 41px;
+          line-height: 31px;
+          font-size: 18px;
+          font-weight: bold;
+          border-bottom: 1px solid #444;
+          cursor: pointer;
+          span {
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
+          }
+          &:before {
+            content: '';
+            position: absolute;
+            left: 0;
+            top: 50%;
+            width: 4px;
+            height: 17px;
+            transform: translateY(-50%);
+            background-color: #3F92F9;
+          }
+          .err, .normal {
+            display: flex;
+            align-items: center;
+            font-size: 14px;
+          }
+          .err {
+            color: #ff635f;
+            .idot {
+              background: #ff635f;
+            }
+          }
+          .normal {
+            margin-right: 20px;
+            color: #d7d7d7;
+          }
+          .idot {
+            margin-right: 5px;
+            display: inline-block;
+            width: 7px;
+            height: 7px;
+            border-radius: 50%;
+            background: #FFFFFF;
+          }
+        }
+        .sub-title {
+          text-align: left;
+          font-size: 14px;
+          font-weight: bold;
+          border-bottom: 1px solid #dcdee2;
+        }
+        .content {
+          padding: 5px 0;
+          height: ~"calc(100% - 41px)";
+          overflow: hidden;
+          font-size: 14px;
+          .row-wrap  {
+            height: calc(100% - 24px) ;
+            overflow: auto
+          }
+          .row {
+            margin-bottom: 5px;
+            display: flex;
+            justify-content: space-between;
+            align-items: flex-start;
+            overflow: auto;
+            &:last-child {
+              margin-bottom: 0;
+            }
+            .col-1 {
+              flex: 1;
+            }
+            .col-3 {
+              flex: 3;
+            }
+            .col-5 {
+              flex: 5;
+            }
+            .col-1, .col-3, .col-5 {
+              padding: 0 5px;
+              overflow: hidden;
+              white-space: nowrap;
+              text-overflow: ellipsis;
+            }
+            .th {
+              padding: 0 5px;
+              color: #a5c4ff;
+              font-size: 16px;
+            }
+            .center {
+              display: flex;
+              justify-content: center;
+              align-items: center;
+            }
+            &.err {
+              color: #ec808d;
+            }
+          }
+          .footer-wrap {
+            position: absolute;
+            right: 0;
+            bottom: 0;
+            width: 100%;
+            .footer {
+              display: flex;
+              justify-content: space-around;
+              .item {
+                padding: 5px 0;
+                display: flex;
+                justify-content: space-between;
+                align-items: center;
+                .block {
+                  margin-right: 5px;
+                  width: 12px;
+                  height: 12px;
+                  background-color: #000000;
+                  &.err {
+                    background-color: #ec808d;
+                  }
+                }
+              }
+            }
+          }
+          .over-view {
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            height: 100%;
+            .over-view-item {
+              flex: 1;
+              display: flex;
+              justify-content: center;
+              align-items: center;
+              cursor: pointer;
+              .item-icon {
+                max-width: 51px;
+                width: 30%;
+                img {
+                  width: 100%;
+                }
+              }
+              .item-info {
+                padding: 0 10px;
+                box-sizing: border-box;
+                height: 100%;
+                display: flex;
+                flex-direction: column;
+                justify-content: space-between;
+                font-size: 16px;
+                color: #FFFFFF;
+                p {
+                  line-height: 1;
+                }
+                .item-info-title {
+                  margin-bottom: 5px;
+                  font-size: 18px;
+                  color: #0077ff;
+                }
+                .num {
+                  padding-right: 5px;
+                  font-size: 30px;
+                  font-weight: bold;
+                  line-height: 1;
+                  vertical-align: sub;
+                }
+              }
+            }
+          }
+        }
+      }
+      .top {
+        flex: 6;
+        margin-bottom: 18px;
+        min-height: 400px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        .top-left {
+          flex: 2;
+          margin-right: 18px;
+          height: 100%;
+          min-width: 700px;
+          display: flex;
+          flex-direction: column;
+          justify-content: flex-start;
+          .top-left-top {
+            flex: 2;
+            min-height: 120px;
+            margin-bottom: 18px;
+          }
+          .top-left-bottom {
+            flex-shrink:0;
+            flex: 4;
+            overflow: hidden;
+            margin-bottom: 18px;
+            display: flex;
+            &:last-child {
+              margin-bottom: 0;
+            }
+            .top-left-bottom-left {
+              flex-shrink:0;
+              flex: 1;
+              margin-right: 18px;
+              overflow: hidden;
+            }
+            .top-left-bottom-right {
+              flex-shrink:0;
+              flex: 1;
+              overflow: hidden;
+            }
+          }
+        }
+        .top-right {
+          flex: 1;
+          height: 100%;
+          min-width: 370px;
+        }
+      }
+      .bottom {
+        flex: 2;
+        min-height: 160px;
+        overflow: hidden;
+        .col-1 {
+          height: 100%;
+        }
+        .sub-title {
+          padding: 10px 0;
+          font-size: 16px;
+          border-bottom: none;
+          color: #4072d0;
+        }
+        .content {
+          overflow: auto;
+        }
+      }
+    }
+  }
+  ::-webkit-scrollbar {
+    //width: 0px; /*对垂直流动条有效*/
+    //height: 0px; /*对水平流动条有效*/
+    width: 0; /*对垂直流动条有效*/
+    height: 1px;
+    background-color: #FFFFFF;
+  }
+  /deep/ .ivu-switch-inner {
+    top: 50%;
+    transform: translateY(-50%);
+  }
+  /deep/ .ivu-radio-wrapper-checked {
+    background: #0077ff;
+    border-color: #0077ff;
+    color: #333333;
+  }
+</style>

+ 111 - 0
src/components/board/chart-pie.vue

@@ -0,0 +1,111 @@
+<template>
+  <div ref="dom" class="charts chart-pie"></div>
+</template>
+
+<script>
+import echarts from 'echarts'
+import { on, off } from '@/libs/tools'
+export default {
+  name: 'ChartPie',
+  props: {
+    value: {
+      type: Array,
+      default () {
+        return []
+      }
+    },
+    name: {
+      type: Array,
+      default () {
+        return []
+      }
+    },
+    text: String,
+    subtext: String
+  },
+  computed: {
+    pieData () {
+      let arr = []
+      this.value.forEach((item, index) => {
+        arr.push({
+          name: this.name[index],
+          value: this.value[index]
+        })
+      })
+      // console.log('?????????????????????pie')
+      // console.log(arr)
+      return arr
+    }
+  },
+  watch: {
+    pieData () {
+      this.$nextTick(() => {
+        // let legend = this.value.map(_ => _.name)
+        let option = {
+          title: {
+            text: this.text,
+            subtext: this.subtext,
+            x: 'center'
+          },
+          tooltip: {
+            trigger: 'item',
+            formatter: '{b} : {c} ({d}%)'
+          },
+          // legend: {
+          //   orient: 'vertical',
+          //   left: 'left',
+          //   data: legend
+          // },
+          series: [
+            {
+              type: 'pie',
+              radius: '40%',
+              color: ['#45C2E0', '#C1EBDD', '#FFC851', '#5A5476', '#1869A0', '#FF9393'],
+              center: ['50%', '50%'],
+              data: this.pieData,
+              itemStyle: {
+                emphasis: {
+                  shadowBlur: 10,
+                  shadowOffsetX: 0,
+                  shadowColor: 'rgba(0, 0, 0, 0.5)'
+                },
+                normal: {
+                  label: {
+                    show: true,
+                    formatter: '{b} ({d}%)'
+                  },
+                  labelLine: { show: true }
+                }
+              }
+            }
+          ]
+        }
+        this.dom = echarts.init(this.$refs.dom)
+        this.dom.setOption(option)
+        this.dom.dispatchAction({
+          type: 'highlight',
+          seriesIndex: 0,
+          dataIndex: 0// 默认选中第二个
+        })
+        on(window, 'resize', this.resize)
+      })
+    }
+  },
+  data () {
+    return {
+      dom: null
+    }
+  },
+  methods: {
+    resize () {
+      this.dom.resize()
+    }
+  },
+  mounted () {
+
+  },
+  beforeDestroy () {
+    off(window, 'resize', this.resize)
+  }
+}
+</script>

+ 58 - 0
src/components/charts/bar.vue

@@ -0,0 +1,58 @@
+<template>
+  <div ref="dom" class="charts chart-bar"></div>
+</template>
+
+<script>
+import echarts from 'echarts'
+import tdTheme from './theme.json'
+import { on, off } from '@/libs/tools'
+echarts.registerTheme('tdTheme', tdTheme)
+export default {
+  name: 'ChartBar',
+  props: {
+    value: Object,
+    text: String,
+    subtext: String
+  },
+  data () {
+    return {
+      dom: null
+    }
+  },
+  methods: {
+    resize () {
+      this.dom.resize()
+    }
+  },
+  mounted () {
+    this.$nextTick(() => {
+      let xAxisData = Object.keys(this.value)
+      let seriesData = Object.values(this.value)
+      let option = {
+        title: {
+          text: this.text,
+          subtext: this.subtext,
+          x: 'center'
+        },
+        xAxis: {
+          type: 'category',
+          data: xAxisData
+        },
+        yAxis: {
+          type: 'value'
+        },
+        series: [{
+          data: seriesData,
+          type: 'bar'
+        }]
+      }
+      this.dom = echarts.init(this.$refs.dom, 'tdTheme')
+      this.dom.setOption(option)
+      on(window, 'resize', this.resize)
+    })
+  },
+  beforeDestroy () {
+    off(window, 'resize', this.resize)
+  }
+}
+</script>

+ 3 - 0
src/components/charts/index.js

@@ -0,0 +1,3 @@
+import ChartPie from './pie.vue'
+import ChartBar from './bar.vue'
+export { ChartPie, ChartBar }

+ 70 - 0
src/components/charts/pie.vue

@@ -0,0 +1,70 @@
+<template>
+  <div ref="dom" class="charts chart-pie"></div>
+</template>
+
+<script>
+import echarts from 'echarts'
+import tdTheme from './theme.json'
+import { on, off } from '@/libs/tools'
+echarts.registerTheme('tdTheme', tdTheme)
+export default {
+  name: 'ChartPie',
+  props: {
+    value: Array,
+    text: String,
+    subtext: String
+  },
+  data () {
+    return {
+      dom: null
+    }
+  },
+  methods: {
+    resize () {
+      this.dom.resize()
+    }
+  },
+  mounted () {
+    this.$nextTick(() => {
+      let legend = this.value.map(_ => _.name)
+      let option = {
+        title: {
+          text: this.text,
+          subtext: this.subtext,
+          x: 'center'
+        },
+        tooltip: {
+          trigger: 'item',
+          formatter: '{a} <br/>{b} : {c} ({d}%)'
+        },
+        legend: {
+          orient: 'vertical',
+          left: 'left',
+          data: legend
+        },
+        series: [
+          {
+            type: 'pie',
+            radius: '55%',
+            center: ['50%', '60%'],
+            data: this.value,
+            itemStyle: {
+              emphasis: {
+                shadowBlur: 10,
+                shadowOffsetX: 0,
+                shadowColor: 'rgba(0, 0, 0, 0.5)'
+              }
+            }
+          }
+        ]
+      }
+      this.dom = echarts.init(this.$refs.dom, 'tdTheme')
+      this.dom.setOption(option)
+      on(window, 'resize', this.resize)
+    })
+  },
+  beforeDestroy () {
+    off(window, 'resize', this.resize)
+  }
+}
+</script>

+ 491 - 0
src/components/charts/theme.json

@@ -0,0 +1,491 @@
+
+{
+    "color": [
+        "#2d8cf0",
+        "#19be6b",
+        "#ff9900",
+        "#E46CBB",
+        "#9A66E4",
+        "#ed3f14"
+    ],
+    "backgroundColor": "rgba(0,0,0,0)",
+    "textStyle": {},
+    "title": {
+        "textStyle": {
+            "color": "#516b91"
+        },
+        "subtextStyle": {
+            "color": "#93b7e3"
+        }
+    },
+    "line": {
+        "itemStyle": {
+            "normal": {
+                "borderWidth": "2"
+            }
+        },
+        "lineStyle": {
+            "normal": {
+                "width": "2"
+            }
+        },
+        "symbolSize": "6",
+        "symbol": "emptyCircle",
+        "smooth": true
+    },
+    "radar": {
+        "itemStyle": {
+            "normal": {
+                "borderWidth": "2"
+            }
+        },
+        "lineStyle": {
+            "normal": {
+                "width": "2"
+            }
+        },
+        "symbolSize": "6",
+        "symbol": "emptyCircle",
+        "smooth": true
+    },
+    "bar": {
+        "itemStyle": {
+            "normal": {
+                "barBorderWidth": 0,
+                "barBorderColor": "#ccc"
+            },
+            "emphasis": {
+                "barBorderWidth": 0,
+                "barBorderColor": "#ccc"
+            }
+        }
+    },
+    "pie": {
+        "itemStyle": {
+            "normal": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            },
+            "emphasis": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            }
+        }
+    },
+    "scatter": {
+        "itemStyle": {
+            "normal": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            },
+            "emphasis": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            }
+        }
+    },
+    "boxplot": {
+        "itemStyle": {
+            "normal": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            },
+            "emphasis": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            }
+        }
+    },
+    "parallel": {
+        "itemStyle": {
+            "normal": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            },
+            "emphasis": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            }
+        }
+    },
+    "sankey": {
+        "itemStyle": {
+            "normal": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            },
+            "emphasis": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            }
+        }
+    },
+    "funnel": {
+        "itemStyle": {
+            "normal": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            },
+            "emphasis": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            }
+        }
+    },
+    "gauge": {
+        "itemStyle": {
+            "normal": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            },
+            "emphasis": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            }
+        }
+    },
+    "candlestick": {
+        "itemStyle": {
+            "normal": {
+                "color": "#edafda",
+                "color0": "transparent",
+                "borderColor": "#d680bc",
+                "borderColor0": "#8fd3e8",
+                "borderWidth": "2"
+            }
+        }
+    },
+    "graph": {
+        "itemStyle": {
+            "normal": {
+                "borderWidth": 0,
+                "borderColor": "#ccc"
+            }
+        },
+        "lineStyle": {
+            "normal": {
+                "width": 1,
+                "color": "#aaa"
+            }
+        },
+        "symbolSize": "6",
+        "symbol": "emptyCircle",
+        "smooth": true,
+        "color": [
+            "#2d8cf0",
+            "#19be6b",
+            "#f5ae4a",
+            "#9189d5",
+            "#56cae2",
+            "#cbb0e3"
+        ],
+        "label": {
+            "normal": {
+                "textStyle": {
+                    "color": "#eee"
+                }
+            }
+        }
+    },
+    "map": {
+        "itemStyle": {
+            "normal": {
+                "areaColor": "#f3f3f3",
+                "borderColor": "#516b91",
+                "borderWidth": 0.5
+            },
+            "emphasis": {
+                "areaColor": "rgba(165,231,240,1)",
+                "borderColor": "#516b91",
+                "borderWidth": 1
+            }
+        },
+        "label": {
+            "normal": {
+                "textStyle": {
+                    "color": "#000"
+                }
+            },
+            "emphasis": {
+                "textStyle": {
+                    "color": "rgb(81,107,145)"
+                }
+            }
+        }
+    },
+    "geo": {
+        "itemStyle": {
+            "normal": {
+                "areaColor": "#f3f3f3",
+                "borderColor": "#516b91",
+                "borderWidth": 0.5
+            },
+            "emphasis": {
+                "areaColor": "rgba(165,231,240,1)",
+                "borderColor": "#516b91",
+                "borderWidth": 1
+            }
+        },
+        "label": {
+            "normal": {
+                "textStyle": {
+                    "color": "#000"
+                }
+            },
+            "emphasis": {
+                "textStyle": {
+                    "color": "rgb(81,107,145)"
+                }
+            }
+        }
+    },
+    "categoryAxis": {
+        "axisLine": {
+            "show": true,
+            "lineStyle": {
+                "color": "#cccccc"
+            }
+        },
+        "axisTick": {
+            "show": false,
+            "lineStyle": {
+                "color": "#333"
+            }
+        },
+        "axisLabel": {
+            "show": true,
+            "textStyle": {
+                "color": "#999999"
+            }
+        },
+        "splitLine": {
+            "show": true,
+            "lineStyle": {
+                "color": [
+                    "#eeeeee"
+                ]
+            }
+        },
+        "splitArea": {
+            "show": false,
+            "areaStyle": {
+                "color": [
+                    "rgba(250,250,250,0.05)",
+                    "rgba(200,200,200,0.02)"
+                ]
+            }
+        }
+    },
+    "valueAxis": {
+        "axisLine": {
+            "show": true,
+            "lineStyle": {
+                "color": "#cccccc"
+            }
+        },
+        "axisTick": {
+            "show": false,
+            "lineStyle": {
+                "color": "#333"
+            }
+        },
+        "axisLabel": {
+            "show": true,
+            "textStyle": {
+                "color": "#999999"
+            }
+        },
+        "splitLine": {
+            "show": true,
+            "lineStyle": {
+                "color": [
+                    "#eeeeee"
+                ]
+            }
+        },
+        "splitArea": {
+            "show": false,
+            "areaStyle": {
+                "color": [
+                    "rgba(250,250,250,0.05)",
+                    "rgba(200,200,200,0.02)"
+                ]
+            }
+        }
+    },
+    "logAxis": {
+        "axisLine": {
+            "show": true,
+            "lineStyle": {
+                "color": "#cccccc"
+            }
+        },
+        "axisTick": {
+            "show": false,
+            "lineStyle": {
+                "color": "#333"
+            }
+        },
+        "axisLabel": {
+            "show": true,
+            "textStyle": {
+                "color": "#999999"
+            }
+        },
+        "splitLine": {
+            "show": true,
+            "lineStyle": {
+                "color": [
+                    "#eeeeee"
+                ]
+            }
+        },
+        "splitArea": {
+            "show": false,
+            "areaStyle": {
+                "color": [
+                    "rgba(250,250,250,0.05)",
+                    "rgba(200,200,200,0.02)"
+                ]
+            }
+        }
+    },
+    "timeAxis": {
+        "axisLine": {
+            "show": true,
+            "lineStyle": {
+                "color": "#cccccc"
+            }
+        },
+        "axisTick": {
+            "show": false,
+            "lineStyle": {
+                "color": "#333"
+            }
+        },
+        "axisLabel": {
+            "show": true,
+            "textStyle": {
+                "color": "#999999"
+            }
+        },
+        "splitLine": {
+            "show": true,
+            "lineStyle": {
+                "color": [
+                    "#eeeeee"
+                ]
+            }
+        },
+        "splitArea": {
+            "show": false,
+            "areaStyle": {
+                "color": [
+                    "rgba(250,250,250,0.05)",
+                    "rgba(200,200,200,0.02)"
+                ]
+            }
+        }
+    },
+    "toolbox": {
+        "iconStyle": {
+            "normal": {
+                "borderColor": "#999"
+            },
+            "emphasis": {
+                "borderColor": "#666"
+            }
+        }
+    },
+    "legend": {
+        "textStyle": {
+            "color": "#999999"
+        }
+    },
+    "tooltip": {
+        "axisPointer": {
+            "lineStyle": {
+                "color": "#ccc",
+                "width": 1
+            },
+            "crossStyle": {
+                "color": "#ccc",
+                "width": 1
+            }
+        }
+    },
+    "timeline": {
+        "lineStyle": {
+            "color": "#8fd3e8",
+            "width": 1
+        },
+        "itemStyle": {
+            "normal": {
+                "color": "#8fd3e8",
+                "borderWidth": 1
+            },
+            "emphasis": {
+                "color": "#8fd3e8"
+            }
+        },
+        "controlStyle": {
+            "normal": {
+                "color": "#8fd3e8",
+                "borderColor": "#8fd3e8",
+                "borderWidth": 0.5
+            },
+            "emphasis": {
+                "color": "#8fd3e8",
+                "borderColor": "#8fd3e8",
+                "borderWidth": 0.5
+            }
+        },
+        "checkpointStyle": {
+            "color": "#8fd3e8",
+            "borderColor": "rgba(138,124,168,0.37)"
+        },
+        "label": {
+            "normal": {
+                "textStyle": {
+                    "color": "#8fd3e8"
+                }
+            },
+            "emphasis": {
+                "textStyle": {
+                    "color": "#8fd3e8"
+                }
+            }
+        }
+    },
+    "visualMap": {
+        "color": [
+            "#516b91",
+            "#59c4e6",
+            "#a5e7f0"
+        ]
+    },
+    "dataZoom": {
+        "backgroundColor": "rgba(0,0,0,0)",
+        "dataBackgroundColor": "rgba(255,255,255,0.3)",
+        "fillerColor": "rgba(167,183,204,0.4)",
+        "handleColor": "#a7b7cc",
+        "handleSize": "100%",
+        "textStyle": {
+            "color": "#333"
+        }
+    },
+    "markPoint": {
+        "label": {
+            "normal": {
+                "textStyle": {
+                    "color": "#eee"
+                }
+            },
+            "emphasis": {
+                "textStyle": {
+                    "color": "#eee"
+                }
+            }
+        }
+    }
+}

+ 48 - 0
src/components/common-icon/common-icon.vue

@@ -0,0 +1,48 @@
+<template>
+<!--  <component :is="iconType" :type="iconName" :color="iconColor" :size="iconSize"/>-->
+  <component :is="iconType" :custom="'iconfont ' + iconName" :color="iconColor" :size="iconSize"/>
+</template>
+
+<script>
+import Icons from '_c/icons'
+export default {
+  name: 'CommonIcon',
+  components: { Icons },
+  props: {
+    type: {
+      type: String
+    },
+    color: String,
+    size: Number
+  },
+  watch: {
+    type (value) {
+      console.log('type', value)
+    }
+  },
+  computed: {
+    iconType () {
+      // return this.type.indexOf('_') === 0 ? 'Icons' : 'Icon'
+      return 'Icon'
+    },
+    iconName () {
+      return this.iconType === 'Icons' ? this.getCustomIconName(this.type) : this.type
+    },
+    iconSize () {
+      return this.size || (this.iconType === 'Icons' ? 12 : undefined)
+    },
+    iconColor () {
+      return this.color || ''
+    }
+  },
+  methods: {
+    getCustomIconName (iconName) {
+      return iconName.slice(1)
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>

+ 2 - 0
src/components/common-icon/index.js

@@ -0,0 +1,2 @@
+import CommonIcon from './common-icon.vue'
+export default CommonIcon

+ 8 - 0
src/components/common/common.less

@@ -0,0 +1,8 @@
+.no-select{
+  -webkit-touch-callout: none;
+  -webkit-user-select: none;
+  -khtml-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}

+ 3 - 0
src/components/common/util.js

@@ -0,0 +1,3 @@
+export const showTitle = (item, vm) => {
+  return vm.$config.useI18n ? vm.$t(item.name) : ((item.meta && item.meta.title) || item.name)
+}

+ 174 - 0
src/components/count-to/count-to.vue

@@ -0,0 +1,174 @@
+<template>
+  <div class="count-to-wrapper">
+    <slot name="left"/>
+    <p class="content-outer"><span :class="['count-to-count-text', countClass]" :id="counterId">{{ init }}</span><i :class="['count-to-unit-text', unitClass]">{{ unitText }}</i></p>
+    <slot name="right"/>
+  </div>
+</template>
+
+<script>
+import CountUp from 'countup'
+import './index.less'
+export default {
+  name: 'CountTo',
+  props: {
+    init: {
+      type: Number,
+      default: 0
+    },
+    /**
+     * @description 起始值,即动画开始前显示的数值
+     */
+    startVal: {
+      type: Number,
+      default: 0
+    },
+    /**
+     * @description 结束值,即动画结束后显示的数值
+     */
+    end: {
+      type: Number,
+      required: true
+    },
+    /**
+     * @description 保留几位小数
+     */
+    decimals: {
+      type: Number,
+      default: 0
+    },
+    /**
+     * @description 分隔整数和小数的符号,默认是小数点
+     */
+    decimal: {
+      type: String,
+      default: '.'
+    },
+    /**
+     * @description 动画持续的时间,单位是秒
+     */
+    duration: {
+      type: Number,
+      default: 2
+    },
+    /**
+     * @description 动画延迟开始的时间,单位是秒
+     */
+    delay: {
+      type: Number,
+      default: 0
+    },
+    /**
+     * @description 是否禁用easing动画效果
+     */
+    uneasing: {
+      type: Boolean,
+      default: false
+    },
+    /**
+     * @description 是否使用分组,分组后每三位会用一个符号分隔
+     */
+    usegroup: {
+      type: Boolean,
+      default: false
+    },
+    /**
+     * @description 用于分组(usegroup)的符号
+     */
+    separator: {
+      type: String,
+      default: ','
+    },
+    /**
+     * @description 是否简化显示,设为true后会使用unit单位来做相关省略
+     */
+    simplify: {
+      type: Boolean,
+      default: false
+    },
+    /**
+     * @description 自定义单位,如[3, 'K+'], [6, 'M+']即大于3位数小于6位数的用k+来做省略
+     *              1000即显示为1K+
+     */
+    unit: {
+      type: Array,
+      default () {
+        return [[3, 'K+'], [6, 'M+'], [9, 'B+']]
+      }
+    },
+    countClass: {
+      type: String,
+      default: ''
+    },
+    unitClass: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      counter: null,
+      unitText: ''
+    }
+  },
+  computed: {
+    counterId () {
+      return `count_to_${this._uid}`
+    }
+  },
+  methods: {
+    getHandleVal (val, len) {
+      return {
+        endVal: parseInt(val / Math.pow(10, this.unit[len - 1][0])),
+        unitText: this.unit[len - 1][1]
+      }
+    },
+    transformValue (val) {
+      let len = this.unit.length
+      let res = {
+        endVal: 0,
+        unitText: ''
+      }
+      if (val < Math.pow(10, this.unit[0][0])) res.endVal = val
+      else {
+        for (let i = 1; i < len; i++) {
+          if (val >= Math.pow(10, this.unit[i - 1][0]) && val < Math.pow(10, this.unit[i][0])) res = this.getHandleVal(val, i)
+        }
+      }
+      if (val > Math.pow(10, this.unit[len - 1][0])) res = this.getHandleVal(val, len)
+      return res
+    },
+    getValue (val) {
+      let res = 0
+      if (this.simplify) {
+        let { endVal, unitText } = this.transformValue(val)
+        this.unitText = unitText
+        res = endVal
+      } else {
+        res = val
+      }
+      return res
+    }
+  },
+  mounted () {
+    this.$nextTick(() => {
+      let endVal = this.getValue(this.end)
+      this.counter = new CountUp(this.counterId, this.startVal, endVal, this.decimals, this.duration, {
+        useEasing: !this.uneasing,
+        useGrouping: this.useGroup,
+        separator: this.separator,
+        decimal: this.decimal
+      })
+      setTimeout(() => {
+        if (!this.counter.error) this.counter.start()
+      }, this.delay)
+    })
+  },
+  watch: {
+    end (newVal) {
+      let endVal = this.getValue(newVal)
+      this.counter.update(endVal)
+    }
+  }
+}
+</script>

+ 2 - 0
src/components/count-to/index.js

@@ -0,0 +1,2 @@
+import countTo from './count-to.vue'
+export default countTo

+ 10 - 0
src/components/count-to/index.less

@@ -0,0 +1,10 @@
+@prefix: ~"count-to";
+
+.@{prefix}-wrapper{
+  .content-outer{
+    display: inline-block;
+    .@{prefix}-unit-text{
+      font-style: normal;
+    }
+  }
+}

+ 2 - 0
src/components/cropper/index.js

@@ -0,0 +1,2 @@
+import Cropper from './index.vue'
+export default Cropper

+ 35 - 0
src/components/cropper/index.less

@@ -0,0 +1,35 @@
+.bg{
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")
+}
+.cropper-wrapper{
+  width: 600px;
+  height: 340px;
+  .img-box{
+    height: 340px;
+    width: 430px;
+    border: 1px solid #ebebeb;
+    display: inline-block;
+    .bg;
+    img{
+      max-width: 100%;
+      display: block;
+    }
+  }
+  .right-con{
+    display: inline-block;
+    width: 170px;
+    vertical-align: top;
+    box-sizing: border-box;
+    padding: 0 10px;
+    .preview-box{
+      height: 150px !important;
+      width: 100% !important;
+      overflow: hidden;
+      border: 1px solid #ebebeb;
+      .bg;
+    }
+    .button-box{
+      padding: 10px 0 0;
+    }
+  }
+}

+ 139 - 0
src/components/cropper/index.vue

@@ -0,0 +1,139 @@
+<template>
+  <div class="cropper-wrapper">
+    <div class="img-box">
+      <img class="cropper-image" :id="imgId" alt="">
+    </div>
+    <div class="right-con">
+      <div v-if="preview" class="preview-box" :id="previewId"></div>
+      <div class="button-box">
+        <slot>
+          <Upload action="image/upload" :before-upload="beforeUpload">
+            <Button style="width: 150px;" type="primary">上传图片</Button>
+          </Upload>
+        </slot>
+        <div v-show="insideSrc">
+          <Button type="primary" @click="rotate">
+            <Icon type="md-refresh" :size="18"/>
+          </Button>
+          <Button type="primary" @click="shrink">
+            <Icon type="md-remove" :size="18"/>
+          </Button>
+          <Button type="primary" @click="magnify">
+            <Icon type="md-add" :size="18"/>
+          </Button>
+          <Button type="primary" @click="scale('X')">
+            <Icon custom="iconfont icon-shuipingfanzhuan" :size="18"/>
+          </Button>
+          <Button type="primary" @click="scale('Y')">
+            <Icon custom="iconfont icon-chuizhifanzhuan" :size="18"/>
+          </Button>
+          <Button type="primary" @click="move(0, -moveStep)">
+            <Icon type="md-arrow-round-up" :size="18"/>
+          </Button>
+          <Button type="primary" @click="move(-moveStep, 0)">
+            <Icon type="md-arrow-round-back" :size="18"/>
+          </Button>
+          <Button type="primary" @click="move(0, moveStep)">
+            <Icon type="md-arrow-round-down" :size="18"/>
+          </Button>
+          <Button type="primary" @click="move(moveStep, 0)">
+            <Icon type="md-arrow-round-forward" :size="18"/>
+          </Button>
+          <Button style="width: 150px;margin-top: 10px;" type="primary" @click="crop">{{ cropButtonText }}</Button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import Cropper from 'cropperjs'
+import './index.less'
+import 'cropperjs/dist/cropper.min.css'
+export default {
+  name: 'Cropper',
+  props: {
+    src: {
+      type: String,
+      default: ''
+    },
+    preview: {
+      type: Boolean,
+      default: true
+    },
+    moveStep: {
+      type: Number,
+      default: 4
+    },
+    cropButtonText: {
+      type: String,
+      default: '裁剪'
+    }
+  },
+  data () {
+    return {
+      cropper: null,
+      insideSrc: ''
+    }
+  },
+  computed: {
+    imgId () {
+      return `cropper${this._uid}`
+    },
+    previewId () {
+      return `cropper_preview${this._uid}`
+    }
+  },
+  watch: {
+    src (src) {
+      this.replace(src)
+    },
+    insideSrc (src) {
+      this.replace(src)
+    }
+  },
+  methods: {
+    beforeUpload (file) {
+      const reader = new FileReader()
+      reader.readAsDataURL(file)
+      reader.onload = (event) => {
+        this.insideSrc = event.srcElement.result
+      }
+      return false
+    },
+    replace (src) {
+      this.cropper.replace(src)
+      this.insideSrc = src
+    },
+    rotate () {
+      this.cropper.rotate(90)
+    },
+    shrink () {
+      this.cropper.zoom(-0.1)
+    },
+    magnify () {
+      this.cropper.zoom(0.1)
+    },
+    scale (d) {
+      this.cropper[`scale${d}`](-this.cropper.getData()[`scale${d}`])
+    },
+    move (...argu) {
+      this.cropper.move(...argu)
+    },
+    crop () {
+      this.cropper.getCroppedCanvas().toBlob(blob => {
+        this.$emit('on-crop', blob)
+      })
+    }
+  },
+  mounted () {
+    this.$nextTick(() => {
+      let dom = document.getElementById(this.imgId)
+      this.cropper = new Cropper(dom, {
+        preview: `#${this.previewId}`,
+        checkCrossOrigin: true
+      })
+    })
+  }
+}
+</script>

+ 404 - 0
src/components/dateSelect/dateSelect.vue

@@ -0,0 +1,404 @@
+<template>
+	<div class="date-filter-wrap" style="float: right">
+		<DatePicker
+      v-if="selectMonthStatus"
+			:clearable="false"
+			@on-change="dateClick2"
+			v-model="dataArea2"
+			type="month"
+			placement="bottom-end"
+			placeholder="请选择月份"
+			style="width: 200px; margin-right: 10px"
+			:style="
+				dataArea2 ? 'border:1px solid #3f92f9;border-radius:5px' : ''
+			"
+		>
+		</DatePicker>
+		<div class="date-filter">
+			<div
+				class="date-tab"
+				v-for="(item, index) in dateTabs"
+				:key="index"
+				:class="index === dateTabIndex ? 'active' : ''"
+				@click="dateTabToggle(index)"
+			>
+				{{ item.label }}
+			</div>
+			<Poptip placement="bottom">
+				<div
+					class="date-tab"
+					:class="dateTabIndex === 5 ? 'active' : ''"
+					style="width: 50px"
+				>
+					其他
+				</div>
+				<div slot="content">
+					<div
+						class="select-time-box"
+						v-for="i in modalTimeList"
+						@click="modalTimeSelect(i.type)"
+						:key="i.type"
+					>
+						{{ i.name }}
+					</div>
+				</div>
+			</Poptip>
+		</div>
+		<DatePicker
+			:style="
+				selectType == 3
+					? 'border:1px solid #3f92f9;border-radius:5px'
+					: ''
+			"
+			:clearable="false"
+			@on-change="dateClick"
+			v-model="dataArea"
+			type="daterange"
+			placement="bottom-end"
+			placeholder="请选择日期"
+			style="width: 200px; margin-left: 10px"
+		>
+		</DatePicker>
+	</div>
+</template>
+<script>
+export default {
+	name: 'test',
+	props: {
+		value: {
+			type: Object,
+		},
+    selectMonthStatus: {
+      type: Boolean,
+      default: true
+    }
+	},
+	watch: {
+		value: {
+			handler() {
+				this.$emit('input', this.value)
+			},
+			deep: true,
+			immediate: true,
+		},
+	},
+	data() {
+		return {
+			selectType: 0,
+			modalTimeList: [
+				{
+					name: '昨日',
+					type: 1,
+				},
+				{
+					name: '前日',
+					type: 2,
+				},
+				{
+					name: '上周',
+					type: 3,
+				},
+				{
+					name: '上月',
+					type: 4,
+				},
+				{
+					name: '近三个月',
+					type: 5,
+				},
+				{
+					name: '近半年',
+					type: 6,
+				},
+			],
+			modalTimeType: null,
+			dateTabIndex: 3,
+			dateTabs: [
+				{ label: '本日' },
+				{ label: '本周' },
+				{ label: '本月' },
+				{ label: '今年' },
+			],
+			dataArea2: null,
+			dataArea: [],
+			time: [],
+		}
+	},
+	methods: {
+		/* 选项卡切换 */
+		dateTabToggle(index) {
+			this.value.type = index + 1
+			this.selectType = 0
+			this.dateTabIndex = index
+			this.dataArea2 = null
+			if (index === 0) {
+				let time = new Date().getTime()
+				this.value.beginTime = this.$dayjs(time).format(
+					'YYYY-MM-DD HH:mm:ss'
+				)
+				this.value.endTime = this.$dayjs(time).format(
+					'YYYY-MM-DD HH:mm:ss'
+				)
+				this.dataArea = [this.value.beginTime, this.value.endTime]
+			} else if (index === 1) {
+				let Nowdate = new Date()
+				let WeekFirstDay = Nowdate.getDay()
+					? new Date(Nowdate - (Nowdate.getDay() - 1) * 86400000)
+					: new Date(Nowdate - (Nowdate.getDay() + 6) * 86400000)
+				let WeekLastDay = new Date(
+					(WeekFirstDay / 1000 + 6 * 86400) * 1000
+				)
+				this.value.beginTime = this.$dayjs(WeekFirstDay).format(
+					'YYYY-MM-DD HH:mm:ss'
+				)
+				this.value.endTime = this.$dayjs(WeekLastDay).format(
+					'YYYY-MM-DD HH:mm:ss'
+				)
+				this.dataArea = [this.value.beginTime, this.value.endTime]
+			} else if (index === 2) {
+				let now = new Date() // 当前日期
+				let nowMonth = now.getMonth() // 当前月
+				let nowYear = now.getFullYear() // 当前年
+				// 本月的开始时间
+				let monthStartDate = new Date(nowYear, nowMonth, 1)
+				// 本月的结束时间
+				let monthEndDate = new Date(nowYear, nowMonth + 1, 0)
+				this.value.beginTime = this.$dayjs(monthStartDate).format(
+					'YYYY-MM-DD HH:mm:ss'
+				)
+				this.value.endTime = this.$dayjs(monthEndDate).format(
+					'YYYY-MM-DD HH:mm:ss'
+				)
+				this.dataArea = [this.value.beginTime, this.value.endTime]
+			} else if (index === 3) {
+				let now = new Date() // 当前日期
+				let nowYear = now.getFullYear() // 当前年
+				// 本年的开始时间
+				let monthStartDate = new Date(nowYear, 0, 1)
+				// 本年的结束时间
+				let monthEndDate = new Date(nowYear, 11, 31)
+				this.value.beginTime = this.$dayjs(monthStartDate).format(
+					'YYYY-MM-DD HH:mm:ss'
+				)
+				this.value.endTime = this.$dayjs(now).format(
+					'YYYY-MM-DD HH:mm:ss'
+				)
+				this.dataArea = [this.value.beginTime, this.value.endTime]
+			}
+			this.$emit('change')
+		},
+		//外部选择时间
+		changeTypeFn(_type) {
+			this.value.type = _type
+			this.value.beginTime = null
+			this.value.endTime = null
+			this.time = []
+			this.$emit('change')
+		},
+		modalTimeSelect(_type) {
+			console.log(_type)
+			this.selectType = 0
+			const format = (timeStamp) => {
+				var date = new Date()
+				date.setTime(timeStamp * 1)
+				var y = date.getFullYear()
+				var m = date.getMonth() + 1
+				m = m < 10 ? '0' + m : m
+				var d = date.getDate()
+				d = d < 10 ? '0' + d : d
+				var h = date.getHours()
+				h = h < 10 ? '0' + h : h
+				var minute = date.getMinutes()
+				var second = date.getSeconds()
+				minute = minute < 10 ? '0' + minute : minute
+				second = second < 10 ? '0' + second : second
+				return y + '-' + m + '-' + d
+			}
+			const v = this
+			const todayNum = new Date(new Date().toLocaleDateString()).getTime()
+			const today = new Date()
+			//年
+			var year = today.getFullYear()
+			//月
+			const month = today.getMonth() + 1
+			//周
+			const nows = today.getDay() || 7
+			//天
+			const day = today.getDate()
+			if (_type == 1) {
+				v.value.beginTime = format(todayNum - 86400000)
+				v.value.endTime = format(todayNum - 86400000)
+			}
+			if (_type == 2) {
+				v.value.beginTime = format(todayNum - 86400000 * 2)
+				v.value.endTime = format(todayNum - 86400000 * 2)
+			}
+			if (_type == 3) {
+				v.value.beginTime = format(todayNum - 86400000 * (nows + 6))
+				v.value.endTime = format(todayNum - 86400000 * nows)
+			}
+			if (_type == 4) {
+				if (month == 1) {
+					v.value.beginTime = year - 1 + '-' + 12 + '-' + '1 00:00:00'
+					v.value.endTime = year + '-' + 1 + '-' + '1 00:00:00'
+				} else {
+					v.value.beginTime =
+						year + '-' + (month - 1) + '-' + '1 00:00:00'
+					v.value.endTime = year + '-' + month + '-' + '1 00:00:00'
+				}
+			}
+			if (_type == 5) {
+				if (month < 4) {
+					v.value.beginTime =
+						year -
+						1 +
+						'-' +
+						(12 - 3 + month) +
+						'-' +
+						day +
+						' 00:00:00'
+					v.value.endTime = format(today.getTime())
+				} else {
+					v.value.beginTime =
+						year + '-' + (month - 3) + '-' + day + ' 00:00:00'
+					v.value.endTime = format(today.getTime())
+				}
+			}
+			if (_type == 6) {
+				if (month < 7) {
+					v.value.beginTime =
+						year -
+						1 +
+						'-' +
+						(12 - 6 + month) +
+						'-' +
+						day +
+						' 00:00:00'
+					v.value.endTime = format(today.getTime())
+				} else {
+					v.value.beginTime =
+						year + '-' + (month - 6) + '-' + day + ' 00:00:00'
+					v.value.endTime = format(today.getTime())
+				}
+			}
+			v.dataArea = [v.value.beginTime, v.value.endTime]
+			v.dateTabIndex = 5
+			v.value.type = 5
+			this.$emit('change')
+		},
+		dateClick2(date) {
+			const dateDayNum = new Date(date).getDate()
+			const dateMonthNum = new Date(date).getMonth() + 1
+			const dateYearNum = new Date(date).getFullYear()
+			this.dateTabIndex = null
+			this.value.beginTime = dateYearNum + '-' + dateMonthNum + '-1'
+			this.value.endTime =
+				dateYearNum +
+				'-' +
+				dateMonthNum +
+				'-' +
+				new Date(dateYearNum, dateMonthNum * 1, 0).getDate()
+			this.dataArea = []
+			this.selectType = 0
+			this.value.type = 99
+			this.$emit('change')
+		},
+		dateClick(date) {
+			this.value.beginTime = date[0]
+			this.value.endTime = date[1]
+			this.dateTabIndex = null
+			this.dataArea2 = null
+			this.selectType = 3
+			this.value.type = 99
+			this.$emit('change')
+		},
+	},
+	created() {
+		let now = new Date() // 当前日期
+		let nowYear = now.getFullYear() // 当前年
+		// 本年的开始时间
+		let monthStartDate = new Date(nowYear, 0, 1)
+		// 本年的结束时间
+		let monthEndDate = new Date(nowYear, 11, 31)
+		this.value.beginTime = this.$dayjs(monthStartDate).format(
+			'YYYY-MM-DD HH:mm:ss'
+		)
+		this.value.endTime = this.$dayjs(now).format(
+			'YYYY-MM-DD HH:mm:ss'
+		)
+		this.dataArea = [this.value.beginTime, this.value.endTime]
+	},
+}
+</script>
+<style scoped lang="less">
+.select-time-box {
+	height: 30px;
+	line-height: 30px;
+	text-align: center;
+	cursor: pointer;
+}
+.select-time-box:hover,
+.select-time-box.active {
+	background: #3f92f9;
+	color: #fff;
+}
+.date-filter-wrap {
+	display: flex;
+	align-items: center;
+	overflow: hidden;
+	.date-filter {
+		width: 300px;
+		overflow: hidden;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		background-color: #ffffff;
+		border-radius: 4px;
+		&.other {
+			width: auto;
+			.date-tab {
+				white-space: nowrap;
+				padding: 9px;
+				.num {
+					font-weight: bold;
+					font-size: 14px;
+					&.red {
+						color: red;
+						cursor: pointer;
+						text-decoration: underline;
+					}
+				}
+				&.active {
+					background-color: #333333;
+				}
+			}
+		}
+
+		.date-tab {
+			flex: 1;
+			padding: 9px 4px;
+			line-height: 1;
+			text-align: center;
+			border: 1px solid #e6e6e6;
+			border-radius: 2px;
+			border-right: none;
+			cursor: pointer;
+			font-weight: 500;
+
+			&:first-child {
+				border-radius: 4px 0 0 4px;
+			}
+
+			&:last-child {
+				border-radius: 0 4px 4px 0;
+				border-right: 1px solid #e6e6e6;
+			}
+
+			&.active {
+				background-color: #3f92f9;
+				color: #ffffff;
+			}
+		}
+	}
+}
+</style>

+ 18 - 0
src/components/drag-drawer/drag-drawer-trigger.vue

@@ -0,0 +1,18 @@
+<template>
+  <div :class="`${prefix}-move-trigger`">
+    <div :class="`${prefix}-move-trigger-point`">
+      <i></i><i></i><i></i><i></i><i></i>
+    </div>
+  </div>
+</template>
+
+<script>
+import Mixin from './mixin'
+export default {
+  name: 'DragDrawerTrigger',
+  mixins: [Mixin]
+}
+</script>
+
+<style>
+</style>

+ 156 - 0
src/components/drag-drawer/drag-drawer.vue

@@ -0,0 +1,156 @@
+<template>
+  <Drawer ref="drawerWrapper"
+          :value="value"
+          @input="handleInput"
+          :width="width"
+          :class-name="outerClasses"
+          v-bind="$attrs"
+          v-on="$listeners">
+    <!-- 所有插槽内容显示在这里 ↓ -->
+
+    <template v-for="(slots, slotsName) in $slots">
+      <template v-if="slotsName !== 'default'">
+        <render-dom v-for="(render, index) in slots"
+                    :key="`b_drawer_${slotsName}_${index}`"
+                    :render="() => render"
+                    :slot="slotsName">
+        </render-dom>
+      </template>
+      <template v-else>
+        <div :class="`${prefix}-body-wrapper`"
+             :key="`b_drawer_${slotsName}`">
+          <render-dom v-for="(render, index) in slots"
+                      :key="`b_drawer_${slotsName}_${index}`"
+                      :render="() => render"
+                      :slot="slotsName">
+          </render-dom>
+        </div>
+      </template>
+    </template>
+    <!-- 所有插槽内容显示在这里 ↑ -->
+    <div v-if="draggable"
+         :style="triggerStyle"
+         :class="`${prefix}-trigger-wrapper`"
+         @mousedown="handleTriggerMousedown">
+      <slot name="trigger">
+        <drag-drawer-trigger></drag-drawer-trigger>
+      </slot>
+    </div>
+    <div v-if="$slots.footer"
+         :class="`${prefix}-footer`">
+      <slot name="footer"></slot>
+    </div>
+  </Drawer>
+</template>
+
+<script>
+import RenderDom from '@/libs/render-dom'
+import DragDrawerTrigger from './drag-drawer-trigger.vue'
+import Mixin from './mixin'
+import { on, off } from '@/libs/tools'
+import './index.less'
+export default {
+  name: 'BDrawer',
+  components: {
+    RenderDom,
+    DragDrawerTrigger
+  },
+  mixins: [Mixin],
+  props: {
+    value: {
+      type: Boolean,
+      default: false
+    },
+    width: {
+      type: [String, Number],
+      default: 256
+    },
+    // 是否可拖动修改宽度
+    draggable: {
+      type: Boolean,
+      default: false
+    },
+    // 最小拖动宽度
+    minWidth: {
+      type: [String, Number],
+      default: 256
+    }
+  },
+  data () {
+    return {
+      canMove: false,
+      wrapperWidth: 0,
+      wrapperLeft: 0
+    }
+  },
+  computed: {
+    outerClasses () {
+      const classesArray = [
+        `${this.prefix}-wrapper`,
+        this.canMove ? 'no-select pointer-events-none' : ''
+      ]
+      return classesArray.join(' ')
+    },
+    placement () {
+      return this.$attrs.placement
+    },
+    innerWidth () {
+      const width = this.width
+      return width <= 100 ? (this.wrapperWidth * width) / 100 : width
+    },
+    triggerStyle () {
+      return {
+        [this.placement]: `${this.innerWidth}px`,
+        position: this.$attrs.inner ? 'absolute' : 'fixed'
+      }
+    }
+  },
+  methods: {
+    handleInput (status) {
+      this.$emit('input', status)
+    },
+    handleTriggerMousedown (event) {
+      this.canMove = true
+      this.$emit('on-resize-start')
+      // 防止鼠标选中抽屉中文字,造成拖动trigger触发浏览器原生拖动行为
+      window.getSelection().removeAllRanges()
+    },
+    handleMousemove (event) {
+      if (!this.canMove) return
+      // 更新容器宽度和距离左侧页面距离,如果是window则距左侧距离为0
+      this.setWrapperWidth()
+      const left = event.pageX - this.wrapperLeft
+      // 如果抽屉方向为右边,宽度计算需用容器宽度减去left
+      let width = this.placement === 'right' ? this.wrapperWidth - left : left
+      // 限定做小宽度
+      width = Math.max(width, parseFloat(this.minWidth))
+      event.atMin = width === parseFloat(this.minWidth)
+      // 如果当前width不大于100,视为百分比
+      if (width <= 100) width = (width / this.wrapperWidth) * 100
+      this.$emit('update:width', parseInt(width))
+      this.$emit('on-resize', event)
+    },
+    handleMouseup (event) {
+      this.canMove = false
+      this.$emit('on-resize-end')
+    },
+    setWrapperWidth () {
+      const {
+        width,
+        left
+      } = this.$refs.drawerWrapper.$el.getBoundingClientRect()
+      this.wrapperWidth = width
+      this.wrapperLeft = left
+    }
+  },
+  mounted () {
+    on(document, 'mousemove', this.handleMousemove)
+    on(document, 'mouseup', this.handleMouseup)
+    this.setWrapperWidth()
+  },
+  beforeDestroy () {
+    off(document, 'mousemove', this.handleMousemove)
+    off(document, 'mouseup', this.handleMouseup)
+  }
+}
+</script>

+ 2 - 0
src/components/drag-drawer/index.js

@@ -0,0 +1,2 @@
+import DragDrawer from './drag-drawer.vue'
+export default DragDrawer

+ 70 - 0
src/components/drag-drawer/index.less

@@ -0,0 +1,70 @@
+@prefix: ~"drag-drawer";
+@drag-drawer-trigger-height: 100px;
+@drag-drawer-trigger-width: 8px;
+
+.@{prefix}-wrapper{
+  &.no-select{
+    user-select: none;
+  }
+  &.pointer-events-none{
+    pointer-events: none;
+    & .@{prefix}-trigger-wrapper{
+      pointer-events: all;
+    }
+  }
+  .ivu-drawer{
+    &-header{
+      overflow: hidden !important;
+      box-sizing: border-box;
+    }
+    &-body{
+      padding: 0;
+      overflow: visible;
+      position: static;
+      display: flex;
+      flex-direction: column;
+    }
+  }
+  .@{prefix}-body-wrapper{
+    width: 100%;
+    height: 100%;
+    padding: 16px;
+    overflow: auto;
+  }
+  .@{prefix}-trigger-wrapper{
+    top: 0;
+    height: 100%;
+    width: 0;
+    .@{prefix}-move-trigger{
+      position: absolute;
+      top: 50%;
+      height: @drag-drawer-trigger-height;
+      width: @drag-drawer-trigger-width;
+      background: rgb(243, 243, 243);
+      transform: translate(-50%, -50%);
+      border-radius: ~"4px / 6px";
+      box-shadow: 0 0 1px 1px rgba(0, 0, 0, .2);
+      line-height: @drag-drawer-trigger-height;
+      cursor: col-resize;
+      &-point{
+        display: inline-block;
+        width: 50%;
+        transform: translateX(50%);
+        i{
+          display: block;
+          border-bottom: 1px solid rgb(192, 192, 192);
+          padding-bottom: 2px;
+        }
+      }
+    }
+  }
+  .@{prefix}-footer{
+    flex-grow: 1;
+    width: 100%;
+    bottom: 0;
+    left: 0;
+    border-top: 1px solid #e8e8e8;
+    padding: 10px 16px;
+    background: #fff;
+  }
+}

+ 7 - 0
src/components/drag-drawer/mixin.js

@@ -0,0 +1,7 @@
+export default {
+  data () {
+    return {
+      prefix: 'drag-drawer'
+    }
+  }
+}

+ 92 - 0
src/components/drag-list/drag-list.vue

@@ -0,0 +1,92 @@
+<template>
+  <div class="drag-list-wrapper">
+    <div class="drag-list-con con1">
+      <slot name="left-title"></slot>
+      <draggable class="drop-box1" :class="dropConClass.left" :options="options" :value="list1" @input="handleListChange($event, 'left')" @end="handleEnd($event, 'left')">
+        <div class="drag-list-item" v-for="(itemLeft, index) in list1" :key="`drag_li1_${index}`">
+          <slot name="left" :itemLeft="itemLeft">{{ itemLeft }}</slot>
+        </div>
+      </draggable>
+    </div>
+    <div class="drag-list-con con2">
+      <slot name="right-title"></slot>
+      <draggable class="drop-box2" :class="dropConClass.right" :options="options" :value="list2" @input="handleListChange($event, 'right')" @end="handleEnd($event, 'right')">
+        <div class="drag-list-item" v-for="(itemRight, index) in list2" :key="`drag_li2_${index}`">
+          <slot name="right" :itemRight="itemRight">{{ itemRight }}</slot>
+        </div>
+      </draggable>
+    </div>
+  </div>
+</template>
+<script>
+import draggable from 'vuedraggable'
+export default {
+  name: 'DragList',
+  components: {
+    draggable
+  },
+  props: {
+    list1: {
+      type: Array,
+      required: true
+    },
+    list2: {
+      type: Array,
+      default: () => []
+    },
+    dropConClass: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  data () {
+    return {
+      options: { group: 'drag_list' }
+    }
+  },
+  methods: {
+    handleListChange (value, type) {
+      if (type === 'left') this.$emit('update:list1', value)
+      else this.$emit('update:list2', value)
+    },
+    handleEnd (event, type) {
+      const srcClassName = (event.srcElement || event.target).classList[0]
+      const targetClassName = event.to.classList[0]
+      let src = ''
+      let target = ''
+      if (srcClassName === targetClassName) {
+        if (type === 'left') {
+          src = 'left'
+          target = 'left'
+        } else {
+          src = 'right'
+          target = 'right'
+        }
+      } else {
+        if (type === 'left') {
+          src = 'left'
+          target = 'right'
+        } else {
+          src = 'right'
+          target = 'left'
+        }
+      }
+      this.$emit('on-change', {
+        src: src,
+        target: target,
+        oldIndex: event.oldIndex,
+        newIndex: event.newIndex
+      })
+    }
+  }
+}
+</script>
+<style lang="less">
+.drag-list-wrapper{
+  height: 100%;
+  .drag-list-con{
+    width: 50%;
+    float: left;
+  }
+}
+</style>

+ 2 - 0
src/components/drag-list/index.js

@@ -0,0 +1,2 @@
+import DragList from './drag-list.vue'
+export default DragList

+ 75 - 0
src/components/editor/editor.vue

@@ -0,0 +1,75 @@
+<template>
+  <div class="editor-wrapper">
+    <div :id="editorId"></div>
+  </div>
+</template>
+
+<script>
+import Editor from 'wangeditor'
+import 'wangeditor/release/wangEditor.min.css'
+import { oneOf } from '@/libs/tools'
+export default {
+  name: 'Editor',
+  props: {
+    value: {
+      type: String,
+      default: ''
+    },
+    /**
+     * 绑定的值的类型, enum: ['html', 'text']
+     */
+    valueType: {
+      type: String,
+      default: 'html',
+      validator: (val) => {
+        return oneOf(val, ['html', 'text'])
+      }
+    },
+    /**
+     * @description 设置change事件触发时间间隔
+     */
+    changeInterval: {
+      type: Number,
+      default: 200
+    },
+    /**
+     * @description 是否开启本地存储
+     */
+    cache: {
+      type: Boolean,
+      default: true
+    }
+  },
+  computed: {
+    editorId () {
+      return `editor${this._uid}`
+    }
+  },
+  methods: {
+    setHtml (val) {
+      this.editor.txt.html(val)
+    }
+  },
+  mounted () {
+    this.editor = new Editor(`#${this.editorId}`)
+    this.editor.customConfig.onchange = (html) => {
+      let text = this.editor.txt.text()
+      if (this.cache) localStorage.editorCache = html
+      this.$emit('input', this.valueType === 'html' ? html : text)
+      this.$emit('on-change', html, text)
+    }
+    this.editor.customConfig.onchangeTimeout = this.changeInterval
+    // create这个方法一定要在所有配置项之后调用
+    this.editor.create()
+    // 如果本地有存储加载本地存储内容
+    let html = this.value || localStorage.editorCache
+    if (html) this.editor.txt.html(html)
+  }
+}
+</script>
+
+<style lang="less">
+.editor-wrapper *{
+  z-index: 100 !important;
+}
+</style>

+ 2 - 0
src/components/editor/index.js

@@ -0,0 +1,2 @@
+import Editor from './editor.vue'
+export default Editor

+ 178 - 0
src/components/form/select-input.vue

@@ -0,0 +1,178 @@
+<template>
+	<div class="select-input">
+		<!-- 用途 -->
+		<div class="purpose" v-if="type == 1">
+			<Select
+				v-model="purposeIndex"
+				style="width: 200px"
+				@on-change="selectPurposeFn"
+				filterable
+			>
+				<div slot="empty">无匹配数据</div>
+				<Option :value="999">全部</Option>
+				<Option
+					v-for="(i, index) in selectPurposeList"
+					:value="index"
+					:key="index"
+					>{{ i.purpose }}</Option
+				>
+			</Select>
+		</div>
+		<!-- 供应商 -->
+		<div v-if="type == 2">
+			<Poptip trigger="focus" width="250" placement="bottom">
+				<div slot="content">
+					<ul style="" class="commons-select-search">
+						<li
+							:key="i.id"
+							v-for="i in supplierList"
+							@click="supplierListCk(i)"
+						>
+							{{ i.name }}
+						</li>
+					</ul>
+				</div>
+				<Input
+					v-model="inputValue"
+					@on-change="getSupplierSelectList"
+					placeholder="请输入用途关键词"
+				></Input>
+			</Poptip>
+		</div>
+        <!-- 物料 -->
+		<div v-if="type == 3">
+			<Poptip trigger="focus" width="250" placement="bottom">
+				<div slot="content">
+					<ul style="" class="commons-select-search">
+						<li
+							:key="i.id"
+							v-for="i in materialList"
+							@click="materialListCk(i)"
+						>
+							{{ i.name }}
+						</li>
+					</ul>
+				</div>
+				<Input
+					v-model="inputValue"
+					@on-change="getMaterialSelectList"
+					placeholder="请输入物料名称"
+				></Input>
+			</Poptip>
+		</div>
+	</div>
+</template>
+
+<script>
+import axios from 'axios'
+export default {
+	props: {
+		//1 用途 2 物料 3供应商
+		type: String,
+		value: {
+			type: String,
+			default: '',
+			require: true,
+		},
+	},
+	name: '',
+	watch: {
+		value: {
+			handler() {
+				this.$emit('input', this.value)
+			},
+			immediate: true,
+		},
+	},
+	data() {
+		return {
+			purposeIndex: null,
+			selectPurposeList: [],
+			inputValue: this.value,
+			supplierList: [],
+            materialList: [],
+		}
+	},
+	methods: {
+        getMaterialSelectList() {
+			const v = this
+			v.loading = true
+			axios
+				.post('/cloudApi/material/selectList', {
+					pageNum:1,
+					pageSize:10,
+					search:this.inputValue,
+				})
+				.then((res) => {
+					v.materialList = res.data.data
+					v.loading = false
+				})
+			
+		},
+		getSupplierSelectList(req) {
+			const v = this
+			v.loading = true
+			axios
+				.post('/cloudApi/supplier/selectList', {
+					search: this.inputValue,
+				})
+				.then((res) => {
+					v.supplierList = res.data.data
+					v.loading = false
+					console.log(v.supplierList)
+				})
+		},
+        materialListCk(i){
+            console.log(i)
+			this.inputValue = i.name
+			this.$emit('input', i.name)
+        },
+		supplierListCk(i) {
+			console.log(i)
+			this.inputValue = i.name
+			this.$emit('input', i.name)
+		},
+		selectPurposeFn(e) {
+			console.log(e)
+			if (e == 999) {
+				this.inputValue = ''
+				this.$emit('input', '')
+			} else {
+				this.inputValue = this.selectPurposeList[e].purpose
+				this.$emit('input', this.selectPurposeList[e].purpose)
+			}
+		},
+		getMaterialSelectPurposeList() {
+			const v = this
+			v.loading = true
+			axios
+				.get('/cloudApi/material/selectPurposeList?purpose=' + '', {})
+				.then((res) => {
+					v.selectPurposeList = res.data.data
+					v.loading = false
+				})
+		},
+	},
+	created() {
+		const v = this
+		if (v.type == undefined) {
+			console.log('请配置type //1 用途 2 物料 3供应商')
+			return
+		}
+		switch (v.type) {
+			case '1':
+				v.getMaterialSelectPurposeList()
+				break
+			case '2':
+				v.getSupplierSelectList()
+            case '3':
+				v.getMaterialSelectList()
+			default:
+				break
+		}
+	},
+}
+</script>
+
+<style lang="less" scoped>
+</style>

+ 35 - 0
src/components/icons/icons.vue

@@ -0,0 +1,35 @@
+<template>
+  <i :class="`iconfont icon-${type}`" :style="styles"></i>
+</template>
+
+<script>
+export default {
+  name: 'Icons',
+  props: {
+    type: {
+      type: String,
+      required: true
+    },
+    color: {
+      type: String,
+      default: '#5c6b77'
+    },
+    size: {
+      type: Number,
+      default: 16
+    }
+  },
+  computed: {
+    styles () {
+      return {
+        fontSize: `${this.size}px`,
+        color: this.color
+      }
+    }
+  }
+}
+</script>
+
+<style>
+
+</style>

+ 2 - 0
src/components/icons/index.js

@@ -0,0 +1,2 @@
+import Icons from './icons.vue'
+export default Icons

+ 2 - 0
src/components/login-form/index.js

@@ -0,0 +1,2 @@
+import LoginForm from './login-form.vue'
+export default LoginForm

+ 85 - 0
src/components/login-form/login-form.vue

@@ -0,0 +1,85 @@
+<template>
+  <Form ref="loginForm" :model="form" :rules="rules" @keydown.enter.native="handleSubmit">
+    <FormItem prop="userName">
+      <Input size="large"  v-model="form.userName" placeholder="请输入账号" prefix="ios-contact-outline"></Input>
+    </FormItem>
+    <FormItem prop="password">
+      <Input size="large" type="password" v-model="form.password" placeholder="请输入密码" prefix="ios-lock-outline"></Input>
+    </FormItem>
+    <FormItem>
+      <Checkbox v-model="remember">记住用户名</Checkbox>
+    </FormItem>
+    <FormItem>
+      <Button size="large" @click="handleSubmit" type="primary" long>登录</Button>
+    </FormItem>
+  </Form>
+</template>
+<script>
+import axios from 'axios'
+export default {
+  name: 'LoginForm',
+  props: {
+    userNameRules: {
+      type: Array,
+      default: () => {
+        return [
+          { required: true, message: '账号不能为空', trigger: 'blur' }
+        ]
+      }
+    },
+    passwordRules: {
+      type: Array,
+      default: () => {
+        return [
+          { required: true, message: '密码不能为空', trigger: 'blur' }
+        ]
+      }
+    }
+  },
+  data () {
+    return {
+      remember: true,
+      form: {
+        userName: '',
+        password: ''
+      }
+    }
+  },
+  computed: {
+    rules () {
+      return {
+        userName: this.userNameRules,
+        password: this.passwordRules
+      }
+    }
+  },
+  methods: {
+    handleSubmit () {
+      if(this.form.password == '123456'){
+        this.$Message.info({
+          content:'密码错误',
+          duration:3,
+        });
+        return
+      }
+      this.$refs.loginForm.validate((valid) => {
+        if (valid) {
+          if (this.remember) {
+            sessionStorage.setItem('userName', this.form.userName)
+          } else {
+            sessionStorage.setItem('userName', '')
+          }
+          this.$emit('on-success-valid', {
+            userName: this.form.userName,
+            password: this.form.password
+          })
+        }
+      })
+    }
+  },
+  mounted () {
+    let userName = sessionStorage.getItem('userName')
+    userName && (this.form.userName = userName)
+  }
+}
+</script>

+ 2 - 0
src/components/main/components/a-back-top/index.js

@@ -0,0 +1,2 @@
+import ABackTop from './index.vue'
+export default ABackTop

+ 90 - 0
src/components/main/components/a-back-top/index.vue

@@ -0,0 +1,90 @@
+<template>
+    <div :class="classes" :style="styles" @click="back">
+        <slot>
+            <div :class="innerClasses">
+                <i class="ivu-icon ivu-icon-ios-arrow-up"></i>
+            </div>
+        </slot>
+    </div>
+</template>
+<script>
+import { scrollTop } from '@/libs/util'
+import { on, off } from '@/libs/tools'
+const prefixCls = 'ivu-back-top'
+
+export default {
+  name: 'ABackTop',
+  props: {
+    height: {
+      type: Number,
+      default: 400
+    },
+    bottom: {
+      type: Number,
+      default: 30
+    },
+    right: {
+      type: Number,
+      default: 30
+    },
+    duration: {
+      type: Number,
+      default: 1000
+    },
+    container: {
+      type: null,
+      default: window
+    }
+  },
+  data () {
+    return {
+      backTop: false
+    }
+  },
+  mounted () {
+    // window.addEventListener('scroll', this.handleScroll, false)
+    // window.addEventListener('resize', this.handleScroll, false)
+    on(this.containerEle, 'scroll', this.handleScroll)
+    on(this.containerEle, 'resize', this.handleScroll)
+  },
+  beforeDestroy () {
+    // window.removeEventListener('scroll', this.handleScroll, false)
+    // window.removeEventListener('resize', this.handleScroll, false)
+    off(this.containerEle, 'scroll', this.handleScroll)
+    off(this.containerEle, 'resize', this.handleScroll)
+  },
+  computed: {
+    classes () {
+      return [
+        `${prefixCls}`,
+        {
+          [`${prefixCls}-show`]: this.backTop
+        }
+      ]
+    },
+    styles () {
+      return {
+        bottom: `${this.bottom}px`,
+        right: `${this.right}px`
+      }
+    },
+    innerClasses () {
+      return `${prefixCls}-inner`
+    },
+    containerEle () {
+      return this.container === window ? window : document.querySelector(this.container)
+    }
+  },
+  methods: {
+    handleScroll () {
+      this.backTop = this.containerEle.scrollTop >= this.height
+    },
+    back () {
+      let target = typeof this.container === 'string' ? this.containerEle : (document.documentElement || document.body)
+      const sTop = target.scrollTop
+      scrollTop(this.containerEle, sTop, 0, this.duration)
+      this.$emit('on-click')
+    }
+  }
+}
+</script>

+ 49 - 0
src/components/main/components/error-store/error-store.vue

@@ -0,0 +1,49 @@
+<template>
+  <div class="error-store">
+    <Badge dot :count="countComputed">
+      <Button type="text" @click="openErrorLoggerPage">
+        <Icon :size="20" type="ios-bug"/>
+      </Button>
+    </Badge>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'ErrorStore',
+  props: {
+    count: {
+      type: Number,
+      default: 0
+    },
+    hasRead: {
+      type: Boolean,
+      default: false
+    }
+  },
+  computed: {
+    countComputed () {
+      return this.hasRead ? 0 : this.count
+    }
+  },
+  methods: {
+    openErrorLoggerPage () {
+      this.$router.push({
+        name: 'error_logger_page'
+      })
+    }
+  }
+}
+</script>
+
+<style lang="less">
+.error-store{
+  margin-right: 12px;
+  .ivu-badge-dot{
+    top: 20px;
+  }
+  .ivu-btn.ivu-btn-text{
+    padding: 5px 1px 6px;
+  }
+}
+</style>

+ 2 - 0
src/components/main/components/error-store/index.js

@@ -0,0 +1,2 @@
+import ErrorStore from './error-store.vue'
+export default ErrorStore

+ 84 - 0
src/components/main/components/fullscreen/fullscreen.vue

@@ -0,0 +1,84 @@
+<template>
+  <div v-if="showFullScreenBtn" class="full-screen-btn-con">
+    <Tooltip :content="value ? '退出全屏' : '全屏'" placement="bottom">
+      <Icon @click.native="handleChange" :type="value ? 'md-contract' : 'md-expand'" :size="23"></Icon>
+    </Tooltip>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'Fullscreen',
+  computed: {
+    showFullScreenBtn () {
+      return window.navigator.userAgent.indexOf('MSIE') < 0
+    }
+  },
+  props: {
+    value: {
+      type: Boolean,
+      default: false
+    }
+  },
+  methods: {
+    handleFullscreen () {
+      let main = document.body
+      if (this.value) {
+        if (document.exitFullscreen) {
+          document.exitFullscreen()
+        } else if (document.mozCancelFullScreen) {
+          document.mozCancelFullScreen()
+        } else if (document.webkitCancelFullScreen) {
+          document.webkitCancelFullScreen()
+        } else if (document.msExitFullscreen) {
+          document.msExitFullscreen()
+        }
+      } else {
+        if (main.requestFullscreen) {
+          main.requestFullscreen()
+        } else if (main.mozRequestFullScreen) {
+          main.mozRequestFullScreen()
+        } else if (main.webkitRequestFullScreen) {
+          main.webkitRequestFullScreen()
+        } else if (main.msRequestFullscreen) {
+          main.msRequestFullscreen()
+        }
+      }
+    },
+    handleChange () {
+      this.handleFullscreen()
+    }
+  },
+  mounted () {
+    let isFullscreen = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen
+    isFullscreen = !!isFullscreen
+    document.addEventListener('fullscreenchange', () => {
+      this.$emit('input', !this.value)
+      this.$emit('on-change', !this.value)
+    })
+    document.addEventListener('mozfullscreenchange', () => {
+      this.$emit('input', !this.value)
+      this.$emit('on-change', !this.value)
+    })
+    document.addEventListener('webkitfullscreenchange', () => {
+      this.$emit('input', !this.value)
+      this.$emit('on-change', !this.value)
+    })
+    document.addEventListener('msfullscreenchange', () => {
+      this.$emit('input', !this.value)
+      this.$emit('on-change', !this.value)
+    })
+    this.$emit('input', isFullscreen)
+  }
+}
+</script>
+
+<style lang="less">
+.full-screen-btn-con .ivu-tooltip-rel{
+  height: 64px;
+  line-height: 56px;
+  i{
+    cursor: pointer;
+  }
+}
+</style>

+ 2 - 0
src/components/main/components/fullscreen/index.js

@@ -0,0 +1,2 @@
+import Fullscreen from './fullscreen.vue'
+export default Fullscreen

+ 4 - 0
src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.less

@@ -0,0 +1,4 @@
+.custom-bread-crumb{
+  display: inline-block;
+  vertical-align: top;
+}

+ 46 - 0
src/components/main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue

@@ -0,0 +1,46 @@
+<template>
+  <div class="custom-bread-crumb">
+    <Breadcrumb :style="{fontSize: `${fontSize}px`}">
+      <BreadcrumbItem v-for="item in list" :to="item.to" :key="`bread-crumb-${item.name}`">
+        <common-icon style="margin-right: 4px;" :type="item.icon || ''"/>
+        {{ showTitle(item) }}
+      </BreadcrumbItem>
+    </Breadcrumb>
+  </div>
+</template>
+<script>
+import { showTitle } from '@/libs/util'
+import CommonIcon from '_c/common-icon'
+import './custom-bread-crumb.less'
+export default {
+  name: 'customBreadCrumb',
+  components: {
+    CommonIcon
+  },
+  props: {
+    list: {
+      type: Array,
+      default: () => []
+    },
+    fontSize: {
+      type: Number,
+      default: 14
+    },
+    showIcon: {
+      type: Boolean,
+      default: false
+    }
+  },
+  methods: {
+    showTitle (item) {
+      return showTitle(item, this)
+    },
+    isCustomIcon (iconName) {
+      return iconName.indexOf('_') === 0
+    },
+    getCustomIconName (iconName) {
+      return iconName.slice(1)
+    }
+  }
+}
+</script>

+ 2 - 0
src/components/main/components/header-bar/custom-bread-crumb/index.js

@@ -0,0 +1,2 @@
+import customBreadCrumb from './custom-bread-crumb.vue'
+export default customBreadCrumb

+ 16 - 0
src/components/main/components/header-bar/header-bar.less

@@ -0,0 +1,16 @@
+.header-bar{
+  width: 100%;
+  height: 100%;
+  position: relative;
+  background-color: #1a2026;
+  color: #ffffff;
+  .custom-content-con{
+    float: right;
+    height: auto;
+    padding-right: 20px;
+    line-height: 64px;
+    & > *{
+      float: right;
+    }
+  }
+}

+ 558 - 0
src/components/main/components/header-bar/header-bar.vue

@@ -0,0 +1,558 @@
+<template>
+  <div class="header-bar">
+<!--    <sider-trigger :collapsed="collapsed" icon="md-menu" @on-change="handleCollpasedChange"></sider-trigger>-->
+<!--    <custom-bread-crumb show-icon style="margin-left: 30px;" :list="breadCrumbList"></custom-bread-crumb>-->
+    <div class="content">
+      <div class="left">
+        <div class="logo-title">
+          <img src="../../../../assets/images/log-new-login.png" alt="">
+          <span class="text">智能仓储系统</span>
+        </div>
+        <div class="item">
+          <span class="title">Hi,{{ name }}</span>
+          <span class="sub-title">欢迎登录!</span>
+        </div>
+      </div>
+      <div class="center" ref="text-wrap">
+        <span ref="text" class="nav-title">实现订单的需求与面料/配件供应的动态匹配</span>
+      </div>
+      <div class="right">
+<!--        <div class="item search">-->
+<!--          <Input prefix="ios-search" placeholder="search" clearable />-->
+<!--        </div>-->
+        <div class="item info">
+          <Poptip v-model="tipVisible" placement="bottom">
+            <img :src="avatarPic" alt="">
+            <span class="sub-title">{{ name }}</span>
+            <Icon type="md-arrow-dropdown" color="#0077ff" />
+            <div class="tip-content" slot="content">
+              <div class="tip-top">
+                <div class="tip-top-left">
+                  <img :src="avatarPic" alt="">
+                </div>
+                <div class="tip-top-right">
+                  <div class="sub-title">{{ name }}</div>
+                  <div class="tip-top-text">{{ accessName }}</div>
+                  <div class="tip-top-text">工号:{{ jobNo }}</div>
+                </div>
+              </div>
+<!--              <div class="tip-center">-->
+<!--                <div class="tip-center-wrap">-->
+<!--                  <div class="row">-->
+<!--                    <span>本次登陆时长</span>-->
+<!--                    <span>总在线时长</span>-->
+<!--                  </div>-->
+<!--                  <div class="row">-->
+<!--                    <span>00.00.00</span>-->
+<!--                    <span>00.00.00</span>-->
+<!--                  </div>-->
+<!--                </div>-->
+<!--              </div>-->
+              <!-- <div @click="changePwd" class="tip-bottom border">
+                <span style="color: rgb(8, 123, 225);">修改密码</span>
+                <my-modal-form v-model="changePwdShow" title="修改密码" :config="formConfig" :rule-validate="ruleValidate" @confirm="changePwdCfm"></my-modal-form>
+              </div> -->
+              <div @click="logout" class="tip-bottom">
+                <span>退出</span>
+              </div>
+            </div>
+          </Poptip>
+        </div>
+        <div class="item" @click="toHandle" v-if="$store.state.user.access !== 'supplier'">
+          <span style="color: #0077ff;cursor: pointer">待审批</span>
+        </div>
+        <div class="item" @click="toMsg">
+          <div class="msg-icon">
+            <Icon type="md-notifications-outline" size="20" />
+            <div class="idot" v-if="msgLength">{{ msgLength }}</div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="custom-content-con">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+<script>
+import * as signalR from '@microsoft/signalr'
+import { MessagePackHubProtocol } from '@microsoft/signalr-protocol-msgpack'
+import config from '@/config'
+import MyModalForm from '_c/my-modal-form/my-modal-form'
+import logoTitlePic from '@/assets/images/login-icon.png'
+import avatarPic from '@/assets/images/avatar.png'
+import { GetMessageRemindPage, ReadMessageRemind } from '@/api/storageHome'
+import { ChangePassword } from '@/api/user'
+import { mapActions } from 'vuex'
+import siderTrigger from './sider-trigger'
+import customBreadCrumb from './custom-bread-crumb'
+import './header-bar.less'
+export default {
+  name: 'HeaderBar',
+  components: {
+    siderTrigger,
+    customBreadCrumb,
+    MyModalForm
+  },
+  props: {
+    collapsed: Boolean
+  },
+  data () {
+    return {
+      baseUrl: process.env.NODE_ENV === 'development' ? config.baseUrl.dev : config.baseUrl.pro,
+      avatarPic,
+      logoTitlePic,
+      tipVisible: false,
+      changePwdShow: false,
+      timer: null,
+      titleTimer: null,
+      title: '',
+      msgList: [],
+      msgLength: 0,
+      name: this.$store.state.user.name,
+      accessName: this.$store.state.user.accessName,
+      jobNo: this.$store.state.user.jobNo,
+      formConfig: [
+        {
+          type: 'input',
+          comType: 'password',
+          label: '新密码',
+          key: 'newPassword',
+          placeholder: '请输入新密码'
+        },
+        {
+          type: 'input',
+          comType: 'password',
+          label: '确认密码',
+          key: 'cfmPassword',
+          placeholder: '请输入确认密码'
+        }
+      ],
+      ruleValidate: {
+        newPassword: [
+          { required: true, message: '密码不能为空', trigger: 'blur' }
+        ],
+        cfmPassword: [
+          { required: true, message: '确认密码不能为空', trigger: 'blur' }
+        ]
+      }
+    }
+  },
+  computed: {
+    msgChange () {
+      return this.$store.state.app.msgChange
+    },
+    breadCrumbList () {
+      return this.$store.state.app.breadCrumbList
+    }
+  },
+  watch: {
+    msgChange () {
+      this.readMessageRemind()
+    }
+  },
+  methods: {
+    ...mapActions([
+      'handleLogOut'
+    ]),
+    handleCollpasedChange (state) {
+      this.$emit('on-coll-change', state)
+    },
+    changePwd () {
+      this.tipVisible = false
+      this.changePwdShow = true
+    },
+    changePwdCfm (type, data) {
+      ChangePassword(data).then(res => {
+        if (res.code === 0) {
+          this.$Message.info('修改成功,请重新登录!')
+          this.changePwdShow = false
+          setTimeout(() => {
+            this.handleLogOut().then(() => {
+              this.$router.push({
+                name: 'login'
+              })
+            })
+          }, 1000)
+        }
+      })
+    },
+    logout () {
+      this.$MyModal.show({
+        type: 'exit',
+        text: '确认退出吗?'
+      }).$on('confirm', () => {
+        this.handleLogOut().then(() => {
+          this.$router.push({
+            name: 'login'
+          })
+        })
+      })
+    },
+    /* 弹出消息提示 */
+    notice (msg) {
+      this.$Notice.warning({
+        title: '消息通知',
+        name: msg.id,
+        duration: 0,
+        render: h => {
+          let _this = this
+          return h('div', [
+            h('div', { style: { paddingBottom: '20px', lineHeight: '1.5' } }, msg.content),
+            h('div', {
+              style: { textAlign: 'right' }
+            }, [
+              h('span', {
+                style: {
+                  color: 'blue',
+                  cursor: 'pointer',
+                  textDecoration: 'underline',
+                  marginRight: '10px'
+                },
+                on: {
+                  click () {
+                    _this.$Notice.destroy()
+                    _this.toMsg()
+                  }
+                }
+              }, '所有未读'),
+              h('span', {
+                style: {
+                  color: 'blue',
+                  cursor: 'pointer',
+                  textDecoration: 'underline'
+                },
+                on: {
+                  click () {
+                    ReadMessageRemind({
+                      id: msg.id
+                    }).then(res => {
+                      if (res.code === 0) {
+                        _this.readMessageRemind()
+                        _this.$Notice.close(msg.id)
+                      }
+                    })
+                  }
+                }
+              }, '已阅')
+            ])
+          ])
+        }
+      })
+    },
+    /* 首次加载显示消息徽章 弹出消息提示 */
+    alertMsg () {
+      GetMessageRemindPage({
+        pageIndex: 1,
+        pageSize: 1,
+        readState: 0
+      }).then(res => {
+        if (res.code === 0) {
+          this.msgLength = res.result.totalCount < 100 ? res.result.totalCount : 99
+          this.msgList = res.result.list[0]
+          if (this.msgList) {
+            this.notice(this.msgList)
+            this.title = this.msgList.content
+            this.blinkMsg()
+          } else {
+            clearInterval(this.timer)
+          }
+        }
+      })
+    },
+    /* 修改当前消息条数 */
+    readMessageRemind () {
+      GetMessageRemindPage({
+        pageIndex: 1,
+        pageSize: 1,
+        readState: 0
+      }).then(res => {
+        if (res.code === 0) {
+          this.msgLength = res.result.totalCount < 100 ? res.result.totalCount : 99
+          this.msgList = res.result.list[0]
+          if (this.msgList) {
+            this.title = this.msgList.content
+            this.blinkMsg()
+          } else {
+            clearInterval(this.timer)
+          }
+        }
+      })
+    },
+    /* 设置消息闪烁 */
+    blinkMsg (content) {
+      clearInterval(this.timer)
+      this.timer = setInterval(() => {
+        // 截取首字符串(第一个)
+        var head = this.title.substring(0, 1)
+        // 截取除首字符串外所有字符串(除第一个所有)
+        var foot = this.title.substring(1)
+        // 头尾拼接后赋给data => tit属性
+        this.title = foot + head
+        // 最后赋给最终显示的标题(标题)
+        document.title = this.title
+      }, 300)
+    },
+    /* 跳转消息列表 */
+    toMsg () {
+      this.$router.push({
+        name: 'msg'
+      })
+    },
+    /* 跳转待审批 */
+    toHandle () {
+      this.$router.push({
+        name: 'schedule'
+      })
+    },
+    /* 中间固定文字滚动 */
+    textAnimate () {
+      let textWrapEl = this.$refs['text-wrap']
+      let textEl = this.$refs['text']
+      let position = 0
+      if (textWrapEl.offsetWidth < textEl.offsetWidth) {
+        position = textWrapEl.offsetWidth - textEl.offsetWidth
+        textEl.style.left = position + 'px'
+      }
+      this.titleTimer = setInterval(() => {
+        if (position === (textWrapEl.offsetWidth - textEl.offsetWidth)) {
+          position = 0
+          textEl.style.left = position + 'px'
+        } else if (textWrapEl.offsetWidth < textEl.offsetWidth) {
+          position = textWrapEl.offsetWidth - textEl.offsetWidth
+          textEl.style.left = position + 'px'
+        }
+      }, 3000)
+    },
+    SRConnection () {
+      let _this = this
+      this.connection = new signalR.HubConnectionBuilder()
+        .withUrl(`${this.baseUrl}/plcHub?groupName=pcGroup`)
+        .withAutomaticReconnect()
+        .withHubProtocol(new MessagePackHubProtocol())
+        .build()
+      // 获取扫描rfid
+      this.connection.on('bindRfid', res => {
+        console.log('获取rfid通知')
+        console.log(res)
+        this.connection.invoke('ReturnSureMes', res.MesId)
+        this.$emit('sr-handle', 'rfid', res.Data)
+      })
+      this.connection.start().then(() => {
+        console.log('连接成功--')
+      }).catch(err => {
+        console.log('err--')
+        console.log(err)
+        re_start()
+      })
+      // 监听网络断开
+      this.connection.onclose(() => {
+        this.connection = null
+        console.log('网络已断开!')
+        // this.$Message.error('网络连接断开')
+        // this.$router.go(0)
+      })
+      // 异常重启
+      async function re_start () {
+        try {
+          await _this.connection.start()
+        } catch (err) {
+          setTimeout(() => re_start(), 5000)
+        }
+      }
+    }
+  },
+  mounted () {
+    // this.SRConnection()
+    this.alertMsg()
+    this.$nextTick(() => {
+      this.textAnimate()
+    })
+  },
+  destroyed () {
+    clearInterval(this.timer)
+    clearInterval(this.titleTimer)
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.content {
+  font-size: 16px;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  height: 100%;
+  min-width: 1000px;
+
+  .left, .right {
+    display: flex;
+    align-items: center;
+    height: 100%;
+    .info {
+      margin-right: 83px !important;
+      .sub-title {
+        font-size: 14px;
+      }
+    }
+    .item {
+      margin-right: 30px;
+      &:last-child {
+        margin-right: 0;
+      }
+      .sub-title {
+        padding: 0 15px;
+        color: #0077ff;
+      }
+    }
+  }
+  .center {
+    position: relative;
+    margin: 0 10px;
+    flex: 1;
+    overflow: hidden;
+    color: #FFFF80;
+    .nav-title {
+      position: relative;
+      white-space: nowrap;
+      transition: all 3s;
+      left: 0;
+    }
+  }
+  .left {
+    .logo-title {
+      margin-right: 54px;
+      height: 100%;
+      display: flex;
+      align-items: center;
+      img {
+        width: 113px
+      }
+      .text {
+        margin-left: 13px;
+        font-size: 28px;
+        font-style: italic;
+        letter-spacing: 2px;
+      }
+    }
+  }
+  .right {
+    .item {
+      display: flex;
+      align-items: center;
+      margin-right: 20px;
+      cursor: pointer;
+      .idot {
+        position: absolute;
+        right: 0;
+        top: 0;
+        display: inline-block;
+        background-color: red;
+        width: 16px;
+        height: 16px;
+        line-height: 16px;
+        border-radius: 50%;
+        text-align: center;
+        font-size: 12px;
+      }
+      .msg-icon {
+        position: relative;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 40px;
+        height: 40px;
+        border-radius: 50%;
+        background-color: #3a4045;
+      }
+    }
+  }
+}
+/deep/ .search {
+  margin-right: 52px !important;
+  .ivu-input {
+    border: none;
+    background: #21262b;
+    border-radius: 16px;
+    color: #d7d7d7;
+  }
+}
+/deep/ .ivu-poptip-rel {
+  display: flex;
+  align-items: center;
+}
+/deep/ .ivu-poptip-popper{
+  padding: 0 !important;
+  top: 79px !important;
+  .ivu-poptip-arrow {
+    display: none;
+  }
+
+  .ivu-poptip-body {
+    padding: 0;
+    .ivu-poptip-body-content {
+      overflow: hidden;
+    }
+    .tip-content {
+      width: 252px;
+      box-sizing: border-box;
+      background-color: #3a4045;
+      border-radius: 0px 0px 4px 4px;
+      border: solid 1px #565c61;
+      .tip-top {
+        height: 93px;
+        box-sizing: border-box;
+        display: flex;
+        .tip-top-left {
+          padding: 20px 15px;
+          img {
+            width: 40px;
+            height: 40px;
+          }
+        }
+        .tip-top-right {
+          .sub-title {
+            padding: 20px 0 10px 0;
+          }
+          .tip-top-text {
+            padding-bottom: 10px;
+            line-height: 1;
+            font-size: 12px;
+          }
+        }
+      }
+      .tip-center {
+        height: 61px;
+        box-sizing: border-box;
+        border-top: solid 1px #565c61;
+        border-bottom: solid 1px #565c61;
+        display: flex;
+        align-items: center;
+        .tip-center-wrap {
+          flex: 1;
+        }
+        .row {
+          display: flex;
+          justify-content: space-around;
+          span {
+            font-size: 12px;
+          }
+        }
+      }
+      .tip-bottom {
+        height: 41px;
+        line-height: 41px;
+        text-align: center;
+        box-sizing: border-box;
+        span {
+          font-size: 12px;
+        }
+        &.border {
+          border-top: solid 1px #565c61;
+          border-bottom: solid 1px #565c61;
+        }
+      }
+    }
+  }
+}
+</style>

+ 2 - 0
src/components/main/components/header-bar/index.js

@@ -0,0 +1,2 @@
+import HeaderBar from './header-bar'
+export default HeaderBar

Some files were not shown because too many files changed in this diff