feat: 优化图片上传功能并修复订单页面样式问题
- 在审批提交页面添加图片压缩功能,提升上传效率 - 修复订单详情和成功页面的图片显示问题,统一使用https协议 - 优化订单成功页面的商品名称显示样式,支持多行文本 - 更新环境配置中的上传地址和开发脚本
This commit is contained in:
parent
95157936af
commit
ea22232c00
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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> => {
|
||||||
|
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)
|
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) {
|
||||||
|
// 使用API返回的完整URL替换临时URL
|
||||||
|
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
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -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(() => {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue