|
|
|
<template>
|
|
|
|
<basic-container>
|
|
|
|
<div v-loading="details.loadingObj.pageLoading">
|
|
|
|
<!-- 标题 -->
|
|
|
|
<div class="header">结 算 信 息</div>
|
|
|
|
|
|
|
|
<!-- 主体内容 -->
|
|
|
|
<div class="main">
|
|
|
|
<!-- 运单 / 订单信息 -->
|
|
|
|
<div>
|
|
|
|
<!-- 标题 -->
|
|
|
|
<div class="header">费 用 信 息</div>
|
|
|
|
|
|
|
|
<!-- 信息 -->
|
|
|
|
<div class="info fwb">
|
|
|
|
<!-- 订单信息 -->
|
|
|
|
<div class="fwb info_title">
|
|
|
|
<span class="title"> 订单号: </span>
|
|
|
|
<span class="text"> {{ details.pageInfo.orderCode }} </span>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 运单信息 -->
|
|
|
|
<div class="info_row mt10">
|
|
|
|
<div v-for="item in details.titleOption" :key="item.label">
|
|
|
|
<span class="title"> {{ item.label }} </span>
|
|
|
|
<span class="text"> {{ details.pageInfo[item.prop] || '暂无数据' }} </span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 异动信息 -->
|
|
|
|
<div
|
|
|
|
v-if="
|
|
|
|
Number(details.pageInfo.balanceStatus) === 0 ||
|
|
|
|
Number(details.pageInfo.balanceStatus) === 1
|
|
|
|
"
|
|
|
|
>
|
|
|
|
<!-- 表单信息 -->
|
|
|
|
<el-form class="info" ref="formRef" :model="details.form" :rules="details.rules">
|
|
|
|
<el-form-item label="结算费用:">
|
|
|
|
<el-input-number
|
|
|
|
class="w100"
|
|
|
|
:value-on-clear="0"
|
|
|
|
:controls="false"
|
|
|
|
v-model="details.form.balanceFee"
|
|
|
|
:precision="2"
|
|
|
|
:step="1"
|
|
|
|
/>
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="结算备注:" class="w100">
|
|
|
|
<el-input type="textarea" v-model="details.form.balanceRemark" />
|
|
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="结算图片:" class="w100">
|
|
|
|
<el-upload
|
|
|
|
list-type="picture-card"
|
|
|
|
v-model:file-list="details.fileList"
|
|
|
|
drag
|
|
|
|
action="/api/blade-resource/oss/endpoint/put-file"
|
|
|
|
multiple
|
|
|
|
:limit="10"
|
|
|
|
:on-preview="handlePictureCardPreview"
|
|
|
|
:before-upload="beforeAvatarUpload"
|
|
|
|
:on-remove="handleRemove"
|
|
|
|
:headers="details.headers"
|
|
|
|
>
|
|
|
|
<el-icon><Plus /></el-icon>
|
|
|
|
</el-upload>
|
|
|
|
</el-form-item>
|
|
|
|
</el-form>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 异动信息 -->
|
|
|
|
<div>
|
|
|
|
<!-- 标题 -->
|
|
|
|
<div class="header algin_center">结 算 记 录</div>
|
|
|
|
|
|
|
|
<!-- 表格 -->
|
|
|
|
<div class="info">
|
|
|
|
<tablecmt
|
|
|
|
ref="tableNodeRef"
|
|
|
|
:columnList="details.columnList"
|
|
|
|
:tableData="details.data"
|
|
|
|
:loading="details.loadingObj.list"
|
|
|
|
>
|
|
|
|
<template #default="slotProps">
|
|
|
|
<el-text @click="() => handleShowImg(slotProps.scope)">查看图片</el-text>
|
|
|
|
</template>
|
|
|
|
</tablecmt>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!-- 底部站位 -->
|
|
|
|
<div class="footer"></div>
|
|
|
|
|
|
|
|
<!-- 底部按钮 -->
|
|
|
|
<div class="footer_container flex-c-c">
|
|
|
|
<!-- 关闭 -->
|
|
|
|
<el-button icon="CircleClose" @click="handleClose"> 关 闭 </el-button>
|
|
|
|
<!-- 提交 -->
|
|
|
|
<el-button
|
|
|
|
v-if="
|
|
|
|
Number(details.pageInfo.balanceStatus) === 0 ||
|
|
|
|
Number(details.pageInfo.balanceStatus) === 1
|
|
|
|
"
|
|
|
|
icon="Position"
|
|
|
|
type="primary"
|
|
|
|
@click="handleSubmit"
|
|
|
|
>
|
|
|
|
提 交
|
|
|
|
</el-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</basic-container>
|
|
|
|
|
|
|
|
<el-dialog v-model="details.popUpShow.imgVisited">
|
|
|
|
<img w-full :src="details.dialogImageUrl" alt="图片加载失败" />
|
|
|
|
</el-dialog>
|
|
|
|
|
|
|
|
<el-dialog v-model="details.popUpShow.showImgVisited">
|
|
|
|
<div class="dialog_img">
|
|
|
|
<el-image
|
|
|
|
v-for="(url, index) in details.imgList"
|
|
|
|
:key="url"
|
|
|
|
style="width: 100px; height: 100px"
|
|
|
|
:src="url"
|
|
|
|
:zoom-rate="1.2"
|
|
|
|
:max-scale="7"
|
|
|
|
:min-scale="0.2"
|
|
|
|
:preview-src-list="details.imgList"
|
|
|
|
:initial-index="index"
|
|
|
|
fit="cover"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</el-dialog>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
import { ref, reactive, toRefs } from 'vue';
|
|
|
|
import {
|
|
|
|
postFindBalanceDetail,
|
|
|
|
postAddBalanceRecord,
|
|
|
|
postFindRecordList,
|
|
|
|
} from '@/api/finance/SettlementInformation';
|
|
|
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
|
import type { UploadUserFile, UploadProps } from 'element-plus';
|
|
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
|
|
import { getOpenOrderAdvanceFindWarehouseList } from '@/api/distribution/CreateOrder.js';
|
|
|
|
import { debounce, getObjType } from '@/utils/util';
|
|
|
|
import { compressImageBlob } from '@/components/IMGcompressor/imgcompressor.js';
|
|
|
|
import { getToken } from '@/utils/auth';
|
|
|
|
import { useStore } from 'vuex';
|
|
|
|
|
|
|
|
const $route = useRoute();
|
|
|
|
const $router = useRouter();
|
|
|
|
const $store = useStore();
|
|
|
|
|
|
|
|
const details = reactive({
|
|
|
|
form: {},
|
|
|
|
fileList: [] as UploadUserFile[],
|
|
|
|
/** 弹窗 */
|
|
|
|
popUpShow: {
|
|
|
|
imgVisited: false,
|
|
|
|
/** 显示异动图片 */
|
|
|
|
showImgVisited: false,
|
|
|
|
},
|
|
|
|
dialogImageUrl: '',
|
|
|
|
data: [],
|
|
|
|
loadingObj: {
|
|
|
|
list: false,
|
|
|
|
pageLoading: false,
|
|
|
|
},
|
|
|
|
columnList: [
|
|
|
|
{
|
|
|
|
prop: '',
|
|
|
|
label: '序号',
|
|
|
|
type: 12,
|
|
|
|
values: '',
|
|
|
|
width: 55,
|
|
|
|
fixed: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
prop: 'balanceFee',
|
|
|
|
label: '结算费用',
|
|
|
|
type: 1,
|
|
|
|
values: '',
|
|
|
|
width: '150',
|
|
|
|
checkarr: [],
|
|
|
|
fixed: false,
|
|
|
|
sortable: true,
|
|
|
|
head: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
prop: 'balanceRemark',
|
|
|
|
label: '结算备注',
|
|
|
|
type: 1,
|
|
|
|
values: '',
|
|
|
|
width: '150',
|
|
|
|
checkarr: [],
|
|
|
|
fixed: false,
|
|
|
|
sortable: true,
|
|
|
|
head: false,
|
|
|
|
},
|
|
|
|
// {
|
|
|
|
// prop: 'waybillNo',
|
|
|
|
// label: '异动数值',
|
|
|
|
// type: 1,
|
|
|
|
// values: '',
|
|
|
|
// width: '150',
|
|
|
|
// checkarr: [],
|
|
|
|
// fixed: false,
|
|
|
|
// sortable: true,
|
|
|
|
// head: false,
|
|
|
|
// },
|
|
|
|
{
|
|
|
|
prop: 'changesPhotoEntityListStr',
|
|
|
|
label: '结算图片',
|
|
|
|
type: 6,
|
|
|
|
values: '',
|
|
|
|
width: '150',
|
|
|
|
checkarr: [],
|
|
|
|
fixed: false,
|
|
|
|
sortable: true,
|
|
|
|
head: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
prop: 'balanceUserName',
|
|
|
|
label: '操作人',
|
|
|
|
type: 1,
|
|
|
|
values: '',
|
|
|
|
width: '150',
|
|
|
|
checkarr: [],
|
|
|
|
fixed: false,
|
|
|
|
sortable: true,
|
|
|
|
head: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
prop: 'createTime',
|
|
|
|
label: '结算操作时间',
|
|
|
|
type: 1,
|
|
|
|
values: '',
|
|
|
|
width: '150',
|
|
|
|
checkarr: [],
|
|
|
|
fixed: false,
|
|
|
|
sortable: true,
|
|
|
|
head: false,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
|
|
|
|
titleOption: [
|
|
|
|
{
|
|
|
|
label: '结算状态:',
|
|
|
|
prop: 'balanceStatusName',
|
|
|
|
option: [
|
|
|
|
{ label: '未结算', value: 0 },
|
|
|
|
{ label: '部分结算', value: 1 },
|
|
|
|
{ label: '已结算', value: 2 },
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: '是否异常:',
|
|
|
|
prop: 'abnormalBalanceStatusName',
|
|
|
|
option: [
|
|
|
|
{ label: '否', value: 0 },
|
|
|
|
{ label: '是', value: 1 },
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: '总费用:',
|
|
|
|
prop: 'totalBalanceFee',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: '已结算费用:',
|
|
|
|
prop: 'hasBalanceFee',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: '异常费用:',
|
|
|
|
prop: 'abnormalBalanceFee',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
/** 页面数据 */
|
|
|
|
pageInfo: {},
|
|
|
|
rules: {
|
|
|
|
changesTimeStr: [{ required: true, message: '请选择异动时间', trigger: ['change', 'blur'] }],
|
|
|
|
statisticsWarehouse: [
|
|
|
|
{ required: true, message: '请选择结算网点', trigger: ['change', 'blur'] },
|
|
|
|
],
|
|
|
|
},
|
|
|
|
imgList: [],
|
|
|
|
headers: { 'Blade-Auth': 'Bearer ' + getToken() },
|
|
|
|
});
|
|
|
|
|
|
|
|
// 组件实例
|
|
|
|
/** 表单 */
|
|
|
|
const formRef = ref();
|
|
|
|
|
|
|
|
const handlePictureCardPreview: UploadProps['onPreview'] = uploadFile => {
|
|
|
|
details.dialogImageUrl = uploadFile.url!;
|
|
|
|
details.popUpShow.imgVisited = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** 获取订单异动记录列表 */
|
|
|
|
const initTransactionList = async () => {
|
|
|
|
const res = await postFindRecordList({ balanceOrderInfoId: $route.query.balanceOrderInfoId });
|
|
|
|
const { data, code } = res.data;
|
|
|
|
if (code !== 200) return;
|
|
|
|
details.data = data || [];
|
|
|
|
};
|
|
|
|
|
|
|
|
initTransactionList();
|
|
|
|
|
|
|
|
/** 订单信息 */
|
|
|
|
const onLoad = async () => {
|
|
|
|
console.log('$route :>> ', $route);
|
|
|
|
try {
|
|
|
|
details.loadingObj.pageLoading = true;
|
|
|
|
|
|
|
|
const res = await postFindBalanceDetail({
|
|
|
|
balanceOrderInfoId: $route.query.balanceOrderInfoId,
|
|
|
|
});
|
|
|
|
|
|
|
|
const { code, data } = res.data;
|
|
|
|
|
|
|
|
if (code !== 200) return;
|
|
|
|
details.pageInfo = data || {};
|
|
|
|
|
|
|
|
for (let i = 0; i < details.titleOption.length; i++) {
|
|
|
|
const value = details.titleOption[i];
|
|
|
|
|
|
|
|
if (!value.option) continue;
|
|
|
|
|
|
|
|
for (let j = 0; j < value.option.length; j++) {
|
|
|
|
const element = value.option[j];
|
|
|
|
|
|
|
|
if (element.value === Number(details.pageInfo[value.prop.replace('Name', '')])) {
|
|
|
|
details.pageInfo[value.prop] = element.label;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
details.form.balanceFee = 0;
|
|
|
|
details.form.balanceRemark = '';
|
|
|
|
|
|
|
|
console.log('details.pageInfo :>> ', details.pageInfo);
|
|
|
|
} catch (error) {
|
|
|
|
console.log('error :>> ', error);
|
|
|
|
} finally {
|
|
|
|
details.loadingObj.pageLoading = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
onLoad();
|
|
|
|
|
|
|
|
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
|
|
|
|
console.log(uploadFile, uploadFiles);
|
|
|
|
};
|
|
|
|
|
|
|
|
/** 关闭 */
|
|
|
|
const handleClose = () => {
|
|
|
|
$store.commit('DEL_TAG_CURRENT');
|
|
|
|
if ($route.query.backPath) return $router.push($route.query.backPath as string);
|
|
|
|
$router.go(-1);
|
|
|
|
};
|
|
|
|
|
|
|
|
/** 提交 */
|
|
|
|
const handleSubmit = () => {
|
|
|
|
formRef.value.validate(async valid => {
|
|
|
|
if (!valid) return;
|
|
|
|
|
|
|
|
const _imgList = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < details.fileList.length; i++) {
|
|
|
|
const value = details.fileList[i];
|
|
|
|
|
|
|
|
if (!value.response)
|
|
|
|
return ElMessage.error('存在上传失败或未上传的图片,请重新上传或等待上传完毕!');
|
|
|
|
|
|
|
|
_imgList.push({ url: value.response.data.link });
|
|
|
|
}
|
|
|
|
|
|
|
|
ElMessageBox.confirm('确定提交吗?', '提示', {
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning',
|
|
|
|
}).then(async () => {
|
|
|
|
try {
|
|
|
|
details.loadingObj.pageLoading = true;
|
|
|
|
|
|
|
|
const submitData = { ...details.form, recordPhotoEntityList: _imgList };
|
|
|
|
submitData.balanceOrderInfoId = $route.query.balanceOrderInfoId;
|
|
|
|
|
|
|
|
const res = await postAddBalanceRecord(submitData);
|
|
|
|
|
|
|
|
const { code, data } = res.data;
|
|
|
|
|
|
|
|
if (code !== 200) return;
|
|
|
|
|
|
|
|
ElMessage.success('提交成功');
|
|
|
|
|
|
|
|
handleClose();
|
|
|
|
} catch (error) {
|
|
|
|
console.log('error :>> ', error);
|
|
|
|
} finally {
|
|
|
|
details.loadingObj.pageLoading = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
/** 重置 */
|
|
|
|
const handleReset = () => {
|
|
|
|
formRef.value.resetFields();
|
|
|
|
};
|
|
|
|
|
|
|
|
/** 查看图片 */
|
|
|
|
const handleShowImg = ({ row }) => {
|
|
|
|
const { recordPhotoEntityList } = row;
|
|
|
|
|
|
|
|
if (!recordPhotoEntityList || getObjType(recordPhotoEntityList) !== 'array')
|
|
|
|
return ElMessage.warning('该结算信息没有图片');
|
|
|
|
|
|
|
|
details.imgList = recordPhotoEntityList.map(val => val.url) || [];
|
|
|
|
|
|
|
|
console.log('details.imgList :>> ', details.imgList);
|
|
|
|
details.popUpShow.showImgVisited = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
// 上传图片规则
|
|
|
|
const beforeAvatarUpload = async rawFile => {
|
|
|
|
console.log(rawFile);
|
|
|
|
if (rawFile.type !== 'image/png' && rawFile.type !== 'image/jpeg') {
|
|
|
|
ElMessage.error('图片格式只能为 png/jpg!');
|
|
|
|
return false;
|
|
|
|
} else if (rawFile.size / 1024 / 1024 > 10) {
|
|
|
|
ElMessage.error('图片大小不能大于10MB!');
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
const res = await compressImageBlob(rawFile);
|
|
|
|
return res;
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
// 标题
|
|
|
|
.header {
|
|
|
|
font-size: 20px;
|
|
|
|
font-weight: 600;
|
|
|
|
color: #333333;
|
|
|
|
// color: var(--el-color-primary);
|
|
|
|
line-height: 22px;
|
|
|
|
padding: 16px 24px;
|
|
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
|
|
|
|
.title_info {
|
|
|
|
color: #f00;
|
|
|
|
margin-left: 30px;
|
|
|
|
font-size: 14px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 主体内容
|
|
|
|
.main {
|
|
|
|
// color: var(--el-color-primary);
|
|
|
|
padding: 0 24px;
|
|
|
|
width: 100%;
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
// 标题
|
|
|
|
.header {
|
|
|
|
border: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 信息
|
|
|
|
.info {
|
|
|
|
font-size: 14px;
|
|
|
|
margin: 0 48px;
|
|
|
|
|
|
|
|
.info_title {
|
|
|
|
font-size: 16px;
|
|
|
|
font-weight: 600;
|
|
|
|
color: #333333;
|
|
|
|
line-height: 22px;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 信息行
|
|
|
|
.info_row {
|
|
|
|
display: flex;
|
|
|
|
padding: 0 10px;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
|
|
& > div {
|
|
|
|
width: 20%;
|
|
|
|
flex: none;
|
|
|
|
box-sizing: border-box;
|
|
|
|
padding: 5px 10px;
|
|
|
|
|
|
|
|
.title {
|
|
|
|
min-width: 90px;
|
|
|
|
display: inline-block;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
:deep(.el-form-item) {
|
|
|
|
margin: 0;
|
|
|
|
padding: 10px;
|
|
|
|
// width: 25%;
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
|
|
.el-form-item__label {
|
|
|
|
min-width: 120px;
|
|
|
|
font-weight: bold;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.dialog_img {
|
|
|
|
& > div {
|
|
|
|
margin: 10px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 底部站位
|
|
|
|
.footer {
|
|
|
|
height: 60px;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 底部按钮
|
|
|
|
.footer_container {
|
|
|
|
position: fixed;
|
|
|
|
bottom: 30px;
|
|
|
|
left: 0;
|
|
|
|
z-index: 10;
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
.algin_center {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
.w100 {
|
|
|
|
width: 100% !important;
|
|
|
|
}
|
|
|
|
|
|
|
|
:deep(.el-upload-dragger) {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
:deep(.el-input-number) {
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
.el-input__inner {
|
|
|
|
text-align: left !important;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|