Files
gjt_mini/pageSub/returnCarCost/detail.vue
2025-12-30 09:44:46 +08:00

1670 lines
48 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view>
<scroll-view scroll-y="true" style="height: 95vh">
<view class="container">
<u-collapse :value="['basic', 'cost']" :border="false">
<u-collapse-item title="基本信息" name="basic">
<view class="item">
<view class="title">车牌号</view>
<u--input
border="surround"
v-model="datas.plateNumber"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">客户名称</view>
<u--input
border="surround"
v-model="datas.customerName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">项目名称</view>
<u--input
border="surround"
v-model="datas.projectName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">交车时间</view>
<u--input
border="surround"
:disabledColor="'#f5f7fa'"
disabled
fontSize="26"
:value="formatDateTimeLocal(datas.handoverDate, 'hour')"
>
</u--input>
</view>
<view class="item">
<view class="title">还车时间</view>
<u--input
border="surround"
:disabledColor="'#f5f7fa'"
disabled
fontSize="26"
:value="formatDateTimeLocal(datas.returnDate, 'hour')"
>
</u--input>
</view>
<view class="item">
<view class="title">账单状态</view>
<u--input
border="surround"
v-model="billText"
disabled
fontSize="26"
></u--input>
</view>
<view class="item" :class="{ isHasOkPack: isHasOkPack }">
<view class="title">有无无忧包</view>
<u--input
:style="{ color: isHasOkPack ? '#026e0d' : '' }"
border="surround"
v-model="isHasOkPackText"
disabled
fontSize="26"
></u--input>
</view>
</u-collapse-item>
<u-collapse-item ref="costCollapse" title="费用明细" name="cost">
<view
class="item department"
v-for="t in departmentList"
:key="t.id"
>
<view class="item">
<u-row customStyle="margin-bottom: 10px;align-items: baseline;">
<u-col span="12">
<view class="title viewBtn">
{{ t.depName }}
</view>
</u-col>
</u-row>
</view>
<view class="item">
<view v-if="t.depCode === '060201'">
<view
v-if="
!t.violationManagementVoList ||
t.violationManagementVoList.length == 0
"
class="no-data"
>
未处理违章信息-暂无数据
</view>
<view v-else>
<scroll-view scroll-y="true" style="max-height: 590rpx">
<no-bad-table
:columns="violationColumns"
:list="t.violationManagementVoList"
:slot-cols="[
'index',
'unlawfulAct',
'penaltyAmount',
'remark',
]"
:span-method="objectSpanMethod"
>
<template v-slot="{ row, col, index }">
<view
v-if="col.key == 'index'"
style="white-space: pre-wrap"
>
{{ index + 1 }}
</view>
<view
v-else-if="col.key == 'unlawfulAct'"
style="white-space: pre-wrap"
>
{{ row.unlawfulAct }}
</view>
<view
v-else-if="col.key == 'penaltyAmount'"
style="white-space: pre-wrap"
>
{{ row.penaltyAmount || "" }}
</view>
<view
v-else-if="col.key == 'remark'"
style="white-space: pre-wrap"
>
{{ row.remark || "" }}
</view>
</template>
</no-bad-table>
</scroll-view>
</view>
<view
v-if="
!t.violationManagementVoList ||
t.violationManagementVoList.length == 0
"
class="no-data"
>
事故信息-暂无数据
</view>
<view v-else>
<scroll-view scroll-y="true" style="max-height: 590rpx">
<no-bad-table
:columns="accidentColumns"
:list="t.accidentItemVoList"
:slot-cols="[
'index',
'accidentTypeDicName',
'responsibilityDicName',
'remark',
]"
:span-method="objectSpanMethod"
>
<template v-slot="{ row, col, index }">
<view
v-if="col.key == 'index'"
style="white-space: pre-wrap"
>
{{ index + 1 }}
</view>
<view
v-else-if="col.key == 'accidentTypeDicName'"
style="white-space: pre-wrap"
>
{{ row.accidentTypeDicName }}
</view>
<view
v-else-if="col.key == 'responsibilityDicName'"
style="white-space: pre-wrap"
>
{{ row.responsibilityDicName || "" }}
</view>
<view
v-else-if="col.key == 'remark'"
style="white-space: pre-wrap"
>
{{ row.remark || "" }}
</view>
</template>
</no-bad-table>
</scroll-view>
</view>
</view>
<view v-else>
<scroll-view
scroll-y="true"
style="max-height: 585rpx; margin-bottom: 20rpx"
>
<no-bad-table
:columns="normalColumns"
:list="t.depDetailCostVoList"
:slot-cols="['index', 'costSubjectName', 'amount']"
:span-method="objectSpanMethod"
>
<template v-slot="{ row, col, index }">
<view
v-if="col.key == 'index'"
style="white-space: pre-wrap"
>
{{ index + 1 }}
</view>
<view
v-else-if="col.key == 'costSubjectName'"
style="white-space: pre-wrap"
>
{{ row.costSubjectName }}
</view>
<view
v-else-if="col.key == 'amount'"
style="white-space: pre-wrap"
>
{{ row.amount || "" }}
</view>
</template>
</no-bad-table>
</scroll-view>
<u-cell-group :border="false">
<u-cell
:border="false"
titleStyle="font-weight: normal;font-size: 13px"
title="费用总计"
:value="t.amount || 0"
></u-cell>
<view class="item">
<view class="title">说明</view>
<u-input
border="surround"
:disabled="true"
v-model="t.remark"
fontSize="26"
>
</u-input>
</view>
</u-cell-group>
</view>
</view>
</view>
</u-collapse-item>
</u-collapse>
<view
><view class="item">
<view class="title">保证金</view>
<u--input
border="surround"
:disabled="true"
v-model="datas.earnestMoney"
fontSize="26"
type="digit"
></u--input>
</view>
<view class="item">
<view class="title">待结算费用</view>
<u--input
border="surround"
:disabled="true"
v-model="_watiBond"
fontSize="26"
type="digit"
></u--input>
</view>
<view class="item">
<view class="title">退回客户费用</view>
<u--input
border="surround"
:disabled="true"
v-model="_returnMoney"
fontSize="26"
type="digit"
></u--input>
</view>
<view class="item">
<view class="title">客户应补缴费用</view>
<u--input
border="surround"
:disabled="true"
v-model="_overdueMoney"
fontSize="26"
type="digit"
></u--input>
</view>
<view v-if="isCoster">
<view class="item">
<view class="title required">账单状态</view>
<u-picker
:show="showBillStatusPicker"
:columns="[billStatusDic]"
keyName="dicName"
:immediateChange="true"
@confirm="confirmBillStatus"
@cancel="showBillStatusPicker = false"
>
</u-picker>
<u--input
border="surround"
:disabledColor="disabled ? '#f5f7fa' : '#ffffff'"
disabled
fontSize="26"
:value="datas.billStatusText"
@tap="!disabled && (showBillStatusPicker = true)"
>
</u--input>
</view>
<view class="item">
<view class="title required">押金条是否收回</view>
<u-picker
:show="showYesNoPicker"
:columns="[yesNoDic]"
keyName="dicName"
:immediateChange="true"
@confirm="confirmYesNo"
@cancel="showYesNoPicker = false"
>
</u-picker>
<u--input
border="surround"
:disabledColor="disabled ? '#f5f7fa' : '#ffffff'"
disabled
fontSize="26"
:value="datas.yesNoText"
@tap="!disabled && (showYesNoPicker = true)"
>
</u--input>
</view>
<view class="item">
<view class="title">押金条照片</view>
<u-upload
:fileList="fileList2"
@afterRead="afterRead"
@delete="deletePic"
:maxCount="10"
:width="155"
:height="155"
:disabled="disabled"
:deletable="!disabled"
name="2"
></u-upload>
</view>
<view class="item">
<view class="title">支付凭证</view>
<u-upload
:fileList="fileList1"
@afterRead="afterReadPdf"
@delete="deletePic"
uploadIcon="plus"
:deletable="!disabled"
:disabled="disabled"
accept="all"
multiple
:width="155"
:height="155"
name="1"
></u-upload>
</view>
<view class="item" v-for="item in yyPdfList1" :key="item.path">
<view class="line yyBlock">
<view class="text-small left">{{ item.fileName }}</view>
<view class="text-small" @tap="previewYyPdf(item)">预览</view>
</view>
</view>
</view>
<view class="item" v-if="!isCoster">
<view class="title">审批意见</view>
<u--textarea
:disabled="disabled"
border="surround"
v-model="auditOpinion"
fontSize="26"
></u--textarea>
</view>
</view>
<!-- <view v-else
><view class="item">
<view class="title">费用总计</view>
<u--input
border="surround"
:disabled="true"
v-model="_bill"
fontSize="26"
type="digit"
></u--input>
</view>
<view class="item">
<view class="title">说明</view>
<u--textarea
border="surround"
v-model="datas.remark"
fontSize="26"
:disabled="disabled"
></u--textarea> </view
></view> -->
<view class="btns">
<button
v-if="isCoster"
class="done"
:class="{ disabled: isRead }"
:disabled="isRead"
@tap="submitConfirm"
>
提交
</button>
<button
v-if="isCoster"
class="done"
:class="{ disabled: isRead }"
:disabled="isRead"
@tap="save"
>
保存
</button>
<button
v-if="!isCoster"
class="done"
:class="{ disabled: isRead }"
:disabled="isRead"
@tap="passTap"
>
通过
</button>
<button
v-if="!isCoster"
class="done"
:class="{ disabled: isRead }"
:disabled="isRead"
@tap="notPassConfirm"
>
驳回
</button>
<button class="cancel" @tap="navigateBack">取消</button>
</view>
<view>
<view class="item">
<view class="basic">审批信息</view>
</view>
<view class="item">
<u-steps :current="activities.length - 1" dot direction="column">
<u-steps-item
v-for="item in activities"
:key="item.id"
:title="`${item.nodeName} ${formatDateTime(
item.createTime,
'yyyy-MM-dd HH:mm:ss'
)}`"
>
<view class="slot-icon" slot="desc">
<view class="line">执行人:{{ item.auditorName }} </view>
<view class="line"
>审批结果:{{ item.auditStatusName }}
</view>
<view class="line">审批意见:{{ item.auditOpinion }} </view>
</view>
</u-steps-item>
</u-steps>
</view>
</view>
</view>
</scroll-view>
<u-loading-page
bg-color="#ffffff"
color="#7ba746"
font-size="24"
:loading="loading"
:loading-text="loadingText"
></u-loading-page>
<view style="width: 0px; height: 0px; overflow: hidden">
<canvas
:style="
'width: ' +
canvasWidth +
'px; height:' +
canvasHeight +
'px;left:8888px'
"
canvas-id="myCanvas"
></canvas>
</view>
</view>
</template>
<script>
import { getUser } from "@/utils/auth.js";
import { formatDateTime } from "@/utils/time.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
value: null,
checkListShow: false, // 检查单弹窗
datas: {
contractNo: "合同编号",
projectName: "项目名称",
dataList: [], // 交车单数据
hydrogenUnit: null,
earnestMoney: 0,
isSubmit: false,
discuss: "",
},
id: "",
brands: [], // 车辆品牌字典列表
truckType: [], // 车辆型号字典列表,
salesManagerDic: [], // 销售经理字典列表
yesNoDic: [], //押金条是否回收列表
billStatusDic: [], // 账单状态字典列表
userInfo: {}, // 用户信息
contractAuthorizerInformationList: [], // 授权人列表
inStoreList: [], // 在库状态车辆列表
showYesNoPicker: false,
showBillStatusPicker: false,
platNumberDisabled: true,
showPlateNumberPicker: false,
fileList1: [], // 支付凭证
fileList2: [], // 押金条
isRead: false, // 页面是否处于阅读模式
formDataList: [], // 交车检查单数据副本
hasSign: false, // 已完成签名,签署文件已生成
hasSaveCheckList: false, // 是否保存过还车检查单
compressPicMap: new Map(), // 缩略图映射key为原图value为缩略图
showSubjectPicker: [false], // 显示项目选择器
subjectList: [], // 项目列表
gpsLocation: "", // GPS定位用在水印上 以前的datas.returnLocation已经改做他用了
departmentList: [], // 部门列表
normalColumns: [
{
title: "序号",
key: "index",
width: 120,
},
{
title: "费用科目",
key: "costSubjectName",
width: 330,
},
{
title: "金额",
key: "amount",
width: 225,
},
],
violationColumns: [
{
title: "序号",
key: "index",
width: 80,
},
{
title: "违法行为",
key: "unlawfulAct",
width: 160,
},
{
title: "罚款金额",
key: "penaltyAmount",
width: 160,
},
{
title: "备注",
key: "remark",
width: 275,
},
],
accidentColumns: [
{
title: "序号",
key: "index",
width: 80,
},
{
title: "事故类型",
key: "accidentTypeDicName",
width: 160,
},
{
title: "责任划分",
key: "responsibilityDicName",
width: 160,
},
{
title: "备注",
key: "remark",
width: 275,
},
],
spanArr: [],
activities: [], // 审批流程
returnId: "", // 获取流程用id
auditOpinion: "", // 审批意见
isCoster: false, // 是否是财务主管用于结算
loading: false,
loadingText: "加载中...",
canvasWidth: 0,
canvasHeight: 0,
isHasOkPack: false, // 是否有确认收货
isHasOkPackText: "", // 是否有确认收货
billText: "", // 账单状态
// energyBalanceNum: 0, // 能源费余额Bug#7044824 bug 1009 还车费用核算未结算氢费取值错误
};
},
computed: {
yyPdfList1() {
return (
this.datas.attachmentList?.filter(
(item) =>
!["jpg", "png", "jpeg"].includes(
item.fileName.substring(item.fileName.lastIndexOf(".") + 1)
)
) || []
);
},
// 大部分组件的禁用直接用 disabled查看模式或者已完成签署
disabled() {
return this.isRead;
},
_watiBond() {
console.log("------------------");
let total = 0;
this.departmentList.forEach((t) => {
let amount = 0;
console.log(t.depDetailCostVoList);
amount =
t.depDetailCostVoList?.reduce(
(amount, item) => amount + (Number(item.amount) || 0),
0
) || 0;
console.log(amount);
total = total + amount;
});
console.log(total);
return this.safeToFixed(total, 2);
},
_returnMoney() {
let money = 0;
if (this.datas.earnestMoney - this._watiBond > 0) {
money = this.datas.earnestMoney - this._watiBond;
}
return this.safeToFixed(money, 2);
},
_overdueMoney() {
let money = 0;
if (this.datas.earnestMoney - this._watiBond < 0) {
money = this._watiBond - this.datas.earnestMoney;
}
return this.safeToFixed(money, 2);
},
isFinanceRole() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "02") {
console.log("财务部");
return true; //财务部
} else {
return false; //其他
}
},
isBussinessRole() {
console.log(this.userInfo);
if (this.userInfo.depCode === "0501") {
console.log("业务服务组-业务助理");
return true; //业务服务组-业务助理
} else {
return false; //其他
}
// const ids = this.userInfo?.roles?.map((item) => item.id) || [];
// if (ids.includes("1066262176854999040")) {
},
},
async onLoad(options) {
if (options.id) {
this.id = options.id;
}
if (options.isRead) {
this.isRead = Number(options.isRead);
}
if (!this.isRead) {
this.getLocation();
}
this.returnId = options.returnId;
this.isCoster = !!Number(options.isCoster);
this.userInfo = getUser() || {};
await this.getsubjectTowId();
await this.getDic();
await this.getCostInfo();
this.getIsHasOKPack();
//this.getEnergyBalance();
this.getQueryApproveNodes();
},
methods: {
safeToFixed(value, digits = 2) {
if (typeof value !== "number" || isNaN(value))
return "0." + "0".repeat(digits);
const factor = Math.pow(10, digits);
return (Math.round((value + Number.EPSILON) * factor) / factor).toFixed(
digits
);
},
async passTap() {
uni.showModal({
title: "提示",
content: "确认通过吗?",
success: (res) => {
if (res.confirm) {
this.passAudit();
}
},
});
},
formatDateTime(val, format) {
return val ? formatDateTime(val, format || "yyyy-MM-dd") : "";
},
getQueryApproveNodes() {
this.$api.audit
.getFlowTaskHistoryList({
formId: this.returnId,
flowTemplateId: "1097648029653057536",
})
.then((res) => {
console.log(res);
if (res.code == 200) {
console.log(res);
this.activities = res.data;
console.log(this.activities);
}
});
},
objectSpanMethod(row, column, rowIndex, columnIndex) {
if (columnIndex === 0) {
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col,
};
}
},
notPassConfirm() {
uni.showModal({
title: "提示",
content: "确认驳回吗?",
success: (res) => {
if (res.confirm) {
this.notPassAudit();
}
},
});
},
//通过
passAudit() {
this.$api.audit
.approve({
formId: this.returnId,
auditOpinion: this.auditOpinion,
flowTaskNodeCode: this.datas.flowTaskNodeCode,
flowTemplateId: "1097648029653057536",
//全部发送会报错,先只发合同编号
formData: { ...this.datas }, //{ contractNo: this.formData.contractNo }
})
.then((res) => {
if (res) {
let task = res.data;
this.$api.returnCost.changeStatusByFlowTask(task).then((res) => {
if (res) {
uni.showToast({
title: "通过成功",
icon: "success",
duration: 1500,
success() {
setTimeout(() => {
uni.navigateBack();
}, 1500);
},
});
}
});
}
});
},
notPassAudit() {
this.$api.audit
.reject({
formId: this.returnId,
auditOpinion: this.auditOpinion,
flowTaskNodeCode: this.datas.flowTaskNodeCode,
flowTemplateId: "1097648029653057536",
//全部发送会报错,先只发合同编号
formData: { ...this.datas }, //{ contractNo: this.formData.contractNo }
})
.then((res) => {
if (res) {
let task = res.data;
this.$api.returnCost.changeStatusByFlowTask(task).then((res) => {
if (res) {
uni.showToast({
title: "驳回成功",
icon: "success",
duration: 1500,
success() {
setTimeout(() => {
uni.navigateBack();
}, 1500);
},
});
}
});
}
});
},
getIsHasOKPack() {
this.$api.returnCost.getIsHasOKPack({ taskId: this.id }).then((res) => {
console.log(`res.getIsHasOKPackdata:\n`, res);
this.isHasOkPackText =
res === true ? "是" : res === false ? "否" : "未配置";
this.isHasOkPack = res || false;
});
},
// getEnergyBalance() {
// this.$api.returnCost.getEnergyBalance({ taskId: this.id }).then((res) => {
// console.log(`res.getEnergyBalance:\n`, res.data);
// this.energyBalanceNum = this.safeToFixed(res.data, 2) || 0;
// });
// },
async getCostInfo() {
await this.$api.returnCost.getCostInfo({ id: this.id }).then((res) => {
this.datas = res.data;
this.departmentList =
this.datas.depCostVoList.map((item) => {
item.depDetailCostVoList = item.depDetailCostVoList.map((t) => {
t.subjectName = this.subjectList.filter(
(s) => s.id == t.costSubjectId
)[0]?.name;
t.pictureList = t.pictureList.map((p) => {
p.url = p.path;
p.thumb = p.compressedImagePath || p.path;
return p;
});
t.attachmentList = t.attachmentList.map((p) => {
p.url = p.path;
return p;
});
return t;
});
return item;
}) || [];
this.datas.earnestMoney = this.datas.earnestMoney || 0;
this.billText = this.datas.billStatus ? "已付款" : "未付款";
this.datas.yesNoText = this.yesNoDic.find(
(s) => s.dicCode == this.datas.isGuaranteeDepositBack
)?.dicName;
this.datas.billStatusText = this.billStatusDic.find(
(s) => s.dicCode == this.datas.billStatus
)?.dicName;
this.$nextTick(() => {
this.$refs.costCollapse.init();
});
this.parseFileListBack();
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
navigateBack() {
setTimeout(() => {
uni.navigateBack();
}, 100);
},
formatDateTimeLocal(obj, type = "date") {
if (obj == null) {
return "";
}
// 精确到日
if (type == "date") {
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
}
// 精确到小时
else if (type == "hour") {
const date = new Date(obj); // 将时间戳转换为毫秒
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始
const day = String(date.getDate()).padStart(2, "0");
const hour = String(date.getHours()).padStart(2, "0");
return `${year}-${month}-${day} ${hour}:00`;
}
},
async getsubjectTowId() {
await this.$api.returnCar
.getQuerySubjectTowNames()
.then((res) => {
console.log("getsubject");
console.log(res);
this.subjectList = res;
})
.catch((err) => {
console.log("error");
this.subjectList = [];
});
},
async getDic() {
this.$api.standbyVehicle.getYesNoDic().then((res) => {
this.yesNoDic = res;
});
this.$api.standbyVehicle.getPaymentStatusDic().then((res) => {
this.billStatusDic = res;
});
},
confirmYesNo(e) {
this.datas.isGuaranteeDepositBack = e.value[0].dicCode;
this.datas.yesNoText = e.value[0].dicName;
this.showYesNoPicker = false;
},
confirmBillStatus(e) {
this.datas.billStatus = e.value[0].dicCode;
this.datas.billStatusText = e.value[0].dicName;
this.showBillStatusPicker = false;
},
// 保存
save() {
let params = { ...this.datas };
params.depCostVoList = Object.assign(
params.depCostVoList,
this.departmentList
);
params.submitType = 0;
params.pendingExpenses = this._watiBond;
this.$api.returnCost.financeSettleAccounts(params).then((res) => {
if (res) {
uni.showToast({
title: "保存成功",
icon: "success",
duration: 1500,
success() {},
});
setTimeout(() => {
uni.navigateBack();
}, 1500);
}
});
},
submitConfirm() {
uni.showModal({
title: "提示",
content: "确认提交?",
success: (res) => {
if (res.confirm) {
this.submit();
}
},
});
},
submit() {
if (!this.check()) {
return;
}
if (!Number(this.datas.billStatus)) {
this.alert("账单状态为未付款,请付款后再提交");
return;
}
let params = { ...this.datas };
params.depCostVoList = Object.assign(
params.depCostVoList,
this.departmentList
);
params.submitType = 1;
params.pendingExpenses = this._watiBond;
this.$api.returnCost.financeSettleAccounts(params).then((res) => {
if (res) {
uni.showToast({
title: "提交成功",
icon: "success",
duration: 1500,
success() {},
});
setTimeout(() => {
uni.navigateBack();
}, 1500);
}
});
},
// 在提交前检查,是否有必填字段未填写
check() {
if (this.datas.billStatus === "" || this.datas.billStatus == null) {
this.alert("请选择账单状态");
return false;
}
if (
this.datas.isGuaranteeDepositBack === "" ||
this.datas.isGuaranteeDepositBack == null
) {
this.alert("请选择押金条是否回收");
return false;
}
return true;
},
deepClone(obj) {
if (obj === null) return null;
if (typeof obj !== "object") return obj;
if (obj instanceof Date) {
let date = new Date();
date.setTime(obj.getTime());
return date;
}
if (obj instanceof RegExp) {
let re = new RegExp(obj.source);
re.lastIndex = obj.lastIndex;
return re;
}
let newObj = new obj.constructor();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = this.deepClone(obj[key]);
}
}
return newObj;
},
// 删除图片
deletePic(event) {
const fileList = this[`fileList${event.name}`];
if (fileList.some((x) => x.status == "uploading")) {
this.alert(`请等待现有文件上传完成后再操作`);
return;
}
this[`fileList${event.name}`].splice(event.index, 1);
switch (event.name) {
case "1": //公司支付凭证
this.info.attachmentList.splice(event.index, 1);
break;
}
},
// 新增图片
async afterRead(event) {
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file);
let fileListLen = this[`fileList${event.name}`].length;
lists.map((item) => {
this[`fileList${event.name}`].push({
...item,
status: "uploading",
message: "上传中",
});
});
console.log(`event.file:\n`, event.file);
console.log(lists);
for (let i = 0; i < lists.length; i++) {
this.loading = true;
this.loadingText = "添加水印中...";
const fileSize = lists[i].size / 1024 ** 2; // 图片多少MB
let waterUrl = "";
console.log(lists[i].url);
try {
waterUrl = await this.addWatermark(lists[i].url, fileSize);
} catch (e) {
console.log(`e:\n`, e);
this.alert(e.toString());
this[`fileList${event.name}`].splice(fileListLen, 1);
return;
}
const result = await this.uploadFilePromise(waterUrl);
// let result = { data: { url: waterUrl }}
let item = this[`fileList${event.name}`][fileListLen];
this[`fileList${event.name}`].splice(
fileListLen,
1,
Object.assign(item, {
status: "success",
message: "",
url: result.data?.url ?? "",
thumb: waterUrl,
})
);
fileListLen++;
const imgUrl = result.data?.url ?? "";
if (imgUrl) {
this.compressPicMap.set(
imgUrl,
result.data?.compressedImageUrl ?? ""
);
}
if (event.name == "2") {
this.datas.depositSlipPhoto.push({
path: imgUrl,
});
}
}
},
// 新增附件
async afterReadPdf(event) {
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file);
let fileListLen = this[`fileList${event.name}`].length;
lists.map((item) => {
this[`fileList${event.name}`].push({
...item,
status: "uploading",
message: "上传中",
});
});
//const fileSize = event.file.size / 1024 ** 2; // 图片多少MB
console.log(`event.file:\n`, event.file);
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url);
// let result = { data: { url: waterUrl }}
let item = this[`fileList${event.name}`][fileListLen];
this[`fileList${event.name}`].splice(
fileListLen,
1,
Object.assign(item, {
status: "success",
message: "",
url: result.data?.url ?? "",
thumb: item.type === "file" ? "/static/pdf.png" : "",
})
);
fileListLen++;
const imgUrl = result.data?.url ?? "";
const fileName = event.file[0]?.name ?? "";
const type = item.type;
if (event.name == "1") {
this.datas.attachmentList.push({
path: imgUrl,
fileName: fileName,
thumb: "/static/pdf.png",
type: type,
});
}
}
},
// 新增图片
uploadFilePromise(url) {
console.log("url");
console.log(url);
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: "/attachment/upload",
filePath: url,
name: "file",
success: (res) => {
resolve(JSON.parse(res.data || {}));
},
fail: (e) => {
reject(e);
},
});
});
},
previewYyPdf(data) {
console.log(data);
if (!data || !data.path) {
this.alert(`文件上传异常`);
return;
}
console.log(data);
const path = data.path;
this.loading = true;
this.loadingText = "加载中...";
const that = this;
uni.downloadFile({
url: path,
success: function (res) {
var filePath = res.tempFilePath;
that.loading = false;
uni.openDocument({
filePath: filePath,
success: function (res) {
that.loading = false;
},
fail() {
that.loading = false;
},
});
},
fail() {
that.alert("预览文件失败");
that.loading = false;
},
});
},
parseFileListBack() {
//this.fileList7 = this.datas.blemish.map((x) => ({ url: x }));
this.fileList1 = this.datas.attachmentList.map((x) => ({
url: x.path,
name: x.fileName,
type: x.fileName.substring(x.fileName.lastIndexOf(".") + 1) || "",
thumb: "",
}));
this.fileList2 = this.datas.depositSlipPhoto.map((x) => ({
url: x.path,
thumb: x.compressedImagePath || x.path,
}));
this.datas.depositSlipPhoto.forEach((x) => {
this.compressPicMap.set(x.path, x.compressedImagePath || x.path);
});
},
getLocation() {
uni.getLocation({
type: "wgs84",
success: (res) => {
const longitude = res.longitude;
const latitude = res.latitude;
this.$api.returnCar
.getAddress({ longitude, latitude })
.then((res) => {
this.gpsLocation = res?.data ?? "浙江省嘉兴市";
});
},
fail: (res) => {
console.log(res);
},
});
},
// 图片添加水印
async addWatermark(img, fileSize) {
const image = img;
let res1 = await new Promise((resolve, reject) => {
uni.getImageInfo({
src: img,
success: (res) => {
// 设置canvas宽高等于原图片宽高
this.canvasWidth = res.width;
this.canvasHeight = res.height;
// 创建 canvas 的绘图上下文
const ctx = uni.createCanvasContext("myCanvas", this);
// 绘制图片
ctx.drawImage(image, 0, 0, res.width, res.height);
//先加logo
// const watermarkImg = this.$refs.logo;
ctx.drawImage("/static/logo3.png", 10, res.height - 150, 200, 40.8);
//再加时间
ctx.font = "25px 黑体";
ctx.fillStyle = "#fff";
ctx.textAlign = "left";
ctx.fillText(this.getNowDateTime(), 10, res.height - 70);
//最后加地址
ctx.font = "25px 黑体";
ctx.fillStyle = "#fff";
ctx.textAlign = "left";
ctx.fillText(this.gpsLocation, 10, res.height - 30);
// 画到 canvas 中
ctx.draw(false, () => {
// 将画布转化为图片
// 设置延时,延时的秒数和图片体积正相关,越大的图片,延时越长
// 如果不延时,导出的图片可能存在有黑边、只显示部分 等问题
let timeout = 0;
if (fileSize <= 3) {
timeout = 1000;
} else {
timeout = 1000 * (fileSize / 3);
}
setTimeout(() => {
uni.canvasToTempFilePath(
{
canvasId: "myCanvas",
fileType: "jpg",
quality: fileSize <= 3 ? 1 : 0.75, // 如果不到3MB则不压缩否则压缩
success: (res) => {
console.log(res);
this.loading = false;
resolve(res.tempFilePath);
},
fail: (err) => {
this.loading = false;
reject(err);
},
},
this
);
}, timeout);
});
},
});
});
return res1;
},
getNowDateTime() {
let currentTime = new Date();
let year = currentTime.getFullYear();
let month = currentTime.getMonth() + 1;
let day = currentTime.getDate();
let hours = currentTime.getHours();
let minutes = currentTime.getMinutes();
month = month < 10 ? "0" + month : month;
day = day < 10 ? "0" + day : day;
hours = hours < 10 ? "0" + hours : hours;
minutes = minutes < 10 ? "0" + minutes : minutes;
return `${year}-${month}-${day} ${hours}:${minutes}`;
},
alert(msg) {
uni.showToast({
title: msg,
icon: "none",
duration: 1500,
});
},
},
onPullDownRefresh() {
// this.getData()
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onShow() {
if (this.loadingText != "添加水印中...") {
this.loading = false;
}
},
onHide() {},
destroyed() {},
};
</script>
<!-- <style>
page {
position: relative !important;
top: 0px !important;
}
</style> -->
<style lang="less" scoped>
.yyBlock {
justify-content: space-between;
display: flex;
font-size: 26rpx;
}
.no-data {
font-size: 26rpx;
}
.viewBtn {
display: inline-block;
font-size: 26rpx;
padding: 5rpx 10rpx;
border-radius: 10rpx;
margin-left: 10rpx;
background: #7ba746;
color: #fff;
}
.container {
// background-color: #d7d7d7;
padding: 30rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
font-size: 14px;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.truckItem {
margin-top: 30rpx;
padding: 30rpx;
border: #7ba746 solid 4rpx;
}
.demo-layout {
display: flex;
.title {
text-align: center;
}
}
.depDetailCostVoListBtns {
display: flex;
justify-content: flex-end;
align-items: center;
button {
background-color: transparent;
font-size: 26rpx;
width: 100rpx;
height: 50rpx;
line-height: 50rpx;
margin-left: 30rpx;
margin-right: 0;
padding: 0;
&.add {
background-color: #7ba746;
color: white;
}
&.del {
background-color: white;
color: #7ba746;
border: 1rpx #7ba746 solid;
}
&.disabled {
opacity: 0.6;
}
}
}
.btns {
display: flex;
align-items: center;
justify-content: space-around;
margin-top: 40rpx;
button {
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
text-align: center;
}
.cancel {
background-color: white;
color: #7ba746;
border: 1rpx #7ba746 solid;
}
.save {
background-color: #7ba746;
color: white;
}
.done {
background-color: #7ba746;
color: white;
}
.disabled {
opacity: 0.6;
}
}
/deep/ .isHasOkPack .u-input__content__field-wrapper__field {
color: #026e0d !important;
}
.item {
margin-top: 30rpx;
.title {
font-size: 26rpx;
margin-bottom: 15rpx;
&.required::before {
content: "*";
color: red;
margin-right: 3rpx;
}
}
.title.isRed {
color: #f00909;
}
.title.isGreen {
color: #017143;
}
.input {
width: 100%;
height: 60rpx;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
border-bottom: 1rpx solid #e5e5e5;
}
.tip {
font-size: 26rpx;
margin-bottom: 15rpx;
color: #aaaaaa;
position: relative;
}
.btn.checkList {
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
text-align: center;
background-color: #7ba746;
color: white;
margin-left: 0;
&.required::before {
content: "*";
color: red;
margin-right: 3rpx;
}
}
.unit {
font-size: 26rpx;
}
.btn {
width: 200rpx;
height: 80rpx;
margin-left: 0;
font-size: 26rpx;
line-height: 26rpx;
padding: 27rpx 0;
text-align: center;
color: white;
&.sign {
background-color: #7ba746;
}
&.genDocument {
background-color: #1e98d7;
}
&.disabled {
opacity: 0.6;
}
}
}
}
/deep/ .twoBtn button:first-child {
margin-bottom: 5px;
}
/deep/ .u-textarea textarea {
min-height: 100rpx !important;
font-size: 26rpx !important;
}
/deep/ .u-border {
border-width: 1rpx !important;
border-color: gray !important;
border-style: solid;
}
/deep/ .u-collapse-item__content__text {
padding: unset !important;
color: unset !important;
font-size: unset !important;
}
/deep/ .u-collapse-item {
margin-bottom: 30rpx;
}
/deep/ .uni-select {
width: 100rpx !important;
}
/deep/ .u-upload__button text {
font-size: 48rpx !important;
}
/deep/ .u-upload__deletable {
height: 42rpx !important;
width: 42rpx !important;
}
/deep/ .u-upload__deletable text {
font-size: 32rpx !important;
line-height: 32rpx !important;
}
/deep/ picker-view {
height: 450rpx !important;
}
/deep/ .uni-select__input-text {
font-size: 26rpx !important;
text-align: right !important;
}
/deep/ .uni-select__selector-item text {
font-size: 26rpx !important;
}
/deep/ .uni-select {
padding-right: 18rpx !important;
border-width: 1rpx !important;
border-color: gray !important;
border-style: solid !important;
border-top-width: 0 !important;
border-right-width: 0 !important;
border-bottom-width: 0 !important;
}
/deep/ picker-view picker-view-column:nth-of-type(5) {
display: none;
}
.changeCarBtn {
height: 76rpx;
font-size: 26rpx;
line-height: 76rpx;
border-width: 1rpx !important;
border-color: gray !important;
border-style: solid !important;
border-top-width: 0 !important;
border-right-width: 0 !important;
border-bottom-width: 0 !important;
}
/deep/ .td_wrap {
height: auto !important;
}
/deep/ .no-bad-table-wrap .td.empty-cells-for-celspan .td_wrap {
opacity: 1 !important;
}
/deep/ .no-bad-table-wrap .td.rowspan {
display: flex;
align-items: center;
justify-content: center;
}
// /deep/ checkbox-group view.td {
// width: 136.5rpx !important;
// }
// /deep/ checkbox-group view.td_wrap {
// width: 136.5rpx !important;
// }
// /deep/ .div-table-head .thead .tr view {
// width: 136.5rpx !important;
// }
/deep/ no-bad-table {
overflow-x: hidden;
}
/deep/ .no-bad-table-wrap .thead .tr .td {
background-color: #7ba746;
color: white;
}
/deep/ .no-bad-table-wrap .thead .tr .td .td_wrap {
background-color: #7ba746;
color: white;
}
/* 检查单样式结束 */
/* loading 置于顶层 */
/deep/ .u-fade-enter-to.u-fade-enter-active {
z-index: 10074 !important;
}
</style>