@ -0,0 +1,5 @@ |
|||
node_modules |
|||
dist |
|||
.idea |
|||
.vscode/launch.json |
|||
|
@ -0,0 +1,16 @@ |
|||
module.exports = { |
|||
presets: [ |
|||
'@vue/cli-plugin-babel/preset' |
|||
], |
|||
"plugins": [ |
|||
[ |
|||
"import", |
|||
{ |
|||
"libraryName": "vant", |
|||
"libraryDirectory": "es", |
|||
"style": true |
|||
}, |
|||
"vant" |
|||
] |
|||
] |
|||
} |
@ -0,0 +1,66 @@ |
|||
{ |
|||
"name": "Report", |
|||
"version": "2.0.0", |
|||
"private": true, |
|||
"scripts": { |
|||
"dev": "vue-cli-service serve", |
|||
"serve": "vue-cli-service serve", |
|||
"build": "vue-cli-service build", |
|||
"lint": "vue-cli-service lint" |
|||
}, |
|||
"dependencies": { |
|||
"@jiaminghi/data-view": "^2.10.0", |
|||
"ag-grid-community": "^30.2.0", |
|||
"ag-grid-vue": "^30.2.0", |
|||
"axios": "^0.21.1", |
|||
"core-js": "^3.6.5", |
|||
"echarts": "^5.4.0", |
|||
"element-ui": "2.15.13", |
|||
"file-saver": "^2.0.2", |
|||
"js-cookie": "^3.0.1", |
|||
"postcss-px-to-viewport": "^1.1.1", |
|||
"quill": "^1.3.7", |
|||
"quill-emoji": "^0.2.0", |
|||
"svg-sprite-loader": "^6.0.11", |
|||
"vue": "^2.6.11", |
|||
"vue-json-excel": "^0.3.0", |
|||
"vue-property-decorator": "^8.0.0", |
|||
"vue-quill-editor": "^3.0.6", |
|||
"vue-router": "^3.2.0", |
|||
"vue-video-player": "^5.0.2", |
|||
"xlsx": "^0.16.0", |
|||
"xlsx-style": "^0.8.13" |
|||
}, |
|||
"devDependencies": { |
|||
"@vue/cli-plugin-babel": "~4.5.0", |
|||
"@vue/cli-plugin-eslint": "~4.5.0", |
|||
"@vue/cli-plugin-router": "^4.5.13", |
|||
"@vue/cli-service": "~4.5.0", |
|||
"babel-eslint": "^10.1.0", |
|||
"babel-plugin-import": "^1.13.3", |
|||
"eslint": "^6.7.2", |
|||
"eslint-plugin-vue": "^6.2.2", |
|||
"less-loader": "^7.3.0", |
|||
"script-loader": "^0.7.2", |
|||
"vue-template-compiler": "^2.6.11" |
|||
}, |
|||
"eslintConfig": { |
|||
"root": true, |
|||
"env": { |
|||
"node": true |
|||
}, |
|||
"extends": [ |
|||
"plugin:vue/essential", |
|||
"eslint:recommended" |
|||
], |
|||
"parserOptions": { |
|||
"parser": "babel-eslint" |
|||
}, |
|||
"rules": {} |
|||
}, |
|||
"browserslist": [ |
|||
"> 1%", |
|||
"last 2 versions", |
|||
"not dead" |
|||
] |
|||
} |
After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1 @@ |
|||
window.SITE_CONFIG['apiURL'] = 'http://dev.ccwin-in.com:60029' |
@ -0,0 +1,27 @@ |
|||
<!DOCTYPE html> |
|||
<html lang=""> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
|||
<!-- <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> --> |
|||
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0"> --> |
|||
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> --> |
|||
<!-- <meta name="x5-fullscreen" content="true"> --> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0"> |
|||
<!-- <meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1"> --> |
|||
<link rel="icon" href="<%= BASE_URL %>WMS.svg"> |
|||
<title><%= htmlWebpackPlugin.options.title %></title> |
|||
</head> |
|||
<body> |
|||
<script> |
|||
window.SITE_CONFIG = {}; |
|||
window.SITE_CONFIG['apiURL'] = '';// api请求地址 |
|||
</script> |
|||
<script src="./config.js"></script> |
|||
<noscript> |
|||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> 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> |
@ -0,0 +1,21 @@ |
|||
<template> |
|||
<div id="app"> |
|||
<router-view/> |
|||
</div> |
|||
</template> |
|||
|
|||
<style> |
|||
html, body { |
|||
margin: 0; |
|||
height: 100%; |
|||
} |
|||
|
|||
#app { |
|||
font-family: Avenir, Helvetica, Arial, sans-serif; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
color: #2c3e50; |
|||
height: 100%; |
|||
user-select: none; |
|||
} |
|||
</style> |
@ -0,0 +1,29 @@ |
|||
import axiosUtil from '@/utils/request' |
|||
let baseURL = window.SITE_CONFIG['apiURL'] |
|||
let procApi = baseURL + '/api/app/report-proc/execute-procedure-by-sql?procName=' |
|||
|
|||
// 通用获取页面数据
|
|||
export function getReportPageList(procName, data) { |
|||
return axiosUtil.ajax_post( |
|||
procApi+procName, |
|||
data |
|||
) |
|||
} |
|||
|
|||
// 获取物料
|
|||
export function getItemCodeList() { |
|||
return axiosUtil.ajax_post(procApi+'Proc_Zheng_InputWhere_ItemCode',{}) |
|||
} |
|||
|
|||
// 获取库位组
|
|||
export function getLocationGroupCodeList() { |
|||
return axiosUtil.ajax_post(procApi+'Proc_Zheng_InputWhere_LocationGroupCode',{}) |
|||
} |
|||
|
|||
// 获取状态
|
|||
export function getInventoryStatusList() { |
|||
return axiosUtil.ajax_post(procApi+'Proc_Zheng_InputWhere_InventoryBalance_Status',{}) |
|||
} |
|||
|
|||
|
|||
|
After Width: | Height: | Size: 715 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 135 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 6.7 KiB |
@ -0,0 +1,153 @@ |
|||
<template> |
|||
<AgGridVue |
|||
:style="`width: 100%; height: ${tableHeight}`" |
|||
class="ag-theme-alpine" |
|||
:columnDefs="columnDefs" |
|||
@grid-ready="onGridReady" |
|||
:defaultColDef="defaultColDef" |
|||
:suppressDragLeaveHidesColumns="true" |
|||
:columnResized="columnResized" |
|||
@filterChanged="onFloatingFilterChanged" |
|||
></AgGridVue> |
|||
</template> |
|||
<script> |
|||
import "ag-grid-community/styles/ag-grid.css"; |
|||
import "ag-grid-community/styles/ag-theme-alpine.css"; |
|||
import { AgGridVue } from 'ag-grid-vue'; |
|||
export default { |
|||
name: "AgTable", |
|||
components: { |
|||
AgGridVue |
|||
}, |
|||
props:{ |
|||
// 列数据 |
|||
columnDefs:{ |
|||
type: Array, |
|||
default: null |
|||
}, |
|||
// 底部汇总元素 |
|||
BottomFixedItem:{ |
|||
type:Array, |
|||
default:[] |
|||
}, |
|||
}, |
|||
data () { |
|||
return { |
|||
gridApi: null, |
|||
gridColumnApi: null, |
|||
defaultColDef: { |
|||
flex: 1, |
|||
filter: true, |
|||
sortable: true, |
|||
floatingFilter: true, |
|||
resizable:true, |
|||
cellClass:"cell-wrap-text", |
|||
headerClass: 'ag-header-center', |
|||
autoHeight:true |
|||
}, |
|||
tableHeight:null, |
|||
// pagination: true, //开启分页(前端分页) |
|||
// paginationAutoPageSize: true, //根据网页高度自动分页(前端分页) |
|||
}; |
|||
}, |
|||
mounted(){ |
|||
this.setTableHeight() |
|||
}, |
|||
methods: { |
|||
// 筛选后操作 |
|||
onFloatingFilterChanged(data){ |
|||
const allData = []; |
|||
data.api.forEachNodeAfterFilter(node => { |
|||
allData.push(node.data) |
|||
}); |
|||
this.setTableTotal(allData) |
|||
}, |
|||
// 自适应高度 |
|||
columnResized(event){ |
|||
if(event.finished){ |
|||
this.gridApi.resetRowHeights() |
|||
} |
|||
}, |
|||
// 总计 |
|||
setTableTotal(list) { |
|||
if(!this.BottomFixedItem || this.BottomFixedItem.length <= 0)return |
|||
let result = [{}] |
|||
this.BottomFixedItem.forEach(item=>{ |
|||
result[0][item] = 0 |
|||
}) |
|||
list.forEach((item,key) => { |
|||
for(let o in item){ |
|||
if(this.BottomFixedItem.indexOf(o) >= 0){ |
|||
result[0][o] += item[o] |
|||
} |
|||
} |
|||
}); |
|||
this.gridApi.setPinnedBottomRowData(result); |
|||
}, |
|||
// 设置表格高度 |
|||
setTableHeight(){ |
|||
let _headerH = document.getElementsByClassName('reportPageHeader')[0].clientHeight + 10 |
|||
this.tableHeight = `calc(100% - ${_headerH}px)` |
|||
}, |
|||
// 更新table值 |
|||
updateTableData(data){ |
|||
this.gridApi.setRowData(data) |
|||
this.setTableTotal(data) |
|||
this.gridApi.resetRowHeights(); |
|||
}, |
|||
// 加载agGrid |
|||
onGridReady(params) { |
|||
this.gridApi = params.api; |
|||
this.gridColumnApi = params.columnApi; |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
<style lang="less"> |
|||
.ag-theme-alpine{ |
|||
--ag-header-foreground-color: white; |
|||
--ag-header-background-color: #5a81b7; |
|||
--ag-header-cell-hover-background-color: #5a81b7; |
|||
--ag-header-cell-moving-background-color: #5a81b7; |
|||
|
|||
.ag-floating-filter-input .ag-input-field-input{ |
|||
color:#333 !important |
|||
} |
|||
|
|||
.ag-header-icon{ |
|||
color:#fff !important |
|||
} |
|||
|
|||
.cell-wrap-text{ |
|||
white-space:normal !important |
|||
} |
|||
|
|||
.ag-row-pinned{ |
|||
background:#5a81b7; |
|||
color:#fff; |
|||
font-weight:bold |
|||
} |
|||
|
|||
.ag-cell{ |
|||
line-height:unset; |
|||
display: flex; |
|||
align-items: center; |
|||
|
|||
&.rightAlign{ |
|||
justify-content: flex-end; |
|||
} |
|||
|
|||
&.centerAlign{ |
|||
justify-content: center; |
|||
} |
|||
} |
|||
|
|||
.ag-cell-value{ |
|||
overflow: unset; |
|||
text-overflow: unset; |
|||
word-break:break-all; |
|||
padding-top:5px; |
|||
padding-bottom:5px |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,85 @@ |
|||
<template> |
|||
<el-popover |
|||
placement="bottom" |
|||
trigger="click" |
|||
> |
|||
<ul class="columnFilterList"> |
|||
<li v-for="(item,index) in columnCopy" :key="index" @click="filterSelectClick(item)"> |
|||
<div class="iconContent" :class="{'isSelect':!item.hide}"> |
|||
<i class="el-icon-check" v-if="!item.hide"></i> |
|||
</div> |
|||
<div class="title">{{item.field}}</div> |
|||
</li> |
|||
</ul> |
|||
<el-button slot="reference" class="setBtn" size="small">字段设置</el-button> |
|||
</el-popover> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: "columnFilter", |
|||
props:{ |
|||
// 列数据 |
|||
columnList:{ |
|||
type: Array, |
|||
default: null |
|||
}, |
|||
}, |
|||
data () { |
|||
return { |
|||
columnCopy:null |
|||
}; |
|||
}, |
|||
mounted(){ |
|||
// this.columnCopy = JSON.parse(JSON.stringify(this.columnList)) |
|||
this.columnCopy = [] |
|||
this.columnList.forEach(item=>{ |
|||
let _item = JSON.parse(JSON.stringify(item)) |
|||
if(item.hide){ |
|||
_item.hide = true |
|||
}else{ |
|||
_item.hide = false |
|||
} |
|||
this.columnCopy.push(_item) |
|||
}) |
|||
}, |
|||
methods: { |
|||
filterSelectClick(data){ |
|||
this.columnCopy.forEach(item => { |
|||
if(item.field == data.field){ |
|||
item.hide = !item.hide |
|||
} |
|||
}); |
|||
this.$emit("columnFliterCallback",this.columnCopy) |
|||
} |
|||
}, |
|||
}; |
|||
</script> |
|||
<style scope lang="less"> |
|||
.columnFilterList{ |
|||
margin:0; |
|||
padding:0; |
|||
|
|||
li{ |
|||
display:flex; |
|||
padding:10px 5px; |
|||
cursor:pointer; |
|||
|
|||
.iconContent{ |
|||
width:18px; |
|||
height:18px; |
|||
border-radius:50%; |
|||
border:#ddd solid 1px; |
|||
margin-right:10px; |
|||
|
|||
&.isSelect{ |
|||
background:#409eff; |
|||
color:#fff; |
|||
text-align:center; |
|||
line-height:18px; |
|||
border-color:#409eff |
|||
} |
|||
|
|||
} |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,126 @@ |
|||
<template> |
|||
<div><el-button @click="exportExcel" size="small" type="warning">导出数据2</el-button></div> |
|||
</template> |
|||
<script> |
|||
import XLSX from "xlsx"; |
|||
import XLSXS from "xlsx-style"; |
|||
import FileSaver from "file-saver"; |
|||
export default { |
|||
name: "exportExcel", |
|||
data () { |
|||
return { |
|||
|
|||
}; |
|||
}, |
|||
methods:{ |
|||
s2ab(s){ |
|||
var buf = new ArrayBuffer(s.length); |
|||
var view = new Uint8Array(buf); |
|||
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff; |
|||
return buf; |
|||
}, |
|||
exportExcel(){ |
|||
// 需要导出的数据 |
|||
let excelData = [ |
|||
["幼儿园课表", null, null, null], // 标题 |
|||
["序号", "课程名称", "教师名称", "上课地点"], // 表头 |
|||
["11.1234", "11,211.1234", "11.1234", "操场"], |
|||
["11.1234", "11,211.1234", "11.1234", "操场"], |
|||
["11.1234", "11,211.1234", "11.1234", "操场"], |
|||
["11.1234", "11,211.1234", "11.1234", "操场"], |
|||
["11.1234", "11,211.1234", "11.1234", "操场"], |
|||
]; |
|||
|
|||
// 导出的excel文件名 |
|||
const filename = "幼儿园课程表.xlsx"; |
|||
|
|||
// Excel第一个sheet的名称 |
|||
const ws_name = "Sheet1"; |
|||
const wb = XLSX.utils.book_new(); |
|||
const ws = XLSX.utils.aoa_to_sheet(excelData); |
|||
XLSX.utils.book_append_sheet(wb, ws, ws_name); // 将数据添加到工作薄 |
|||
|
|||
// 设置标题行单元格合并 |
|||
// s即start, e即end, r即row, c即column |
|||
// 合并从--0行0列开始,到0行3列 |
|||
ws["!merges"] = [{ s: { r: 0, c: 0 }, e: { r: 0, c: 3 } }]; |
|||
|
|||
// 设置单元格宽度 |
|||
ws["!cols"] = [ |
|||
{ |
|||
wpx: 40, |
|||
}, |
|||
{ |
|||
wpx: 100, |
|||
}, |
|||
{ |
|||
wpx: 100, |
|||
}, |
|||
{ |
|||
wpx: 100, |
|||
}, |
|||
]; |
|||
|
|||
/* |
|||
设置单元格其他样式 |
|||
这里列举一部分,其他样式大同小异,自行网上搜索 |
|||
*/ |
|||
|
|||
// 可以遍历全部单元格,进行样式设置 |
|||
console.log(91,ws) |
|||
for (let i in ws) { |
|||
if (i === "B2") { |
|||
ws[i].s = { |
|||
// 居中 |
|||
alignment: { |
|||
horizontal: "center", |
|||
vertical: "center", |
|||
wrapText: true, |
|||
}, |
|||
// 字体 |
|||
font: { |
|||
name: "仿宋", |
|||
sz: 14, |
|||
bold: true, |
|||
}, |
|||
}; |
|||
} else if (i === "B3") { |
|||
ws[i].s = { |
|||
// 单元格边框 |
|||
border: { |
|||
top: { |
|||
style: "thin", |
|||
}, |
|||
bottom: { |
|||
style: "thin", |
|||
}, |
|||
left: { |
|||
style: "thin", |
|||
}, |
|||
right: { |
|||
style: "thin", |
|||
}, |
|||
}, |
|||
}; |
|||
} |
|||
} |
|||
|
|||
// 导出Excel, 注意这里用到的是XLSXS对象 |
|||
let wbout = XLSXS.write(wb, { |
|||
bookType: "xlsx", |
|||
bookSST: false, |
|||
type: "binary", |
|||
}); |
|||
let _this = this |
|||
FileSaver.saveAs( |
|||
new Blob([_this.s2ab(wbout)], { |
|||
type: "application/octet-stream", |
|||
}), |
|||
filename |
|||
); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
<style> |
|||
</style> |
@ -0,0 +1,110 @@ |
|||
<template> |
|||
<div style="height:100%" class="reportPageTable" v-loading="pageLoading"> |
|||
<reportPageHeader |
|||
:columnList="columnList" |
|||
:downloadData="tableData" |
|||
@columnFliterCallback="columnFliterCallback" |
|||
:searchConfig="searchConfig" |
|||
:searchForm="searchForm" |
|||
:reportName="reportName" |
|||
@headerSearchHandle="headerSearchHandle" |
|||
:showReportTitle="showReportTitle" |
|||
></reportPageHeader> |
|||
<AgTable |
|||
ref="AgTable_Ref" |
|||
:columnDefs="columnList" |
|||
:BottomFixedItem="BottomFixedItem" |
|||
></AgTable> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import {getReportPageList} from '@/api/api' |
|||
import reportPageHeader from "@/components/reportPageHeader/index" |
|||
import AgTable from "@/components/AgTable/index" |
|||
import util from '@/utils/util' |
|||
|
|||
export default { |
|||
name: "reportPage", |
|||
components: { |
|||
AgTable, |
|||
reportPageHeader, |
|||
}, |
|||
props:{ |
|||
// 是否显示报表表头 |
|||
showReportTitle:{ |
|||
type:Boolean, |
|||
default: true |
|||
}, |
|||
// 列数据 |
|||
columnList:{ |
|||
type: Array, |
|||
default: null |
|||
}, |
|||
// 搜索条件配置 |
|||
searchConfig:{ |
|||
type: Array, |
|||
default: null |
|||
}, |
|||
// 搜索值 |
|||
searchForm:{ |
|||
type: Object, |
|||
default: null |
|||
}, |
|||
// 底部汇总配置 |
|||
BottomFixedItem:{ |
|||
type: Array, |
|||
default: null |
|||
}, |
|||
// 报表名称 |
|||
reportName:{ |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
// 方法名称 |
|||
procName:{ |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
}, |
|||
data () { |
|||
return { |
|||
// 导出数据 |
|||
tableData:[], |
|||
pageLoading:false |
|||
}; |
|||
}, |
|||
mounted(){ |
|||
this.getList() |
|||
}, |
|||
methods: { |
|||
// 字段设置点击事件 |
|||
columnFliterCallback(data){ |
|||
this.$refs.AgTable_Ref.gridApi.setColumnDefs(data) |
|||
}, |
|||
// 获取数据 |
|||
getList(){ |
|||
this.pageLoading = true |
|||
getReportPageList(this.procName,this.searchForm) |
|||
.then(res=>{ |
|||
this.$refs.AgTable_Ref.updateTableData(res) |
|||
this.tableData = res |
|||
this.pageLoading = false |
|||
}) |
|||
.catch(err=>{ |
|||
this.$refs.AgTable_Ref.updateTableData([]) |
|||
this.tableData = [] |
|||
this.pageLoading = false |
|||
}) |
|||
// fetch('https://www.ag-grid.com/example-assets/olympic-winners.json') |
|||
// .then((resp) => resp.json()) |
|||
// .then((data) => this.$refs.AgTable_Ref.updateTableData(data)) |
|||
// .then((data) => this.tableData = data) |
|||
}, |
|||
// 查询事件 |
|||
headerSearchHandle(data){ |
|||
this.getList() |
|||
} |
|||
}, |
|||
}; |
|||
</script> |
@ -0,0 +1,225 @@ |
|||
<template> |
|||
<div class="reportPageHeader"> |
|||
<!-- 搜索条件及按钮 --> |
|||
<div class="FormHeader"> |
|||
<!-- 左侧查询 --> |
|||
<div class="headerLeftSearch" v-if="searchConfig && searchConfig.length > 0"> |
|||
<el-form |
|||
:inline="true" |
|||
:model="searchForm" |
|||
:rules="searchRules" |
|||
size="small" |
|||
> |
|||
<el-form-item |
|||
v-for="(item,index) in searchConfig" |
|||
:label="item.label" |
|||
:key="index" |
|||
:prop="item.prop" |
|||
> |
|||
<!-- 输入框 --> |
|||
<el-input |
|||
v-if="item.type == 'input'" |
|||
v-model="searchForm[item.prop]" |
|||
:placeholder="'请输入'+item.label" |
|||
:clearable="true" |
|||
></el-input> |
|||
<!-- 下拉 --> |
|||
<el-select |
|||
v-if="item.type == 'select'" |
|||
v-model="searchForm[item.prop]" |
|||
filterable |
|||
:placeholder="'请选择'+item.label" |
|||
:clearable="true" |
|||
> |
|||
<el-option |
|||
v-for="op in item.options" |
|||
:key="op[item.opV] || op.value" |
|||
:label="op[item.opL] || op.label" |
|||
:value="op[item.opV] || op.value"> |
|||
</el-option> |
|||
</el-select> |
|||
<!-- 日期 --> |
|||
<el-date-picker |
|||
v-if="item.type == 'date'" |
|||
:clearable="true" |
|||
v-model="searchForm[item.prop]" |
|||
type="date" |
|||
placeholder="选择日期" |
|||
value-format="yyyy-MM-ddTHH:mm:ss" |
|||
></el-date-picker> |
|||
</el-form-item> |
|||
<el-form-item> |
|||
<el-button type="primary" @click="searchHandle">查询</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
<!-- 右侧按钮 --> |
|||
<div class="headerRightBtn"> |
|||
<downloadExcel |
|||
:data="downloadData" |
|||
:fields="downloadFields" |
|||
:name="reportName" |
|||
:title="downloadExcelTitle" |
|||
class="output-excel" |
|||
type="xls" |
|||
> |
|||
<el-button size="small" type="warning">导出数据</el-button> |
|||
</downloadExcel> |
|||
<exportExcel></exportExcel> |
|||
<columnFilter |
|||
:columnList="columnList" |
|||
@columnFliterCallback="columnFliterCallback" |
|||
></columnFilter> |
|||
</div> |
|||
</div> |
|||
<!-- 报表名称 --> |
|||
<div class="reportTitle" v-if="showReportTitle">{{reportName}}</div> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
import columnFilter from "@/components/columnFilter/index" |
|||
import exportExcel from "@/components/exportExcel/index" |
|||
import { |
|||
getItemCodeList, |
|||
getLocationGroupCodeList, |
|||
getInventoryStatusList |
|||
} from '@/api/api' |
|||
export default { |
|||
name: "reportPageHeader", |
|||
props:{ |
|||
// 是否显示报表表头 |
|||
showReportTitle:{ |
|||
type:Boolean, |
|||
default: true |
|||
}, |
|||
// 列数据 |
|||
columnList:{ |
|||
type: Array, |
|||
default: null |
|||
}, |
|||
// 报表名称 |
|||
reportName:{ |
|||
type: String, |
|||
default: '导出' |
|||
}, |
|||
// 查询条件 |
|||
searchConfig:{ |
|||
type: Array, |
|||
default:null |
|||
}, |
|||
// 查询条件必填项 |
|||
searchRules:{ |
|||
type: Object, |
|||
default:null |
|||
}, |
|||
// 搜索值 |
|||
searchForm:{ |
|||
type: Object, |
|||
default: null |
|||
}, |
|||
// 导出数据 |
|||
downloadData:{ |
|||
type: Array, |
|||
default: null |
|||
}, |
|||
}, |
|||
components: { |
|||
columnFilter, |
|||
exportExcel |
|||
}, |
|||
data () { |
|||
return { |
|||
downloadFields:{},//导出列 |
|||
}; |
|||
}, |
|||
mounted(){ |
|||
this.initDownloadFields() |
|||
this.initSearchConfig() |
|||
}, |
|||
methods: { |
|||
initSearchConfig(){ |
|||
this.searchConfig.forEach(item=>{ |
|||
if(item.type == 'select' && item.optionsProc){ |
|||
// 物料 |
|||
if(item.optionsProc == 'itemCode'){ |
|||
getItemCodeList().then(res=>{ |
|||
item.options = res |
|||
item.opL="ItemCode" |
|||
item.opV="ItemCode" |
|||
}) |
|||
} |
|||
// 库位组 |
|||
if(item.optionsProc == 'LocationGroupCode'){ |
|||
getLocationGroupCodeList().then(res=>{ |
|||
item.options = res |
|||
item.opL="LocationGroupCode" |
|||
item.opV="LocationGroupCode" |
|||
}) |
|||
} |
|||
// 状态 |
|||
if(item.optionsProc == 'InventoryStatus'){ |
|||
getInventoryStatusList().then(res=>{ |
|||
res.forEach(res_item=>res_item.sValue = String(res_item.Value)) |
|||
item.options = res |
|||
item.opL="Key" |
|||
item.opV="sValue" |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
// 初始化导出列 |
|||
initDownloadFields(){ |
|||
this.columnList.forEach(item=>{ |
|||
this.downloadFields[item.field] = item.headerName || item.field |
|||
}) |
|||
}, |
|||
// 字段设置点击事件 |
|||
columnFliterCallback(data){ |
|||
this.$emit("columnFliterCallback",data) |
|||
}, |
|||
// 表头查询事件 |
|||
searchHandle(){ |
|||
this.$emit("headerSearchHandle",this.searchForm) |
|||
}, |
|||
downloadExcelTitle(){ |
|||
let _title = this.reportName |
|||
let _begin = this.searchForm.beginDate ? this.searchForm.beginDate.slice(0,10) : '--' |
|||
let _end = this.searchForm.endDate ? this.searchForm.endDate.slice(0,10) : '--' |
|||
if(this.searchForm.beginDate || this.searchForm.endDate){ |
|||
_title = `${this.reportName} (${_begin}至${_end})` |
|||
} |
|||
return _title |
|||
} |
|||
}, |
|||
}; |
|||
</script> |
|||
<style scope lang="less"> |
|||
.reportPageHeader{ |
|||
|
|||
.FormHeader{ |
|||
padding:20px 20px 0; |
|||
display:flex; |
|||
justify-content: space-between; |
|||
|
|||
.headerRightBtn{ |
|||
display:flex; |
|||
justify-content: flex-end; |
|||
|
|||
.output-excel{ |
|||
margin-right:10px |
|||
} |
|||
} |
|||
} |
|||
|
|||
.reportTitle{ |
|||
background:#2d568e; |
|||
color:#fff; |
|||
line-height:40px; |
|||
text-align:center; |
|||
font-size:16px; |
|||
font-weight:bold; |
|||
letter-spacing:2px |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,20 @@ |
|||
|
|||
import Vue from 'vue' |
|||
import App from './App.vue' |
|||
|
|||
import router from './router' |
|||
import './styles/index.css' |
|||
import ElementUI from 'element-ui'; |
|||
import 'element-ui/lib/theme-chalk/index.css'; |
|||
|
|||
import JsonExcel from 'vue-json-excel' |
|||
Vue.component('downloadExcel', JsonExcel) |
|||
|
|||
Vue.use(ElementUI); |
|||
|
|||
Vue.config.productionTip = false |
|||
|
|||
new Vue({ |
|||
router, |
|||
render: h => h(App) |
|||
}).$mount('#app') |
@ -0,0 +1,42 @@ |
|||
import Vue from 'vue' |
|||
import VueRouter from 'vue-router' |
|||
import Home from '../views/Home.vue' |
|||
import inventoryAndAge from '../views/inventoryAndAge.vue' |
|||
|
|||
Vue.use(VueRouter) |
|||
|
|||
const routes = [ |
|||
{ |
|||
path: '/', |
|||
name: 'Home', |
|||
component: Home |
|||
}, |
|||
{ |
|||
path: '/inventoryAndAge', |
|||
name: 'inventoryAndAge', |
|||
component: inventoryAndAge |
|||
}, |
|||
] |
|||
|
|||
const router = new VueRouter({ |
|||
routes |
|||
}) |
|||
|
|||
// router.beforeEach((to, from, next) => {
|
|||
// console.log('router.beforeEach',to)
|
|||
// /* 路由发生变化修改页面title */
|
|||
// if (to.meta.title) {
|
|||
// document.title = to.meta.title
|
|||
// }
|
|||
// // if(to.meta.content){
|
|||
// // let head = document.getElementsByTagName('head');
|
|||
// // let metas = document.getElementsByTagName('meta');
|
|||
// // for (let i = 0; i < metas.length; i++) {
|
|||
// // if (metas[i].name === 'viewport') {
|
|||
// // metas[i].content += ', ' + to.meta.content
|
|||
// // }
|
|||
// // }
|
|||
// // }
|
|||
// })
|
|||
|
|||
export default router |
@ -0,0 +1,11 @@ |
|||
.clearfix { |
|||
zoom: 1; |
|||
} |
|||
.clearfix:after { |
|||
clear: both; |
|||
display: block; |
|||
visibility: hidden; |
|||
height: 0; |
|||
line-height: 0; |
|||
content: ''; |
|||
} |
@ -0,0 +1,11 @@ |
|||
.clearfix{ |
|||
zoom:1 |
|||
} |
|||
.clearfix:after{ |
|||
clear:both; |
|||
display:block; |
|||
visibility:hidden; |
|||
height:0; |
|||
line-height:0; |
|||
content:''; |
|||
} |
@ -0,0 +1,59 @@ |
|||
import axiosUtil from '../utils/request' |
|||
|
|||
var getAgoDay = function (n){ |
|||
let date = new Date() |
|||
let seperator = '-' |
|||
let newDate = new Date(date.getTime() - n*24*60*60*1000) |
|||
let year = newDate.getFullYear() |
|||
let month = newDate.getMonth()+1 |
|||
let day = newDate.getDate() |
|||
return year.toString() + seperator + month.toString() + seperator + day.toString() |
|||
} |
|||
|
|||
var getnowDay = function (){ |
|||
let date = new Date() |
|||
let seperator = '-' |
|||
let newDate = new Date(date.getTime()) |
|||
let year = newDate.getFullYear() |
|||
let month = newDate.getMonth()+1 |
|||
let day = newDate.getDate() |
|||
return year.toString() + seperator + month.toString() + seperator + day.toString() |
|||
} |
|||
|
|||
var getnowTime = function (){ |
|||
let date = new Date() |
|||
let seperator = ':' |
|||
let newDate = new Date(date.getTime()) |
|||
function __formatLength(value){ |
|||
if(Number(value) < 10){ |
|||
return "0"+value |
|||
}else{ |
|||
return value |
|||
} |
|||
} |
|||
let hour = __formatLength(newDate.getHours()); |
|||
let minute = __formatLength(newDate.getMinutes()); |
|||
let second = __formatLength(newDate.getSeconds()); |
|||
return hour.toString() + seperator + minute.toString() + seperator + second.toString() |
|||
} |
|||
|
|||
|
|||
var getServerTime = function (callback){ |
|||
axiosUtil.ajax_get('/api/dashboard/asn-time-window/get-server-date-time').then(res => { |
|||
let _res = new Date(res).getTime() |
|||
let date = getnowDay(_res) |
|||
let time = getnowTime(_res) |
|||
let datetime = date + ' ' + time |
|||
if(callback)callback(date,time,datetime,_res,res) |
|||
localStorage.setItem('currentServerDate', date); |
|||
}).catch(error => { |
|||
console.log(error) |
|||
}) |
|||
} |
|||
|
|||
export default { |
|||
getAgoDay: getAgoDay, // 获取当前天前几天
|
|||
getnowDay: getnowDay, // 获取当前时间 yyyy-dd-mm
|
|||
getnowTime: getnowTime, // 获取当前时间 hh:mm:ss
|
|||
getServerTime:getServerTime,// 获取服务器时间 走接口
|
|||
} |
@ -0,0 +1,57 @@ |
|||
import axios from 'axios' |
|||
import qs from "querystring"; |
|||
|
|||
// http request拦截器 添加一个请求拦截器
|
|||
axios.interceptors.request.use(function (config) { |
|||
// Do something before request is sent
|
|||
let token = localStorage.getItem('token') //window.localStorage.getItem("accessToken")
|
|||
if (token) { |
|||
config.headers.token = token; //将token放到请求头发送给服务器
|
|||
return config; |
|||
//这里经常搭配token使用,将token值配置到tokenkey中,将tokenkey放在请求头中
|
|||
// config.headers['accessToken'] = Token;
|
|||
} |
|||
return config |
|||
}, function (error) { |
|||
// Do something with request error
|
|||
return Promise.reject(error); |
|||
}); |
|||
|
|||
// // 添加一个响应拦截器
|
|||
// axios.interceptors.response.use(function (response) {
|
|||
// // Do something with response data
|
|||
// return response;
|
|||
// }, function (error) {
|
|||
// // Do something with response error
|
|||
// return Promise.reject(error);
|
|||
// });
|
|||
|
|||
//是我封装的axios.post请求方式
|
|||
export default class Axios { |
|||
static ajax_post(url, params ) { |
|||
return new Promise((resolve, reject) => { |
|||
return axios.post(url, params).then(response => { |
|||
resolve(response.data); |
|||
return response.data |
|||
}).catch(error => { |
|||
reject(error); |
|||
return error |
|||
// 异常处理
|
|||
}) |
|||
}) |
|||
} |
|||
static ajax_get(url, param ) { |
|||
return new Promise((resolve, reject) => { |
|||
return axios.get(url, { |
|||
params: param, |
|||
}).then(response => { |
|||
resolve(response.data); |
|||
return response.data |
|||
}).catch(error => { |
|||
reject(error); |
|||
return error |
|||
// 异常处理
|
|||
}) |
|||
}) |
|||
} |
|||
} |
@ -0,0 +1,36 @@ |
|||
// 窗口改变,页面刷新
|
|||
var addEventResizeFlesh = function(){ |
|||
window.addEventListener('resize',function(){ |
|||
window.location.reload() |
|||
}) |
|||
} |
|||
|
|||
// 时间查询(agTable)
|
|||
var dateFilterParams = { |
|||
comparator: (filterLocalDateAtMidnight, cellValue) => { |
|||
var dateAsString = cellValue; |
|||
if (dateAsString == null) return -1; |
|||
var dateParts = dateAsString.split('/'); |
|||
var cellDate = new Date( |
|||
Number(dateParts[2]), |
|||
Number(dateParts[1]) - 1, |
|||
Number(dateParts[0]) |
|||
); |
|||
if (filterLocalDateAtMidnight.getTime() === cellDate.getTime()) { |
|||
return 0; |
|||
} |
|||
if (cellDate < filterLocalDateAtMidnight) { |
|||
return -1; |
|||
} |
|||
if (cellDate > filterLocalDateAtMidnight) { |
|||
return 1; |
|||
} |
|||
return 0; |
|||
} |
|||
} |
|||
|
|||
export default { |
|||
waitTime:20000,//滚屏列表刷新等待间隔配置项
|
|||
addEventResizeFlesh:addEventResizeFlesh, |
|||
dateFilterParams:dateFilterParams |
|||
} |
@ -0,0 +1,18 @@ |
|||
<template> |
|||
<div>home</div> |
|||
</template> |
|||
<script> |
|||
export default { |
|||
name: "home", |
|||
data () { |
|||
return { |
|||
|
|||
}; |
|||
}, |
|||
methods: { |
|||
|
|||
}, |
|||
}; |
|||
</script> |
|||
<style> |
|||
</style> |
@ -0,0 +1,56 @@ |
|||
<template> |
|||
<reportPage |
|||
:columnList="columnDefs" |
|||
:searchConfig="searchConfig" |
|||
:searchForm="searchForm" |
|||
:reportName="'库存库龄报表'" |
|||
:BottomFixedItem="BottomFixedItem" |
|||
:procName="'Proc_Zheng_库存库龄'" |
|||
></reportPage> |
|||
</template> |
|||
|
|||
<script> |
|||
import reportPage from "@/components/reportPage/index" |
|||
import util from '@/utils/util' |
|||
|
|||
export default { |
|||
name: "inventoryAndAge", |
|||
components: { |
|||
reportPage |
|||
}, |
|||
data () { |
|||
const numberFormatter = (item) =>{ |
|||
return Number(item.value).toFixed(2); |
|||
} |
|||
return { |
|||
columnDefs: [ |
|||
{ field: '物料代码', filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '物料名称', filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '物料描述1', filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '物料描述2', filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '库位组', filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '总数', cellClass:"rightAlign", valueFormatter: numberFormatter, filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '<=30天', cellClass:"rightAlign", valueFormatter: numberFormatter, filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '31-180天', cellClass:"rightAlign", valueFormatter: numberFormatter, filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '181-240天', cellClass:"rightAlign", valueFormatter: numberFormatter, filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '241-300天', cellClass:"rightAlign", valueFormatter: numberFormatter, filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '301-360天', cellClass:"rightAlign", valueFormatter: numberFormatter, filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '>=361天', cellClass: 'rightAlign', valueFormatter: numberFormatter, filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '单位', cellClass:"centerAlign", filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true } }, |
|||
{ field: '状态', cellClass:"centerAlign", filter: 'agTextColumnFilter', suppressMenu: true, floatingFilterComponentParams: { suppressFilterButton: true }}, |
|||
], |
|||
searchConfig:[ |
|||
{type:'select',prop:'ItemCode',label:'物料',optionsProc:'itemCode'}, |
|||
{type:'select',prop:'LocationGroupCode',label:'库位组',optionsProc:'LocationGroupCode'}, |
|||
{type:'select',prop:'InventoryStatus',label:'状态',optionsProc:'InventoryStatus'}, |
|||
], |
|||
searchForm:{ |
|||
ItemCode:'', |
|||
LocationGroupCode:'', |
|||
InventoryStatus:"", |
|||
}, |
|||
BottomFixedItem:['总数','<=30天','31-180天','181-240天','241-300天','301-360天','>=361天'] |
|||
}; |
|||
}, |
|||
}; |
|||
</script> |
@ -0,0 +1,101 @@ |
|||
/** |
|||
* 配置参考: https://cli.vuejs.org/zh/config/
|
|||
*/ |
|||
|
|||
var webpack = require('webpack'); |
|||
const path = require('path') |
|||
const pxtovw = require('postcss-px-to-viewport'); |
|||
function resolve(dir) { |
|||
return path.join(__dirname, dir) |
|||
} |
|||
|
|||
module.exports = { |
|||
publicPath: process.env.NODE_ENV === 'production' ? './' : '/', |
|||
chainWebpack: config => { |
|||
const svgRule = config.module.rule('svg') |
|||
svgRule.uses.clear() |
|||
svgRule |
|||
.test(/\.svg$/) |
|||
.use('svg-sprite-loader') |
|||
.loader('svg-sprite-loader') |
|||
|
|||
// svg图标加载
|
|||
config.module |
|||
.rule('svg') |
|||
.exclude.add(resolve('src/assets/svg/icons')) |
|||
.end() |
|||
|
|||
config.module |
|||
.rule('icons')// 定义一个名叫 icons 的规则
|
|||
.test(/\.svg$/)// 设置 icons 的匹配正则
|
|||
.include.add(resolve('src/assets/svg/icons'))// 设置当前规则的作用目录,只在当前目录下才执行当前规则
|
|||
.end() |
|||
.use('svg-sprite')// 指定一个名叫 svg-sprite 的 loader 配置
|
|||
.loader('svg-sprite-loader')// 该配置使用 svg-sprite-loader 作为处理 loader
|
|||
.options({// 该 svg-sprite-loader 的配置
|
|||
symbolId:'icon-[name]' |
|||
}) |
|||
.end() |
|||
}, |
|||
|
|||
configureWebpack: { |
|||
resolve: { |
|||
alias: { |
|||
'@': resolve('src') |
|||
} |
|||
}, |
|||
plugins: [], |
|||
}, |
|||
// eslint : false,
|
|||
// 默认打开eslint效验,如果需要关闭,设置成false即可
|
|||
lintOnSave: false, |
|||
productionSourceMap: false, |
|||
devServer: { |
|||
open: true, |
|||
port: 8082, |
|||
https: false, |
|||
hotOnly: false, |
|||
overlay: { |
|||
errors: true, |
|||
warnings: true |
|||
}, |
|||
// proxy: {
|
|||
// '/asn': {
|
|||
// target: 'http://192.168.0.67:8081',
|
|||
// changeOrigin: true,
|
|||
// // logLevel: 'debug',
|
|||
// pathRewrite: {
|
|||
// '^/asn': ''
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
}, |
|||
// css: {
|
|||
// loaderOptions: {
|
|||
// sass: {
|
|||
// //给sass-loader传递选项
|
|||
// },
|
|||
// css: {
|
|||
// //给css-loader传递选项
|
|||
// },
|
|||
// postcss: {
|
|||
// //给postcss-loader传递选项
|
|||
// plugins: [
|
|||
// new pxtovw({
|
|||
// unitToConvert: 'px', //需要转换的单位,默认为"px";
|
|||
// viewportWidth: 375, //设计稿的视口宽度
|
|||
// unitPrecision: 5, //单位转换后保留的小数位数
|
|||
// propList: ['*'], //要进行转换的属性列表,*表示匹配所有,!表示不转换
|
|||
// viewportUnit: 'vw', //转换后的视口单位
|
|||
// fontViewportUnit: 'vw', //转换后字体使用的视口单位
|
|||
// selectorBlackList: [], //不进行转换的css选择器,继续使用原有单位
|
|||
// minPixelValue: 1, //设置最小的转换数值
|
|||
// mediaQuery: false, //设置媒体查询里的单位是否需要转换单位
|
|||
// replace: true, //是否直接更换属性值,而不添加备用属性
|
|||
// exclude: [/node_modules/] //忽略某些文件夹下的文件
|
|||
// })
|
|||
// ]
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
} |