|
@@ -0,0 +1,97 @@
|
|
|
|
|
+export function formatStoreTime(time) {
|
|
|
|
|
+ if (!time) return '-'
|
|
|
|
|
+ return new Date(time).toLocaleString('zh-CN', {
|
|
|
|
|
+ year: 'numeric',
|
|
|
|
|
+ month: '2-digit',
|
|
|
|
|
+ day: '2-digit',
|
|
|
|
|
+ hour: '2-digit',
|
|
|
|
|
+ minute: '2-digit'
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function formatStoreTimeFull(time) {
|
|
|
|
|
+ if (!time) return '-'
|
|
|
|
|
+ return new Date(time).toLocaleString('zh-CN', {
|
|
|
|
|
+ year: 'numeric',
|
|
|
|
|
+ month: '2-digit',
|
|
|
|
|
+ day: '2-digit',
|
|
|
|
|
+ hour: '2-digit',
|
|
|
|
|
+ minute: '2-digit',
|
|
|
|
|
+ second: '2-digit'
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export const PAY_TYPE_MAP = {
|
|
|
|
|
+ alipay: { label: '支付宝', icon: 'alipay' },
|
|
|
|
|
+ wxpay: { label: '微信支付', icon: 'wechat' },
|
|
|
|
|
+ qqpay: { label: 'QQ支付', icon: 'qq' }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function getPayTypeLabel(type) {
|
|
|
|
|
+ return PAY_TYPE_MAP[type]?.label ?? type ?? '-'
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export const ORDER_STATE_MAP = {
|
|
|
|
|
+ 0: { label: '待支付', color: 'orangered' },
|
|
|
|
|
+ 1: { label: '待处理', color: 'arcoblue' },
|
|
|
|
|
+ 2: { label: '已完成', color: 'green' },
|
|
|
|
|
+ 3: { label: '已关闭', color: 'gray' },
|
|
|
|
|
+ 4: { label: '处理异常', color: 'red' }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function getOrderStateMeta(state) {
|
|
|
|
|
+ return ORDER_STATE_MAP[state] ?? { label: '未知', color: 'gray' }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export const DEFAULT_GOODS_EMOJI = '🏃'
|
|
|
|
|
+
|
|
|
|
|
+/** 商品展示用 emoji(icon 字段存 emoji,若为图片 URL 则回退默认) */
|
|
|
|
|
+export function getGoodsEmoji(icon, fallback = DEFAULT_GOODS_EMOJI) {
|
|
|
|
|
+ if (icon == null || icon === '') return fallback
|
|
|
|
|
+ const value = String(icon).trim()
|
|
|
|
|
+ if (!value) return fallback
|
|
|
|
|
+ if (/^https?:\/\//i.test(value) || value.startsWith('data:') || /\.(png|jpe?g|gif|webp|svg)(\?|$)/i.test(value)) {
|
|
|
|
|
+ return fallback
|
|
|
|
|
+ }
|
|
|
|
|
+ return value
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function stockLabel(num) {
|
|
|
|
|
+ if (num == null) return '-'
|
|
|
|
|
+ return num > 99 ? '充足' : String(num)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function parseFeatures(features) {
|
|
|
|
|
+ if (!features) return []
|
|
|
|
|
+ if (Array.isArray(features)) return features
|
|
|
|
|
+ try {
|
|
|
|
|
+ const parsed = JSON.parse(features)
|
|
|
|
|
+ return Array.isArray(parsed) ? parsed : []
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ return String(features)
|
|
|
|
|
+ .split(/[,,\n]/)
|
|
|
|
|
+ .map((s) => s.trim())
|
|
|
|
|
+ .filter(Boolean)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function serializeFeatures(list) {
|
|
|
|
|
+ const arr = (list || []).map((s) => String(s).trim()).filter(Boolean)
|
|
|
|
|
+ return JSON.stringify(arr)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function decodeGoodsContent(content) {
|
|
|
|
|
+ if (!content) return ''
|
|
|
|
|
+ const text = String(content).trim()
|
|
|
|
|
+ // 已是 HTML 明文则直接展示
|
|
|
|
|
+ if (text.startsWith('<')) return text
|
|
|
|
|
+ try {
|
|
|
|
|
+ return decodeURI(atob(text))
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ return text
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export function hasPayData(payData) {
|
|
|
|
|
+ return payData && typeof payData === 'object' && Object.keys(payData).length > 0
|
|
|
|
|
+}
|