New file |
| | |
| | | > 1% |
| | | last 2 versions |
New file |
| | |
| | | [*.{js,jsx,ts,tsx,vue}] |
| | | indent_style = space |
| | | indent_size = 2 |
| | | trim_trailing_whitespace = true |
| | | insert_final_newline = true |
New file |
| | |
| | | # just a flag |
| | | ENV = 'development' |
| | | |
| | | # base api |
| | | VUE_APP_BASE_API = 'http://127.0.0.1:8081/' |
| | | |
| | | # vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable, |
| | | # to control whether the babel-plugin-dynamic-import-node plugin is enabled. |
| | | # It only does one thing by converting all import() to require(). |
| | | # This configuration can significantly increase the speed of hot updates, |
| | | # when you have a large number of pages. |
| | | # Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js |
| | | |
| | | VUE_CLI_BABEL_TRANSPILE_MODULES = true |
New file |
| | |
| | | # just a flag |
| | | ENV = 'production' |
| | | |
| | | # base api |
| | | VUE_APP_BASE_API = 'http://47.76.147.249:8081/' |
| | | #VUE_APP_BASE_API = 'http://127.0.0.1:8081/' |
| | | |
| | | |
New file |
| | |
| | | module.exports = { |
| | | root: true, |
| | | env: { |
| | | node: true |
| | | }, |
| | | 'extends': [ |
| | | 'plugin:vue/essential', |
| | | '@vue/standard' |
| | | ], |
| | | rules: { |
| | | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', |
| | | 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' |
| | | }, |
| | | parserOptions: { |
| | | parser: 'babel-eslint' |
| | | } |
| | | } |
New file |
| | |
| | | <h1 align="center">Construction-Data</h1> |
| | | |
| | | ## Project setup |
| | | ``` |
| | | yarn install |
| | | ``` |
| | | |
| | | ### Compiles and hot-reloads for development |
| | | ``` |
| | | yarn run dev |
| | | ``` |
| | | |
| | | ### Compiles and minifies for production |
| | | ``` |
| | | yarn run build |
| | | ``` |
New file |
| | |
| | | module.exports = { |
| | | presets: [ |
| | | '@vue/app' |
| | | ] |
| | | } |
New file |
| | |
| | | { |
| | | "name": "adev", |
| | | "version": "0.1.0", |
| | | "private": true, |
| | | "scripts": { |
| | | "dev": "vue-cli-service serve", |
| | | "build": "vue-cli-service build", |
| | | "lint": "vue-cli-service lint" |
| | | }, |
| | | "dependencies": { |
| | | "@jiaminghi/data-view": "^2.10.0", |
| | | "axios": "^1.7.9", |
| | | "element-ui": "^2.15.14", |
| | | "html2canvas": "^1.4.1", |
| | | "jspdf": "^2.5.2", |
| | | "less": "^3.9.0", |
| | | "less-loader": "^5.0.0", |
| | | "print-js": "^1.6.0", |
| | | "vue": "^2.6.10" |
| | | }, |
| | | "devDependencies": { |
| | | "@vue/cli-plugin-babel": "^3.8.0", |
| | | "@vue/cli-plugin-eslint": "^3.8.0", |
| | | "@vue/cli-service": "^3.8.0", |
| | | "@vue/eslint-config-standard": "^4.0.0", |
| | | "babel-eslint": "^10.0.1", |
| | | "eslint": "^5.16.0", |
| | | "eslint-plugin-vue": "^5.0.0", |
| | | "vue-template-compiler": "^2.6.10" |
| | | } |
| | | } |
New file |
| | |
| | | module.exports = { |
| | | plugins: { |
| | | autoprefixer: {} |
| | | } |
| | | } |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | <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"> |
| | | <link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
| | | <title>DATAV-DEMO</title> |
| | | </head> |
| | | <body> |
| | | <noscript> |
| | | <strong>We're sorry but adev 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> |
New file |
| | |
| | | <template> |
| | | <div id="app"> |
| | | <datav /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | import datav from './components/datav/index.vue' |
| | | |
| | | export default { |
| | | name: 'app', |
| | | components: { |
| | | datav |
| | | }, |
| | | data () { |
| | | return {} |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | #app { |
| | | font-family: 'Avenir', Helvetica, Arial, sans-serif; |
| | | -webkit-font-smoothing: antialiased; |
| | | -moz-osx-font-smoothing: grayscale; |
| | | color: #2c3e50; |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | </style> |
New file |
| | |
| | | html, body { |
| | | width: 100%; |
| | | height: 100%; |
| | | padding: 0px; |
| | | margin: 0px; |
| | | } |
New file |
| | |
| | | <template> |
| | | <div id="cards"> |
| | | <div |
| | | class="card-item" |
| | | v-for="(card, i) in cards" |
| | | :key="card.title" |
| | | > |
| | | <div class="card-header"> |
| | | <div class="card-header-left">{{ card.title }}</div> |
| | | <div class="card-header-right">{{ '0' + (i + 1) }}</div> |
| | | </div> |
| | | <dv-charts class="ring-charts" :option="card.ring" /> |
| | | <div class="card-footer"> |
| | | <div class="card-footer-item"> |
| | | <div class="footer-title">累计金额</div> |
| | | <div class="footer-detail"> |
| | | <dv-digital-flop :config="card.total" style="width:70%;height:35px;" />元 |
| | | </div> |
| | | </div> |
| | | <div class="card-footer-item"> |
| | | <div class="footer-title">巡查病害</div> |
| | | <div class="footer-detail"> |
| | | <dv-digital-flop :config="card.num" style="width:70%;height:35px;" />处 |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'Cards', |
| | | data () { |
| | | return { |
| | | cards: [] |
| | | } |
| | | }, |
| | | methods: { |
| | | createData () { |
| | | const { randomExtend } = this |
| | | |
| | | this.cards = new Array(5).fill(0).map((foo, i) => ({ |
| | | title: '测试路段' + (i + i), |
| | | total: { |
| | | number: [randomExtend(9000, 10000)], |
| | | content: '{nt}', |
| | | textAlign: 'right', |
| | | style: { |
| | | fill: '#ea6027', |
| | | fontWeight: 'bold' |
| | | } |
| | | }, |
| | | num: { |
| | | number: [randomExtend(30, 60)], |
| | | content: '{nt}', |
| | | textAlign: 'right', |
| | | style: { |
| | | fill: '#26fcd8', |
| | | fontWeight: 'bold' |
| | | } |
| | | }, |
| | | ring: { |
| | | series: [ |
| | | { |
| | | type: 'gauge', |
| | | startAngle: -Math.PI / 2, |
| | | endAngle: Math.PI * 1.5, |
| | | arcLineWidth: 13, |
| | | radius: '80%', |
| | | data: [ |
| | | { name: '资金占比', value: randomExtend(40, 60) } |
| | | ], |
| | | axisLabel: { |
| | | show: false |
| | | }, |
| | | axisTick: { |
| | | show: false |
| | | }, |
| | | pointer: { |
| | | show: false |
| | | }, |
| | | backgroundArc: { |
| | | style: { |
| | | stroke: '#224590' |
| | | } |
| | | }, |
| | | details: { |
| | | show: true, |
| | | formatter: '资金占比{value}%', |
| | | style: { |
| | | fill: '#1ed3e5', |
| | | fontSize: 20 |
| | | } |
| | | } |
| | | } |
| | | ], |
| | | color: ['#03d3ec'] |
| | | } |
| | | })) |
| | | }, |
| | | randomExtend (minNum, maxNum) { |
| | | if (arguments.length === 1) { |
| | | return parseInt(Math.random() * minNum + 1, 10) |
| | | } else { |
| | | return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10) |
| | | } |
| | | } |
| | | }, |
| | | mounted () { |
| | | const { createData } = this |
| | | |
| | | createData() |
| | | |
| | | setInterval(this.createData, 30000) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | #cards { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | height: 45%; |
| | | |
| | | .card-item { |
| | | background-color: rgba(6, 30, 93, 0.5); |
| | | border-top: 2px solid rgba(1, 153, 209, .5); |
| | | width: 19%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .card-header { |
| | | display: flex; |
| | | height: 20%; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | |
| | | .card-header-left { |
| | | font-size: 18px; |
| | | font-weight: bold; |
| | | padding-left: 20px; |
| | | } |
| | | |
| | | .card-header-right { |
| | | padding-right: 20px; |
| | | font-size: 40px; |
| | | color: #03d3ec; |
| | | } |
| | | } |
| | | |
| | | .ring-charts { |
| | | height: 55%; |
| | | } |
| | | |
| | | .card-footer { |
| | | height: 25%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-around; |
| | | } |
| | | |
| | | .card-footer-item { |
| | | padding: 5px 10px 0px 10px; |
| | | box-sizing: border-box; |
| | | width: 40%; |
| | | background-color: rgba(6, 30, 93, 0.7); |
| | | border-radius: 3px; |
| | | |
| | | .footer-title { |
| | | font-size: 15px; |
| | | margin-bottom: 5px; |
| | | } |
| | | |
| | | .footer-detail { |
| | | font-size: 20px; |
| | | color: #1294fb; |
| | | display: flex; |
| | | font-size: 18px; |
| | | align-items: center; |
| | | |
| | | .dv-digital-flop { |
| | | margin-right: 5px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div id="digital-flop"> |
| | | <div class="digital-flop-item" v-for="(item,index) in Object.keys(waveLabels)" :key="index"> |
| | | <div class="digital-flop-title">{{ waveLabels[item] }}</div> |
| | | <div class="digital-flop"> |
| | | <div class="cell-item" v-if="item == 'workQty'"> |
| | | {{data.anfme - data[item]}} |
| | | </div> |
| | | <div class="cell-item" v-else> |
| | | {{data[item]}} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <dv-decoration-10 /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'DigitalFlop', |
| | | data () { |
| | | return { |
| | | digitalFlopData: [], |
| | | waveLabels: { |
| | | orderNo: '订单编号', |
| | | siteNo: '播种位', |
| | | matnr: '物料编号', |
| | | batch: '批号', |
| | | waveNo: '波次', |
| | | anfme: '总需求数量', |
| | | workQty: '剩余需求数量', |
| | | } |
| | | } |
| | | }, |
| | | |
| | | props: { |
| | | data: Object |
| | | }, |
| | | methods: { |
| | | |
| | | }, |
| | | |
| | | mounted () { |
| | | // setInterval(createData, 30000) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | |
| | | @media screen and (max-width: 1920px){ |
| | | #digital-flop { |
| | | position: relative; |
| | | height: 100%; |
| | | flex-shrink: 0; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | background-color: rgba(6, 30, 93, 0.5); |
| | | |
| | | .dv-decoration-10 { |
| | | position: absolute; |
| | | width: 95%; |
| | | left: 2.5%; |
| | | height: 5px; |
| | | bottom: 0px; |
| | | } |
| | | |
| | | .digital-flop-item { |
| | | width: auto; |
| | | padding: 10px; |
| | | height: 80%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | } |
| | | |
| | | .digital-flop-title { |
| | | padding: 10px; |
| | | font-size: 20px; |
| | | } |
| | | |
| | | .digital-flop { |
| | | display: flex; |
| | | |
| | | .cell-item { |
| | | height: 50px; |
| | | text-align: center; |
| | | font-style: italic; |
| | | font-size: 18px; |
| | | } |
| | | } |
| | | |
| | | .unit { |
| | | margin-left: 10px; |
| | | display: flex; |
| | | align-items: flex-end; |
| | | box-sizing: border-box; |
| | | padding-bottom: 13px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | @media screen and (max-width: 1280px) { |
| | | #digital-flop{ |
| | | .digital-flop-title { |
| | | padding: 10px; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .digital-flop { |
| | | .cell-item { |
| | | font-size: 12px; |
| | | height: unset; |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div id="data-view" > |
| | | <dv-full-screen-container> |
| | | <top-header/> |
| | | <template> |
| | | <el-row> |
| | | <el-col :span="15"> |
| | | <el-row class="header-left-task" type="flex" align="center" > |
| | | <el-col v-for="(task, index) in tasks" :key="index" > |
| | | <el-row type="flex" align="center" justify="center" @click.native="borderClick(task)"> |
| | | <dv-border-box-2> |
| | | <el-card class="header-card" > |
| | | <el-row> |
| | | <el-col :span="4" v-for="(item, index) in Object.keys(waveLabels)" :key="index"> |
| | | <div class="header-card-label" >{{ waveLabels[item] }}</div> |
| | | <div class="header-card-val" >{{ task[item] }}</div> |
| | | </el-col> |
| | | </el-row> |
| | | </el-card> |
| | | </dv-border-box-2> |
| | | </el-row> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row class="detl-info-row"> |
| | | <dv-border-box-2> |
| | | <el-card> |
| | | <el-table :data="mergeTaskDetl" class="talbe-matnr" @row-click="selectRow"> |
| | | <el-table-column v-for="(item,index) in Object.keys(detlLabels)" :prop="item" :label="detlLabels[item]" :key="index"/> |
| | | </el-table> |
| | | </el-card> |
| | | </dv-border-box-2> |
| | | </el-row> |
| | | <el-row class="pick-order-detl"> |
| | | <dv-border-box11 title="拣货订单明细" class="detl-box-border"> |
| | | <div class="detl-box-padding"></div> |
| | | <div class="order-detl-list"> |
| | | <div class="main-content" v-for="(item,index) in taskDetls" @click="selectView(item)" :key="index"> |
| | | <digital-flop :data = item /> |
| | | </div> |
| | | </div> |
| | | </dv-border-box11> |
| | | </el-row> |
| | | </el-col> |
| | | <el-col :span="9"> |
| | | <el-row class="order-box-row"> |
| | | <dv-border-box-11 title="订单完成情况" class="order-box"> |
| | | <el-table :data="orders" v-if="orders.length > 0" class="order-table"> |
| | | <el-table-column v-for="(item, dex) in Object.keys(orderStatus)" :prop="item" :label="orderStatus[item]" :key="dex"> |
| | | <template slot-scope="scope"> |
| | | <el-popover |
| | | placement="right" |
| | | width="300" |
| | | trigger="manual" |
| | | v-model="visible" |
| | | v-if="item === 'action'" > |
| | | <template> |
| | | <div> |
| | | <span>选择目标发货区</span> |
| | | <el-divider/> |
| | | <el-row :gutter="15"> |
| | | <el-col v-for="(palt, index) in platforms" :key="index" class="platform" :span="7" @click.native="bindShipping(palt, scope)"> |
| | | <div>{{palt.platformNo}}</div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </template> |
| | | <el-button slot="reference" type="text" @click.native.prevent="print(scope.$index, orders)">打印明细</el-button> |
| | | </el-popover> |
| | | <div v-else class="ship-order-list"> |
| | | {{scope.row[item]}} |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <el-empty description="暂无投放订单" class="empty-padding" v-else></el-empty> |
| | | </dv-border-box-11> |
| | | </el-row> |
| | | <el-row type="flex" align="center" id="datav"> |
| | | <dv-border-box-11 title="播种墙" class="pick-wall" > |
| | | <el-row type="flex" align="center" justify="center" class="pick-wall-circle" > |
| | | <el-col :span="1"> |
| | | <p class="pick-wall-tip"></p> |
| | | </el-col> |
| | | <el-col :span="22"> |
| | | <p>绿色:任务已完成 黄色:等待中 红色:播种中</p> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="pick-wall-box"> |
| | | <el-col :span="6" v-for="(item, index) in seedBracket" :key="index" @click.native="lightClick(item)"> |
| | | <div class="seed-bracket" :style="getLightStatus(item)" /> |
| | | </el-col> |
| | | </div> |
| | | </dv-border-box-11> |
| | | </el-row> |
| | | </el-col> |
| | | </el-row> |
| | | </template> |
| | | </dv-full-screen-container> |
| | | <template> |
| | | <el-dialog :visible.sync="show" fullscreen> |
| | | <el-row type="flex" align="center" justify="center"> |
| | | <dv-border-box-10 class="dialog-confirm" v-if="show"> |
| | | <div class="container"> |
| | | <el-row :gutter="25" > |
| | | <el-col :span="12"> |
| | | <el-row> |
| | | <el-col class="header-title">复核当前作业中数量</el-col> |
| | | <el-col style="text-align: center"> |
| | | <el-col :span="10" class="content">总需求数量:</el-col> |
| | | <el-col :span="8" class="content-value">{{ selected.anfme }}</el-col> |
| | | </el-col> |
| | | <el-col> |
| | | <el-col :span="10" class="content">剩余需求数量:</el-col> |
| | | <el-col :span="8" class="content-value">{{ selected.anfme - selected.workQty }}</el-col> |
| | | </el-col> |
| | | </el-row> |
| | | </el-col> |
| | | <el-col :span="12" > |
| | | <el-row> |
| | | <el-col> |
| | | <div class="header-title">拣货数量:</div> |
| | | <dv-border-box-10 class="box"> |
| | | <el-input type="text" v-model="workQty"></el-input> |
| | | </dv-border-box-10> |
| | | </el-col> |
| | | </el-row> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row :gutter="100" style="margin:25px;"> |
| | | <el-col :span="12"> |
| | | <el-button type="success" class="btn" @click="review">确认</el-button> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-button type="danger" class="btn" @click="delSow">取消</el-button> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </dv-border-box-10> |
| | | </el-row> |
| | | </el-dialog> |
| | | </template> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import topHeader from './topHeader' |
| | | import print from 'print-js' |
| | | import digitalFlop from './digitalFlop' |
| | | |
| | | export default { |
| | | name: 'DataView', |
| | | components: { |
| | | topHeader, |
| | | digitalFlop |
| | | }, |
| | | data () { |
| | | return { |
| | | visible: false, |
| | | waveSeeds: [], |
| | | tasks: [], |
| | | taskDetls: [], |
| | | mergeTaskDetl: [], |
| | | currTask: {}, |
| | | detlLabels: { |
| | | matnr: '物料码', |
| | | batch: '批次', |
| | | anfme: '拣货任务数量', |
| | | stock: '库存数量' |
| | | }, |
| | | orderStatus: { |
| | | orderNo: '订单编码', |
| | | orderStatus: '订单状态', |
| | | action: '操作' |
| | | }, |
| | | waveLabels: { |
| | | barcode: '拖盘码', |
| | | taskNo: '任务编号', |
| | | waveNo: '波次', |
| | | anfme: '数量', |
| | | title: '作业类型' |
| | | }, |
| | | waveNo: '', |
| | | header: {}, |
| | | orders: [], |
| | | seedBracket: [], |
| | | platforms: [], |
| | | selectOrder: {}, |
| | | selected: {}, |
| | | workQty: 0, //弹窗拣货数量 |
| | | show: false, |
| | | } |
| | | }, |
| | | created () { |
| | | //获取当前执行任务 |
| | | this.getWaves() |
| | | //获取当前播种墙库位信息 |
| | | this.getSeedLoc() |
| | | //获取所有发货暂存区 |
| | | this.getAllPlatforms() |
| | | }, |
| | | computed: { |
| | | getLightStatus() { |
| | | return (item)=> { |
| | | if (item.orderNo != undefined && item.orderNo != null && item.orderNo != '') { |
| | | return 'background: yellow;' |
| | | } else { |
| | | return 'background: gainsboro;' |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | printPage() { |
| | | // let element = document.querySelector('#datav'); |
| | | // let el = this.$refs.datav |
| | | // console.log(this.$refs.datav) |
| | | // console.log(element) |
| | | // if (el) { |
| | | // let pdfLoader = new PdfLoader(el, 'pdf'); |
| | | // pdfLoader.outPutPdfFn('datav') |
| | | // } |
| | | print( 'datav','html') |
| | | |
| | | }, |
| | | |
| | | //点击打印明细按钮 |
| | | print(e, data) { |
| | | this.visible = true |
| | | this.selectOrder = data[e] |
| | | }, |
| | | //拍灯容器流动 |
| | | lightClick(item) { |
| | | this.slapLight(item) |
| | | }, |
| | | //订单入库集货区,并打印单据 |
| | | bindShipping(plat, item) { |
| | | this.visible = false |
| | | let order = item.row |
| | | if (order == null) { |
| | | this.$message.error("当前订单信息不存在,请联系管理员!!") |
| | | return |
| | | } |
| | | let that = this |
| | | // eslint-disable-next-line no-undef |
| | | $ajax.post('/api/bind/shipping/platform', {orderId: order.id, waveId: order.waveId, platformId: plat.id}).then(response => { |
| | | if (response.code === 200) { |
| | | //隐藏发货区,执行打印 |
| | | } else { |
| | | this.$message.error(response.msg) |
| | | } |
| | | }) |
| | | }, |
| | | //获取所有集货区 |
| | | getAllPlatforms() { |
| | | let that = this |
| | | // eslint-disable-next-line no-undef |
| | | $ajax.get('/out/stock/all/platforms').then(response => { |
| | | if (response.code === 200) { |
| | | that.platforms = response.data |
| | | console.log(that.platforms) |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | slapLight(item) { |
| | | let that = this |
| | | if (that.tasks == null || that.tasks.length < 1) { |
| | | this.$message.error('当前任务号为空,无法执行!!') |
| | | return |
| | | } |
| | | let taskNo = that.tasks[0].taskNo |
| | | // eslint-disable-next-line no-undef |
| | | $ajax.post('/out/stock/slap/light', {taskNo: taskNo, siteNo: item.siteNo, orderNo: item.orderNo}).then(response => { |
| | | if (response.code === 200) { |
| | | //刷新播种墙 |
| | | this.getSeedLoc() |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | /** |
| | | * 获取播种库位状态 |
| | | */ |
| | | getSeedLoc() { |
| | | let that = this |
| | | // eslint-disable-next-line no-undef |
| | | $ajax.get('wave/seed/locs/').then(response => { |
| | | if (response.code === 200) { |
| | | that.seedBracket = response.data |
| | | } |
| | | }) |
| | | }, |
| | | /** |
| | | * 获取波次订单完成状态 |
| | | * @param waveNo |
| | | */ |
| | | getWaveOrders(waveNo) { |
| | | let that = this |
| | | // eslint-disable-next-line no-undef |
| | | $ajax.get('wave/orders/' + this.waveNo).then(response => { |
| | | if (response.code === 200) { |
| | | that.orders = response.data |
| | | } |
| | | }) |
| | | }, |
| | | selectRow (row, index) { |
| | | this.currTask = row |
| | | }, |
| | | /** |
| | | * 头部任务栏,支持多任务显示。可手动切换 |
| | | * @param data |
| | | */ |
| | | borderClick (data) { |
| | | // this.getMergeTaskDetl(data.taskNo) |
| | | }, |
| | | /** |
| | | * 波次播种 |
| | | */ |
| | | review () { |
| | | for (let i = 0; i < this.mergeTaskDetl.length; i++) { |
| | | if (this.mergeTaskDetl[i].matnr === this.selected.matnr && this.workQty > this.mergeTaskDetl[i].anfme) { |
| | | this.$message({ |
| | | message: '拣货数量不能大于任务数量!!', |
| | | type: 'error' |
| | | }) |
| | | return |
| | | } |
| | | } |
| | | //隐藏弹框 |
| | | this.show = false |
| | | // eslint-disable-next-line no-undef |
| | | $ajax.post('wave/sow/review', { waveSeedId: this.selected.id, reviewNum: this.workQty }).then(response => { |
| | | if (response.code === 200) { |
| | | this.getWaves() |
| | | } else { |
| | | this.$message({ |
| | | message: response.msg, |
| | | type: 'error' |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | delSow () { |
| | | this.show = false |
| | | // eslint-disable-next-line no-undef |
| | | // $ajax.get('wave/sow/remove/' + this.selected.id).then(response => { |
| | | // if (response.code === 200) { |
| | | // this.getWaves() |
| | | // } |
| | | // }) |
| | | }, |
| | | selectView (item) { |
| | | if (item.siteNo == undefined && item.siteNo == null && item.siteNo == '') { |
| | | this.$message({ |
| | | message: '请绑定播种站点后,再进行播种!!', |
| | | type: 'error' |
| | | }) |
| | | return |
| | | } |
| | | this.show = true |
| | | this.workQty = item.workQty |
| | | this.selected = item |
| | | }, |
| | | |
| | | getWaves () { |
| | | let that = this |
| | | // eslint-disable-next-line no-undef |
| | | $ajax.get('wave/sow/tasks').then(response => { |
| | | if (response.code === 200) { |
| | | that.tasks = [] |
| | | // this.show = false |
| | | that.tasks.push(...response.data) |
| | | //获取合并波次任务明细 |
| | | that.getMergeTaskDetl(that.tasks[0].taskNo) |
| | | //获取波次订单状态 |
| | | that.waveNo = that.tasks[0].waveNo |
| | | that.getWaveOrders() |
| | | //刷新播种墙信息 |
| | | this.getSeedLoc() |
| | | } |
| | | }) |
| | | |
| | | }, |
| | | |
| | | getMergeTaskDetl (taskNo) { |
| | | let that = this |
| | | // eslint-disable-next-line no-undef |
| | | $ajax.get('wave/sow/task/detl/' + taskNo).then(response => { |
| | | if (response.code === 200) { |
| | | that.mergeTaskDetl = [] |
| | | that.mergeTaskDetl.push(...response.data) |
| | | that.getTaskDetl(that.mergeTaskDetl[0]) |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | getTaskDetl (data) { |
| | | let that = this |
| | | // eslint-disable-next-line no-undef |
| | | $ajax.post('wave/task/detl/qutify/', { taskNo: data.taskNo, matnr: data.matnr }).then(response => { |
| | | if (response.code === 200) { |
| | | that.taskDetls = [] |
| | | // this.show = false |
| | | that.taskDetls.push(...response.data) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | |
| | | |
| | | @media screen and (max-width: 1920px){ |
| | | #data-view { |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: #030409; |
| | | color: #fff; |
| | | |
| | | #dv-full-screen-container { |
| | | background-image: url('./img/bg.png'); |
| | | background-size: 100% 100%; |
| | | box-shadow: 0 0 3px blue; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .main-content { |
| | | margin: 5px 0; |
| | | } |
| | | |
| | | .platform { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | height: 80px; |
| | | background-color: #03d3ec; |
| | | margin: 5px; |
| | | text-align: center; |
| | | } |
| | | |
| | | .pick-order-detl { |
| | | padding: 0 15px; |
| | | |
| | | .detl-box-border { |
| | | height: 59vh; |
| | | |
| | | .detl-box-padding { |
| | | height: 65px |
| | | } |
| | | } |
| | | } |
| | | |
| | | .dialog-confirm { |
| | | text-align: center; |
| | | color: white; |
| | | margin: 20vh; |
| | | |
| | | .container { |
| | | padding: 45px 60px; |
| | | |
| | | .btn { |
| | | width: 30vh;height: 7vh;font-size: 23px; |
| | | } |
| | | .header-title { |
| | | font-size: 24px; |
| | | font-style: italic; |
| | | padding: 10px; |
| | | } |
| | | |
| | | .box { |
| | | height:8vh; |
| | | width: 20vh; |
| | | margin: auto; |
| | | text-align: center; |
| | | } |
| | | .content { |
| | | font-size: 20px; |
| | | text-align: end; |
| | | padding: 10px; |
| | | } |
| | | .content-value { |
| | | padding: 10px; |
| | | text-align: start;font-size: 20px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .pick-wall { |
| | | padding: 60px 10px 10px 10px; |
| | | height: 68vh; |
| | | |
| | | .pick-wall-box { |
| | | .seed-bracket { |
| | | background: gainsboro; |
| | | margin: 15px; |
| | | height: 110px; |
| | | } |
| | | .seed-bracket .el-col .el-col-24 :hover { |
| | | background: white; |
| | | } |
| | | } |
| | | |
| | | .pick-wall-circle { |
| | | padding: 10px;margin: 10px; background-color: #50bfff2e; |
| | | .pick-wall-tip { |
| | | height: 25px; |
| | | width: 1px; |
| | | background: #03d3ec; |
| | | border-left: 5px solid #50bfff |
| | | } |
| | | } |
| | | } |
| | | |
| | | .header-left-task { |
| | | display: flex; |
| | | padding: 15px 15px 5px 15px; |
| | | margin-bottom: 0px !important; |
| | | |
| | | .header-card { |
| | | margin: 10px;height: 120px; |
| | | text-align: center; |
| | | padding: 15px; |
| | | |
| | | .header-card-label { |
| | | font-size: 25px; |
| | | font-style: oblique; |
| | | padding: 5px; |
| | | color: white; |
| | | } |
| | | .header-card-val { |
| | | font-size: 20px; |
| | | padding: 10px; |
| | | color: orange; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .detl-info-row { |
| | | padding: 0 15px; |
| | | } |
| | | |
| | | .order-box-row { |
| | | width: 84vh; |
| | | height: 38vh; |
| | | |
| | | .order-box { |
| | | padding:0px 30px; |
| | | |
| | | .order-table { |
| | | width: 74vh; |
| | | padding-top: 65px; |
| | | height: 275px; |
| | | |
| | | .ship-order-list { |
| | | font-size: 18px; color: white; |
| | | } |
| | | } |
| | | } |
| | | .empty-padding { |
| | | padding-top: 65px; |
| | | } |
| | | } |
| | | .order-detl-list { |
| | | overflow: hidden; |
| | | overflow-y: scroll; |
| | | height: 43vh; |
| | | padding: 0 15px; |
| | | } |
| | | |
| | | .el-card { |
| | | background: rgba(8,32,92, 0.5) !important; |
| | | } |
| | | |
| | | .bounce-enter-active { |
| | | animation: bounce-in 0.5s; |
| | | } |
| | | .bounce-leave-active { |
| | | animation: bounce-in 0.5s reverse; |
| | | } |
| | | @keyframes bounce-in { |
| | | 0% { |
| | | transform: scale(0); |
| | | } |
| | | 50% { |
| | | transform: scale(1.25); |
| | | } |
| | | 100% { |
| | | transform: scale(1); |
| | | } |
| | | } |
| | | |
| | | .el-input__inner { |
| | | background: rgba(8,32,92, 0.5) !important; |
| | | border: 0 !important; |
| | | height: unset !important; |
| | | line-height: 80px !important; |
| | | font-size: 30px !important; |
| | | color: white !important; |
| | | text-align: center !important; |
| | | } |
| | | |
| | | .el-dialog { |
| | | background: rgba(8,32,92, 0.9) !important; |
| | | } |
| | | |
| | | .el-row { |
| | | margin-bottom: 20px; |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | } |
| | | .el-col { |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .el-dialog__wrapper { |
| | | top: 0px !important; |
| | | } |
| | | |
| | | .talbe-matnr { |
| | | height: 26vh; |
| | | } |
| | | |
| | | .el-table { |
| | | background-color: unset !important; |
| | | color: white !important; |
| | | flex: 0.7 !important; |
| | | font-style: italic !important; |
| | | } |
| | | |
| | | .el-table::before { |
| | | height: 0px !important; |
| | | } |
| | | |
| | | .el-table .cell { |
| | | font-size: 23px !important; |
| | | color: white !important; |
| | | } |
| | | |
| | | .el-table tr { |
| | | background-color: unset !important; |
| | | } |
| | | |
| | | .el-table th.el-table__cell { |
| | | background-color: unset !important; |
| | | } |
| | | |
| | | /* 用来设置当前页面element全局table 选中某行时的背景色*/ |
| | | .el-table__body tr.current-row > td { |
| | | background-color: #92cbf1 !important; |
| | | color: #fff; |
| | | } |
| | | |
| | | /*鼠标移入某行时的背景色*/ |
| | | .el-table--enable-row-hover .el-table__body tr:hover > td { |
| | | background-color: #071539 !important; |
| | | /* color: #fff; */ |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | | |
| | | @media screen and (max-width: 1281px) { |
| | | #data-view { |
| | | .header-left-task { |
| | | .header-card { |
| | | margin: 5px;height: 90px; |
| | | padding: 5px; |
| | | |
| | | .header-card-label { |
| | | font-size: 18px; |
| | | padding: 5px; |
| | | } |
| | | |
| | | .header-card-val { |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .order-box-row { |
| | | width: 58vh; |
| | | height: 28vh; |
| | | |
| | | .order-box { |
| | | padding:0px 30px; |
| | | |
| | | .order-table { |
| | | width: 74vh; |
| | | padding-top: 65px; |
| | | height: 275px; |
| | | |
| | | .ship-order-list { |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | } |
| | | .empty-padding { |
| | | padding-top: 65px; |
| | | } |
| | | } |
| | | |
| | | |
| | | .talbe-matnr { |
| | | height: 20vh; |
| | | } |
| | | |
| | | .el-table .cell { |
| | | font-size: 16px !important; |
| | | } |
| | | |
| | | .pick-order-detl { |
| | | padding: 0 10px; |
| | | |
| | | .detl-box-border { |
| | | height: 39vh; |
| | | |
| | | .detl-box-padding { |
| | | height: 65px |
| | | } |
| | | |
| | | .order-detl-list { |
| | | height: 23vh; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .pick-wall { |
| | | padding: 60px 10px 10px 10px; |
| | | height: 45vh; |
| | | |
| | | .pick-wall-circle { |
| | | margin: 10px; |
| | | padding: unset; |
| | | background-color: #50bfff2e; |
| | | |
| | | .pick-wall-tip { |
| | | height: 20px; |
| | | width: 1px; |
| | | background: #03d3ec; |
| | | border-left: 5px solid #50bfff |
| | | } |
| | | } |
| | | .pick-wall-box { |
| | | .seed-bracket { |
| | | background: gainsboro; |
| | | margin: 8px; |
| | | height: 65px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div id="ranking-board"> |
| | | <div class="ranking-board-title">巡查上报记录数量</div> |
| | | <dv-scroll-ranking-board :config="config" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'RankingBoard', |
| | | data () { |
| | | return { |
| | | config: { |
| | | data: [ |
| | | { |
| | | name: '日常养护', |
| | | value: 55 |
| | | }, |
| | | { |
| | | name: '交通事故', |
| | | value: 120 |
| | | }, |
| | | { |
| | | name: '路面', |
| | | value: 78 |
| | | }, |
| | | { |
| | | name: '桥通', |
| | | value: 66 |
| | | }, |
| | | { |
| | | name: '计日工', |
| | | value: 80 |
| | | }, |
| | | { |
| | | name: '路基', |
| | | value: 45 |
| | | }, |
| | | { |
| | | name: '交安设施', |
| | | value: 29 |
| | | }, |
| | | { |
| | | name: '除雪', |
| | | value: 29 |
| | | }, |
| | | { |
| | | name: '绿化', |
| | | value: 29 |
| | | } |
| | | ], |
| | | rowNum: 9 |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | #ranking-board { |
| | | width: 20%; |
| | | box-shadow: 0 0 3px blue; |
| | | display: flex; |
| | | flex-direction: column; |
| | | background-color: rgba(6, 30, 93, 0.5); |
| | | border-top: 2px solid rgba(1, 153, 209, .5); |
| | | box-sizing: border-box; |
| | | padding: 0px 30px; |
| | | |
| | | .ranking-board-title { |
| | | font-weight: bold; |
| | | height: 50px; |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 20px; |
| | | } |
| | | |
| | | .dv-scroll-ranking-board { |
| | | flex: 1; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div id="rose-chart"> |
| | | <div class="rose-chart-title">累计计量资金分布</div> |
| | | <dv-charts :option="option" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'RoseChart', |
| | | data () { |
| | | return { |
| | | option: {} |
| | | } |
| | | }, |
| | | methods: { |
| | | createData () { |
| | | const { randomExtend } = this |
| | | |
| | | this.option = { |
| | | series: [ |
| | | { |
| | | type: 'pie', |
| | | radius: '50%', |
| | | roseSort: false, |
| | | data: [ |
| | | { name: '路基', value: randomExtend(40, 70) }, |
| | | { name: '交安设施', value: randomExtend(20, 30) }, |
| | | { name: '日常养护', value: randomExtend(10, 50) }, |
| | | { name: '桥通', value: randomExtend(5, 20) }, |
| | | { name: '交通事故', value: randomExtend(40, 50) }, |
| | | { name: '路面', value: randomExtend(20, 30) }, |
| | | { name: '绿化', value: randomExtend(5, 10) }, |
| | | { name: '计日工', value: randomExtend(20, 35) }, |
| | | { name: '除雪', value: randomExtend(5, 10) } |
| | | ], |
| | | insideLabel: { |
| | | show: false |
| | | }, |
| | | outsideLabel: { |
| | | formatter: '{name} {percent}%', |
| | | labelLineEndLength: 20, |
| | | style: { |
| | | fill: '#fff' |
| | | }, |
| | | labelLineStyle: { |
| | | stroke: '#fff' |
| | | } |
| | | }, |
| | | roseType: true |
| | | } |
| | | ], |
| | | color: ['#da2f00', '#fa3600', '#ff4411', '#ff724c', '#541200', '#801b00', '#a02200', '#5d1400', '#b72700'] |
| | | } |
| | | }, |
| | | randomExtend (minNum, maxNum) { |
| | | if (arguments.length === 1) { |
| | | return parseInt(Math.random() * minNum + 1, 10) |
| | | } else { |
| | | return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10) |
| | | } |
| | | } |
| | | }, |
| | | mounted () { |
| | | const { createData } = this |
| | | |
| | | createData() |
| | | |
| | | setInterval(createData, 30000) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | #rose-chart { |
| | | width: 30%; |
| | | height: 100%; |
| | | background-color: rgba(6, 30, 93, 0.5); |
| | | border-top: 2px solid rgba(1, 153, 209, .5); |
| | | box-sizing: border-box; |
| | | |
| | | .rose-chart-title { |
| | | height: 50px; |
| | | font-weight: bold; |
| | | text-indent: 20px; |
| | | font-size: 20px; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .dv-charts-container { |
| | | height: calc(~"100% - 50px"); |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div id="scroll-board"> |
| | | <dv-scroll-board :config="config" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'ScrollBoard', |
| | | data () { |
| | | return { |
| | | config: { |
| | | header: ['时间', '病害信息', '数量', '标段'], |
| | | data: [ |
| | | ['2019-07-01 19:25:00', '路面危害-松散', '5', 'xxxxxxx'], |
| | | ['2019-07-02 17:25:00', '路面危害-路面油污清理', '13', 'xxxxxxx'], |
| | | ['2019-07-03 16:25:00', '交安设施-交通标志牌结构', '6', 'xxxxxxx'], |
| | | ['2019-07-04 15:25:00', '路基危害-防尘网', '2', 'xxxxxxx'], |
| | | ['2019-07-05 14:25:00', '交安设施-交通标志牌结构', '1', 'xxxxxxx'], |
| | | ['2019-07-06 13:25:00', '路面危害-松散', '3', 'xxxxxxx'], |
| | | ['2019-07-07 12:25:00', '路基危害-防尘网', '4', 'xxxxxxx'], |
| | | ['2019-07-08 11:25:00', '路面危害-路面油污清理', '2', 'xxxxxxx'], |
| | | ['2019-07-09 10:25:00', '交安设施-交通标志牌结构', '5', 'xxxxxxx'], |
| | | ['2019-07-10 09:25:00', '路基危害-防尘网', '3', 'xxxxxxx'] |
| | | ], |
| | | index: true, |
| | | columnWidth: [50, 170, 300], |
| | | align: ['center'], |
| | | rowNum: 7, |
| | | headerBGC: '#1981f6', |
| | | headerHeight: 45, |
| | | oddRowBGC: 'rgba(0, 44, 81, 0.8)', |
| | | evenRowBGC: 'rgba(10, 29, 50, 0.8)' |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | #scroll-board { |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | margin: 10px; |
| | | height: 100%; |
| | | overflow: hidden; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div id="top-header"> |
| | | <dv-decoration-8 class="header-left-decoration" /> |
| | | <dv-decoration-5 class="header-center-decoration" /> |
| | | <dv-decoration-8 class="header-right-decoration" :reverse="true" /> |
| | | <div class="center-title" @click="fullScreen">波次播种任务系统</div> |
| | | <!-- <el-button class="center-title" @click="handleFullScreen">全屏</el-button>--> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'TopHeader', |
| | | |
| | | data() { |
| | | return { |
| | | |
| | | } |
| | | }, |
| | | |
| | | methods: { |
| | | // fullScreen() { |
| | | // let element = document.documentElement |
| | | // element.requestFullscreen() |
| | | // }, |
| | | handleFullScreen() { |
| | | const element = document.documentElement |
| | | if (this.fullscreen) { |
| | | if (document.exitFullscreen) { |
| | | document.exitFullscreen() |
| | | } else if (document.webkitCancelFullScreen) { |
| | | document.webkitCancelFullScreen() |
| | | } else if (document.mozCancelFullScreen) { |
| | | document.mozCancelFullScreen() |
| | | } else if (document.msExitFullscreen) { |
| | | document.msExitFullscreen() |
| | | } |
| | | } else { |
| | | if (element.requestFullscreen) { |
| | | element.requestFullscreen() |
| | | } else if (element.webkitRequestFullScreen) { |
| | | element.webkitRequestFullScreen() |
| | | } else if (element.mozRequestFullScreen) { |
| | | element.mozRequestFullScreen() |
| | | } else if (element.msRequestFullscreen) { |
| | | element.msRequestFullscreen() |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | @media screen and (max-width: 1920px){ |
| | | #top-header { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100px; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | flex-shrink: 0; |
| | | |
| | | .header-center-decoration { |
| | | width: 40%; |
| | | height: 60px; |
| | | margin-top: 30px; |
| | | } |
| | | |
| | | .header-left-decoration, .header-right-decoration { |
| | | width: 25%; |
| | | height: 60px; |
| | | } |
| | | |
| | | .center-title { |
| | | position: absolute; |
| | | font-size: 30px; |
| | | font-weight: bold; |
| | | left: 50%; |
| | | top: 15px; |
| | | transform: translateX(-50%); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @media only screen and (max-width: 1280px){ |
| | | #top-header { |
| | | |
| | | .center-title { |
| | | font-size: 24px; |
| | | font-weight: bold; |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div id="water-level-chart"> |
| | | <div class="water-level-chart-title">计划资金累计完成情况</div> |
| | | |
| | | <div class="water-level-chart-details"> |
| | | 累计完成<span>235,680</span>元 |
| | | </div> |
| | | |
| | | <div class="chart-container"> |
| | | <dv-water-level-pond :config="config" /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: 'WaterLevelChart', |
| | | data () { |
| | | return { |
| | | config: { |
| | | data: [45], |
| | | shape: 'round', |
| | | waveHeight: 25, |
| | | waveNum: 2 |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style lang="less"> |
| | | #water-level-chart { |
| | | width: 20%; |
| | | box-sizing: border-box; |
| | | margin-left: 20px; |
| | | background-color: rgba(6, 30, 93, 0.5); |
| | | border-top: 2px solid rgba(1, 153, 209, .5); |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .water-level-chart-title { |
| | | font-weight: bold; |
| | | height: 50px; |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 20px; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .water-level-chart-details { |
| | | height: 15%; |
| | | display: flex; |
| | | justify-content: center; |
| | | font-size: 17px; |
| | | align-items: flex-end; |
| | | |
| | | span { |
| | | font-size: 35px; |
| | | font-weight: bold; |
| | | color: #58a1ff; |
| | | margin: 0 5px; |
| | | margin-bottom: -5px; |
| | | } |
| | | } |
| | | |
| | | .chart-container { |
| | | flex: 1; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | } |
| | | |
| | | .dv-water-pond-level { |
| | | max-width: 90%; |
| | | width: 200px; |
| | | height: 200px; |
| | | border: 10px solid #19c3eb; |
| | | border-radius: 50%; |
| | | |
| | | ellipse { |
| | | stroke: transparent !important; |
| | | } |
| | | |
| | | text { |
| | | font-size: 40px; |
| | | } |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | import Vue from 'vue' |
| | | import App from './App.vue' |
| | | import Ajax from './utils/ajax.js' |
| | | |
| | | import './assets/common.less' |
| | | |
| | | import dataV from '@jiaminghi/data-view' |
| | | import ElementUI from 'element-ui' |
| | | import 'element-ui/lib/theme-chalk/index.css' |
| | | |
| | | Vue.config.productionTip = false |
| | | Vue.prototype.$ajax = Ajax |
| | | Vue.use(ElementUI) |
| | | Vue.use(dataV) |
| | | |
| | | global.$ajax = Ajax |
| | | |
| | | new Vue({ |
| | | render: h => h(App) |
| | | }).$mount('#app') |
New file |
| | |
| | | /* eslint-disable */ |
| | | import axios from 'axios' |
| | | import {MessageBox, Message} from 'element-ui' |
| | | import utilVue from '../utils/utilVue.js' |
| | | |
| | | const baseUrl = process.env.VUE_APP_BASE_API |
| | | // create an axios instance |
| | | const service = axios.create({ |
| | | baseURL: baseUrl + 'wms/', // url = base url + request url |
| | | timeout: 120000 // request timeout |
| | | }) |
| | | |
| | | // request interceptor |
| | | service.interceptors.request.use( |
| | | (config) => { |
| | | // do something before request is sent |
| | | |
| | | // if (store.getters.currentUser) { |
| | | // // let each request carry token |
| | | // // ['X-Token'] is a custom headers key |
| | | // // please modify it according to the actual situation |
| | | // config.headers['Authorization'] = sessionStorage.getItem('Authorization') |
| | | // // config.headers['warehouseId'] = store.getters.currentWarehouse.id |
| | | // // config.headers['requestType'] = 'spdpc' |
| | | // } |
| | | if (config.method != 'get' && window.appendParam && config.data) { |
| | | Object.keys(window.appendParam).forEach((key) => { |
| | | if (Object.prototype.hasOwnProperty.call(window.appendParam, key)) { |
| | | if (window.appendParam[key]) { |
| | | if (Array.isArray(config.data)) { |
| | | config.data.forEach(data => { |
| | | if (typeof data == 'object') { |
| | | data[key] = window.appendParam[key] |
| | | } |
| | | }) |
| | | } else { |
| | | config.data[key] = window.appendParam[key] |
| | | } |
| | | } |
| | | } |
| | | }) |
| | | window.appendParam = null |
| | | } |
| | | return config |
| | | }, |
| | | (error) => { |
| | | return Promise.reject(error) |
| | | } |
| | | ) |
| | | |
| | | const download = (resp) => { |
| | | //这里res.data是返回的blob对象 |
| | | var blob = new Blob([resp.data], {type: resp.headers['content-type']}); |
| | | |
| | | // 自定义响应头 |
| | | let fileName = resp.headers['content-filename'] && decodeURIComponent(resp.headers['content-filename']) |
| | | if (fileName === undefined || fileName === null || fileName === "") { |
| | | fileName = new Date().getTime() + '.xlsx' |
| | | } |
| | | |
| | | if (window.navigator.msSaveOrOpenBlob) { |
| | | // 如果是IE浏览器 |
| | | navigator.msSaveBlob(blob, fileName);//filename文件名包括扩展名,下载路径为浏览器默认路径 |
| | | return |
| | | } |
| | | |
| | | // chrome、Firefox |
| | | var downloadElement = document.createElement('a'); |
| | | var href = window.URL.createObjectURL(blob); //创建下载的链接 |
| | | downloadElement.href = href; |
| | | downloadElement.download = fileName |
| | | document.body.appendChild(downloadElement); |
| | | downloadElement.click(); //点击下载 |
| | | document.body.removeChild(downloadElement); //下载完成移除元素a |
| | | window.URL.revokeObjectURL(href); //释放掉blob对象 |
| | | } |
| | | |
| | | // response interceptor |
| | | service.interceptors.response.use( |
| | | /** |
| | | * If you want to get http information such as headers or status |
| | | * Please return response => response |
| | | */ |
| | | |
| | | /** |
| | | * Determine the request status by custom code |
| | | * Here is just an example |
| | | * You can also judge the status by HTTP Status Code |
| | | */ |
| | | (response) => { |
| | | let {headers, data} = response |
| | | |
| | | // 处理文件下载 |
| | | let contentType = headers['content-type'] |
| | | if (headers && contentType |
| | | && (contentType.indexOf('application/x-msdownload') != -1 |
| | | || contentType.indexOf('application/octet-stream') != -1 |
| | | || contentType.indexOf('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') != -1)) { |
| | | download(response) |
| | | return response |
| | | } |
| | | |
| | | if (contentType && contentType.indexOf('application/json') == -1) { |
| | | return response |
| | | } |
| | | |
| | | let isValidexception = headers && '1' == headers.validexception |
| | | |
| | | const res = data |
| | | // if the custom code is not 0, it is judged as an error. |
| | | if (res.success) { |
| | | return res |
| | | } |
| | | utilVue.loadHide() |
| | | if (res.success == undefined) { //如果未定义,直接返回 |
| | | return res |
| | | } |
| | | |
| | | Message({ |
| | | message: '<div class="el-notification__content ">'+res.msg || 'Error'+'</div>', |
| | | duration: 5000, |
| | | dangerouslyUseHTMLString: true, |
| | | iconClass: isValidexception ? 'el-notification__icon el-icon-warning' : 'el-notification__icon el-icon-error', |
| | | customClass: isValidexception ? 'warn-ajax' : 'error-ajax', |
| | | showClose: true, |
| | | showIcon: true, |
| | | offset: 1 |
| | | }) |
| | | |
| | | //下面功能尚未实现,暂时注释掉 |
| | | // return Promise.reject(new Error(res.msg || 'Error')) |
| | | // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; |
| | | if (res.code === 50008 || res.code === 50012 || res.code === 50014) { |
| | | // to re-login |
| | | // MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { |
| | | // confirmButtonText: 'Re-Login', |
| | | // cancelButtonText: 'Cancel', |
| | | // type: 'warning' |
| | | // }).then(() => { |
| | | // store.dispatch('user/resetToken').then(() => { |
| | | // location.reload() |
| | | // }) |
| | | // }) |
| | | } |
| | | return res |
| | | // return Promise.reject(new Error(res.msg || 'Error')) |
| | | }, |
| | | (error) => { |
| | | utilVue.loadHide() |
| | | let response = error?error.response:null |
| | | let status = response?response.status:null |
| | | let data = response?response.data:null |
| | | let isValidexception = response.headers && '1' == response.headers.validexception |
| | | if (data && data.data && data.data.needLogin) { |
| | | try { |
| | | MessageBox.close() |
| | | }catch (e) { |
| | | |
| | | } |
| | | MessageBox.alert('会话超时,请重新登录!', '系统提示', { |
| | | confirmButtonText: '确定', |
| | | type: 'warning', |
| | | callback: action => { |
| | | // router.push('/login', () => { |
| | | // // Message.error(error.response.data.msg) |
| | | // location.reload() |
| | | // }) |
| | | } |
| | | }) |
| | | |
| | | return Promise.reject(error) |
| | | } |
| | | let msg='未知异常' |
| | | if(!status){ |
| | | msg= '网络连接异常,请检查本地网络是否连接' |
| | | }else if(status == 500){ |
| | | if(response.data.msg){ |
| | | msg= response.data.msg |
| | | }else if(response.data.message){ |
| | | msg= response.data.message |
| | | if(msg.indexOf('服务器异常') == -1) msg='服务器异常,原因:'+msg |
| | | }else if(typeof(response.data) == 'string' && response.data.indexOf('Proxy error') != -1){ |
| | | msg= '服务器暂时无法访问,请稍候重试' |
| | | } |
| | | }else if(status == 502){ |
| | | msg= '代理服务器暂时不可以使用,请稍候重试' |
| | | } |
| | | Message({ |
| | | message: '<div class="el-notification__content ">'+msg+'</div>', |
| | | duration: 5000, |
| | | dangerouslyUseHTMLString: true, |
| | | iconClass: isValidexception ? 'el-notification__icon el-icon-warning' : 'el-notification__icon el-icon-error', |
| | | customClass: isValidexception ? 'warn-ajax' : 'error-ajax', |
| | | showClose: true, |
| | | showIcon: true, |
| | | offset: 1 |
| | | }) |
| | | return Promise.reject(error) |
| | | } |
| | | ) |
| | | |
| | | export default service |
New file |
| | |
| | | import jsPDF from 'jspdf' |
| | | import html2canvas from 'html2canvas' |
| | | |
| | | /* |
| | | * 使用说明 |
| | | * ele:需要导出pdf的容器元素(dom节点 不是id) |
| | | * pdfFileName: 导出文件的名字 通过调用outPutPdfFn方法也可传参数改变 |
| | | * splitClassName: 避免分段截断的类名 当pdf有多页时需要传入此参数 , 避免pdf分页时截断元素 如表格<tr class="itemClass"></tr> |
| | | * 调用方式 先 let pdf = new PdfLoader(ele, 'pdf' ,'itemClass'); |
| | | * 若想改变pdf名称 pdf.outPutPdfFn(fileName); outPutPdfFn方法返回一个promise 可以使用then方法处理pdf生成后的逻辑 |
| | | * */ |
| | | class PdfLoader { |
| | | constructor (ele, pdfFileName, splitClassName) { |
| | | this.ele = ele |
| | | this.pdfFileName = pdfFileName |
| | | this.splitClassName = splitClassName || '' |
| | | this.A4_WIDTH = 841.89 |
| | | this.A4_HEIGHT = 595.28 |
| | | } |
| | | |
| | | async getPDF (resolve) { |
| | | const ele = this.ele |
| | | const pdfFileName = this.pdfFileName |
| | | const eleW = ele.offsetWidth // 获得该容器的宽 |
| | | const eleH = ele.scrollHeight // 获得该容器的高 |
| | | const eleOffsetTop = ele.offsetTop // 获得该容器到文档顶部的距离 |
| | | const eleOffsetLeft = ele.offsetLeft // 获得该容器到文档最左的距离 |
| | | window.pageYoffset = 0 |
| | | document.documentElement.scrollTop = 0 |
| | | document.body.scrollTop = 0 |
| | | const canvas = document.createElement('canvas') |
| | | let abs = 0 |
| | | // eslint-disable-next-line camelcase |
| | | const win_in = document.documentElement.clientWidth || document.body.clientWidth // 获得当前可视窗口的宽度(不包含滚动条) |
| | | // eslint-disable-next-line camelcase |
| | | const win_out = window.innerWidth // 获得当前窗口的宽度(包含滚动条) |
| | | // eslint-disable-next-line camelcase |
| | | if (win_out > win_in) { |
| | | // eslint-disable-next-line camelcase |
| | | abs = (win_out - win_in) / 2 // 获得滚动条宽度的一半 |
| | | } |
| | | canvas.width = eleW * 2 // 将画布宽&&高放大两倍 |
| | | canvas.height = eleH * 2 |
| | | const context = canvas.getContext('2d') |
| | | context.scale(2, 2) // 增强图片清晰度 |
| | | context.translate(-eleOffsetLeft - abs, -eleOffsetTop) |
| | | ele.style.height = ele.scrollHeight + 'px' // 获取元素的滚动高度,用于截取被滚动条隐藏的部分 |
| | | html2canvas(ele, { |
| | | backgroundColor: null, |
| | | allowTaint: false, |
| | | dpi: window.devicePixelRatio * 4, |
| | | width: ele.width, |
| | | height: ele.width, |
| | | windowWidth: ele.scrollWidth, |
| | | scale: 4, // 按比例增加分辨率 |
| | | useCORS: true // 允许canvas画布内可以跨域请求外部链接图片, 允许跨域请求。 |
| | | }).then(async (canvas) => { |
| | | const contentWidth = canvas.width |
| | | const contentHeight = canvas.height |
| | | ele.style.height = ele.clientHeight + 'px' // 获取元素的实际高度,不包括滚动条隐藏的部分 |
| | | // 一页pdf显示html页面生成的canvas高度; |
| | | const pageHeight = (contentWidth / this.A4_WIDTH) * this.A4_HEIGHT // 这样写的目的在于保持宽高比例一致 pageHeight/canvas.width = a4纸高度/a4纸宽度// 宽度和canvas.width保持一致 |
| | | // 未生成pdf的html页面高度 |
| | | let leftHeight = contentHeight |
| | | // 页面偏移 |
| | | let position = 0 |
| | | // a4纸的尺寸[595,842],单位像素,html页面生成的canvas在pdf中图片的宽高 |
| | | const imgWidth = this.A4_WIDTH - 10 // -10为了页面有右边距 |
| | | const imgHeight = (this.A4_WIDTH / contentWidth) * contentHeight |
| | | const pageData = canvas.toDataURL('image/jpeg', 1.0) |
| | | const pdf = jsPDF('l', 'pt', 'a4') |
| | | // 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89) |
| | | // 当内容未超过pdf一页显示的范围,无需分页 |
| | | if (leftHeight < pageHeight) { |
| | | // 在pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置在pdf中显示; |
| | | pdf.addImage(pageData, 'JPEG', 5, 0, imgWidth, imgHeight) |
| | | // pdf.addImage(pageData, 'JPEG', 20, 40, imgWidth, imgHeight); |
| | | } else { |
| | | // 分页 |
| | | while (leftHeight > 0) { |
| | | pdf.addImage( |
| | | pageData, |
| | | 'JPEG', |
| | | 5, |
| | | position, |
| | | imgWidth, |
| | | imgHeight |
| | | ) |
| | | leftHeight -= pageHeight |
| | | position -= this.A4_HEIGHT |
| | | // 避免添加空白页 |
| | | if (leftHeight > 0) { |
| | | pdf.addPage() |
| | | } |
| | | } |
| | | } |
| | | // pdf.save(pdfFileName + '.pdf', { returnPromise: true }).then(() => { |
| | | // // 去除添加的空div 防止页面混乱 |
| | | // const doms = document.querySelectorAll('.emptyDiv') |
| | | // for (let i = 0; i < doms.length; i++) { |
| | | // doms[i].remove() |
| | | // } |
| | | // }) |
| | | let pdfData = pdf.output('datauristring') |
| | | this.showPreview(pdfData) |
| | | |
| | | this.ele.style.height = '' |
| | | resolve() |
| | | }) |
| | | } |
| | | |
| | | // 此方法是防止(图表之类)内容因为A4纸张问题被截断 |
| | | async outPutPdfFn (pdfFileName) { |
| | | return new Promise((resolve, reject) => { |
| | | this.ele.style.height = 'initial' |
| | | // eslint-disable-next-line no-unused-expressions |
| | | pdfFileName ? (this.pdfFileName = pdfFileName) : null |
| | | const target = this.ele |
| | | const pageHeight = (target.scrollWidth / this.A4_WIDTH) * this.A4_HEIGHT |
| | | if (this.splitClassName !== '' || this.splitClassName != null) { |
| | | // 获取分割dom,此处为class类名为item的dom |
| | | const domList = document.getElementsByClassName(this.splitClassName) |
| | | // 进行分割操作,当dom内容已超出a4的高度,则将该dom前插入一个空dom,把他挤下去,分割 |
| | | let pageNum = 1 // pdf页数 |
| | | const eleBounding = this.ele.getBoundingClientRect() |
| | | for (let i = 0; i < domList.length; i++) { |
| | | const node = domList[i] |
| | | const bound = node.getBoundingClientRect() |
| | | const offset2Ele = bound.top - eleBounding.top |
| | | const currentPage = Math.ceil( |
| | | (bound.bottom - eleBounding.top) / pageHeight |
| | | ) // 当前元素应该在哪一页 |
| | | if (pageNum < currentPage) { |
| | | pageNum++ |
| | | const divParent = domList[i].parentNode // 获取该div的父节点 |
| | | const newNode = document.createElement('div') |
| | | newNode.className = 'emptyDiv' |
| | | newNode.style.background = 'white' |
| | | newNode.style.height = |
| | | pageHeight * (pageNum - 1) - offset2Ele + 30 + 'px' // +30为了在换下一页时有顶部的边距 |
| | | newNode.style.width = '100%' |
| | | divParent.insertBefore(newNode, node) // 在每一个节点前面插入一个空的新节点,防止内容被分割截断 |
| | | } |
| | | } |
| | | } |
| | | // 异步函数,导出成功后处理交互 |
| | | this.getPDF(resolve, reject) |
| | | }) |
| | | } |
| | | |
| | | async showPreview (pdfData) { |
| | | // const pdfPreview = this.$refs.pdfPreview |
| | | const iframe = document.createElement('iframe') |
| | | iframe.src = pdfData |
| | | iframe.style.width = '100%' |
| | | iframe.style.height = '600px' |
| | | |
| | | this.ele.innerHTML = '' |
| | | this.ele.appendChild(iframe) |
| | | // let loction = window.location.href |
| | | // let url = loction + 'pdf/' + this.pdfFileName + '.pdf' |
| | | |
| | | // // 这一步是关键,使用window.URL.createObjectURL把blob数据转为本地URL |
| | | // let url = window.URL.createObjectURL(new Blob([pdfData])) |
| | | // let content = `/pdfjs/viewer.html?file=${url}` |
| | | // window.open(content, '_blank') |
| | | |
| | | // let msg = open('cnrose', 'DisplayWindow', 'toolbar=no,,menubar=no,location=no,scrollbars=no') |
| | | // msg.document.write('<HEAD><TITLE>sunset</TITLE></HEAD>') |
| | | // msg.document.write('<CENTER>http://www.cjpfw.com/</CENTER>') |
| | | // console.log(msg.document.body) |
| | | // let iframe = msg.document.body.createElement('iframe') |
| | | // iframe.src = pdfData |
| | | // iframe.style.width = '100%' |
| | | // iframe.style.height = '600px' |
| | | // msg.document.write(iframe) |
| | | } |
| | | } |
| | | |
| | | export default PdfLoader |
New file |
| | |
| | | /* eslint-disable */ |
| | | /** |
| | | * vue相关工具类 |
| | | */ |
| | | let loadSystem |
| | | import {Loading, Message} from 'element-ui' |
| | | const utilVue = { |
| | | /**显示系统遮罩层 |
| | | * @param isShow true:显示遮罩层 |
| | | * @Description:显示系统遮罩层 |
| | | */ |
| | | async loadShow(isShow,target, text){ |
| | | if(isShow != undefined && !isShow) return; |
| | | if(!target) target= document.body |
| | | if(loadSystem && await loadSystem.close()){ |
| | | loadSystem.show() |
| | | } |
| | | |
| | | loadSystem=await Loading.service({ fullscreen: true, text: text ? text : '请稍候', |
| | | spinner: 'spinner-user', background: 'rgba(0, 0, 0, 0)',customClass: 'spinner-custom', target: target |
| | | }); |
| | | |
| | | }, |
| | | |
| | | //隐藏系统遮罩层 |
| | | async loadHide(){ |
| | | if(loadSystem) await loadSystem.close(); |
| | | }, |
| | | |
| | | //字符串转换成json对象,单层 |
| | | str2json(jsonStr){ |
| | | return JSON.parse(jsonStr); |
| | | }, |
| | | |
| | | //json对象转换成json字符串 |
| | | json2str(jsonOb){ |
| | | return JSON.stringify(jsonOb); |
| | | } |
| | | } |
| | | |
| | | export default utilVue |
New file |
| | |
| | | const port = 5555 // dev port |
| | | // eslint-disable-next-line import/order |
| | | // const VueLoaderPlugin = require('vue-loader/lib/plugin'); |
| | | let proxyApi = process.env.VUE_APP_BASE_API |
| | | |
| | | // let printApi = process.env.VUE_APP_PRINT_API |
| | | module.exports = { |
| | | transpileDependencies: ['@jiaminghi/data-view'], |
| | | publicPath: '/', |
| | | outputDir: 'dist', |
| | | assetsDir: 'static', |
| | | lintOnSave: false, |
| | | // lintOnSave: false, |
| | | productionSourceMap: false, |
| | | devServer: { |
| | | port, |
| | | open: false, |
| | | overlay: { |
| | | warnings: true, |
| | | errors: true |
| | | }, |
| | | proxy: { |
| | | '/wms': { |
| | | target: proxyApi, // 对应自己的接口 |
| | | changeOrigin: true, |
| | | ws: true, |
| | | pathRewrite: { |
| | | '^/wms': '' |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |