修复文件上传和下单支付流程
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"hfb_sys/backend/internal/config"
|
||||
@@ -21,6 +22,8 @@ import (
|
||||
type Storage struct {
|
||||
client *minio.Client
|
||||
bucket string
|
||||
bucketMu sync.Mutex
|
||||
bucketReady bool
|
||||
}
|
||||
|
||||
type Object struct {
|
||||
@@ -43,7 +46,7 @@ func NewStorage(cfg config.StorageConfig) (*Storage, error) {
|
||||
}
|
||||
storage := &Storage{client: client, bucket: cfg.Bucket}
|
||||
if err := storage.ensureBucket(context.Background()); err != nil {
|
||||
return nil, err
|
||||
return storage, err
|
||||
}
|
||||
return storage, nil
|
||||
}
|
||||
@@ -62,6 +65,9 @@ func (s *Storage) Put(ctx context.Context, scene string, header *multipart.FileH
|
||||
}
|
||||
|
||||
func (s *Storage) PutObject(ctx context.Context, key string, reader io.Reader, size int64, contentType string, metadata map[string]string) error {
|
||||
if err := s.ensureBucketReady(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := s.client.PutObject(ctx, s.bucket, key, reader, size, minio.PutObjectOptions{
|
||||
ContentType: contentType,
|
||||
UserMetadata: metadata,
|
||||
@@ -95,9 +101,23 @@ func (s *Storage) ensureBucket(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
if exists {
|
||||
s.bucketReady = true
|
||||
return nil
|
||||
}
|
||||
return s.client.MakeBucket(ctx, s.bucket, minio.MakeBucketOptions{})
|
||||
if err := s.client.MakeBucket(ctx, s.bucket, minio.MakeBucketOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
s.bucketReady = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Storage) ensureBucketReady(ctx context.Context) error {
|
||||
s.bucketMu.Lock()
|
||||
defer s.bucketMu.Unlock()
|
||||
if s.bucketReady {
|
||||
return nil
|
||||
}
|
||||
return s.ensureBucket(ctx)
|
||||
}
|
||||
|
||||
func normalizeEndpoint(raw string) (string, bool, error) {
|
||||
|
||||
@@ -242,7 +242,7 @@ func New(cfg config.Config, deps Dependencies, logger *zap.Logger) *gin.Engine {
|
||||
var err error
|
||||
fileStorage, err = filemodule.NewStorage(cfg.Storage)
|
||||
if err != nil {
|
||||
logger.Warn("file storage unavailable; file APIs will return 503", zap.Error(err))
|
||||
logger.Warn("file storage bucket is not ready; file APIs will retry on request", zap.Error(err))
|
||||
}
|
||||
}
|
||||
fileService := filemodule.NewService(fileStorage)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
X-Frame-Options "DENY"
|
||||
Referrer-Policy "strict-origin-when-cross-origin"
|
||||
Permissions-Policy "camera=(), microphone=(), geolocation=()"
|
||||
Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self'"
|
||||
Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data: blob:; font-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self'"
|
||||
}
|
||||
|
||||
# 聊天 SSE 长连接:关闭缓冲,逐条推送。
|
||||
|
||||
@@ -241,8 +241,8 @@ async function submitOrder() {
|
||||
ordering.value = true
|
||||
try {
|
||||
const order = await createOrder(listing.value.id)
|
||||
ElMessage.success('订单已创建,请完成支付')
|
||||
await router.push(`/orders/${order.id}`)
|
||||
ElMessage.success('订单已创建,正在打开支付')
|
||||
await router.push({ path: `/orders/${order.id}`, query: { pay: '1' } })
|
||||
} catch (error) {
|
||||
ElMessage.error(readError(error, '下单失败'))
|
||||
} finally {
|
||||
|
||||
@@ -231,9 +231,9 @@ async function submitOrder() {
|
||||
if (!listing.value) return
|
||||
ordering.value = true
|
||||
try {
|
||||
await createOrder(listing.value.id)
|
||||
showToast({ message: '订单已创建,请完成支付', icon: 'passed' })
|
||||
await router.push(`/m/orders`)
|
||||
const order = await createOrder(listing.value.id)
|
||||
showToast({ message: '订单已创建,正在打开支付', icon: 'passed' })
|
||||
await router.push({ path: `/m/orders/${order.id}`, query: { pay: '1' } })
|
||||
} catch (error) {
|
||||
showToast({ message: readError(error, '下单失败'), icon: 'cross' })
|
||||
} finally {
|
||||
|
||||
@@ -90,6 +90,7 @@ const activeNames = ref<string[]>([])
|
||||
const showDisputePopup = ref(false)
|
||||
const showCounterPopup = ref(false)
|
||||
const showRejectPopup = ref(false)
|
||||
let autoPayHandled = false
|
||||
|
||||
const isOwner = computed(() => order.value?.owner_id === session.userId)
|
||||
const isRenter = computed(() => order.value?.renter_id === session.userId)
|
||||
@@ -139,6 +140,16 @@ async function loadOrder() {
|
||||
handoffRecords.value = await fetchHandoffRecords(String(route.params.id))
|
||||
hydrateResourceUsage()
|
||||
hydrateCounterForm()
|
||||
if (
|
||||
!autoPayHandled &&
|
||||
route.query.pay === '1' &&
|
||||
order.value?.status === 'pending_payment' &&
|
||||
order.value?.renter_id === session.userId
|
||||
) {
|
||||
autoPayHandled = true
|
||||
void router.replace({ path: route.path })
|
||||
void handlePay()
|
||||
}
|
||||
} catch {
|
||||
showToast({ message: '加载订单失败', icon: 'cross' })
|
||||
} finally {
|
||||
|
||||
@@ -33,9 +33,28 @@ function elementPlusChunk(id: string) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
function stripVantRemoteIconFont() {
|
||||
return {
|
||||
name: 'strip-vant-remote-icon-font',
|
||||
generateBundle(_options, bundle) {
|
||||
for (const chunk of Object.values(bundle)) {
|
||||
if (chunk.type !== 'asset' || typeof chunk.source !== 'string') continue
|
||||
if (!chunk.fileName.endsWith('.css')) continue
|
||||
|
||||
// Vant 图标字体已经内联了 woff2,这里去掉远程 woff 备用地址,避免触发 CSP 外链字体拦截。
|
||||
chunk.source = chunk.source.replace(
|
||||
/,url\(\/\/at\.alicdn\.com\/t\/c\/font_2553510_ciljc7axaw7\.woff\?t=1705587463221\) format\("woff"\)/g,
|
||||
''
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
stripVantRemoteIconFont(),
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user