Files
shanxia2.0/miniprogram/utils/upload.js
T
wuzilongandCursor 6a8cd90b98 feat: cascade column facet options by current list context
Make dynamic column-facet values respect other active filters (Excel-style), with backend facet context helpers, list-page wiring, slip print/sidebar fixes, and refreshed graphify graphs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-11 22:04:20 +08:00

113 lines
3.1 KiB
JavaScript

/**
* 小程序拍照凭证上传(OpenSpec 基线)
* chooseImage → uni.uploadFile → 收集 URL → 业务接口再传 imageUrls
*/
import { resolveApiBase, TOKEN_KEY, UPLOAD_API } from '@/config/api'
function parseUploadBody(raw) {
try {
return JSON.parse(typeof raw === 'string' ? raw : String(raw || ''))
} catch {
return {}
}
}
function extractUrl(body) {
const data = body && body.data
if (!data || typeof data !== 'object') return ''
const url = data.url || data.fileUrl || data.file_url
return url != null ? String(url).trim() : ''
}
function getToken() {
const raw = uni.getStorageSync(TOKEN_KEY)
return typeof raw === 'string' ? raw.trim() : raw ? String(raw).trim() : ''
}
/**
* @param {{
* folder?: string,
* maxCount?: number,
* currentUrls?: string[],
* uploadUrl?: string,
* sourceType?: Array<'album'|'camera'>
* }} opts
* @returns {Promise<string[]>} 本次新上传成功的 URL 列表
*/
export async function chooseAndUploadImages(opts = {}) {
const folder = opts.folder || 'mini-evidence'
const maxCount = opts.maxCount != null ? opts.maxCount : 6
const currentUrls = Array.isArray(opts.currentUrls) ? opts.currentUrls : []
const uploadUrl = opts.uploadUrl || `${resolveApiBase()}${UPLOAD_API.IMAGE}`
const sourceType =
Array.isArray(opts.sourceType) && opts.sourceType.length
? opts.sourceType
: ['album', 'camera']
const remain = maxCount - currentUrls.length
if (remain <= 0) {
uni.showToast({ title: `最多上传${maxCount}张`, icon: 'none' })
return []
}
const choose = await new Promise((resolve) => {
uni.chooseImage({
count: remain,
sizeType: ['compressed'],
sourceType,
success: (res) => resolve(res),
fail: () => resolve(null)
})
})
if (!choose?.tempFilePaths?.length) return []
const token = getToken()
const urls = []
uni.showLoading({ title: '上传中...' })
try {
for (const filePath of choose.tempFilePaths) {
const uploadRes = await new Promise((ok, fail) => {
uni.uploadFile({
url: uploadUrl,
filePath,
name: 'file',
header: {
Authorization: token ? `Bearer ${token}` : ''
},
formData: { folder },
success: ok,
fail
})
})
if (uploadRes.statusCode === 401) {
uni.showToast({ title: '登录已失效,请重新登录', icon: 'none' })
break
}
const body = parseUploadBody(uploadRes.data)
const url = extractUrl(body)
if (body.code !== 200 || !url) {
uni.showToast({ title: body.message || '上传失败', icon: 'none' })
break
}
urls.push(url)
}
} catch (e) {
uni.showToast({
title: e instanceof Error ? e.message : '上传失败',
icon: 'none'
})
} finally {
uni.hideLoading()
}
return urls
}
export function previewImages(urls, current) {
const list = (urls || []).map((u) => String(u || '').trim()).filter(Boolean)
if (!list.length) return
uni.previewImage({
urls: list,
current: current || list[0]
})
}