feat: 优化图片上传功能并修复订单页面样式问题

- 在审批提交页面添加图片压缩功能,提升上传效率
- 修复订单详情和成功页面的图片显示问题,统一使用https协议
- 优化订单成功页面的商品名称显示样式,支持多行文本
- 更新环境配置中的上传地址和开发脚本
This commit is contained in:
dzq 2025-11-11 17:09:41 +08:00
parent 95157936af
commit ea22232c00
6 changed files with 144 additions and 17 deletions

2
env/.env vendored
View File

@ -13,7 +13,7 @@ VITE_APP_PUBLIC_BASE=/
# VITE_SERVER_BASEURL = 'http://localhost:8090/api/' # VITE_SERVER_BASEURL = 'http://localhost:8090/api/'
VITE_SERVER_BASEURL = 'https://wxshop.ab98.cn/shop-api/api/' VITE_SERVER_BASEURL = 'https://wxshop.ab98.cn/shop-api/api/'
# 后台上传地址 # 后台上传地址
VITE_UPLOAD_BASEURL = 'http://localhost:8081/upload' VITE_UPLOAD_BASEURL = 'https://wxshop.ab98.cn/shop-back-end'
# 汇邦云token请求地址 # 汇邦云token请求地址
VITE_HUIBANG_BASEURL = 'https://www.ab98.cn' VITE_HUIBANG_BASEURL = 'https://www.ab98.cn'

View File

@ -27,7 +27,8 @@
"dev:app-android": "uni -p app-android", "dev:app-android": "uni -p app-android",
"dev:app-ios": "uni -p app-ios", "dev:app-ios": "uni -p app-ios",
"dev:custom": "uni -p", "dev:custom": "uni -p",
"dev": "node --experimental-loader ./scripts/window-path-loader.js node_modules/@dcloudio/vite-plugin-uni/bin/uni.js", "dev": "pnpm run dev:mp-weixin",
"dev_bak": "node --experimental-loader ./scripts/window-path-loader.js node_modules/@dcloudio/vite-plugin-uni/bin/uni.js",
"dev:test": "uni --mode test", "dev:test": "uni --mode test",
"dev:prod": "uni --mode production", "dev:prod": "uni --mode production",
"dev:h5": "uni", "dev:h5": "uni",

View File

@ -4,7 +4,7 @@ import { submitApprovalApi } from '@/api/approval'
import type { SubmitApprovalRequestData } from '@/api/approval/types' import type { SubmitApprovalRequestData } from '@/api/approval/types'
import { useOrderStore } from '@/pinia/stores/order' import { useOrderStore } from '@/pinia/stores/order'
import { useWxStoreOutside } from '@/pinia/stores/wx' import { useWxStoreOutside } from '@/pinia/stores/wx'
import { getEnvBaseUploadUrl } from '@/utils' import { getEnvBaseUploadUrl, toHttpsUrl } from '@/utils'
import type { UploadFile } from 'wot-design-uni/components/wd-upload/types' import type { UploadFile } from 'wot-design-uni/components/wd-upload/types'
// //
@ -49,14 +49,127 @@ const submitting = ref(false)
// - 使 wd-upload v-model // - 使 wd-upload v-model
const fileList = ref<UploadFile[]>([]) const fileList = ref<UploadFile[]>([])
const uploadFileList = ref<UploadFile[]>([]) //
const uploading = ref(false) const uploading = ref(false)
// //
const uploadUrl = `${getEnvBaseUploadUrl()}/file/upload` const uploadUrl = `${getEnvBaseUploadUrl()}/file/upload`
// //
const beforeUpload = ({ files, resolve }: { files: Record<string, any>[], resolve: (isPass: boolean) => void }) => { const compressImage = (src: string): Promise<string> => {
resolve(true) return new Promise((resolve, reject) => {
uni.compressImage({
src: src,
quality: 0.8,
maxWidth: 980,
maxHeight: 980,
success: (res) => {
console.log('图片压缩成功:', res)
resolve(res.tempFilePath)
},
fail: (err) => {
console.warn('图片压缩失败,使用原图:', err)
// 使
resolve(src)
}
})
})
}
// -
const beforeUpload = async ({ files, resolve }: { files: Record<string, any>[], resolve: (isPass: boolean) => void }) => {
try {
uploading.value = true;
console.log('上传前置处理 - 压缩图片:', JSON.stringify(files))
console.log(`开始压缩 ${files.length} 张图片...`)
//
const compressedFiles = await Promise.all(
files.map(async (file: any, index: number) => {
try {
const originalUrl = file.url || file.path
console.log(`开始压缩第 ${index + 1} 张图片:`, originalUrl)
//
if (originalUrl && (originalUrl.startsWith('http') || originalUrl.startsWith('https'))) {
//
const downloadResult = await new Promise<{ tempFilePath: string }>((resolve, reject) => {
uni.downloadFile({
url: originalUrl,
success: resolve,
fail: reject
})
})
console.log(`图片 ${index + 1} 下载完成:`, downloadResult.tempFilePath)
//
const compressedPath = await compressImage(downloadResult.tempFilePath)
console.log(`图片 ${index + 1} 压缩完成:`, compressedPath)
file.url = compressedPath;
file.path = compressedPath;
return {
...file,
url: compressedPath,
compressed: true
}
} else {
//
const compressedPath = await compressImage(originalUrl)
console.log(`图片 ${index + 1} 压缩完成:`, compressedPath)
file.url = compressedPath;
file.path = compressedPath;
return {
...file,
url: compressedPath,
compressed: true
}
}
} catch (error) {
console.error(`图片 ${index + 1} 处理失败:`, file, error)
//
return file
}
})
)
console.log('所有图片压缩处理完成')
resolve(true)
} catch (error) {
console.error('图片压缩处理失败:', error)
uni.showToast({
title: '图片处理失败,将使用原图',
icon: 'none'
})
// 使
resolve(true)
} finally {
uploading.value = false
}
}
//
const handleUploadChange = ({ fileList: files }: { fileList: UploadFile[] }) => {
// URL
const processedFiles = files.map((file: any) => {
// 使url
if (file.status === 'success' && file.response) {
const { code, data } = JSON.parse(file.response);
if (code === 0 && data && data.url) {
// 使APIURLURL
return {
...file,
url: toHttpsUrl(data.url),
name: data.newFileName || file.name,
}
}
}
return file
})
//
uploadFileList.value = processedFiles;
} }
// //
@ -83,7 +196,7 @@ const handleSubmit = async () => {
if (!validateForm()) return if (!validateForm()) return
// //
if (fileList.value.length === 0) { if (uploadFileList.value.length === 0) {
uni.showToast({ uni.showToast({
title: '请先上传凭证图片', title: '请先上传凭证图片',
icon: 'none', icon: 'none',
@ -93,12 +206,12 @@ const handleSubmit = async () => {
submitting.value = true submitting.value = true
try { try {
// URL // URL - 使
formData.value.returnImages = fileList.value.map(item => item.url).join(',') formData.value.returnImages = uploadFileList.value.map(item => item.url).join(',')
formData.value.corpid = wxStore.corpid formData.value.corpid = wxStore.corpid
formData.value.applyUserid = wxStore.userid formData.value.applyUserid = wxStore.userid
console.log('提交数据:', formData.value) console.log('提交数据:', formData.value);
const { code, data } = await submitApprovalApi(formData.value) const { code, data } = await submitApprovalApi(formData.value)
@ -161,6 +274,7 @@ const handleSubmit = async () => {
:limit="3" :limit="3"
image-mode="aspectFill" image-mode="aspectFill"
:before-upload="beforeUpload" :before-upload="beforeUpload"
@change="handleUploadChange"
accept="image" accept="image"
multiple multiple
> >

View File

@ -5,6 +5,7 @@ import { Order, useOrderStore } from '@/pinia/stores/order'
import { useWxStore } from '@/pinia/stores/wx' import { useWxStore } from '@/pinia/stores/wx'
import { useAb98UserStore } from '@/pinia/stores/ab98-user' import { useAb98UserStore } from '@/pinia/stores/ab98-user'
import { openCabinetApi } from '@/api/shop' import { openCabinetApi } from '@/api/shop'
import { toHttpsUrl } from '@/utils/common'
definePage({ definePage({
style: { style: {
@ -139,7 +140,7 @@ onLoad((options: any) => {
class="goods-item" class="goods-item"
> >
<image <image
:src="item.goodsInfo?.coverImg" :src="toHttpsUrl(item.goodsInfo?.coverImg)"
mode="aspectFill" mode="aspectFill"
class="product-image" class="product-image"
/> />

View File

@ -47,7 +47,7 @@ const getStatusText = (status: number) => {
const goToOrderDetail = (orderId: number) => { const goToOrderDetail = (orderId: number) => {
uni.navigateTo({ uni.navigateTo({
url: `/pages/order/detail?id=${orderId}` url: `/pages/order/detail?id=${orderId}`
}) });
} }
onMounted(() => { onMounted(() => {

View File

@ -4,6 +4,7 @@ import { useOrderStore } from '@/pinia/stores/order'
import { useWxStore } from '@/pinia/stores/wx' import { useWxStore } from '@/pinia/stores/wx'
import { useAb98UserStore } from '@/pinia/stores/ab98-user' import { useAb98UserStore } from '@/pinia/stores/ab98-user'
import { openCabinetApi } from '@/api/shop' import { openCabinetApi } from '@/api/shop'
import { toHttpsUrl } from '@/utils/common'
definePage({ definePage({
style: { style: {
@ -101,7 +102,7 @@ onLoad(async (options: any) => {
class="goods-item" class="goods-item"
> >
<image <image
:src="item.goodsInfo.coverImg" :src="toHttpsUrl(item.goodsInfo.coverImg)"
mode="aspectFill" mode="aspectFill"
class="product-image" class="product-image"
/> />
@ -240,20 +241,29 @@ onLoad(async (options: any) => {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: flex-start;
height: 140rpx; align-items: flex-end;
min-height: 140rpx;
} }
.product-name { .product-name {
font-size: 28rpx; font-size: 28rpx;
color: #333; color: #333;
line-height: 1.4; line-height: 1.5;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
align-self: flex-start;
} }
.text-ellipsis { .text-ellipsis {
/* 移除单行限制,商品名称现在支持多行显示 */
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; word-break: break-all;
} }
.product-price { .product-price {
@ -261,6 +271,7 @@ onLoad(async (options: any) => {
color: #e95d5d; color: #e95d5d;
font-weight: bold; font-weight: bold;
margin: 12rpx 0; margin: 12rpx 0;
align-self: flex-start;
} }
.action-row { .action-row {