wxml:<view class="refuelMoney-main" style="padding-bottom: 150rpx;"> <view class="item-head"> <view class="head_top"> <text style="font-size:40rpx;" class="item-head-title">{{globalParams.taskId}}</text> </view> <!-- <view class="startbtn {{globalParams.state==0?'red_btn':globalParams.state==1?'gre_btn':globalParams.state==2?'blue_btn':'col_hui'}}">{{globalParams.state==0?'进行中':globalParams.state==1?'已完成':globalParams.state==2?'已驳回':''}}</view> --> </view> <view class="refuel-itemTextArea"> <text>出差人</text> <text>{{obj.userName}}</text> </view> <view class="refuel-itemTextArea"> <text>所属部门</text> <text>{{obj.deptName}}</text> </view> <view class="refuel-itemTextArea"> <text>职务</text> <text>{{obj.postName}}</text> </view> <view class="refuel-itemTextArea"> <text>出差开始时间</text> <text>{{starTime}}</text> </view> <view class="refuel-itemTextArea"> <text>出差结束时间</text> <text>{{endTime}}</text> </view> <view class="refuel-itemTextArea"> <text>出差天数</text> <text>{{obj.evectionDay}}</text> </view> <view class="refuel-itemTextArea"> <text>申请日期</text> <text>{{obj.applyTime}}</text> </view> <view class="refuel-itemTextArea"> <text>单据数量</text> <text>{{obj.documentNum}}</text> </view> <view class="refuel-itemTextArea"> <text>金额合计</text> <text>{{obj.totalAmount}}</text> </view> <view class="refuel-itemTextArea"> <text>出差理由</text> <text>{{obj.evectionReason}}</text> </view> <view style="display: flex;align-items: center;justify-content: space-between;border-bottom: 1rpx solid #dadada;padding:20rpx;background-color: #f0f4ff;"> <view >申请附件</view> </view> <view class="bot_fle" wx:for="{{fileList}}" wx:key="index"> <view wx:if="{{item.fileType === 1}}" > <view style="width: 200rpx;" bind:tap="tapPreviewImage" data-index="{{index}}" data-url="{{item.url}}"> <image src="{{item.url}}" mode="widthFix" style="width: 100%;" /> </view> </view> <view wx:else style="display: flex;flex-direction:row;justify-content:space-between;"> <view style="width: 70%; overflow: hidden;">{{item.name}}</view> <view class="botf_ri" style="width: 100px;text-align: right;" > <view bindtap="openFiles" data-index="{{index}}" data-id="{{item.id}}" data-fileUrl="{{item.url}}">下载</view> </view> </view> </view> <view class="itemPhoto"> <view style="display: flex;align-items: center;justify-content: space-between;background-color: #f0f4ff;padding: 20rpx ;"> <text>报销单明细</text> </view> <view wx:for="{{formList}}" wx:key="index"> <view class="refuel-item"> <text>起始日期</text> <text>{{item.startDate}}</text> </view> <view class="refuel-item"> <text>结束日期</text> <text>{{item.endDate}}</text> </view> <view class="refuel-item"> <text>报销项目</text> <text>{{item.reimbursementTypeZh}}</text> </view> <view class="refuel-itemTextArea"> <text>报销金额</text> <text>{{item.reimbursementAmount}}</text> </view> </view> </view> <view class="refuel-itemPhoto"> <text style=" background-color: #f0f4ff;">流转记录</text> </view> <view class="bot_box" wx:for="{{recordList}}" wx:key="index" wx:for-index="index" wx:for-item="item"> <view style="display: flex;align-items: center;"> <view class="raod" style="background: {{!item.comment ? 'gray' : (item.comment.type == 3 ? 'red' : '#3fc389')}};"></view> <view>{{item.taskName}}</view> </view> <view style="padding: 0 40rpx; display: flex;align-items: center;justify-content: space-between;"> <view>办理人</view> <view>{{item.assigneeName?item.assigneeName:''}}</view> </view> <view style="padding: 0 40rpx; display: flex;align-items: center;justify-content: space-between;"> <view>接收时间</view> <view>{{item.createTime?item.createTime:''}}</view> </view> <view style="padding: 0 40rpx; display: flex;align-items: center;justify-content: space-between;"> <view>处理时间</view> <view>{{item.finishTime?item.finishTime:''}}</view> </view> <view style="padding: 0 40rpx; display: flex; align-items: flex-start;justify-content: space-between;" wx:if="{{item.comment}}"> <view>备注</view> <view>{{item.comment.comment||''}}</view> </view> </view> </view> <view class="bomBtn" wx:if="{{showBtn==1}}" style="display: flex;justify-content: space-around;"> <button class=" weui-btn " data-num="1" style="width:40%;background-color:#ff7d6d !important; margin: 20rpx 0 ;" type="primary" bindtap="disallow">驳回</button> <button class=" weui-btn " data-num="2" style="width:40%;background-color:#3fc389 !important; margin: 20rpx 0 ;" type="primary" bindtap="accede">同意</button> </view> <view class="mask" catchtouchmove="preventTouchMove" wx:if="{{showModal}}"></view> <view class="modalDlg" wx:if="{{showModal}}"> <view class="clsty" > <text>处理意见</text> <textarea class="inp_tex" bindinput="cliInput" data-name="opinion" placeholder="请输入处理意见" value="{{opinion}}" /> </view> <view class="czbtn"> <view class="quxbtn" bindtap="go">取消</view> <view class="quedbtn" bindtap="determine" >确定</view> </view> </view>
js:` const app = getApp();
const AJAX = require(‘…/…/…/utils/request’);
Page({
/**
- 页面的初始数据
/
data: {
obj: {},
globalParams: {},
recordList: [],
starTime: ‘’,
endTime: ‘’,
fileList: [],
formList: [],
showBtn: ‘’, //控制审批按钮显示与隐藏
showModal: false,
opinion: ‘’,
showNum:‘’,
gas_typeList:[],
fileProgress: 0, // 文件下载进度
},
/* - 生命周期函数–监听页面加载
/
onLoad: function (options) {
this.getOctaneRating()
this.setData({
globalParams: JSON.parse(options.item),
showBtn: options.num
})
this.getList()
},
/* - 生命周期函数–监听页面初次渲染完成
*/
onReady: function () {
},
// 获取报销项目字典项接口
getOctaneRating() {
AJAX.get(‘api/dictData/list’, {
dictType: ‘travel_reimbursement’
})
.then(res => {
this.setData({
gas_typeList: res.data
})
})
},
getList() {
var that = this
wx.showLoading({
title: “加载中…”,
mask: true
})
AJAX.get(“flowable/task/processVariables/” + this.data.globalParams.taskId, {
}).then(res => {
that.getrecord()
var arr = res.data.subform
var arr2 = that.data.gas_typeList
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr2.length; j++) {
if (arr[i].reimbursementItems == arr2[j].dictValue) {
arr[i].reimbursementItems = arr2[j].dictLabel
}
}
}
that.setData({
obj: res.data,
starTime: res.data.evectionTime[0],
endTime: res.data.evectionTime[1],
fileList: res.data.annex,
formList: arr
})
const processedFileList = this.data.fileList.map(file => {
const url = file.url ?? ''; // 处理 url 为 undefined 或 null 的情况
const type = this.getFileType(url);
// 使用可选链和空值合并安全提取扩展名
const ext = url?.split('/')?.pop()?.split('.')?.pop() || '';
const key = ext ? `.${ext}` : '';
return {
...file,
fileType: type,
key: key
};
});
this.setData({
fileList: processedFileList
});
}).catch(err => {
console.log(err)
wx.showToast({
title: "数据加载失败",
icon: "none"
})
})
},
getFileType(url) {
if (!url) return 2;
const imageExtensions = [‘jpg’, ‘jpeg’, ‘png’, ‘gif’, ‘bmp’, ‘webp’];
const lowerUrl = url.toLowerCase();
const ext = lowerUrl.split(‘.’).pop();
if (imageExtensions.includes(ext)) {
return 1; // 图片类型
} else {
return 2; // 其他类型
}
},
tapPreviewImage(e) {
let url = e.currentTarget.dataset.url
wx.previewImage({
urls: [url],
current: url
})
},
// 使用外部应用打开文档
openFiles(event) {
let fileUrl = event.currentTarget.dataset.fileurl
let index = event.currentTarget.dataset.index
let key = this.data.fileList[index].key
let fileType = key.substr(1) == ‘txt’ ? ‘’ : key.substr(1)
wx.showLoading({
title: “文件加载中…”
})
let that = this;
let downloadTask = wx.downloadFile({
url: fileUrl,
success: function (res) {
wx.hideLoading()
var filePath = res.tempFilePath;
wx.openDocument({
filePath: filePath,
fileType:fileType,
success: function (res) {
},
fail: function (err) {
console.log(err)
wx.showToast({
title: "该小程序不支持打开该文件类型",
icon: "none"
})
}
});
},
fail: function (err) {
wx.showToast({
title: "文件地址解析错误!",
icon: "none"
})
}
});
// 文件下载进度监听
downloadTask.onProgressUpdate((res) => {
this.setData({
fileProgress: res.progress
})
});
},
getrecord() {
AJAX.get(“flowable/task/flowRecord”, {
procInsId: this.data.globalParams.procInsId,
deployId: this.data.globalParams.deployId,
}).then(res => {
this.setData({
recordList: res.data.flowList
})
}).catch(err => {
wx.showToast({
title: err,
icon: “none”
})
})
},
cliInput: function (e) {
this.setData({
[e.currentTarget.dataset.name]: e.detail.value,
})
},
//点击驳回按钮
disallow: function (e) {
this.setData({
showModal: true,
showNum: e.currentTarget.dataset.num
})
},
// 确认审核
determine: function () {
if (!this.data.opinion) {
wx.showToast({
title: ‘请输入处理意见’,
icon: “none”
})
return
}
if (this.data.showNum == 1) {
AJAX.post("flowable/task/apireject", {
instanceId: this.data.globalParams.procInsId,
taskId: this.data.globalParams.taskId,
comment: this.data.opinion,
}).then(res => {
wx.showToast({
title: '已驳回',
icon: "none"
})
setTimeout(() => {
wx.hideLoading();
wx.navigateBack({
delta: 1, // 返回上一级页面。
})
}, 1500)
}).catch(err => {
console.log(err)
wx.showToast({
title: "驳回失败,稍后再试",
icon: "none"
})
})
} else {
AJAX.post("flowable/task/apicomplete", {
instanceId: this.data.globalParams.procInsId,
taskId: this.data.globalParams.taskId,
comment: this.data.opinion,
applyTime: this.data.obj.applyTime,
}).then(res => {
wx.showToast({
title: '已同意',
icon: "none"
})
setTimeout(() => {
wx.hideLoading();
wx.navigateBack({
delta: 1, // 返回上一级页面。
})
}, 1500)
}).catch(err => {
console.log(err)
wx.showToast({
title: "审批失败,稍后再试",
icon: "none"
})
})
}
},
//点击同意按钮
accede: function (e) {
this.setData({
showModal: true,
showNum: e.currentTarget.dataset.num
})
},
preventTouchMove: function () {
},
/**
- 文件列表字符串转数组
- @param {Object} str
*/
getJsonSplit(str) {
if (str != “”) {
let arr = str.split(“,”)
let result = []
arr.forEach(item => {
result.push({
fileName: item.substr(item.lastIndexOf(‘/’) + 1, item.length),
fileUrl: item,
progress: 0, // 文件进度
downStatus: false, // 文件是否下载
})
})
return result
}
return []
},
go: function () {
this.setData({
showModal: false
})
}
}) wxss文件:
/* pages/applyloan/detail/detail.wxss /.saveBtn{
position: absolute;
bottom: 20rpx;
left: 50%;
transform: translate(-50%);
padding: 20rpx;
width: 90%;
text-align: center;
background-color: #035cfa;
color: #f0f4ff;
font-size: 40rpx;
}
.refuel-item {
display: flex;
align-items: center;
justify-content: space-between;
/ border-bottom: 1rpx solid #dadada; /
padding: 0 20rpx;
font-size: 40rpx;
}
.lee-color-gray-4{
color: #333 !important;
}
.refuel-itemPhoto {
display: flex;
flex-direction: column;
padding: 20rpx;
}
.bot_fle{
display: flex;
align-items: center;
padding: 20rpx;
justify-content: space-between;
}
.refuel-itemTextArea {
display: flex;
align-items: center;
justify-content: space-between;
/ border-bottom: 1rpx solid #dadada; */
padding:0 20rpx;
font-size: 40rpx;
}
.refuel-itemTextArea textarea {
min-height: 60rpx !important;
width: 300rpx !important;
text-align: right;
}
.refuel-item input {
text-align: right;
}
.refuel-item .refuel-tabList {
display: flex;
flex-wrap: wrap;
width: 70%;
}
.refuel-itemTab {
border: 1rpx solid #a1a1a1;
width: 100rpx;
padding: 5rpx 0;
color: #333333;
margin: 10rpx;
display: flex;
align-items: center;
justify-content: center;
}
.refuel-itemTabActive {
border: 1rpx solid #008cff;
color: #008cff;
}
.add_record{
background-color: #f0f4ff;
padding: 10rpx 20rpx;
color: #333;
font-weight: bold;
font-size: 40rpx;
}
.head_top{
width: 75%;
display: flex;
align-items: center;
}
.startbtn{
padding: 10rpx 20rpx;
color: #fff;
border-radius: 5rpx;
}
.red_btn{
background-color: #ff7d6d;
}
.blue_btn{
background-color: #035cfa;
}
.gre_btn{
background-color: #3fc389;
}
.col_hui{
background-color: #999;
}
.item-head {
background-color: #f0f4ff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx;
}
/* .bomBtn {
position: fixed;
background-color: #fff;
width: 100%;
z-index: 3;
bottom: 0;
padding-bottom: env(safe-area-inset-bottom);
} */
.btn {
margin: 30rpx 0 30rpx 5%;
}
.bot_box{
padding: 20rpx;
}
.raod{
width: 35rpx;
height: 35rpx;
border-radius: 50%;
background-color: #3fc389;
margin-right: 10rpx;
}
.mask{
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: #000;
z-index: 9000;
opacity: 0.7;
}
.modalDlg{
width: 94%;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%,-75%);
z-index: 9999;
background-color: #fff;
border-radius: 36rpx;
overflow: hidden;
padding: 20rpx;
}
.inp_tex{
border: 1px solid #efefef;
padding-left: 20rpx;
padding-top: 20rpx;
width: auto;
height: 200rpx;
margin-top: 20rpx;
border-radius: 10rpx;
}
.czbtn{
display: flex;align-items: center;justify-content: space-around;
}
`