feat: 报告中增过程中媒体区块,单按钮上传照片/视频;基础信息折叠优化
This commit is contained in:
parent
d6b4419225
commit
1e10ebc759
@ -341,13 +341,6 @@ const loadReport = async () => {
|
|||||||
else notFound.value = true
|
else notFound.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const playVideo = (url) => {
|
|
||||||
if (!url) return
|
|
||||||
uni.navigateTo({
|
|
||||||
url: `/pages/video-player/videoPlayer?url=${encodeURIComponent(url)}`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const goHome = () => uni.reLaunch({ url: '/pages/home/Home' })
|
const goHome = () => uni.reLaunch({ url: '/pages/home/Home' })
|
||||||
|
|
||||||
const callStore = () => {
|
const callStore = () => {
|
||||||
@ -383,6 +376,13 @@ const previewPhotos = (group, index = 0) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const playVideo = (url) => {
|
||||||
|
if (!url) return
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/video-player/videoPlayer?url=${encodeURIComponent(url)}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onShareAppMessage(() => {
|
onShareAppMessage(() => {
|
||||||
const q = routeToken.value ? `token=${encodeURIComponent(routeToken.value)}` : ''
|
const q = routeToken.value ? `token=${encodeURIComponent(routeToken.value)}` : ''
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -9,9 +9,11 @@
|
|||||||
<view class="report-body">
|
<view class="report-body">
|
||||||
<!-- 基础信息 -->
|
<!-- 基础信息 -->
|
||||||
<view class="section">
|
<view class="section">
|
||||||
<view class="section-head">
|
<view class="section-head section-head--clickable" @click="basicInfoCollapsed = !basicInfoCollapsed">
|
||||||
<text class="section-label">基础信息</text>
|
<text class="section-label">基础信息</text>
|
||||||
|
<text class="section-toggle">{{ basicInfoCollapsed ? '展开' : '收起' }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
<view v-show="!basicInfoCollapsed">
|
||||||
<view class="form-row">
|
<view class="form-row">
|
||||||
<text class="form-label">宠物名字</text>
|
<text class="form-label">宠物名字</text>
|
||||||
<input v-model="report.petName" class="form-input" placeholder="请输入宠物名字" />
|
<input v-model="report.petName" class="form-input" placeholder="请输入宠物名字" />
|
||||||
@ -47,6 +49,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<!-- 服务照片 — 核心区域 -->
|
<!-- 服务照片 — 核心区域 -->
|
||||||
<view class="section">
|
<view class="section">
|
||||||
@ -66,7 +69,7 @@
|
|||||||
<image :src="item.url" class="thumb-img" mode="aspectFill" />
|
<image :src="item.url" class="thumb-img" mode="aspectFill" />
|
||||||
<view class="thumb-del" @click="removeMedia('beforeMedia', idx)">✕</view>
|
<view class="thumb-del" @click="removeMedia('beforeMedia', idx)">✕</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="report.beforeMedia.length < 4" class="photo-add" @click="uploadMedia('beforeMedia', 'photo')">
|
<view v-if="report.beforeMedia.length < 4" class="photo-add" @click="uploadPhoto('beforeMedia')">
|
||||||
<AppIcon name="camera" :size="20" color="#bbbbb5" />
|
<AppIcon name="camera" :size="20" color="#bbbbb5" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -84,7 +87,7 @@
|
|||||||
<image :src="item.url" class="thumb-img" mode="aspectFill" />
|
<image :src="item.url" class="thumb-img" mode="aspectFill" />
|
||||||
<view class="thumb-del" @click="removeMedia('afterMedia', idx)">✕</view>
|
<view class="thumb-del" @click="removeMedia('afterMedia', idx)">✕</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="report.afterMedia.length < 4" class="photo-add" @click="uploadMedia('afterMedia', 'photo')">
|
<view v-if="report.afterMedia.length < 4" class="photo-add" @click="uploadPhoto('afterMedia')">
|
||||||
<AppIcon name="camera" :size="20" color="#bbbbb5" />
|
<AppIcon name="camera" :size="20" color="#bbbbb5" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -99,14 +102,10 @@
|
|||||||
<text class="section-hint">照片或视频,记录服务细节</text>
|
<text class="section-hint">照片或视频,记录服务细节</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="during-actions">
|
<view class="during-add-row">
|
||||||
<view class="during-action-btn" @click="uploadMedia('duringMedia', 'photo')">
|
<view class="during-add-btn" @click="uploadDuring()">
|
||||||
<AppIcon name="camera" :size="18" color="#666660" />
|
<AppIcon name="camera" :size="18" color="#bbbbb5" />
|
||||||
<text>上传照片</text>
|
<text>添加照片或视频</text>
|
||||||
</view>
|
|
||||||
<view class="during-action-btn during-action-btn--video" @click="uploadMedia('duringMedia', 'video')">
|
|
||||||
<AppIcon name="video" :size="18" color="#666660" />
|
|
||||||
<text>拍摄视频</text>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@ -121,17 +120,12 @@
|
|||||||
:show-play-btn="false"
|
:show-play-btn="false"
|
||||||
objectFit="cover"
|
objectFit="cover"
|
||||||
/>
|
/>
|
||||||
<!-- 视频角标 -->
|
|
||||||
<view v-if="item.mediaType === 'video'" class="video-badge">
|
<view v-if="item.mediaType === 'video'" class="video-badge">
|
||||||
<text>视频</text>
|
<text>视频</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="thumb-del" @click="removeMedia('duringMedia', idx)">✕</view>
|
<view class="thumb-del" @click="removeMedia('duringMedia', idx)">✕</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="report.duringMedia.length === 0" class="during-empty">
|
|
||||||
<text>暂无过程中记录</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 备注 -->
|
<!-- 备注 -->
|
||||||
@ -139,10 +133,23 @@
|
|||||||
<view class="section-head">
|
<view class="section-head">
|
||||||
<text class="section-label">备注</text>
|
<text class="section-label">备注</text>
|
||||||
</view>
|
</view>
|
||||||
<textarea v-model="report.remark" class="form-textarea" placeholder="服务细节、注意事项(可选)" />
|
<textarea
|
||||||
|
v-model="report.remark"
|
||||||
|
class="form-textarea"
|
||||||
|
placeholder="服务细节、注意事项(可选)"
|
||||||
|
@focus="onRemarkFocus"
|
||||||
|
@blur="onRemarkBlur"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<button class="submit-btn" :disabled="submitting" @click="submitReport">
|
</view>
|
||||||
|
|
||||||
|
<view
|
||||||
|
class="submit-fixed"
|
||||||
|
:class="{ 'submit-fixed--scrolled': hasScrolled }"
|
||||||
|
:style="submitFixedStyle"
|
||||||
|
>
|
||||||
|
<button class="submit-btn submit-btn--fixed" :disabled="submitting" @click="submitReport">
|
||||||
{{ submitting ? '提交中…' : '生成报告' }}
|
{{ submitting ? '提交中…' : '生成报告' }}
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
@ -154,14 +161,13 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<TabBar current-page="report" @change="goPage" />
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||||||
|
import { onPageScroll } from '@dcloudio/uni-app'
|
||||||
import { createReport, getServiceTypeList, imgUrl, BASE_URL } from '../../api/index.js'
|
import { createReport, getServiceTypeList, imgUrl, BASE_URL } from '../../api/index.js'
|
||||||
import TabBar from '../../components/TabBar.vue'
|
|
||||||
import AppIcon from '../../components/AppIcon.vue'
|
import AppIcon from '../../components/AppIcon.vue'
|
||||||
import { getUserSession, getStoreSession } from '../../utils/session.js'
|
import { getUserSession, getStoreSession } from '../../utils/session.js'
|
||||||
import { useNavigator } from '../../composables/useNavigator.js'
|
import { useNavigator } from '../../composables/useNavigator.js'
|
||||||
@ -175,7 +181,7 @@ import {
|
|||||||
|
|
||||||
const userInfo = getUserSession()
|
const userInfo = getUserSession()
|
||||||
const storeInfo = getStoreSession()
|
const storeInfo = getStoreSession()
|
||||||
const { goPage, navigateTo } = useNavigator()
|
const { navigateTo } = useNavigator()
|
||||||
const navSafeStyle = (() => {
|
const navSafeStyle = (() => {
|
||||||
const statusBarHeight = uni.getSystemInfoSync?.().statusBarHeight || 20
|
const statusBarHeight = uni.getSystemInfoSync?.().statusBarHeight || 20
|
||||||
let navHeight = statusBarHeight + 44
|
let navHeight = statusBarHeight + 44
|
||||||
@ -201,6 +207,17 @@ const report = ref({
|
|||||||
const serviceTypes = ref([])
|
const serviceTypes = ref([])
|
||||||
const currentAppointmentId = ref(null)
|
const currentAppointmentId = ref(null)
|
||||||
const submitting = ref(false)
|
const submitting = ref(false)
|
||||||
|
const basicInfoCollapsed = ref(false)
|
||||||
|
const hasScrolled = ref(false)
|
||||||
|
const keyboardHeight = ref(0)
|
||||||
|
const remarkFocused = ref(false)
|
||||||
|
const autoCollapsedByKeyboard = ref(false)
|
||||||
|
let keyboardChangeHandler = null
|
||||||
|
|
||||||
|
const submitFixedStyle = computed(() => {
|
||||||
|
const bottom = keyboardHeight.value > 0 ? `${keyboardHeight.value}px` : '0px'
|
||||||
|
return `bottom:${bottom};`
|
||||||
|
})
|
||||||
|
|
||||||
const serviceColumns = computed(() =>
|
const serviceColumns = computed(() =>
|
||||||
serviceTypes.value.map(s => ({ label: s.name, value: s.name }))
|
serviceTypes.value.map(s => ({ label: s.name, value: s.name }))
|
||||||
@ -213,67 +230,15 @@ const loadServiceTypes = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传媒体文件
|
* 上传照片(用于服务前/后)
|
||||||
* @param {string} field - beforeMedia | afterMedia | duringMedia
|
|
||||||
* @param {string} mediaType - photo | video
|
|
||||||
*/
|
*/
|
||||||
const uploadMedia = (field, mediaType) => {
|
const uploadPhoto = (field) => {
|
||||||
const maxTotal = 12 // 全局最多12条
|
const fieldMax = 4
|
||||||
|
const maxTotal = 12
|
||||||
if (report.value[field].length >= maxTotal) {
|
if (report.value[field].length >= maxTotal) {
|
||||||
return uni.showToast({ title: `最多上传${maxTotal}个`, icon: 'none' })
|
return uni.showToast({ title: `最多上传${maxTotal}个`, icon: 'none' })
|
||||||
}
|
}
|
||||||
const remain = maxTotal - report.value[field].length
|
const count = Math.min(fieldMax - report.value[field].length, maxTotal - report.value[field].length, 4)
|
||||||
|
|
||||||
if (mediaType === 'video') {
|
|
||||||
// 拍摄/选择视频
|
|
||||||
uni.chooseMedia({
|
|
||||||
count: Math.min(remain, 4),
|
|
||||||
mediaType: ['video'],
|
|
||||||
success: (res) => {
|
|
||||||
const tempFiles = res.tempFiles
|
|
||||||
uni.showLoading({ title: '上传中...' })
|
|
||||||
let failCount = 0
|
|
||||||
const tasks = tempFiles.map(f => {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const sizeMB = (f.size || 0) / 1024 / 1024
|
|
||||||
if (sizeMB > 100) {
|
|
||||||
failCount++
|
|
||||||
uni.showToast({ title: '视频不能超过100MB', icon: 'none' })
|
|
||||||
resolve()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
uni.uploadFile({
|
|
||||||
url: `${BASE_URL}/upload/image`,
|
|
||||||
filePath: f.tempFilePath,
|
|
||||||
name: 'file',
|
|
||||||
success: (uploadRes) => {
|
|
||||||
try {
|
|
||||||
const data = JSON.parse(uploadRes.data)
|
|
||||||
if (data.code === 200) {
|
|
||||||
report.value[field].push({ url: imgUrl(data.data.url), mediaType: 'video' })
|
|
||||||
} else {
|
|
||||||
failCount++
|
|
||||||
}
|
|
||||||
} catch (e) { failCount++ }
|
|
||||||
resolve()
|
|
||||||
},
|
|
||||||
fail: () => { failCount++; resolve() }
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
Promise.all(tasks).then(() => {
|
|
||||||
uni.hideLoading()
|
|
||||||
if (failCount > 0) uni.showToast({ title: `${failCount}个上传失败`, icon: 'none' })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// 上传照片
|
|
||||||
const fieldMax = 4
|
|
||||||
if (report.value[field].length >= fieldMax) {
|
|
||||||
return uni.showToast({ title: '最多上传4张', icon: 'none' })
|
|
||||||
}
|
|
||||||
const count = Math.min(fieldMax - report.value[field].length, remain, 4)
|
|
||||||
uni.chooseImage({
|
uni.chooseImage({
|
||||||
count,
|
count,
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
@ -306,6 +271,74 @@ const uploadMedia = (field, mediaType) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传视频(用于过程中)
|
||||||
|
*/
|
||||||
|
const uploadVideo = (field) => {
|
||||||
|
const maxTotal = 12
|
||||||
|
if (report.value[field].length >= maxTotal) {
|
||||||
|
return uni.showToast({ title: `最多上传${maxTotal}个`, icon: 'none' })
|
||||||
|
}
|
||||||
|
uni.chooseMedia({
|
||||||
|
count: 1,
|
||||||
|
mediaType: ['video'],
|
||||||
|
success: (res) => {
|
||||||
|
const tempFiles = res.tempFiles
|
||||||
|
uni.showLoading({ title: '上传中...' })
|
||||||
|
let failCount = 0
|
||||||
|
const tasks = tempFiles.map(f => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const sizeMB = (f.size || 0) / 1024 / 1024
|
||||||
|
if (sizeMB > 100) {
|
||||||
|
failCount++
|
||||||
|
uni.showToast({ title: '视频不能超过100MB', icon: 'none' })
|
||||||
|
resolve()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uni.uploadFile({
|
||||||
|
url: `${BASE_URL}/upload/image`,
|
||||||
|
filePath: f.tempFilePath,
|
||||||
|
name: 'file',
|
||||||
|
success: (uploadRes) => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(uploadRes.data)
|
||||||
|
if (data.code === 200) {
|
||||||
|
report.value[field].push({ url: imgUrl(data.data.url), mediaType: 'video' })
|
||||||
|
} else { failCount++ }
|
||||||
|
} catch (e) { failCount++ }
|
||||||
|
resolve()
|
||||||
|
},
|
||||||
|
fail: () => { failCount++; resolve() }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Promise.all(tasks).then(() => {
|
||||||
|
uni.hideLoading()
|
||||||
|
if (failCount > 0) uni.showToast({ title: `${failCount}个上传失败`, icon: 'none' })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传过程中媒体(照片或视频,弹窗选择)
|
||||||
|
*/
|
||||||
|
const uploadDuring = () => {
|
||||||
|
const maxTotal = 12
|
||||||
|
if (report.value.duringMedia.length >= maxTotal) {
|
||||||
|
return uni.showToast({ title: `最多上传${maxTotal}个`, icon: 'none' })
|
||||||
|
}
|
||||||
|
uni.showActionSheet({
|
||||||
|
itemList: ['照片', '视频'],
|
||||||
|
success: (res) => {
|
||||||
|
if (res.tapIndex === 0) {
|
||||||
|
uploadPhoto('duringMedia')
|
||||||
|
} else {
|
||||||
|
uploadVideo('duringMedia')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeMedia = (field, idx) => { report.value[field].splice(idx, 1) }
|
const removeMedia = (field, idx) => { report.value[field].splice(idx, 1) }
|
||||||
@ -381,6 +414,7 @@ const submitReport = async () => {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
report.value = { petName: '', serviceType: '', appointmentTime: '', beforeMedia: [], afterMedia: [], duringMedia: [], remark: '' }
|
report.value = { petName: '', serviceType: '', appointmentTime: '', beforeMedia: [], afterMedia: [], duringMedia: [], remark: '' }
|
||||||
currentAppointmentId.value = null
|
currentAppointmentId.value = null
|
||||||
|
basicInfoCollapsed.value = false
|
||||||
uni.navigateTo({ url: `/pages/report-view/reportView?token=${token}` })
|
uni.navigateTo({ url: `/pages/report-view/reportView?token=${token}` })
|
||||||
}, 800)
|
}, 800)
|
||||||
} else {
|
} else {
|
||||||
@ -398,6 +432,25 @@ const goBack = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
if (typeof uni.onKeyboardHeightChange === 'function') {
|
||||||
|
keyboardChangeHandler = (res) => {
|
||||||
|
const h = Math.max(0, Number(res?.height || 0))
|
||||||
|
keyboardHeight.value = h
|
||||||
|
|
||||||
|
// 仅在备注输入态自动折叠基础信息,减少输入时视觉干扰。
|
||||||
|
if (h > 0 && remarkFocused.value && !basicInfoCollapsed.value) {
|
||||||
|
basicInfoCollapsed.value = true
|
||||||
|
autoCollapsedByKeyboard.value = true
|
||||||
|
}
|
||||||
|
// 仅恢复由本逻辑触发的折叠,避免覆盖用户手动操作。
|
||||||
|
if (h === 0 && autoCollapsedByKeyboard.value) {
|
||||||
|
basicInfoCollapsed.value = false
|
||||||
|
autoCollapsedByKeyboard.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uni.onKeyboardHeightChange(keyboardChangeHandler)
|
||||||
|
}
|
||||||
|
|
||||||
await loadServiceTypes()
|
await loadServiceTypes()
|
||||||
const prefill = JSON.parse(uni.getStorageSync('petstore_report_prefill') || 'null')
|
const prefill = JSON.parse(uni.getStorageSync('petstore_report_prefill') || 'null')
|
||||||
if (prefill) {
|
if (prefill) {
|
||||||
@ -412,14 +465,34 @@ onMounted(async () => {
|
|||||||
report.value.appointmentTime = `${d}T${normalizeToHalfHour(hm)}`
|
report.value.appointmentTime = `${d}T${normalizeToHalfHour(hm)}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 预约数据带入,默认折叠基础信息
|
||||||
|
basicInfoCollapsed.value = true
|
||||||
uni.removeStorageSync('petstore_report_prefill')
|
uni.removeStorageSync('petstore_report_prefill')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (typeof uni.offKeyboardHeightChange === 'function' && keyboardChangeHandler) {
|
||||||
|
uni.offKeyboardHeightChange(keyboardChangeHandler)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onPageScroll((e) => {
|
||||||
|
hasScrolled.value = (e?.scrollTop || 0) > 8
|
||||||
|
})
|
||||||
|
|
||||||
|
const onRemarkFocus = () => {
|
||||||
|
remarkFocused.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const onRemarkBlur = () => {
|
||||||
|
remarkFocused.value = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.report-page {
|
.report-page {
|
||||||
padding-bottom: calc(76px + env(safe-area-inset-bottom));
|
padding-bottom: calc(96px + env(safe-area-inset-bottom));
|
||||||
background: #fafaf8;
|
background: #fafaf8;
|
||||||
}
|
}
|
||||||
.report-nav {
|
.report-nav {
|
||||||
@ -433,7 +506,7 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.report-body {
|
.report-body {
|
||||||
padding: 12px 16px 32px;
|
padding: 12px 16px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 区块 */
|
/* 区块 */
|
||||||
@ -446,6 +519,16 @@ onMounted(async () => {
|
|||||||
.section-head {
|
.section-head {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
|
.section-head--clickable {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.section-toggle {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #2db96d;
|
||||||
|
}
|
||||||
.section-label {
|
.section-label {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@ -573,35 +656,24 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 过程中区块 */
|
/* 过程中区块 */
|
||||||
.during-actions {
|
.during-add-row {
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
}
|
}
|
||||||
.during-action-btn {
|
.during-add-btn {
|
||||||
flex: 1;
|
height: 44px;
|
||||||
height: 42px;
|
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
border: 1.5px solid #ebebea;
|
border: 1.5px dashed #ddddd8;
|
||||||
background: #fafaf8;
|
background: #fafaf8;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 600;
|
color: #999993;
|
||||||
color: #666660;
|
|
||||||
}
|
}
|
||||||
.during-action-btn:active {
|
.during-add-btn:active {
|
||||||
background: #f0f0ee;
|
background: #f0f0ee;
|
||||||
}
|
}
|
||||||
.during-action-btn--video {
|
|
||||||
border-color: #e0d8f5;
|
|
||||||
background: #f8f5ff;
|
|
||||||
}
|
|
||||||
.during-action-btn--video:active {
|
|
||||||
background: #f0ecff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.during-grid {
|
.during-grid {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -628,13 +700,6 @@ onMounted(async () => {
|
|||||||
letter-spacing: 0.3px;
|
letter-spacing: 0.3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.during-empty {
|
|
||||||
padding: 16px 0 4px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #bbbbb5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 备注 */
|
/* 备注 */
|
||||||
.form-textarea {
|
.form-textarea {
|
||||||
background: #f5f5f2;
|
background: #f5f5f2;
|
||||||
@ -663,10 +728,28 @@ onMounted(async () => {
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
border: none;
|
border: none;
|
||||||
margin-top: 8px;
|
margin-top: 0;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
transition: opacity 0.15s;
|
transition: opacity 0.15s;
|
||||||
}
|
}
|
||||||
|
.submit-fixed {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
|
||||||
|
background: rgba(250, 250, 248, 0.96);
|
||||||
|
border-top: 1px solid #efefeb;
|
||||||
|
backdrop-filter: blur(2px);
|
||||||
|
z-index: 50;
|
||||||
|
transition: box-shadow 0.2s ease, background 0.2s ease, bottom 0.2s ease;
|
||||||
|
}
|
||||||
|
.submit-fixed--scrolled {
|
||||||
|
box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.08);
|
||||||
|
background: rgba(250, 250, 248, 0.985);
|
||||||
|
}
|
||||||
|
.submit-btn--fixed {
|
||||||
|
box-shadow: 0 5px 16px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
.submit-btn:active { opacity: 0.85; }
|
.submit-btn:active { opacity: 0.85; }
|
||||||
.submit-btn[disabled] { background: #ddddd8; color: #999993; }
|
.submit-btn[disabled] { background: #ddddd8; color: #999993; }
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user