爱简收旧衣按件回收前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1419 lines
42 KiB

5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
4 months ago
4 months ago
5 months ago
4 months ago
4 months ago
4 months ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
4 months ago
5 months ago
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
  1. <template>
  2. <view class="inspect-container">
  3. <!-- 顶部导航栏 -->
  4. <view class="nav-bar">
  5. <view class="back" @tap="goBack">
  6. <uni-icons type="left" size="20" color="#222" />
  7. </view>
  8. <text class="nav-title">步骤一数量确认</text>
  9. <view class="nav-icons">
  10. <uni-icons type="scan" size="24" color="#222" />
  11. </view>
  12. </view>
  13. <view class="main-content">
  14. <!-- 左侧分类导航 -->
  15. <view class="category-nav">
  16. <view v-for="(cat, idx) in categories" :key="cat.title"
  17. :class="['category-item', { active: idx === currentCategory }]" @tap="switchCategory(idx)">
  18. <text>{{ cat.title }}</text>
  19. <view v-if="cat.badge" class="category-badge">{{ cat.badge }}</view>
  20. </view>
  21. </view>
  22. <!-- 右侧商品卡片区 -->
  23. <scroll-view class="goods-list" scroll-y @scrolltolower="loadMoreGoods">
  24. <view v-for="(item, idx) in currentGoods" :key="item.id" class="goods-card">
  25. <view class="goods-header">
  26. <image :src="item.image" class="goods-img" />
  27. <view class="goods-info">
  28. <view class="goods-title-row">
  29. <text class="goods-name">{{ item.name }}</text>
  30. <text class="goods-price">
  31. {{ formatPrice(item) }}
  32. <text class="goods-unit" v-if="item.unit">/{{item.unit}}</text>
  33. </text>
  34. </view>
  35. <text class="goods-desc">{{ item.desc }}</text>
  36. </view>
  37. </view>
  38. <view class="goods-row">
  39. <text class="row-label">合格数量</text>
  40. <view class="num-ctrl">
  41. <button class="num-btn" @tap="changeNum(item, 'qualified', -1)">-</button>
  42. <text class="num">{{ item.qualified }}</text>
  43. <button
  44. class="num-btn"
  45. @tap="changeNum(item, 'qualified', 1)"
  46. >+</button>
  47. </view>
  48. </view>
  49. <view class="goods-row">
  50. <text class="row-label">总金额</text>
  51. <input class="amount-input" :value="getInspectPrice(item)" @input="updateInspectPrice(item, $event)" placeholder="请输入金额" :disabled="!item.qualified || item.qualified === 0" />
  52. </view>
  53. </view>
  54. <view v-if="loadingMore" class="loading-more">加载中...</view>
  55. <view v-else-if="finished" class="loading-more">没有更多了</view>
  56. </scroll-view>
  57. </view>
  58. <!-- 底部操作按钮 -->
  59. <view class="footer-btns">
  60. <button class="btn-outline" @tap="goBack">返回订单详情</button>
  61. <button class="btn-main" @tap="goNext">下一步</button>
  62. </view>
  63. <!-- 品牌索引弹窗 -->
  64. <view v-if="showBrandPopup" class="brand-popup-mask">
  65. <view class="brand-popup">
  66. <view class="brand-popup-header">
  67. <text class="brand-popup-close" @click="closeBrandPopup">关闭</text>
  68. <text class="brand-popup-title">可回收的品牌</text>
  69. </view>
  70. <view class="brand-popup-search">
  71. <input class="brand-search-input" v-model="brandSearch" placeholder="请输入要查询的内容" @input="onBrandSearchInput" />
  72. </view>
  73. <scroll-view class="brand-popup-list" scroll-y>
  74. <view v-for="letter in brandIndexList" :key="letter" :id="'brand-letter-' + letter">
  75. <view class="brand-letter" :style="letter === '#' ? 'color:red' : ''">{{letter}}</view>
  76. <view v-for="brand in brandList.filter(b => b.letter === letter)" :key="brand.name" class="brand-item" @click="openBrandConfirm(brand)">
  77. <image :src="brand.logo" class="brand-logo" mode="aspectFit" />
  78. <text class="brand-name">{{brand.name}}</text>
  79. </view>
  80. </view>
  81. </scroll-view>
  82. </view>
  83. </view>
  84. <!-- 品牌确认弹窗 -->
  85. <view v-if="showBrandConfirm" class="brand-confirm-mask" @click.self="closeBrandConfirm">
  86. <view class="brand-confirm-popup">
  87. <view class="brand-confirm-title">品牌确认提示</view>
  88. <view class="brand-confirm-logo-wrap">
  89. <image :src="brandConfirmInfo.logo" class="brand-confirm-logo" mode="aspectFit" />
  90. </view>
  91. <view class="brand-confirm-name">{{ brandConfirmInfo.name }}</view>
  92. <view class="brand-confirm-desc">请确认所选品牌是否与实物品牌信息一致否则将无法进行回收</view>
  93. <view class="brand-confirm-btn-row">
  94. <button class="brand-confirm-btn retry" @click="closeBrandConfirm">重新选择</button>
  95. <button class="brand-confirm-btn confirm" @click="confirmBrand">确认一致</button>
  96. </view>
  97. </view>
  98. </view>
  99. </view>
  100. </template>
  101. <script>
  102. export default {
  103. data() {
  104. return {
  105. statusBarHeight: 0,
  106. currentCategory: 0,
  107. orderId: '',
  108. order: null, // 订单数据
  109. currentGoods: [], // 当前显示的商品列表
  110. inspectResult: {}, // 质检结果对象,按照新的数据格式
  111. allProducts: {}, // { [categoryId]: [商品数组] }
  112. allProductsPage: {}, // { [categoryId]: 当前已加载页码 }
  113. allProductsTotal: {}, // { [categoryId]: 总数 }
  114. pageSize: 10,
  115. loadingMore: false,
  116. finished: false,
  117. // 品牌选择相关
  118. showBrandPopup: false,
  119. brandList: [],
  120. brandSearch: '',
  121. currentProductId: null,
  122. pendingBrandIndex: null,
  123. brandConfirmInfo: {},
  124. showBrandConfirm: false,
  125. searchTimer: null,
  126. // brandIndexList 改为 computed
  127. }
  128. },
  129. computed: {
  130. categories() {
  131. const list = getApp().globalData.pricePreviewList || []
  132. console.log('categories计算 - pricePreviewList:', list.length)
  133. // 显示所有分类,不再根据订单数据筛选
  134. const allCategories = list.filter(item => item.pid === '0').sort((a, b) => a.sort - b.sort)
  135. console.log('categories计算 - allCategories:', allCategories.length)
  136. // 为每个分类计算数量
  137. const categoriesWithCount = allCategories.map(category => {
  138. const count = this.getCategoryItemCountDirect(category.id)
  139. return {
  140. ...category,
  141. badge: count > 0 ? count : null
  142. }
  143. })
  144. // 新增不可回收和质量问题分类
  145. const extra = [
  146. { id: 'unrecyclable', title: '不可回收', badge: this.getUnrecyclableCount() },
  147. { id: 'quality_issue', title: '质量问题', badge: this.getQualityIssueCount() }
  148. ]
  149. const result = [...categoriesWithCount, ...extra]
  150. console.log('categories计算 - 最终结果:', result.map(c => ({ id: c.id, title: c.title, badge: c.badge })))
  151. return result
  152. },
  153. // brandIndexList 改为 computed
  154. brandIndexList() {
  155. // 动态生成品牌索引,包含所有有品牌的首字母和 #
  156. const letters = new Set()
  157. let hasSharp = false
  158. this.brandList.forEach(b => {
  159. if (b.letter && /^[A-Z]$/.test(b.letter)) {
  160. letters.add(b.letter)
  161. } else {
  162. letters.add('#')
  163. hasSharp = true
  164. }
  165. })
  166. const arr = Array.from(letters).filter(l => l !== '#').sort()
  167. if (hasSharp) arr.push('#')
  168. console.log('brandIndexList for render:', arr)
  169. // 如果brandList里有letter为#的品牌但arr没有#,强制返回['#']
  170. if (this.brandList.some(b => b.letter === '#') && !arr.includes('#')) return ['#']
  171. return arr
  172. },
  173. },
  174. methods: {
  175. initInspectResult() {
  176. // 只初始化空的list
  177. this.inspectResult = {
  178. id: this.order ? this.order.id : '',
  179. list: []
  180. }
  181. },
  182. // 获取分类商品数量(直接方法,避免递归)
  183. getCategoryItemCountDirect(categoryId) {
  184. if (categoryId === 'unrecyclable') {
  185. return this.getUnrecyclableCount()
  186. }
  187. if (categoryId === 'quality_issue') {
  188. return this.getQualityIssueCount()
  189. }
  190. let totalCount = 0
  191. if (this.inspectResult.list && this.inspectResult.list.length > 0) {
  192. this.inspectResult.list.forEach(inspectItem => {
  193. if (inspectItem.categoryId === categoryId) {
  194. totalCount += inspectItem.qualifiedNum || 0
  195. }
  196. })
  197. }
  198. return totalCount
  199. },
  200. // 获取当前分类ID(避免递归)
  201. getCurrentCategoryId() {
  202. const list = getApp().globalData.pricePreviewList || []
  203. const allCategories = list.filter(item => item.pid === '0').sort((a, b) => a.sort - b.sort)
  204. const extra = [
  205. { id: 'unrecyclable', title: '不可回收' },
  206. { id: 'quality_issue', title: '质量问题' }
  207. ]
  208. const allCategoriesWithExtra = [...allCategories, ...extra]
  209. return allCategoriesWithExtra[this.currentCategory]?.id
  210. },
  211. // 获取分类商品数量(保持原有方法名兼容性)
  212. getCategoryItemCount(categoryId) {
  213. return this.getCategoryItemCountDirect(categoryId)
  214. },
  215. // 获取不可回收数量
  216. getUnrecyclableCount() {
  217. // 从inspectResult中获取不可回收的数量
  218. const unrecyclableItem = this.inspectResult.list?.find(item => item.id === 'unrecyclable')
  219. return unrecyclableItem ? unrecyclableItem.unrecyclable : 0
  220. },
  221. // 获取质量问题数量
  222. getQualityIssueCount() {
  223. // 从inspectResult中获取质量问题的数量
  224. const qualityIssueItem = this.inspectResult.list?.find(item => item.id === 'quality_issue')
  225. return qualityIssueItem ? qualityIssueItem.noQualifiedNum : 0
  226. },
  227. fetchGoodsList(categoryId, page = 1, callback) {
  228. this.$api('getClassGoodsList', {
  229. classId: categoryId,
  230. pageNo: page,
  231. pageSize: this.pageSize
  232. }, res => {
  233. if (res.code === 200 && res.result && Array.isArray(res.result.records)) {
  234. const oldList = this.allProducts[categoryId] || []
  235. const newList = page === 1 ? res.result.records : oldList.concat(res.result.records)
  236. this.$set(this.allProducts, categoryId, newList)
  237. this.$set(this.allProductsPage, categoryId, page)
  238. this.$set(this.allProductsTotal, categoryId, res.result.total)
  239. this.updateCurrentGoods()
  240. }
  241. if (callback) callback()
  242. })
  243. },
  244. updateCurrentGoods() {
  245. const currentCategoryId = this.categories[this.currentCategory]?.id
  246. // 不可回收分类内容
  247. if (currentCategoryId === 'unrecyclable') {
  248. // 从inspectResult中获取不可回收的数量
  249. const unrecyclableItem = this.inspectResult.list?.find(item => item.id === 'unrecyclable')
  250. const unrecyclableCount = unrecyclableItem ? unrecyclableItem.unrecyclable : 0
  251. this.currentGoods = [{
  252. id: 'unrecyclable-1',
  253. image: '/static/回收/衣物.png',
  254. name: '不可回收品类',
  255. price: '—',
  256. desc: '允许脏破烂,160码以上',
  257. qualified: unrecyclableCount,
  258. amount: '',
  259. originalNum: 0 // 不设置最大数量限制
  260. }]
  261. return
  262. }
  263. // 质量问题分类内容
  264. if (currentCategoryId === 'quality_issue') {
  265. // 从inspectResult中获取质量问题的数量
  266. const qualityIssueItem = this.inspectResult.list?.find(item => item.id === 'quality_issue')
  267. const qualityIssueCount = qualityIssueItem ? qualityIssueItem.noQualifiedNum : 0
  268. this.currentGoods = [{
  269. id: 'quality-issue-1',
  270. image: '/static/回收/衣物.png',
  271. name: '质量问题品类',
  272. price: '—',
  273. desc: '存在质量问题,无法正常回收',
  274. qualified: qualityIssueCount,
  275. amount: '',
  276. originalNum: 0 // 不设置最大数量限制
  277. }]
  278. return
  279. }
  280. // 从API获取的商品数据
  281. const categoryGoods = this.allProducts[currentCategoryId] || []
  282. // 将API商品数据转换为质检页面格式,并合并inspectResult.list中已选状态(shopId和id双向查找)
  283. const goodsList = categoryGoods.map((item, index) => {
  284. // 从订单数据中查找对应的商品
  285. const orderItem = this.getOrderItemByProductId(item.id)
  286. let itemId = item.id
  287. if (orderItem && orderItem.id) {
  288. itemId = orderItem.id
  289. }
  290. const inspectItem = this.inspectResult.list?.find(listItem =>
  291. listItem.shopId == item.id || listItem.shopId == itemId || listItem.id == item.id || listItem.id == itemId
  292. )
  293. return {
  294. id: item.id,
  295. image: item.image || '/static/回收/衣物.png',
  296. name: item.name,
  297. price: item.price || 0,
  298. maxPrice: item.maxPrice || 0,
  299. desc: item.service || '允许脏破烂,160码以上',
  300. qualified: inspectItem ? inspectItem.qualifiedNum : 0,
  301. amount: inspectItem ? inspectItem.price : '', // 只用inspectResult里的金额
  302. originalNum: 0,
  303. estimatedPrice: orderItem ? orderItem.estimatedPrice : 0,
  304. originalId: item.id,
  305. isPin: item.isPin || 'N',
  306. orderItem: orderItem
  307. }
  308. })
  309. this.currentGoods = goodsList
  310. },
  311. // 根据商品ID从订单数据中查找对应商品
  312. getOrderItemByProductId(productId) {
  313. if (!this.order || !this.order.commonOrderList) {
  314. return null
  315. }
  316. // 支持id和shopId双向查找
  317. return this.order.commonOrderList.find(item => item.id == productId || item.shopId == productId)
  318. },
  319. goBack() {
  320. uni.navigateBack()
  321. },
  322. goNext() {
  323. // 检测是否所有商品都已完成质检和填写价格
  324. const validationResult = this.validateInspectData()
  325. if (!validationResult.isValid) {
  326. uni.showToast({
  327. title: validationResult.message,
  328. icon: 'none',
  329. duration: 2000
  330. })
  331. return
  332. }
  333. // 构造传递给步骤二的完整数据
  334. const resultData = {
  335. inspectResult: this.inspectResult,
  336. order: this.order // 同时传递订单信息
  337. }
  338. console.log('resultDataStr:', resultData)
  339. const resultDataStr = encodeURIComponent(JSON.stringify(resultData))
  340. uni.navigateTo({
  341. url: `/pages/manager/inspect-result?resultData=${resultDataStr}`
  342. })
  343. },
  344. validateInspectData() {
  345. if (!this.inspectResult.list || this.inspectResult.list.length === 0) {
  346. return {
  347. isValid: false,
  348. message: '没有质检数据'
  349. }
  350. }
  351. for (const item of this.inspectResult.list) {
  352. // 不可回收和质量问题不需要校验金额
  353. if (item.id === 'unrecyclable' || item.id === 'quality_issue') {
  354. continue
  355. }
  356. // 只判断是否填写了commonOrderList(即有质检结果)
  357. if (!item.commonOrderList || item.commonOrderList.length === 0) {
  358. return {
  359. isValid: false,
  360. message: '有商品未完成质检选择'
  361. }
  362. }
  363. // 检查是否有空的testingStatus
  364. const hasEmptyStatus = item.commonOrderList.some(commonItem =>
  365. commonItem.testingStatus === '' || commonItem.testingStatus === null || commonItem.testingStatus === undefined
  366. )
  367. if (hasEmptyStatus) {
  368. return {
  369. isValid: false,
  370. message: '有商品未完成质检选择'
  371. }
  372. }
  373. // 检查总金额(price)是否填写(不可回收和质量问题不校验)
  374. if (!item.price || item.price === 0 || item.price === '') {
  375. return {
  376. isValid: false,
  377. message: '有商品未填写总金额'
  378. }
  379. }
  380. }
  381. return {
  382. isValid: true,
  383. message: ''
  384. }
  385. },
  386. switchCategory(idx) {
  387. this.currentCategory = idx
  388. this.loadingMore = false
  389. this.finished = false
  390. const categoryId = this.categories[idx]?.id
  391. if (categoryId === 'unrecyclable' || categoryId === 'quality_issue') {
  392. // 不可回收和质量问题分类直接更新商品列表
  393. this.updateCurrentGoods()
  394. return
  395. }
  396. // 如果该分类的商品还没有加载,调用API获取
  397. if (!this.allProducts[categoryId]) {
  398. this.fetchGoodsList(categoryId, 1)
  399. } else {
  400. // 已有数据,直接更新显示
  401. this.updateCurrentGoods()
  402. }
  403. },
  404. changeNum(item, key, delta) {
  405. if (key === 'qualified') {
  406. const currentCategoryId = this.categories[this.currentCategory]?.id
  407. // 处理不可回收和质量问题
  408. if (item.id === 'unrecyclable-1' || item.id === 'unrecyclable') {
  409. const newQualified = Math.max(0, (item.qualified || 0) + delta)
  410. this.$set(item, 'qualified', newQualified)
  411. this.updateInspectResult(item, 'qualified', delta, currentCategoryId)
  412. this.$forceUpdate()
  413. return
  414. }
  415. // 处理普通商品
  416. const newQualified = Math.max(0, (item.qualified || 0) + delta)
  417. this.$set(item, 'qualified', newQualified)
  418. this.updateInspectResult(item, 'qualified', delta, currentCategoryId)
  419. // 新增:如果数量为0,移除该商品对象(包括不可回收和质量问题)
  420. if (newQualified === 0) {
  421. this.removeInspectItem(item)
  422. }
  423. this.$forceUpdate()
  424. console.log('更新后的inspectResult:', JSON.stringify(this.inspectResult, null, 2))
  425. }
  426. },
  427. // 修改:移除商品对象方法,支持不可回收和质量问题
  428. removeInspectItem(item) {
  429. // 判断不可回收和质量问题
  430. if (item.id === 'unrecyclable-1' || item.id === 'unrecyclable') {
  431. const idx = this.inspectResult.list.findIndex(listItem => listItem.id === 'unrecyclable')
  432. if (idx !== -1) {
  433. this.inspectResult.list.splice(idx, 1)
  434. }
  435. return
  436. }
  437. if (item.id === 'quality-issue-1' || item.id === 'quality_issue') {
  438. const idx = this.inspectResult.list.findIndex(listItem => listItem.id === 'quality_issue')
  439. if (idx !== -1) {
  440. this.inspectResult.list.splice(idx, 1)
  441. }
  442. return
  443. }
  444. let itemId = item.originalId || item.id
  445. const orderItem = this.getOrderItemByProductId(itemId)
  446. if (orderItem && orderItem.id) {
  447. itemId = orderItem.id
  448. }
  449. // shopId 匹配
  450. const idx = this.inspectResult.list.findIndex(listItem => listItem.shopId == (orderItem ? (orderItem.shopId || orderItem.id) : itemId))
  451. if (idx !== -1) {
  452. this.inspectResult.list.splice(idx, 1)
  453. }
  454. },
  455. updateInspectResult(item, type, delta, currentCategoryId) {
  456. // 处理不可回收分类
  457. if (item.id === 'unrecyclable-1') {
  458. let inspectItem = this.inspectResult.list.find(listItem => listItem.id === 'unrecyclable')
  459. if (!inspectItem && delta > 0) {
  460. inspectItem = {
  461. id: 'unrecyclable',
  462. price: 0,
  463. qualifiedNum: 0,
  464. noQualifiedNum: 0,
  465. unrecyclable: 0, // 初始值为0
  466. shopId: '',
  467. pinId: '',
  468. categoryId: '',
  469. commonOrderList: [] // 初始为空数组
  470. }
  471. this.inspectResult.list.push(inspectItem)
  472. }
  473. if (!inspectItem) return
  474. if (type === 'qualified' && delta > 0) {
  475. inspectItem.unrecyclable++
  476. // 增加一个commonOrderList对象
  477. inspectItem.commonOrderList.push({
  478. testingInstructions: '',
  479. testingImages: '',
  480. testingStatus: 2
  481. })
  482. } else if (type === 'qualified' && delta < 0) {
  483. inspectItem.unrecyclable = Math.max(0, inspectItem.unrecyclable - 1)
  484. // 减少一个commonOrderList对象
  485. if (inspectItem.commonOrderList.length > 0) {
  486. inspectItem.commonOrderList.pop()
  487. }
  488. // 新增:如果减到0,移除该对象
  489. if (inspectItem.unrecyclable === 0) {
  490. const idx = this.inspectResult.list.findIndex(listItem => listItem === inspectItem)
  491. if (idx !== -1) {
  492. this.inspectResult.list.splice(idx, 1)
  493. }
  494. return
  495. }
  496. }
  497. console.log('不可回收对象:', inspectItem)
  498. return
  499. }
  500. if (item.id === 'quality-issue-1') {
  501. let inspectItem = this.inspectResult.list.find(listItem => listItem.id === 'quality_issue')
  502. if (!inspectItem && delta > 0) {
  503. inspectItem = {
  504. id: 'quality_issue',
  505. price: 0,
  506. qualifiedNum: 0,
  507. noQualifiedNum: 0, // 初始值为0
  508. unrecyclable: 0,
  509. shopId: '',
  510. pinId: '',
  511. categoryId: '',
  512. commonOrderList: [] // 初始为空数组
  513. }
  514. this.inspectResult.list.push(inspectItem)
  515. }
  516. if (!inspectItem) return
  517. if (type === 'qualified' && delta > 0) {
  518. inspectItem.noQualifiedNum++
  519. // 增加一个commonOrderList对象
  520. inspectItem.commonOrderList.push({
  521. testingInstructions: '',
  522. testingImages: '',
  523. testingStatus: 1
  524. })
  525. } else if (type === 'qualified' && delta < 0) {
  526. inspectItem.noQualifiedNum = Math.max(0, inspectItem.noQualifiedNum - 1)
  527. // 减少一个commonOrderList对象
  528. if (inspectItem.commonOrderList.length > 0) {
  529. inspectItem.commonOrderList.pop()
  530. }
  531. // 新增:如果减到0,移除该对象
  532. if (inspectItem.noQualifiedNum === 0) {
  533. const idx = this.inspectResult.list.findIndex(listItem => listItem === inspectItem)
  534. if (idx !== -1) {
  535. this.inspectResult.list.splice(idx, 1)
  536. }
  537. return
  538. }
  539. }
  540. console.log('质量问题对象:', inspectItem)
  541. return
  542. }
  543. let itemId = item.originalId || item.id
  544. const orderItem = this.getOrderItemByProductId(itemId)
  545. if (orderItem && orderItem.id) {
  546. itemId = orderItem.id
  547. }
  548. let inspectItem = this.inspectResult.list.find(listItem => listItem.shopId == (orderItem ? (orderItem.shopId || orderItem.id) : itemId))
  549. if (!inspectItem && delta > 0) {
  550. inspectItem = {
  551. price: 0,
  552. qualifiedNum: 0,
  553. noQualifiedNum: 0,
  554. unrecyclable: 0,
  555. shopId: orderItem ? (orderItem.shopId || orderItem.id) : itemId,
  556. pinId: '',
  557. categoryId: currentCategoryId || '', // 直接用当前分类id
  558. commonOrderList: [] // 初始为空数组,会在增加数量时动态添加
  559. }
  560. this.inspectResult.list.push(inspectItem)
  561. }
  562. if (!inspectItem) return
  563. if (type === 'qualified' && delta > 0) {
  564. inspectItem.qualifiedNum++
  565. // 增加一个commonOrderList对象
  566. inspectItem.commonOrderList.push({
  567. testingInstructions: '',
  568. testingImages: '',
  569. testingStatus: 0
  570. })
  571. } else if (type === 'qualified' && delta < 0) {
  572. inspectItem.qualifiedNum = Math.max(0, inspectItem.qualifiedNum - 1)
  573. // 减少一个commonOrderList对象
  574. if (inspectItem.commonOrderList.length > 0) {
  575. inspectItem.commonOrderList.pop()
  576. }
  577. // 新增:如果减到0,移除该商品对象
  578. if (inspectItem.qualifiedNum === 0) {
  579. const idx = this.inspectResult.list.findIndex(listItem => listItem === inspectItem)
  580. if (idx !== -1) {
  581. this.inspectResult.list.splice(idx, 1)
  582. }
  583. return
  584. }
  585. }
  586. console.log('更新后的inspectResult:', JSON.stringify(this.inspectResult, null, 2))
  587. },
  588. getInspectPrice(item) {
  589. // 优化:不可回收和质量问题通过id匹配
  590. if (item.id === 'unrecyclable-1' || item.id === 'unrecyclable') {
  591. const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'unrecyclable')
  592. return inspectItem ? inspectItem.price : ''
  593. }
  594. if (item.id === 'quality-issue-1' || item.id === 'quality_issue') {
  595. const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'quality_issue')
  596. return inspectItem ? inspectItem.price : ''
  597. }
  598. // 普通商品
  599. const inspectItem = this.inspectResult.list?.find(listItem => listItem.shopId == item.id)
  600. return inspectItem ? inspectItem.price : ''
  601. },
  602. updateInspectPrice(item, event) {
  603. // 优化:不可回收和质量问题通过id匹配
  604. if (item.id === 'unrecyclable-1' || item.id === 'unrecyclable') {
  605. const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'unrecyclable')
  606. if (!inspectItem) return
  607. inspectItem.price = parseFloat(event.detail.value) || 0
  608. return
  609. }
  610. if (item.id === 'quality-issue-1' || item.id === 'quality_issue') {
  611. const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'quality_issue')
  612. if (!inspectItem) return
  613. inspectItem.price = parseFloat(event.detail.value) || 0
  614. return
  615. }
  616. // 普通商品
  617. let itemId = item.originalId || item.id
  618. const orderItem = this.getOrderItemByProductId(itemId)
  619. if (orderItem && orderItem.id) {
  620. itemId = orderItem.id // 使用订单中的商品ID
  621. }
  622. // 只查找,不新建
  623. let inspectItem = this.inspectResult.list?.find(listItem => listItem.shopId == (orderItem ? (orderItem.shopId || orderItem.id) : itemId))
  624. if (!inspectItem) return // 没有就不处理
  625. const newPrice = parseFloat(event.detail.value) || 0
  626. inspectItem.price = newPrice
  627. console.log('更新价格:', itemId, newPrice)
  628. console.log('当前商品对象:', inspectItem)
  629. },
  630. loadMoreGoods() {
  631. const categoryId = this.categories[this.currentCategory]?.id
  632. // 不可回收和质量问题分类不支持加载更多
  633. if (categoryId === 'unrecyclable' || categoryId === 'quality_issue') {
  634. return
  635. }
  636. const page = (this.allProductsPage[categoryId] || 1) + 1
  637. const total = this.allProductsTotal[categoryId] || 0
  638. const loaded = (this.allProducts[categoryId] || []).length
  639. if (this.loadingMore || this.finished) return
  640. if (loaded < total) {
  641. this.loadingMore = true
  642. this.fetchGoodsList(categoryId, page, () => {
  643. this.loadingMore = false
  644. // 判断是否加载完
  645. const newLoaded = (this.allProducts[categoryId] || []).length
  646. this.finished = newLoaded >= (this.allProductsTotal[categoryId] || 0)
  647. })
  648. } else {
  649. this.finished = true
  650. }
  651. },
  652. // 获取品牌列表
  653. getGoodsBrandList(productId, searchName = '') {
  654. this.currentProductId = productId
  655. const params = { productId }
  656. if (searchName.trim()) {
  657. params.name = searchName.trim()
  658. }
  659. this.$api('getGoodsBrandList', params, res => {
  660. if (res && res.success && res.result && res.result.records) {
  661. // 保证响应式
  662. const newList = res.result.records.map(item => {
  663. // 获取品牌名称的拼音首字母
  664. const firstChar = this.getPinyinFirstLetter(item.name)
  665. return {
  666. id: item.id,
  667. logo: item.image || '/static/brand/alexander.png',
  668. name: item.name,
  669. letter: firstChar
  670. }
  671. })
  672. // 打印所有品牌的name和letter
  673. newList.forEach(b => console.log('品牌:', b.name, 'letter:', b.letter))
  674. this.brandList = [...newList]
  675. // 打印brandList和brandIndexList
  676. this.$nextTick(() => {
  677. console.log('brandList:', this.brandList)
  678. console.log('brandIndexList:', this.brandIndexList)
  679. })
  680. }
  681. })
  682. },
  683. // 获取中文拼音首字母
  684. getPinyinFirstLetter(str) {
  685. if (!str) return '#'
  686. const firstChar = str.charAt(0)
  687. // 只认A-Z,否则归为#
  688. if (/^[A-Za-z]$/.test(firstChar)) {
  689. return firstChar.toUpperCase()
  690. }
  691. return '#'
  692. },
  693. // 品牌搜索输入事件处理
  694. onBrandSearchInput(e) {
  695. const searchValue = e.detail.value
  696. // 清除之前的定时器
  697. if (this.searchTimer) {
  698. clearTimeout(this.searchTimer)
  699. }
  700. // 设置防抖,500ms后执行搜索
  701. this.searchTimer = setTimeout(() => {
  702. if (this.currentProductId) {
  703. this.getGoodsBrandList(this.currentProductId, searchValue)
  704. }
  705. }, 500)
  706. },
  707. // 打开品牌确认弹窗
  708. openBrandConfirm(brand) {
  709. this.brandConfirmInfo = {
  710. id: brand.id,
  711. logo: brand.logo,
  712. name: brand.name
  713. }
  714. this.showBrandConfirm = true
  715. },
  716. // 关闭品牌确认弹窗
  717. closeBrandConfirm() {
  718. this.showBrandConfirm = false
  719. },
  720. // 确认品牌选择
  721. confirmBrand() {
  722. this.showBrandConfirm = false
  723. this.showBrandPopup = false
  724. // 确认后增加商品数量
  725. if (this.pendingBrandIndex !== null) {
  726. const item = this.currentGoods[this.pendingBrandIndex]
  727. if (item) {
  728. const newQualified = Math.max(0, (item.qualified || 0) + 1)
  729. this.$set(item, 'qualified', newQualified)
  730. this.updateInspectResult(item, 'qualified', 1, this.categories[this.currentCategory]?.id)
  731. // 强制更新categories计算属性,使左侧分类数字变化
  732. this.$forceUpdate()
  733. }
  734. this.pendingBrandIndex = null
  735. }
  736. },
  737. // 关闭品牌弹窗
  738. closeBrandPopup() {
  739. this.showBrandPopup = false
  740. this.pendingBrandIndex = null
  741. this.brandSearch = ''
  742. this.currentProductId = null
  743. },
  744. // 格式化价格显示
  745. formatPrice(item) {
  746. const price = item.price
  747. const maxPrice = item.maxPrice
  748. // 如果两个价格都没有或都为0,显示占位符
  749. if ((!price || price === 0) && (!maxPrice || maxPrice === 0)) {
  750. return '¥ —'
  751. }
  752. // 如果只有一个价格有值
  753. if (price && (!maxPrice || maxPrice === 0)) {
  754. return `¥ ${price}`
  755. }
  756. if (maxPrice && (!price || price === 0)) {
  757. return `¥ ${maxPrice}`
  758. }
  759. // 如果两个价格都有值且不相等,显示价格范围
  760. if (price && maxPrice && price !== maxPrice) {
  761. const minPrice = Math.min(price, maxPrice)
  762. const maxPriceValue = Math.max(price, maxPrice)
  763. return `¥ ${minPrice} - ${maxPriceValue}`
  764. }
  765. // 如果两个价格相等,只显示一个
  766. return `¥ ${price || maxPrice}`
  767. },
  768. },
  769. created() {
  770. this.currentCategory = 0
  771. },
  772. onLoad(options) {
  773. // 接收订单数据
  774. if (options && options.orderData) {
  775. try {
  776. this.order = JSON.parse(decodeURIComponent(options.orderData))
  777. console.log('接收到的订单数据:', this.order)
  778. // 订单数据加载完成后初始化质检结果
  779. this.$nextTick(() => {
  780. this.initInspectResult()
  781. })
  782. } catch (error) {
  783. console.error('解析订单数据失败:', error)
  784. }
  785. }
  786. if (options && options.orderId) {
  787. this.orderId = options.orderId
  788. }
  789. // 初始化加载第一个分类的商品
  790. this.$nextTick(() => {
  791. // 确保categories已经计算完成
  792. if (this.categories.length > 0) {
  793. const firstCategoryId = this.categories[0]?.id
  794. console.log('第一个分类ID:', firstCategoryId, '所有分类:', this.categories.map(c => c.id))
  795. if (firstCategoryId && firstCategoryId !== 'unrecyclable' && firstCategoryId !== 'quality_issue') {
  796. this.fetchGoodsList(firstCategoryId, 1)
  797. } else if (firstCategoryId === 'unrecyclable' || firstCategoryId === 'quality_issue') {
  798. this.updateCurrentGoods()
  799. }
  800. } else {
  801. console.log('categories为空,等待数据加载')
  802. // 如果categories为空,等待一下再尝试
  803. setTimeout(() => {
  804. if (this.categories.length > 0) {
  805. const firstCategoryId = this.categories[0]?.id
  806. if (firstCategoryId && firstCategoryId !== 'unrecyclable' && firstCategoryId !== 'quality_issue') {
  807. this.fetchGoodsList(firstCategoryId, 1)
  808. } else if (firstCategoryId === 'unrecyclable' || firstCategoryId === 'quality_issue') {
  809. this.updateCurrentGoods()
  810. }
  811. }
  812. }, 500)
  813. }
  814. })
  815. console.log(this.orderId, 'orderId')
  816. },
  817. onShow() {
  818. // 确保在页面显示时categories已经正确计算
  819. console.log('onShow - categories:', this.categories.map(c => ({ id: c.id, title: c.title, badge: c.badge })))
  820. // 强制更新视图,确保所有分类都显示
  821. this.$nextTick(() => {
  822. console.log('分类导航应该显示的分类数量:', this.categories.length)
  823. this.categories.forEach((cat, index) => {
  824. console.log(`分类 ${index}: ${cat.title} (${cat.id})`)
  825. })
  826. })
  827. },
  828. }
  829. </script>
  830. <style lang="scss" scoped>
  831. .inspect-container {
  832. min-height: 100vh;
  833. background: #f8f8f8;
  834. display: flex;
  835. flex-direction: column;
  836. }
  837. .nav-bar {
  838. display: flex;
  839. align-items: center;
  840. height: calc(150rpx + var(--status-bar-height));
  841. padding: 0 32rpx;
  842. padding-top: var(--status-bar-height);
  843. background: #fff;
  844. position: fixed;
  845. top: 0;
  846. left: 0;
  847. right: 0;
  848. z-index: 999;
  849. box-sizing: border-box;
  850. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
  851. .back {
  852. padding: 20rpx;
  853. margin-left: -20rpx;
  854. }
  855. .nav-title {
  856. flex: 1;
  857. text-align: center;
  858. font-size: 32rpx;
  859. font-weight: 500;
  860. color: #222;
  861. }
  862. .nav-icons {
  863. display: flex;
  864. align-items: center;
  865. gap: 12px;
  866. }
  867. }
  868. .main-content {
  869. margin-top: calc(200rpx + var(--status-bar-height));
  870. display: flex;
  871. background: none;
  872. height: calc(100vh - 200rpx - var(--status-bar-height));
  873. min-height: calc(100vh - 200rpx - var(--status-bar-height));
  874. }
  875. .category-nav {
  876. width: 160rpx;
  877. background: #fff;
  878. border-radius: 48rpx 0 0 48rpx;
  879. // padding: 48rpx 0;
  880. display: flex;
  881. flex-direction: column;
  882. align-items: center;
  883. box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.03);
  884. height: calc(100vh - 200rpx - var(--status-bar-height) - 160rpx);
  885. max-height: calc(100vh - 200rpx - var(--status-bar-height) - 160rpx);
  886. overflow-y: scroll;
  887. overflow-x: hidden;
  888. position: relative;
  889. z-index: 2;
  890. -webkit-overflow-scrolling: touch;
  891. scrollbar-width: thin;
  892. scrollbar-color: #ddd transparent;
  893. &::-webkit-scrollbar {
  894. width: 8rpx;
  895. }
  896. &::-webkit-scrollbar-track {
  897. background: transparent;
  898. }
  899. &::-webkit-scrollbar-thumb {
  900. background: #ddd;
  901. border-radius: 4rpx;
  902. }
  903. &::-webkit-scrollbar-thumb:hover {
  904. background: #ccc;
  905. }
  906. .category-item {
  907. width: 128rpx;
  908. height: 88rpx;
  909. border-radius: 32rpx 0 0 32rpx;
  910. display: flex;
  911. align-items: center;
  912. justify-content: flex-start;
  913. font-size: 32rpx;
  914. color: #222;
  915. margin-bottom: 24rpx;
  916. background: #fff;
  917. position: relative;
  918. transition: background 0.2s, color 0.2s, font-weight 0.2s;
  919. padding-left: 24rpx;
  920. &.active {
  921. background: linear-gradient(90deg, #fff7e6 80%, #fff 100%);
  922. color: #ffb400;
  923. font-weight: bold;
  924. &::before {
  925. content: '';
  926. position: absolute;
  927. left: 0;
  928. top: 30%;
  929. height: 40%;
  930. width: 4rpx;
  931. border-radius: 8rpx;
  932. background: #ffb400;
  933. bottom: auto;
  934. }
  935. }
  936. .category-badge {
  937. position: absolute;
  938. top: 12rpx;
  939. right: 20rpx;
  940. background: #ff4d4f;
  941. color: #fff;
  942. font-size: 24rpx;
  943. border-radius: 50%;
  944. width: 36rpx;
  945. height: 36rpx;
  946. display: flex;
  947. align-items: center;
  948. justify-content: center;
  949. }
  950. }
  951. }
  952. .goods-list {
  953. flex: 1;
  954. height: calc(100vh - 200rpx - var(--status-bar-height) - 160rpx);
  955. padding: 0 0 0 32rpx;
  956. overflow-y: auto;
  957. background: none;
  958. }
  959. .goods-card {
  960. background: #fff;
  961. border-radius: 48rpx;
  962. box-shadow: 0 8rpx 48rpx rgba(0, 0, 0, 0.06);
  963. margin-bottom: 36rpx;
  964. padding: 36rpx 36rpx 18rpx 36rpx;
  965. }
  966. .goods-header {
  967. display: flex;
  968. align-items: center;
  969. margin-bottom: 24rpx;
  970. .goods-img {
  971. width: 112rpx;
  972. height: 112rpx;
  973. border-radius: 32rpx;
  974. margin-right: 24rpx;
  975. background: #f8f8f8;
  976. object-fit: contain;
  977. }
  978. .goods-info {
  979. flex: 1;
  980. display: flex;
  981. flex-direction: column;
  982. justify-content: center;
  983. min-width: 0;
  984. .goods-title-row {
  985. display: flex;
  986. align-items: baseline;
  987. justify-content: space-between;
  988. .goods-name {
  989. font-size: 28rpx;
  990. font-weight: bold;
  991. color: #222;
  992. margin-right: 16rpx;
  993. flex: 1;
  994. overflow: hidden;
  995. text-overflow: ellipsis;
  996. white-space: nowrap;
  997. }
  998. .goods-price {
  999. font-size: 30rpx;
  1000. color: #ffb400;
  1001. font-weight: bold;
  1002. white-space: nowrap;
  1003. flex-shrink: 0;
  1004. .goods-unit {
  1005. font-size: 26rpx;
  1006. color: #bbb;
  1007. }
  1008. }
  1009. }
  1010. .goods-desc {
  1011. font-size: 26rpx;
  1012. color: #999;
  1013. margin-top: 8rpx;
  1014. }
  1015. }
  1016. }
  1017. .goods-row {
  1018. display: flex;
  1019. align-items: center;
  1020. margin-bottom: 24rpx;
  1021. .row-label {
  1022. font-size: 28rpx;
  1023. color: #888;
  1024. width: 160rpx;
  1025. flex-shrink: 0;
  1026. }
  1027. .num-ctrl {
  1028. display: flex;
  1029. align-items: center;
  1030. .num-btn {
  1031. width: 60rpx;
  1032. height: 60rpx;
  1033. padding: 0;
  1034. margin: 0;
  1035. display: flex;
  1036. align-items: center;
  1037. justify-content: center;
  1038. font-size: 28rpx;
  1039. color: #666;
  1040. background: #ffffff;
  1041. border: none;
  1042. border-radius: 50%;
  1043. &::after {
  1044. border: none;
  1045. }
  1046. &:active {
  1047. opacity: 0.8;
  1048. }
  1049. }
  1050. .num {
  1051. width: 80rpx;
  1052. text-align: center;
  1053. font-size: 32rpx;
  1054. color: #333;
  1055. }
  1056. }
  1057. .amount-input {
  1058. flex: 1;
  1059. height: 64rpx;
  1060. border-radius: 24rpx;
  1061. background: #f6f6f6;
  1062. border: none;
  1063. font-size: 30rpx;
  1064. color: #222;
  1065. padding-left: 20rpx;
  1066. margin-left: 16rpx;
  1067. }
  1068. }
  1069. .footer-btns {
  1070. position: fixed;
  1071. left: 0;
  1072. right: 0;
  1073. bottom: 0;
  1074. background: #fff;
  1075. display: flex;
  1076. gap: 32rpx;
  1077. padding: 24rpx 32rpx 48rpx 32rpx;
  1078. z-index: 101;
  1079. .btn-outline {
  1080. flex: 1;
  1081. height: 80rpx;
  1082. border-radius: 32rpx;
  1083. border: 2rpx solid #ffe09a;
  1084. color: #ffb400;
  1085. background: #fff0d2;
  1086. font-size: 30rpx;
  1087. font-weight: 500;
  1088. box-shadow: none;
  1089. padding: 0 36rpx;
  1090. }
  1091. .btn-main {
  1092. flex: 1;
  1093. height: 80rpx;
  1094. border-radius: 32rpx;
  1095. background: linear-gradient(90deg, #ffd01e 0%, #ffac04 100%);
  1096. color: #fff;
  1097. border: none;
  1098. font-size: 30rpx;
  1099. font-weight: 500;
  1100. box-shadow: none;
  1101. padding: 0 36rpx;
  1102. }
  1103. }
  1104. .loading-more {
  1105. text-align: center;
  1106. color: #999;
  1107. padding: 20rpx 0;
  1108. font-size: 26rpx;
  1109. }
  1110. // 品牌选择弹窗样式
  1111. .brand-popup-mask {
  1112. position: fixed;
  1113. left: 0;
  1114. right: 0;
  1115. top: 0;
  1116. bottom: 0;
  1117. background: rgba(0,0,0,0.35);
  1118. z-index: 3000;
  1119. display: flex;
  1120. align-items: flex-end;
  1121. justify-content: center;
  1122. }
  1123. .brand-popup {
  1124. position: relative;
  1125. width: 100%;
  1126. max-width: 1500rpx;
  1127. background: #fff;
  1128. border-radius: 64rpx 64rpx 0 0;
  1129. box-shadow: 0 -8rpx 48rpx rgba(0,0,0,0.08);
  1130. padding-bottom: 80rpx;
  1131. max-height: 90vh;
  1132. display: flex;
  1133. flex-direction: column;
  1134. overflow: hidden;
  1135. }
  1136. .brand-popup-header {
  1137. display: flex;
  1138. align-items: center;
  1139. justify-content: center;
  1140. padding: 32rpx 24rpx 0 24rpx;
  1141. font-size: 32rpx;
  1142. font-weight: bold;
  1143. position: relative;
  1144. }
  1145. .brand-popup-close {
  1146. position: absolute;
  1147. left: 24rpx;
  1148. font-size: 28rpx;
  1149. color: #888;
  1150. }
  1151. .brand-popup-title {
  1152. font-size: 32rpx;
  1153. color: #222;
  1154. font-weight: bold;
  1155. }
  1156. .brand-popup-search {
  1157. padding: 20rpx 24rpx 0 24rpx;
  1158. }
  1159. .brand-search-input {
  1160. width: 100%;
  1161. height: 60rpx;
  1162. border-radius: 30rpx;
  1163. background: #f5f5f5;
  1164. border: none;
  1165. padding-left: 40rpx;
  1166. font-size: 28rpx;
  1167. color: #888;
  1168. }
  1169. .brand-popup-list {
  1170. flex: 1;
  1171. overflow-y: auto;
  1172. max-height: 60vh;
  1173. padding: 0 24rpx;
  1174. scrollbar-width: none; /* Firefox */
  1175. -ms-overflow-style: none; /* IE and Edge */
  1176. &::-webkit-scrollbar {
  1177. width: 0 !important;
  1178. display: none; /* Chrome, Safari, Opera */
  1179. }
  1180. }
  1181. .brand-letter {
  1182. font-size: 28rpx;
  1183. color: #888;
  1184. margin: 24rpx 0 8rpx 0;
  1185. font-weight: bold;
  1186. }
  1187. .brand-item {
  1188. display: flex;
  1189. align-items: center;
  1190. padding: 16rpx 0;
  1191. border-bottom: 1px solid #f0f0f0;
  1192. }
  1193. .brand-logo {
  1194. width: 60rpx;
  1195. height: 60rpx;
  1196. margin-right: 20rpx;
  1197. border-radius: 8rpx;
  1198. background: #f8f8f8;
  1199. }
  1200. .brand-name {
  1201. font-size: 28rpx;
  1202. color: #222;
  1203. }
  1204. // 品牌确认弹窗样式
  1205. .brand-confirm-mask {
  1206. position: fixed;
  1207. left: 0;
  1208. right: 0;
  1209. top: 0;
  1210. bottom: 0;
  1211. background: rgba(0,0,0,0.25);
  1212. z-index: 5001;
  1213. display: flex;
  1214. align-items: center;
  1215. justify-content: center;
  1216. }
  1217. .brand-confirm-popup {
  1218. width: 70vw;
  1219. max-width: 540rpx;
  1220. background: #fff;
  1221. border-radius: 64rpx;
  1222. box-shadow: 0 16rpx 64rpx rgba(0,0,0,0.12);
  1223. display: flex;
  1224. flex-direction: column;
  1225. align-items: center;
  1226. padding: 96rpx 40rpx 72rpx 40rpx;
  1227. position: relative;
  1228. }
  1229. .brand-confirm-title {
  1230. font-size: 36rpx;
  1231. color: #222;
  1232. font-weight: bold;
  1233. text-align: center;
  1234. margin-bottom: 24rpx;
  1235. }
  1236. .brand-confirm-logo-wrap {
  1237. width: 120rpx;
  1238. height: 120rpx;
  1239. background: #f8f8f8;
  1240. border-radius: 50%;
  1241. display: flex;
  1242. align-items: center;
  1243. justify-content: center;
  1244. margin-bottom: 18rpx;
  1245. }
  1246. .brand-confirm-logo {
  1247. width: 80rpx;
  1248. height: 80rpx;
  1249. border-radius: 50%;
  1250. }
  1251. .brand-confirm-name {
  1252. font-size: 28rpx;
  1253. color: #222;
  1254. font-weight: bold;
  1255. text-align: center;
  1256. margin-bottom: 16rpx;
  1257. }
  1258. .brand-confirm-desc {
  1259. font-size: 24rpx;
  1260. color: #999;
  1261. text-align: center;
  1262. margin-bottom: 32rpx;
  1263. line-height: 1.6;
  1264. }
  1265. .brand-confirm-btn-row {
  1266. width: 100%;
  1267. display: flex;
  1268. justify-content: space-between;
  1269. gap: 24rpx;
  1270. }
  1271. .brand-confirm-btn {
  1272. flex: 1;
  1273. height: 72rpx;
  1274. border-radius: 36rpx;
  1275. font-size: 28rpx;
  1276. font-weight: bold;
  1277. display: flex;
  1278. align-items: center;
  1279. justify-content: center;
  1280. border: none;
  1281. margin: 0 0;
  1282. }
  1283. .brand-confirm-btn.retry {
  1284. background: #fff;
  1285. color: #ff9c00;
  1286. border: 2rpx solid #ff9c00;
  1287. }
  1288. .brand-confirm-btn.confirm {
  1289. background: linear-gradient(to right, #ffd01e, #ff8917);
  1290. color: #fff;
  1291. border: none;
  1292. }
  1293. </style>