317 lines
10 KiB
JavaScript
317 lines
10 KiB
JavaScript
// components/fakuan-list/fakuan-list.js
|
|
import request from '../../../../utils/request.js';
|
|
|
|
const app = getApp();
|
|
const MEIYE_TIAOSHU = 5;
|
|
|
|
Component({
|
|
properties: {
|
|
status: { type: Number, value: 1, observer: 'reload' },
|
|
searchDingdan: { type: String, value: '', observer: 'reload' },
|
|
trigger: { type: Number, value: 0, observer: 'reload' }
|
|
},
|
|
|
|
data: {
|
|
list: [],
|
|
page: 1,
|
|
hasMore: true,
|
|
loading: false,
|
|
loadingMore: false,
|
|
ossImageUrl: app.globalData.ossImageUrl || '',
|
|
|
|
// 详情弹窗
|
|
showDetail: false,
|
|
detailItem: null,
|
|
|
|
// 申诉弹窗
|
|
showShensu: false,
|
|
shensuLiyou: '',
|
|
shensuTupian: [],
|
|
uploading: false,
|
|
uploadProgress: { current: 0, total: 0 },
|
|
uploadProgressWidth: '0%',
|
|
|
|
// 支付弹窗
|
|
showPay: false,
|
|
payFadan: null
|
|
},
|
|
|
|
lifetimes: {
|
|
attached() { this.reload(); }
|
|
},
|
|
|
|
methods: {
|
|
// ==================== 数据加载 ====================
|
|
reload() {
|
|
this.setData({ page: 1, list: [], hasMore: true });
|
|
this.loadData();
|
|
},
|
|
|
|
async loadData(isLoadMore = false) {
|
|
// 防止重复请求
|
|
if (this.data.loading || this.data.loadingMore) return;
|
|
|
|
if (!isLoadMore) {
|
|
this.setData({ loading: true });
|
|
} else {
|
|
// 加载更多时,如果后端已经告知没有更多数据,不发送请求
|
|
if (!this.data.hasMore) {
|
|
wx.showToast({ title: '没有更多了', icon: 'none', duration: 1000 });
|
|
return;
|
|
}
|
|
this.setData({ loadingMore: true });
|
|
}
|
|
|
|
try {
|
|
const res = await request({
|
|
url: '/yonghu/dsfklbhq',
|
|
method: 'POST',
|
|
data: {
|
|
page: this.data.page,
|
|
page_size: MEIYE_TIAOSHU,
|
|
zhuangtai: this.data.status,
|
|
sousuo_dingdan_id: this.data.searchDingdan
|
|
}
|
|
});
|
|
if (res.statusCode === 200 && res.data.code === 0) {
|
|
const data = res.data.data;
|
|
const newList = isLoadMore ? this.data.list.concat(data.list || []) : (data.list || []);
|
|
this.setData({
|
|
list: newList,
|
|
hasMore: data.has_more || false, // 以后端返回为准
|
|
page: isLoadMore ? this.data.page + 1 : 2, // 首次加载后页码为2
|
|
loading: false,
|
|
loadingMore: false
|
|
});
|
|
} else {
|
|
wx.showToast({ title: res.data?.msg || '加载失败', icon: 'none' });
|
|
this.setData({ loading: false, loadingMore: false });
|
|
}
|
|
} catch (e) {
|
|
wx.showToast({ title: '网络请求失败', icon: 'none' });
|
|
this.setData({ loading: false, loadingMore: false });
|
|
}
|
|
},
|
|
|
|
loadMore() {
|
|
if (this.data.list.length === 0) return;
|
|
this.loadData(true);
|
|
},
|
|
|
|
// ==================== 详情弹窗 ====================
|
|
openDetail(e) {
|
|
const item = e.currentTarget.dataset.item;
|
|
this.setData({ showDetail: true, detailItem: item });
|
|
},
|
|
closeDetail() {
|
|
this.setData({ showDetail: false, detailItem: null });
|
|
},
|
|
|
|
// ==================== 申诉逻辑 ====================
|
|
openShensu() {
|
|
const item = this.data.detailItem;
|
|
if (item.bohuiliyou) {
|
|
wx.showToast({ title: '该罚单申诉已被驳回', icon: 'none' });
|
|
return;
|
|
}
|
|
const existingImgs = (item.shensu_tupian || []).map(url => this.getFullUrl(url));
|
|
this.setData({
|
|
showShensu: true,
|
|
shensuLiyou: item.shensuliyou || '',
|
|
shensuTupian: existingImgs,
|
|
uploading: false,
|
|
uploadProgress: { current: 0, total: 0 },
|
|
uploadProgressWidth: '0%'
|
|
});
|
|
},
|
|
closeShensu() {
|
|
this.setData({ showShensu: false });
|
|
},
|
|
onShensuInput(e) {
|
|
this.setData({ shensuLiyou: e.detail.value.slice(0, 500) });
|
|
},
|
|
|
|
chooseImage() {
|
|
const remain = 9 - this.data.shensuTupian.length;
|
|
if (remain <= 0) return;
|
|
wx.chooseMedia({
|
|
count: remain,
|
|
mediaType: ['image'],
|
|
sourceType: ['album', 'camera'],
|
|
success: (res) => {
|
|
const newImgs = [...this.data.shensuTupian, ...res.tempFiles.map(f => f.tempFilePath)];
|
|
this.setData({ shensuTupian: newImgs.slice(0, 9) });
|
|
}
|
|
});
|
|
},
|
|
deleteShensuImg(e) {
|
|
const arr = this.data.shensuTupian;
|
|
arr.splice(e.currentTarget.dataset.index, 1);
|
|
this.setData({ shensuTupian: arr });
|
|
},
|
|
previewImage(e) {
|
|
wx.previewImage({ current: e.currentTarget.dataset.url, urls: [e.currentTarget.dataset.url] });
|
|
},
|
|
previewLocalImg(e) {
|
|
const idx = e.currentTarget.dataset.index;
|
|
wx.previewImage({ current: this.data.shensuTupian[idx], urls: this.data.shensuTupian });
|
|
},
|
|
|
|
// ==================== 提交流程 ====================
|
|
async submitShensu() {
|
|
if (!this.data.shensuLiyou.trim()) {
|
|
wx.showToast({ title: '请输入申诉理由', icon: 'none' });
|
|
return;
|
|
}
|
|
wx.showLoading({ title: '提交中...' });
|
|
try {
|
|
const newLocalPaths = this.data.shensuTupian.filter(path => !path.startsWith('http'));
|
|
let finalUrls = [];
|
|
if (newLocalPaths.length > 0) {
|
|
finalUrls = await this.piliangShangchuanShensuTupian(newLocalPaths);
|
|
if (!finalUrls) {
|
|
wx.hideLoading();
|
|
return;
|
|
}
|
|
}
|
|
const oldRemoteRelative = this.data.shensuTupian
|
|
.filter(path => path.startsWith('http'))
|
|
.map(url => url.replace(this.data.ossImageUrl, '').replace(/^\//, ''));
|
|
const allUrls = oldRemoteRelative.concat(finalUrls);
|
|
await this.doSubmitShensu(allUrls);
|
|
} catch (err) {
|
|
console.error('提交申诉失败', err);
|
|
wx.showToast({ title: err.message || '提交失败', icon: 'none' });
|
|
} finally {
|
|
wx.hideLoading();
|
|
}
|
|
},
|
|
|
|
async doSubmitShensu(tupianUrls) {
|
|
const res = await request({
|
|
url: '/yonghu/fkss',
|
|
method: 'POST',
|
|
data: {
|
|
fadan_id: this.data.detailItem.id,
|
|
shensu_liyou: this.data.shensuLiyou,
|
|
shensu_tupian_urls: tupianUrls
|
|
}
|
|
});
|
|
if (res.statusCode === 200 && res.data.code === 0) {
|
|
wx.showToast({ title: '申诉已提交', icon: 'success' });
|
|
this.setData({ showShensu: false, showDetail: false });
|
|
this.reload();
|
|
} else {
|
|
throw new Error(res.data?.msg || '提交失败');
|
|
}
|
|
},
|
|
|
|
// ==================== 图片上传到COS ====================
|
|
async piliangShangchuanShensuTupian(localPaths) {
|
|
const total = localPaths.length;
|
|
if (!total) return [];
|
|
this.setData({ uploading: true, uploadProgress: { current: 0, total: total }, uploadProgressWidth: '0%' });
|
|
|
|
let tokenData;
|
|
try {
|
|
const credRes = await request({
|
|
url: '/dingdan/dsscpz',
|
|
method: 'POST',
|
|
data: {
|
|
dingdan_id: this.data.detailItem.guanliandingdan_id || '',
|
|
fadan_id: this.data.detailItem.id,
|
|
yongtu: 'fakuan'
|
|
}
|
|
});
|
|
if (credRes.data.code !== 0) throw new Error(credRes.data.msg || '凭证获取失败');
|
|
tokenData = credRes.data.data;
|
|
} catch (e) {
|
|
wx.showToast({ title: '获取上传凭证失败', icon: 'none' });
|
|
this.setData({ uploading: false });
|
|
return null;
|
|
}
|
|
|
|
const COS = require('../../../../utils/cos-wx-sdk-v5.js');
|
|
const credentials = tokenData.credentials || tokenData;
|
|
const cos = new COS({
|
|
SimpleUploadMethod: 'putObject',
|
|
getAuthorization: (options, callback) => {
|
|
callback({
|
|
TmpSecretId: credentials.tmpSecretId,
|
|
TmpSecretKey: credentials.tmpSecretKey,
|
|
SecurityToken: credentials.sessionToken || '',
|
|
StartTime: tokenData.startTime,
|
|
ExpiredTime: tokenData.expiredTime
|
|
});
|
|
}
|
|
});
|
|
const bucket = tokenData.bucket || 'julebu-1361527063';
|
|
const region = tokenData.region || 'ap-shanghai';
|
|
|
|
const yonghuid = app.globalData.userInfo?.yonghuid || wx.getStorageSync('uid') || '0000000';
|
|
const fadanId = this.data.detailItem.id;
|
|
const keys = [];
|
|
for (let i = 0; i < total; i++) {
|
|
keys.push(`fakuan/dashoufakuan/dashoufakuanshensu/${yonghuid}_${fadanId}_${Date.now() + i}.jpg`);
|
|
}
|
|
|
|
for (let i = 0; i < total; i++) {
|
|
try {
|
|
await new Promise((resolve, reject) => {
|
|
const timeoutId = setTimeout(() => resolve(), 2000);
|
|
cos.uploadFile({
|
|
Bucket: bucket,
|
|
Region: region,
|
|
Key: keys[i],
|
|
FilePath: localPaths[i],
|
|
onProgress: (info) => {
|
|
if (Math.round(info.percent * 100) === 100) {
|
|
clearTimeout(timeoutId);
|
|
resolve();
|
|
}
|
|
}
|
|
}, (err) => {
|
|
clearTimeout(timeoutId);
|
|
if (err) reject(err);
|
|
else resolve();
|
|
});
|
|
});
|
|
} catch (err) {
|
|
wx.showToast({ title: `第 ${i + 1} 张上传失败`, icon: 'none' });
|
|
this.setData({ uploading: false });
|
|
return null;
|
|
}
|
|
const done = i + 1;
|
|
this.setData({
|
|
uploadProgress: { current: done, total: total },
|
|
uploadProgressWidth: `${((done / total) * 100).toFixed(0)}%`
|
|
});
|
|
}
|
|
this.setData({ uploading: false });
|
|
return keys;
|
|
},
|
|
|
|
// ==================== 缴纳支付 ====================
|
|
startPay() {
|
|
this.setData({
|
|
showDetail: false,
|
|
showPay: true,
|
|
payFadan: this.data.detailItem
|
|
});
|
|
},
|
|
onPayClose() {
|
|
this.setData({ showPay: false, payFadan: null });
|
|
},
|
|
onPaySuccess() {
|
|
this.setData({ showPay: false, payFadan: null });
|
|
this.reload();
|
|
},
|
|
|
|
// ==================== 工具方法 ====================
|
|
getFullUrl(url) {
|
|
if (!url) return '';
|
|
if (url.startsWith('http')) return url;
|
|
return this.data.ossImageUrl + url;
|
|
}
|
|
}
|
|
}); |