ts_aimz_uni/pages/copyright/refund/refund.vue
2025-06-24 14:08:30 +08:00

750 lines
19 KiB
Vue

<template>
<view class="page-container">
<view class="condition-box">
<view class="condition-input-box">
<view class="condition-input-container">
<icon class="ml-20" type="search" size="20"></icon>
<input class="condition-input-text" :value="keywords" @input="inputKeywords"
@confirm="doSearchKeyWord" placeholder-style="font-size:28rpx;" type="text"
confirm-type="search" placeholder="项目名称" />
<view class="icon-clear size-32 mr-10" v-if="keywords != ''" @click="clearSearch"></view>
<view @click="chooseOptions" class="condition-option-btn icon-arrow-solid">筛选</view>
</view>
<view class="add-btn" @click="applyRefund">申请退款</view>
</view>
<view :class="['condition-content', { 'visible': isShowOptions }]">
<view class="condition-content-container">
<view class="condition-content-box">
<view class="condition-content-box-left">
<view class="left-item">
<view class="left-sel-line"></view>
<view class="left-sel-text">状态</view>
</view>
</view>
<scroll-view class="condition-content-box-scroll-right" scroll-y>
<view class="condition-content-box-right">
<block v-for="(item,index) in stateList" :key="index">
<view
:class="['condition-content-right-item',tempSelState==item.value? 'right-item-sel':'right-item-normal']"
:data-value="item.value" @click="chooseState">{{item.title}}</view>
</block>
</view>
</scroll-view>
</view>
<view class="condition-content-btns">
<view class="condition-content-btn clear" @click="clearChooseOption">清除</view>
<view class="condition-content-btn cancel" @click="cancelChooseOption">取消</view>
<view class="condition-content-btn confirm" @click="confirmChooseOption">确定</view>
</view>
</view>
<view class="condition-mask" @click="cancelChooseOption"></view>
</view>
</view>
<!-- #ifdef MP-TOUTIAO || MP-WEIXIN -->
<view style="margin-top: 120rpx;">
<!-- #endif -->
<!-- #ifndef MP-TOUTIAO || MP-WEIXIN -->
<view style="margin-top: 80rpx;">
<!-- #endif -->
<ContainerLoading :loadingVisible="loadingState">
<scroll-view scroll-y style="height: 85vh;" :lower-threshold="100" refresher-background="#FFFFFF00"
@scrolltolower="doLoadMore">
<view class="repair-list-box">
<block v-for="(item,index) in refundList" :key="index">
<view class="repair-list-item">
<view class="repair-item-title-box" :data-value="item" @click="showReason">
<view class="repair-title-box">
<view :class="repairStatusColor(item.applyStatus)"
class="repair-status-content">
{{repairStatus(item.applyStatus)}}
</view>
</view>
<view class="repair-title-apply-time">{{item.gmtCreate}}</view>
</view>
<view class="divider-v mt-20"></view>
<view class="repair-name-box mt-10">
<view :data-value="item" @click="showReason" class="repair-title-content">
{{item.projName}}
</view>
<view v-if="item.applyStatus=='PENDING'" class="icon-cancel-yellow size-48"
@click="cancelApply" :data-value="item"></view>
</view>
<view :data-value="item" @click="showReason"
class="repair-reason-desc multiple-2-ellipsis">{{item.refundReason}}</view>
<view class="repair-footer-box">
<view class="repair-attr-box" :data-value="item" @click="showReason">
<view class="repair-attr-item">{{item.userInfoName}}</view>
<rich-text :nodes="moneyTxt(10,14,item.projPayment/100)"></rich-text>
</view>
</view>
</view>
</block>
<uni-load-more :status="hasMore"></uni-load-more>
</view>
</scroll-view>
</ContainerLoading>
</view>
<uni-popup type="message" ref="msg">
<uni-popup-message :type="msgType" :message="msgHint" :duration="2000"></uni-popup-message>
</uni-popup>
<DownloadProgress :isShow="downloading" :progress="downloadProgress"></DownloadProgress>
<uni-popup ref="reasonDialog" type="center" background-color="#fff" border-radius="15rpx 15rpx 15rpx 15rpx">
<view class="bottom-dialog-container" style="width: 80vw;">
<view class="approve-title">退款原因</view>
<view v-if="reasonItem != null" class="approve-content mt-10">{{reasonItem.refundReason}}</view>
<view class="approve-title mt-10">退款凭证</view>
<view v-if="reasonItem != null" class="approve-img-box mt-10">
<block v-for="(item,index) in reasonItem.refundVoucherFileKVs" :key="index">
<view class="approve-img-item single-line" @click="previewImg" :data-item="item">
{{item.value}}
</view>
</block>
</view>
<view v-if="reasonItem != null && reasonItem.gmtReview !=''" class="approve-content-box">
<view class="approve-title mt-10">审核时间</view>
<view class="approve-content mt-10">{{reasonItem.gmtReview}}</view>
<view class="approve-title mt-10">审核意见</view>
<view class="approve-content mt-10">{{reasonItem.reviewReason}}</view>
</view>
<view class="close-btn" @click="closeDialog">关闭</view>
</view>
</uni-popup>
</view>
</template>
<script>
import ProApi from '@/common/js/net/projectApi.js'
import ContainerLoading from '@/components/container-loading.vue'
import DownloadProgress from '@/components/download-progress.vue'
import {
previewUrl
} from '../../../common/js/net/mainUrl'
import {
stateList
} from '@/common/js/data.js'
import {
repairStatusColor,
repairStatus,
moneyTxt
} from '@/common/js/conver.js'
import {
get
} from '@/common/js/cache/storage.js'
export default {
components: {
ContainerLoading,
DownloadProgress
},
setup() {
},
data() {
return {
pageData: {
page: 1,
rows: 10,
applyStatus: '', //状态
projName: '' //项目名称
},
keywords: '',
stateList: stateList,
selectState: '',
tempSelState: '',
msgHint: '',
msgType: 'error',
msgShow: false,
loadingState: 'loading',
listRefreshTrig: false,
isLoadMore: false,
hasMore: true,
refundList: [],
showHint: false,
tempItem: null,
isShowOptions: false,
needRefresh: false, //是否需要刷新
reasonItem: null,
downloading: false,
downloadProgress: 0
}
},
onLoad(options) {
uni.setNavigationBarTitle({
title: '退款项目',
})
uni.setNavigationBarColor({
frontColor: '#000000', // 必写项,字体颜色仅支持#ffffff和#000000
backgroundColor: '#F0F0F0', // 传递的颜色值,仅支持十六进制颜色
animation: { // 可选项
duration: 500,
timingFunc: 'easeIn'
}
})
this.doRefreshList()
},
onShow() {
if (this.needRefresh) {
this.needRefresh = false
this.doRefreshList()
}
},
onPullDownRefresh() {
this.doRefreshList()
},
methods: {
repairStatusColor,
repairStatus,
moneyTxt,
chooseOptions() {
this.isShowOptions = !this.isShowOptions
this.tempSelState = this.selectState
},
//取消条件
cancelChooseOption() {
this.isShowOptions = false
this.tempSelState = ''
},
//清除条件
clearChooseOption() {
this.isShowOptions = false
this.selectState = ''
this.tempSelState = ''
this.doRefreshList()
},
//确定条件
confirmChooseOption() {
this.selectState = this.tempSelState
this.isShowOptions = false
this.tempSelState = ''
this.doRefreshList()
},
//去退款
applyRefund() {
uni.navigateTo({
url: '/pages/copyright/applyRefund/applyRefund',
})
},
inputKeywords(e) {
this.keywords = e.detail.value
},
clearSearch() {
this.keywords = ''
this.doRefreshList()
},
doSearchKeyWord() {
this.doRefreshList()
},
chooseState(e) {
this.tempSelState = e.currentTarget.dataset.value
},
doGetMineList(isRefresh) {
const _self = this
_self.refundList = isRefresh ? [] : _self.refundList
_self.loadingState = isRefresh ? 'loading' : ''
ProApi.doGetMineRefundProList(_self.pageData)
.then(res => {
uni.stopPullDownRefresh()
var status = 'success'
status = res.rows && res.rows.length > 0 ? 'success' : 'empty'
_self.loadingState = isRefresh ? status : ''
_self.refundList = _self.refundList.concat(res.rows)
_self.listRefreshTrig = false
_self.isLoadMore = false
_self.hasMore = _self.refundList.length < res.total ? 'more' : 'noMore'
})
.catch(err => {
uni.stopPullDownRefresh()
_self.loadingState = 'error'
_self.listRefreshTrig = false
_self.isLoadMore = false
_self.hasMore = 'more'
})
},
//下拉刷新
doRefreshList() {
const _self = this
_self.loadingState = 'loading'
_self.hasMore = 'more'
_self.isLoadMore = false
_self.pageData.page = 1
_self.pageData.projName = _self.keywords
_self.pageData.applyStatus = _self.selectState
_self.doGetMineList(true)
},
//加载更多
doLoadMore() {
//判断是否正在加载中 与是否存在更多数据
const _self = this
if (_self.isLoadMore || _self.hasMore == 'noMore') {
return
}
_self.isLoadMore = true
_self.hasMore = 'loading'
_self.pageData.page = ++_self.pageData.page
_self.pageData.projName = _self.keywords
_self.pageData.applyStatus = _self.selectState
_self.doGetMineList(false)
},
//显示详情
showReason(e) {
const _self = this
const item = e.currentTarget.dataset.value
item.refundVoucherFileKVs.map(value => {
value.url = previewUrl + value.key
return value
})
_self.reasonItem = item
_self.$refs.reasonDialog.open()
},
closeDialog() {
this.$refs.reasonDialog.close()
},
previewImg(e) {
const _self = this
_self.$refs.reasonDialog.close()
const item = e.currentTarget.dataset.item
console.log(item)
const fileName = item.value
const path = item.url
//判断是pdf还是图片
if (fileName.toLowerCase().endsWith('.pdf')) {
//文件,下载文件
_self.download(path)
} else {
//图片
const urls = [path]
uni.previewImage({
urls: urls,
})
}
},
//取消申请
cancelApply(e) {
const item = e.currentTarget.dataset.value
const _self = this
uni.showModal({
title: '警告',
content: '您确定要撤销这次退款吗?',
success: res => {
if (res.confirm) {
_self.doCancelApply(item)
}
}
})
},
//撤销
doCancelApply(item) {
const _self = this
uni.showLoading({
title: '撤销中...',
})
ProApi.doCancelRefundPro(item.projRefundApplyId)
.then(res => {
uni.hideLoading()
_self.msgType = 'success'
_self.msgHint = '撤销成功'
_self.$refs.msg.open()
_self.doRefreshList()
})
.catch(err => {
uni.hideLoading()
_self.msgType = 'error'
_self.msgHint = err.msg ? err.msg : '撤销失败,请稍后重试'
_self.$refs.msg.open()
})
},
//下载文件
doDownload(url, header) {
const _self = this
return new Promise((resolve, reject) => {
const downloadTask = uni.downloadFile({
url: url,
header: header,
success: resolve,
fail: reject
})
downloadTask.onProgressUpdate(res => {
_self.downloadProgress = res.progress
})
})
},
//点击下载
//path :文件地址
async download(path) {
const _self = this
_self.downloadProgress = 0 //重置下载进度
_self.downloading = true //显示进度
const url = path
const token = get('token')
const header = {}
if (token) {
header.Auth = `Bearer ${token}`;
}
const downloadRes = await _self.doDownload(url, header)
console.log('下载返回', downloadRes)
if (downloadRes && downloadRes.statusCode == 200) {
_self.downloadProgress = 0
_self.downloading = false
uni.openDocument({
filePath: downloadRes.tempFilePath,
showMenu: true,
success: res => {
},
fail: err => {
_self.showErr('很抱歉,文件下载出现问题。建议您稍作等待,之后再尝试下载。')
}
})
} else {
_self.showErr('很抱歉,文件下载出现问题。建议您稍作等待,之后再尝试下载。')
}
},
showErr(msg) {
const _self = this
_self.msgHint = msg
_self.msgType = 'error'
_self.showDownload = false
_self.downloading = false
_self.downloadProgress = 0
_self.$refs.msg.open()
},
},
onPullDownRefresh() {
this.doRefreshList()
uni.stopPullDownRefresh()
}
}
</script>
<style lang="scss" scoped>
.condition-content-container {
background-color: $divider-color;
padding: 0rpx 30rpx;
height: 350rpx;
display: flex;
flex-direction: column;
}
.condition-content-box {
display: flex;
flex-direction: row;
flex: 1;
padding: 20rpx;
}
.condition-content-box-left {
display: flex;
flex-direction: column;
flex: .2;
border-right: 1rpx solid $white-color;
height: 100%;
margin-top: 10rpx;
}
.condition-content-box-scroll-right {
flex: .8;
height: 230rpx;
padding: 0rpx 20rpx;
}
.condition-content-box-right {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.left-item {
display: flex;
flex-direction: row;
align-items: center;
}
.left-sel-line {
width: 8rpx;
height: 30rpx;
border-radius: 5rpx;
background-color: $primary-color;
}
.left-sel-text {
font-size: 28rpx;
margin-left: 10rpx;
}
.left-sel {
border-left: 5rpx solid $primary-color;
padding-left: 10rpx;
}
.condition-content-right-item {
white-space: nowrap;
line-height: 28rpx;
height: 28rpx;
border-radius: 10rpx;
font-size: 24rpx;
text-align: center;
padding: 5rpx 10rpx;
margin: 10rpx;
color: $text-brown-color;
}
.right-item-sel {
background-color: $primary-color-light;
}
.right-item-normal {
background-color: transparent;
}
.condition-content-btns {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-evenly;
margin-bottom: 20rpx;
margin-top: 10rpx;
}
.condition-content-btn {
font-size: 28rpx;
padding: 5rpx 60rpx;
text-align: center;
line-height: 40rpx;
height: 40rpx;
border-radius: 8rpx;
}
.cancel {
background-color: $white-color;
color: $text-gray-desc-color;
}
.clear {
background-color: $white-color;
color: $text-gray-desc-color;
}
.confirm {
background-color: $btn-green-color;
color: $white-color;
}
.add-btn {
border-radius: 8rpx;
background-color: $btn-green-color;
color: rgba(255, 255, 255, 1);
font-size: 28rpx;
text-align: center;
height: 50rpx;
margin-left: 20rpx;
line-height: 50rpx;
font-family: PingFangSC-regular;
padding: 5rpx 10rpx;
}
.add-btn:active {
background-color: $btn-green-color-active;
}
.repair-list-box {
display: flex;
flex-direction: column;
}
.repair-list-item {
display: flex;
flex-direction: column;
background-color: $white-color;
padding: 20rpx;
border-radius: 8rpx;
}
.repair-list-item:nth-of-type(n+2) {
margin-top: 20rpx;
}
.repair-item-title-box {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.repair-title-box {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
font-size: 28rpx;
}
.repair-name-box {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.repair-title-content {
font-size: 28rpx;
font-weight: bold;
flex: 1;
padding-right: 15rpx;
}
.repair-reason-desc {
margin-top: 10rpx;
font-size: 24rpx;
color: $text-gray-desc-color;
}
.repair-footer-box {
margin-top: 20rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-end;
}
.repair-attr-box {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: baseline;
width: 100%;
}
.repair-attr-item {
font-size: 24rpx;
color: $text-brown-color;
background-color: $divider-color;
padding: 5rpx 15rpx;
border-radius: 5rpx;
line-height: 40rpx;
height: 40rpx;
text-align: center;
}
.repair-attr-item:nth-of-type(n+2) {
margin-left: 10rpx;
}
.repair-title-apply-time {
font-size: 22rpx;
color: $text-gray-hint-color;
}
.repair-status-green {
background-color: $bg-green-color;
}
.repair-status-red {
background-color: $bg-red-color;
}
.repair-status-yellow {
background-color: $primary-color;
}
.repair-status-content {
padding: 2rpx 10rpx;
font-size: 22rpx;
border-radius: 5rpx;
height: 30rpx;
line-height: 30rpx;
text-align: center;
color: $text-color;
}
.repair-status-gray {
background-color: $bg-gray-deep-color;
}
.close-btn {
font-size: 28rpx;
text-align: center;
width: 120rpx;
align-self: center;
border-radius: 15rpx;
padding: 10rpx 15rpx;
color: $btn-blue-color;
}
.close-btn:active {
color: $btn-blue-color-active;
}
.approve-title {
font-size: 28rpx;
color: $text-color;
font-weight: bold;
}
.approve-content-box {
margin-top: 10rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.approve-img-box {
display: flex;
flex-direction: column;
margin-top: 15rpx;
box-sizing: border-box;
width: 100%;
}
.approve-img-item {
font-size: 24rpx;
border-radius: 5rpx;
padding: 10rpx;
text-align: left;
background-color: $gray-bg-color;
width: 100%;
margin: 10rpx;
box-sizing: border-box;
}
.approve-img-item:nth-of-type(n+2) {
margin-top: 10rpx;
}
.approve-content {
font-size: 24rpx;
margin-left: 20rpx;
text-align: left;
color: $text-gray-desc-color;
}
.approve-hint {
margin-top: 20rpx;
font-size: 24rpx;
color: $text-gray-hint-color;
}
.col-yellow {
background-color: $primary-color;
color: $text-color;
}
.col-gray {
background-color: $bg-gray-deep-color;
color: $text-gray-desc-color;
}
.col-green {
background-color: $bg-green-color;
color: $text-brown-color;
}
.col-red {
background-color: $bg-red-color;
color: $text-brown-color;
}
</style>