修正了 pages 名为拼音的问题

This commit is contained in:
2026-06-13 10:44:02 +08:00
parent 76cc4ac55e
commit 296e41a8a7
249 changed files with 29660 additions and 29505 deletions

View File

@@ -0,0 +1,684 @@
// pages/penalty/penalty.js
import request from '../../utils/request.js'
const app = getApp()
const MEIYE_TIAOSHU = 5
Page({
data: {
zongshu: 0,
daichuli: 0,
yichuli: 0,
shenfen: 0,
chufaList: [],
dangqianye: 1,
haiyougengduo: true,
jiazhaozhong: false,
jiazhaigengduo: false,
scrollHeight: 0,
showXiangqing: false,
xuanzhongChufa: {},
showShensuModal: false,
shensuLiyou: '',
shensuTupian: [],
shensuTupianUrls: [],
shangchuanJindu: 0,
shangchuanZongshu: 0,
jinduWidth: '0%',
isShangchuanzhong: false,
ossImageUrl: '',
fangdouTimer: null
},
onLoad(options) {
this.registerNotificationComponent()
this.initOSSUrl()
this.jisuanGaodu()
this.chushihuaShuju()
},
onShow() {
this.registerNotificationComponent()
},
onUnload() {
if (this.data.fangdouTimer) clearTimeout(this.data.fangdouTimer)
},
onReachBottom() {
this.shanglaShuaxin()
},
registerNotificationComponent() {
const notificationComp = this.selectComponent('#global-notification')
if (notificationComp && notificationComp.showNotification) {
app.globalData.globalNotification = {
show: (data) => notificationComp.showNotification(data),
hide: () => notificationComp.hideNotification()
}
}
},
initOSSUrl() {
const ossImageUrl = app.globalData.ossImageUrl || ''
this.setData({ ossImageUrl })
},
jisuanGaodu() {
const systemInfo = wx.getSystemInfoSync()
const windowHeight = systemInfo.windowHeight
const height = windowHeight - 200 - 100 - 40
this.setData({
scrollHeight: height > 0 ? height : 400
})
},
chushihuaShuju() {
this.setData({
dangqianye: 1,
chufaList: [],
haiyougengduo: true
})
this.jiazhuoquTongji()
this.jiazhuoquChufaList()
},
async jiazhuoquTongji() {
try {
const res = await request({
url: '/yonghu/dshqcfjl',
method: 'POST',
data: { qingqiu_tongji: true }
})
if (res.statusCode === 200 && res.data.code === 0) {
const data = res.data.data
this.setData({
zongshu: data.zongshu || 0,
daichuli: data.daichuli || 0,
yichuli: data.yichuli || 0
})
}
} catch (error) {
console.error('获取统计信息失败:', error)
}
},
async jiazhuoquChufaList(isLoadMore = false) {
if (this.data.jiazhaozhong || this.data.jiazhaigengduo) return
if (isLoadMore) {
if (!this.data.haiyougengduo) return
this.setData({ jiazhaigengduo: true })
} else {
this.setData({ jiazhaozhong: true })
}
try {
const params = {
page: this.data.dangqianye,
page_size: MEIYE_TIAOSHU
}
if (this.data.shenfen === 0) {
params.zhuangtai = 0
} else {
params.zhuangtai = 1
}
const res = await request({
url: '/yonghu/dshqcfjl',
method: 'POST',
data: params
})
//console.log('🔴【后端返回的数据】:', res.data)
if (res.statusCode === 200 && res.data.code === 0) {
const data = res.data.data
if (data.list && Array.isArray(data.list)) {
// 🔴【关键修复】在数据加载时就处理好显示字段
const processedList = data.list.map(item => {
// 处理显示时间
let displayTime = '--'
if (item.create_time) {
if (typeof item.create_time === 'number') {
displayTime = String(item.create_time)
} else if (typeof item.create_time === 'string') {
displayTime = item.create_time
} else {
displayTime = String(item.create_time)
}
}
// 处理显示状态
let displayStatus = '未知状态'
let statusClass = 'zhuangtai-weizhi'
const statusNum = Number(item.sqzhuangtai)
if (!isNaN(statusNum)) {
if (statusNum === 0) {
displayStatus = '待处罚'
statusClass = 'zhuangtai-daichuli'
} else if (statusNum === 1) {
displayStatus = '已处罚'
statusClass = 'zhuangtai-yichufa'
} else if (statusNum === 2) {
displayStatus = '已驳回'
statusClass = 'zhuangtai-yibohui'
} else if (statusNum === 3) {
displayStatus = '申诉中'
statusClass = 'zhuangtai-shensuzhong'
}
}
// 处理图片URL在数据加载时就拼接完整URL
const fullZhengjuTupian = (item.zhengju_tupian || []).map(url => this.getFullImageUrl(url))
const fullShensuTupian = (item.shensu_tupian || []).map(url => this.getFullImageUrl(url))
return {
...item,
display_time: displayTime, // 🔴 处理好的显示时间
display_status: displayStatus, // 🔴 处理好的显示状态
status_class: statusClass, // 🔴 处理好的状态样式类
zhengju_tupian: item.zhengju_tupian || [],
shensu_tupian: item.shensu_tupian || [],
full_zhengju_tupian: fullZhengjuTupian, // 🔴 完整图片URL
full_shensu_tupian: fullShensuTupian // 🔴 完整图片URL
}
})
//console.log('🔴【处理后的数据】:', processedList)
let newList
if (isLoadMore) {
newList = [...this.data.chufaList, ...processedList]
} else {
newList = processedList
}
const hasMore = data.has_more === true
this.setData({
chufaList: newList,
haiyougengduo: hasMore,
dangqianye: this.data.dangqianye + 1
})
} else {
this.setData({ haiyougengduo: false })
}
} else {
throw new Error(res.data?.msg || '加载处罚记录失败')
}
} catch (error) {
console.error('加载处罚记录失败:', error)
wx.showToast({
title: error.message || '加载失败',
icon: 'none'
})
this.setData({ haiyougengduo: false })
} finally {
if (isLoadMore) {
this.setData({ jiazhaigengduo: false })
} else {
this.setData({ jiazhaozhong: false })
}
}
},
qiehuanShenfen(e) {
const type = parseInt(e.currentTarget.dataset.type)
if (this.data.shenfen === type) return
this.setData({
shenfen: type,
dangqianye: 1,
chufaList: [],
haiyougengduo: true
})
this.jiazhuoquChufaList()
},
shanglaShuaxin() {
if (this.data.fangdouTimer) clearTimeout(this.data.fangdouTimer)
const timer = setTimeout(() => {
if (this.data.jiazhaozhong || this.data.jiazhaigengduo) return
if (!this.data.haiyougengduo) return
this.jiazhuoquChufaList(true)
}, 300)
this.setData({ fangdouTimer: timer })
},
chakanXiangqing(e) {
const item = e.currentTarget.dataset.item
this.setData({
xuanzhongChufa: item,
showXiangqing: true
})
},
guanbiXiangqing() {
this.setData({
showXiangqing: false,
xuanzhongChufa: {}
})
},
openShensuModal() {
if (this.data.xuanzhongChufa.ssliyou ||
(this.data.xuanzhongChufa.shensu_tupian && this.data.xuanzhongChufa.shensu_tupian.length > 0)) {
wx.showToast({
title: '您已经提交过申诉,请等待处理结果',
icon: 'none'
})
return
}
this.setData({
showShensuModal: true,
shensuLiyou: '',
shensuTupian: [],
shensuTupianUrls: [],
shangchuanJindu: 0,
shangchuanZongshu: 0,
jinduWidth: '0%'
})
},
closeShensuModal() {
this.setData({
showShensuModal: false,
shensuLiyou: '',
shensuTupian: [],
shensuTupianUrls: []
})
},
onShensuLiyouInput(e) {
const value = e.detail.value.slice(0, 500)
this.setData({ shensuLiyou: value })
},
chooseShensuTupian() {
if (this.data.isShangchuanzhong) return
const shengyu = 9 - this.data.shensuTupian.length
if (shengyu <= 0) {
wx.showToast({
title: '最多只能上传9张图片',
icon: 'none'
})
return
}
wx.chooseMedia({
count: shengyu,
mediaType: ['image'],
sourceType: ['album', 'camera'],
success: (res) => {
const newTupian = [...this.data.shensuTupian, ...res.tempFiles.map(file => file.tempFilePath)]
this.setData({ shensuTupian: newTupian.slice(0, 9) })
}
})
},
deleteShensuTupian(e) {
const index = e.currentTarget.dataset.index
const newTupian = [...this.data.shensuTupian]
newTupian.splice(index, 1)
this.setData({ shensuTupian: newTupian })
},
yulanShensuTupian(e) {
const index = e.currentTarget.dataset.index
const urls = this.data.shensuTupian
if (!urls[index]) return
wx.previewImage({
current: urls[index],
urls: urls
})
},
lianxiKefu() {
const kefuLink = app.globalData.kefuConfig?.link || '';
const corpId = app.globalData.kefuConfig?.enterpriseId || '';
if (!kefuLink || !corpId) {
wx.showToast({
title: '客服配置未加载',
icon: 'none'
});
return;
}
wx.openCustomerServiceChat({
extInfo: { url: kefuLink },
corpId: corpId,
success: (res) => {
console.log('跳转客服成功', res);
},
fail: (err) => {
console.error('跳转客服失败', err);
wx.showToast({
title: '暂时无法连接客服',
icon: 'none'
});
}
});
},
async getCOSZhengshu() {
try {
const res = await request({
url: '/dingdan/dsscpz',
method: 'POST',
data: {
dingdan_id: this.data.xuanzhongChufa.dingdan_id,
yongtu: 'chufa'
}
})
if (res.statusCode === 200 && res.data.code === 0 && res.data.data) {
return res.data.data
} else {
throw new Error(res?.data?.msg || '获取上传凭证失败')
}
} catch (error) {
console.error('获取COS凭证失败:', error)
throw error
}
},
initCOSClient(tokenData) {
const COS = require('../../utils/cos-wx-sdk-v5.js')
const credentials = tokenData.credentials || tokenData
const bucket = tokenData.bucket || 'julebu-1361527063'
const region = tokenData.region || 'ap-shanghai'
const cos = new COS({
SimpleUploadMethod: 'putObject',
getAuthorization: async (options, callback) => {
const authParams = {
TmpSecretId: credentials.tmpSecretId,
TmpSecretKey: credentials.tmpSecretKey,
SecurityToken: credentials.sessionToken || '',
StartTime: tokenData.startTime || Math.floor(Date.now() / 1000),
ExpiredTime: tokenData.expiredTime || (Math.floor(Date.now() / 1000) + 7200)
}
callback(authParams)
}
})
return { cos, bucket, region }
},
async shangchuanDanZhangTupian(filePath, cosKey, index, cosInstance, bucket, region) {
return new Promise((resolve) => {
const timeoutId = setTimeout(() => {
resolve({ status: 'optimistic_success', key: cosKey })
}, 2000)
cosInstance.uploadFile({
Bucket: bucket,
Region: region,
Key: cosKey,
FilePath: filePath,
onProgress: (progressInfo) => {
const percent = Math.round(progressInfo.percent * 100)
if (percent === 100) {
clearTimeout(timeoutId)
resolve({ status: 'optimistic_success', key: cosKey })
}
}
})
})
},
async piliangShangchuanShensuTupian() {
const total = this.data.shensuTupian.length
if (total === 0) return []
this.setData({
shangchuanZongshu: total,
shangchuanJindu: 0,
jinduWidth: '0%',
isShangchuanzhong: true
})
let yonghuid = ''
// 方案1直接从全局缓存获取
const uid = wx.getStorageSync('uid')
if (uid) {
yonghuid = String(uid).padStart(7, '0')
//console.log('🔴【从uid获取yonghuid】', yonghuid)
}
// 方案2如果还没有从用户信息获取
if (!yonghuid && app.globalData.userInfo && app.globalData.userInfo.yonghuid) {
yonghuid = String(app.globalData.userInfo.yonghuid).padStart(7, '0')
//console.log('🔴【从userInfo获取yonghuid】', yonghuid)
}
// 方案3如果还没有直接提示并返回
if (!yonghuid) {
wx.showToast({
title: '请先登录',
icon: 'none'
})
this.setData({ isShangchuanzhong: false })
return []
}
const preGeneratedUrls = []
for (let i = 0; i < total; i++) {
const timestamp = Date.now() + i
const random = Math.floor(Math.random() * 10000)
const fileExt = this.getFileExtension(this.data.shensuTupian[i])
const fileName = `${yonghuid}_${timestamp}_${random}${fileExt}`
const cosKey = `a_long/chfajltp/dssstp/${fileName}`
preGeneratedUrls.push(cosKey)
}
let cosClient, bucket, region
try {
const tokenData = await this.getCOSZhengshu()
const { cos, bucket: cosBucket, region: cosRegion } = this.initCOSClient(tokenData)
cosClient = cos
bucket = cosBucket
region = cosRegion
} catch (error) {
wx.showToast({ title: '上传初始化失败', icon: 'none' })
this.setData({ isShangchuanzhong: false })
return []
}
const uploadTasks = []
for (let i = 0; i < total; i++) {
const task = this.shangchuanDanZhangTupian(
this.data.shensuTupian[i],
preGeneratedUrls[i],
i,
cosClient,
bucket,
region
).then((result) => {
const currentDone = i + 1
const jinduPercent = ((currentDone / total) * 100).toFixed(0)
this.setData({
shangchuanJindu: currentDone,
jinduWidth: `${jinduPercent}%`
})
return result
})
uploadTasks.push(task)
}
await Promise.all(uploadTasks)
this.setData({ isShangchuanzhong: false })
return preGeneratedUrls
},
getFileExtension(filePath) {
const lastDotIndex = filePath.lastIndexOf('.')
if (lastDotIndex === -1) return '.jpg'
const ext = filePath.substring(lastDotIndex).toLowerCase()
const allowedExts = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
return allowedExts.includes(ext) ? ext : '.jpg'
},
async submitShensu() {
if (!this.data.shensuLiyou.trim()) {
wx.showToast({ title: '请输入申诉理由', icon: 'none' }); return
}
if (this.data.shensuTupian.length === 0) {
wx.showModal({
title: '提示',
content: '未上传任何图片,确定要提交申诉吗?',
success: async (res) => {
if (res.confirm) await this.tijiaoShensuData([])
}
})
return
}
wx.showToast({ title: '开始上传图片...', icon: 'none' })
try {
const tupianUrls = await this.piliangShangchuanShensuTupian()
if (!tupianUrls || tupianUrls.length === 0) throw new Error('图片上传失败')
await this.tijiaoShensuData(tupianUrls)
} catch (error) {
console.error('提交申诉失败:', error)
wx.showToast({ title: error.message || '提交失败', icon: 'none' })
}
},
async tijiaoShensuData(tupianUrls) {
wx.showToast({ title: '提交申诉中...', icon: 'none' })
try {
const res = await request({
url: '/yonghu/dscfss',
method: 'POST',
data: {
chufa_id: this.data.xuanzhongChufa.id,
shensu_liyou: this.data.shensuLiyou,
shensu_tupian_urls: tupianUrls
}
})
if (res.statusCode === 200 && res.data.code === 0) {
this.updateChufaRecord({
sqzhuangtai: 3,
ssliyou: this.data.shensuLiyou,
shensu_tupian: tupianUrls
})
this.setData({
showShensuModal: false,
showXiangqing: false,
shensuLiyou: '',
shensuTupian: [],
xuanzhongChufa: {}
})
wx.showToast({ title: '申诉提交成功,请等待处理', icon: 'success' })
setTimeout(() => { this.chushihuaShuju() }, 500)
} else {
throw new Error(res.data?.msg || '提交申诉失败')
}
} catch (error) {
console.error('提交申诉数据失败:', error)
wx.showToast({ title: error.message || '提交失败', icon: 'none' })
}
},
updateChufaRecord(newData) {
const newList = this.data.chufaList.map(item => {
if (item.id === this.data.xuanzhongChufa.id) {
const updatedItem = { ...item, ...newData }
// 🔴 更新显示字段
if (newData.sqzhuangtai === 3) {
updatedItem.display_status = '申诉中'
updatedItem.status_class = 'zhuangtai-shensuzhong'
}
if (newData.shensu_tupian) {
updatedItem.full_shensu_tupian = newData.shensu_tupian.map(url => this.getFullImageUrl(url))
}
return updatedItem
}
return item
})
this.setData({ chufaList: newList })
},
// 🔴【图片URL拼接 - 确保返回完整URL】
getFullImageUrl(relativeUrl) {
//console.log('🔴【图片拼接】输入:', relativeUrl)
if (!relativeUrl) return ''
if (relativeUrl.startsWith('http')) {
//console.log('🔴【已经是完整URL】返回:', relativeUrl)
return relativeUrl
}
const ossUrl = this.data.ossImageUrl
if (!ossUrl) {
//console.log('🔴【OSS地址为空】返回原始URL:', relativeUrl)
return relativeUrl
}
let fullUrl
if (ossUrl.endsWith('/') && relativeUrl.startsWith('/')) {
fullUrl = ossUrl + relativeUrl.substring(1)
} else if (!ossUrl.endsWith('/') && !relativeUrl.startsWith('/')) {
fullUrl = ossUrl + '/' + relativeUrl
} else {
fullUrl = ossUrl + relativeUrl
}
// console.log('🔴【拼接后URL】:', fullUrl)
return fullUrl
},
yulanTupian(e) {
const currentUrl = e.currentTarget.dataset.url
const urls = e.currentTarget.dataset.urls || []
if (!currentUrl) return
const fullCurrentUrl = currentUrl.startsWith('http') ? currentUrl : this.getFullImageUrl(currentUrl)
const fullUrls = urls.map(url => url.startsWith('http') ? url : this.getFullImageUrl(url))
wx.previewImage({
current: fullCurrentUrl,
urls: fullUrls.length > 0 ? fullUrls : [fullCurrentUrl]
})
},
fuzhiWenben(e) {
const text = e.currentTarget.dataset.text
if (!text) return
wx.setClipboardData({
data: text,
success: () => {
wx.showToast({ title: '复制成功', icon: 'success' })
},
fail: () => {
wx.showToast({ title: '复制失败', icon: 'none' })
}
})
},
// 🔴【保留原函数但已不再使用(用于向后兼容)】
formatShijian(shijian) {
if (!shijian) return '--'
return String(shijian)
},
getZhuangtaiText(zhuangtai) {
const statusNum = Number(zhuangtai)
if (statusNum === 0) return '待处罚'
if (statusNum === 1) return '已处罚'
if (statusNum === 2) return '已驳回'
if (statusNum === 3) return '申诉中'
return '未知状态'
},
getZhuangtaiClass(zhuangtai) {
const statusNum = Number(zhuangtai)
if (statusNum === 0) return 'zhuangtai-daichuli'
if (statusNum === 1) return 'zhuangtai-yichufa'
if (statusNum === 2) return 'zhuangtai-yibohui'
if (statusNum === 3) return 'zhuangtai-shensuzhong'
return 'zhuangtai-weizhi'
}
})