ts_aimz_uni/pages/copyright/applyRefund/applyRefund.vue

554 lines
16 KiB
Vue
Raw 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 class="page-container">
<swiper indicator-dots style="height: 120rpx;" autoplay indicator-active-color="#fff">
<swiper-item>
<image :src="globalData.locImg+'/banner_1.png'" style="width: 100vw;height: 120rpx;"></image>
</swiper-item>
<swiper-item>
<image :src="globalData.locImg+'/banner_2.png'" style="width: 100vw;height: 120rpx;"></image>
</swiper-item>
</swiper>
<view class="apply-box">
<text class="label">申请退款</text>
<view class="apply-item-row mt-20 ml-10">
<view class="apply-title star" style="align-self: center;">退款软著</view>
<view class="apply-content" @click="showSelProDialog">
<view :class="selPro == null? 'text-hint':'text-sel'">
{{selPro==null? '选择需要退款的软著' :selPro.projName}}
</view>
<view class="icon-arrow-solid"></view>
</view>
</view>
<view class="apply-item-column mt-20 ml-10">
<view class="apply-title star">退款原因</view>
<textarea @input="inputRemark" :value="remark" placeholder="请输入退款原因"
placeholder-style="font-size:28rpx;color:$text-gray-hint-color"
class="reason-content mt-10"></textarea>
</view>
<view class="apply-item-column mt-20 ml-10">
<view class="apply-title star">退款凭证</view>
<view class="mt-10">
<!-- 图片上传 files 4 max-->
<uni-file-picker ref="imgPicker" :value="files" :del-icon="true" limit="4" fileMediatype="image"
@delete="delImgs" :auto-upload="false" :image-styles="imageStyles"
@select="uploadImgToNet"></uni-file-picker>
</view>
<view class="hint">
*上传完整的补正通知书或者完整的补正通知书的截图,要求右上方的流水号和右下方的补正通知书的日期都得完整显示
</view>
</view>
</view>
<view class="bottom-fixed-footer">
<view class="bottom-btn-green" @click="doApply">提交</view>
</view>
<!-- 可以退款的项目dialog -->
<uni-popup ref="proDialog" type="bottom" background-color="#fff" border-radius="15rpx 15rpx 0rpx 0rpx">
<view class="bottom-dialog-container">
<view class="dialog-title-box">
<view class="search-container">
<input placeholder="请输入项目名称" class="search-input" :value="proKeywords" @input="inputSearchPro"
type="text" @confirm="doSearchKeyWord" confirm-type="search" />
</view>
<view class="icon-close size-48" @click="closeDialog"></view>
</view>
<view style="height: 600rpx;" class="mt-10">
<containerLoadingVue :loadingVisible="loadingState">
<scroll-view scroll-y style="height: 580rpx;" :lower-threshold="10" @doRefresh="doRefreshList"
refresher-background="#FFFFFF00" @scrolltolower="doLoadMore">
<view class="pro-list-box">
<radio-group @change="bindChangeSelPro">
<view v-for="(item,index) in proList" :key="index" class="pro-list-item"
:data-value="item">
<radio :value="item.projId"
:checked="tempSelPro != null && tempSelPro.projId==item.projId"></radio>
<view class="pro-list-item-left" @click="choosePro" :data-value="item">
<view class="pro-list-item-left-title">
<view class="pro-list-name">{{item.projName}}</view>
</view>
<view class="pro-list-item-left-footer">
<view class="pro-list-item-left-tag mr-10 single-line">
{{item.authorName}}
</view>
<view class="pro-list-item-left-tag">{{item.gmtCreate}}</view>
</view>
</view>
</view>
</radio-group>
<uni-load-more :status="hasMore"></uni-load-more>
</view>
</scroll-view>
</containerLoadingVue>
</view>
<view class="bottom-btn-green" @click="confirmSelPro">确定</view>
</view>
</uni-popup>
<uni-popup type="message" ref="msg">
<uni-popup-message :type="msgType" :message="msgHint" :duration="2000"></uni-popup-message>
</uni-popup>
</view>
</template>
<script>
import ProApi from '../../../common/js/net/projectApi'
import containerLoadingVue from '../../../components/container-loading.vue'
import {
inject
} from 'vue'
import {
kindList
} from '../../../common/js/data'
import {
get
} from '../../../common/js/cache/storage'
import {
uploadImgUrl,
previewUrl
} from '../../../common/js/net/mainUrl'
export default {
components: {
containerLoadingVue
},
setup() {
const globalData = inject('globalData')
return {
globalData
}
},
data() {
return {
primaryColor: this.globalData.primaryColor,
msgHint: '',
msgType: '',
selPro: null,
selType: null,
files: [],
proList: [],
tempSelPro: null,
typeList: kindList,
showSelPro: false,
showSelType: false,
tempSelType: null,
remark: '',
proKeywords: '',
proPageData: {
page: 1,
rows: 10,
keywords: ''
},
listRefreshTrig: false,
loadingState: 'loading',
hasMore: true,
imageStyles: {
width: 72,
height: 72,
border: {
color: "#F5F5F5",
width: 1,
style: 'solid',
radius: '2px'
}
},
}
},
onLoad(options) {
uni.setNavigationBarTitle({
title: '申请退款',
})
uni.setNavigationBarColor({
frontColor: '#000000', // 必写项,字体颜色仅支持#ffffff和#000000
backgroundColor: '#F0F0F0', // 传递的颜色值,仅支持十六进制颜色
animation: { // 可选项
duration: 500,
timingFunc: 'easeIn'
}
})
console.log(this.globalData.primaryColor)
},
methods: {
inputRemark(e) {
this.remark = e.detail.value
},
inputSearchPro(e) {
this.proKeywords = e.detail.value
},
//显示补正软著选择
showSelProDialog() {
const _self = this
_self.doRefreshList()
_self.tempSelPro = _self.selPro
_self.$refs.proDialog.open()
},
closeDialog() {
this.$refs.proDialog.close()
},
confirmSelPro() {
if (this.tempSelPro == null) {
this.msgHint = '请选择退款项目'
this.msgType = 'error'
this.$refs.msg.open()
} else {
this.$refs.proDialog.close()
this.selPro = this.tempSelPro
this.tempSelPro = null
}
},
doSearchKeyWord() {
this.doRefreshList()
},
//刷新
doRefreshList() {
const _self = this
_self.loadingState = 'loading'
_self.hasMore = 'more'
_self.isLoadMore = false
_self.proPageData.page = 1
_self.proPageData.keywords = _self.proKeywords
_self.getCanRefundList(true)
},
//加载更多
doLoadMore() {
//判断是否正在加载中 与是否存在更多数据
const _self = this
if (_self.isLoadMore || _self.hasMore == 'noMore') {
return
}
_self.isLoadMore = true
_self.hasMore = 'loading'
_self.proPageData.page = ++_self.proPageData.page
_self.proPageData.keywords = _self.proKeywords
_self.getCanRefundList(false)
},
getCanRefundList(isRefresh) {
const _self = this
_self.proList = isRefresh ? [] : _self.proList
_self.loadingState = isRefresh ? 'loading' : ''
ProApi.doGetCanRefundProList(_self.proPageData)
.then(res => {
console.log(res)
var status = 'success'
status = res.rows && res.rows.length > 0 ? 'success' : 'empty'
_self.loadingState = isRefresh ? status : ''
_self.proList = _self.proList.concat(res.rows)
_self.isLoadMore = false
_self.hasMore = _self.proList.length < res.total ? 'more' : 'noMore'
})
.catch(err => {
_self.loadingState = 'error'
_self.isLoadMore = false
_self.hasMore = 'more'
})
},
bindChangeSelPro(e) {
const id = e.detail.value
const item = this.proList.find(item => item.projId == id)
this.tempSelPro = item
},
choosePro(e) {
this.tempSelPro = e.currentTarget.dataset.value
},
//删除图片
delImgs(e) {
console.log('删除凭证', e)
this.files.splice(e.index, 1)
},
//上传图片
async uploadImgToNet(e) {
uni.showLoading({
title: '上传中...'
})
const tempFilePaths = e.tempFilePaths;
const token = get('token');
const header = token ? {
Auth: `Bearer ${token}`
} : {};
const that = this;
try {
// 创建一个数组存储上传结果
const results = [];
// 串行上传(一个完成后再上传下一个)
for (let i = 0; i < tempFilePaths.length; i++) {
const filePath = tempFilePaths[i];
// 使用 Promise 封装 uni.uploadFile
const result = await new Promise((resolve, reject) => {
uni.uploadFile({
url: uploadImgUrl,
header: header,
filePath: filePath,
name: 'image',
success(res) {
if (res.statusCode === 200) {
let data = res.data;
if (typeof data === 'string') {
data = JSON.parse(data);
}
resolve(data.data);
} else {
reject(new Error('上传失败状态码非200'));
}
},
fail(err) {
reject(err);
}
});
});
// 按顺序添加到结果数组
//封装参数
result.url = previewUrl + result.fileId
result.name = result.fileName
let lastDot = result.fileName.lastIndexOf('.')
result.extname = result.fileName.substring(lastDot + 1);
results.push(result);
}
// 全部上传成功后更新文件列表
that.files = that.files.concat(results);
uni.hideLoading();
} catch (error) {
uni.hideLoading();
that.msgHint = '凭证上传失败,请稍后重试';
that.msgType = 'error';
that.$refs.msg.open();
// 清空已选择的文件
that.$refs.imgPicker.clearFiles();
console.error('上传错误:', error);
}
},
//提交
doApply() {
const legal = this.checkParams()
if (legal) {
const _self = this
uni.showLoading({
title: '提交中...',
})
const ids = _self.files.map(item => item.fileId).join(',');
const data = {
projId: _self.selPro.projId,
refundReason: _self.remark,
refundVoucher: ids
}
ProApi.doApplyRefundPro(data)
.then(res => {
uni.hideLoading()
_self.msgHint = '提交操作已顺利完成,我们会尽快审核,还请耐心等待'
_self.msgType = 'success'
_self.$refs.msg.open()
//TODO 返回上一页刷新
// setTimeout(() => {
// _self.backPageRefresh()
// }, 2000);
setTimeout(() => {
uni.navigateBack({
success: function() {
let pages = getCurrentPages();
let prevPage = pages[pages.length - 2];
if (prevPage && typeof prevPage.doRefreshList ===
'function') {
prevPage.doRefreshList()
}
}
});
}, 1500)
})
.catch(err => {
wx.hideLoading()
_self.msgHint = err.msg ? err.msg : '提交失败,请稍后重试'
_self.msgType = 'error'
_self.$refs.msg.open()
})
}
},
//校验参数
checkParams() {
const _self = this
if (_self.selPro == null) {
_self.msgHint = '请选择退款软著'
_self.msgType = 'error'
_self.$refs.msg.open()
return false
}
if (_self.remark == '') {
_self.msgHint = '请输入退款原因'
_self.msgType = 'error'
_self.$refs.msg.open()
return false
}
if (_self.files.length <= 0) {
_self.msgHint = '请上传退款凭证'
_self.msgType = 'error'
_self.$refs.msg.open()
return false
}
return true
}
}
}
</script>
<style lang="scss" scoped>
.apply-box {
margin-top: 20rpx;
display: flex;
flex-direction: column;
padding: 30rpx;
background-color: $white-color;
border-radius: 10rpx;
}
.label {
font-size: 32rpx;
font-weight: bold;
}
.apply-item-row {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.apply-item-column {
display: flex;
flex-direction: column;
}
.apply-title {
font-size: 28rpx;
color: $text-color;
flex: 0.3;
}
.apply-content {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
flex: 0.7;
background-color: $bg-gray-input-color;
padding: 10rpx 15rpx;
font-size: 28rpx;
border-radius: 15rpx;
}
.reason-content {
border-radius: 15rpx;
height: 120rpx;
background-color: $bg-gray-input-color;
font-size: 28rpx;
padding: 20rpx;
}
.text-hint {
color: $text-gray-hint-color;
}
.text-sel {
color: $text-color;
}
.hint {
margin-top: 10rpx;
font-size: 26rpx;
color: $red-color;
}
.pro-list-box {
display: flex;
flex-direction: column;
}
.pro-list-item {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
border-radius: 10rpx;
padding: 30rpx;
margin: 10rpx;
box-shadow: 1rpx 1rpx 2rpx 2rpx $bg-gray-input-color;
}
.pro-list-item:nth-of-type(n+2) {
margin-top: 20rpx;
}
.pro-list-item-left {
display: flex;
flex-direction: column;
flex: 1;
margin-left: 30rpx;
}
.pro-list-item-left-title {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.pro-list-item-left-footer {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-top: 20rpx;
}
.pro-list-item-left-count {
font-size: 24rpx;
color: $text-color;
flex-wrap: nowrap;
margin-top: 4rpx;
}
.pro-list-item-left-tag {
font-size: 24rpx;
color: $text-color;
flex: .5;
}
.pro-list-name {
font-size: 26rpx;
font-weight: bold;
flex: 1;
}
.search-container {
position: relative;
align-self: center;
border-radius: 5px;
background-color: $bg-gray-color;
padding: 5px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: 100%;
margin-right: 20rpx;
}
.search-input {
box-sizing: border-box;
color: $text-color;
font-size: 28rpx;
text-align: center;
flex: 1;
background-color: $bg-gray-input-color;
border-radius: 10rpx;
}
.search-input::after {
content: '';
position: absolute;
left: 10px;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
margin-top: -1px;
background-size: cover;
background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSI2NCA2NCA4OTYgODk2IiB3aWR0aD0iMTQiIGhlaWdodD0iMTkiIHN0eWxlPSIiIGZpbHRlcj0ibm9uZSI+CiAgICAKICAgIDxnPgogICAgPHBhdGggZD0iTTkwOS42IDg1NC41TDY0OS45IDU5NC44QzY5MC4yIDU0Mi43IDcxMiA0NzkgNzEyIDQxMmMwLTgwLjItMzEuMy0xNTUuNC04Ny45LTIxMi4xLTU2LjYtNTYuNy0xMzItODcuOS0yMTIuMS04Ny45cy0xNTUuNSAzMS4zLTIxMi4xIDg3LjlDMTQzLjIgMjU2LjUgMTEyIDMzMS44IDExMiA0MTJjMCA4MC4xIDMxLjMgMTU1LjUgODcuOSAyMTIuMUMyNTYuNSA2ODAuOCAzMzEuOCA3MTIgNDEyIDcxMmM2NyAwIDEzMC42LTIxLjggMTgyLjctNjJsMjU5LjcgMjU5LjZhOC4yIDguMiAwIDAgMCAxMS42IDBsNDMuNi00My41YTguMiA4LjIgMCAwIDAgMC0xMS42ek01NzAuNCA1NzAuNEM1MjggNjEyLjcgNDcxLjggNjM2IDQxMiA2MzZzLTExNi0yMy4zLTE1OC40LTY1LjZDMjExLjMgNTI4IDE4OCA0NzEuOCAxODggNDEyczIzLjMtMTE2LjEgNjUuNi0xNTguNEMyOTYgMjExLjMgMzUyLjIgMTg4IDQxMiAxODhzMTE2LjEgMjMuMiAxNTguNCA2NS42UzYzNiAzNTIuMiA2MzYgNDEycy0yMy4zIDExNi4xLTY1LjYgMTU4LjR6IiBmaWxsPSJyZ2JhKDIwNCwyMDQsMjA0LDEpIj48L3BhdGg+CiAgICA8L2c+CiAgPC9zdmc+');
}
:deep(.file-picker__progress) {
display: none !important;
}
</style>