fix:图片访问
fix:权限修改
This commit is contained in:
1 parent
6d267bcfc5
commit
653b4688cd
80 files changed
+232
-265
No files matched your search
+4
-1
@@ -18,4 +18,7 @@ dist
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
*.sw?
|
||||
|
||||
# Local file-access credentials
|
||||
.env.*.local
|
||||
@@ -1,4 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { startFileAccess, stopFileAccess } from "./sheep/utils/file-access"
|
||||
import { getLaunchParam, getAppInfo } from "./sheep/utils/app"
|
||||
import { jump } from "./sheep/router/index"
|
||||
import { useTabbarStore } from "./sheep/stores/tabbar"
|
||||
@@ -11,6 +12,7 @@ export default {
|
||||
}
|
||||
},
|
||||
onLaunch() {
|
||||
startFileAccess()
|
||||
console.log("App Launch");
|
||||
const _this = this;
|
||||
// uni.hideTabBar()
|
||||
@@ -19,9 +21,11 @@ export default {
|
||||
// #endif
|
||||
},
|
||||
onShow() {
|
||||
startFileAccess()
|
||||
console.log("App Show");
|
||||
},
|
||||
onHide() {
|
||||
stopFileAccess()
|
||||
console.log("App Hide");
|
||||
// const _this = this;
|
||||
// wx.offAppRoute(_this.watchRouter)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { installFileAccess } from './sheep/utils/file-access'
|
||||
import { createSSRApp } from "vue"
|
||||
import "uno.css"
|
||||
|
||||
@@ -8,6 +9,7 @@ import pinia from "@@/stores/index"
|
||||
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
installFileAccess(app)
|
||||
|
||||
app.use(pinia)
|
||||
app.use(tmUi)
|
||||
|
||||
@@ -20,7 +20,7 @@ const state = reactive<any>({
|
||||
// 重新设置图片路径
|
||||
const boxesList = computed(() => {
|
||||
return pageHook.list.map((item: any) => {
|
||||
return { ...item, images: filePath(item.images) }
|
||||
return { ...item, images: item.images }
|
||||
})
|
||||
})
|
||||
|
||||
@@ -66,7 +66,7 @@ onShow(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="餐桌列表" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="餐桌列表" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="999"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
@@ -80,7 +80,7 @@ onShow(() => {
|
||||
<view class="boxes-grid">
|
||||
<view v-for="item in boxesList" :key="item.id" class="box-card">
|
||||
<view class="card-image-section">
|
||||
<image v-if="item.images" :src="item.images" class="box-image" mode="aspectFill" />
|
||||
<image v-if="item.images" :src="$fileUrl(item.images)" class="box-image" mode="aspectFill" @error="$fileRetry(item.images)" />
|
||||
<view v-else class="image-placeholder">
|
||||
<text class="placeholder-icon">🍴</text>
|
||||
<text class="placeholder-text">餐桌</text>
|
||||
|
||||
@@ -49,8 +49,8 @@ const remove = () => {
|
||||
<template>
|
||||
<view class="flex-row items-start card p-x-15rpx p-y-25rpx m-b-20rpx"
|
||||
@tap="props.productId && router.jump('/pages/canteen/product-detail', { id: props.productId })">
|
||||
<image v-if="props.mode == 'default'" class="size-180rpx rounded-12rpx" :src="props.pic" mode="aspectFill" />
|
||||
<image v-if="props.mode == 'cart'" class="size-120rpx rounded-12rpx" :src="props.pic" mode="aspectFill" />
|
||||
<image v-if="props.mode == 'default'" class="size-180rpx rounded-12rpx" :src="$fileUrl(props.pic)" mode="aspectFill" @error="$fileRetry(props.pic)" />
|
||||
<image v-if="props.mode == 'cart'" class="size-120rpx rounded-12rpx" :src="$fileUrl(props.pic)" mode="aspectFill" @error="$fileRetry(props.pic)" />
|
||||
<view class="flex-1 m-l-20rpx">
|
||||
<view class="sub-text-28 show-line">{{ props.name }}</view>
|
||||
<view class="m-t-10rpx flex-row items-center">
|
||||
|
||||
@@ -236,12 +236,12 @@ const doFood = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout mainIsScroll tabBarType="just-flot-back" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll tabBarType="just-flot-back" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<tm-sticky>
|
||||
<swiper class="w-100vw h-30vh" circular :indicator-dots="true" indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff" :autoplay="true">
|
||||
<swiper-item v-for="(v, i) in state.canteenDetail?.swiperPic?.split(',')" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
|
||||
<image class="w-full h-full" :src="$fileUrl(filePath(v))" mode="aspectFill" @error="$fileRetry(filePath(v))" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
@@ -250,8 +250,8 @@ const doFood = () => {
|
||||
<!-- start 简介 start -->
|
||||
<view class="h-15rpx" />
|
||||
<view class="flex-row card p-20rpx">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(state.canteenDetail.logoPic)"
|
||||
mode="aspectFill" />
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="$fileUrl(filePath(state.canteenDetail.logoPic))"
|
||||
mode="aspectFill" @error="$fileRetry(filePath(state.canteenDetail.logoPic))" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">
|
||||
|
||||
@@ -52,7 +52,7 @@ const query = (page: number, pagesize: number) => {
|
||||
// 重新设置图片路径
|
||||
const foodList = computed(() => {
|
||||
return pageHook.list.map((item: any) => {
|
||||
return { ...item, picUrl: filePath(item.picUrl) }
|
||||
return { ...item, picUrl: item.picUrl }
|
||||
})
|
||||
})
|
||||
|
||||
@@ -94,7 +94,7 @@ const doProduct = (v: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="每日菜谱" navBgColor="#1777FF" navBgTitleColor="white" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="每日菜谱" navBgColor="#1777FF" navBgTitleColor="white" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="8"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
|
||||
@@ -34,9 +34,9 @@ const getDetail = async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="菜品详情" tabBarType="just-flot-back" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="菜品详情" tabBarType="just-flot-back" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view v-if="state.detail">
|
||||
<image class="w-100vw" :src="filePath(state.detail.picUrl)" mode="widthFix" />
|
||||
<image class="w-100vw" :src="$fileUrl(filePath(state.detail.picUrl))" mode="widthFix" @error="$fileRetry(filePath(state.detail.picUrl))" />
|
||||
<view class="p-x-15rpx">
|
||||
<view class="flex-col justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
@@ -58,7 +58,7 @@ const getDetail = async () => {
|
||||
<view v-if="state.detail.description"
|
||||
class="m-t-15rpx flex-col justify-between card p-y-20rpx p-x-30rpx">
|
||||
<view class="prefix_title">详情</view>
|
||||
<view class="m-t-15rpx" v-html="state.detail.description"></view>
|
||||
<view class="m-t-15rpx" v-html="$fileHtml(state.detail.description)"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -83,7 +83,7 @@ const doSubmit = async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="申请车辆" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="申请车辆" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-30rpx" />
|
||||
<view class="card p-x-30rpx p-y-40rpx">
|
||||
<tm-form ref="applyFormRef" v-model="applyForm" :rules="applyFormRules" direction="vertical">
|
||||
|
||||
@@ -39,7 +39,7 @@ const doApply = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="我的车辆" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="我的车辆" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
|
||||
@@ -35,8 +35,8 @@ const switchRich = (type: string) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout mainIsScroll :title="state.title" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll :title="state.title" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-30rpx" />
|
||||
<view class="sub-text-24" style="line-height: 1.6 !important;" v-html="switchRich(state.id)"></view>
|
||||
<view class="sub-text-24" style="line-height: 1.6 !important;" v-html="$fileHtml(switchRich(state.id))"></view>
|
||||
</crud-layout>
|
||||
</template>
|
||||
@@ -42,7 +42,7 @@ const getDetail = async () => {
|
||||
if (!isEmpty(data)) {
|
||||
const img = filePath(data.faceImg)
|
||||
applyForm.faceImg = [img]
|
||||
uploadFileUrl.value = img
|
||||
uploadFileUrl.value = data.faceImg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ const doSubmit = async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout :title="state.detailId ? '修改人脸' : '人脸上传'" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout :title="state.detailId ? '修改人脸' : '人脸上传'" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-30rpx" />
|
||||
<view class="card px-30rpx py-40rpx">
|
||||
<tm-form ref="applyFormRef" v-model="applyForm" :rules="applyFormRules" direction="vertical">
|
||||
|
||||
@@ -49,14 +49,14 @@ const doDel = (id: string) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="人脸管理" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="人脸管理" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
<view class="h-20rpx" />
|
||||
<view class="card flex-col-center p-20rpx mb-20rpx" v-for="(v, i) in pageHook.list" :key="v.id">
|
||||
<image class="w-300rpx h-300rpx rounded-50rpx mb-16rpx" :src="filePath(v.faceImg)" mode="aspectFill"
|
||||
@click.stop="hooks.usePreviewImage(filePath(v.faceImg))" />
|
||||
<image class="w-300rpx h-300rpx rounded-50rpx mb-16rpx" :src="$fileUrl(filePath(v.faceImg))" mode="aspectFill"
|
||||
@click.stop="hooks.usePreviewImage(filePath(v.faceImg))" @error="$fileRetry(filePath(v.faceImg))" />
|
||||
<view class="sub-text-30 mb-16rpx">{{ v.username }}·{{ v.deptName }}</view>
|
||||
<view v-if="false" class="flex w-full items-center justify-end gap-16rpx second-text-26">
|
||||
<text class="botder_btn" @click="doEdit(v.id)">修改</text>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="意见反馈" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="意见反馈" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view v-if="!detail.title" class="loading-tip">加载中...</view>
|
||||
<view v-else>
|
||||
<view class="detail-header">
|
||||
@@ -12,7 +12,7 @@
|
||||
<view class="content-text">{{ detail.description || '无描述' }}</view>
|
||||
<view v-if="imageList.length" class="image-list">
|
||||
<image v-for="(img, idx) in imageList" :key="idx"
|
||||
:src="img.startsWith('http') || img.startsWith('https') ? img : filePath(img)" class="feedback-img"
|
||||
:src="$fileUrl(img.startsWith('http') || img.startsWith('https') ? img : filePath(img))" class="feedback-img"
|
||||
mode="aspectFill" @error="handleImageError(img)" @load="handleImageLoad(img)" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="意见反馈" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="意见反馈" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="feedback-tabs">
|
||||
<view :class="['tab', { active: activeTab === 0 }]" @click="activeTab = 0">提交反馈</view>
|
||||
<view :class="['tab', { active: activeTab === 1 }]" @click="activeTab = 1">我的反馈</view>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="失物招领" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="失物招领" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view v-if="loading" class="loading">加载中...</view>
|
||||
<view v-else-if="detail">
|
||||
<view class="detail-card">
|
||||
@@ -12,13 +12,13 @@
|
||||
</view>
|
||||
|
||||
<view v-if="imageList.length" class="image-list">
|
||||
<image v-for="(src, index) in imageList" :key="index" class="detail-image" :src="src" mode="aspectFill"
|
||||
@tap="previewImage(index)" />
|
||||
<image v-for="(src, index) in imageList" :key="index" class="detail-image" :src="$fileUrl(src)" mode="aspectFill"
|
||||
@tap="previewImage(index)" @error="$fileRetry(src)" />
|
||||
</view>
|
||||
|
||||
<view class="detail-section">
|
||||
<view class="section-title">物品描述</view>
|
||||
<rich-text v-if="descriptionNodes" :nodes="descriptionNodes"></rich-text>
|
||||
<rich-text v-if="descriptionNodes" :nodes="$fileNodes(descriptionNodes)"></rich-text>
|
||||
<view v-else class="section-content">暂无描述信息</view>
|
||||
</view>
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { previewFiles } from '@/sheep/utils/file-access'
|
||||
|
||||
import { computed, ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
@@ -44,7 +46,7 @@ import dayjs from 'dayjs'
|
||||
|
||||
import lostAndFoundApi from '@/sheep/api/lost-and-found'
|
||||
|
||||
import { filePath } from '@/sheep/utils/file'
|
||||
import { filePath, parseHtml } from '@/sheep/utils/file'
|
||||
import { SERVICE_IMAGE } from "@@/constant/index"
|
||||
|
||||
interface LostAndFoundDetail {
|
||||
@@ -102,11 +104,7 @@ const imageList = computed(() => {
|
||||
const descriptionNodes = computed(() => {
|
||||
const desc = detail.value?.description
|
||||
if (!desc) return ''
|
||||
return desc.replace(/<img\s+[^>]*src=["']([^"']+)["']/gi, (match, src) => {
|
||||
const fullSrc = toAbsoluteUrl(src)
|
||||
if (!fullSrc) return match
|
||||
return match.replace(src, fullSrc)
|
||||
})
|
||||
return parseHtml(desc)
|
||||
})
|
||||
|
||||
const contactInfo = computed(() => {
|
||||
@@ -123,7 +121,7 @@ const formatDate = (date?: string) => {
|
||||
|
||||
const previewImage = (index: number) => {
|
||||
if (!imageList.value.length) return
|
||||
uni.previewImage({
|
||||
previewFiles({
|
||||
current: index,
|
||||
urls: imageList.value,
|
||||
})
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="失物招领" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="失物招领" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<scroll-view scroll-y class="scroll-view" @scrolltolower="onLoadMore" refresher-enabled
|
||||
:refresher-triggered="refreshing" @refresherrefresh="onRefresh">
|
||||
<view v-if="list.length > 0">
|
||||
<view v-for="item in list" :key="item.id" class="item-card" @tap="viewDetail(item)">
|
||||
<view class="item-title">{{ item.title }}</view>
|
||||
<view class="item-description" v-html="item.description"></view>
|
||||
<view class="item-description" v-html="$fileHtml(item.description)"></view>
|
||||
<view class="item-info">
|
||||
<text>地点:{{ item.location }}</text>
|
||||
<text>时间:{{ formatDate(item.dateFound) }}</text>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="会议预定" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="会议预定" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<!-- 会议室信息卡片 -->
|
||||
<view class="room-card">
|
||||
<view class="room-header">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="预约会议" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="预约会议" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
|
||||
<!-- 会议室信息 -->
|
||||
<view class="room-info-box">
|
||||
<image :src="roomImage" class="room-img" mode="aspectFill" />
|
||||
<image :src="$fileUrl(roomImage)" class="room-img" mode="aspectFill" @error="$fileRetry(roomImage)" />
|
||||
<view class="room-info-main">
|
||||
<view class="room-title">{{ room.name }} <text class="room-capacity">{{ room.capacity }}人</text></view>
|
||||
<view class="room-address"><text>📍</text> {{ room.address }}</view>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="会议预定" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="会议预定" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<!-- 日期选择栏(简化版) -->
|
||||
<view class="date-bar">
|
||||
<text class="date-text">{{ todayText }}</text>
|
||||
@@ -38,7 +38,7 @@
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<image :src="getRoomImage(room.picUrl)" class="room-img" mode="aspectFill" />
|
||||
<image :src="$fileUrl(getRoomImage(room.picUrl))" class="room-img" mode="aspectFill" @error="$fileRetry(getRoomImage(room.picUrl))" />
|
||||
</view>
|
||||
<!-- 时间条 -->
|
||||
<view class="timeline-bar">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="会议预定" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="会议预定" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<!-- 顶部tab -->
|
||||
<view class="tabs">
|
||||
<view v-for="(tab, idx) in tabs" :key="tab" :class="['tab', idx === activeTab ? 'active' : '']"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="通知公告" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="通知公告" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="notice-detail">
|
||||
<view class="detail-header">
|
||||
<view class="title">
|
||||
@@ -15,7 +15,7 @@
|
||||
</view>
|
||||
|
||||
<view class="detail-content">
|
||||
<rich-text :nodes="nodes || ''"></rich-text>
|
||||
<rich-text :nodes="$fileNodes(nodes || '')"></rich-text>
|
||||
</view>
|
||||
|
||||
<view v-if="detail.attachments && detail.attachments.length > 0" class="attachments">
|
||||
@@ -32,10 +32,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { downloadFile as downloadProtectedFile } from '@/sheep/utils/file-access'
|
||||
|
||||
import { computed, ref } from "vue"
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
|
||||
import { filePath } from "@@/utils/file"
|
||||
import { filePath, parseHtml } from "@@/utils/file"
|
||||
import { SERVICE_IMAGE } from "@@/constant/index"
|
||||
import { actCancel, actComApi, noticeApi } from "@/sheep/api"
|
||||
|
||||
@@ -66,36 +68,11 @@ const goGetCoupon = () => {
|
||||
uni.navigateTo({ url: `/pages/merchant/merchant-activity?actId=${actDetail.value.actId}&actType=${actDetail.value.actType}` })
|
||||
}
|
||||
|
||||
const normalizeRichText = (html: string) => {
|
||||
const origin = "https://stgl.pj.gov.cn"
|
||||
return html.replace(/<img\b[^>]*>/gi, (imgTag) => {
|
||||
let next = imgTag
|
||||
|
||||
next = next.replace(/\bsrc\s*=\s*(['"])(.*?)\1/i, (_m, quote: string, src: string) => {
|
||||
let resolved = src
|
||||
if (resolved?.startsWith("/api")) resolved = `${origin}${resolved}`
|
||||
if (resolved?.startsWith("//")) resolved = `https:${resolved}`
|
||||
return `src=${quote}${resolved}${quote}`
|
||||
})
|
||||
|
||||
const styleMatch = next.match(/\bstyle\s*=\s*(['"])([\s\S]*?)\1/i)
|
||||
const required = "max-width: 100%; height: auto; display: block;"
|
||||
if (styleMatch) {
|
||||
const quote = styleMatch[1]
|
||||
const styleValue = styleMatch[2] ?? ""
|
||||
if (styleValue.includes("max-width") || styleValue.includes("width")) return next
|
||||
const merged = styleValue.trim().length ? `${styleValue.replace(/;?\s*$/, "; ")}${required}` : required
|
||||
return next.replace(/\bstyle\s*=\s*(['"])([\s\S]*?)\1/i, `style=${quote}${merged}${quote}`)
|
||||
}
|
||||
|
||||
return next.replace(/<img\b/i, `<img style="${required}"`)
|
||||
})
|
||||
}
|
||||
|
||||
const nodes = computed(() => {
|
||||
const html = detail.value.description
|
||||
if (!html) return ""
|
||||
return normalizeRichText(html)
|
||||
return parseHtml(html)
|
||||
})
|
||||
|
||||
function getTypeLabel(type: string) {
|
||||
@@ -132,7 +109,7 @@ function formatFileSize(size: number) {
|
||||
}
|
||||
|
||||
function downloadFile(file: any) {
|
||||
uni.downloadFile({
|
||||
downloadProtectedFile({
|
||||
url: file.url,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="通知公告" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="通知公告" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-30rpx" />
|
||||
<view class="notice-container">
|
||||
<view class="notice-list">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="会议预定" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="会议预定" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="detail-header">
|
||||
<view class="equipment-info">
|
||||
<text class="equipment-name">{{ detail.title || detail.equipmentName || '无标题' }}</text>
|
||||
@@ -28,7 +28,7 @@
|
||||
<text class="description">{{ detail.description }}</text>
|
||||
</view>
|
||||
<view v-if="imageList.length" class="image-list">
|
||||
<image v-for="(img, idx) in imageList" :key="idx" :src="filePath(img)" class="repair-img" mode="aspectFill" />
|
||||
<image v-for="(img, idx) in imageList" :key="idx" :src="$fileUrl(filePath(img))" class="repair-img" mode="aspectFill" @error="$fileRetry(filePath(img))" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
<text class="reply-text">{{ detail.handleRemark }}</text>
|
||||
</view>
|
||||
<view v-if="handleImageList.length" class="handle-image-list">
|
||||
<image v-for="(img, idx) in handleImageList" :key="idx" :src="filePath(img)" class="handle-img"
|
||||
mode="aspectFill" @click="previewHandleImage(idx)" />
|
||||
<image v-for="(img, idx) in handleImageList" :key="idx" :src="$fileUrl(filePath(img))" class="handle-img"
|
||||
mode="aspectFill" @click="previewHandleImage(idx)" @error="$fileRetry(filePath(img))" />
|
||||
</view>
|
||||
<view class="reply-footer">
|
||||
<text class="handle-by" v-if="detail.handleBy">处理人:{{ detail.handleBy }}</text>
|
||||
@@ -61,6 +61,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { previewFiles } from '@/sheep/utils/file-access'
|
||||
|
||||
import { ref, computed } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
@@ -181,7 +183,7 @@ const hasHandleInfo = computed(() => {
|
||||
function previewHandleImage(index: number) {
|
||||
if (handleImageList.value.length === 0) return
|
||||
const urls = handleImageList.value.map(img => filePath(img))
|
||||
uni.previewImage({
|
||||
previewFiles({
|
||||
current: index,
|
||||
urls: urls
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll title="会议预定" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll title="会议预定" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="repair-tabs">
|
||||
<view :class="['tab', { active: activeTab === 0 }]" @click="activeTab = 0">维修申请</view>
|
||||
<view :class="['tab', { active: activeTab === 1 }]" @click="activeTab = 1">维修记录</view>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="详情" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="详情" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<view class="banner-detail">
|
||||
<view class="detail-header">
|
||||
<view class="title">{{ detail.title || "加载中..." }}</view>
|
||||
@@ -7,7 +7,7 @@
|
||||
<view v-if="loading" class="loading-tip">加载中...</view>
|
||||
<view v-else-if="error" class="error-tip">{{ error }}</view>
|
||||
<view v-else class="detail-content">
|
||||
<rich-text :nodes="richTextNodes || ''" />
|
||||
<rich-text :nodes="$fileNodes(richTextNodes || '')" />
|
||||
</view>
|
||||
</view>
|
||||
</crud-layout>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="工作代办" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="工作代办" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="todo-page">
|
||||
<view class="todo-tabs">
|
||||
<view :class="['tab-item', activeTab === 0 ? 'active' : '']" @click="switchTab(0)">我的待办</view>
|
||||
@@ -112,7 +112,7 @@
|
||||
<text v-if="selectedUser?.id === employee.id" class="check-icon">✓</text>
|
||||
</view>
|
||||
<view class="user-icon employee-icon">
|
||||
<image v-if="employee.avatar" :src="employee.avatar" class="avatar-img" />
|
||||
<image v-if="employee.avatar" :src="$fileUrl(employee.avatar)" class="avatar-img" @error="$fileRetry(employee.avatar)" />
|
||||
<text v-else class="avatar-text">{{ employee.name.charAt(0) }}</text>
|
||||
</view>
|
||||
<view class="user-info">
|
||||
@@ -226,7 +226,7 @@
|
||||
<view v-if="flow.userVoList && flow.userVoList.length > 0" class="flow-users">
|
||||
<view v-for="user in flow.userVoList" :key="user.id" class="flow-user">
|
||||
<view class="user-avatar">
|
||||
<image v-if="user.avatar" :src="user.avatar" class="avatar-img" />
|
||||
<image v-if="user.avatar" :src="$fileUrl(user.avatar)" class="avatar-img" @error="$fileRetry(user.avatar)" />
|
||||
<text v-else class="avatar-text">{{ user.name?.charAt(0) || '?' }}</text>
|
||||
</view>
|
||||
<text class="user-name">{{ user.name || '未知用户' }}</text>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="详情" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="详情" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view v-if="detail.id">
|
||||
<view class="h-20rpx" />
|
||||
<tm-alert v-if="alertListType2[detail.checkStatus] && detail.type == '2'" :showClose="false" skin="normal"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="访客记录" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="访客记录" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="访客邀约" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="访客邀约" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-20rpx" />
|
||||
<tm-sheet :margin="[0]">
|
||||
<tm-alert :border="['2']" :borderColor="['#89c0ff']" :darkBorderColor="['#3b5066']">访客邀约请填写以下信息</tm-alert>
|
||||
|
||||
@@ -67,14 +67,14 @@ const toDetail = async (v: any) => {
|
||||
<swiper class="w-100vw h-30vh" circular :indicator-dots="true" indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff" :autoplay="true">
|
||||
<swiper-item v-for="(v, i) in state.detail?.swiperPic?.split(',')" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
|
||||
<image class="w-full h-full" :src="$fileUrl(filePath(v))" mode="aspectFill" @error="$fileRetry(filePath(v))" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</template>
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i"
|
||||
@tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="filePath(v.logoPic)"
|
||||
mode="aspectFill" />
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="$fileUrl(filePath(v.logoPic))"
|
||||
mode="aspectFill" @error="$fileRetry(filePath(v.logoPic))" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="sub-text-34">{{ v.name }}</view>
|
||||
<view class="m-t-10rpx">
|
||||
|
||||
@@ -55,11 +55,11 @@ const doViewQrcode = async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout tabBarType="just-flot-back" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout tabBarType="just-flot-back" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-30rpx"></view>
|
||||
<view class="size-full relative">
|
||||
<image class="w-650rpx h-1030rpx p-10rpx rounded-12rpx" :src="filePath(SERVICE_IMAGE.birthdayCoupon)"
|
||||
mode="aspectFit" />
|
||||
<image class="w-650rpx h-1030rpx p-10rpx rounded-12rpx" :src="$fileUrl(filePath(SERVICE_IMAGE.birthdayCoupon))"
|
||||
mode="aspectFit" @error="$fileRetry(filePath(SERVICE_IMAGE.birthdayCoupon))" />
|
||||
<view class="z-100 size-120px absolute left-20rpx top-600rpx flex-row-center bg-white p-20rpx rounded-12rpx"
|
||||
@tap="doViewQrcode">
|
||||
<canvas canvas-id="qrcodeId" class="size-100px" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll tabBarType="just-flot-back" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll tabBarType="just-flot-back" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<tm-sticky>
|
||||
<swiper class="w-100vw h-30vh" circular :indicator-dots="true" indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff" :autoplay="true">
|
||||
<swiper-item v-for="(v, i) in state.detail?.swiperPic?.split(',')" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
|
||||
<image class="w-full h-full" :src="$fileUrl(filePath(v))" mode="aspectFill" @error="$fileRetry(filePath(v))" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
<view class="h-15rpx" />
|
||||
<!-- start 简介 start -->
|
||||
<view class="flex-row card p-20rpx m-b-20rpx">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="filePath(state.detail.logoPic)"
|
||||
mode="aspectFill" />
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="$fileUrl(filePath(state.detail.logoPic))"
|
||||
mode="aspectFill" @error="$fileRetry(filePath(state.detail.logoPic))" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="sub-text-34">{{ state.detail.name }}</view>
|
||||
<view class="m-t-10rpx">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="商户活动" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="商户活动" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<view v-if="state.actId" class="py-32rpx">
|
||||
<view v-if="state.actType == 'CANCEL_ACT'"
|
||||
class="card rounded-lb-0! rounded-rb-0! w-full h-400rpx relative activity-card overflow-hidden">
|
||||
@@ -85,7 +85,7 @@
|
||||
</template>
|
||||
</view>
|
||||
<view class="detail-content">
|
||||
<rich-text :nodes="nodes || ''"></rich-text>
|
||||
<rich-text :nodes="$fileNodes(nodes || '')"></rich-text>
|
||||
</view>
|
||||
<template #main-bottom>
|
||||
<view class="w-full flex-col-center">
|
||||
@@ -105,7 +105,7 @@ import { actCancel, actComApi, actCouponApi, userApi } from "@/sheep/api"
|
||||
import { hooks, router } from "@/sheep"
|
||||
import { serviceEnum, storageConstant } from "@@/constant";
|
||||
import { SERVICE_IMAGE } from "@@/constant/index"
|
||||
import { filePath } from "@@/utils/file"
|
||||
import { filePath, parseHtml } from "@@/utils/file"
|
||||
|
||||
import ModifyUser from "@@/components/modify-user.vue"
|
||||
|
||||
@@ -122,7 +122,7 @@ const state = reactive<any>({
|
||||
})
|
||||
|
||||
const nodes = computed(() => {
|
||||
return state.actDetail.description?.replaceAll(`<img src="/api`, `<img src="https://stgl.pj.gov.cn/api`)
|
||||
return parseHtml(state.actDetail.description || '')
|
||||
})
|
||||
|
||||
onLoad((option: any) => {
|
||||
|
||||
@@ -160,7 +160,7 @@ const genVerificationCode = async (params: Record<string, any>) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="我的礼券" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="我的礼券" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="dynamicPageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false"
|
||||
|
||||
@@ -70,12 +70,12 @@ const doCancelRefund = async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="订单详情" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="订单详情" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="flex-row-center m-t-30rpx"
|
||||
v-if="state.detail.orderStatus === '5' && ['2', '7'].includes(state.detail.orderType)">
|
||||
<view class="flex-row-center bg-white w-550rpx rounded-16rpx">
|
||||
<image class="w-500rpx" :src="filePath(state.detail.reserveCode)" mode="widthFix"
|
||||
@click.stop="hooks.usePreviewImage(filePath(state.detail.reserveCode))" />
|
||||
<image class="w-500rpx" :src="$fileUrl(filePath(state.detail.reserveCode))" mode="widthFix"
|
||||
@click.stop="hooks.usePreviewImage(filePath(state.detail.reserveCode))" @error="$fileRetry(filePath(state.detail.reserveCode))" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
@@ -118,7 +118,7 @@ const doCancelRefund = async () => {
|
||||
<view class="m-t-15rpx">
|
||||
<view class="flex-row items-start justify-between" v-for="(v, i) in state.shopCarList" :key="i">
|
||||
<view class="flex-row items-center">
|
||||
<image class="w-160rpx h-160rpx rounded-8rpx" :src="filePath(v.productPic)" mode="aspectFill" />
|
||||
<image class="w-160rpx h-160rpx rounded-8rpx" :src="$fileUrl(filePath(v.productPic))" mode="aspectFill" @error="$fileRetry(filePath(v.productPic))" />
|
||||
<view class="flex-col m-l-15rpx second-text-26">
|
||||
<view class="sub-text-28">{{ v.productName }}</view>
|
||||
<view class="m-t-5rpx color-red">¥ {{ hooks.useMoney(v.productPrice) }}</view>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="支付成功" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="支付成功" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<view class="flex-col-center p-30rpx m-t-30rpx card">
|
||||
<view class="flex-col-center m-y-50rpx">
|
||||
<svg t="1742978804614" class="icon" viewBox="0 0 1024 1024" version="1.1"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll :title="scanPayState.mchName" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout mainIsScroll :title="scanPayState.mchName" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<view class="h-screen flex flex-col">
|
||||
<tm-sheet :margin="[0, 10]" class="flex flex-col ">
|
||||
<view class="flex flex-row items-center">
|
||||
@@ -26,7 +26,7 @@
|
||||
:class="{ 'border-6 border-solid border-blue!': selectWallet.id == v.id }"
|
||||
@click="selectWallet = v">
|
||||
<view class="flex items-center">
|
||||
<image class="size-50rpx mr-8rpx" :src="filePath(v.walletTypeIcon)" />
|
||||
<image class="size-50rpx mr-8rpx" :src="$fileUrl(filePath(v.walletTypeIcon))" @error="$fileRetry(filePath(v.walletTypeIcon))" />
|
||||
<view class="text-32rpx">{{ v.walletTypeName }}</view>
|
||||
</view>
|
||||
<view class="text-28rpx flex items-center">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<crud-layout title="转账" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="转账" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-20rpx"></view>
|
||||
<view class="p-32rpx card flex items-center justify-between">
|
||||
<view class="flex items-center">
|
||||
<image class="w-64rpx h-64rpx mr-16rpx" :src="filePath(payStore.sourceWalletData.walletTypeIcon)" />
|
||||
<image class="w-64rpx h-64rpx mr-16rpx" :src="$fileUrl(filePath(payStore.sourceWalletData.walletTypeIcon))" @error="$fileRetry(filePath(payStore.sourceWalletData.walletTypeIcon))" />
|
||||
<view>{{ payStore.sourceWalletData.walletTypeName }}</view>
|
||||
</view>
|
||||
<view class="flex items-center c-#0094ff! font-bold">
|
||||
@@ -50,7 +50,7 @@
|
||||
:class="{ 'border-4 border-solid border-blue!': targetWalletType.id == v.walletTypeId }"
|
||||
@click="selectTargetWalletType(v)">
|
||||
<view class="flex items-center">
|
||||
<image class="w-70rpx h-70rpx mr-16rpx" :src="filePath(v.walletTypeIcon)" />
|
||||
<image class="w-70rpx h-70rpx mr-16rpx" :src="$fileUrl(filePath(v.walletTypeIcon))" @error="$fileRetry(filePath(v.walletTypeIcon))" />
|
||||
<view class="flex flex-col">
|
||||
<view class="main-text-32">{{ v.walletTypeName }}</view>
|
||||
<view class="text-gray-500 text-sm">{{ v.cardNumber }}</view>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-40rpx"></view>
|
||||
<view class="card flex justify-between items-center mb-16rpx mx-20rpx p-32rpx" v-for="item in categoryList"
|
||||
:key="item.id">
|
||||
<image :src="filePath(item.picUrl)" class="size-100rpx mr-32rpx" />
|
||||
<image :src="$fileUrl(filePath(item.picUrl))" class="size-100rpx mr-32rpx" @error="$fileRetry(filePath(item.picUrl))" />
|
||||
<view class="flex-1 flex-col">
|
||||
<view class="flex justify-between items-center">
|
||||
<text class="sub-text-30">{{ item.name }}</text>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<tm-drawer z-index="800" v-model:show="modelValue" showClose title="购物车" size="80%" bgColor="#ECF4F9"
|
||||
@close="doClose">
|
||||
<view v-if="totPrice > 0" class="flex-row card px-15rpx py-25rpx mb-20rpx" v-for="(v, i) in cartList" :key="i">
|
||||
<image class="size-160rpx rounded-12rpx mr-20rpx bg-#eeeeee" :src="filePath(v.productPic)"
|
||||
mode="aspectFill" />
|
||||
<image class="size-160rpx rounded-12rpx mr-20rpx bg-#eeeeee" :src="$fileUrl(filePath(v.productPic))"
|
||||
mode="aspectFill" @error="$fileRetry(filePath(v.productPic))" />
|
||||
<view class="flex-1 overflow-hidden">
|
||||
<view class="sub-text-30 truncate">{{ v.productName }}</view>
|
||||
<view class="second-text-26 show-line">单位 {{ v.unit }}</view>
|
||||
@@ -30,7 +30,7 @@
|
||||
</view>
|
||||
|
||||
<view v-else class="flex-col justify-center items-center pt-300rpx">
|
||||
<image :src="filePath(SERVICE_IMAGE.carEmpty)" class="size-350rpx" />
|
||||
<image :src="$fileUrl(filePath(SERVICE_IMAGE.carEmpty))" class="size-350rpx" @error="$fileRetry(filePath(SERVICE_IMAGE.carEmpty))" />
|
||||
<text class="sub-text-32 font-bold">购物车空空如也</text>
|
||||
</view>
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
<view class="flex-col card py-20rpx px-30rpx mb-20rpx">
|
||||
<view class="prefix_title mb-15rpx">商品信息</view>
|
||||
<view class="flex items-center">
|
||||
<image class="size-160rpx bg-#eeeeee rounded-1 mr-16rpx" :src="filePath(goodsInfo.coverImage)"
|
||||
<image class="size-160rpx bg-#eeeeee rounded-1 mr-16rpx" :src="$fileUrl(filePath(goodsInfo.coverImage))"
|
||||
mode="aspectFill"
|
||||
@tap.stop="goodsInfo.coverImage && usePreviewImage(filePath(goodsInfo.coverImage))" />
|
||||
@tap.stop="goodsInfo.coverImage && usePreviewImage(filePath(goodsInfo.coverImage))" @error="$fileRetry(filePath(goodsInfo.coverImage))" />
|
||||
<view class="flex-1 overflow-hidden">
|
||||
<view class="sub-text-32 truncate">{{ goodsInfo.title }}</view>
|
||||
<view class="second-text-32 c-red!">
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<crud-layout title="共富商城" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="共富商城" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<swiper class="w-full h-500rpx" circular :indicator-dots="true" indicator-active-color="#0779FD"
|
||||
indicator-color="#ffffff" :autoplay="true">
|
||||
<swiper-item v-for="(v, i) in goodsDetail.carouselImages?.split(',')" :key="i">
|
||||
<image class="w-full h-full" :src="filePath(v)" mode="aspectFill" />
|
||||
<image class="w-full h-full" :src="$fileUrl(filePath(v))" mode="aspectFill" @error="$fileRetry(filePath(v))" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
<view class="mt-20rpx card p-20rpx mx-20rpx">
|
||||
<view class="prefix_title">详情</view>
|
||||
<view class="w-full mt-20rpx overflow-hidden text-26rpx!" v-html="description"></view>
|
||||
<view class="w-full mt-20rpx overflow-hidden text-26rpx!" v-html="$fileHtml(description)"></view>
|
||||
</view>
|
||||
<view class="h-30rpx" />
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
import { onLoad } from "@dcloudio/uni-app"
|
||||
import { computed, reactive } from "vue"
|
||||
import { prosperityShopApi } from "@/sheep/api"
|
||||
import { filePath } from "@/sheep/utils/file"
|
||||
import { filePath, parseHtml } from "@/sheep/utils/file"
|
||||
import { displayPrice } from "@/sheep/utils/format-money"
|
||||
import { SERVICE_IMAGE } from "@@/constant/index"
|
||||
|
||||
@@ -105,7 +105,7 @@ const state = reactive<any>({
|
||||
})
|
||||
const goodsDetail = computed(() => state.goodsDetail)
|
||||
const description = computed(() => {
|
||||
return goodsDetail.value.description?.replaceAll(`<img`, `<img style="width: 100%;"`)
|
||||
return parseHtml(goodsDetail.value.description || '')
|
||||
})
|
||||
|
||||
onLoad(async (option: any) => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-30rpx" />
|
||||
<tm-form @submit="onsubmit" v-model="form" :rules="rules" direction="horizontal">
|
||||
<view class="card p-20rpx mb-20rpx">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
<view v-for="v in pageHook.list" :key="v.id" class="card mb-16rpx px-32rpx py-16rpx">
|
||||
<view class="flex">
|
||||
<image :src="filePath(v.coverImage)" class="size-180rpx rounded-12rpx bg-#eeeeee" mode="aspectFill"
|
||||
@click.stop="hooks.usePreviewImage(filePath(v.coverImage))" />
|
||||
<image :src="$fileUrl(filePath(v.coverImage))" class="size-180rpx rounded-12rpx bg-#eeeeee" mode="aspectFill"
|
||||
@click.stop="hooks.usePreviewImage(filePath(v.coverImage))" @error="$fileRetry(filePath(v.coverImage))" />
|
||||
<view class="flex-1 ml-16rpx overflow-hidden">
|
||||
<view class="truncate sub-text-32">{{ v.title }}</view>
|
||||
<view class="sub-text-24 my-6rpx">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="共富商城" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="共富商城" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<view v-for="v in pageHook.list" :key="v.id" class="card flex mb-16rpx p-16rpx"
|
||||
@click="doGoodsDetail(v.id)">
|
||||
<image :src="filePath(v.coverImage)" class="size-160rpx rounded-12rpx bg-#eeeeee" mode="aspectFill" />
|
||||
<image :src="$fileUrl(filePath(v.coverImage))" class="size-160rpx rounded-12rpx bg-#eeeeee" mode="aspectFill" @error="$fileRetry(filePath(v.coverImage))" />
|
||||
<view class="flex-1 ml-16rpx overflow-hidden">
|
||||
<view class="truncate sub-text-30">{{ v.title }}</view>
|
||||
<view>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="结算" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="结算" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-20rpx" />
|
||||
<view class="bg-#FFA61Ecc color-#fff px-16rpx py-8rpx text-28rpx rounded-2">温馨提示:当天的订单预计明天开始配送</view>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<view class="prefix_title text-36rpx mb-16rpx">自提点</view>
|
||||
<view class="flex-row items-center justify-between" @click="onPickupPoint">
|
||||
<view v-if="curPickup.id" class="sub-text-30 mb-16rpx flex items-center">
|
||||
<image class="size-80rpx rounded-1 mr-16rpx" :src="filePath(curPickup.logo)" />
|
||||
<image class="size-80rpx rounded-1 mr-16rpx" :src="$fileUrl(filePath(curPickup.logo))" @error="$fileRetry(filePath(curPickup.logo))" />
|
||||
<view>
|
||||
<view>{{ curPickup.name }}</view>
|
||||
<view class="sub-text-26">{{ curPickup.phone }}</view>
|
||||
@@ -29,8 +29,8 @@
|
||||
<view class="card p-20rpx mb-20rpx">
|
||||
<view class="prefix_title text-36rpx mb-16rpx">我的购买</view>
|
||||
<view v-if="totalCount > 0" class="flex-row mb-20rpx" v-for="(v, i) in cartList" :key="i">
|
||||
<image class="size-140rpx rounded-12rpx mr-20rpx bg-#eeeeee" :src="filePath(v.productPic)"
|
||||
mode="aspectFill" />
|
||||
<image class="size-140rpx rounded-12rpx mr-20rpx bg-#eeeeee" :src="$fileUrl(filePath(v.productPic))"
|
||||
mode="aspectFill" @error="$fileRetry(filePath(v.productPic))" />
|
||||
<view class="flex-1 overflow-hidden">
|
||||
<view class="sub-text-30 truncate">{{ v.productName }}</view>
|
||||
<view class="flex justify-between items-center">
|
||||
@@ -69,8 +69,8 @@
|
||||
<tm-radio v-for="(v, i) in pageHook.list" :key="i" class="w-full h-full px-16rpx" :value="v.id">
|
||||
<template v-slot:label="checked">
|
||||
<view class="flex items-center mb-8rpx">
|
||||
<image class="size-140rpx rounded-12rpx mr-16rpx" :src="filePath(v.logo)"
|
||||
mode="aspectFill" />
|
||||
<image class="size-140rpx rounded-12rpx mr-16rpx" :src="$fileUrl(filePath(v.logo))"
|
||||
mode="aspectFill" @error="$fileRetry(filePath(v.logo))" />
|
||||
<view class="flex-1 overflow-hidden">
|
||||
<view class="sub-text-30 truncate">{{ v.name }}</view>
|
||||
<view class="sub-text-26">{{ v.phone }}</view>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<crud-layout title="共富商城" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)" @scroll="onScroll">
|
||||
<crud-layout title="共富商城" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" @scroll="onScroll">
|
||||
<view class="w-full h-400rpx relative">
|
||||
<image :src="filePath(mchDetail.images)" class="w-full h-full bg-#eeeeee" mode="aspectFill" />
|
||||
<image :src="$fileUrl(filePath(mchDetail.images))" class="w-full h-full bg-#eeeeee" mode="aspectFill" @error="$fileRetry(filePath(mchDetail.images))" />
|
||||
<view class="absolute w-full h-full top-0 left-0" :style="filterStyle"></view>
|
||||
</view>
|
||||
<view v-if="visible"
|
||||
@@ -37,8 +37,8 @@
|
||||
style="height: calc(100vh - 420rpx)">
|
||||
<view v-for="v in state.goodsList" :key="v.id" class="card flex mx-15rpx mb-16rpx p-8rpx"
|
||||
@click="doGoodsDetail(v.id)">
|
||||
<image :src="filePath(v.coverImage)" class="size-170rpx rounded-12rpx bg-#eeeeee"
|
||||
mode="aspectFill" />
|
||||
<image :src="$fileUrl(filePath(v.coverImage))" class="size-170rpx rounded-12rpx bg-#eeeeee"
|
||||
mode="aspectFill" @error="$fileRetry(filePath(v.coverImage))" />
|
||||
<view class="flex-1 ml-16rpx overflow-hidden">
|
||||
<view class="truncate sub-text-30">{{ v.title }}</view>
|
||||
<view>
|
||||
|
||||
@@ -142,12 +142,12 @@ const doSwiper = async (v: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="智慧后勤系统" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="智慧后勤系统" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<view class="h-20rpx" />
|
||||
<swiper class="w-full h-280rpx rounded-16rpx overflow-hidden" circular :indicator-dots="true"
|
||||
indicator-active-color="#0779FD" indicator-color="#ffffff" :autoplay="true">
|
||||
<swiper-item v-for="(v, i) in state?.swiperList" :key="v.id" @tap="doSwiper(v)">
|
||||
<image class="w-full h-full" :src="v.imageUrl" mode="aspectFill" />
|
||||
<image class="w-full h-full" :src="$fileUrl(v.imageUrl)" mode="aspectFill" @error="$fileRetry(v.imageUrl)" />
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<view class="h-20rpx" />
|
||||
@@ -194,7 +194,7 @@ const doSwiper = async (v: any) => {
|
||||
<view class="flex flex-col items-center justify-center" v-for="(v, i) in appMenuListSafe" :key="i"
|
||||
@tap="doMenu(v)">
|
||||
<view class="flex-col-center">
|
||||
<image class="size-100rpx" :src="filePath(v?.icon)" mode="aspectFill" />
|
||||
<image class="size-100rpx" :src="$fileUrl(filePath(v?.icon))" mode="aspectFill" @error="$fileRetry(filePath(v?.icon))" />
|
||||
<view class="m-t-10rpx sub-text-26">{{ v?.title || "" }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -97,12 +97,12 @@ const affirmConfirm = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="登录" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="登录" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-30rpx" />
|
||||
|
||||
<view class="flex-col-center m-t-160rpx">
|
||||
<view class="size-220rpx bg-white rounded-full flex-row-center">
|
||||
<image class="size-200rpx rounded-full" :src="filePath(SERVICE_IMAGE.logo)" mode="aspectFit" />
|
||||
<image class="size-200rpx rounded-full" :src="$fileUrl(filePath(SERVICE_IMAGE.logo))" mode="aspectFit" @error="$fileRetry(filePath(SERVICE_IMAGE.logo))" />
|
||||
</view>
|
||||
<view class="m-t-20rpx sub-text-28">浦江县机关事务智慧后勤一体化平台</view>
|
||||
</view>
|
||||
|
||||
@@ -112,7 +112,7 @@ const affirmModalConfirm = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="账号密码登录" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="账号密码登录" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-30rpx" />
|
||||
<view class="card p-x-30rpx p-y-40rpx">
|
||||
<tm-form ref="applyFormRef" v-model="applyForm" :rules="applyFormRules" direction="vertical">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
|
||||
@@ -55,13 +55,13 @@ const toDetail = async (v: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="食堂" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="食堂" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="$fileUrl(filePath(v.logoPic))" mode="aspectFill" @error="$fileRetry(filePath(v.logoPic))" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="喜好分析" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="喜好分析" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" safe-area-inset-bottom :loading-more-enabled="true"
|
||||
:show-scrollbar="false" @query="query" :auto-clean-list-when-reload="false"
|
||||
:auto-scroll-to-top-when-reload="false" hide-empty-view>
|
||||
|
||||
@@ -70,7 +70,7 @@ const toDetail = async (v: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="合作商家" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="合作商家" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
@@ -93,7 +93,7 @@ const toDetail = async (v: any) => {
|
||||
</template>
|
||||
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="$fileUrl(filePath(v.logoPic))" mode="aspectFill" @error="$fileRetry(filePath(v.logoPic))" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="sub-text-34">
|
||||
<text class="mr-16rpx">{{ v.name }}</text>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<div class="integrated-title-card">
|
||||
<div class="integrated-title">综合服务</div>
|
||||
</div>
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="service-grid">
|
||||
<div v-for="item in services" :key="item.name" class="service-item" @click="goPage(item)">
|
||||
<div class="service-icon-wrapper">
|
||||
<image :src="item.icon" class="service-icon" />
|
||||
<image :src="$fileUrl(item.icon)" class="service-icon" @error="$fileRetry(item.icon)" />
|
||||
<view v-if="item.name === 'todo' && todoCount > 0" class="badge">
|
||||
{{ todoCount > 99 ? "99+" : todoCount }}
|
||||
</view>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<crud-layout title="我的" mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="我的" mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<template #main-top>
|
||||
<view class="flex items-center py-24rpx px-40rpx" @tap="doUserArea">
|
||||
<view class="flex items-center" v-if="state.userInfo?.sysUser?.userId">
|
||||
<image v-if="state.userInfo?.sysUser?.userId" class="size-100rpx rounded-full"
|
||||
:src="filePath(state.userInfo.sysUser.avatar)" mode="aspectFill" />
|
||||
:src="$fileUrl(filePath(state.userInfo.sysUser.avatar))" mode="aspectFill" @error="$fileRetry(filePath(state.userInfo.sysUser.avatar))" />
|
||||
<image v-else class="w-100rpx h-100rpx rounded-full" src="/static/icon/default-avatar.png"
|
||||
mode="aspectFill" />
|
||||
<view class="ml-30rpx">
|
||||
@@ -32,7 +32,7 @@
|
||||
<view class="service_item flex items-center justify-between" v-for="(v, i) in state.menuList" :key="i"
|
||||
@tap="onTabMenu(v)">
|
||||
<view class="flex-row-center">
|
||||
<image class="size-40rpx" :src="v.icon" mode="aspectFill" />
|
||||
<image class="size-40rpx" :src="$fileUrl(v.icon)" mode="aspectFill" @error="$fileRetry(v.icon)" />
|
||||
<text class="sub-text-28 m-l-20rpx">{{ v.text }}</text>
|
||||
</view>
|
||||
<view class="iconfont icon-youjiantou" />
|
||||
|
||||
@@ -86,7 +86,7 @@ const doRefund = (v: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="订单" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="订单" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
@@ -98,7 +98,7 @@ const doRefund = (v: any) => {
|
||||
|
||||
<view class="flex-col justify-center card p-24rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i">
|
||||
<view class="flex-row">
|
||||
<image class="size-130rpx rounded-8rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<image class="size-130rpx rounded-8rpx" :src="$fileUrl(filePath(v.logoPic))" mode="aspectFill" @error="$fileRetry(filePath(v.logoPic))" />
|
||||
<view class="flex-1 ml-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="sub-text-30">{{ v.merchantName }}</view>
|
||||
@@ -145,9 +145,9 @@ const doRefund = (v: any) => {
|
||||
<view class="flex items-center w-6/10">
|
||||
<view class="size-100rpx">
|
||||
<image v-if="v.payType == '9'" class="size-100rpx rounded-8rpx"
|
||||
:src="pV.productPic" mode="aspectFill" />
|
||||
<image v-else class="size-100rpx rounded-8rpx" :src="filePath(pV.productPic)"
|
||||
mode="aspectFill" />
|
||||
:src="$fileUrl(pV.productPic)" mode="aspectFill" @error="$fileRetry(pV.productPic)" />
|
||||
<image v-else class="size-100rpx rounded-8rpx" :src="$fileUrl(filePath(pV.productPic))"
|
||||
mode="aspectFill" @error="$fileRetry(filePath(pV.productPic))" />
|
||||
</view>
|
||||
<view class="ml-16rpx overflow-hidden">
|
||||
<view class="sub-text-26 truncate">{{ pV.productName }}</view>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<crud-layout title="共富商城" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="共富商城" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
<view class="card p-20rpx mb-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<view class="flex">
|
||||
<image class="w-160rpx h-160rpx bg-#eeeeee rounded-12rpx" :src="filePath(v.images)"
|
||||
mode="aspectFill" />
|
||||
<image class="w-160rpx h-160rpx bg-#eeeeee rounded-12rpx" :src="$fileUrl(filePath(v.images))"
|
||||
mode="aspectFill" @error="$fileRetry(filePath(v.images))" />
|
||||
<view class="ml-20rpx flex-1 overflow-hidden">
|
||||
<view class="sub-text-32 truncate">{{ v.name }}</view>
|
||||
<view class="second-text-26 flex justify-between my-6rpx">
|
||||
@@ -46,8 +46,8 @@
|
||||
<view class="flex">
|
||||
<view class="w-180rpx flex-col items-center mr-20rpx" v-for="(pV, pI) in v.featuredProducts"
|
||||
:key="pI">
|
||||
<image class="size-180rpx rounded-12rpx bg-#eeeeee" :src="filePath(pV.coverImage)"
|
||||
mode="aspectFill" />
|
||||
<image class="size-180rpx rounded-12rpx bg-#eeeeee" :src="$fileUrl(filePath(pV.coverImage))"
|
||||
mode="aspectFill" @error="$fileRetry(filePath(pV.coverImage))" />
|
||||
<view class="w-full mt-4rpx sub-text-24 truncate">{{ pV.title }}</view>
|
||||
<view class="w-full flex justify-between">
|
||||
<text class="text-26rpx color-red!">
|
||||
|
||||
@@ -79,7 +79,7 @@ const toDetail = async (v: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="共富商家" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="共富商家" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
@@ -103,7 +103,7 @@ const toDetail = async (v: any) => {
|
||||
</template>
|
||||
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx my-auto" :src="$fileUrl(filePath(v.logoPic))" mode="aspectFill" @error="$fileRetry(filePath(v.logoPic))" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="sub-text-34">
|
||||
<text class="mr-16rpx">{{ v.name }}</text>
|
||||
|
||||
@@ -43,13 +43,13 @@ const toDetail = async (v: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="自营商家" :bg="filePath(SERVICE_IMAGE.blueBg)" ref="crudLayoutRef">
|
||||
<crud-layout title="自营商家" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))" ref="crudLayoutRef">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
<view class="h-20rpx" />
|
||||
<view class="flex-row card p-20rpx m-b-20rpx" v-for="(v, i) in pageHook.list" :key="i" @tap="toDetail(v)">
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="filePath(v.logoPic)" mode="aspectFill" />
|
||||
<image class="w-180rpx h-180rpx rounded-12rpx" :src="$fileUrl(filePath(v.logoPic))" mode="aspectFill" @error="$fileRetry(filePath(v.logoPic))" />
|
||||
<view class="flex-1 flex-col m-l-20rpx">
|
||||
<view class="flex-row items-center justify-between">
|
||||
<view class="flex-row-center sub-text-34">{{ v.name }}</view>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<crud-layout mainIsScroll :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout mainIsScroll :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="w-full text-center mt-20">
|
||||
<image :src="filePath(SERVICE_IMAGE.happyMall)" class="rounded-full w-1/3" mode="widthFix" />
|
||||
<image :src="$fileUrl(filePath(SERVICE_IMAGE.happyMall))" class="rounded-full w-1/3" mode="widthFix" @error="$fileRetry(filePath(SERVICE_IMAGE.happyMall))" />
|
||||
<view>美好商城</view>
|
||||
<view class="h-100rpx" />
|
||||
<tm-button @click="show = true">继续跳转</tm-button>
|
||||
|
||||
@@ -45,7 +45,7 @@ const doTab = (e: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="饭卡" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="饭卡" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="10"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
|
||||
@@ -141,7 +141,7 @@ const doTransferMoney = (v: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="我的钱包" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="我的钱包" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<z-paging ref="pageRef" height="100%" :fixed="false" v-model="pageHook.list" :default-page-size="5"
|
||||
safe-area-inset-bottom :loading-more-enabled="true" :show-scrollbar="false" @query="query"
|
||||
:auto-clean-list-when-reload="false" :auto-scroll-to-top-when-reload="false" @scroll="pageHook.scroll">
|
||||
@@ -164,7 +164,7 @@ const doTransferMoney = (v: any) => {
|
||||
</view>
|
||||
<view class="flex-row items-center justify-between m-t-10rpx">
|
||||
<view class="flex-row items-center">
|
||||
<image class="size-50rpx rounded-full" :src="filePath(v.walletTypeIcon)" mode="aspectFill" />
|
||||
<image class="size-50rpx rounded-full" :src="$fileUrl(filePath(v.walletTypeIcon))" mode="aspectFill" @error="$fileRetry(filePath(v.walletTypeIcon))" />
|
||||
<text class="m-l-25rpx sub-text-28">
|
||||
{{ v.walletTypeName }}
|
||||
</text>
|
||||
|
||||
@@ -110,13 +110,13 @@ const toRechargeRecord = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<crud-layout title="充值" :bg="filePath(SERVICE_IMAGE.blueBg)">
|
||||
<crud-layout title="充值" :bg="$fileUrl(filePath(SERVICE_IMAGE.blueBg))">
|
||||
<view class="h-30rpx" />
|
||||
<view @tap="toRechargeRecord"
|
||||
class="relative flex-row items-center justify-between h-120rpx p-x-30rpx bg-#222222 rounded-20rpx">
|
||||
<view class="flex-row items-center">
|
||||
<view class="flex-row-center size-60rpx bg-white rounded-full">
|
||||
<image class="size-50rpx rounded-full" :src="state.detail.walletIcon" mode="aspectFill" />
|
||||
<image class="size-50rpx rounded-full" :src="$fileUrl(state.detail.walletIcon)" mode="aspectFill" @error="$fileRetry(state.detail.walletIcon)" />
|
||||
</view>
|
||||
<view class="flex-row-center">
|
||||
<view class="m-l-25rpx main-text-32 color-#fbddb0!">
|
||||
|
||||
@@ -169,7 +169,7 @@ defineExpose({
|
||||
|
||||
<template>
|
||||
<view class="layout">
|
||||
<image class="layout_bg" v-if="props.bg" :src="props.bg" mode="aspectFill" />
|
||||
<image class="layout_bg" v-if="props.bg" :src="$fileUrl(props.bg)" mode="aspectFill" @error="$fileRetry(props.bg)" />
|
||||
<view class="layout_header">
|
||||
<base-safe-height :bgColor="props.navBgColor" v-if="state.visble.topSafe" type="top" />
|
||||
<base-nav v-if="state.visble.topNav" :titleColor="props.navBgTitleColor" :bgColor="props.navBgColor"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<view v-for="item in nodeData" :key="item.id">
|
||||
<view class="tree-item" :style="item.id == selectedNodeId ? { borderColor: '#1879ff' } : { color: '#000' }"
|
||||
@click.stop="toCurrentNode(item)">
|
||||
<image class="tree-item-icon" :src="filePath(item.picUrl)" />
|
||||
<image class="tree-item-icon" :src="$fileUrl(filePath(item.picUrl))" @error="$fileRetry(filePath(item.picUrl))" />
|
||||
<text>{{ item.name }}</text>
|
||||
</view>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<view class="keyboard-panel" :class="{ 'keyboard-panel--open': show }">
|
||||
<view class="keyboard-toggle" @tap.stop="toggleShow">
|
||||
<image class="keyboard-toggle__icon"
|
||||
:src="show ? '/static/page/fold.svg' : '/static/page/unfold.svg'" />
|
||||
:src="$fileUrl(show ? '/static/page/fold.svg' : '/static/page/unfold.svg')" @error="$fileRetry(show ? '/static/page/fold.svg' : '/static/page/unfold.svg')" />
|
||||
</view>
|
||||
<view v-show="show" class="keyboard-content">
|
||||
<view class="flex mb-20rpx" v-for="(row, rowIndex) in keyboardLayout" :key="rowIndex">
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
},
|
||||
{ 'img-error': !item2[data.imageKey] },
|
||||
]"
|
||||
:src="item2[data.imageKey]"
|
||||
:src="$fileUrl(item2[data.imageKey])"
|
||||
mode="widthFix"
|
||||
@load="imgLoad(item2, index + 1)"
|
||||
@error="imgError(item2, index + 1)"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { previewFiles } from '@/sheep/utils/file-access'
|
||||
export const usePreviewImage = (str: string | undefined) => {
|
||||
if (str == undefined) return
|
||||
let urlList = str.split(",")
|
||||
uni.previewImage({
|
||||
previewFiles({
|
||||
urls: urlList,
|
||||
})
|
||||
}
|
||||
+10
-49
@@ -1,50 +1,11 @@
|
||||
import { isDevEnv } from "./app"
|
||||
export { fileUrl as filePath, originalFileUrl, stripFileHtml, downloadFile, previewFiles } from './file-access'
|
||||
import { fileHtml } from './file-access'
|
||||
|
||||
const normalizeBase = (base: string | undefined) => {
|
||||
if (!base) return ""
|
||||
return base.endsWith("/") ? base.slice(0, -1) : base
|
||||
}
|
||||
|
||||
const ensureLeadingSlash = (url: string) => {
|
||||
if (!url) return ""
|
||||
return url.startsWith("/") ? url : `/${url}`
|
||||
}
|
||||
|
||||
export const filePath = (path?: string | null) => {
|
||||
const rawPath = (path || "").trim()
|
||||
if (!rawPath) return ""
|
||||
if (/^https?:\/\//i.test(rawPath)) return rawPath
|
||||
const devBase = normalizeBase(import.meta.env.VITE_IMAGE_DEV_PATH || import.meta.env.VITE_APP_DEV_SERVICE)
|
||||
const prodBase = normalizeBase(import.meta.env.VITE_APP_PROD_IMAGE)
|
||||
const base = isDevEnv() ? devBase : prodBase
|
||||
|
||||
if (!base) return rawPath
|
||||
|
||||
return `${base}${ensureLeadingSlash(rawPath)}`
|
||||
}
|
||||
|
||||
export const parseHtml = (html: string) => {
|
||||
const origin = "https://stgl.pj.gov.cn"
|
||||
return html.replace(/<img\b[^>]*>/gi, (imgTag) => {
|
||||
let next = imgTag
|
||||
|
||||
next = next.replace(/\bsrc\s*=\s*(['"])(.*?)\1/i, (_m, quote: string, src: string) => {
|
||||
let resolved = src
|
||||
if (resolved?.startsWith("/api")) resolved = `${origin}${resolved}`
|
||||
if (resolved?.startsWith("//")) resolved = `https:${resolved}`
|
||||
return `src=${quote}${resolved}${quote}`
|
||||
})
|
||||
|
||||
const styleMatch = next.match(/\bstyle\s*=\s*(['"])([\s\S]*?)\1/i)
|
||||
const required = "max-width: 100%; height: auto; display: block;"
|
||||
if (styleMatch) {
|
||||
const quote = styleMatch[1]
|
||||
const styleValue = styleMatch[2] ?? ""
|
||||
if (styleValue.includes("max-width") || styleValue.includes("width")) return next
|
||||
const merged = styleValue.trim().length ? `${styleValue.replace(/;?\s*$/, "; ")}${required}` : required
|
||||
return next.replace(/\bstyle\s*=\s*(['"])([\s\S]*?)\1/i, `style=${quote}${merged}${quote}`)
|
||||
}
|
||||
|
||||
return next.replace(/<img\b/i, `<img style="${required}"`)
|
||||
})
|
||||
}
|
||||
/** Preserve existing responsive article images while signing resource attributes. */
|
||||
export const parseHtml = (html: string) => fileHtml(html || '').replace(/<img\b[^>]*>/gi, img => {
|
||||
const required = 'max-width: 100%; height: auto; display: block;'
|
||||
const style = img.match(/\bstyle\s*=\s*(['"])([\s\S]*?)\1/i)
|
||||
if (!style) return img.replace(/<img\b/i, `<img style="${required}"`)
|
||||
if (/(?:max-)?width\s*:/i.test(style[2])) return img
|
||||
return img.replace(style[0], `style=${style[1]}${style[2].replace(/;?\s*$/, '; ')}${required}${style[1]}`)
|
||||
})
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
}" class="tmAvatarGroupImage"
|
||||
:class="[!_flat?'tmAvatarGroupImageFLat':'']"
|
||||
:src="item.name" :mode="props.model"></image>
|
||||
:src="$fileUrl(item.name)" :mode="props.model" @error="$fileRetry(item.name)"></image>
|
||||
<view @click="itemClick(item,index)" v-else :style="{
|
||||
width:_size,
|
||||
height:_size,
|
||||
|
||||
@@ -4,37 +4,37 @@
|
||||
<!-- 图片 -->
|
||||
<!-- 占位图 -->
|
||||
<image v-if="n.name==='img'&&!n.t&&((opts[1]&&!ctrl[i])||ctrl[i]<0)&&typeof (ctrl[i]<0?opts[2]:opts[1]) == 'string'" class="_img" :style="n.attrs.style"
|
||||
:src="ctrl[i]<0?opts[2]:opts[1]" mode="widthFix" />
|
||||
:src="$fileUrl(ctrl[i]<0?opts[2]:opts[1])" mode="widthFix" @error="$fileRetry(ctrl[i]<0?opts[2]:opts[1])" />
|
||||
<!-- 显示图片 -->
|
||||
<!-- #ifdef H5 || (APP-PLUS && VUE2) -->
|
||||
<img v-if="n.name==='img'&&typeof (n.attrs.src||(ctrl.load?n.attrs['data-src']:'')) == 'string'" :id="n.attrs.id" :class="'_img '+n.attrs.class"
|
||||
:style="(ctrl[i]===-1?'display:none;':'')+n.attrs.style"
|
||||
:src="n.attrs.src||(ctrl.load?n.attrs['data-src']:'')" :data-i="i" @load="imgLoad" @error="mediaError"
|
||||
:src="$fileUrl(n.attrs.src||(ctrl.load?n.attrs['data-src']:''))" :data-i="i" @load="imgLoad" @error="mediaError"
|
||||
@tap.stop="imgTap(n.attrs.src||(ctrl.load?n.attrs['data-src']:''))" @longpress="imgLongTap" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef H5 || (APP-PLUS && VUE2) -->
|
||||
<!-- 表格中的图片,使用 rich-text 防止大小不正确 -->
|
||||
<rich-text v-if="n.name==='img'&&n.t" :style="'display:'+n.t"
|
||||
:nodes="[{attrs:{style:n.attrs.style||'',src:n.attrs.src},name:'img'}]" :data-i="i"
|
||||
:nodes="$fileNodes([{attrs:{style:n.attrs.style||'',src:n.attrs.src},name:'img'}])" :data-i="i"
|
||||
@tap.stop="imgTap(n.attrs.sr)" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef H5 || APP-PLUS || MP-KUAISHOU -->
|
||||
<image v-else-if="n.name==='img'" :id="n.attrs.id" :class="'_img '+n.attrs.class"
|
||||
:style="(ctrl[i]===-1?'display:none;':'')+'width:'+(ctrl[i]||1)+'px;height:1px;'+n.attrs.style"
|
||||
:src="n.attrs.src" :mode="!n.h?'widthFix':(!n.w?'heightFix':(n.m||'scaleToFill'))" :lazy-load="opts[0]"
|
||||
:src="$fileUrl(n.attrs.src)" :mode="!n.h?'widthFix':(!n.w?'heightFix':(n.m||'scaleToFill'))" :lazy-load="opts[0]"
|
||||
:webp="n.webp" :show-menu-by-longpress="opts[3]&&!n.attrs.ignore"
|
||||
:image-menu-prevent="!opts[3]||n.attrs.ignore" :data-i="i" @load="imgLoad" @error="mediaError"
|
||||
@tap.stop="imgTap(n.attrs.src)" @longpress="imgLongTap" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-KUAISHOU -->
|
||||
<image v-else-if="n.name==='img'" :id="n.attrs.id" :class="'_img '+n.attrs.class"
|
||||
:style="(ctrl[i]===-1?'display:none;':'')+n.attrs.style" :src="n.attrs.src" :lazy-load="opts[0]"
|
||||
:style="(ctrl[i]===-1?'display:none;':'')+n.attrs.style" :src="$fileUrl(n.attrs.src)" :lazy-load="opts[0]"
|
||||
:data-i="i" @load="imgLoad" @error="mediaError" @tap.stop="imgTap(n.attrs.src)"></image>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS && VUE3 -->
|
||||
<image v-else-if="n.name==='img'" :id="n.attrs.id" :class="'_img '+n.attrs.class"
|
||||
:style="(ctrl[i]===-1?'display:none;':'')+'width:'+(ctrl[i]||1)+'px;'+n.attrs.style"
|
||||
:src="n.attrs.src||(ctrl.load?n.attrs['data-src']:'')"
|
||||
:src="$fileUrl(n.attrs.src||(ctrl.load?n.attrs['data-src']:''))"
|
||||
:mode="!n.h?'widthFix':(!n.w?'heightFix':(n.m||''))" :data-i="i" @load="imgLoad" @error="mediaError"
|
||||
@tap.stop="imgTap(n.attrs.src||(ctrl.load?n.attrs['data-src']:''))" @longpress="imgLongTap" />
|
||||
<!-- #endif -->
|
||||
@@ -54,24 +54,24 @@
|
||||
<!-- 视频 -->
|
||||
<!-- #ifdef APP-PLUS || APP-HARMONY -->
|
||||
<view v-else-if="n.html" :id="n.attrs.id" :class="'_video '+n.attrs.class" :style="n.attrs.style"
|
||||
v-html="n.html" @vplay.stop="play" />
|
||||
v-html="$fileHtml(n.html)" @vplay.stop="play" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef APP-PLUS || APP-HARMONY -->
|
||||
<video v-else-if="n.name==='video'" :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style"
|
||||
:autoplay="n.attrs.autoplay" :controls="n.attrs.controls" :loop="n.attrs.loop" :muted="n.attrs.muted"
|
||||
:object-fit="n.attrs['object-fit']" :poster="n.attrs.poster" :src="n.src[ctrl[i]||0]" :data-i="i"
|
||||
:object-fit="n.attrs['object-fit']" :poster="$fileUrl(n.attrs.poster)" :src="$fileUrl(n.src[ctrl[i]||0])" :data-i="i"
|
||||
@play="play" @error="mediaError" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef H5 || APP-PLUS || APP-HARMONY -->
|
||||
<iframe v-else-if="n.name==='iframe'" :style="n.attrs.style" :allowfullscreen="n.attrs.allowfullscreen"
|
||||
:frameborder="n.attrs.frameborder" :src="n.attrs.src" />
|
||||
<embed v-else-if="n.name==='embed'" :style="n.attrs.style" :src="n.attrs.src" />
|
||||
:frameborder="n.attrs.frameborder" :src="$fileUrl(n.attrs.src)" />
|
||||
<embed v-else-if="n.name==='embed'" :style="n.attrs.style" :src="$fileUrl(n.attrs.src)" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-TOUTIAO || ((H5 || APP-PLUS || APP-HARMONY) && VUE3) -->
|
||||
<!-- 音频 -->
|
||||
<audio v-else-if="n.name==='audio'" :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style"
|
||||
:author="n.attrs.author" :controls="n.attrs.controls" :loop="n.attrs.loop" :name="n.attrs.name"
|
||||
:poster="n.attrs.poster" :src="n.src[ctrl[i]||0]" :data-i="i" @play="play" @error="mediaError" />
|
||||
:poster="$fileUrl(n.attrs.poster)" :src="$fileUrl(n.src[ctrl[i]||0])" :data-i="i" @play="play" @error="mediaError" />
|
||||
<!-- #endif -->
|
||||
<view v-else-if="(n.name==='table'&&n.c)||n.name==='li'" :id="n.attrs.id"
|
||||
:class="'_'+n.name+' '+n.attrs.class" :style="n.attrs.style">
|
||||
@@ -97,11 +97,11 @@
|
||||
<!-- 富文本 -->
|
||||
<!-- #ifdef H5 || ((MP-WEIXIN || MP-QQ || APP-PLUS || MP-360 || APP-HARMONY) && VUE2) -->
|
||||
<rich-text v-else-if="!n.c&&!handler.isInline(n.name, n.attrs.style)" :id="n.attrs.id" :style="n.f"
|
||||
:user-select="opts[4]" :nodes="[n]" />
|
||||
:user-select="opts[4]" :nodes="$fileNodes([n])" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef H5 || ((MP-WEIXIN || MP-QQ || APP-PLUS || MP-360 || APP-HARMONY) && VUE2) -->
|
||||
<rich-text v-else-if="!n.c" :id="n.attrs.id" :style="'display:inline;'+n.f" :preview="false"
|
||||
:selectable="opts[4]" :user-select="opts[4]" :nodes="[n]" />
|
||||
:selectable="opts[4]" :user-select="opts[4]" :nodes="$fileNodes([n])" />
|
||||
<!-- #endif -->
|
||||
<!-- 继续递归 -->
|
||||
<view v-else-if="n.c===2" :id="n.attrs.id" :class="'_block _'+n.name+' '+n.attrs.class"
|
||||
@@ -143,6 +143,8 @@
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
import { previewFiles, downloadFile, accessFileUrl, retryFileAccess, isProtectedFile, openFileLink } from '@/sheep/utils/file-access'
|
||||
|
||||
import node from './mp-node.vue'
|
||||
// 行内标签列表
|
||||
var inlineTags = {
|
||||
@@ -296,7 +298,7 @@
|
||||
this.$emit('imgtap', e)
|
||||
// 自动预览图片
|
||||
if (this.opts[5]) {
|
||||
uni.previewImage({
|
||||
previewFiles({
|
||||
// #ifdef MP-WEIXIN
|
||||
showmenu: this.opts[3],
|
||||
// #endif
|
||||
@@ -336,7 +338,7 @@
|
||||
})
|
||||
}
|
||||
if (this.root.imgList[attrs.i].startsWith('http')) {
|
||||
uni.downloadFile({
|
||||
downloadFile({
|
||||
url: this.root.imgList[attrs.i],
|
||||
success: res => save(res.tempFilePath)
|
||||
})
|
||||
@@ -392,10 +394,14 @@
|
||||
linkTap(e) {
|
||||
const node = e.currentTarget ? this.childs[e.currentTarget.dataset.i] : {}
|
||||
const attrs = node.attrs || e
|
||||
const href = attrs.href
|
||||
const href = accessFileUrl(attrs.href)
|
||||
this.root.$emit('linktap', Object.assign({
|
||||
innerText: this.root.getText(node.children || []) // 链接内的文本内容
|
||||
}, attrs))
|
||||
if (isProtectedFile(attrs.href)) {
|
||||
openFileLink(attrs.href)
|
||||
return
|
||||
}
|
||||
if (href) {
|
||||
if (href[0] === '#') {
|
||||
// 跳转锚点
|
||||
@@ -438,9 +444,11 @@
|
||||
* @description 错误事件
|
||||
* @param {Event} e
|
||||
*/
|
||||
mediaError(e) {
|
||||
async mediaError(e) {
|
||||
const i = e.currentTarget.dataset.i
|
||||
const node = this.childs[i]
|
||||
const source = node.name === 'img' ? node.attrs.src : node.src?.[this.ctrl[i] || 0]
|
||||
if (await retryFileAccess(source)) return
|
||||
// 加载其他源
|
||||
if (node.name === 'video' || node.name === 'audio') {
|
||||
let index = (this.ctrl[i] || 0) + 1
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
rotateDeg ? { transform: `rotate(${rotateDeg})` } : {},
|
||||
_style
|
||||
]"></text>
|
||||
<image v-if="isImg" @tap="onclick" :src="iconName" :class="['tmIcon', isSpin ? 'tmIconSpin' : '', _class]" :style="[
|
||||
<image v-if="isImg" @tap="onclick" :src="$fileUrl(iconName)" :class="['tmIcon', isSpin ? 'tmIconSpin' : '', _class]" :style="[
|
||||
{ width: iconSize, height: iconSize },
|
||||
rotateDeg ? { transform: `rotate(${rotateDeg})` } : {},
|
||||
_style
|
||||
]"></image>
|
||||
]" @error="$fileRetry(iconName)"></image>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
//@ts-nocheck
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<tm-icon :size="iconSize" v-if="isError" color="error" name="landscape-line"></tm-icon>
|
||||
<tm-icon :size="iconSize" v-if="isLoading" name="loader-line" color="primary" :spin="true"></tm-icon>
|
||||
</view>
|
||||
<image :draggable="draggable" :lazy-load="lazy" :src="_src"
|
||||
<image :draggable="draggable" :lazy-load="lazy" :src="$fileUrl(_src)"
|
||||
:showMenuByLongpress="showMenuByLongpress"
|
||||
:class="[isLoading ? 'tmImageImgAbs' : '', fadeShow ? 'tmImageFadeShow' : '']" :mode="_model"
|
||||
:style="[_styleMap]" class="tmImageImg" @error="imgError" @load="imgLoad">
|
||||
@@ -21,6 +21,8 @@
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { previewFiles } from '@/sheep/utils/file-access'
|
||||
|
||||
//@ts-nocheck
|
||||
import { computed, getCurrentInstance, onBeforeUnmount, onMounted, PropType, ref, watch } from 'vue'
|
||||
import { covetUniNumber, getUid, getUnit } from '../../libs/tool'
|
||||
@@ -274,7 +276,7 @@ const _styleMap = computed(() => {
|
||||
const prevImage = () => {
|
||||
emit('click');
|
||||
if (props.preview) {
|
||||
uni.previewImage({
|
||||
previewFiles({
|
||||
current: props.src,
|
||||
urls: [props.src]
|
||||
});
|
||||
|
||||
@@ -292,8 +292,8 @@ export default {
|
||||
@open="onOpen"
|
||||
>
|
||||
<view class="skuHeader">
|
||||
<tm-image :preview="true" :src="(_nowSelectedItem?.img??_nowImgDefault)" height="160" round="12"
|
||||
width="160"></tm-image>
|
||||
<tm-image :preview="true" :src="$fileUrl((_nowSelectedItem?.img??_nowImgDefault))" height="160" round="12"
|
||||
width="160" @error="$fileRetry((_nowSelectedItem?.img??_nowImgDefault))"></tm-image>
|
||||
<view style="margin-left: 20rpx">
|
||||
<view v-if="_nowSelectedItem">
|
||||
<text :style="{color:'red',fontSize:'36rpx'}">¥{{ _nowSelectedItem.price }}</text>
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
<view v-for="(item, index) in list" :key="index"
|
||||
:style="{ width: `calc(${_width} - ${_coloumn==1?0:guuterSpace}px)`, height: _height,borderRadius:_round }"
|
||||
class="tmUploadPhotoItem">
|
||||
<image :mode="props.mode" :src="item.path" :style="{width: '100%',height: '100%'}"
|
||||
@click="imagePreve(index)"></image>
|
||||
<image :mode="props.mode" :src="$fileUrl(item.path)" :style="{width: '100%',height: '100%'}"
|
||||
@click="imagePreve(index)" @error="$fileRetry(item.path)"></image>
|
||||
<view :style="{ color: STATUS_COLOR.get(item.status) || 'white' }" class="tmUploadLabel">{{ item.statusText
|
||||
}}
|
||||
</view>
|
||||
@@ -49,6 +49,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { previewFiles } from '@/sheep/utils/file-access'
|
||||
|
||||
import { computed, PropType, ref, watch } from 'vue'
|
||||
import { covetUniNumber } from '../../libs/tool'
|
||||
import { TMUPLOAD_PHOTO_STATUS } from '../../interface'
|
||||
@@ -567,7 +569,7 @@
|
||||
emit('delete', JSON.parse(JSON.stringify(item)))
|
||||
}
|
||||
const imagePreve = (index : number) => {
|
||||
uni.previewImage({
|
||||
previewFiles({
|
||||
current: index,
|
||||
urls: list.value.map(item => item.path)
|
||||
})
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<view class="tmUploadPhotoItem"
|
||||
:style="{ width: `calc(${_width} - ${_coloumn==1?0:guuterSpace}px)`, height: _height,borderRadius:_round }"
|
||||
v-for="(item, index) in list" :key="index">
|
||||
<video :autoplay="false" :controls="false" @click="imagePreve(index)" :src="item.path" :mode="props.mode"
|
||||
<video :autoplay="false" :controls="false" @click="imagePreve(index)" :src="$fileUrl(item.path)" :mode="props.mode"
|
||||
style="width: 100%;height: 100%;"></video>
|
||||
<view class="tmUploadLabel" :style="{ color: STATUS_COLOR.get(item.status) || 'white' }">{{ item.statusText
|
||||
}}
|
||||
|
||||
@@ -9,6 +9,13 @@ import { useRouter } from "./src/sheep/plugs/use-router/vite-router-plug"
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ mode }) => {
|
||||
const fileEnv = loadEnv(mode, process.cwd(), '')
|
||||
if (fileEnv.VITE_FILE_ACCESS_APP_ID !== 'mini' || !/^[a-zA-Z0-9_-]{1,32}$/.test(fileEnv.VITE_FILE_ACCESS_KEY_ID || '')
|
||||
|| !/^[A-Za-z0-9+/]+={0,2}$/.test(fileEnv.VITE_FILE_ACCESS_KEY || '')
|
||||
|| Buffer.from(fileEnv.VITE_FILE_ACCESS_KEY || '', 'base64').length < 32) {
|
||||
throw new Error('请配置文件访问 appId、kid 和至少 32 字节的 Base64 密钥(.env.<mode>.local)')
|
||||
}
|
||||
|
||||
const { NODE_ENV, VITE_APP_DEV_SERVICE, VITE_APP_PROD_SERVICE, VITE_IMAGE_DEV_PATH } = loadEnv(mode, process.cwd(), "")
|
||||
const baseUrl = NODE_ENV == "development" ? VITE_APP_DEV_SERVICE : VITE_APP_PROD_SERVICE
|
||||
// 生产环境强制 HTTPS 检查
|
||||
|
||||
Reference in new issue
Block a user