| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- <template>
- <view class="record-card">
- <view class="title">
- <view class="line"></view>
- <text>任务跟踪记录</text>
- </view>
- <view v-for="(item, idx) in records" :key="idx" class="record-item">
- <view class="item-header">
- <text class="user">{{ item.createUserName || '-' }}</text>
- <text class="time">{{ item.createTime || '-' }}</text>
- </view>
- <view class="item-body">
- <text class="content">{{ item.remark || '-' }} {{ item.newContent || '-' }}</text>
- </view>
- <view v-if="getImgs(item).length" class="item-images">
- <u-image
- v-for="(img, i) in getImgs(item)"
- :key="i"
- :src="img"
- width="160rpx"
- height="160rpx"
- radius="8"
- mode="aspectFill"
- @click="preview(getImgs(item), i)"
- ></u-image>
- </view>
- </view>
- </view>
- </template>
- <script setup>
- const props = defineProps({
- records: {
- type: Array,
- default: () => []
- }
- })
- const isImageUrl = (v) => {
- if (!v || typeof v !== 'string') return false
- const s = v.trim()
- if (!s) return false
- if (/^https?:\/\//i.test(s) || s.startsWith('/') || s.startsWith('data:image')) return true
- return /\.(png|jpe?g|gif|webp|bmp)(\?.*)?$/i.test(s)
- }
- const normalizeImgs = (arr) => {
- if (!arr) return []
- if (typeof arr === 'string') {
- return arr.split(',').map(s => s.trim()).filter(isImageUrl)
- }
- if (Array.isArray(arr)) {
- return arr.map(v => typeof v === 'string' ? v : (v?.url || v?.imgUrl || '')).filter(isImageUrl)
- }
- if (typeof arr === 'object') {
- if (Array.isArray(arr.imgUrlList)) return normalizeImgs(arr.imgUrlList)
- if (arr.url) return isImageUrl(arr.url) ? [arr.url] : []
- }
- return []
- }
- const getImgs = (item) => {
- const candidates = [
- item?.imgInfo,
- item?.images,
- item?.files,
- item?.fileList,
- item?.pictures,
- item?.imgUrlList,
- item?.imgUrls,
- ]
- for (const c of candidates) {
- const imgs = normalizeImgs(c)
- if (imgs.length) return imgs
- }
- // newContent 可能是纯文本,只有确认是图片 URL 才展示
- return normalizeImgs(item?.newContent)
- }
- const preview = (urls, index) => {
- uni.previewImage({ urls, current: index })
- }
- </script>
- <style lang="scss" scoped>
- .record-card {
- background: #ffffff;
- border-radius: 12rpx;
- padding: 20rpx;
- }
- .title {
- display: flex;
- align-items: center;
- gap: 12rpx;
- margin-bottom: 16rpx;
- }
- .line {
- width: 8rpx;
- height: 32rpx;
- background: #22ac38;
- border-radius: 4rpx;
- }
- .record-item {
- padding: 20rpx 0;
- border-top: 1rpx solid #f0f0f0;
- }
- .item-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 8rpx;
- }
- .user {
- font-size: 28rpx;
- color: #666666;
- }
- .time {
- font-size: 26rpx;
- color: #969696;
- }
- .item-body {
- margin-top: 6rpx;
- }
- .content {
- font-size: 28rpx;
- color: #333333;
- }
- .item-images {
- margin-top: 12rpx;
- display: flex;
- flex-wrap: wrap;
- gap: 12rpx;
- }
- </style>
|