SJ před 3 dny
rodič
revize
8495943b4e

+ 167 - 166
package.json

@@ -1,166 +1,167 @@
-{
-  "name": "vue-antd-jeecg",
-  "version": "3.4.3",
-  "private": true,
-  "scripts": {
-    "pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ",
-    "serve": "vue-cli-service serve",
-    "build:test": "vue-cli-service build --mode test",
-    "build": "vue-cli-service build --report",
-    "lint": "vue-cli-service lint"
-  },
-  "dependencies": {
-    "@antv/data-set": "^0.11.4",
-    "@babel/parser": "^7.7.4",
-    "@dcloudio/uni-webview-js": "^0.0.3",
-    "@riophae/vue-treeselect": "0.4.0",
-    "@tinymce/tinymce-vue": "2.1.0",
-    "@toast-ui/editor": "^2.1.2",
-    "@types/qrcode": "^1.5.1",
-    "@vue-office/pdf": "^2.0.10",
-    "@vue/composition-api": "^1.7.2",
-    "ant-design-vue": "^1.7.2",
-    "area-data": "^5.0.6",
-    "axios": "^0.18.0",
-    "babel-plugin-import": "^1.13.0",
-    "beautifier": "^0.1.7",
-    "china-area-data": "^5.0.1",
-    "clipboard": "^2.0.4",
-    "codemirror": "^5.46.0",
-    "core-js": "3.8.1",
-    "cron-parser": "^2.10.0",
-    "crypto-js": "^4.1.1",
-    "dayjs": "^1.8.0",
-    "diagram-js-minimap": "^2.0.4",
-    "dom-align": "1.12.0",
-    "element-ui": "2.15.6",
-    "enquire.js": "^2.1.6",
-    "file-saver": "2.0.4",
-    "form-gen-parser": "^1.0.3",
-    "highlight.js": "^10.5.0",
-    "jquery": "^3.6.0",
-    "js-cookie": "^2.2.0",
-    "js-pinyin": "^0.1.9",
-    "lodash.get": "^4.4.2",
-    "lodash.pick": "^4.4.0",
-    "mathjs": "^9.5.1",
-    "md5": "^2.2.1",
-    "min-dash": "^3.5.2",
-    "nprogress": "^0.2.0",
-    "print-js": "^1.6.0",
-    "qiankun": "^2.5.1",
-    "qrcode": "^1.5.3",
-    "quill": "^1.3.7",
-    "sass": "1.32.0",
-    "sass-loader": "10.1.0",
-    "tinymce": "5.4.1",
-    "v-click-outside-x": "^4.1.3",
-    "view-design": "^4.2.0",
-    "view-ui-plus": "^1.3.1",
-    "viser-vue": "^2.4.8",
-    "voca": "^1.4.0",
-    "vue": "2.6.10",
-    "vue-area-linkage": "^5.1.0",
-    "vue-baidu-map": "^0.21.22",
-    "vue-barcode": "^1.3.0",
-    "vue-codemirror": "^4.0.6",
-    "vue-cropper": "^0.5.4",
-    "vue-demi": "^0.14.6",
-    "vue-i18n": "^8.7.0",
-    "vue-loader": "^15.7.0",
-    "vue-ls": "^3.2.0",
-    "vue-photo-preview": "^1.1.3",
-    "vue-print-nb-jeecg": "^1.0.10",
-    "vue-qr": "^4.0.9",
-    "vue-quill-editor": "^3.0.6",
-    "vue-router": "^3.0.1",
-    "vue-splitpane": "^1.0.4",
-    "vuedraggable": "^2.20.0",
-    "vuex": "^3.1.0",
-    "vuex-persistedstate": "^4.1.0",
-    "vxe-table": "2.9.13",
-    "vxe-table-plugin-antd": "1.8.10",
-    "weixin-js-sdk": "^1.6.0",
-    "workflow-bpmn-modeler-jeecgboot": "^0.1.3",
-    "x2js": "^3.4.2",
-    "xe-utils": "2.4.8",
-    "xml-js": "^1.6.11",
-    "xss": "^1.0.13"
-  },
-  "devDependencies": {
-    "@babel/polyfill": "^7.2.5",
-    "@vue/cli-plugin-babel": "^4.5.0",
-    "@vue/cli-plugin-eslint": "^4.5.0",
-    "@vue/cli-service": "^4.5.0",
-    "@vue/compiler-sfc": "^3.0.1",
-    "@vue/eslint-config-prettier": "^5.0.0",
-    "@vue/eslint-config-standard": "^4.0.0",
-    "@jeecg/antd-online-mini": "3.4.3-beta2",
-    "babel-eslint": "^10.1.0",
-    "camunda-bpmn-moddle": "^4.4.1",
-    "compression-webpack-plugin": "^3.1.0",
-    "eslint": "^6.7.2",
-    "eslint-plugin-prettier": "^3.1.0",
-    "eslint-plugin-vue": "^6.2.2",
-    "fs-extra": "^8.1.0",
-    "html-webpack-plugin": "^4.2.0",
-    "less": "^3.9.0",
-    "less-loader": "^4.1.0",
-    "sass-loader": "^10.1.0",
-    "vue-template-compiler": "2.6.10"
-  },
-  "eslintConfig": {
-    "root": true,
-    "env": {
-      "node": true
-    },
-    "extends": [
-      "plugin:vue/strongly-recommended",
-      "@vue/standard"
-    ],
-    "parserOptions": {
-      "parser": "babel-eslint"
-    },
-    "rules": {
-      "generator-star-spacing": "off",
-      "no-mixed-operators": 0,
-      "vue/max-attributes-per-line": [
-        2,
-        {
-          "singleline": 5,
-          "multiline": {
-            "max": 1,
-            "allowFirstLine": false
-          }
-        }
-      ],
-      "vue/attribute-hyphenation": 0,
-      "vue/html-self-closing": 0,
-      "vue/component-name-in-template-casing": 0,
-      "vue/html-closing-bracket-spacing": 0,
-      "vue/singleline-html-element-content-newline": 0,
-      "vue/no-unused-components": 0,
-      "vue/multiline-html-element-content-newline": 0,
-      "vue/no-use-v-if-with-v-for": 0,
-      "vue/html-closing-bracket-newline": 0,
-      "vue/no-parsing-error": 0,
-      "no-tabs": 0,
-      "indent": [
-        "off",
-        2
-      ],
-      "no-console": 0,
-      "space-before-function-paren": 0
-    }
-  },
-  "postcss": {
-    "plugins": {
-      "autoprefixer": {}
-    }
-  },
-  "browserslist": [
-    "> 1%",
-    "last 2 versions",
-    "not ie <= 10"
-  ]
-}
+{
+  "name": "vue-antd-jeecg",
+  "version": "3.4.3",
+  "private": true,
+  "scripts": {
+    "pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ",
+    "serve": "vue-cli-service serve",
+    "build:test": "vue-cli-service build --mode test",
+    "build": "vue-cli-service build --report",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "@antv/data-set": "^0.11.4",
+    "@babel/parser": "^7.7.4",
+    "@dcloudio/uni-webview-js": "^0.0.3",
+    "@riophae/vue-treeselect": "0.4.0",
+    "@tinymce/tinymce-vue": "2.1.0",
+    "@toast-ui/editor": "^2.1.2",
+    "@types/qrcode": "^1.5.1",
+    "@vue-office/pdf": "^2.0.10",
+    "@vue/composition-api": "^1.7.2",
+    "ant-design-vue": "^1.7.2",
+    "area-data": "^5.0.6",
+    "axios": "^0.18.0",
+    "babel-plugin-import": "^1.13.0",
+    "beautifier": "^0.1.7",
+    "china-area-data": "^5.0.1",
+    "clipboard": "^2.0.4",
+    "codemirror": "^5.46.0",
+    "core-js": "3.8.1",
+    "cron-parser": "^2.10.0",
+    "crypto-js": "^4.1.1",
+    "dayjs": "^1.8.0",
+    "diagram-js-minimap": "^2.0.4",
+    "dom-align": "1.12.0",
+    "element-ui": "2.15.6",
+    "enquire.js": "^2.1.6",
+    "file-saver": "2.0.4",
+    "form-gen-parser": "^1.0.3",
+    "highlight.js": "^10.5.0",
+    "jquery": "^3.6.0",
+    "js-cookie": "^2.2.0",
+    "js-pinyin": "^0.1.9",
+    "lodash.get": "^4.4.2",
+    "lodash.pick": "^4.4.0",
+    "mathjs": "^9.5.1",
+    "md5": "^2.2.1",
+    "min-dash": "^3.5.2",
+    "nprogress": "^0.2.0",
+    "print-js": "^1.6.0",
+    "qiankun": "^2.5.1",
+    "qrcode": "^1.5.3",
+    "quill": "^1.3.7",
+    "sass": "1.32.0",
+    "sass-loader": "10.1.0",
+    "tinymce": "5.4.1",
+    "v-click-outside-x": "^4.1.3",
+    "view-design": "^4.2.0",
+    "view-ui-plus": "^1.3.1",
+    "viser-vue": "^2.4.8",
+    "voca": "^1.4.0",
+    "vue": "2.6.10",
+    "vue-area-linkage": "^5.1.0",
+    "vue-baidu-map": "^0.21.22",
+    "vue-barcode": "^1.3.0",
+    "vue-codemirror": "^4.0.6",
+    "vue-cropper": "^0.5.4",
+    "vue-demi": "^0.14.6",
+    "vue-i18n": "^8.7.0",
+    "vue-loader": "^15.7.0",
+    "vue-ls": "^3.2.0",
+    "vue-photo-preview": "^1.1.3",
+    "vue-print-nb-jeecg": "^1.0.10",
+    "vue-qr": "^4.0.9",
+    "vue-quill-editor": "^3.0.6",
+    "vue-router": "^3.0.1",
+    "vue-splitpane": "^1.0.4",
+    "vuedraggable": "^2.20.0",
+    "vuex": "^3.1.0",
+    "vuex-persistedstate": "^4.1.0",
+    "vxe-table": "2.9.13",
+    "vxe-table-plugin-antd": "1.8.10",
+    "weixin-js-sdk": "^1.6.0",
+    "workflow-bpmn-modeler-jeecgboot": "^0.1.3",
+    "x2js": "^3.4.2",
+    "xe-utils": "2.4.8",
+    "xml-js": "^1.6.11",
+    "xss": "^1.0.13",
+    "echarts": "^5.4.3"
+  },
+  "devDependencies": {
+    "@babel/polyfill": "^7.2.5",
+    "@vue/cli-plugin-babel": "^4.5.0",
+    "@vue/cli-plugin-eslint": "^4.5.0",
+    "@vue/cli-service": "^4.5.0",
+    "@vue/compiler-sfc": "^3.0.1",
+    "@vue/eslint-config-prettier": "^5.0.0",
+    "@vue/eslint-config-standard": "^4.0.0",
+    "@jeecg/antd-online-mini": "3.4.3-beta2",
+    "babel-eslint": "^10.1.0",
+    "camunda-bpmn-moddle": "^4.4.1",
+    "compression-webpack-plugin": "^3.1.0",
+    "eslint": "^6.7.2",
+    "eslint-plugin-prettier": "^3.1.0",
+    "eslint-plugin-vue": "^6.2.2",
+    "fs-extra": "^8.1.0",
+    "html-webpack-plugin": "^4.2.0",
+    "less": "^3.9.0",
+    "less-loader": "^4.1.0",
+    "sass-loader": "^10.1.0",
+    "vue-template-compiler": "2.6.10"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
+    },
+    "extends": [
+      "plugin:vue/strongly-recommended",
+      "@vue/standard"
+    ],
+    "parserOptions": {
+      "parser": "babel-eslint"
+    },
+    "rules": {
+      "generator-star-spacing": "off",
+      "no-mixed-operators": 0,
+      "vue/max-attributes-per-line": [
+        2,
+        {
+          "singleline": 5,
+          "multiline": {
+            "max": 1,
+            "allowFirstLine": false
+          }
+        }
+      ],
+      "vue/attribute-hyphenation": 0,
+      "vue/html-self-closing": 0,
+      "vue/component-name-in-template-casing": 0,
+      "vue/html-closing-bracket-spacing": 0,
+      "vue/singleline-html-element-content-newline": 0,
+      "vue/no-unused-components": 0,
+      "vue/multiline-html-element-content-newline": 0,
+      "vue/no-use-v-if-with-v-for": 0,
+      "vue/html-closing-bracket-newline": 0,
+      "vue/no-parsing-error": 0,
+      "no-tabs": 0,
+      "indent": [
+        "off",
+        2
+      ],
+      "no-console": 0,
+      "space-before-function-paren": 0
+    }
+  },
+  "postcss": {
+    "plugins": {
+      "autoprefixer": {}
+    }
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 10"
+  ]
+}

+ 89 - 87
src/main.js

@@ -1,88 +1,90 @@
-/** init domain config */
-import './config'
-
-import Vue from 'vue'
-import App from './App.vue'
-import Storage from 'vue-ls'
-import router from './router'
-import store from './store/'
-import { VueAxios } from "@/utils/request"
-
-require('@jeecg/antd-online-mini')
-require('@jeecg/antd-online-mini/dist/OnlineForm.css')
-
-import Antd, { version } from 'ant-design-vue'
-console.log('ant-design-vue version:', version)
-
-import Viser from 'viser-vue'
-import 'ant-design-vue/dist/antd.less';  // or 'ant-design-vue/dist/antd.less'
-
-import '@/permission' // permission control
-import '@/utils/filter' // base filter
-import Print from 'vue-print-nb-jeecg'
-/*import '@babel/polyfill'*/
-import preview from 'vue-photo-preview'
-import 'vue-photo-preview/dist/skin.css'
-import SSO from '@/cas/sso.js'
-import {
-  ACCESS_TOKEN,
-  DEFAULT_COLOR,
-  DEFAULT_THEME,
-  DEFAULT_LAYOUT_MODE,
-  DEFAULT_COLOR_WEAK,
-  SIDEBAR_TYPE,
-  DEFAULT_FIXED_HEADER,
-  DEFAULT_FIXED_HEADER_HIDDEN,
-  DEFAULT_FIXED_SIDEMENU,
-  DEFAULT_CONTENT_WIDTH_TYPE,
-  DEFAULT_MULTI_PAGE
-} from "@/store/mutation-types"
-import config from '@/defaultSettings'
-
-import JDictSelectTag from './components/dict/index.js'
-import hasPermission from '@/utils/hasPermission'
-import vueBus from '@/utils/vueBus';
-import JeecgComponents from '@/components/jeecg/index'
-import '@/assets/less/JAreaLinkage.less'
-import VueAreaLinkage from 'vue-area-linkage'
-import '@/components/jeecg/JVxeTable/install'
-import '@/components/JVxeCells/install'
-//表单验证
-import { rules } from '@/utils/rules'
-Vue.prototype.rules = rules
-Vue.config.productionTip = false
-Vue.use(Storage, config.storageOptions)
-Vue.use(Antd)
-Vue.use(VueAxios, router)
-Vue.use(Viser)
-Vue.use(hasPermission)
-Vue.use(JDictSelectTag)
-Vue.use(Print)
-Vue.use(preview)
-Vue.use(vueBus);
-Vue.use(JeecgComponents);
-Vue.use(VueAreaLinkage);
-
-SSO.init(() => {
-  main()
-})
-function main() {
-  new Vue({
-    router,
-    store,
-    mounted () {
-      store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true))
-      store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme))
-      store.commit('TOGGLE_LAYOUT_MODE', Vue.ls.get(DEFAULT_LAYOUT_MODE, config.layout))
-      store.commit('TOGGLE_FIXED_HEADER', Vue.ls.get(DEFAULT_FIXED_HEADER, config.fixedHeader))
-      store.commit('TOGGLE_FIXED_SIDERBAR', Vue.ls.get(DEFAULT_FIXED_SIDEMENU, config.fixSiderbar))
-      store.commit('TOGGLE_CONTENT_WIDTH', Vue.ls.get(DEFAULT_CONTENT_WIDTH_TYPE, config.contentWidth))
-      store.commit('TOGGLE_FIXED_HEADER_HIDDEN', Vue.ls.get(DEFAULT_FIXED_HEADER_HIDDEN, config.autoHideHeader))
-      store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
-      store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
-      store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
-      store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage))
-    },
-    render: h => h(App)
-  }).$mount('#app')
+/** init domain config */
+import './config'
+
+import Vue from 'vue'
+import App from './App.vue'
+import Storage from 'vue-ls'
+import router from './router'
+import store from './store/'
+import { VueAxios } from "@/utils/request"
+
+require('@jeecg/antd-online-mini')
+require('@jeecg/antd-online-mini/dist/OnlineForm.css')
+
+import Antd, { version } from 'ant-design-vue'
+console.log('ant-design-vue version:', version)
+
+import Viser from 'viser-vue'
+import 'ant-design-vue/dist/antd.less';  // or 'ant-design-vue/dist/antd.less'
+
+import '@/permission' // permission control
+import '@/utils/filter' // base filter
+import Print from 'vue-print-nb-jeecg'
+/*import '@babel/polyfill'*/
+import preview from 'vue-photo-preview'
+import 'vue-photo-preview/dist/skin.css'
+import SSO from '@/cas/sso.js'
+import {
+  ACCESS_TOKEN,
+  DEFAULT_COLOR,
+  DEFAULT_THEME,
+  DEFAULT_LAYOUT_MODE,
+  DEFAULT_COLOR_WEAK,
+  SIDEBAR_TYPE,
+  DEFAULT_FIXED_HEADER,
+  DEFAULT_FIXED_HEADER_HIDDEN,
+  DEFAULT_FIXED_SIDEMENU,
+  DEFAULT_CONTENT_WIDTH_TYPE,
+  DEFAULT_MULTI_PAGE
+} from "@/store/mutation-types"
+import config from '@/defaultSettings'
+
+import JDictSelectTag from './components/dict/index.js'
+import hasPermission from '@/utils/hasPermission'
+import vueBus from '@/utils/vueBus';
+import JeecgComponents from '@/components/jeecg/index'
+import '@/assets/less/JAreaLinkage.less'
+import VueAreaLinkage from 'vue-area-linkage'
+import '@/components/jeecg/JVxeTable/install'
+import '@/components/JVxeCells/install'
+import * as echarts from 'echarts' 
+//表单验证
+import { rules } from '@/utils/rules'
+Vue.prototype.$echarts = echarts
+Vue.prototype.rules = rules
+Vue.config.productionTip = false
+Vue.use(Storage, config.storageOptions)
+Vue.use(Antd)
+Vue.use(VueAxios, router)
+Vue.use(Viser)
+Vue.use(hasPermission)
+Vue.use(JDictSelectTag)
+Vue.use(Print)
+Vue.use(preview)
+Vue.use(vueBus);
+Vue.use(JeecgComponents);
+Vue.use(VueAreaLinkage);
+
+SSO.init(() => {
+  main()
+})
+function main() {
+  new Vue({
+    router,
+    store,
+    mounted () {
+      store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true))
+      store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme))
+      store.commit('TOGGLE_LAYOUT_MODE', Vue.ls.get(DEFAULT_LAYOUT_MODE, config.layout))
+      store.commit('TOGGLE_FIXED_HEADER', Vue.ls.get(DEFAULT_FIXED_HEADER, config.fixedHeader))
+      store.commit('TOGGLE_FIXED_SIDERBAR', Vue.ls.get(DEFAULT_FIXED_SIDEMENU, config.fixSiderbar))
+      store.commit('TOGGLE_CONTENT_WIDTH', Vue.ls.get(DEFAULT_CONTENT_WIDTH_TYPE, config.contentWidth))
+      store.commit('TOGGLE_FIXED_HEADER_HIDDEN', Vue.ls.get(DEFAULT_FIXED_HEADER_HIDDEN, config.autoHideHeader))
+      store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
+      store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
+      store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
+      store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage))
+    },
+    render: h => h(App)
+  }).$mount('#app')
 }

+ 366 - 0
src/views/lg/ProdPlan/ProdPlanList.vue

@@ -0,0 +1,366 @@
+<template>
+  <a-card :bordered="false">
+    <div ref="pie" :style="{ 
+        width: '600px', 
+        height: '400px', 
+        position: 'absolute', 
+        left: '-9999px',
+        top: '-9999px',
+        visibility: 'hidden'
+      }" />
+    <div ref="barline" :style="{ 
+        width: '600px', 
+        height: '400px', 
+        position: 'absolute', 
+        left: '-9999px',
+        top: '-9999px',
+        visibility: 'hidden'
+      }" />
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <!-- <a-button type="primary" icon="download" @click="handleExportXls('生产计划')">导出</a-button> -->
+      <!-- <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel" :customRequest="customRequest">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <!-- 高级查询区域 -->
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown> -->
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{x:true}"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+        class="j-table-force-nowrap"
+        @change="handleTableChange">
+
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text,record">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a @click="handleDetail(record)">详情</a>
+
+          <a-divider type="vertical" />
+          <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+            <a>删除</a>
+          </a-popconfirm>
+
+          <a-divider type="vertical" />
+          <a @click="handleAnalysis(record.id)">解析</a>
+
+          <a-divider type="vertical" />
+          <a @click="handleReport(record.id)">生成报告</a>
+
+          <a-divider type="vertical" />
+          <a @click="handleEmal(record.id)">发送邮件</a>
+        </span>
+
+      </a-table>
+    </div>
+
+    <prod-plan-modal ref="modalForm" @ok="modalFormOk"></prod-plan-modal>
+  </a-card>
+</template>
+
+<script>
+
+  import '@/assets/less/TableExpand.less'
+  import { mixinDevice } from '@/utils/mixin'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import ProdPlanModal from './modules/ProdPlanModal'
+  import {  getAction,downFile,postAction} from '@/api/manage'
+
+  export default {
+    name: 'ProdPlanList',
+    mixins:[JeecgListMixin, mixinDevice],
+    components: {
+      ProdPlanModal
+    },
+    data () {
+      return {
+        description: '生产计划管理页面',
+        // 表头
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+          },
+          {
+            title:'计划日期',
+            align:"center",
+            dataIndex: 'planDate',
+            customRender:function (text) {
+              return !text?"":(text.length>10?text.substr(0,10):text)
+            }
+          },
+          {
+            title:'计划表',
+            align:"center",
+            dataIndex: 'planSheet',
+            scopedSlots: {customRender: 'fileSlot'}
+          },
+          {
+            title:'发件状态',
+            align:"center",
+            dataIndex: 'sendState'
+          },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        url: {
+          list: "/ProdPlan/prodPlan/list",
+          delete: "/ProdPlan/prodPlan/delete",
+          analysis: "/ProdPlan/prodPlan/analysis",
+          report: "/ProdPlan/prodPlan/report",
+          email: "/ProdPlan/prodPlan/email",
+          deleteBatch: "/ProdPlan/prodPlan/deleteBatch",
+          exportXlsUrl: "/ProdPlan/prodPlan/exportXls",
+          importExcelUrl: "ProdPlan/prodPlan/importExcel",
+          
+        },
+        dictOptions:{},
+        superFieldList:[],
+      }
+    },
+    created() {
+      this.getSuperFieldList();
+    },
+    computed: {
+      importExcelUrl: function(){
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      },
+    },
+    mounted() {
+      this.initPie();
+    },
+    methods: {
+      customRequest(options){
+        let params = new FormData();
+        params.append("file", options.file)
+        params.append("plan")
+        httpAction(this.url.importExcelUrl,params,'POST').then(res=>{
+            if(res.success){
+              this.$message.success(res.message)
+              this.searchQuery()
+            }else{
+              this.$message.warning(res.message);
+            }
+        })
+
+      },
+      initDictConfig(){
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'date',value:'planDate',text:'计划日期'})
+        fieldList.push({type:'string',value:'planSheet',text:'计划表',dictCode:''})
+        fieldList.push({type:'int',value:'sendState',text:'发件状态',dictCode:''})
+        this.superFieldList = fieldList
+      },
+      handleAnalysis: function (id) {
+        var that = this;
+        getAction(that.url.analysis, {id: id}).then((res) => {
+          if (res.success) {
+            that.$message.success(res.message);
+          } else {
+            that.$message.warning(res.message);
+          }
+        });
+      },
+      handleReport(id){
+        let fileName = "导出文件"
+        let pie = this.pieChart.getDataURL({
+            type: 'png',
+            pixelRatio: 2, // 设置像素比,提高清晰度
+            backgroundColor: '#fff' // 设置背景色
+          }).replace(/^data:image\/\w+;base64,/, '')
+          
+        downFile(this.url.report,{id: id,pie:pie},"POST").then((data)=>{
+          if (!data) {
+            this.$message.warning("文件下载失败")
+            return
+          }
+          if (typeof window.navigator.msSaveBlob !== 'undefined') {
+            window.navigator.msSaveBlob(new Blob([data],{type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}), fileName+'.xlsx')
+            // window.navigator.msSaveBlob(new Blob([data],{type: 'application/vnd.ms-excel'}), fileName+'.xls')
+          }else{
+            let url = window.URL.createObjectURL(new Blob([data],{type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}))
+            // let url = window.URL.createObjectURL(new Blob([data],{type: 'application/vnd.ms-excel'}))
+            let link = document.createElement('a')
+            link.style.display = 'none'
+            link.href = url
+            link.setAttribute('download', fileName+'.xlsx')
+            document.body.appendChild(link)
+            link.click()
+            document.body.removeChild(link); //下载完成移除元素
+            window.URL.revokeObjectURL(url); //释放掉blob对象
+          }
+        })
+      },
+      handleEmal: function (id) {
+        var that = this;
+        let pie = that.pieChart.getDataURL({
+            type: 'png',
+            pixelRatio: 2, // 设置像素比,提高清晰度
+            backgroundColor: '#fff' // 设置背景色
+          }).replace(/^data:image\/\w+;base64,/, '')
+        postAction(that.url.email, {id: id,pie:pie}).then((res) => {
+          if (res.success) {
+            that.$message.success(res.message);
+          } else {
+            that.$message.warning(res.message);
+          }
+        });
+      },
+      initPie(){
+        this.pieChart = this.$echarts.init(this.$refs.pie)
+        let option = {
+          color: ['#70bfe5', '#eb6a6c', '#f9c942', '#91c974', '#5a6ac0'],
+          tooltip: {
+            trigger: 'item',
+            formatter: '{a} <br/>{b}: {c} ({d}%)'
+          },
+          backgroundColor: '#fff',
+          legend: {
+            data: [
+              '开发未完',
+              '日别Capa不足',
+              '合并生产',
+              'LOT不良'
+            ]
+          },
+          series: [
+            {
+              name: 'Access From',
+              type: 'pie',
+              selectedMode: 'single',
+              radius: [0, '30%'],
+              label: {
+                position: 'inner',
+                fontSize: 14
+              },
+              labelLine: {
+                show: false
+              },
+              data: [
+                { value: 280, name: 'R&D',itemStyle: {color:'#fc8251'} },
+                { value: 494, name: '制造',itemStyle: {color:'#033E6B'}, selected: true }
+              ]
+            },
+            {
+              name: 'Access From',
+              type: 'pie',
+              radius: ['45%', '60%'],
+              labelLine: {
+                length: 30
+              },
+              label: {
+                formatter: '{a|{b}}{abg|}\n{hr|}\n  {b|数量:}{c}  {per|{d}%}  ',
+                backgroundColor: '#F6F8FC',
+                borderColor: '#8C8D8E',
+                borderWidth: 1,
+                borderRadius: 4,
+                rich: {
+                  a: {
+                    color: '#6E7079',
+                    lineHeight: 22,
+                    align: 'center'
+                  },
+                  hr: {
+                    borderColor: '#8C8D8E',
+                    width: '100%',
+                    borderWidth: 1,
+                    height: 0
+                  },
+                  b: {
+                    color: '#4C5058',
+                    fontSize: 14,
+                    fontWeight: 'bold',
+                    lineHeight: 33
+                  },
+                  per: {
+                    color: '#fff',
+                    backgroundColor: '#4C5058',
+                    padding: [3, 4],
+                    borderRadius: 4
+                  }
+                }
+              },
+              data: [
+                { value: 280, name: '开发未完' ,itemStyle: {color:'#fc8251'}},
+                { value: 376, name: '日别Capa不足',itemStyle: {color:'#25567B'} },
+                { value: 40, name: '合并生产',itemStyle: {color:'#0B61A4'} },
+                { value: 78, name: 'LOT不良',itemStyle: {color:'#66A3D2'} },
+              ]
+            }
+          ]
+        };
+        this.pieChart.setOption(option)
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>

+ 109 - 0
src/views/lg/ProdPlan/modules/ProdPlanForm.vue

@@ -0,0 +1,109 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item label="计划日期" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="planDate">
+              <j-date placeholder="请选择计划日期" v-model="model.planDate"  style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="计划表" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="planSheet">
+              <j-upload v-model="model.planSheet" number="1" multiple="false"  ></j-upload>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+
+  import { httpAction, getAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+
+  export default {
+    name: 'ProdPlanForm',
+    components: {
+    },
+    props: {
+      //表单禁用
+      disabled: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+    },
+    data () {
+      return {
+        model:{
+         },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+        confirmLoading: false,
+        validatorRules: {
+        },
+        url: {
+          add: "/ProdPlan/prodPlan/add",
+          edit: "/ProdPlan/prodPlan/edit",
+          queryById: "/ProdPlan/prodPlan/queryById"
+        }
+      }
+    },
+    computed: {
+      formDisabled(){
+        return this.disabled
+      },
+    },
+    created () {
+       //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+      add () {
+        this.edit(this.modelDefault);
+      },
+      edit (record) {
+        this.model = Object.assign({}, record);
+        this.visible = true;
+      },
+      submitForm () {
+        const that = this;
+        // 触发表单验证
+        this.$refs.form.validate(valid => {
+          if (valid) {
+            that.confirmLoading = true;
+            let httpurl = '';
+            let method = '';
+            if(!this.model.id){
+              httpurl+=this.url.add;
+              method = 'post';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+            })
+          }
+         
+        })
+      },
+    }
+  }
+</script>

+ 60 - 0
src/views/lg/ProdPlan/modules/ProdPlanModal.vue

@@ -0,0 +1,60 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <prod-plan-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></prod-plan-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import ProdPlanForm from './ProdPlanForm'
+  export default {
+    name: 'ProdPlanModal',
+    components: {
+      ProdPlanForm
+    },
+    data () {
+      return {
+        title:'',
+        width:800,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        })
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>