新增费用汇总

This commit is contained in:
龙运模 2024-09-10 18:01:12 +08:00
parent dc52b1eb65
commit 17dae88049
13 changed files with 546 additions and 442 deletions

View File

@ -73,5 +73,12 @@ export default {
return await http.post(this.url,params,{'Content-Type': 'multipart/form-data'}); return await http.post(this.url,params,{'Content-Type': 'multipart/form-data'});
} }
}, },
summary:{
url: `${config.API_URL}/cost.summary.list`,
name: "成本汇总",
post: async function (params) {
return await http.post(this.url, params);
}
}
}, },
}; };

View File

@ -27,9 +27,11 @@
option: { option: {
deep:true, deep:true,
handler (v) { handler (v) {
if(unwarp(this.myChart)){
unwarp(this.myChart).setOption(v); unwarp(this.myChart).setOption(v);
} }
} }
}
}, },
computed: { computed: {
myOptions: function() { myOptions: function() {
@ -54,7 +56,7 @@
}, },
methods: { methods: {
draw(){ draw(){
var myChart = echarts.init(this.$refs.scEcharts, 'T'); const myChart = echarts.init(this.$refs.scEcharts, 'T');
myChart.setOption(this.myOptions); myChart.setOption(this.myOptions);
this.myChart = myChart; this.myChart = myChart;
window.addEventListener('resize', () => myChart.resize()); window.addEventListener('resize', () => myChart.resize());

View File

@ -12,6 +12,7 @@
</div> </div>
<div class="searchItem" v-if="item.type == 'select' && ((item.isOpen && item.show) || item.show)"> <div class="searchItem" v-if="item.type == 'select' && ((item.isOpen && item.show) || item.show)">
<label class="name">{{item.name}}</label> <label class="name">{{item.name}}</label>
<el-select class="input" :size="size" v-model="params[item.code]" @visible-change="getSelect(item,$event)" :placeholder="item.placeholder" filterable clearable> <el-select class="input" :size="size" v-model="params[item.code]" @visible-change="getSelect(item,$event)" :placeholder="item.placeholder" filterable clearable>
<el-option v-for="em in item.data" :key="em" :label="em.label" :value="em[item.code[0]] || em.active_status"></el-option> <el-option v-for="em in item.data" :key="em" :label="em.label" :value="em[item.code[0]] || em.active_status"></el-option>
</el-select> </el-select>
@ -31,6 +32,7 @@
</div> </div>
</div> </div>
</div> </div>
<slot></slot>
</template> </template>
<script> <script>

View File

@ -98,28 +98,28 @@
id: 1, id: 1,
type: 'user', type: 'user',
avatar: "img/avatar.jpg", avatar: "img/avatar.jpg",
title: "Skuya", title: "dragon",
describe: "如果喜欢就点个星星支持一下哦", describe: "如果喜欢就点个星星支持一下哦",
link: "https://gitee.com/lolicode/scui", link: "",
time: "5分钟前" time: "5分钟前"
}, },
{ {
id: 2, id: 2,
type: 'user', type: 'user',
avatar: "img/avatar2.gif", avatar: "img/avatar2.gif",
title: "Lolowan", title: "ykxiao",
describe: "点进去Gitee获取最新开源版本", describe: "点进去Gitee获取最新开源版本",
link: "https://gitee.com/lolicode/scui", link: "",
time: "14分钟前" time: "14分钟前"
}, },
{ {
id: 3, id: 3,
type: 'system', type: 'system',
avatar: "img/logo.png", avatar: "img/logo1.png",
title: "感谢登录SCUI Admin", title: "感谢登录象玮云科",
describe: "Vue 3.0 + Vue-Router 4.0 + ElementPlus + Axios 后台管理系统。", describe: "后台管理系统。",
link: "https://gitee.com/lolicode/scui", link: "",
time: "2020年7月24日" time: "2024年7月24日"
} }
] ]
} }

View File

@ -59,7 +59,6 @@
<img class="logo" src="https://dm-auto.oss-cn-shanghai.aliyuncs.com/xw_cloud/image/logo.png" alt=""> <img class="logo" src="https://dm-auto.oss-cn-shanghai.aliyuncs.com/xw_cloud/image/logo.png" alt="">
</span> </span>
<img v-else class="logo" src="https://dm-auto.oss-cn-shanghai.aliyuncs.com/xw_cloud/image/login_logo.png"> <img v-else class="logo" src="https://dm-auto.oss-cn-shanghai.aliyuncs.com/xw_cloud/image/login_logo.png">
<!-- <span v-else>{{ $CONFIG.APP_NAME }}</span>-->
</div> </div>
<div class="adminui-side-bottom" @click="$store.commit('TOGGLE_menuIsCollapse')"> <div class="adminui-side-bottom" @click="$store.commit('TOGGLE_menuIsCollapse')">
<el-icon><el-icon-expand v-if="menuIsCollapse"/><el-icon-fold v-else /></el-icon> <el-icon><el-icon-expand v-if="menuIsCollapse"/><el-icon-fold v-else /></el-icon>

View File

@ -63,7 +63,8 @@ a,button,input,textarea{-webkit-tap-highlight-color:rgba(0,0,0,0);box-sizing: bo
.adminui-side-top .adminui-side-collapse{width: 64px;display: flex;align-items: center;justify-content: center;cursor: pointer;} .adminui-side-top .adminui-side-collapse{width: 64px;display: flex;align-items: center;justify-content: center;cursor: pointer;}
.adminui-side-top .adminui-side-collapse i{font-size: 16px;} .adminui-side-top .adminui-side-collapse i{font-size: 16px;}
.adminui-side-scroll {overflow: auto;overflow-x:hidden;flex: 1;} .adminui-side-scroll {overflow: auto;overflow-x:hidden;flex: 1;}
.adminui-side-bottom {border-top: 1px solid #ebeef5;height:51px;cursor: pointer;display: flex;align-items: center;justify-content: center;} //border-top: 1px solid #ebeef5;
.adminui-side-bottom {height:51px;cursor: pointer;display: flex;align-items: center;justify-content: center;}
.adminui-side-bottom i {font-size: 16px;} .adminui-side-bottom i {font-size: 16px;}
.adminui-side-bottom:hover {color: var(--el-color-primary);} .adminui-side-bottom:hover {color: var(--el-color-primary);}
.aminui-side.isCollapse {width: 65px;} .aminui-side.isCollapse {width: 65px;}

View File

@ -90,8 +90,8 @@ export default {
exportShow:false, exportShow:false,
searchShow:false, searchShow:false,
searchList:[ searchList:[
{name:'费用类型',type:'select',code:'type_name', data:[], placeholder:"请选择费用类型",show:true}, {name:'费用类型',type:'select',code:['type_name'], data:[], placeholder:"请选择费用类型",show:true},
{name:'费用类别',type:'select',code:'category_name', data:[], placeholder:"请选择费用类别",isOpen:true,show:false}, {name:'费用类别',type:'select',code:['category_name'], data:[], placeholder:"请选择费用类别",isOpen:true,show:false},
{name:'地址',type:'text',code:['location'],placeholder:"请输入地址",isOpen:true,show:false}, {name:'地址',type:'text',code:['location'],placeholder:"请输入地址",isOpen:true,show:false},
{name:'单号',type:'text',code:['identifier'],placeholder:"请输入单号",isOpen:true,show:false}, {name:'单号',type:'text',code:['identifier'],placeholder:"请输入单号",isOpen:true,show:false},
{name:'单位',type:'text',code:['unit'],placeholder:"请输入单位",isOpen:true,show:false}, {name:'单位',type:'text',code:['unit'],placeholder:"请输入单位",isOpen:true,show:false},

View File

@ -0,0 +1,97 @@
<template>
<div class="feesTable">
<el-scrollbar>
<table>
<thead class="columnView">
<tr class="th" v-if="data.header">
<th class="td sq">序号</th>
<th class="td">成本类型</th>
<th class="td" v-for="(item,index) in data.header" :key="index">{{item}}</th>
</tr>
</thead>
<tbody class="rowView">
<tr class="tr" v-for="(item,index) in data.data" :key="index">
<td class="td sq">{{index + 1}}</td>
<td class="td" v-for="(em,ind) in item" :key="ind">{{em}}</td>
</tr>
</tbody>
</table>
</el-scrollbar>
</div>
</template>
<script>
export default {
name: "",
props:{
info:{
type:Object,
}
},
watch:{
info:{
handler(val){
if(val){
this.data = val;
}
},
deep:true
}
},
data(){
return{
data:this.info
}
},
mounted() {
},
methods:{
}
}
</script>
<style scoped lang="scss">
.columnView{
display: flex;
flex-wrap: nowrap;
.th{
display: flex;
flex-wrap: nowrap;
background: #F5F7FA;
padding: 6px 5px;
.td{
white-space: nowrap;
margin: 0 10px;
line-height: 23px;
width: 90px;
text-align: left;
color: #606266;
font-weight: 400;
}
.sq{
width: 45px;
}
}
}
.rowView{
.tr{
display: flex;
flex-wrap: nowrap;
border-bottom: 1px solid #ebeef5;
padding: 6px 5px;
.td{
white-space: nowrap;
margin: 0 10px;
width: 90px;
line-height: 23px;
color: #606266;
font-weight: inherit;
}
.sq{
width: 45px;
}
}
}
</style>

View File

@ -1,76 +1,48 @@
<template> <template>
<el-container class="mainBox mainHeaderNoBorderPadding"> <el-container class="mainBox mainBoxHeaderNoBorder">
<el-header> <el-main class="nopadding">
<div class="left-panel"> <el-scrollbar>
<el-button type="primary" :size="size" icon="el-icon-plus" @click="add">新增</el-button> <div class="searchMain">
<scImport ref="scImport" :size="size" title="批量导入维保工单" @parentParams="importUpload" @importSuccess="importSuccess"> <scSearch ref="scSearch" :searchList="searchList" @fetchSelectData="getSelectData">
<template #header> <div class="searchItem">
<el-button v-auth="'organizationImport'" type="primary" :size="size" plain @click="importFile">批量导入</el-button> <label class="name">时间粒度</label>
</template> <el-select :size="size" class="input" placeholder="请选择时间粒度" v-model="reqParams.date_type">
<template #download> <el-option v-for="(item,index) in setMap.dataTypeList" :key="index" :label="item.label" :value="item.date_type"></el-option>
<div v-auth="'companyImportTemplate'" @click="importTemplate">下载导入模版</div> </el-select>
</template>
</scImport>
</div> </div>
<div class="right-panel"> <div class="searchItem">
<label class="name">时间范围</label>
<el-date-picker :size="size" class="input" type="daterange" v-model="reqParams.dateSelect" value-format="YYYY-MM-DD" start-placeholder="开始时间" end-placeholder="结束时间"></el-date-picker>
</div>
</scSearch>
<div class="searchItem searchBtn">
<el-button :size="size" type="primary" icon="el-icon-search" @click="upSearch">查询</el-button>
<el-button :size="size" type="info" icon="el-icon-RefreshRight" @click="reset">重置</el-button>
<scExport :size="size" @exportData="exportData" @updateShow="exportChangeShow" :show="exportShow" type="11"> <scExport :size="size" @exportData="exportData" @updateShow="exportChangeShow" :show="exportShow" type="11">
<el-button :size="size" icon="sc-icon-Download" @click="exportData">下载</el-button> <el-button :size="size" icon="sc-icon-Download" @click="exportData">下载</el-button>
</scExport> </scExport>
</div> </div>
</el-header> </div>
<el-main class="nopadding"> <div class="mainMiddle">
<div class="searchMain searchMainNoTop"> <div class="echartsView">
<scSearch ref="scSearch" :searchList="searchList" @fetchSelectData="getSelectData"></scSearch> <scEcharts ref="c1" height="300px" :option="option"></scEcharts>
</div>
<div class="searchItem searchBtn"> <div class="tableView">
<el-button :size="size" :icon="searchShow?'el-icon-ArrowUpBold':'el-icon-ArrowDownBold'" @click="searchShowClick">{{searchShow?'收起':'更多'}}</el-button> <feesTable :info="feesData.tableList"></feesTable>
<el-button :size="size" type="primary" icon="el-icon-search" @click="upSearch">查询</el-button>
<el-button :size="size" type="info" icon="el-icon-RefreshRight" @click="reset">重置</el-button>
</div> </div>
</div> </div>
<scTable ref="table" :apiObj="list.apiObj" :column="list.column" row-key="id" stripe :size="size" @selection-change="selectionChange"> </el-scrollbar>
<el-table-column type="selection" align="center" width="40"></el-table-column>
<sc-table-column label="序号" align="center" type="index"></sc-table-column>
<template #logo="scope">
<el-image class="logoCell" :src="scope.row.logo" preview-teleported :preview-src-list="[scope.row.logo]" fit="contain">
<template #error>
<div class="image-slot" style="text-align: center;font-size: 20px;">
<el-icon><el-icon-Picture /></el-icon>
</div>
</template>
</el-image>
</template>
<template #active_status="scope">
<el-switch :size="size" v-model="scope.row.active_status" @change="changeSwitch($event, scope.row)" :loading="scope.row.$switch_status" :active-value="true" :inactive-value="false"></el-switch>
</template>
<el-table-column label="操作" fixed="right" align="center" width="150">
<template #default="scope">
<el-dropdown>
<el-button class="noBorderBtn" icon="el-icon-more" :size="size"></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="table_show(scope.row, 'see')" icon="sc-icon-See">查看详情</el-dropdown-item>
<el-dropdown-item @click="table_edit(scope.row, 'edit')" icon="sc-icon-Edit">编辑公司</el-dropdown-item>
<el-dropdown-item icon="sc-icon-AbilityAuthorization" @click="table_empower(scope.row)" divided>功能授权</el-dropdown-item>
<el-dropdown-item icon="sc-icon-DataAuthorization">数据授权</el-dropdown-item>
<el-dropdown-item icon="sc-icon-UserList" @click="table_user_ist(scope.row)" divided>用户列表</el-dropdown-item>
<el-dropdown-item @click="table_del(scope.row, 'delete')" icon="sc-icon-Delete">删除公司</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
</scTable>
</el-main> </el-main>
</el-container> </el-container>
</template> </template>
<script> <script>
import scEcharts from '@/components/scEcharts';
import feesTable from './components/table'
export default { export default {
components: { components: {
scEcharts,
feesTable
}, },
data() { data() {
return { return {
@ -79,179 +51,145 @@ export default {
save: false, save: false,
show: false, show: false,
}, },
list: { setMap:{
apiObj: {}, dataTypeList:[
column: [], {date_type:'hour',label:'按时'},
{date_type:'day',label:'按天'},
{date_type:'month',label:'按月'},
{date_type:'year',label:'按年'},
],
}, },
option:{},
feesData:{
tableList:{}
},
selection: [], selection: [],
exportShow:false, exportShow:false,
searchShow:false,
searchList:[ searchList:[
{name:'生产日期',type:'date',code:'activation_date'}, {name:'成本类型',type:'select',code:['type_name'], data:[], placeholder:"请选择费用类型",show:true},
{name:'反厂日期',type:'date',code:'activation_date'}, {name:'成本类别',type:'select',code:['category_name'], data:[], placeholder:"请选择费用类别",show:true},
{name:'处理时间',type:'date',code:'activation_date'},
{name:'客户名称',type:'multiple',code:'id', data:[], placeholder:"请选择公司名称",show:false},
{name:'状态',type:'select',code:'active_status', data:[], placeholder:"请选择状态",show:false},
{name:'工单号',type:'text',code:['mobile'],placeholder:"请输入手机号",isOpen:true,show:false},
{name:'邮件地址',type:'text',code:['email'],placeholder:"请输入邮箱地址",isOpen:true,show:false},
{name:'公司地址',type:'text',code:['address'],placeholder:"请输入公司地址",isOpen:true,show:false},
{name:'负责人',type:'text',code:['owner'],placeholder:"请输入负责人",isOpen:true,show:false},
{name:'关键字',type:'text',code:['domain','name'],keyword:true,show:true},
], ],
params: {}, params: {},
reqParams:{
page:1,
pageSize:30,
date_type:'day',
dateSelect:[],
start:'',
end:'',
} }
}
},
watch:{
'reqParams.dateSelect':function (val){
if(val){
this.reqParams.start = val[0];
this.reqParams.end = val[1];
}else{
this.reqParams.start = "";
this.reqParams.end = "";
}
}
},
computed:{
},
created(){
},
mounted() {
this.getData();
}, },
methods: { methods: {
searchShowClick(){ async getSelectData(item) {
this.searchShow = !this.searchShow;
this.searchList.forEach(item=>{
if(item.isOpen){
item.show = this.searchShow
}
})
},
getSelectData(item){
let {data, params} = item; let {data, params} = item;
this.params = params; this.params = params;
if(data.code == "id"){ let searchParams = this.$TOOL.objCopy(params);
this.getCompanyList(data,params) searchParams.field = ""
}else if(data.code == "active_status"){ if (typeof data.code === 'string') {
this.getStatusList(data,params); searchParams.field = data.code;
} else {
searchParams.field = data.code[0];
} }
}, if (data.type == 'select') {
const res = await this.$API.finance.cost.field.post(searchParams);
async getCompanyList(data,params) { if (res.code == 200) {
const res = await this.$API.system.company.select.post(params);
if (res.data && res.data.length > 0) { if (res.data && res.data.length > 0) {
res.data.forEach(item => { res.data.forEach(item => {
item.label = item.full_name; item.label = item[data.code];
item.value = item.id;
}) })
} }
if(res.code == 200){
this.searchList.forEach(item => { this.searchList.forEach(item => {
if (item.code == data.code) { if (item.code == data.code) {
item.data = res.data; item.data = res.data;
} }
}) })
} }
},
async getStatusList(data,params) {
const res = await this.$API.oss.status.post(params);
if(res.code == 200){
this.searchList.forEach(item=>{
if(item.code == data.code){
item.data = res.data;
}
})
} }
}, },
// async getData() {
add(){ const res = await this.$API.finance.cost.summary.post(this.reqParams);
this.dialog.save = true; if(res.code == 200){
this.$nextTick(() => { res.data.tableList.data = this.setTableList(res.data.tableList.data);
this.$refs.saveDialog.open() this.feesData = res.data;
}) let option = {
tooltip: {
trigger: 'axis'
},
xAxis: {
boundaryGap: false,
type: 'category',
data: this.feesData.dateRange
},
yAxis: [{
type: 'value',
name: '',
splitLine: {
show: false
}
}],
series: this.setList(this.feesData.summaryList),
};
this.option = option;
}
},
setList(data){
let newData = data[0].cost_item.map(item => ({
name: item,
data: [],
type:'bar',
symbol: 'none',
stack:'fees'
}));
if(data && data.length>0){
data.forEach(item => {
item.cost_amount.forEach((amount, index) => {
newData[index].data.push(amount);
});
});
}
return newData
},
setTableList(data){
let newData = data.columns.map(column => [column]);
if(data.rows && data.rows.length>0){
data.rows.forEach((row, rowIndex) => {
data.columns.forEach((columnName, columnIndex) => {
newData[columnIndex][1 + rowIndex] = row[columnIndex]==0?'-':'¥'+row[columnIndex];
});
});
}
return newData
}, },
//
importFile(){
this.$nextTick(()=>{
this.$refs.scImport.importFile();
})
},
async importTemplate() {
const res = await this.$API.orders.order.maintenance.template.post();
const blob = new Blob([res]);
const text = new Date().getTime();
const eLink = document.createElement('a');
eLink.download = "维保导入模版_"+text+'.xlsx';
eLink.style.display = 'none';
eLink.href = URL.createObjectURL(blob);
document.body.appendChild(eLink);
eLink.click();
URL.revokeObjectURL(eLink.href);
document.body.removeChild(eLink);
},
async importUpload(params) {
const res = await this.$API.orders.order.maintenance.import.post(params);
if(res.code == 200){
this.$message.success('上传成功,开始导入数据');
}
},
importSuccess(){
this.$refs.table.refresh()
},
//
table_edit(row){
this.dialog.save = true
this.$nextTick(() => {
this.$refs.saveDialog.open('edit').setData(row)
})
},
//
table_show(row){
this.dialog.show = true
this.$nextTick(() => {
this.$refs.showDialog.open('show').setData(row);
})
},
//
async table_del(row){
this.$confirm(`确定删除 ${row.name} 吗?`, '提示', {
type: 'warning'
}).then(async () => {
const reqData = {id: row.id};
const res = await this.$API.system.company.delete.post(reqData);
if(res.code == 200){
this.$refs.table.refresh()
this.$message.success("删除成功")
}else{
await this.$alert(res.message, "提示", {type: 'error'})
}
}).catch(()=>{})
},
//
table_empower(row){
this.$router.push({
path: '/setting/company/add-permission',
query: {
id: row.id,
name:row.name
}
})
},
//
table_user_ist(row){
this.$router.push({
path: '/setting/user/company-user-list',
query: {
id: row.id,
name:row.name
}
})
},
// //
selectionChange(selection){ selectionChange(selection){
this.selection = selection; this.selection = selection;
}, },
//
changeSwitch(val, row) {
row.$switch_yx = true;
setTimeout(async () => {
let params = {
id: row.id,
status: row.active_status,
};
const res = await this.$API.system.company.status.post(params);
if(res.code !=200){
row.active_status = !row.active_status;
}
delete row.$switch_status;
delete row.$switch_yx;
}, 500);
},
// //
exportChangeShow(params){ exportChangeShow(params){
if(params.type == 11){ if(params.type == 11){
@ -266,15 +204,23 @@ export default {
} }
}, },
upSearch(){ upSearch(){
this.$refs.table.upData(this.params); this.reqParams = {...this.reqParams,...this.params};
this.getData();
}, },
reset(){ reset(){
this.params = {}; this.reqParams = {
page:1,
pageSize:30,
date_type:'day',
dateSelect:[],
start:'',
end:''
};
this.$refs.scSearch.reload(); this.$refs.scSearch.reload();
this.$refs.table.reload(); this.getData();
}, },
handleSaveSuccess(){ handleSaveSuccess(){
this.$refs.table.refresh(); // this.$refs.table.refresh();
}, },
} }
} }

View File

@ -0,0 +1,96 @@
<template>
<div class="feesTable">
<el-scrollbar>
<table>
<thead class="columnView">
<tr class="th">
<th class="td sq">序号</th>
<th class="td">成本类型</th>
<th class="td" v-for="(item,index) in data.header" :key="index">{{item}}</th>
</tr>
</thead>
<tbody class="rowView">
<tr class="tr" v-for="(item,index) in data.data" :key="index">
<td class="td sq">{{index + 1}}</td>
<td class="td" v-for="(em,ind) in item" :key="ind">{{em}}</td>
</tr>
</tbody>
</table>
</el-scrollbar>
</div>
</template>
<script>
export default {
name: "",
props:{
info:{
type:Object,
}
},
watch:{
info:{
handler(val){
if(val){
this.data = val;
}
},
deep:true
}
},
data(){
return{
data:this.info
}
},
mounted() {
},
methods:{
}
}
</script>
<style scoped lang="scss">
.columnView{
display: flex;
flex-wrap: nowrap;
.th{
display: flex;
flex-wrap: nowrap;
background: #F5F7FA;
padding: 4px 5px;
.td{
white-space: nowrap;
margin: 0 10px;
line-height: 23px;
width: 90px;
text-align: left;
color: #606266;
font-weight: 400;
}
.sq{
width: 45px;
}
}
}
.rowView{
.tr{
display: flex;
flex-wrap: nowrap;
border-bottom: 1px solid #ebeef5;
padding: 4px 5px;
.td{
white-space: nowrap;
margin: 0 10px;
width: 90px;
line-height: 23px;
color: #222;
}
.sq{
width: 45px;
}
}
}
</style>

View File

@ -1,73 +1,38 @@
<template> <template>
<el-container class="mainBox mainHeaderNoBorderPadding"> <el-container class="mainBox mainBoxHeaderNoBorder">
<el-header> <el-main class="nopadding">
<div class="left-panel"> <el-scrollbar>
<el-button type="primary" :size="size" icon="el-icon-plus" @click="add">新增</el-button> <div class="searchMain">
<scImport ref="scImport" :size="size" title="批量导入维保工单" @parentParams="importUpload" @importSuccess="importSuccess"> <scSearch ref="scSearch" :searchList="searchList" @fetchSelectData="getSelectData"></scSearch>
<template #header> <div class="searchItem searchBtn">
<el-button v-auth="'organizationImport'" type="primary" :size="size" plain @click="importFile">批量导入</el-button> <el-button :size="size" type="primary" icon="el-icon-search" @click="upSearch">查询</el-button>
</template> <el-button :size="size" type="info" icon="el-icon-RefreshRight" @click="reset">重置</el-button>
<template #download>
<div v-auth="'companyImportTemplate'" @click="importTemplate">下载导入模版</div>
</template>
</scImport>
</div>
<div class="right-panel">
<scExport :size="size" @exportData="exportData" @updateShow="exportChangeShow" :show="exportShow" type="11"> <scExport :size="size" @exportData="exportData" @updateShow="exportChangeShow" :show="exportShow" type="11">
<el-button :size="size" icon="sc-icon-Download" @click="exportData">下载</el-button> <el-button :size="size" icon="sc-icon-Download" @click="exportData">下载</el-button>
</scExport> </scExport>
</div> </div>
</el-header> </div>
<el-main class="nopadding"> <div class="mainMiddle">
<div class="searchMain searchMainNoTop"> <div class="echartsView">
<scSearch ref="scSearch" :searchList="searchList" @fetchSelectData="getSelectData"></scSearch> <scEcharts ref="c1" height="300px" :option="option"></scEcharts>
</div>
<div class="searchItem searchBtn"> <div class="tableView">
<el-button :size="size" :icon="searchShow?'el-icon-ArrowUpBold':'el-icon-ArrowDownBold'" @click="searchShowClick">{{searchShow?'收起':'更多'}}</el-button> <feesTable :info="feesData.tableList"></feesTable>
<el-button :size="size" type="primary" icon="el-icon-search" @click="upSearch">查询</el-button>
<el-button :size="size" type="info" icon="el-icon-RefreshRight" @click="reset">重置</el-button>
</div> </div>
</div> </div>
<scTable ref="table" :apiObj="list.apiObj" :column="list.column" row-key="id" stripe :size="size" @selection-change="selectionChange"> </el-scrollbar>
<el-table-column type="selection" align="center" width="40"></el-table-column>
<sc-table-column label="序号" align="center" type="index"></sc-table-column>
<template #logo="scope">
<el-image class="logoCell" :src="scope.row.logo" preview-teleported :preview-src-list="[scope.row.logo]" fit="contain">
<template #error>
<div class="image-slot" style="text-align: center;font-size: 20px;">
<el-icon><el-icon-Picture /></el-icon>
</div>
</template>
</el-image>
</template>
<template #active_status="scope">
<el-switch :size="size" v-model="scope.row.active_status" @change="changeSwitch($event, scope.row)" :loading="scope.row.$switch_status" :active-value="true" :inactive-value="false"></el-switch>
</template>
<el-table-column label="操作" fixed="right" align="center" width="150">
<template #default="scope">
<el-dropdown>
<el-button class="noBorderBtn" icon="el-icon-more" :size="size"></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="table_edit(scope.row, 'edit')" icon="sc-icon-Edit">编辑费用</el-dropdown-item>
<el-dropdown-item @click="table_del(scope.row, 'delete')" icon="sc-icon-Delete">删除费用</el-dropdown-item>
<el-dropdown-item @click="table_show(scope.row, 'see')" icon="sc-icon-See" divided>查看详情</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</el-table-column>
</scTable>
</el-main> </el-main>
</el-container> </el-container>
</template> </template>
<script> <script>
import scEcharts from '@/components/scEcharts';
import feesTable from './components/table'
export default { export default {
components: { components: {
scEcharts,
feesTable
}, },
data() { data() {
return { return {
@ -76,177 +41,131 @@ export default {
save: false, save: false,
show: false, show: false,
}, },
list: { option:{},
apiObj: this.$API.finance.cost.list, feesData:{
column: [], tableList:{}
}, },
selection: [], selection: [],
exportShow:false, exportShow:false,
searchShow:false,
searchList:[ searchList:[
{name:'费用类型',type:'multiple',code:'type_name', data:[], placeholder:"请选择费用类型",show:true}, {name:'成本类型',type:'select',code:['type_name'], data:[], placeholder:"请选择费用类型",show:true},
{name:'费用类别',type:'select',code:'category_name', data:[], placeholder:"请选择费用类别",show:false}, {name:'成本类别',type:'select',code:['category_name'], data:[], placeholder:"请选择费用类别",show:true},
{name:'地址',type:'text',code:['location'],placeholder:"地址",isOpen:true,show:false}, {name:'时间粒度',type:'select',code:['date_type'],
{name:'单号',type:'text',code:['identifier'],placeholder:"请输入单号",isOpen:true,show:false}, data:[
{name:'单位',type:'text',code:['unit'],placeholder:"请输入单位",isOpen:true,show:false}, {date_type:'hour',label:'按时'},
{name:'交付/快递日期',type:'date',code:'time',show:true}, {date_type:'day',label:'按天'},
{name:'新增日期',type:'date',code:'created_at',show:true}, {date_type:'month',label:'按月'},
{name:'关键字',type:'text',code:['quantity','amount','remark'],keyword:true,show:true}, {date_type:'year',label:'按年'},
], placeholder:"请选择时间粒度",show:true},
{name:'时间范围',type:'date',code:'time',show:true},
], ],
params: {}, params: {
page:1,
pageSize:30,
date_type:'day',
// start:'2024-01-01',
// end:'2024-12-31'
},
} }
}, },
created(){
},
mounted() {
this.getData();
},
methods: { methods: {
searchShowClick(){ async getSelectData(item) {
this.searchShow = !this.searchShow;
this.searchList.forEach(item=>{
if(item.isOpen){
item.show = this.searchShow
}
})
},
getSelectData(item){
let {data, params} = item; let {data, params} = item;
this.params = params; this.params = params;
if(data.code == "id"){ let searchParams = this.$TOOL.objCopy(params);
this.getCompanyList(data,params) searchParams.field = ""
}else if(data.code == "active_status"){ if (typeof data.code === 'string') {
this.getStatusList(data,params); searchParams.field = data.code;
} else {
searchParams.field = data.code[0];
} }
}, if (data.type == 'select') {
const res = await this.$API.finance.cost.field.post(searchParams);
async getCompanyList(data,params) { if (res.code == 200) {
const res = await this.$API.system.company.select.post(params);
if (res.data && res.data.length > 0) { if (res.data && res.data.length > 0) {
res.data.forEach(item => { res.data.forEach(item => {
item.label = item.full_name; item.label = item[data.code];
item.value = item.id;
}) })
} }
if(res.code == 200){
this.searchList.forEach(item => { this.searchList.forEach(item => {
if (item.code == data.code) { if (item.code == data.code) {
item.data = res.data; item.data = res.data;
} }
}) })
} }
},
async getStatusList(data,params) {
const res = await this.$API.oss.status.post(params);
if(res.code == 200){
this.searchList.forEach(item=>{
if(item.code == data.code){
item.data = res.data;
}
})
} }
}, },
// async getData() {
add(){ const res = await this.$API.finance.cost.summary.post(this.params);
this.dialog.save = true; if(res.code == 200){
this.$nextTick(() => { res.data.tableList.data = this.setTableList(res.data.tableList.data);
this.$refs.saveDialog.open() this.feesData = res.data;
})
console.log(this.feesData)
let option = {
tooltip: {
trigger: 'axis'
},
xAxis: {
boundaryGap: false,
type: 'category',
data: this.feesData.dateRange
},
yAxis: [{
type: 'value',
name: '',
splitLine: {
show: false
}
}],
series: this.setList(this.feesData.summaryList),
};
this.option = option;
}
},
setList(data){
let newData = data[0].cost_item.map(item => ({
name: item,
data: [],
type:'bar',
symbol: 'none',
stack:'fees'
}));
if(data && data.length>0){
data.forEach(item => {
item.cost_amount.forEach((amount, index) => {
newData[index].data.push(amount);
});
});
}
return newData
},
setTableList(data){
let newData = data.columns.map(column => [column]);
if(data.rows && data.rows.length>0){
data.rows.forEach((row, rowIndex) => {
data.columns.forEach((columnName, columnIndex) => {
newData[columnIndex][1 + rowIndex] = row[columnIndex]==0?'-':'¥'+row[columnIndex];
});
});
}
return newData
}, },
//
importFile(){
this.$nextTick(()=>{
this.$refs.scImport.importFile();
})
},
async importTemplate() {
const res = await this.$API.orders.order.maintenance.template.post();
const blob = new Blob([res]);
const text = new Date().getTime();
const eLink = document.createElement('a');
eLink.download = "维保导入模版_"+text+'.xlsx';
eLink.style.display = 'none';
eLink.href = URL.createObjectURL(blob);
document.body.appendChild(eLink);
eLink.click();
URL.revokeObjectURL(eLink.href);
document.body.removeChild(eLink);
},
async importUpload(params) {
const res = await this.$API.orders.order.maintenance.import.post(params);
if(res.code == 200){
this.$message.success('上传成功,开始导入数据');
}
},
importSuccess(){
this.$refs.table.refresh()
},
//
table_edit(row){
this.dialog.save = true
this.$nextTick(() => {
this.$refs.saveDialog.open('edit').setData(row)
})
},
//
table_show(row){
this.dialog.show = true
this.$nextTick(() => {
this.$refs.showDialog.open('show').setData(row);
})
},
//
async table_del(row){
this.$confirm(`确定删除 ${row.name} 吗?`, '提示', {
type: 'warning'
}).then(async () => {
const reqData = {id: row.id};
const res = await this.$API.system.company.delete.post(reqData);
if(res.code == 200){
this.$refs.table.refresh()
this.$message.success("删除成功")
}else{
await this.$alert(res.message, "提示", {type: 'error'})
}
}).catch(()=>{})
},
//
table_empower(row){
this.$router.push({
path: '/setting/company/add-permission',
query: {
id: row.id,
name:row.name
}
})
},
//
table_user_ist(row){
this.$router.push({
path: '/setting/user/company-user-list',
query: {
id: row.id,
name:row.name
}
})
},
// //
selectionChange(selection){ selectionChange(selection){
this.selection = selection; this.selection = selection;
}, },
//
changeSwitch(val, row) {
row.$switch_yx = true;
setTimeout(async () => {
let params = {
id: row.id,
status: row.active_status,
};
const res = await this.$API.system.company.status.post(params);
if(res.code !=200){
row.active_status = !row.active_status;
}
delete row.$switch_status;
delete row.$switch_yx;
}, 500);
},
// //
exportChangeShow(params){ exportChangeShow(params){
if(params.type == 11){ if(params.type == 11){
@ -261,15 +180,15 @@ export default {
} }
}, },
upSearch(){ upSearch(){
this.$refs.table.upData(this.params); // this.$refs.table.upData(this.params);
}, },
reset(){ reset(){
this.params = {}; this.params = {};
this.$refs.scSearch.reload(); this.$refs.scSearch.reload();
this.$refs.table.reload(); // this.$refs.table.reload();
}, },
handleSaveSuccess(){ handleSaveSuccess(){
this.$refs.table.refresh(); // this.$refs.table.refresh();
}, },
} }
} }

View File

@ -40,6 +40,11 @@
</template> </template>
</el-image> </el-image>
</template> </template>
<template #company_type="scope">
<span v-for="(item,index) in setMap.companyType" :key="index">
<span v-if="item.company_type == scope.row.company_type">{{item.label}}</span>
</span>
</template>
<template #active_status="scope"> <template #active_status="scope">
<el-switch :size="size" v-auth="'organizationUpdateStatus'" v-model="scope.row.active_status" @change="changeSwitch($event, scope.row)" :loading="scope.row.$switch_status" :active-value="true" :inactive-value="false"></el-switch> <el-switch :size="size" v-auth="'organizationUpdateStatus'" v-model="scope.row.active_status" @change="changeSwitch($event, scope.row)" :loading="scope.row.$switch_status" :active-value="true" :inactive-value="false"></el-switch>
</template> </template>
@ -93,6 +98,9 @@ export default {
save: false, save: false,
show: false, show: false,
}, },
setMap:{
companyType:[]
},
list: { list: {
apiObj: this.$API.system.company.list, apiObj: this.$API.system.company.list,
column: [], column: [],
@ -102,8 +110,9 @@ export default {
searchShow:false, searchShow:false,
searchList:[ searchList:[
{name:'开通日期',type:'date',code:'activation_date',show:true}, {name:'开通日期',type:'date',code:'activation_date',show:true},
{name:'公司类型',type:'select',code:['company_type'], data:[], placeholder:"请选择公司类型",show:true},
{name:'公司名称',type:'multiple',code:'id', data:[], placeholder:"请选择公司名称",show:true}, {name:'公司名称',type:'multiple',code:'id', data:[], placeholder:"请选择公司名称",show:true},
{name:'状态',type:'select',code:'active_status', data:[], placeholder:"请选择状态",show:true}, {name:'状态',type:'select',code:'active_status', data:[], placeholder:"请选择状态",isOpen:true,show:false},
{name:'手机号',type:'text',code:['mobile'],placeholder:"请输入手机号",isOpen:true,show:false}, {name:'手机号',type:'text',code:['mobile'],placeholder:"请输入手机号",isOpen:true,show:false},
{name:'邮件地址',type:'text',code:['email'],placeholder:"请输入邮箱地址",isOpen:true,show:false}, {name:'邮件地址',type:'text',code:['email'],placeholder:"请输入邮箱地址",isOpen:true,show:false},
{name:'公司地址',type:'text',code:['address'],placeholder:"请输入公司地址",isOpen:true,show:false}, {name:'公司地址',type:'text',code:['address'],placeholder:"请输入公司地址",isOpen:true,show:false},
@ -113,6 +122,9 @@ export default {
params: {}, params: {},
} }
}, },
mounted() {
this.getCompanyTypeSelect();
},
methods: { methods: {
searchShowClick(){ searchShowClick(){
this.searchShow = !this.searchShow; this.searchShow = !this.searchShow;
@ -129,9 +141,17 @@ export default {
this.getCompanyList(data,params) this.getCompanyList(data,params)
}else if(data.code == "active_status"){ }else if(data.code == "active_status"){
this.getStatusList(data,params); this.getStatusList(data,params);
}else if(data.code == "company_type"){
this.getCompanyTypeList(data,params);
}
},
//
async getCompanyTypeSelect(){
const res = await this.$API.system.company.typeSelect.post();
if(res.code == 200){
this.setMap['companyType'] = res.data;
} }
}, },
async getCompanyList(data,params) { async getCompanyList(data,params) {
const res = await this.$API.system.company.select.post(params); const res = await this.$API.system.company.select.post(params);
if(res.data && res.data.length>0){ if(res.data && res.data.length>0){
@ -157,6 +177,21 @@ export default {
}) })
} }
}, },
async getCompanyTypeList(data,params) {
const res = await this.$API.system.company.typeSelect.post(params);
if (res.data && res.data.length > 0) {
res.data.forEach(item => {
item.value = item.id;
})
}
if(res.code == 200){
this.searchList.forEach(item=>{
if(item.code == data.code){
item.data = res.data;
}
})
}
},
// //
add(){ add(){