benefitSingleItem.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104
  1. <template>
  2. <view class="page">
  3. <!-- 头部切换 -->
  4. <u-sticky zIndex="999" customNavHeight="0" style="position: relative;">
  5. <uni-NavBar headerTitle="权益单品" background="#fff" :isSlot="false" :rightSlot="true"
  6. borderBottom="1rpx solid #eee">
  7. </uni-NavBar>
  8. <uni-dropdown :close-on-click-mask="mask" ref="uDropdown" :activeColor="activeColor" border-radius="10"
  9. menuIcon="arrow-down-fill" :borderBottom="borderBottom" @menuClick="menuClick">
  10. <uni-dropdown-item :title="location.cityName || '地区'"></uni-dropdown-item>
  11. <uni-dropdown-item title="价格区间">
  12. <view class="slotArea">
  13. <view class="p-3">
  14. <!-- 双边滑动选择器 -->
  15. <view class="slider-header dis a-c j-s ">
  16. <text>价值</text>
  17. <text>{{ queryInfo.minPrice }}-{{ queryInfo.maxPrice }}元</text>
  18. </view>
  19. <view style="padding: 0 40rpx;">
  20. <uni-tianzai-slider-range :step="50" :min="0" :max="1000"
  21. :value="[queryInfo.minPrice, queryInfo.maxPrice]" @change="onChange" @end="onEnd">
  22. </uni-tianzai-slider-range>
  23. </view>
  24. <view class="options dis a-c f-wrap mt-3">
  25. <view class="options-card dis a-c j-c"
  26. :class="item.label == priceRangeName ? 'active' : ''"
  27. v-for="(item, index) in priceRangeOptions" :key="index"
  28. @click="filterCriteriaClick(item)">
  29. {{ item.label }}
  30. </view>
  31. </view>
  32. </view>
  33. <!-- 按钮 -->
  34. <view class="slider-btn dis a-c j-s">
  35. <view class="btn dis a-c j-c mr-3" @click="clearForm">
  36. 清空
  37. </view>
  38. <view class="btn btns dis a-c j-c" @click="querySearch">
  39. 确定
  40. </view>
  41. </view>
  42. </view>
  43. </uni-dropdown-item>
  44. <uni-dropdown-item title="默认排序">
  45. <view class="slotArea">
  46. <view class="sort">
  47. <view class="item dis a-c " @click="sortItem(item.value)"
  48. v-for="(item, index) in sortOrderOptions" :key="index">
  49. <text class="text" :class="{ 'sort-active': item.value === queryInfo.sortType }">{{
  50. item.label }}</text>
  51. <view class="slice dis a-c j-c " v-if="item.value === queryInfo.sortType">
  52. <u-icon name="checkmark" color="#333" size="11" :bold="true"></u-icon>
  53. </view>
  54. </view>
  55. </view>
  56. </view>
  57. </uni-dropdown-item>
  58. </uni-dropdown>
  59. <view class="tabView">
  60. <u-tabs :list="tabsList" @click="tabClick" :current="statusCurrent" :scrollable="true" lineWidth="32"
  61. :activeStyle="{ color: '#333', fontWeight: 'bold', fontSize: '30rpx' }"
  62. :inactiveStyle="{ color: '#999', fontSize: '30rpx' }" :itemStyle="{ height: '48rpx' }">
  63. <view slot="right" class="moreFilters dis a-c j-c" @tap="toggleFilterPanel">
  64. <text>更多</text>
  65. <u-icon name="list" size="21" color="#999"></u-icon>
  66. </view>
  67. </u-tabs>
  68. </view>
  69. <!-- 下拉筛选内容 -->
  70. <view class="equity-dropdown-content" :class="{ 'show': showFilterPanel }">
  71. <view class="p-3" style="position: relative;">
  72. <!-- 筛选条件 -->
  73. <view class="overflow-content">
  74. <view class="filterCriteria-item mb-3" v-for="(item, index) in tabsList" :key="index">
  75. <view class="header dis a-c ">
  76. <image src="/static/icon/equity/Tabler.png" mode=""></image>
  77. <text class="title">{{ item.name }}</text>
  78. </view>
  79. <view class="content">
  80. <view class="options dis a-c f-wrap mt-3" :class="{ 'collapsed': !item.isExpanded }">
  81. <view class="options-card dis a-c j-c" :class="childrenitem.active ? 'active' : ''"
  82. v-for="(childrenitem, childrenindex) in item.children" :key="childrenindex"
  83. @click="filterOptionClick(childrenitem)">
  84. {{ childrenitem.name }}
  85. </view>
  86. </view>
  87. <view class="Collapse dis a-c j-c" @click="toggleExpand(item)">
  88. <image src="/static/icon/equity/Vector.png" mode=""
  89. :style="{ transform: `rotate(${item.isExpanded ? 180 : 0}deg)` }"></image>
  90. </view>
  91. </view>
  92. </view>
  93. </view>
  94. <view class="backgroundBlur"></view>
  95. </view>
  96. <view class="dropdown-footer">
  97. <view class="btn btns dis a-c j-c" @click="confirmFilter">
  98. 确认
  99. </view>
  100. </view>
  101. </view>
  102. <!-- 下拉遮罩 -->
  103. <view class="overlay-mask" :class="{ 'show': showFilterPanel }" @click="closeFilterPanel"></view>
  104. </u-sticky>
  105. <!-- 内容 -->
  106. <view class="content-body">
  107. <!-- 权益列表 -->
  108. <view class="view-card dis f-c " v-for="(item, index) in privilegeItem" :key="index"
  109. v-if="privilegeItem.length">
  110. <!-- 权益信息 -->
  111. <view class="dis view-header" @click="rightsDetails(item)">
  112. <!-- 图片 -->
  113. <image class="image" :src="item.rightsPicture" mode=""></image>
  114. <view class="content dis f-c j-s">
  115. <u--text :lines="1" :text="item.rightsName" color="#333" size="16" :bold="true"
  116. style="line-height: 1;flex:0 auto;"></u--text>
  117. <view class="sum dis a-c ">
  118. <!-- 市场价/ 券数量 -->
  119. <text class="marketPrice">市场价 {{ item.marketPrice }}</text>
  120. <u-number-box v-model="item.rightsCount" :min="0" style="margin-left: auto;"
  121. @change="val => onRightsCountChange(val, index, 'privilegeItem', 'contractRate')"
  122. :asyncChange="true">
  123. <view slot="minus" class="numberBoxMinus dis a-c j-c ">
  124. <u-icon name="minus" size="12" color="#333" bold></u-icon>
  125. </view>
  126. <text slot="input" class="numberBoxInput">
  127. {{ item.rightsCount }}
  128. </text>
  129. <view slot="plus" class="numberBoxPlus dis a-c j-c ">
  130. <u-icon name="plus" color="#333" size="12" bold></u-icon>
  131. </view>
  132. </u-number-box>
  133. </view>
  134. <view class=" dis a-c j-s ">
  135. <text class="plice">¥{{ item.contractRate }}</text>
  136. </view>
  137. </view>
  138. </view>
  139. </view>
  140. </view>
  141. <u-empty v-if="privilegeItem.length == 0" mode="car" icon="/static/image/Empty1.png" text="没有可用的权益券,换个地区试试~"
  142. width="120" height="120">
  143. </u-empty>
  144. <!-- 底部样式 -->
  145. <view class="footer dis a-c">
  146. <!-- 图标 -->
  147. <view class="icon-view dis f-c a-c ">
  148. <view class="">
  149. <image src="/static/icon/balance/balance.png" mode=""></image>
  150. <u-badge numberType="overflow" :max="99" :value="selectedCount" :absolute="true" color="#fff"
  151. bgColor="#FF4545" :offset="[-5, -5]" style="font-size: 18rpx;"></u-badge>
  152. </view>
  153. <text>已选</text>
  154. </view>
  155. <!-- 价格 -->
  156. <view class="dis f-c a-start">
  157. <view class="price">
  158. <text>¥</text>
  159. <text>{{ totalPriceCount }}</text>
  160. </view>
  161. <text class="marketPrice">市场价:{{ totalMarketPriceCount }}</text>
  162. </view>
  163. <view class="footer-btn" @click="userRightsSubmit">
  164. 立即发放
  165. </view>
  166. </view>
  167. <!-- 省市区组件 -->
  168. <uni-areaCascadePicker :show="addressPickershow" @confirm="addressConfirm" @close="areaCascadeClose"
  169. @cancel="addressPickershow = false"></uni-areaCascadePicker>
  170. <!-- 自定义加载动画 -->
  171. <u-overlay :show="loadingShow" style="background-color: rgba(255, 255, 255, 0.6);">
  172. <view class="dis f-c a-c j-c " style="height: 100%;">
  173. <u-loading-icon></u-loading-icon>
  174. <text style="color: #909399;" class="mt-1">{{ loadingText }}</text>
  175. </view>
  176. </u-overlay>
  177. </view>
  178. </template>
  179. <script>
  180. import LocationService from '@/utils/location';
  181. import Decimal from 'decimal.js';
  182. export default {
  183. data() {
  184. return {
  185. availableAmount: 0, //可用金额
  186. loadingShow: true, //加载
  187. loadingText: '加载中', //加载提示文字
  188. vehicleTaxIsExpanded: false, //明细 展开收起
  189. // 位置信息
  190. location: {
  191. cityName: "",
  192. },
  193. privilegeItem: [], //权益单品列表
  194. // 页面初始化查询信息
  195. queryInfo: {
  196. countryAll: "", //省市区
  197. minPrice: 0,
  198. maxPrice: 1000,
  199. sortType: 0, //排序 0 默认 1低价 2高价
  200. classifyList: [],
  201. pageNo: 1,
  202. pageSize: 20,
  203. },
  204. addressPickershow: false, //省市区组件
  205. mask: true, //点遮罩关闭
  206. borderBottom: true,
  207. activeColor: '#333', //下拉菜单选中激活项
  208. doubleResult: null,
  209. singleResult: null,
  210. statusCurrent: 0, //状态tabs切换
  211. showFilterPanel: false, //更多筛选面板显示控制
  212. // 筛选选项
  213. filterOptions: [{
  214. label: '选项1',
  215. value: 1,
  216. active: false
  217. },
  218. {
  219. label: '选项2',
  220. value: 2,
  221. active: false
  222. },
  223. {
  224. label: '选项3',
  225. value: 3,
  226. active: false
  227. },
  228. {
  229. label: '选项4',
  230. value: 4,
  231. active: false
  232. },
  233. ],
  234. // 分类tab列表
  235. tabsList: [],
  236. // 排序
  237. sortOrderOptions: [{
  238. label: '默认排序',
  239. value: 0,
  240. },
  241. {
  242. label: '低价优先',
  243. value: 1,
  244. },
  245. {
  246. label: '高价优先',
  247. value: 2,
  248. }
  249. ],
  250. priceRangeName: "", //区间选中
  251. // 价格区间列表
  252. priceRangeOptions: [{
  253. label: "100元以下",
  254. value: [0, 100]
  255. },
  256. {
  257. label: "100-200元",
  258. value: [100, 200]
  259. },
  260. {
  261. label: "200-300元",
  262. value: [200, 300]
  263. },
  264. {
  265. label: "300-400元",
  266. value: [300, 400]
  267. },
  268. {
  269. label: "400-500元",
  270. value: [400, 500]
  271. },
  272. {
  273. label: "500-1000元",
  274. value: [500, 1000]
  275. },
  276. ],
  277. }
  278. },
  279. onShow() {
  280. },
  281. async onLoad(options) {
  282. this.loadingShow = true;
  283. try {
  284. if (options) {
  285. this.availableAmount = options.availableAmount;
  286. }
  287. // 获取定位城市信息
  288. const locationData = await LocationService.initLocation();
  289. console.log(locationData);
  290. if (locationData.provinceCode) {
  291. this.queryInfo.countryAll =
  292. `${locationData.provinceCode},${locationData.cityCode},${locationData.districtCode}`; //
  293. this.location.cityName =
  294. `${locationData.provinceName}-${locationData.cityName}-${locationData.districtName}`;
  295. }
  296. await this.getequityClassification(); //权益分类
  297. await this.getprivilegeItem(); //权益单品列表
  298. console.log();
  299. this.loadingShow = false;
  300. } catch (error) {
  301. this.loadingShow = false;
  302. }
  303. },
  304. computed: {
  305. selectedCount() {
  306. const total = this.privilegeItem.reduce(
  307. (sum, item) => sum.plus(new Decimal(item.rightsCount)),
  308. new Decimal(0)
  309. );
  310. const sum = new Decimal(total);
  311. return sum.toString();
  312. },
  313. //选中售价总和
  314. totalPriceCount() {
  315. const total = this.privilegeItem.reduce(
  316. (sum, item) => {
  317. // 计算当前项的 packagePrice * quantity(高精度乘法)
  318. const itemTotal = new Decimal(item.contractRate).times(new Decimal(item.rightsCount));
  319. // 累加到总和
  320. return sum.plus(itemTotal);
  321. },
  322. new Decimal(0) // 初始值
  323. );
  324. const sum = new Decimal(total);
  325. return sum.toString(); // 返回字符串
  326. },
  327. //选中市场价总和
  328. totalMarketPriceCount() {
  329. const total = this.privilegeItem.reduce(
  330. (sum, item) => {
  331. // 计算当前项的 packagePrice * quantity(高精度乘法)
  332. const itemTotal = new Decimal(item.marketPrice).times(new Decimal(item.rightsCount));
  333. // 累加到总和
  334. return sum.plus(itemTotal);
  335. },
  336. new Decimal(0) // 初始值
  337. );
  338. const sum = new Decimal(total);
  339. return sum.toString(); // 返回字符串
  340. }
  341. },
  342. methods: {
  343. //权益商品详情
  344. async rightsDetails(item) {
  345. await this.$http.post('/rightsGrant/get/product', {
  346. rightsId: item.id
  347. }).then(res => {
  348. if (res.code == 200) {
  349. uni.navigateTo({
  350. url: '/pages/reward/locationFilter?productId=' + res.data[0]
  351. .productId,
  352. })
  353. }
  354. });
  355. },
  356. // 获取权益分类
  357. async getequityClassification() {
  358. // 递归添加 active 字段
  359. const addActiveField = (data) => {
  360. if (!data || !Array.isArray(data)) return;
  361. data.forEach(item => {
  362. item.active = false;
  363. item.isExpanded = false;
  364. if (item.children && Array.isArray(item.children)) {
  365. addActiveField(item.children);
  366. }
  367. });
  368. };
  369. await this.$http.post('/rightsGrant/get/category').then(res => {
  370. if (res.code == 200) {
  371. addActiveField(res.data);
  372. this.tabsList = res.data;
  373. this.queryInfo.classifyList = [this.tabsList[0].id];
  374. }
  375. });
  376. },
  377. // 权益数量变化监听
  378. onRightsCountChange(e, index, name, field) {
  379. // 获取当前项
  380. const item = this[name][index];
  381. // 获取当前数量和新数量
  382. const currentCount = item.rightsCount;
  383. const newCount = e.value;
  384. // 计算价格
  385. const price = parseFloat(item[field]);
  386. // 计算当前总价
  387. const currentTotalPrice = parseFloat(this.totalPriceCount);
  388. // 计算数量变化和价格变化
  389. const countChange = newCount - currentCount;
  390. const priceChange = countChange * price;
  391. // 计算新总价
  392. const newTotalPrice = currentTotalPrice + priceChange;
  393. // 如果是增加数量,检查是否超过可用金额
  394. if (countChange > 0 && newTotalPrice > this.availableAmount) {
  395. uni.showToast({
  396. title: `权益总价不能超过可用金额${this.availableAmount}元`,
  397. icon: 'none'
  398. });
  399. } else {
  400. // 无论是减少数量还是增加数量且未超过限制,都允许更新
  401. item.rightsCount = newCount;
  402. }
  403. },
  404. // 确认选择
  405. async userRightsSubmit() {
  406. // 验证是否有选择权益
  407. if (parseInt(this.selectedCount) === 0) {
  408. uni.showToast({
  409. title: '请至少选择一项权益',
  410. icon: 'none'
  411. });
  412. return;
  413. }
  414. // 收集选择的权益单品
  415. const selectedItems = this.privilegeItem
  416. .filter(item => item.rightsCount > 0)
  417. let pages = getCurrentPages(); //获取所有页面栈实例列表
  418. let prevPage = pages[pages.length - 2]; //上一页页面实例
  419. console.log(selectedItems);
  420. prevPage.$vm.insOrderRightsList = selectedItems; //选中权益列表
  421. uni.navigateBack({ //uni.navigateTo跳转的返回,默认1为返回上一级
  422. delta: 1
  423. });
  424. },
  425. //获取权益单品列表
  426. async getprivilegeItem() {
  427. let res = await this.$http.post('/rightsGrant/rights/list', this.queryInfo);
  428. if (res.code == 200) {
  429. this.privilegeItem = res.data.records;
  430. }
  431. },
  432. // 省市区选择回调
  433. async addressConfirm(e) {
  434. console.log(e);
  435. this.queryInfo.countryAll = e.codes.join(',') || "";
  436. this.location.cityName = e.fullAddress;
  437. this.addressPickershow = false;
  438. this.$refs.uDropdown.close();
  439. await this.getprivilegeItem();
  440. },
  441. // 查看明细
  442. detailClick() {
  443. },
  444. async querySearch() {
  445. this.$refs.uDropdown.close();
  446. await this.getprivilegeItem();
  447. },
  448. //清空价格区间
  449. async clearForm() {
  450. this.queryInfo.minPrice = 0;
  451. this.queryInfo.maxPrice = 1000;
  452. this.priceRangeName = "";
  453. this.$refs.uDropdown.close();
  454. await this.getprivilegeItem();
  455. },
  456. filterCriteriaClick(item) {
  457. this.priceRangeName = item.label;
  458. this.queryInfo.minPrice = item.value[0];
  459. this.queryInfo.maxPrice = item.value[1];
  460. },
  461. //排序选择
  462. async sortItem(value) {
  463. this.queryInfo.sortType = value;
  464. this.$refs.uDropdown.close();
  465. await this.getprivilegeItem();
  466. },
  467. // 价格区间选择
  468. onChange(values) {
  469. this.queryInfo.minPrice = values[0];
  470. this.queryInfo.maxPrice = values[1];
  471. },
  472. // 下拉菜单选项事件
  473. menuClick(value) {
  474. if (value == 0) {
  475. this.addressPickershow = true;
  476. }
  477. },
  478. onEnd(event) {
  479. console.log('最终选择:', event.values);
  480. },
  481. areaCascadeClose() {
  482. this.addressPickershow = false;
  483. this.$refs.uDropdown.close();
  484. },
  485. // tabs状态切换
  486. async tabClick(e) {
  487. console.log(e);
  488. this.statusCurrent = e.index;
  489. this.queryInfo.classifyList = [e.id];
  490. await this.getprivilegeItem();
  491. if (this.scrollTop > 0) {
  492. uni.pageScrollTo({
  493. selector: 'content-body', // 滚动到顶部
  494. duration: 100, // 动画时长(ms)
  495. });
  496. }
  497. },
  498. // 切换筛选面板
  499. toggleFilterPanel() {
  500. this.showFilterPanel = !this.showFilterPanel;
  501. },
  502. // 关闭筛选面板
  503. closeFilterPanel() {
  504. this.showFilterPanel = false;
  505. },
  506. // 筛选选项点击
  507. filterOptionClick(item) {
  508. item.active = !item.active;
  509. if (item.active) {
  510. // 选中:添加到 classifyList
  511. if (!this.queryInfo.classifyList.includes(item.id)) {
  512. this.queryInfo.classifyList.push(item.id);
  513. }
  514. } else {
  515. // 取消选中:从 classifyList 中删除
  516. const index = this.queryInfo.classifyList.indexOf(item.id);
  517. if (index > -1) {
  518. this.queryInfo.classifyList.splice(index, 1);
  519. }
  520. }
  521. },
  522. // 展开收起
  523. toggleExpand(item) {
  524. console.log(item);
  525. item.isExpanded = !item.isExpanded;
  526. },
  527. // 重置筛选
  528. resetFilter() {
  529. this.filterOptions.forEach(item => {
  530. item.active = false;
  531. });
  532. this.$u.toast('已重置筛选条件');
  533. },
  534. // 确认筛选
  535. async confirmFilter() {
  536. // 获取选中的筛选项
  537. const selectedFilters = this.filterOptions.filter(item => item.active);
  538. console.log('选中的筛选条件:', selectedFilters);
  539. this.closeFilterPanel();
  540. await this.getprivilegeItem();
  541. this.$u.toast('筛选成功');
  542. },
  543. }
  544. }
  545. </script>
  546. <style lang="scss" scoped>
  547. page {
  548. background-color: #F8F8F8;
  549. height: 100vh;
  550. }
  551. .container {
  552. padding: 20rpx;
  553. }
  554. .dropdown-title {
  555. font-size: 32rpx;
  556. color: #333;
  557. }
  558. .reward-tabs {
  559. margin-right: 48rpx;
  560. flex: 1;
  561. }
  562. /* 自定义tab滑块样式 */
  563. ::v-deep .u-tabs__wrapper__nav__line {
  564. background-color: transparent !important;
  565. font-size: 30px;
  566. }
  567. ::v-deep .u-tabs__wrapper__nav__item__text {
  568. font-size: 32rpx;
  569. }
  570. /* 自定义tab滑块样式 */
  571. ::v-deep .u-tabs__wrapper__nav__line {
  572. background: linear-gradient(90deg, #FDE935 10%, rgba(253, 233, 53, 0.1) 100%) !important;
  573. border-radius: 6rpx;
  574. }
  575. .slotArea {
  576. background-color: #FFFFFF;
  577. border-top: 1rpx solid #eee;
  578. .slider-header {
  579. text:first-child {
  580. font-size: 30rpx;
  581. color: #333;
  582. font-weight: bold;
  583. }
  584. text:last-child {
  585. font-size: 28rpx;
  586. color: #333;
  587. }
  588. }
  589. .slider-btn {
  590. background: #FFFFFF;
  591. border-radius: 0rpx 0rpx 20rpx 20rpx;
  592. border-top: 1rpx solid #EEEEEE;
  593. padding: 30rpx 44rpx;
  594. box-sizing: border-box;
  595. .btn {
  596. padding: 18rpx 30rpx;
  597. box-sizing: border-box;
  598. width: 50%;
  599. border-radius: 50rpx 50rpx 50rpx 50rpx;
  600. border: 1rpx solid #FDE935;
  601. font-size: 30rpx;
  602. color: #333;
  603. }
  604. .btns {
  605. width: 50%;
  606. background: #FDE935;
  607. border-radius: 50rpx 50rpx 50rpx 50rpx;
  608. }
  609. }
  610. .sort {
  611. padding: 30rpx;
  612. box-sizing: border-box;
  613. display: grid;
  614. grid-template-columns: repeat(1, 1fr);
  615. grid-template-rows: auto;
  616. row-gap: 30rpx;
  617. .item {
  618. text {
  619. font-size: 30rpx;
  620. color: #333;
  621. }
  622. .slice {
  623. margin-left: auto;
  624. width: 32rpx;
  625. height: 32rpx;
  626. background: #FDE935;
  627. border-radius: 20rpx 20rpx 20rpx 20rpx;
  628. }
  629. }
  630. .sort-active {
  631. font-weight: bold;
  632. }
  633. }
  634. .item-box {
  635. margin-bottom: 50rpx;
  636. display: flex;
  637. flex-wrap: wrap;
  638. justify-content: space-between;
  639. .item {
  640. border: 1px solid #f2f2f2;
  641. color: #333;
  642. padding: 8rpx 40rpx;
  643. border-radius: 100rpx;
  644. margin-top: 30rpx;
  645. }
  646. .active {
  647. color: #FFFFFF;
  648. background-color: #000;
  649. }
  650. }
  651. .options {
  652. display: grid;
  653. /* 启用网格布局 */
  654. grid-template-columns: repeat(3, 1fr);
  655. /* 3 列,每列等宽 */
  656. grid-template-rows: auto;
  657. /* 行高自适应 */
  658. row-gap: 30rpx;
  659. /* 只设置行间距(上下) */
  660. column-gap: 20rpx;
  661. /* 列间距设为 0(可选) */
  662. }
  663. .options-card {
  664. padding: 11rpx 24rpx;
  665. box-sizing: border-box;
  666. border-radius: 4rpx 4rpx 4rpx 4rpx;
  667. border: 1rpx solid #EEEEEE;
  668. font-size: 28rpx;
  669. color: #666;
  670. }
  671. .active {
  672. background-color: rgba(253, 233, 53, 0.2);
  673. border: 1rpx solid #FDE935;
  674. color: #333;
  675. }
  676. }
  677. .content-body {
  678. padding: 20rpx 30rpx 166rpx;
  679. box-sizing: border-box;
  680. position: relative;
  681. .view-card {
  682. background-color: #fff;
  683. border-radius: 10rpx;
  684. margin-bottom: 20rpx;
  685. .view-header {
  686. padding: 25rpx 30rpx;
  687. box-sizing: border-box;
  688. .image {
  689. width: 136rpx;
  690. height: 136rpx;
  691. border-radius: 10rpx;
  692. flex-shrink: 0;
  693. margin-right: 20rpx;
  694. }
  695. .content {
  696. flex: 1;
  697. min-width: 0;
  698. line-height: 1;
  699. .sum {
  700. text {
  701. font-size: 24rpx;
  702. color: #666;
  703. }
  704. }
  705. .plice {
  706. font-size: 30rpx;
  707. color: #FF540A;
  708. font-weight: bold;
  709. line-height: 1;
  710. }
  711. .Detail {
  712. font-size: 26rpx;
  713. color: #FFAC1D;
  714. line-height: 1.4;
  715. text {
  716. margin-right: 5rpx;
  717. }
  718. }
  719. }
  720. }
  721. .Detail-list {
  722. padding: 0 30rpx 25rpx;
  723. box-sizing: border-box;
  724. .Detail-header {
  725. width: 100%;
  726. height: 30rpx;
  727. background: linear-gradient(0deg, #FFFCEA 0%, #FFFFFF 100%);
  728. border-radius: 6rpx 6rpx 0rpx 0rpx;
  729. border-top: 1rpx solid #FFE1A4;
  730. }
  731. .Detail-footer {
  732. width: 100%;
  733. height: 30rpx;
  734. background: linear-gradient(0deg, #FFFCEA 0%, #FFFFFF 100%);
  735. border-radius: 6rpx 6rpx 0rpx 0rpx;
  736. border-bottom: 1rpx solid #FFE1A4;
  737. }
  738. .view {
  739. .view-header {
  740. padding: 0 20rpx 20rpx;
  741. box-sizing: border-box;
  742. border-bottom: 1rpx solid #eee;
  743. margin: 20rpx 0;
  744. }
  745. .view-header:last-child {
  746. border-bottom: none;
  747. }
  748. }
  749. }
  750. }
  751. }
  752. // 步进器自定义样式
  753. .numberBoxMinus {
  754. width: 32rpx;
  755. height: 32rpx;
  756. border-radius: 20rpx 20rpx 20rpx 20rpx;
  757. border: 1rpx solid #FDE935;
  758. }
  759. .numberBoxInput {
  760. font-size: 30rpx;
  761. color: #333;
  762. padding: 0 20rpx;
  763. box-sizing: border-box;
  764. text-align: center;
  765. }
  766. .numberBoxPlus {
  767. width: 32rpx;
  768. height: 32rpx;
  769. border-radius: 20rpx 20rpx 20rpx 20rpx;
  770. background-color: #FDE935;
  771. border: 1rpx solid #FDE935;
  772. }
  773. .footer {
  774. position: fixed;
  775. bottom: 0;
  776. left: 0;
  777. right: 0;
  778. padding: 25rpx 30rpx 55rpx;
  779. box-sizing: border-box;
  780. background: linear-gradient(0deg, #FFFFFF 0%, rgba(255, 254, 245, 0.7) 100%);
  781. border-radius: 0rpx 0rpx 0rpx 0rpx;
  782. backdrop-filter: blur(12rpx);
  783. .icon-view {
  784. margin-right: 30rpx;
  785. >view {
  786. position: relative;
  787. image {
  788. width: 48rpx;
  789. height: 48rpx;
  790. }
  791. }
  792. text {
  793. font-size: 20rpx;
  794. color: #333;
  795. }
  796. }
  797. .price {
  798. text:nth-child(1) {
  799. font-size: 28rpx;
  800. color: #FF540A;
  801. }
  802. text:nth-child(2) {
  803. font-size: 42rpx;
  804. color: #FF540A;
  805. }
  806. }
  807. .marketPrice {
  808. font-size: 20rpx;
  809. color: #999;
  810. letter-spacing: 1rpx;
  811. margin-left: 4rpx;
  812. }
  813. .footer-btn {
  814. padding: 20rpx 68rpx;
  815. box-sizing: border-box;
  816. background: #FDE935;
  817. border-radius: 58rpx 58rpx 58rpx 58rpx;
  818. font-size: 36rpx;
  819. color: #1F1F1F;
  820. font-weight: bold;
  821. margin-left: auto;
  822. }
  823. }
  824. .tabView {
  825. padding: 13rpx 30rpx;
  826. box-sizing: border-box;
  827. background-color: #fff;
  828. }
  829. .u-empty {
  830. position: absolute;
  831. top: 50%;
  832. left: 50%;
  833. transform: translate(-50%, -50%);
  834. /* 反向偏移自身宽高的50% */
  835. }
  836. .moreFilters {
  837. font-size: 30rpx;
  838. color: #999;
  839. }
  840. /* 下拉筛选内容 */
  841. .equity-dropdown-content {
  842. position: fixed;
  843. top: 182rpx;
  844. left: 0;
  845. right: 0;
  846. height: 0px;
  847. background: white;
  848. overflow: hidden;
  849. z-index: 100;
  850. transition: height 0.4s ease;
  851. border-radius: 0 0 20rpx 20rpx;
  852. .overflow-content {
  853. overflow-y: auto;
  854. height: 926rpx;
  855. padding-bottom: 45rpx;
  856. box-sizing: border-box;
  857. }
  858. .backgroundBlur {
  859. position: absolute;
  860. bottom: 0;
  861. left: 0;
  862. right: 0;
  863. width: 100%;
  864. height: 115rpx;
  865. background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 40%, #FFFFFF 100%);
  866. backdrop-filter: blur(12rpx);
  867. -webkit-backdrop-filter: blur(12rpx);
  868. mask-image: linear-gradient(to top,
  869. rgba(0, 0, 0, 1) 0%,
  870. rgba(0, 0, 0, 0.6) 60%,
  871. rgba(0, 0, 0, 0) 100%);
  872. -webkit-mask-image: linear-gradient(to top,
  873. rgba(0, 0, 0, 1) 0%,
  874. rgba(0, 0, 0, 0.6) 60%,
  875. rgba(0, 0, 0, 0) 100%);
  876. }
  877. // 筛选条件
  878. .filterCriteria-item {
  879. >.header {
  880. image {
  881. width: 32rpx;
  882. height: 32rpx;
  883. margin-right: 6rpx;
  884. }
  885. .title {
  886. flex: 1;
  887. font-size: 30rpx;
  888. color: #333;
  889. font-weight: bold;
  890. }
  891. }
  892. .content {
  893. display: flex;
  894. align-items: start;
  895. justify-content: space-between;
  896. .options {
  897. display: grid;
  898. grid-template-columns: repeat(3, 1fr);
  899. grid-template-rows: auto;
  900. row-gap: 30rpx;
  901. column-gap: 20rpx;
  902. transition: all 0.3s ease; // 添加这行
  903. &.collapsed {
  904. // 添加这个嵌套样式
  905. overflow: hidden;
  906. max-height: 160rpx; // 两行的高度,可以根据实际效果调整
  907. }
  908. >.options-card {
  909. padding: 11rpx 40rpx;
  910. box-sizing: border-box;
  911. background: #F5F5F5;
  912. border-radius: 4rpx;
  913. font-size: 28rpx;
  914. color: #333;
  915. }
  916. .active {
  917. background: #FDE935;
  918. }
  919. }
  920. .Collapse {
  921. margin-top: 30rpx;
  922. width: 50rpx;
  923. height: 50rpx;
  924. background: #F5F5F5;
  925. border-radius: 50%;
  926. image {
  927. width: 20rpx;
  928. height: 12rpx;
  929. }
  930. }
  931. }
  932. }
  933. // 底部按钮
  934. .footer {
  935. padding: 30rpx 0;
  936. border-top: 1rpx solid #eee;
  937. .btn {
  938. padding: 18rpx 30rpx;
  939. box-sizing: border-box;
  940. width: 50%;
  941. border-radius: 50rpx;
  942. border: 1rpx solid #FDE935;
  943. font-size: 30rpx;
  944. color: #333;
  945. }
  946. .btns {
  947. width: 50%;
  948. background: #FDE935;
  949. border-radius: 50rpx;
  950. }
  951. }
  952. }
  953. .equity-dropdown-content.show {
  954. opacity: 1;
  955. height: 1126rpx;
  956. overflow: auto;
  957. }
  958. /* 下拉区域底部按钮 */
  959. .dropdown-footer {
  960. position: absolute;
  961. bottom: 0;
  962. left: 0;
  963. right: 0;
  964. padding: 30rpx 44rpx;
  965. box-sizing: border-box;
  966. border-top: 1rpx solid #eee;
  967. background-color: #fff;
  968. display: flex;
  969. align-items: center;
  970. justify-content: space-between;
  971. .btn {
  972. padding: 18rpx 30rpx;
  973. box-sizing: border-box;
  974. width: 100%;
  975. border-radius: 50rpx;
  976. border: 1rpx solid #FDE935;
  977. font-size: 30rpx;
  978. color: #1f1f1f;
  979. background: #FDE935;
  980. }
  981. }
  982. /* 遮罩层 */
  983. .overlay-mask {
  984. position: fixed;
  985. top: 0;
  986. left: 0;
  987. right: 0;
  988. bottom: 0;
  989. background: rgba(0, 0, 0, 0.6);
  990. display: none;
  991. z-index: 99;
  992. }
  993. .overlay-mask.show {
  994. display: block;
  995. }
  996. </style>