| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612 |
- <template>
- <view class="detail-container">
- <!-- 加载动画 -->
- <view class="loading-container" v-if="pageLoading">
- <!-- 顶部骨架 -->
- <view class="skeleton-header">
- <view class="skeleton-line skeleton-ani" style="width: 30%; height: 36rpx;"></view>
- <view class="skeleton-line skeleton-ani" style="width: 20%; height: 36rpx;"></view>
- </view>
- <view class="skeleton-progress">
- <view class="skeleton-circle skeleton-ani" v-for="i in 4" :key="i"></view>
- </view>
- <!-- 卡片骨架 -->
- <view class="skeleton-card" v-for="j in 3" :key="'c' + j">
- <view class="skeleton-line skeleton-ani" style="width: 60%; height: 28rpx; margin-bottom: 20rpx;">
- </view>
- <view class="skeleton-line skeleton-ani" style="width: 90%; height: 24rpx; margin-bottom: 14rpx;">
- </view>
- <view class="skeleton-line skeleton-ani" style="width: 75%; height: 24rpx;"></view>
- </view>
- </view>
- <template v-else>
- <!-- 顶部动态状态区 -->
- <view class="detail-header">
- <view class="status-row">
- <text class="status-title">{{ displayStatusText }}</text>
- <text class="status-price">¥{{ orderDetail.fulfillmentCommission }}</text>
- </view>
- <!-- 进度条区域 -->
- <view class="progress-bar">
- <view class="step-item" v-for="(step, index) in progressSteps" :key="index"
- :class="{ 'active': index === progressIndex, 'done': index < progressIndex }">
- <view class="step-circle-wrapper">
- <!-- Connecting Line before circle, except first item -->
- <view class="step-line" v-if="index !== 0"
- :class="{ 'active-line': index <= progressIndex }">
- </view>
- <view class="step-circle">{{ index + 1 }}</view>
- </view>
- <text class="step-text">{{ step }}</text>
- </view>
- </view>
- </view>
- <!-- 内容区域 -->
- <scroll-view scroll-y class="detail-content">
- <!-- 宠物信息 -->
- <view class="white-card pet-bar">
- <image class="pb-avatar" :src="orderDetail.petAvatar" mode="aspectFill"></image>
- <view class="pb-info">
- <view class="pb-name-row">
- <text class="pb-name">{{ orderDetail.petName }}</text>
- </view>
- <view class="pb-tags">
- <text class="pb-tag">{{ orderDetail.serviceName }}</text>
- </view>
- </view>
- <view class="pb-actions">
- <view class="pb-btn profile-btn" @click="showPetProfile">宠物档案</view>
- <view class="pb-btn phone-btn" @click="callPhone">
- <image class="phone-icon" src="/static/icons/phone_orange.svg"></image>
- </view>
- </view>
- </view>
- <!-- 路线及服务信息 -->
- <view class="white-card service-info-card">
- <view class="si-row time-row">
- <image class="si-icon outline" src="/static/icons/clock.svg"></image>
- <view class="si-content">
- <text class="si-label">服务时间</text>
- <text class="si-val">{{ orderDetail.time }}</text>
- </view>
- <view class="si-action record-btn" @tap.stop="openAnomalyModal">
- <text>异常记录</text>
- <image class="record-arrow" src="/static/icons/right_arrow_orange.svg"></image>
- </view>
- </view>
- <!-- 接送类型的地址展现 -->
- <template v-if="orderDetail.type === 1">
- <view class="si-row addr-row start-addr">
- <view class="icon-circle start">起</view>
- <view class="route-line-vertical"></view>
- <view class="si-content">
- <text class="si-addr-title">{{ orderDetail.startLocation }}</text>
- <text class="si-addr-desc">{{ orderDetail.startAddress }}</text>
- </view>
- <view class="nav-btn-circle" @click="openNavigation('start')">
- <image class="nav-arrow" src="/static/icons/nav_arrow.svg"></image>
- </view>
- </view>
- <view class="si-row addr-row end-addr">
- <view class="icon-circle end">终</view>
- <view class="si-content">
- <text class="si-addr-title">{{ orderDetail.endLocation }}</text>
- <text class="si-addr-desc">{{ orderDetail.endAddress }}</text>
- </view>
- <view class="nav-btn-circle" @click="openNavigation('end')">
- <image class="nav-arrow" src="/static/icons/nav_arrow.svg"></image>
- </view>
- </view>
- </template>
- <!-- 喂遛/洗护类型的地址展现 -->
- <template v-else>
- <view class="si-row addr-row end-addr">
- <view class="icon-circle service">服</view>
- <view class="si-content">
- <text class="si-addr-title">{{ orderDetail.endLocation }}</text>
- <text class="si-addr-desc">{{ orderDetail.endAddress }}</text>
- </view>
- <view class="nav-btn-circle" @click="openNavigation('end')">
- <image class="nav-arrow" src="/static/icons/nav_arrow.svg"></image>
- </view>
- </view>
- </template>
- <view class="si-row">
- <image class="si-icon outline custom-icon-file" src="/static/icons/file.svg"></image>
- <view class="si-content">
- <text class="si-label">备注</text>
- <text class="si-val">{{ orderDetail.remark || '无' }}</text>
- </view>
- </view>
- <!-- <view class="si-row record-history-row" @tap.stop="openAnomalyModal">
- <view class="si-content">
- <text class="si-label">异常记录</text>
- <text class="si-val">查看历史异常记录</text>
- </view>
- <image class="record-arrow" src="/static/icons/right_arrow_orange.svg"></image>
- </view> -->
- </view>
- <!-- 打卡任务 -->
- <view class="white-card task-card" v-if="currentStep < steps.length">
- <text class="tc-title">当前任务:{{ currentTaskTitle }}</text>
- <text class="tc-desc">{{ currentTaskDesc }}</text>
- <!-- 单个巨大点击区触发弹窗 -->
- <view class="full-media-add" @click="openUploadModal">
- <image class="upload-icon-large" src="/static/icons/camera_grey.svg"></image>
- <text class="upload-text-large">上传图或视频</text>
- </view>
- </view>
- <!-- 订单属性 -->
- <view class="white-card base-info-card">
- <view class="bi-row">
- <image class="si-icon outline" src="/static/icons/order_no.svg"></image>
- <view class="bi-content">
- <text class="bi-label">订单编号</text>
- <view class="bi-val-row">
- <text class="bi-val">{{ orderDetail.orderNo }}</text>
- <text class="bi-copy" @click="copyOrderNo">复制</text>
- </view>
- </view>
- </view>
- <view class="bi-row">
- <image class="si-icon outline" src="/static/icons/clock.svg"></image>
- <view class="bi-content">
- <text class="bi-label">下单时间</text>
- <text class="bi-val">{{ orderDetail.createTime }}</text>
- </view>
- </view>
- </view>
- <!-- 订单进度 -->
- <view class="white-card timeline-card">
- <view class="tl-title-row">
- <view class="orange-bar"></view>
- <text class="tl-title">订单进度</text>
- </view>
- <view class="tl-list">
- <view class="tl-item" v-for="(log, idx) in orderDetail.progressLogs" :key="idx">
- <view class="tl-marker active">
- <view class="tl-dot-inner"></view>
- </view>
- <view class="tl-content-row">
- <view class="tl-header">
- <text class="tl-status">{{ log.status }}</text>
- <text class="tl-time">{{ log.time }}</text>
- </view>
- <!-- 媒体(图片/视频)展示 -->
- <view class="tl-medias" v-if="log.medias && log.medias.length > 0">
- <view class="tl-media-item" v-for="(media, midx) in log.medias" :key="midx"
- @click="previewMedia(log.medias, midx)">
- <image v-if="!isVideo(media)" class="tl-img" :src="media" mode="aspectFill">
- </image>
- <view v-else class="tl-video-placeholder">
- <view class="tl-play-icon">
- </view>
- <text class="tl-video-label">视频</text>
- </view>
- </view>
- </view>
- <!-- 备注展示 -->
- <view class="tl-remark" v-if="log.remark">
- <text>{{ log.remark }}</text>
- </view>
- </view>
- </view>
- </view>
- </view>
- <view style="height: 140rpx;"></view>
- </scroll-view>
- <!-- 底部操作栏 -->
- <view class="bottom-action-bar">
- <view class="action-left">
- <button class="action-btn outline grey-outline" @click="goToAnomaly">异常上报</button>
- <button class="action-btn outline orange-outline" @click="openSumModal"
- v-if="serviceMode === 0">宠护小结</button>
- </view>
- <view class="action-right">
- <button class="action-btn primary" @click="openUploadModal" v-if="currentStep < steps.length">{{
- currentTaskTitle }}</button>
- <button class="action-btn primary grey-bg" v-else>已完成</button>
- </view>
- </view>
- <!-- 宠物档案弹窗 -->
- <view class="pet-modal-mask" v-if="showPetModal" @click="closePetProfile">
- <view class="pet-modal-content" @click.stop>
- <!-- 头部 -->
- <view class="pet-modal-header">
- <text class="pet-modal-title">宠物档案</text>
- <view style="flex:1"></view>
- <view class="pm-remark-btn" @click="openPetRemarkInput">备注</view>
- <view class="close-icon-btn" @click="closePetProfile">×</view>
- </view>
- <scroll-view scroll-y class="pet-modal-scroll">
- <!-- 宠物基础信息 -->
- <view class="pet-base-info">
- <image class="pm-avatar" :src="currentPetInfo.petAvatar" mode="aspectFill"></image>
- <view class="pm-info-text">
- <view class="pm-name-row">
- <text class="pm-name">{{ currentPetInfo.petName }}</text>
- <view class="pm-gender" v-if="currentPetInfo.petGender === 'M'">
- <text class="gender-icon">♂</text>
- <text>公</text>
- </view>
- <view class="pm-gender female" v-else-if="currentPetInfo.petGender === 'F'">
- <text class="gender-icon">♀</text>
- <text>母</text>
- </view>
- </view>
- <text class="pm-breed">品种:{{ currentPetInfo.petBreed }}</text>
- </view>
- </view>
- <!-- 属性网格 -->
- <view class="pm-detail-grid">
- <view class="pm-grid-item half">
- <text class="pm-label">年龄</text>
- <text class="pm-val">{{ currentPetInfo.petAge || '未知' }}</text>
- </view>
- <view class="pm-grid-item half">
- <text class="pm-label">体重</text>
- <text class="pm-val">{{ currentPetInfo.petWeight || '未知' }}</text>
- </view>
- <view class="pm-grid-item full">
- <text class="pm-label">性格</text>
- <text class="pm-val">{{ currentPetInfo.petPersonality || '无' }}</text>
- </view>
- <view class="pm-grid-item full">
- <text class="pm-label">爱好</text>
- <text class="pm-val">{{ currentPetInfo.petHobby || '无' }}</text>
- </view>
- <view class="pm-grid-item full">
- <text class="pm-label">备注</text>
- <text class="pm-val">{{ currentPetInfo.petRemark || '无特殊过敏史' }}</text>
- </view>
- </view>
- <!-- 标签 -->
- <view class="pm-tags-row" v-if="currentPetInfo.petTags && currentPetInfo.petTags.length > 0">
- <view class="pm-tag-chip" v-for="(tag, ti) in currentPetInfo.petTags" :key="ti">
- <text class="pm-tag-chip-text">{{ tag }}</text>
- </view>
- </view>
- <!-- 备注日志 -->
- <view class="pm-log-section">
- <view class="pm-log-header">
- <view
- style="width:6rpx; height:28rpx; background:#FF9800; border-radius:3rpx; margin-right:12rpx;">
- </view>
- <text class="pm-log-section-title">备注日志</text>
- </view>
- <view class="pm-log-item" v-for="(log, lIndex) in currentPetInfo.petLogs" :key="lIndex">
- <text class="pm-log-date">{{ log.date }}</text>
- <text class="pm-log-text">{{ log.content }}</text>
- <text class="pm-log-recorder" v-if="log.recorder !== '系统记录'">记录人:{{ log.recorder
- }}</text>
- <text class="pm-log-recorder system" v-else>系统记录</text>
- </view>
- </view>
- <view style="height: 30rpx;"></view>
- </scroll-view>
- </view>
- </view>
- <!-- 宠物备注输入弹窗 -->
- <view class="upload-modal-mask" v-if="showPetRemarkInput" @click="closePetRemarkInput">
- <view class="upload-modal-content" @click.stop>
- <view class="um-header">
- <text class="um-title">添加备注</text>
- </view>
- <view class="um-body">
- <textarea class="um-textarea" v-model="petRemarkText" auto-height placeholder="请输入宠物备注内容..."
- placeholder-style="color:#ccc; font-size:26rpx;"></textarea>
- </view>
- <view class="um-footer">
- <button class="um-submit-btn active" @click="submitPetRemark">确认提交</button>
- </view>
- </view>
- </view>
- <!-- 选择地图导航弹窗 (复用) -->
- <view class="nav-modal-mask" v-if="showNavModal" @click="closeNavModal">
- <view class="nav-action-sheet" @click.stop>
- <view class="nav-sheet-title">选择地图进行导航</view>
- <view class="nav-sheet-item" @click="chooseMap('高德')">高德地图</view>
- <view class="nav-sheet-item" @click="chooseMap('腾讯')">腾讯地图</view>
- <view class="nav-sheet-item" @click="chooseMap('百度')">百度地图</view>
- <view class="nav-sheet-gap"></view>
- <view class="nav-sheet-item cancel" @click="closeNavModal">取消</view>
- </view>
- </view>
- <!-- 上传图视频弹窗 (新增) -->
- <view class="upload-modal-mask" v-if="showUploadModal" @click="closeUploadModal">
- <view class="upload-modal-content" @click.stop>
- <view class="um-header">
- <text class="um-title">上传图或视频 ({{ modalMediaList.length }}/5)</text>
- <text class="um-remark-hint">{{ currentTaskDesc }}</text>
- </view>
- <view class="um-body">
- <view class="um-grid">
- <view class="um-item" v-for="(img, idx) in modalMediaList" :key="idx">
- <image class="um-preview" :src="img.thumb || img.url || img.localPath || img"
- mode="aspectFill">
- </image>
- <view class="um-video-badge" v-if="img.mediaType === 'video'">
- <image class="play-icon-small" src="/static/icons/play_circle.svg"></image>
- </view>
- <view class="um-del" @click="removeModalMedia(idx)">×</view>
- </view>
- <view class="um-add" @click="chooseModalMedia" v-if="modalMediaList.length < 5">
- <image class="um-add-icon" src="/static/icons/camera_grey.svg"></image>
- <text class="um-add-text">拍摄/上传</text>
- </view>
- </view>
- <textarea class="um-textarea" v-model="modalRemark" placeholder="在此输入备注信息..."
- placeholder-style="color:#ccc; font-size:26rpx;"></textarea>
- </view>
- <view class="um-footer">
- <view class="um-submit-btn" :class="{ 'active': modalMediaList.length > 0 }"
- @click="handleConfirmUpload">
- 确认提交</view>
- </view>
- </view>
- </view>
- <!-- 宠护小结弹窗 -->
- <view class="sum-modal-mask" v-if="showSumModal" @click="closeSumModal">
- <view class="sum-modal-card" @click.stop>
- <scroll-view scroll-y class="sum-modal-scroll">
- <view class="sum-modal-inner">
- <text class="sum-modal-title">宠物护理工作小结</text>
- <view class="sum-meta-row">
- <text class="sum-meta-label">日期:</text>
- <text class="sum-meta-val">{{ sumDate }}</text>
- </view>
- <view class="sum-meta-row">
- <text class="sum-meta-label">客户住址:</text>
- <text class="sum-meta-val">{{ orderDetail.endAddress }}</text>
- </view>
- <view class="sum-meta-row">
- <text class="sum-meta-label">宠主姓名:</text>
- <text class="sum-meta-val">{{ orderDetail.ownerName || '未知' }}</text>
- </view>
- <view class="sum-section-title">宠物信息</view>
- <view class="sum-pet-card">
- <image class="sum-pet-avatar" :src="orderDetail.petAvatar" mode="aspectFill"></image>
- <view class="sum-pet-info">
- <view class="sum-pet-name-row">
- <text class="sum-pet-name">{{ orderDetail.petName || '未知' }}</text>
- <text class="sum-pet-breed">品种: {{ orderDetail.petBreed || '未知' }}</text>
- </view>
- <text class="sum-pet-remark">{{ orderDetail.petNotes || '暂无备注' }}</text>
- </view>
- </view>
- <view class="sum-section-title">服务内容记录</view>
- <textarea class="sum-textarea" v-model="sumContent" auto-height placeholder="请填写服务内容..."
- placeholder-style="color:#ccc"></textarea>
- <view class="sum-sign-row">
- <text class="sum-sign-label">护宠师签名:</text>
- <text class="sum-sign-val">{{ sumSigner }}</text>
- </view>
- <view style="height: 20rpx;"></view>
- </view>
- </scroll-view>
- <view class="sum-footer">
- <button class="sum-submit-btn" @click="submitSumModal">提交小结</button>
- </view>
- </view>
- </view>
- <!-- 异常记录弹窗 -->
- <view class="modal-mask" v-if="showAnomalyModal" @click="closeAnomalyModal">
- <view class="anomaly-modal-content" @click.stop>
- <view class="am-header">
- <text class="am-title">历史异常记录</text>
- <view class="close-icon-btn" @click="closeAnomalyModal">×</view>
- </view>
- <scroll-view scroll-y class="am-scroll-list">
- <view class="empty-list" v-if="anomalyList.length === 0">
- <image class="empty-icon" src="/static/empty-rest.png" mode="aspectFit"></image>
- <text class="empty-text">暂无异常记录</text>
- </view>
- <view class="am-item" v-for="(item, index) in anomalyList" :key="index">
- <view class="am-item-header">
- <text class="am-item-type">{{ item.typeLabel }}</text>
- <text class="am-item-status" :class="'status-' + item.status">{{
- getAnomalyStatusLabel(item.status)
- }}</text>
- </view>
- <text class="am-item-content">{{ item.content }}</text>
- <view class="am-item-photos" v-if="item.photos && item.photos.length > 0">
- <view class="am-photo-item" v-for="(photoUrl, pIdx) in item.photoUrls" :key="pIdx"
- @click="previewMedia(item.photoUrls, pIdx)">
- <image v-if="!isVideo(photoUrl)" class="am-photo" :src="photoUrl" mode="aspectFill">
- </image>
- <view v-else class="tl-video-placeholder miniaturized">
- <view class="tl-play-icon small">
- </view>
- <text class="tl-video-label small">视频</text>
- </view>
- </view>
- </view>
- <view class="am-audit-box" v-if="item.status !== 0">
- <view class="am-audit-header">
- <text class="am-audit-label">{{ item.status === 1 ? '审核通过' : '驳回理由' }}</text>
- <text class="am-audit-time">{{ item.auditTime }}</text>
- </view>
- <text class="am-audit-remark">{{ item.auditRemark || '无' }}</text>
- </view>
- </view>
- </scroll-view>
- </view>
- </view>
- <!-- 视频播放弹窗 -->
- <view class="video-player-mask" v-if="videoPlayerShow" @click="closeVideoPlayer">
- <view class="video-player-content" @click.stop>
- <video class="v-player" :src="videoPlayerUrl" autoplay controls></video>
- <view class="v-close" @click="closeVideoPlayer">×</view>
- </view>
- </view>
- </template>
- </view>
- </template>
- <script>
- import { getOrderInfo, clockIn, submitNursingSummary } from '@/api/order/subOrder'
- import { getOrderLogs } from '@/api/order/subOrderLog'
- import { uploadFile } from '@/api/fulfiller/app'
- import { getAnomalyList } from '@/api/fulfiller/anamaly'
- import { listAllService } from '@/api/service/list'
- import { reportGps } from '@/utils/gps'
- import { getDictDataByType } from '@/api/system/dict'
- import { getPetDetail, submitPetRemark as apiSubmitPetRemark } from '@/api/archieves/pet'
- import { listChangeLog } from '@/api/archieves/changeLog'
- export default {
- data() {
- return {
- orderId: null,
- pageLoading: true,
- orderType: 1,
- orderStatus: 2,
- serviceId: null,
- serviceMode: null,
- petId: null,
- petDetail: null,
- clockInSteps: [],
- currentClockIn: null,
- currentStep: 0,
- orderDetail: {
- type: 1, fulfillmentCommission: '0.00', timeLabel: '服务时间', time: '',
- petAvatar: '/static/dog.png', petName: '', petBreed: '',
- serviceTag: '', startLocation: '', startAddress: '', endAddress: '',
- customerPhone: '', serviceContent: '', remark: '',
- orderNo: '', createTime: '', serviceName: '',
- progressLogs: [], nursingSummary: ''
- },
- serviceList: [],
- showPetModal: false,
- currentPetInfo: {},
- showNavModal: false,
- navTargetPointType: '',
- showUploadModal: false,
- modalMediaList: [],
- modalRemark: '',
- showSumModal: false,
- sumContent: '',
- sumDate: '',
- sumSigner: '未知',
- showPetRemarkInput: false,
- petRemarkText: '',
- showAnomalyModal: false,
- anomalyList: [],
- anomalyTypeDict: [],
- videoPlayerShow: false,
- videoPlayerUrl: ''
- }
- },
- computed: {
- steps() {
- if (this.clockInSteps.length > 0) return this.clockInSteps.map(s => s.title)
- return this.orderType === 1
- ? ['到达打卡', '确认出发', '送达打卡']
- : ['到达打卡', '开始服务', '服务结束']
- },
- progressSteps() { return ['已接单', ...this.steps, '订单完成'] },
- progressIndex() { return this.currentStep + 1 },
- displayStatusText() {
- if (this.currentStep >= this.steps.length) return '已完成';
- if (this.currentStep > 0) return this.orderType === 1 ? '配送中' : '服务中';
- return this.orderType === 1 ? '待接送' : '待服务';
- },
- currentStatusText() {
- return this.currentStep >= this.steps.length ? '已完成' : this.steps[this.currentStep];
- },
- currentTaskTitle() {
- if (this.currentStep >= this.steps.length) return '订单已完成';
- if (this.currentClockIn) return this.currentClockIn.title;
- return this.steps[this.currentStep] || '打卡';
- },
- currentTaskDesc() {
- if (this.currentStep >= this.steps.length) return '感谢您的服务,请注意休息';
- if (this.currentClockIn && this.currentClockIn.remark) return this.currentClockIn.remark;
- return '请按要求提交照片或视频及备注';
- }
- },
- async onLoad(options) {
- if (options.id) this.orderId = options.id
- this.pageLoading = true
- reportGps(true).catch(e => console.log('Init GPS check skipped', e));
- try {
- await this.loadAnomalyTypeDict()
- await this.loadServiceList()
- await this.loadOrderDetail()
- } finally {
- this.pageLoading = false
- }
- },
- methods: {
- async loadServiceList() {
- try {
- const res = await listAllService()
- this.serviceList = res.data || []
- } catch (err) { console.error('获取服务类型失败:', err) }
- },
- loadServiceDetail(serviceId) {
- const serviceInfo = (this.serviceList || []).find(s => s.id === serviceId)
- if (serviceInfo) {
- this.serviceMode = serviceInfo.mode
- this.orderDetail.serviceName = serviceInfo.name
- if (serviceInfo.clockInRemark) {
- try {
- const parsed = JSON.parse(serviceInfo.clockInRemark)
- if (Array.isArray(parsed) && parsed.length > 0) this.clockInSteps = parsed
- } catch (parseErr) { console.error('解析 clockInRemark 失败:', parseErr) }
- }
- }
- },
- async loadOrderDetail() {
- if (!this.orderId) { uni.showToast({ title: '订单ID缺失', icon: 'none' }); return }
- try {
- const res = await getOrderInfo(this.orderId)
- const order = res.data
- if (!order) { uni.showToast({ title: '订单不存在', icon: 'none' }); return }
- this.serviceId = order.service
- this.petId = order.usrPet || null
- this.transformOrderData(order)
- if (this.serviceId) this.loadServiceDetail(this.serviceId)
- if (this.petId) await this.loadPetDetail(this.petId)
- await this.loadOrderLogs()
- } catch (err) {
- console.error('获取订单详情失败:', err)
- uni.showToast({ title: '加载失败', icon: 'none' })
- }
- },
- async loadOrderLogs() {
- try {
- const res = await getOrderLogs(this.orderId)
- const logs = res.data || []
- const progressLogs = logs.filter(log => log.logType === 1)
- this.orderDetail.progressLogs = progressLogs.map(log => ({
- status: log.title || '', time: log.createTime || '',
- medias: log.photoUrls || [], remark: log.content || ''
- }))
- const validLogs = logs.filter(log => log.logType === 1 && log.step !== undefined && log.step !== null)
- .sort((a, b) => new Date(b.createTime).getTime() - new Date(a.createTime).getTime())
- if (validLogs.length > 0) {
- const latestStep = validLogs[0].step
- const stepIndex = this.clockInSteps.findIndex(s => s.step === latestStep)
- this.currentStep = stepIndex >= 0 ? stepIndex + 1 : Number(latestStep)
- } else { this.currentStep = 0 }
- this.updateCurrentClockIn()
- } catch (err) { console.error('获取订单日志失败:', err) }
- },
- updateCurrentClockIn() {
- this.currentClockIn = this.currentStep < this.clockInSteps.length ? this.clockInSteps[this.currentStep] : null
- },
- transformOrderData(order) {
- const mode = order.mode || 0
- const isRoundTrip = mode === 1
- this.orderType = isRoundTrip ? 1 : 2
- this.orderStatus = order.status || 2
- this.orderDetail = {
- type: this.orderType,
- fulfillmentCommission: (order.price / 100).toFixed(2),
- timeLabel: isRoundTrip ? '取货时间' : '服务时间',
- time: order.serviceTime || '',
- petAvatar: '/static/dog.png',
- petName: order.petName || order.contact || '',
- petBreed: order.breed || '',
- serviceTag: order.groupPurchasePackageName || '',
- startLocation: order.fromAddress || '暂无起点',
- startAddress: order.fromAddress || '',
- fromAddress: order.fromAddress || '',
- fromLat: order.fromLat, fromLng: order.fromLng,
- endLocation: (order.contact || '') + ' ' + (order.contactPhoneNumber || ''),
- endAddress: order.toAddress || '',
- toAddress: order.toAddress || '',
- toLat: order.toLat, toLng: order.toLng,
- customerPhone: order.contactPhoneNumber || '',
- ownerName: order.contact || '',
- serviceContent: '', remark: '',
- orderNo: order.code || 'T' + order.id,
- createTime: order.serviceTime || '',
- nursingSummary: order.nursingSummary || '',
- fulfillerName: order.fulfillerName || '',
- progressLogs: [{ status: '您已接单', time: order.serviceTime || '' }]
- }
- if (this.orderDetail.fulfillerName) this.sumSigner = this.orderDetail.fulfillerName
- },
- async loadPetDetail(petId) {
- try {
- const res = await getPetDetail(petId)
- const pet = res.data
- if (pet) {
- this.petDetail = pet
- this.orderDetail.petAvatar = pet.avatarUrl || '/static/dog.png'
- this.orderDetail.petName = pet.name || this.orderDetail.petName
- this.orderDetail.petBreed = pet.breed || this.orderDetail.petBreed
- this.orderDetail.ownerName = pet.ownerName || this.orderDetail.ownerName
- }
- } catch (err) { console.error('获取宠物档案失败:', err) }
- },
- async loadAnomalyList() {
- if (!this.orderId) return
- try {
- const res = await getAnomalyList(this.orderId)
- const list = res.data || []
- this.anomalyList = list.map(item => {
- const dict = this.anomalyTypeDict.find(d => d.value === item.type)
- return { ...item, typeLabel: dict ? dict.label : item.type, photoUrls: item.photoUrls || [] }
- })
- } catch (err) { console.error('获取异常列表失败:', err) }
- },
- async loadAnomalyTypeDict() {
- try {
- const res = await getDictDataByType('flf_anamaly_type')
- this.anomalyTypeDict = res.data.map(item => ({ label: item.dictLabel, value: item.dictValue }))
- } catch (err) { console.error('获取异常字典失败:', err) }
- },
- openAnomalyModal() { this.showAnomalyModal = true; this.loadAnomalyList() },
- closeAnomalyModal() { this.showAnomalyModal = false },
- getAnomalyStatusLabel(status) {
- return { 0: '待审核', 1: '已通过', 2: '已驳回' }[status] || '未知'
- },
- showPetProfile() {
- const pet = this.petDetail
- if (pet) {
- this.currentPetInfo = {
- petAvatar: pet.avatarUrl || '/static/dog.png',
- petName: pet.name || '', petBreed: pet.breed || '',
- petGender: pet.gender === 1 ? 'M' : (pet.gender === 2 ? 'F' : ''),
- petAge: pet.age ? pet.age + '岁' : '未知',
- petWeight: pet.weight ? pet.weight + 'kg' : '未知',
- petPersonality: pet.personality || pet.cutePersonality || '无',
- petHobby: '', petRemark: pet.remark || '无',
- petTags: (pet.tags || []).map(t => t.name), petLogs: [],
- petSize: pet.size || '', petIsSterilized: pet.isSterilized,
- petHealthStatus: pet.healthStatus || '', petAllergies: pet.allergies || '',
- petMedicalHistory: pet.medicalHistory || '', petVaccineStatus: pet.vaccineStatus || '',
- ownerName: pet.ownerName || '', ownerPhone: pet.ownerPhone || ''
- }
- this.loadPetChangeLogs(pet.id)
- } else {
- this.currentPetInfo = {
- ...this.orderDetail, petGender: '', petAge: '未知', petWeight: '未知',
- petPersonality: '无', petHobby: '', petRemark: '无', petTags: [], petLogs: []
- }
- }
- this.showPetModal = true
- },
- async loadPetChangeLogs(petId) {
- if (!petId) return
- try {
- const res = await listChangeLog({ targetId: petId, targetType: 'pet' })
- const logs = res.data || []
- this.currentPetInfo.petLogs = logs.map(item => ({
- date: item.createTime || '', content: item.content || '', recorder: item.operatorName || '未知'
- }))
- } catch (err) { console.error('获取宠物备注列表失败:', err) }
- },
- closePetProfile() { this.showPetModal = false },
- openPetRemarkInput() { this.petRemarkText = ''; this.showPetRemarkInput = true },
- closePetRemarkInput() { this.showPetRemarkInput = false },
- async submitPetRemark() {
- if (!this.petRemarkText.trim()) { uni.showToast({ title: '备注内容不能为空', icon: 'none' }); return }
- if (!this.petId) { uni.showToast({ title: '宠物信息缺失', icon: 'none' }); return }
- uni.showLoading({ title: '提交中...', mask: true });
- try {
- await apiSubmitPetRemark({ petId: this.petId, content: this.petRemarkText });
- uni.hideLoading(); uni.showToast({ title: '备注已添加', icon: 'success' });
- this.closePetRemarkInput(); this.loadPetChangeLogs(this.petId);
- } catch (err) { uni.hideLoading(); console.error('提交宠物备注失败:', err) }
- },
- goToAnomaly() {
- uni.navigateTo({ url: '/pages/orders/anomaly/index?orderId=' + (this.orderId || '') });
- },
- callPhone() {
- const phoneNum = this.orderDetail.customerPhone || '18900008451'
- if (!phoneNum) { uni.showToast({ title: '手机号不存在', icon: 'none' }); return }
- uni.showModal({
- title: '拨号提示',
- content: `系统将为您拨打手机号: ${phoneNum},请授予拨号权限以正常通话。`,
- confirmText: '呼叫', cancelText: '取消',
- success: (res) => {
- if (res.confirm) {
- uni.makePhoneCall({
- phoneNumber: phoneNum,
- fail: () => { uni.showToast({ title: '无法唤起拨号盘,请检查权限设置', icon: 'none' }) }
- });
- }
- }
- });
- },
- openNavigation(type) { this.navTargetPointType = type; this.showNavModal = true },
- closeNavModal() { this.showNavModal = false },
- chooseMap(mapType) {
- let pointType = this.navTargetPointType;
- let name = pointType === 'start' ? (this.orderDetail.fromAddress || '起点') : (this.orderDetail.toAddress || '终点');
- let address = pointType === 'start' ? (this.orderDetail.fromAddress || '起点地址') : (this.orderDetail.toAddress || '终点地址');
- let latitude = pointType === 'start' ? Number(this.orderDetail.fromLat) : Number(this.orderDetail.toLat);
- let longitude = pointType === 'start' ? Number(this.orderDetail.fromLng) : Number(this.orderDetail.toLng);
- this.showNavModal = false;
- const navigateTo = (lat, lng, addrName, addrDesc) => {
- uni.openLocation({
- latitude: lat, longitude: lng, name: addrName,
- address: addrDesc || '无法获取详细地址',
- success: () => { console.log('打开导航成功: ' + mapType) },
- fail: (err) => { console.error('打开导航失败:', err); uni.showToast({ title: '打开地图失败', icon: 'none' }) }
- });
- };
- if (latitude && longitude && !isNaN(latitude) && !isNaN(longitude)) {
- navigateTo(latitude, longitude, name, address);
- } else {
- uni.showLoading({ title: '获取当前位置...', mask: true });
- reportGps(true).then(res => {
- uni.hideLoading(); navigateTo(res.latitude, res.longitude, name, address);
- }).catch(err => { uni.hideLoading(); console.error('获取地理位置失败:', err) });
- }
- },
- openUploadModal() { this.modalMediaList = []; this.modalRemark = ''; this.showUploadModal = true },
- closeUploadModal() { this.showUploadModal = false },
- handleConfirmUpload() { this.confirmUploadModal() },
- async chooseModalMedia() {
- uni.chooseMedia({
- count: 5 - this.modalMediaList.length,
- mediaType: ['image', 'video'],
- sourceType: ['album', 'camera'],
- success: async (res) => {
- uni.showLoading({ title: '上传中...', mask: true });
- try {
- for (const file of res.tempFiles) {
- const uploadRes = await uploadFile(file.tempFilePath);
- if (uploadRes.code === 200) {
- this.modalMediaList.push({
- url: uploadRes.data.url, ossId: uploadRes.data.ossId,
- localPath: file.tempFilePath, mediaType: file.fileType,
- thumb: file.thumbTempFilePath
- });
- }
- }
- uni.hideLoading(); uni.showToast({ title: '上传成功', icon: 'success' });
- } catch (err) { uni.hideLoading(); uni.showToast({ title: '上传失败', icon: 'none' }) }
- },
- fail: (err) => { console.error('选择媒体文件失败:', err) }
- });
- },
- removeModalMedia(index) { this.modalMediaList.splice(index, 1) },
- async confirmUploadModal() {
- if (this.modalMediaList.length === 0) { uni.showToast({ title: '请上传至少一张图片或视频', icon: 'none' }); return }
- try {
- uni.showLoading({ title: '提交中...' });
- const ossIds = this.modalMediaList.map(item => item.ossId);
- const clockInType = this.currentClockIn ? this.currentClockIn.step : (this.currentStep + 1);
- const clockInData = {
- orderId: this.orderId, photos: ossIds,
- content: this.modalRemark || '', step: clockInType,
- title: this.currentTaskTitle,
- startFlag: Number(clockInType) === 1,
- endFlag: Number(this.currentStep) === this.steps.length - 1
- };
- await clockIn(clockInData);
- uni.hideLoading(); this.closeUploadModal();
- uni.showToast({ title: '打卡成功', icon: 'success' });
- await this.loadOrderDetail();
- } catch (err) {
- uni.hideLoading(); console.error('打卡失败:', err);
- uni.showToast({ title: '打卡失败,请重试', icon: 'none' });
- }
- },
- copyOrderNo() {
- uni.setClipboardData({ data: this.orderDetail.orderNo, success: () => { uni.showToast({ title: '复制成功', icon: 'none' }) } });
- },
- openSumModal() {
- let displayDate = '';
- if (this.orderDetail.time) {
- displayDate = this.orderDetail.time.split(' ')[0].replace(/-/g, '/');
- } else {
- const now = new Date();
- displayDate = `${now.getFullYear()}/${String(now.getMonth() + 1).padStart(2, '0')}/${String(now.getDate()).padStart(2, '0')}`;
- }
- this.sumDate = displayDate;
- if (this.orderDetail.nursingSummary) {
- this.sumContent = this.orderDetail.nursingSummary;
- } else if (!this.sumContent) {
- this.sumContent = '1. 精神/身体状态:\n2. 进食/饮水:\n3. 排泤情况:\n4. 卫生情况:\n5. 互动情况:\n6. 特殊情况/备注:';
- }
- this.showSumModal = true;
- },
- closeSumModal() { this.showSumModal = false },
- async submitSumModal() {
- if (!this.sumContent.trim()) { uni.showToast({ title: '请填写服务内容', icon: 'none' }); return }
- uni.showLoading({ title: '提交中...', mask: true });
- try {
- const res = await submitNursingSummary({ orderId: this.orderId, content: this.sumContent });
- uni.hideLoading();
- if (res.code === 200) {
- uni.showToast({ title: '小结已提交', icon: 'success' });
- this.closeSumModal(); await this.loadOrderDetail();
- } else { uni.showToast({ title: res.msg || '提交失败', icon: 'none' }) }
- } catch (err) {
- uni.hideLoading(); console.error('提交宠护小结失败:', err);
- uni.showToast({ title: '提交失败,请重试', icon: 'none' });
- }
- },
- isVideo(url) {
- if (!url) return false;
- const videoExts = ['.mp4', '.mov', '.m4v', '.3gp', '.avi', '.wmv'];
- return videoExts.some(ext => url.toLowerCase().includes(ext));
- },
- getVideoPoster(url) {
- if (!this.isVideo(url)) return url;
- if (url.includes('?x-oss-process') || url.includes('?ci-process') || url.includes('?vframe')) return url;
- if (url.includes('myqcloud.com')) return url + '?ci-process=snapshot&time=1';
- return url + '?x-oss-process=video/snapshot,t_1,f_jpg,w_300,m_fast';
- },
- previewMedia(medias, currentIdx) {
- const url = medias[currentIdx];
- if (this.isVideo(url)) {
- this.videoPlayerUrl = url; this.videoPlayerShow = true;
- } else {
- const imageUrls = medias.filter(m => !this.isVideo(m));
- const newIdx = imageUrls.indexOf(url);
- uni.previewImage({ current: newIdx >= 0 ? newIdx : 0, urls: imageUrls });
- }
- },
- closeVideoPlayer() { this.videoPlayerShow = false; this.videoPlayerUrl = '' }
- }
- }
- </script>
- <style>
- page {
- background-color: #F8F8F8;
- }
- .detail-container {
- padding-bottom: 200rpx;
- }
- .loading-container {
- padding: 30rpx;
- }
- .skeleton-header {
- background: linear-gradient(135deg, #FF9800 0%, #FF5722 100%);
- border-radius: 20rpx;
- padding: 40rpx;
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20rpx;
- }
- .skeleton-progress {
- background: linear-gradient(135deg, #FF9800 0%, #FF5722 100%);
- border-radius: 0 0 20rpx 20rpx;
- margin-top: -40rpx;
- padding: 30rpx 40rpx 40rpx;
- display: flex;
- justify-content: space-around;
- margin-bottom: 25rpx;
- }
- .skeleton-circle {
- width: 40rpx;
- height: 40rpx;
- border-radius: 50%;
- background-color: rgba(255, 255, 255, 0.3);
- }
- .skeleton-card {
- background-color: #fff;
- border-radius: 20rpx;
- padding: 30rpx;
- margin-bottom: 25rpx;
- box-shadow: 0 5rpx 20rpx rgba(0, 0, 0, 0.03);
- }
- .skeleton-line {
- border-radius: 8rpx;
- background-color: #f0f0f0;
- }
- .skeleton-ani {
- background: linear-gradient(90deg, #f0f0f0 25%, #e8e8e8 37%, #f0f0f0 63%);
- background-size: 400% 100%;
- animation: skeleton-loading 1.4s ease infinite;
- }
- .skeleton-header .skeleton-ani {
- background: linear-gradient(90deg, rgba(255, 255, 255, 0.2) 25%, rgba(255, 255, 255, 0.35) 37%, rgba(255, 255, 255, 0.2) 63%);
- background-size: 400% 100%;
- animation: skeleton-loading 1.4s ease infinite;
- }
- .skeleton-progress .skeleton-ani {
- background: linear-gradient(90deg, rgba(255, 255, 255, 0.2) 25%, rgba(255, 255, 255, 0.35) 37%, rgba(255, 255, 255, 0.2) 63%);
- background-size: 400% 100%;
- animation: skeleton-loading 1.4s ease infinite;
- }
- @keyframes skeleton-loading {
- 0% {
- background-position: 100% 50%;
- }
- 100% {
- background-position: 0 50%;
- }
- }
- .detail-header {
- background: linear-gradient(135deg, #FF9800 0%, #FF5722 100%);
- padding: 40rpx 40rpx 50rpx 40rpx;
- color: #fff;
- border-radius: 20rpx;
- margin: 30rpx 30rpx 25rpx 30rpx;
- box-shadow: 0 5rpx 15rpx rgba(255, 87, 34, 0.2);
- }
- .status-row {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 40rpx;
- }
- .status-title {
- font-size: 28rpx;
- font-weight: bold;
- }
- .status-fulfillmentCommission {
- font-size: 40rpx;
- font-weight: bold;
- }
- .progress-bar {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- padding: 0 10rpx;
- }
- .step-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- flex: 1;
- position: relative;
- opacity: 0.5;
- }
- .step-item.done {
- opacity: 1;
- }
- .step-item.done .step-circle {
- background-color: #fff;
- color: #FF5722;
- font-weight: bold;
- }
- .step-item.done .step-text {
- font-weight: 500;
- }
- .step-item.active {
- opacity: 1;
- }
- .step-item.active .step-circle {
- background-color: #fff;
- color: #FF5722;
- font-weight: bold;
- width: 48rpx;
- height: 48rpx;
- font-size: 24rpx;
- box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.15);
- }
- .step-item.active .step-text {
- font-weight: bold;
- }
- .step-circle-wrapper {
- position: relative;
- width: 100%;
- display: flex;
- justify-content: center;
- margin-bottom: 10rpx;
- }
- .step-circle {
- width: 40rpx;
- height: 40rpx;
- border-radius: 50%;
- background-color: rgba(255, 255, 255, 0.3);
- color: rgba(255, 255, 255, 0.8);
- font-size: 20rpx;
- display: flex;
- justify-content: center;
- align-items: center;
- position: relative;
- z-index: 2;
- transition: all 0.2s;
- }
- .step-line {
- position: absolute;
- top: 50%;
- right: calc(50% + 20rpx);
- width: calc(100% - 40rpx);
- height: 2rpx;
- background-color: rgba(255, 255, 255, 0.3);
- z-index: 1;
- transform: translateY(-50%);
- }
- .step-line.active-line {
- background-color: #fff;
- height: 3rpx;
- }
- .step-text {
- font-size: 24rpx;
- }
- .detail-content {
- width: 100%;
- box-sizing: border-box;
- padding: 0 30rpx;
- position: relative;
- z-index: 10;
- }
- .white-card {
- background-color: #fff;
- border-radius: 20rpx;
- padding: 30rpx;
- margin-bottom: 25rpx;
- box-shadow: 0 5rpx 20rpx rgba(0, 0, 0, 0.03);
- }
- .pet-bar {
- display: flex;
- align-items: center;
- }
- .pb-avatar {
- width: 100rpx;
- height: 100rpx;
- border-radius: 50%;
- margin-right: 20rpx;
- }
- .pb-info {
- flex: 1;
- display: flex;
- flex-direction: column;
- }
- .pb-name-row {
- margin-bottom: 10rpx;
- }
- .pb-name {
- font-size: 32rpx;
- font-weight: bold;
- color: #333;
- margin-right: 15rpx;
- }
- .pb-breed {
- font-size: 26rpx;
- color: #999;
- }
- .pb-tags {
- display: flex;
- }
- .pb-tag {
- background-color: #FFF3E0;
- color: #FF9800;
- font-size: 22rpx;
- padding: 4rpx 16rpx;
- border-radius: 8rpx;
- }
- .pb-actions {
- display: flex;
- align-items: center;
- }
- .pb-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .profile-btn {
- border: 2rpx solid #FF9800;
- color: #FF9800;
- font-size: 24rpx;
- padding: 8rpx 20rpx;
- border-radius: 30rpx;
- margin-right: 20rpx;
- }
- .phone-btn {
- width: 60rpx;
- height: 60rpx;
- border-radius: 50%;
- background-color: #FFF3E0;
- }
- .phone-icon {
- width: 32rpx;
- height: 32rpx;
- }
- .si-row {
- display: flex;
- align-items: flex-start;
- margin-bottom: 30rpx;
- }
- .si-row:last-child {
- margin-bottom: 0;
- }
- .si-icon {
- width: 36rpx;
- height: 36rpx;
- margin-right: 20rpx;
- margin-top: 4rpx;
- }
- .si-icon-uni {
- margin-right: 20rpx;
- margin-top: 4rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .si-content {
- flex: 1;
- display: flex;
- flex-direction: column;
- }
- .si-label {
- font-size: 24rpx;
- color: #999;
- margin-bottom: 6rpx;
- }
- .icon-bg {
- width: 44rpx;
- height: 44rpx;
- border-radius: 8rpx;
- display: flex;
- justify-content: center;
- align-items: center;
- margin-right: 20rpx;
- margin-top: 4rpx;
- flex-shrink: 0;
- }
- .icon-bg.grey-bg {
- background-color: #F8F8F8;
- }
- .custom-icon {
- width: 28rpx;
- height: 28rpx;
- }
- .custom-icon-file {
- width: 36rpx;
- height: 36rpx;
- }
- .si-val {
- font-size: 28rpx;
- color: #333;
- }
- .record-btn {
- font-size: 24rpx;
- color: #FF5722;
- display: flex;
- align-items: center;
- }
- .record-arrow {
- width: 24rpx;
- height: 24rpx;
- margin-left: 6rpx;
- }
- .record-history-row {
- margin-top: 30rpx;
- padding-top: 25rpx;
- border-top: 1px dashed #f0f0f0;
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- .addr-row {
- position: relative;
- align-items: stretch;
- }
- .icon-circle {
- width: 40rpx;
- height: 40rpx;
- border-radius: 50%;
- color: #fff;
- font-size: 22rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-right: 20rpx;
- flex-shrink: 0;
- font-weight: bold;
- margin-top: 6rpx;
- position: relative;
- z-index: 1;
- }
- .icon-circle.start {
- background-color: #FFB74D;
- }
- .icon-circle.end {
- background-color: #81C784;
- }
- .icon-circle.service {
- background-color: #81C784;
- }
- .route-line-vertical {
- position: absolute;
- left: 19rpx;
- top: 46rpx;
- bottom: -6rpx;
- border-left: 2rpx dashed #E0E0E0;
- width: 0;
- z-index: 0;
- }
- .si-addr-title {
- font-size: 30rpx;
- font-weight: bold;
- color: #333;
- margin-bottom: 6rpx;
- }
- .si-addr-desc {
- font-size: 24rpx;
- color: #999;
- }
- .nav-btn-circle {
- width: 50rpx;
- height: 50rpx;
- background-color: #FFF3E0;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-top: 6rpx;
- }
- .nav-arrow {
- width: 28rpx;
- height: 28rpx;
- }
- .task-card {
- display: flex;
- flex-direction: column;
- }
- .tc-title {
- font-size: 30rpx;
- font-weight: bold;
- color: #333;
- margin-bottom: 15rpx;
- }
- .tc-desc {
- font-size: 22rpx;
- color: #666;
- margin-bottom: 12rpx;
- }
- .media-grid {
- display: flex;
- flex-wrap: wrap;
- gap: 20rpx;
- margin-bottom: 20rpx;
- }
- .media-item {
- width: 160rpx;
- height: 160rpx;
- position: relative;
- border-radius: 12rpx;
- }
- .media-preview {
- width: 100%;
- height: 100%;
- border-radius: 12rpx;
- }
- .media-del {
- position: absolute;
- top: -10rpx;
- right: -10rpx;
- width: 36rpx;
- height: 36rpx;
- background-color: rgba(0, 0, 0, 0.5);
- color: #fff;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 24rpx;
- z-index: 2;
- }
- .media-add {
- width: 160rpx;
- height: 160rpx;
- border: 2rpx dashed #ccc;
- border-radius: 12rpx;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- background-color: #FAFAFA;
- box-sizing: border-box;
- }
- .upload-icon-small {
- width: 40rpx;
- height: 40rpx;
- margin-bottom: 10rpx;
- }
- .upload-text-small {
- font-size: 22rpx;
- color: #999;
- }
- .full-media-add {
- width: 100%;
- height: 140rpx;
- background-color: #FAFAFA;
- border: 2rpx dashed #E0E0E0;
- border-radius: 12rpx;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- margin-top: 10rpx;
- }
- .upload-icon-large {
- width: 50rpx;
- height: 50rpx;
- margin-bottom: 10rpx;
- opacity: 0.5;
- }
- .upload-text-large {
- font-size: 24rpx;
- color: #999;
- }
- .bi-row {
- display: flex;
- align-items: flex-start;
- margin-bottom: 25rpx;
- }
- .bi-row:last-child {
- margin-bottom: 0;
- }
- .bi-icon {
- width: 32rpx;
- height: 32rpx;
- margin-right: 20rpx;
- margin-top: 4rpx;
- }
- .bi-icon-uni {
- margin-right: 20rpx;
- margin-top: 4rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .bi-content {
- flex: 1;
- display: flex;
- flex-direction: column;
- }
- .bi-label {
- font-size: 24rpx;
- color: #999;
- margin-bottom: 6rpx;
- }
- .bi-val-row {
- display: flex;
- align-items: center;
- }
- .bi-val {
- font-size: 28rpx;
- color: #333;
- }
- .bi-copy {
- background-color: #F0F0F0;
- color: #666;
- font-size: 20rpx;
- padding: 2rpx 10rpx;
- border-radius: 6rpx;
- margin-left: 15rpx;
- }
- .tl-title-row {
- display: flex;
- align-items: center;
- margin-bottom: 30rpx;
- }
- .orange-bar {
- width: 8rpx;
- height: 32rpx;
- background-color: #FF9800;
- margin-right: 16rpx;
- border-radius: 4rpx;
- }
- .tl-title {
- font-size: 30rpx;
- font-weight: bold;
- color: #333;
- }
- .tl-list {
- display: flex;
- flex-direction: column;
- padding-left: 10rpx;
- }
- .tl-item {
- display: flex;
- position: relative;
- padding-bottom: 40rpx;
- }
- .tl-item:last-child {
- padding-bottom: 0;
- }
- .tl-marker {
- width: 16rpx;
- height: 16rpx;
- border-radius: 50%;
- background-color: #E0E0E0;
- position: absolute;
- left: 0;
- top: 6rpx;
- z-index: 2;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .tl-marker.active {
- background-color: #fff;
- border: 3rpx solid #FF9800;
- width: 18rpx;
- height: 18rpx;
- left: -1rpx;
- }
- .tl-dot-inner {
- width: 10rpx;
- height: 10rpx;
- border-radius: 50%;
- background-color: #FF9800;
- }
- .tl-item:not(:last-child)::after {
- content: '';
- position: absolute;
- left: 7rpx;
- top: 24rpx;
- bottom: -6rpx;
- width: 2rpx;
- background-color: #FFE0B2;
- z-index: 1;
- }
- .tl-content-row {
- margin-left: 40rpx;
- display: flex;
- flex-direction: column;
- width: 100%;
- }
- .tl-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 100%;
- margin-bottom: 10rpx;
- }
- .tl-status {
- font-size: 28rpx;
- color: #333;
- font-weight: 500;
- }
- .tl-time {
- font-size: 24rpx;
- color: #999;
- }
- .tl-medias {
- display: flex;
- flex-wrap: wrap;
- gap: 15rpx;
- margin-bottom: 15rpx;
- }
- .tl-img {
- width: 140rpx;
- height: 140rpx;
- border-radius: 8rpx;
- }
- .tl-remark {
- font-size: 24rpx;
- color: #666;
- background-color: #F9F9F9;
- padding: 15rpx;
- border-radius: 8rpx;
- line-height: 1.5;
- }
- .bottom-action-bar {
- position: fixed;
- bottom: 0;
- left: 0;
- width: 100%;
- height: 120rpx;
- background-color: #fff;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 30rpx;
- box-shadow: 0 -5rpx 20rpx rgba(0, 0, 0, 0.05);
- box-sizing: border-box;
- padding-bottom: constant(safe-area-inset-bottom);
- padding-bottom: env(safe-area-inset-bottom);
- z-index: 100;
- }
- .action-left,
- .action-right {
- display: flex;
- align-items: center;
- }
- .action-btn {
- height: 64rpx;
- line-height: 64rpx;
- border-radius: 32rpx;
- font-size: 26rpx;
- padding: 0 35rpx;
- margin: 0;
- }
- .action-left .action-btn:first-child {
- margin-right: 20rpx;
- }
- .action-btn.grey-outline {
- background-color: #fff;
- color: #666;
- border: 1px solid #E0E0E0;
- }
- .action-btn.orange-outline {
- background-color: #FFF8F0;
- color: #FF9800;
- border: 1px solid #FF9800;
- }
- .action-btn.primary {
- background: linear-gradient(90deg, #FF9800 0%, #FF5722 100%);
- color: #fff;
- box-shadow: 0 4rpx 12rpx rgba(255, 87, 34, 0.2);
- border: none;
- }
- .action-btn.grey-bg {
- background: #E0E0E0;
- color: #999;
- box-shadow: none;
- border: none;
- }
- .action-btn::after {
- border: none;
- }
- .upload-modal-mask {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-color: rgba(0, 0, 0, 0.4);
- z-index: 999;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .upload-modal-content {
- width: 600rpx;
- background-color: #ffffff;
- border-radius: 20rpx;
- padding: 40rpx;
- box-sizing: border-box;
- display: flex;
- flex-direction: column;
- }
- .um-header {
- text-align: center;
- margin-bottom: 40rpx;
- }
- .um-title {
- font-size: 32rpx;
- font-weight: bold;
- color: #333;
- }
- .um-remark-hint {
- display: block;
- font-size: 22rpx;
- color: #999;
- margin-top: 16rpx;
- line-height: 1.4;
- }
- .um-grid {
- display: flex;
- flex-wrap: wrap;
- margin-bottom: 30rpx;
- }
- .um-item {
- width: 130rpx;
- height: 130rpx;
- border-radius: 8rpx;
- margin-right: 20rpx;
- margin-bottom: 20rpx;
- position: relative;
- background-color: #f5f5f5;
- overflow: hidden;
- }
- .um-item:nth-child(4n) {
- margin-right: 0;
- }
- .um-preview {
- width: 100%;
- height: 100%;
- }
- .um-del {
- position: absolute;
- top: 4rpx;
- right: 4rpx;
- width: 36rpx;
- height: 36rpx;
- line-height: 32rpx;
- text-align: center;
- background-color: rgba(0, 0, 0, 0.5);
- color: #fff;
- border-radius: 50%;
- font-size: 28rpx;
- z-index: 10;
- }
- .um-video-badge {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: rgba(0, 0, 0, 0.2);
- z-index: 5;
- }
- .play-icon-small {
- width: 48rpx;
- height: 48rpx;
- opacity: 0.9;
- }
- .um-add {
- width: 130rpx;
- height: 130rpx;
- border-radius: 8rpx;
- border: 1px dashed #e5e5e5;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- box-sizing: border-box;
- margin-bottom: 20rpx;
- }
- .um-add-icon {
- width: 44rpx;
- height: 44rpx;
- margin-bottom: 10rpx;
- opacity: 0.4;
- }
- .um-add-text {
- font-size: 24rpx;
- color: #ccc;
- }
- .um-textarea {
- width: 100%;
- height: 160rpx;
- background-color: #ffffff;
- border-radius: 12rpx;
- padding: 24rpx;
- font-size: 28rpx;
- color: #333;
- box-sizing: border-box;
- border: 1px solid #f0f0f0;
- }
- .um-footer {
- margin-top: 40rpx;
- display: flex;
- justify-content: center;
- }
- .um-submit-btn {
- width: 100%;
- height: 88rpx;
- line-height: 88rpx;
- border-radius: 44rpx;
- font-size: 32rpx;
- background-color: #E0E0E0;
- color: #fff;
- border: none;
- text-align: center;
- }
- .um-submit-btn.active {
- background: linear-gradient(90deg, #FF9800 0%, #FF5722 100%);
- color: #fff;
- box-shadow: 0 4rpx 10rpx rgba(255, 87, 34, 0.3);
- }
- .um-submit-btn::after {
- border: none;
- }
- .pet-modal-mask {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-color: rgba(0, 0, 0, 0.5);
- z-index: 999;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .pet-modal-content {
- width: 680rpx;
- max-height: 85vh;
- background-color: #fff;
- border-radius: 20rpx;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.15);
- }
- .pet-modal-header {
- display: flex;
- align-items: center;
- padding: 30rpx 30rpx 20rpx;
- border-bottom: 1px solid #f5f5f5;
- flex-shrink: 0;
- }
- .pet-modal-title {
- font-size: 32rpx;
- font-weight: bold;
- color: #333;
- }
- .close-icon-btn {
- width: 52rpx;
- height: 52rpx;
- line-height: 52rpx;
- text-align: center;
- font-size: 36rpx;
- color: #999;
- border-radius: 50%;
- background-color: #f5f5f5;
- flex-shrink: 0;
- }
- .pm-remark-btn {
- height: 52rpx;
- line-height: 52rpx;
- padding: 0 24rpx;
- background: linear-gradient(90deg, #FF9800 0%, #FF5722 100%);
- color: #fff;
- font-size: 26rpx;
- border-radius: 26rpx;
- margin-right: 16rpx;
- font-weight: bold;
- flex-shrink: 0;
- }
- .pet-modal-scroll {
- flex: 1;
- height: 65vh;
- overflow: auto;
- }
- .pet-base-info {
- display: flex;
- align-items: center;
- padding: 24rpx 30rpx;
- border-bottom: 1px solid #f9f9f9;
- }
- .pm-avatar {
- width: 100rpx;
- height: 100rpx;
- border-radius: 50%;
- margin-right: 20rpx;
- flex-shrink: 0;
- }
- .pm-info-text {
- flex: 1;
- display: flex;
- flex-direction: column;
- }
- .pm-name-row {
- display: flex;
- align-items: center;
- margin-bottom: 8rpx;
- }
- .pm-name {
- font-size: 32rpx;
- font-weight: bold;
- color: #333;
- margin-right: 12rpx;
- }
- .pm-gender {
- display: flex;
- align-items: center;
- background-color: #E3F2FD;
- color: #1976D2;
- font-size: 22rpx;
- padding: 2rpx 10rpx;
- border-radius: 10rpx;
- }
- .pm-gender.female {
- background-color: #FCE4EC;
- color: #C2185B;
- }
- .gender-icon {
- font-size: 22rpx;
- margin-right: 4rpx;
- }
- .pm-breed {
- font-size: 26rpx;
- color: #999;
- }
- .pm-detail-grid {
- padding: 20rpx 30rpx;
- display: flex;
- flex-wrap: wrap;
- gap: 16rpx;
- border-bottom: 1px solid #f9f9f9;
- }
- .pm-grid-item {
- background-color: #FAFAFA;
- border-radius: 12rpx;
- padding: 16rpx 20rpx;
- display: flex;
- flex-direction: column;
- }
- .pm-grid-item.half {
- width: calc(50% - 8rpx);
- }
- .pm-grid-item.full {
- width: 100%;
- }
- .pm-label {
- font-size: 24rpx;
- color: #999;
- margin-bottom: 8rpx;
- }
- .pm-val {
- font-size: 28rpx;
- color: #333;
- line-height: 1.5;
- }
- .pm-tags-row {
- display: flex;
- flex-wrap: wrap;
- padding: 0 24rpx 20rpx;
- gap: 16rpx;
- }
- .pm-tag-chip {
- background-color: #FFF3E0;
- border: 1px solid #FFB74D;
- border-radius: 20rpx;
- padding: 6rpx 20rpx;
- }
- .pm-tag-chip-text {
- font-size: 24rpx;
- color: #FF9800;
- }
- .pm-log-section {
- padding: 20rpx 24rpx;
- border-top: 1px solid #f5f5f5;
- margin-top: 10rpx;
- }
- .pm-log-header {
- display: flex;
- align-items: center;
- margin-bottom: 20rpx;
- }
- .pm-log-section-title {
- font-size: 28rpx;
- font-weight: bold;
- color: #333;
- }
- .pm-log-item {
- padding: 16rpx 0;
- border-bottom: 1px solid #f9f9f9;
- display: flex;
- flex-direction: column;
- }
- .pm-log-date {
- font-size: 24rpx;
- color: #999;
- margin-bottom: 8rpx;
- }
- .pm-log-text {
- font-size: 28rpx;
- color: #333;
- line-height: 1.6;
- margin-bottom: 6rpx;
- }
- .pm-log-recorder {
- font-size: 22rpx;
- color: #FF9800;
- text-align: right;
- }
- .pm-log-recorder.system {
- color: #999;
- }
- .pm-bottom-close {
- margin: 16rpx 30rpx;
- height: 72rpx;
- line-height: 72rpx;
- border-radius: 36rpx;
- font-size: 28rpx;
- background-color: #f5f5f5;
- color: #666;
- border: none;
- }
- .pm-bottom-close::after {
- border: none;
- }
- .sum-modal-mask {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background-color: rgba(0, 0, 0, 0.5);
- z-index: 999;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .sum-modal-card {
- width: 660rpx;
- max-height: 80vh;
- background-color: #fff;
- border-radius: 20rpx;
- display: flex;
- flex-direction: column;
- overflow: hidden;
- box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.15);
- }
- .sum-modal-scroll {
- flex: 1;
- overflow: hidden;
- }
- .sum-modal-inner {
- padding: 32rpx 36rpx 0;
- }
- .sum-modal-title {
- display: block;
- font-size: 34rpx;
- font-weight: bold;
- color: #333;
- text-align: center;
- margin-bottom: 30rpx;
- }
- .sum-meta-row {
- display: flex;
- margin-bottom: 16rpx;
- align-items: flex-start;
- }
- .sum-meta-label {
- font-size: 26rpx;
- color: #999;
- flex-shrink: 0;
- width: 140rpx;
- }
- .sum-meta-val {
- font-size: 24rpx;
- color: #333;
- flex: 1;
- }
- .sum-section-title {
- font-size: 26rpx;
- font-weight: bold;
- color: #333;
- padding-left: 12rpx;
- border-left: 6rpx solid #FF9800;
- margin-top: 24rpx;
- margin-bottom: 16rpx;
- }
- .sum-pet-card {
- background-color: #FAFAFA;
- border-radius: 12rpx;
- padding: 20rpx;
- display: flex;
- align-items: center;
- }
- .sum-pet-avatar {
- width: 80rpx;
- height: 80rpx;
- border-radius: 50%;
- margin-right: 20rpx;
- flex-shrink: 0;
- }
- .sum-pet-info {
- flex: 1;
- display: flex;
- flex-direction: column;
- }
- .sum-pet-name-row {
- display: flex;
- align-items: center;
- margin-bottom: 8rpx;
- }
- .sum-pet-name {
- font-size: 26rpx;
- font-weight: bold;
- color: #333;
- margin-right: 12rpx;
- }
- .sum-pet-breed {
- font-size: 24rpx;
- color: #999;
- }
- .sum-pet-remark {
- font-size: 24rpx;
- color: #666;
- line-height: 1.5;
- }
- .sum-textarea {
- width: 100%;
- min-height: 220rpx;
- background-color: #fff;
- border: 1px solid #eeeeee;
- border-radius: 12rpx;
- padding: 18rpx;
- font-size: 26rpx;
- color: #333;
- box-sizing: border-box;
- line-height: 1.8;
- }
- .sum-sign-row {
- display: flex;
- align-items: center;
- margin-top: 30rpx;
- padding: 16rpx 0;
- border-top: 1px solid #f5f5f5;
- }
- .sum-sign-label {
- font-size: 26rpx;
- color: #999;
- margin-right: 10rpx;
- }
- .sum-sign-val {
- font-size: 26rpx;
- color: #333;
- }
- .sum-footer {
- padding: 20rpx 36rpx 36rpx;
- padding-bottom: max(36rpx, constant(safe-area-inset-bottom));
- padding-bottom: max(36rpx, env(safe-area-inset-bottom));
- background-color: #fff;
- }
- .sum-submit-btn {
- width: 100%;
- height: 84rpx;
- line-height: 84rpx;
- border-radius: 42rpx;
- font-size: 30rpx;
- background: linear-gradient(90deg, #FF9800 0%, #FF5722 100%);
- color: #fff;
- border: none;
- box-shadow: 0 4rpx 16rpx rgba(255, 87, 34, 0.25);
- }
- .sum-submit-btn::after {
- border: none;
- }
- .modal-mask {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.5);
- z-index: 999;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .anomaly-modal-content {
- width: 650rpx;
- background-color: #fff;
- border-radius: 20rpx;
- padding: 30rpx;
- position: relative;
- max-height: 80vh;
- display: flex;
- flex-direction: column;
- }
- .am-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 30rpx;
- padding-bottom: 20rpx;
- border-bottom: 1px solid #f5f5f5;
- }
- .am-title {
- font-size: 32rpx;
- font-weight: bold;
- color: #333;
- }
- .am-scroll-list {
- flex: 1;
- }
- .am-item {
- padding: 24rpx;
- background-color: #F9FAFB;
- border-radius: 12rpx;
- margin-bottom: 24rpx;
- }
- .am-item-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 16rpx;
- }
- .am-item-type {
- font-size: 28rpx;
- font-weight: bold;
- color: #333;
- }
- .am-item-status {
- font-size: 22rpx;
- padding: 4rpx 16rpx;
- border-radius: 20rpx;
- }
- .am-item-status.status-0 {
- background-color: #FFF3E0;
- color: #FF9800;
- }
- .am-item-status.status-1 {
- background-color: #E8F5E9;
- color: #4CAF50;
- }
- .am-item-status.status-2 {
- background-color: #FFEBEE;
- color: #F44336;
- }
- .am-item-content {
- font-size: 26rpx;
- color: #666;
- line-height: 1.6;
- display: block;
- margin-bottom: 16rpx;
- }
- .am-item-photos {
- display: flex;
- flex-wrap: wrap;
- gap: 12rpx;
- margin-bottom: 20rpx;
- }
- .am-photo {
- width: 130rpx;
- height: 130rpx;
- border-radius: 8rpx;
- }
- .am-audit-box {
- margin-top: 20rpx;
- padding-top: 20rpx;
- border-top: 1px dashed #E0E0E0;
- }
- .am-audit-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 8rpx;
- }
- .am-audit-label {
- font-size: 24rpx;
- font-weight: bold;
- color: #333;
- }
- .am-audit-time {
- font-size: 22rpx;
- color: #999;
- }
- .am-audit-remark {
- font-size: 24rpx;
- color: #666;
- line-height: 1.5;
- }
- .empty-list {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 100rpx 0;
- }
- .empty-icon {
- width: 200rpx;
- height: 200rpx;
- margin-bottom: 20rpx;
- opacity: 0.5;
- }
- .empty-text {
- font-size: 26rpx;
- color: #999;
- }
- .tl-media-item {
- position: relative;
- width: 140rpx;
- height: 140rpx;
- }
- .tl-video-placeholder {
- width: 100%;
- height: 100%;
- background: linear-gradient(135deg, #444 0%, #222 100%);
- border-radius: 8rpx;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- }
- .tl-video-placeholder.miniaturized {
- border-radius: 8rpx;
- overflow: hidden;
- }
- .tl-video-label {
- color: #fff;
- font-size: 20rpx;
- margin-top: 50rpx;
- opacity: 0.8;
- }
- .tl-video-label.small {
- margin-top: 35rpx;
- font-size: 18rpx;
- }
- .tl-play-icon {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 60rpx;
- height: 60rpx;
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: rgba(255, 255, 255, 0.2);
- border: 2rpx solid #fff;
- border-radius: 50%;
- }
- .tl-play-icon::after {
- content: '';
- display: block;
- width: 0;
- height: 0;
- border-top: 15rpx solid transparent;
- border-bottom: 15rpx solid transparent;
- border-left: 20rpx solid #fff;
- margin-left: 6rpx;
- }
- .tl-play-icon.small {
- width: 40rpx;
- height: 40rpx;
- }
- .tl-play-icon.small::after {
- border-top: 10rpx solid transparent;
- border-bottom: 10rpx solid transparent;
- border-left: 14rpx solid #fff;
- margin-left: 4rpx;
- }
- .video-player-mask {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.9);
- z-index: 999;
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .video-player-content {
- position: relative;
- width: 100%;
- height: 600rpx;
- }
- .v-player {
- width: 100%;
- height: 100%;
- }
- .v-close {
- position: absolute;
- top: -80rpx;
- right: 40rpx;
- width: 60rpx;
- height: 60rpx;
- background-color: rgba(255, 255, 255, 0.2);
- color: #fff;
- border-radius: 50%;
- display: flex;
- justify-content: center;
- align-items: center;
- font-size: 40rpx;
- }
- .am-photo-item {
- position: relative;
- width: 150rpx;
- height: 150rpx;
- border-radius: 8rpx;
- overflow: hidden;
- }
- .am-photo {
- width: 150rpx;
- height: 150rpx;
- border-radius: 8rpx;
- }
- .nav-modal-mask {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: rgba(0, 0, 0, 0.6);
- z-index: 1000;
- display: flex;
- align-items: flex-end;
- }
- .nav-action-sheet {
- width: 100%;
- background-color: #fff;
- border-radius: 30rpx 30rpx 0 0;
- padding-bottom: constant(safe-area-inset-bottom);
- padding-bottom: env(safe-area-inset-bottom);
- overflow: hidden;
- }
- .nav-sheet-title {
- display: block;
- text-align: center;
- font-size: 26rpx;
- color: #999;
- padding: 30rpx 0;
- border-bottom: 1px solid #f5f5f5;
- }
- .nav-sheet-item {
- display: block;
- text-align: center;
- font-size: 32rpx;
- color: #333;
- padding: 35rpx 0;
- border-bottom: 1px solid #f5f5f5;
- background-color: #fff;
- }
- .nav-sheet-item:active {
- background-color: #f9f9f9;
- }
- .nav-sheet-item.cancel {
- color: #999;
- }
- .nav-sheet-gap {
- height: 12rpx;
- background-color: #f5f5f5;
- }
- </style>
|