feat(账单列表): 修复因为缺失数据导致的报错不显示

This commit is contained in:
hzj 2026-02-28 16:15:36 +08:00
parent e1fd24328e
commit d75ba843a3
2 changed files with 340 additions and 246 deletions

View File

@ -11,18 +11,18 @@
custom-class="drawer-auto-layout"
>
<div class="team-bill-content">
<div class="blockquote">代理</div>
<div class="content">
<user-table-exhibit :user-profile="row.ownUserProfile" :query-details="true" />
<user-table-exhibit
:user-profile="row.ownUserProfile"
:query-details="true"
/>
</div>
<div class="blockquote">账单信息</div>
<div class="content">
<div class="flex-b bill-row">
<div class="left bill-col nowrap-ellipsis">
ID: {{ row.id }}
</div>
<div class="left bill-col nowrap-ellipsis">ID: {{ row.id }}</div>
<div class="right bill-col nowrap-ellipsis">
区域: {{ row.regionName }}
</div>
@ -32,7 +32,7 @@
账单归属: {{ row.billBelong }}
</div>
<div class="left bill-col nowrap-ellipsis">
账单标题: {{ row.billTitle }}
账单标题: {{ row.billTitle }}
</div>
</div>
@ -70,15 +70,19 @@
</div>
</div>
<div v-if="row.settleResult.policy.policyType === 'SALARY_DIAMOND'" class="flex-b bill-row">
<!-- <div
v-if="row.settleResult.policy.policyType === 'SALARY_DIAMOND'"
class="flex-b bill-row"
>
<div class="left bill-col nowrap-ellipsis">
团队已兑换钻石: {{ row.settleResult.redeemedDiamondsSalary || 0 }}
团队已兑换钻石:
{{ row.settleResult.redeemedDiamondsSalary || 0 }}
</div>
<div class="right bill-col nowrap-ellipsis">
团队剩余钻石: {{ row.settleResult.remainingDiamondsSalary || 0 }}
团队剩余钻石:
{{ row.settleResult.remainingDiamondsSalary || 0 }}
</div>
</div>
</div> -->
</div>
<div v-if="row.remarks" class="bill-row">
@ -96,7 +100,8 @@
:timestamp="item.createTime"
>
<div class="remark">
<span class="nickname">{{ item.createBackUserName }}:</span> &nbsp;{{ item.remark }}
<span class="nickname">{{ item.createBackUserName }}:</span>
&nbsp;{{ item.remark }}
</div>
</el-timeline-item>
</el-timeline>
@ -110,7 +115,10 @@
<div class="bank-card-item back-blue">
<div class="card-info flex-b">
<div class="card-icon">
<img src="https://img.sugartimeapp.com/avatar/57800817-7e89-4ba5-9640-4697a5a61048.png" alt="">
<img
src="https://img.sugartimeapp.com/avatar/57800817-7e89-4ba5-9640-4697a5a61048.png"
alt=""
/>
</div>
<div class="profile">
<div class="card-no ellipsis-nowrap">
@ -126,11 +134,15 @@
</div>
</div>
<div v-if="row.settleResult">
<!-- <div v-if="row.settleResult">
<div class="blockquote">政策</div>
<div class="content">
<div class="policy">
<div v-for="(item, index) in row.settleResult.policy.policy" :key="index" class="policy-row">
<div
v-for="(item, index) in row.settleResult.policy.policy"
:key="index"
class="policy-row"
>
<div class="title blockquote">Lv.{{ item.level }}</div>
<div class="policy-content flex-l flex-wrap">
<div class="policy-block">
@ -161,16 +173,15 @@
</div>
</div>
</div>
</div>
</div> -->
</div>
</el-drawer>
</div>
</template>
<script>
import { teamBillStatusMap } from '@/constant/team-type'
import { teamBillStatusMap } from "@/constant/team-type";
export default {
name: 'TeamBillDetailsDrawer',
name: "TeamBillDetailsDrawer",
props: {
row: {
type: Object,
@ -180,91 +191,89 @@ export default {
data() {
return {
teamBillStatusMap: teamBillStatusMap()
}
};
},
methods: {
handleClose() {
this.$emit('close')
this.$emit("close");
}
}
};
</script>
<style scope.d lang="scss">
.team-bill-content {
padding: 0px 10px;
.content {
margin-bottom: 10px;
}
.remark {
width: 100%;
overflow: auto;
word-wrap: break-word;
.nickname {
font-weight: bold;
}
}
.bill-row {
padding: 10px 0px;
> .bill-col {
width: 50%;
}
}
.policy {
.policy-row {
color: #333333;
.title {
padding: 5px 15px !important;
background-color: transparent !important;
}
.policy-content {
text-align: center;
.policy-block {
border: 1px solid #ffffff;
width: 33.33%;
padding: 10px;
background-color: #f1f2f3;
.label {
padding-bottom: 5px;
}
}
}
}
}
.bank-card-list {
.back-green {
background-image: linear-gradient(to left, #018aa8 0%, #00b39f 100%);
}
.back-blue {
background-image: linear-gradient(to left, #2d61cf 0%, #3893e6 100%);
}
.bank-card-item {
color: #ffffff;
margin-bottom: 0.2rem;
border-radius: 0.2rem;
padding: 10px;
.card-info {
.card-icon {
height: 50px;
width: 50px;
flex-shrink: 0;
img {
width: 100%;
height: 100%;
border-radius: 100%;
}
}
.profile {
width: 100%;
padding: 0px 10px;
.payee {
padding: 5px 0px;
}
}
}
}
}
}
</script>
<style scope.d lang="scss">
.team-bill-content {
padding: 0px 10px;
.content {
margin-bottom: 10px;
}
.remark {
width: 100%;
overflow: auto;
word-wrap: break-word;
.nickname {
font-weight: bold;
}
}
.bill-row {
padding: 10px 0px;
>.bill-col {
width: 50%;
}
}
.policy {
.policy-row {
color: #333333;
.title {
padding: 5px 15px !important;
background-color: transparent !important;
}
.policy-content {
text-align: center;
.policy-block {
border: 1px solid #FFFFFF;
width: 33.33%;
padding: 10px;
background-color: #F1F2F3;
.label {
padding-bottom: 5px;
}
}
}
}
}
.bank-card-list {
.back-green {
background-image: linear-gradient(to left, #018AA8 0%, #00B39F 100%);
}
.back-blue {
background-image: linear-gradient(to left, #2D61CF 0%, #3893E6 100%);
}
.bank-card-item {
color: #FFFFFF;
margin-bottom: .2rem;
border-radius: .2rem;
padding: 10px;
.card-info {
.card-icon {
height: 50px;
width: 50px;
flex-shrink: 0;
img {
width: 100%;
height: 100%;
border-radius: 100%;
}
}
.profile {
width: 100%;
padding: 0px 10px;
.payee {
padding: 5px 0px;
}
}
}
}
}
}
</style>
</style>

View File

@ -1,7 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<div class="filter-item" style="width: 120px;">
<sys-origin-permission-select
v-model="listQuery.sysOrigin"
@ -54,7 +53,11 @@
</el-select> -->
<div class="filter-item">
<account-input v-model="listQuery.ownUserId" :sys-origin="listQuery.sysOrigin" placeholder="代理ID" />
<account-input
v-model="listQuery.ownUserId"
:sys-origin="listQuery.sysOrigin"
placeholder="代理ID"
/>
</div>
<div class="filter-item">
@ -100,27 +103,56 @@
fit
highlight-current-row
>
<el-table-column type="index" width="50" label="No" />
<el-table-column label="代理" align="left" show-overflow-tooltip min-width="220">
<el-table-column
label="代理"
align="left"
show-overflow-tooltip
min-width="220"
>
<template slot-scope="scope">
<user-table-exhibit :user-profile="scope.row.ownUserProfile" :query-details="true" />
<user-table-exhibit
:user-profile="scope.row.ownUserProfile"
:query-details="true"
/>
</template>
</el-table-column>
<el-table-column label="区域" align="left" prop="regionName" show-overflow-tooltip min-width="100" />
<el-table-column label="归属" prop="billBelong" align="center" show-overflow-tooltip min-width="80" />
<el-table-column
label="区域"
align="left"
prop="regionName"
show-overflow-tooltip
min-width="100"
/>
<el-table-column
label="归属"
prop="billBelong"
align="center"
show-overflow-tooltip
min-width="80"
/>
<!-- <el-table-column label="状态" align="left" show-overflow-tooltip min-width="80">
<template slot-scope="scope">
<div>{{ teamBillStatusMap[scope.row.status].name }}</div>
</template>
</el-table-column> -->
<el-table-column v-if="listQuery.status === 'SETTLED' && listQuery.status !== 'PRE_CREATION'" label="工资" align="left" show-overflow-tooltip min-width="220">
<el-table-column
v-if="
listQuery.status === 'SETTLED' && listQuery.status !== 'PRE_CREATION'
"
label="工资"
align="left"
show-overflow-tooltip
min-width="220"
>
<template slot-scope="scope">
<div class="settled-row">
<div class="col ">
成员/代理: {{ scope.row.settleResult.memberSalary }}/{{ scope.row.settleResult.ownSalary }}
成员/代理: {{ scope.row.settleResult.memberSalary }}/{{
scope.row.settleResult.ownSalary
}}
</div>
<div class="col">
合计: {{ scope.row.settleResult.totalSalary }}
@ -144,15 +176,35 @@
</template>
</el-table-column> -->
<el-table-column align="center" label="备注" show-overflow-tooltip min-width="60">
<!-- <el-table-column
align="center"
label="备注"
show-overflow-tooltip
min-width="60"
>
<template slot-scope="scope">
<div class="settled-row settled-row-min"> <el-link @click.native="clickInternalRemarks(scope.row)">{{ scope.row.internalRemarks.length }}</el-link></div>
<div class="settled-row settled-row-min">
<el-link @click.native="clickInternalRemarks(scope.row)">{{
scope.row.internalRemarks ? scope.row.internalRemarks.length : 0
}}</el-link>
</div>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column label="修改人" prop="updateUserNickname" align="center" show-overflow-tooltip min-width="80" />
<el-table-column
label="修改人"
prop="updateUserNickname"
align="center"
show-overflow-tooltip
min-width="80"
/>
<el-table-column label="时间" align="center" show-overflow-tooltip min-width="200">
<el-table-column
label="时间"
align="center"
show-overflow-tooltip
min-width="200"
>
<template slot-scope="scope">
<div>创建: {{ scope.row.createTime | dateFormat }}</div>
<div>修改: {{ scope.row.updateTime | dateFormat }}</div>
@ -166,8 +218,14 @@
<i class="el-icon-more" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="clickQueryDetails(scope.row)">详情</el-dropdown-item>
<el-dropdown-item :disabled="scope.row.status === 'PRE_CREATION'" @click.native="clickInternalRemarks(scope.row)">内部备注</el-dropdown-item>
<el-dropdown-item @click.native="clickQueryDetails(scope.row)"
>详情</el-dropdown-item
>
<!-- <el-dropdown-item
:disabled="scope.row.status === 'PRE_CREATION'"
@click.native="clickInternalRemarks(scope.row)"
>内部备注</el-dropdown-item
> -->
<!-- <el-dropdown-item :disabled="scope.row.status === 'PRE_CREATION'" @click.native="clickRemarks(scope.row)">对外备注</el-dropdown-item> -->
<!-- <el-dropdown-item v-if="settleBillStatus.includes(scope.row.status)" :disabled="scope.row.status === 'PRE_CREATION'" @click.native="clickSettle(scope.row)">结算账单</el-dropdown-item>
<el-dropdown-item v-if="closeBillStatus.includes(scope.row.status)" :disabled="scope.row.status === 'PRE_CREATION'" @click.native="clickStatusChange(scope.row, 'CLOSE')">关闭订单</el-dropdown-item>
@ -180,7 +238,14 @@
</el-table>
<div v-if="listQuery.lastId" class="load-more">
<span v-if="notData">已加载全部</span>
<el-button v-else size="mini" :disabled="loadMoreLoading" :loading="loadMoreLoading" @click="clickLoadMore">加载更多</el-button>
<el-button
v-else
size="mini"
:disabled="loadMoreLoading"
:loading="loadMoreLoading"
@click="clickLoadMore"
>加载更多</el-button
>
</div>
<el-drawer
@ -234,13 +299,19 @@
style="width: 100%;"
/>
</el-form-item>
</el-form>
</div>
<div class="drawer-footer">
<el-button :disabled="importLoading" @click="exportConditionClose"> </el-button>
<el-button type="primary" :loading="importLoading" :disabled="importLoading" @click="handleExcel()"> </el-button>
<el-button :disabled="importLoading" @click="exportConditionClose"
> </el-button
>
<el-button
type="primary"
:loading="importLoading"
:disabled="importLoading"
@click="handleExcel()"
> </el-button
>
</div>
</div>
</el-drawer>
@ -248,13 +319,13 @@
<details-drawer
v-if="billDetailsVisible"
:row="thatRow"
@close="billDetailsVisible=false"
@close="billDetailsVisible = false"
/>
<team-bill-internal-remark
v-if="teamBillInternalRemarkVisible"
:row="thatRow"
@close="teamBillInternalRemarkVisible=false"
@close="teamBillInternalRemarkVisible = false"
@addRemarks="addRemarks"
@revemoRemarks="revemoRemarks"
/>
@ -262,14 +333,14 @@
<team-bill-remark
v-if="teamBillRemarkVisible"
:row="thatRow"
@close="teamBillRemarkVisible=false"
@close="teamBillRemarkVisible = false"
@success="teamBillRemarkSuccess"
/>
<team-bill-settle
v-if="teamBillSettleVisible"
:row="thatRow"
@close="teamBillSettleVisible=false"
@close="teamBillSettleVisible = false"
@success="teamBillSettleSUccess"
/>
@ -277,45 +348,55 @@
v-if="teamBillStatusVisible"
:status="teamBillChangeStatus"
:bill-id="thatRow.id"
@close="teamBillStatusVisible=false"
@close="teamBillStatusVisible = false"
@success="teamBillStatusSuccess"
/>
<team-details-drawer
v-if="teamDetailsDrawerVisible"
:team-id="thatRow.teamProfile.id"
@close="teamDetailsDrawerVisible=false"
@close="teamDetailsDrawerVisible = false"
/>
</div>
</template>
<script>
import { listTeamBillTable, excelAnchorBill } from '@/api/team'
import { pickerOptions } from '@/constant/el-const'
import { billCyclePolicyTypes, teamBillStatus, teamBillStatusMap } from '@/constant/team-type'
import { listTeamBillTable, excelAnchorBill } from "@/api/team";
import { pickerOptions } from "@/constant/el-const";
import {
billCyclePolicyTypes,
teamBillStatus,
teamBillStatusMap
} from "@/constant/team-type";
import TeamBillRemark from './team-bill-remark'
import DetailsDrawer from './details-drawer'
import TeamBillInternalRemark from './team-bill-internal-remark'
import TeamBillSettle from './team-bill-settle'
import TeamBillStatus from './team-bill-status'
import TeamDetailsDrawer from './../components/TeamDetailsDrawer'
import TeamBillRemark from "./team-bill-remark";
import DetailsDrawer from "./details-drawer";
import TeamBillInternalRemark from "./team-bill-internal-remark";
import TeamBillSettle from "./team-bill-settle";
import TeamBillStatus from "./team-bill-status";
import TeamDetailsDrawer from "./../components/TeamDetailsDrawer";
export default {
components: { TeamDetailsDrawer, DetailsDrawer, TeamBillInternalRemark, TeamBillRemark, TeamBillSettle, TeamBillStatus },
components: {
TeamDetailsDrawer,
DetailsDrawer,
TeamBillInternalRemark,
TeamBillRemark,
TeamBillSettle,
TeamBillStatus
},
data() {
const commonRules = [
{ required: true, message: '必填字段不可为空', trigger: 'blur' }
]
{ required: true, message: "必填字段不可为空", trigger: "blur" }
];
return {
importLoading: false,
teamDetailsDrawerVisible: false,
teamBillChangeStatus: '',
teamBillChangeStatus: "",
teamBillStatusVisible: false,
closeBillStatus: ['PAY_OUT', 'HANG_UP'],
hangUpBillStatus: ['PAY_OUT', 'CLOSE'],
settleBillStatus: ['PAY_OUT', 'HANG_UP'],
closeBillStatus: ["PAY_OUT", "HANG_UP"],
hangUpBillStatus: ["PAY_OUT", "CLOSE"],
settleBillStatus: ["PAY_OUT", "HANG_UP"],
teamBillSettleVisible: false,
teamBillRemarkVisible: false,
teamBillInternalRemarkVisible: false,
@ -327,23 +408,23 @@ export default {
thatRow: {},
pickerOptions,
listQuery: {
id: '',
sysOrigin: '',
teamId: '',
status: '',
settleType: '',
region: '',
startTime: '',
endTime: '',
lastId: '',
limit: ''
id: "",
sysOrigin: "",
teamId: "",
status: "",
settleType: "",
region: "",
startTime: "",
endTime: "",
lastId: "",
limit: ""
},
excelQuery: {
sysOrigin: '',
billStatusStr: '',
sysOrigin: "",
billStatusStr: "",
billStatusList: [],
region: '',
monthDate: ''
region: "",
monthDate: ""
},
exportQueryRules: {
billStatusList: commonRules,
@ -354,8 +435,8 @@ export default {
list: [],
notData: false,
loadMoreLoading: false,
rangeDate: ''
}
rangeDate: ""
};
},
watch: {
rangeDate: {
@ -363,156 +444,160 @@ export default {
deep: true,
handler(newVal) {
if (newVal && newVal.length > 0) {
this.listQuery.startTime = newVal[0]
this.listQuery.endTime = newVal[1]
return
this.listQuery.startTime = newVal[0];
this.listQuery.endTime = newVal[1];
return;
}
this.listQuery.startTime = ''
this.listQuery.endTime = ''
this.listQuery.startTime = "";
this.listQuery.endTime = "";
}
}
},
created() {
this.listQuery.status = teamBillStatus[0].value
this.listQuery.status = teamBillStatus[0].value;
},
methods: {
renderData(isReset, loadMore) {
const that = this
renderData(isReset, loadMore = false) {
const that = this;
if (!that.listQuery.sysOrigin) {
return
return;
}
if (isReset === true) {
that.list = []
that.notData = false
that.listQuery.lastId = ''
that.list = [];
that.notData = false;
that.listQuery.lastId = "";
}
that.loadMoreLoading = loadMore
that.listLoading = !loadMore
listTeamBillTable(that.listQuery).then(res => {
that.listLoading = false
that.loadMoreLoading = false
const { body } = res
const list = body || []
that.notData = list.length <= 0
if (!that.notData) {
that.list = that.list.concat(list)
that.listQuery.lastId = that.list[that.list.length - 1].id
}
}).catch(er => {
that.listLoading = false
that.loadMoreLoading = false
})
that.loadMoreLoading = loadMore;
that.listLoading = !loadMore;
listTeamBillTable(that.listQuery)
.then(res => {
that.listLoading = false;
that.loadMoreLoading = false;
const { body } = res;
const list = body || [];
that.notData = list.length <= 0;
if (!that.notData) {
that.list = that.list.concat(list);
that.listQuery.lastId = that.list[that.list.length - 1].id;
}
})
.catch(er => {
that.listLoading = false;
that.loadMoreLoading = false;
});
},
handleSearch() {
this.renderData(true)
this.renderData(true);
},
clickLoadMore() {
const that = this
that.loadMoreLoading = true
that.renderData(false, true)
const that = this;
that.loadMoreLoading = true;
that.renderData(false, true);
},
editTeamProfile(row) {
this.thatRow = row
this.teamEditVisible = true
this.thatRow = row;
this.teamEditVisible = true;
},
tableSelectable(row) {
return row.role !== 'OWN'
return row.role !== "OWN";
},
changeSysOrigin(val) {
this.handleSearch()
this.handleSearch();
// this.$refs.regionSelectPolicy.clearValue()
// this.listQuery.region = ''
},
onLoadPermissionSysOrigin(val) {
const that = this
that.renderData()
const that = this;
that.renderData();
},
clickQueryDetails(row) {
this.thatRow = row
this.billDetailsVisible = true
this.thatRow = row;
this.billDetailsVisible = true;
},
clickInternalRemarks(row) {
this.thatRow = row
this.teamBillInternalRemarkVisible = true
this.thatRow = row;
this.teamBillInternalRemarkVisible = true;
},
addRemarks(remarks) {
this.thatRow.internalRemarks.push(remarks)
this.thatRow.internalRemarks.push(remarks);
},
revemoRemarks(index) {
this.thatRow.internalRemarks.splice(index, 1)
this.thatRow.internalRemarks.splice(index, 1);
},
clickRemarks(row) {
this.thatRow = row
this.teamBillRemarkVisible = true
this.thatRow = row;
this.teamBillRemarkVisible = true;
},
teamBillRemarkSuccess(res) {
const that = this
that.$opsMessage.success()
const that = this;
that.$opsMessage.success();
if (res) {
that.thatRow.remarks = res.remarks
that.teamBillRemarkVisible = false
that.thatRow.remarks = res.remarks;
that.teamBillRemarkVisible = false;
}
},
clickSettle(row) {
const that = this
that.thatRow = row
that.teamBillSettleVisible = true
const that = this;
that.thatRow = row;
that.teamBillSettleVisible = true;
},
clickStatusChange(row, status) {
const that = this
that.thatRow = row
that.teamBillStatusVisible = true
that.teamBillChangeStatus = status
const that = this;
that.thatRow = row;
that.teamBillStatusVisible = true;
that.teamBillChangeStatus = status;
},
teamBillStatusSuccess(form) {
this.teamBillStatusVisible = false
this.thatRow.status = form.status
this.teamBillStatusVisible = false;
this.thatRow.status = form.status;
},
clickBillShare(row) {
this.$opsMessage.fail('还没有实现')
this.$opsMessage.fail("还没有实现");
},
clickQueryTeamDetails(row) {
this.thatRow = row
this.teamDetailsDrawerVisible = true
this.thatRow = row;
this.teamDetailsDrawerVisible = true;
},
teamBillSettleSUccess(form) {
this.list = this.list.filter(item => form.id !== item.id)
this.teamBillSettleVisible = false
this.$opsMessage.success()
this.list = this.list.filter(item => form.id !== item.id);
this.teamBillSettleVisible = false;
this.$opsMessage.success();
},
clickExcel() {
this.excelQuery.sysOrigin = this.listQuery.sysOrigin
this.dialogExcelVisible = true
this.excelQuery.sysOrigin = this.listQuery.sysOrigin;
this.dialogExcelVisible = true;
},
exportConditionClose() {
if (this.importLoading) {
this.$opsMessage.warn('正在执行导出, 请稍等~')
return
this.$opsMessage.warn("正在执行导出, 请稍等~");
return;
}
this.dialogExcelVisible = false
this.dialogExcelVisible = false;
},
handleExcel() {
const that = this
that.excelQuery.billStatusStr = that.excelQuery.billStatusList.join(',')
const that = this;
that.excelQuery.billStatusStr = that.excelQuery.billStatusList.join(",");
that.$refs.exportQuery.validate(valid => {
if (!valid) {
console.error('error submit!!')
return false
console.error("error submit!!");
return false;
}
that.importLoading = true
excelAnchorBill(that.excelQuery, 'AnchorWorkDetails').then(res => {
that.importLoading = false
this.dialogExcelVisible = false
}).catch(er => {
that.importLoading = false
this.dialogExcelVisible = false
this.$opsMessage.fail('下载失败!')
})
})
that.importLoading = true;
excelAnchorBill(that.excelQuery, "AnchorWorkDetails")
.then(res => {
that.importLoading = false;
this.dialogExcelVisible = false;
})
.catch(er => {
that.importLoading = false;
this.dialogExcelVisible = false;
this.$opsMessage.fail("下载失败!");
});
});
}
}
}
};
</script>
<style scoped lang="scss">
.load-more {