xlTask.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897
  1. <template>
  2. <view class="container">
  3. <!-- 搜索+筛选栏 -->
  4. <view class="top-box">
  5. <view class="input-item">
  6. <image class="icon search-icon" src="@/static/image/search.png" mode="widthFix"></image>
  7. <input placeholder="请输入客户姓名/机构名称" placeholder-class="placeholder" />
  8. </view>
  9. <view class="filter-item" @click="showFilter = true">
  10. <image class="filter-icon" src="@/static/image/icon_select.png" mode="widthFix"></image>
  11. <text>筛选</text>
  12. </view>
  13. </view>
  14. <!-- 顶部选项卡:任务列表/审核列表 -->
  15. <view class="top-tabs">
  16. <view class="top-tab-item" :class="{ active: currentTopTab === 'task' }" @click="switchTopTab('task')">
  17. 任务列表
  18. </view>
  19. <view class="top-tab-item" :class="{ active: currentTopTab === 'audit' }" @click="switchTopTab('audit')">
  20. 审核列表
  21. </view>
  22. </view>
  23. <!-- 动态子标签 -->
  24. <view class="sub-tabs">
  25. <view class="sub-tab-item" :class="{ active: currentSubTab === item.value }"
  26. @click="currentSubTab = item.value" v-for="(item, index) in currentSubTabsList" :key="index">
  27. {{ item.label }}
  28. </view>
  29. </view>
  30. <!-- 列表内容 -->
  31. <scroll-view class="content" scroll-y>
  32. <view class="task-card" v-for="(item, index) in currentList" :key="index" @click="goDetails(item)">
  33. <!-- 任务/审核标题+状态 -->
  34. <view class="card-top">
  35. <text class="card-task-title">{{ item.taskTitle }}</text>
  36. <view class="status-tag" :class="item.statusClass">{{ item.statusText }}</view>
  37. </view>
  38. <view class="card-content">
  39. <!-- 讲者信息 -->
  40. <view class="speaker-info">
  41. <text class="speaker-name">{{ item.speaker }}</text>
  42. <view class="level-tag">{{ item.level }}</view>
  43. </view>
  44. <!-- 医院+科室 -->
  45. <view class="org-info">
  46. <image class="org-icon" src="@/static/image/icon_hospital.png" mode="widthFix"></image>
  47. <text>{{ item.hospital }}</text>
  48. <view class="line"></view>
  49. <text>{{ item.department }}</text>
  50. </view>
  51. <!-- 标签组 -->
  52. <view class="card-tags">
  53. <view class="tag-left-group">
  54. <view class="tag-item video-tag" v-if="item.videoType">
  55. <image class="video-tag-icon" src="@/static/image/icon_longvideo.png" mode="widthFix">
  56. </image>
  57. <text>{{ item.videoType }}</text>
  58. </view>
  59. <view class="tag-item category-tag" v-if="item.category">
  60. {{ item.category }}
  61. </view>
  62. </view>
  63. <view class="tag-right-group">
  64. <view class="tag-item points-tag">{{ item.points }}积分</view>
  65. <view class="tag-item count-tag">{{ item.count }}个</view>
  66. <view class="tag-item count-tag">院内</view>
  67. </view>
  68. </view>
  69. <!-- 时间信息 -->
  70. <view class="time-info">
  71. <view class="time-item">
  72. <text>申请时间:</text>
  73. <text>{{ item.applyTime }}</text>
  74. </view>
  75. <view class="time-item" v-if="currentTopTab === 'task'">
  76. <text>完成时间:</text>
  77. <text>{{ item.finishTime || '-' }}</text>
  78. </view>
  79. <view class="time-item" v-if="currentTopTab === 'task'">
  80. <text>完成审核:</text>
  81. <text>{{ item.auditStatus || '-' }}</text>
  82. </view>
  83. </view>
  84. <!-- 操作按钮 -->
  85. <view class="operate-btn-group" v-if="currentTopTab === 'task'">
  86. <view class="share-btn" @click="handleShare(item)">
  87. <image class="share-icon" src="/static/image/icon_share.png" mode="widthFix"></image>
  88. <text>分享</text>
  89. </view>
  90. <view class="btn-group">
  91. <view class="btn" v-if="item.showDelete" @click="handleTaskDelete(item, index)">删除</view>
  92. <view class="btn" @click="handleCopy(item)">复制创建</view>
  93. </view>
  94. </view>
  95. <view class="operate-btn-group flex-end" v-else>
  96. <view class="btn-group">
  97. <view class="btn" v-if="item.showDelete" @click="handleAuditDelete(item, index)">删除</view>
  98. <view class="btn" v-if="item.showEdit" @click="handleEdit(item)">编辑</view>
  99. </view>
  100. </view>
  101. <!-- 状态印章 -->
  102. <image class="status-seal" :src="item.sealImg" mode="widthFix" v-if="currentTopTab === 'task'">
  103. </image>
  104. </view>
  105. </view>
  106. </scroll-view>
  107. <view class="side">
  108. <view class="side-item" @click="goCreate" >
  109. <image class="icon" src="/static/image/icon_close.png"></image>
  110. </view>
  111. <view class="side-item" @click="goData">
  112. <image class="icon" src="/static/image/icon_close.png"></image>
  113. </view>
  114. </view>
  115. <!-- 筛选弹窗 -->
  116. <view class="filter-popup" v-if="showFilter" @click="closeFilter">
  117. <view class="filter-content" @click.stop>
  118. <view class="filter-header">
  119. <view class="filter-title">筛选</view>
  120. <image class="filter-close-btn" src="@/static/image/icon_close.png" @click="closeFilter"
  121. mode="widthFix"></image>
  122. </view>
  123. <view class="filter-form">
  124. <!-- 任务申请时间 -->
  125. <view class="filter-section">
  126. <view class="section-label">任务申请时间</view>
  127. <view class="time-range">
  128. <input class="time-input" placeholder="开始时间" v-model="filters.applyTimeStart" />
  129. <view class="time-separator">-</view>
  130. <input class="time-input" placeholder="结束时间" v-model="filters.applyTimeEnd" />
  131. </view>
  132. </view>
  133. <!-- 任务完成时间 -->
  134. <view class="filter-section" v-if="currentTopTab === 'audit'">
  135. <view class="section-label">任务完成时间</view>
  136. <view class="time-range">
  137. <input class="time-input" placeholder="开始时间" v-model="filters.finishTimeStart" />
  138. <view class="time-separator">-</view>
  139. <input class="time-input" placeholder="结束时间" v-model="filters.finishTimeEnd" />
  140. </view>
  141. </view>
  142. <!-- 完成审核时间 -->
  143. <view class="filter-section" v-if="currentTopTab === 'audit'">
  144. <view class="section-label">完成审核时间</view>
  145. <view class="time-range">
  146. <input class="time-input" placeholder="开始时间" v-model="filters.auditTimeStart" />
  147. <view class="time-separator">-</view>
  148. <input class="time-input" placeholder="结束时间" v-model="filters.auditTimeEnd" />
  149. </view>
  150. </view>
  151. <!-- 任务归属 -->
  152. <view class="filter-section">
  153. <view class="section-label">任务归属</view>
  154. <view class="btn-group">
  155. <view class="filter-btn" :class="{ active: filters.taskBelong === 'my' }"
  156. @click="filters.taskBelong = 'my'">我的任务</view>
  157. <view class="filter-btn" :class="{ active: filters.taskBelong === 'dept' }"
  158. @click="filters.taskBelong = 'dept'">部门任务</view>
  159. </view>
  160. </view>
  161. <!-- 完结状态 -->
  162. <view class="filter-section" v-if="currentTopTab === 'audit'">
  163. <view class="section-label">完结状态</view>
  164. <view class="btn-group">
  165. <view class="filter-btn" :class="{ active: filters.finishStatus === 'unfinished' }"
  166. @click="filters.finishStatus = 'unfinished'">未完结</view>
  167. <view class="filter-btn" :class="{ active: filters.finishStatus === 'finished' }"
  168. @click="filters.finishStatus = 'finished'">已完结</view>
  169. </view>
  170. </view>
  171. <!-- 归属类型 -->
  172. <view class="filter-section">
  173. <view class="section-label">归属类型</view>
  174. <view class="btn-group">
  175. <view class="filter-btn" :class="{ active: filters.belongType === 'inner' }"
  176. @click="filters.belongType = 'inner'">院内</view>
  177. <view class="filter-btn" :class="{ active: filters.belongType === 'outer' }"
  178. @click="filters.belongType = 'outer'">院外</view>
  179. </view>
  180. </view>
  181. </view>
  182. <view class="filter-actions">
  183. <view class="reset-btn" @click="resetFilters">重置</view>
  184. <view class="confirm-btn" @click="confirmFilters">确定</view>
  185. </view>
  186. </view>
  187. </view>
  188. </view>
  189. </template>
  190. <script>
  191. export default {
  192. data() {
  193. return {
  194. showFilter: false,
  195. filters: {
  196. applyTimeStart: '',
  197. applyTimeEnd: '',
  198. finishTimeStart: '',
  199. finishTimeEnd: '',
  200. auditTimeStart: '',
  201. auditTimeEnd: '',
  202. taskBelong: 'my',
  203. finishStatus: '',
  204. belongType: ''
  205. },
  206. currentTopTab: 'task',
  207. currentSubTab: 'all',
  208. taskSubTabs: [{
  209. label: '全部任务',
  210. value: 'all'
  211. },
  212. {
  213. label: '未完成',
  214. value: 'unfinished'
  215. },
  216. {
  217. label: '已完成',
  218. value: 'finished'
  219. }
  220. ],
  221. auditSubTabs: [{
  222. label: '全部',
  223. value: 'all'
  224. },
  225. {
  226. label: '创建待审批',
  227. value: 'createPending'
  228. },
  229. {
  230. label: '完成待审批',
  231. value: 'finishPending'
  232. },
  233. {
  234. label: '驳回',
  235. value: 'rejected'
  236. }
  237. ],
  238. taskList: [{
  239. taskTitle: '王小明医生的学术讲座',
  240. statusText: '待完成',
  241. statusClass: 'status-wait',
  242. speaker: '王小明',
  243. level: '一级',
  244. hospital: '湖南省人民医院',
  245. department: '口腔科',
  246. videoType: '长视频',
  247. category: '学术',
  248. points: 10,
  249. count: 1,
  250. applyTime: '2025-9-20 13:55',
  251. finishTime: '-',
  252. auditStatus: '-',
  253. showDelete: true,
  254. sealImg: '/static/image/img_unfinish.png'
  255. }],
  256. auditList: [{
  257. taskTitle: '王小明医生的学术讲座',
  258. statusText: '创建驳回',
  259. statusClass: 'status-rejected',
  260. speaker: '王小明',
  261. level: '一级',
  262. hospital: '湖南省人民医院',
  263. department: '口腔科',
  264. videoType: '长视频',
  265. category: '学术',
  266. points: 10,
  267. count: 1,
  268. applyTime: '2025-9-20 13:55',
  269. showDelete: true,
  270. showEdit: true
  271. }]
  272. }
  273. },
  274. computed: {
  275. currentSubTabsList() {
  276. return this.currentTopTab === 'task' ? this.taskSubTabs : this.auditSubTabs;
  277. },
  278. currentList() {
  279. return this.currentTopTab === 'task' ? this.taskList : this.auditList;
  280. }
  281. },
  282. methods: {
  283. goCreate(){
  284. uni.navigateTo({
  285. url: '/pages_task/createTask'
  286. })
  287. },
  288. goData(){
  289. uni.navigateTo({
  290. url: '/pages_echarts/statistics'
  291. })
  292. },
  293. goDetails(item) {
  294. uni.navigateTo({
  295. url: '/pages_task/taskDetail'
  296. })
  297. },
  298. switchTopTab(type) {
  299. this.currentTopTab = type;
  300. this.currentSubTab = 'all';
  301. },
  302. closeFilter() {
  303. this.showFilter = false
  304. },
  305. resetFilters() {
  306. this.filters = {
  307. applyTimeStart: '',
  308. applyTimeEnd: '',
  309. finishTimeStart: '',
  310. finishTimeEnd: '',
  311. auditTimeStart: '',
  312. auditTimeEnd: '',
  313. taskBelong: 'my',
  314. finishStatus: '',
  315. belongType: ''
  316. }
  317. },
  318. confirmFilters() {
  319. this.showFilter = false
  320. console.log('筛选条件:', this.filters)
  321. },
  322. handleShare(item) {
  323. uni.showToast({
  324. title: '分享功能待实现',
  325. icon: 'none'
  326. })
  327. },
  328. handleTaskDelete(item, index) {
  329. uni.showModal({
  330. title: '提示',
  331. content: '确定要删除这条任务吗?',
  332. cancelText: '取消',
  333. confirmText: '删除',
  334. confirmColor: '#FF0000',
  335. success: (res) => {
  336. if (res.confirm) {
  337. this.taskList.splice(index, 1);
  338. uni.showToast({
  339. title: '任务已删除',
  340. icon: 'success',
  341. duration: 1500
  342. });
  343. }
  344. }
  345. });
  346. },
  347. handleCopy(item) {
  348. uni.navigateTo({
  349. url: '/pages_task/createTask'
  350. })
  351. // uni.showToast({
  352. // title: '复制创建功能待实现',
  353. // icon: 'none'
  354. // })
  355. },
  356. handleAuditDelete(item, index) {
  357. uni.showModal({
  358. title: '提示',
  359. content: '确定要删除这条审核项吗?',
  360. cancelText: '取消',
  361. confirmText: '删除',
  362. confirmColor: '#FF0000',
  363. success: (res) => {
  364. if (res.confirm) {
  365. this.auditList.splice(index, 1);
  366. uni.showToast({
  367. title: '审核项已删除',
  368. icon: 'success',
  369. duration: 1500
  370. });
  371. }
  372. }
  373. });
  374. },
  375. handleEdit(item) {
  376. uni.showToast({
  377. title: '编辑功能待实现',
  378. icon: 'none'
  379. })
  380. }
  381. }
  382. }
  383. </script>
  384. <style lang="scss" scoped>
  385. .container {
  386. min-height: 100vh;
  387. background: #f5f5f5;
  388. .top-box {
  389. padding: 20rpx 32rpx;
  390. display: flex;
  391. align-items: center;
  392. background: #fff;
  393. .input-item {
  394. display: flex;
  395. align-items: center;
  396. flex: 1;
  397. height: 72rpx;
  398. background: #F7F8FA;
  399. border-radius: 38rpx;
  400. .search-icon {
  401. width: 26rpx;
  402. height: 26rpx;
  403. margin: 0 10rpx 0 28rpx;
  404. }
  405. input {
  406. flex: 1;
  407. font-size: 28rpx;
  408. color: #333;
  409. }
  410. }
  411. .filter-item {
  412. margin-left: 24rpx;
  413. display: flex;
  414. align-items: center;
  415. font-size: 28rpx;
  416. color: #999;
  417. .filter-icon {
  418. width: 28rpx;
  419. height: 28rpx;
  420. margin-right: 10rpx;
  421. }
  422. }
  423. }
  424. .top-tabs {
  425. display: flex;
  426. background: #fff;
  427. .top-tab-item {
  428. flex: 1;
  429. text-align: center;
  430. padding: 24rpx 0;
  431. font-size: 28rpx;
  432. color: #999;
  433. transition: all 0.2s;
  434. &.active {
  435. color: #333;
  436. font-weight: 500;
  437. position: relative;
  438. &::after {
  439. content: '';
  440. position: absolute;
  441. bottom: 0;
  442. left: 50%;
  443. transform: translateX(-50%);
  444. border-radius: 3rpx;
  445. width: 80rpx;
  446. height: 6rpx;
  447. background: #388BFF;
  448. }
  449. }
  450. }
  451. }
  452. .sub-tabs {
  453. display: flex;
  454. justify-content: space-between;
  455. background: #fff;
  456. padding: 16rpx 32rpx;
  457. gap: 24rpx;
  458. .sub-tab-item {
  459. padding: 12rpx 24rpx;
  460. border-radius: 30rpx;
  461. font-size: 28rpx;
  462. color: #666;
  463. transition: all 0.2s;
  464. &.active {
  465. background: #EBF3FF;
  466. color: #388BFF;
  467. }
  468. }
  469. }
  470. .content {
  471. padding: 24rpx;
  472. box-sizing: border-box;
  473. min-height: calc(100vh - 300rpx);
  474. .task-card {
  475. background: #fff;
  476. border-radius: 24rpx;
  477. margin-bottom: 20rpx;
  478. border: 2rpx solid #E9F2FF;
  479. position: relative;
  480. padding-bottom: 24rpx;
  481. .card-top {
  482. display: flex;
  483. justify-content: space-between;
  484. align-items: center;
  485. background: linear-gradient(90deg, #E8F1FF 0%, #FFFFFF 100%);
  486. border-radius: 24rpx 24rpx 0 0;
  487. padding: 26rpx 24rpx;
  488. margin-bottom: 16rpx;
  489. .card-task-title {
  490. font-size: 32rpx;
  491. font-weight: 600;
  492. color: #333;
  493. }
  494. .status-tag {
  495. padding: 8rpx 16rpx;
  496. border-radius: 20rpx;
  497. font-size: 24rpx;
  498. &.status-wait {
  499. background: #E3F2FD;
  500. color: #2196F3;
  501. }
  502. &.status-finish {
  503. background: #E6FAEF;
  504. color: #07C160;
  505. }
  506. &.status-rejected {
  507. background: #FFF4F5;
  508. color: #CF3546;
  509. }
  510. &.status-createPending {
  511. background: #FFF8E6;
  512. color: #FF9500;
  513. }
  514. }
  515. }
  516. .card-content {
  517. padding: 0 24rpx;
  518. .speaker-info {
  519. display: flex;
  520. align-items: center;
  521. margin-bottom: 16rpx;
  522. .speaker-name {
  523. font-weight: 600;
  524. font-size: 32rpx;
  525. color: #333;
  526. }
  527. .level-tag {
  528. margin-left: 16rpx;
  529. padding: 2rpx 12rpx;
  530. font-size: 22rpx;
  531. color: #C89743;
  532. background: #FFF6E5;
  533. border-radius: 8rpx;
  534. }
  535. }
  536. .org-info {
  537. display: flex;
  538. align-items: center;
  539. margin-bottom: 16rpx;
  540. font-size: 28rpx;
  541. color: #666;
  542. .org-icon {
  543. width: 32rpx;
  544. height: 32rpx;
  545. margin-right: 16rpx;
  546. }
  547. .line {
  548. width: 2rpx;
  549. height: 28rpx;
  550. background: #EAEBEE;
  551. margin: 0 24rpx;
  552. }
  553. }
  554. .card-tags {
  555. display: flex;
  556. align-items: center;
  557. flex-wrap: wrap;
  558. gap: 12rpx;
  559. margin-bottom: 16rpx;
  560. .tag-left-group {
  561. display: flex;
  562. gap: 0;
  563. .video-tag {
  564. background: linear-gradient(90deg, #FFE9C7 0%, #F3D091 100%);
  565. border-radius: 8rpx 0 0 8rpx;
  566. color: #5D410F;
  567. display: flex;
  568. align-items: center;
  569. padding: 8rpx;
  570. font-size: 24rpx;
  571. .video-tag-icon {
  572. width: 28rpx;
  573. height: 28rpx;
  574. margin-right: 10rpx;
  575. }
  576. }
  577. .category-tag {
  578. border-radius: 0 8rpx 8rpx 0;
  579. border: 2rpx solid #F3D191;
  580. background: #FFFAF4;
  581. color: #5D410F;
  582. padding: 8rpx;
  583. font-size: 24rpx;
  584. }
  585. }
  586. .tag-right-group {
  587. display: flex;
  588. gap: 12rpx;
  589. .points-tag {
  590. border: 1rpx solid #388BFF;
  591. color: #388BFF;
  592. background: transparent;
  593. border-radius: 8rpx;
  594. padding: 8rpx;
  595. font-size: 24rpx;
  596. }
  597. .count-tag {
  598. border: 2rpx solid #E8E8E8;
  599. border-radius: 8rpx;
  600. padding: 8rpx;
  601. font-size: 24rpx;
  602. color: #666;
  603. }
  604. }
  605. }
  606. .time-info {
  607. font-size: 28rpx;
  608. color: #666;
  609. display: flex;
  610. flex-direction: column;
  611. gap: 8rpx;
  612. margin-bottom: 24rpx;
  613. .time-item {
  614. display: flex;
  615. &:first-child {
  616. color: #333;
  617. }
  618. }
  619. }
  620. .operate-btn-group {
  621. display: flex;
  622. align-items: center;
  623. justify-content: space-between;
  624. &.flex-end {
  625. justify-content: flex-end;
  626. }
  627. .share-btn {
  628. display: flex;
  629. align-items: center;
  630. font-size: 28rpx;
  631. color: #666;
  632. .share-icon {
  633. width: 36rpx;
  634. height: 36rpx;
  635. margin-right: 8rpx;
  636. }
  637. }
  638. .btn-group {
  639. display: flex;
  640. align-items: center;
  641. .btn {
  642. padding: 12rpx 32rpx;
  643. font-size: 28rpx;
  644. color: #388BFF;
  645. border: 2rpx solid #388BFF;
  646. margin-left: 16rpx;
  647. border-radius: 34rpx;
  648. transition: all 0.2s;
  649. &:active {
  650. background: #EBF3FF;
  651. }
  652. }
  653. }
  654. }
  655. .status-seal {
  656. position: absolute;
  657. right: 24rpx;
  658. bottom: 156rpx;
  659. width: 152rpx;
  660. height: 142rpx;
  661. opacity: 0.8;
  662. }
  663. }
  664. }
  665. }
  666. .side {
  667. position: absolute;
  668. top: 60%;
  669. right: 36rpx;
  670. display: flex;
  671. flex-direction: column;
  672. align-items: center;
  673. .side-item {
  674. width: 96rpx;
  675. height: 96rpx;
  676. background: linear-gradient(0deg, #388BFF 0%, #388BFF 100%);
  677. box-shadow: inset 0rpx 4rpx 8rpx 0rpx rgba(255, 255, 255, 0.25), inset 0rpx -6rpx 8rpx 0rpx rgba(255, 255, 255, 0.25), 4rpx 8rpx 12rpx 0rpx rgba(88, 144, 239, 0.29);
  678. border-radius: 110rpx 110rpx 110rpx 110rpx;
  679. margin-bottom: 28rpx;
  680. text-align: center;
  681. line-height: 96rpx;
  682. .icon {
  683. width: 38rpx;
  684. height: 38rpx;
  685. }
  686. &:active {
  687. opacity: 0.6;
  688. }
  689. }
  690. }
  691. .filter-popup {
  692. position: fixed;
  693. top: 0;
  694. left: 0;
  695. right: 0;
  696. bottom: 0;
  697. background: rgba(0, 0, 0, 0.5);
  698. z-index: 999;
  699. display: flex;
  700. align-items: flex-end;
  701. .filter-content {
  702. width: 100%;
  703. background: #fff;
  704. border-radius: 24rpx 24rpx 0 0;
  705. padding: 32rpx;
  706. .filter-header {
  707. display: flex;
  708. align-items: center;
  709. justify-content: center;
  710. margin-bottom: 32rpx;
  711. position: relative;
  712. .filter-title {
  713. font-size: 32rpx;
  714. font-weight: bold;
  715. color: #333;
  716. }
  717. .filter-close-btn {
  718. position: absolute;
  719. right: 0;
  720. width: 44rpx;
  721. height: 44rpx;
  722. }
  723. }
  724. .filter-form {
  725. padding: 0 0 24rpx 0;
  726. .filter-section {
  727. margin-bottom: 32rpx;
  728. .section-label {
  729. font-weight: 500;
  730. font-size: 28rpx;
  731. color: #333;
  732. margin-bottom: 24rpx;
  733. }
  734. .time-range {
  735. display: flex;
  736. align-items: center;
  737. gap: 16rpx;
  738. .time-input {
  739. flex: 1;
  740. height: 72rpx;
  741. text-align: center;
  742. background: #F7F8FA;
  743. border-radius: 8rpx;
  744. padding: 0 16rpx;
  745. font-size: 26rpx;
  746. color: #333;
  747. }
  748. .time-separator {
  749. font-size: 24rpx;
  750. color: #999;
  751. }
  752. }
  753. .btn-group {
  754. display: flex;
  755. gap: 16rpx;
  756. .filter-btn {
  757. width: 214rpx;
  758. height: 72rpx;
  759. background: #F7F8FA;
  760. border-radius: 70rpx 70rpx 70rpx 70rpx;
  761. line-height: 72rpx;
  762. text-align: center;
  763. font-size: 28rpx;
  764. transition: all 0.2s;
  765. color: #333333;
  766. &.active {
  767. background: rgba(56, 139, 255, 0.15);
  768. color: #388BFF;
  769. }
  770. }
  771. }
  772. }
  773. }
  774. .filter-actions {
  775. display: flex;
  776. gap: 24rpx;
  777. margin-top: 40rpx;
  778. .reset-btn,
  779. .confirm-btn {
  780. flex: 1;
  781. height: 80rpx;
  782. line-height: 80rpx;
  783. text-align: center;
  784. border-radius: 200rpx;
  785. font-size: 28rpx;
  786. transition: all 0.2s;
  787. }
  788. .reset-btn {
  789. background: #fff;
  790. color: #388BFF;
  791. border: 2rpx solid #388BFF;
  792. &:active {
  793. background: #EBF3FF;
  794. }
  795. }
  796. .confirm-btn {
  797. background: #388BFF;
  798. color: #fff;
  799. &:active {
  800. background: #2A78E5;
  801. }
  802. }
  803. }
  804. }
  805. }
  806. }
  807. </style>