爱简收旧衣按件回收前端代码仓库
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.

1415 lines
42 KiB

3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 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. testingInstructions: '',
  560. testingImages: '',
  561. testingStatus: 0
  562. }] // 合格产品固定一个commonOrderList项
  563. }
  564. this.inspectResult.list.push(inspectItem)
  565. }
  566. if (!inspectItem) return
  567. if (type === 'qualified' && delta > 0) {
  568. inspectItem.qualifiedNum++
  569. // 合格产品不需要动态增加commonOrderList,保持固定一个
  570. } else if (type === 'qualified' && delta < 0) {
  571. inspectItem.qualifiedNum = Math.max(0, inspectItem.qualifiedNum - 1)
  572. // 合格产品不需要动态减少commonOrderList
  573. // 新增:如果减到0,移除该商品对象
  574. if (inspectItem.qualifiedNum === 0) {
  575. const idx = this.inspectResult.list.findIndex(listItem => listItem === inspectItem)
  576. if (idx !== -1) {
  577. this.inspectResult.list.splice(idx, 1)
  578. }
  579. return
  580. }
  581. }
  582. console.log('更新后的inspectResult:', JSON.stringify(this.inspectResult, null, 2))
  583. },
  584. getInspectPrice(item) {
  585. // 优化:不可回收和质量问题通过id匹配
  586. if (item.id === 'unrecyclable-1' || item.id === 'unrecyclable') {
  587. const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'unrecyclable')
  588. return inspectItem ? inspectItem.price : ''
  589. }
  590. if (item.id === 'quality-issue-1' || item.id === 'quality_issue') {
  591. const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'quality_issue')
  592. return inspectItem ? inspectItem.price : ''
  593. }
  594. // 普通商品
  595. const inspectItem = this.inspectResult.list?.find(listItem => listItem.shopId == item.id)
  596. return inspectItem ? inspectItem.price : ''
  597. },
  598. updateInspectPrice(item, event) {
  599. // 优化:不可回收和质量问题通过id匹配
  600. if (item.id === 'unrecyclable-1' || item.id === 'unrecyclable') {
  601. const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'unrecyclable')
  602. if (!inspectItem) return
  603. inspectItem.price = parseFloat(event.detail.value) || 0
  604. return
  605. }
  606. if (item.id === 'quality-issue-1' || item.id === 'quality_issue') {
  607. const inspectItem = this.inspectResult.list?.find(listItem => listItem.id === 'quality_issue')
  608. if (!inspectItem) return
  609. inspectItem.price = parseFloat(event.detail.value) || 0
  610. return
  611. }
  612. // 普通商品
  613. let itemId = item.originalId || item.id
  614. const orderItem = this.getOrderItemByProductId(itemId)
  615. if (orderItem && orderItem.id) {
  616. itemId = orderItem.id // 使用订单中的商品ID
  617. }
  618. // 只查找,不新建
  619. let inspectItem = this.inspectResult.list?.find(listItem => listItem.shopId == (orderItem ? (orderItem.shopId || orderItem.id) : itemId))
  620. if (!inspectItem) return // 没有就不处理
  621. const newPrice = parseFloat(event.detail.value) || 0
  622. inspectItem.price = newPrice
  623. console.log('更新价格:', itemId, newPrice)
  624. console.log('当前商品对象:', inspectItem)
  625. },
  626. loadMoreGoods() {
  627. const categoryId = this.categories[this.currentCategory]?.id
  628. // 不可回收和质量问题分类不支持加载更多
  629. if (categoryId === 'unrecyclable' || categoryId === 'quality_issue') {
  630. return
  631. }
  632. const page = (this.allProductsPage[categoryId] || 1) + 1
  633. const total = this.allProductsTotal[categoryId] || 0
  634. const loaded = (this.allProducts[categoryId] || []).length
  635. if (this.loadingMore || this.finished) return
  636. if (loaded < total) {
  637. this.loadingMore = true
  638. this.fetchGoodsList(categoryId, page, () => {
  639. this.loadingMore = false
  640. // 判断是否加载完
  641. const newLoaded = (this.allProducts[categoryId] || []).length
  642. this.finished = newLoaded >= (this.allProductsTotal[categoryId] || 0)
  643. })
  644. } else {
  645. this.finished = true
  646. }
  647. },
  648. // 获取品牌列表
  649. getGoodsBrandList(productId, searchName = '') {
  650. this.currentProductId = productId
  651. const params = { productId }
  652. if (searchName.trim()) {
  653. params.name = searchName.trim()
  654. }
  655. this.$api('getGoodsBrandList', params, res => {
  656. if (res && res.success && res.result && res.result.records) {
  657. // 保证响应式
  658. const newList = res.result.records.map(item => {
  659. // 获取品牌名称的拼音首字母
  660. const firstChar = this.getPinyinFirstLetter(item.name)
  661. return {
  662. id: item.id,
  663. logo: item.image || '/static/brand/alexander.png',
  664. name: item.name,
  665. letter: firstChar
  666. }
  667. })
  668. // 打印所有品牌的name和letter
  669. newList.forEach(b => console.log('品牌:', b.name, 'letter:', b.letter))
  670. this.brandList = [...newList]
  671. // 打印brandList和brandIndexList
  672. this.$nextTick(() => {
  673. console.log('brandList:', this.brandList)
  674. console.log('brandIndexList:', this.brandIndexList)
  675. })
  676. }
  677. })
  678. },
  679. // 获取中文拼音首字母
  680. getPinyinFirstLetter(str) {
  681. if (!str) return '#'
  682. const firstChar = str.charAt(0)
  683. // 只认A-Z,否则归为#
  684. if (/^[A-Za-z]$/.test(firstChar)) {
  685. return firstChar.toUpperCase()
  686. }
  687. return '#'
  688. },
  689. // 品牌搜索输入事件处理
  690. onBrandSearchInput(e) {
  691. const searchValue = e.detail.value
  692. // 清除之前的定时器
  693. if (this.searchTimer) {
  694. clearTimeout(this.searchTimer)
  695. }
  696. // 设置防抖,500ms后执行搜索
  697. this.searchTimer = setTimeout(() => {
  698. if (this.currentProductId) {
  699. this.getGoodsBrandList(this.currentProductId, searchValue)
  700. }
  701. }, 500)
  702. },
  703. // 打开品牌确认弹窗
  704. openBrandConfirm(brand) {
  705. this.brandConfirmInfo = {
  706. id: brand.id,
  707. logo: brand.logo,
  708. name: brand.name
  709. }
  710. this.showBrandConfirm = true
  711. },
  712. // 关闭品牌确认弹窗
  713. closeBrandConfirm() {
  714. this.showBrandConfirm = false
  715. },
  716. // 确认品牌选择
  717. confirmBrand() {
  718. this.showBrandConfirm = false
  719. this.showBrandPopup = false
  720. // 确认后增加商品数量
  721. if (this.pendingBrandIndex !== null) {
  722. const item = this.currentGoods[this.pendingBrandIndex]
  723. if (item) {
  724. const newQualified = Math.max(0, (item.qualified || 0) + 1)
  725. this.$set(item, 'qualified', newQualified)
  726. this.updateInspectResult(item, 'qualified', 1, this.categories[this.currentCategory]?.id)
  727. // 强制更新categories计算属性,使左侧分类数字变化
  728. this.$forceUpdate()
  729. }
  730. this.pendingBrandIndex = null
  731. }
  732. },
  733. // 关闭品牌弹窗
  734. closeBrandPopup() {
  735. this.showBrandPopup = false
  736. this.pendingBrandIndex = null
  737. this.brandSearch = ''
  738. this.currentProductId = null
  739. },
  740. // 格式化价格显示
  741. formatPrice(item) {
  742. const price = item.price
  743. const maxPrice = item.maxPrice
  744. // 如果两个价格都没有或都为0,显示占位符
  745. if ((!price || price === 0) && (!maxPrice || maxPrice === 0)) {
  746. return '¥ —'
  747. }
  748. // 如果只有一个价格有值
  749. if (price && (!maxPrice || maxPrice === 0)) {
  750. return `¥ ${price}`
  751. }
  752. if (maxPrice && (!price || price === 0)) {
  753. return `¥ ${maxPrice}`
  754. }
  755. // 如果两个价格都有值且不相等,显示价格范围
  756. if (price && maxPrice && price !== maxPrice) {
  757. const minPrice = Math.min(price, maxPrice)
  758. const maxPriceValue = Math.max(price, maxPrice)
  759. return `¥ ${minPrice} - ${maxPriceValue}`
  760. }
  761. // 如果两个价格相等,只显示一个
  762. return `¥ ${price || maxPrice}`
  763. },
  764. },
  765. created() {
  766. this.currentCategory = 0
  767. },
  768. onLoad(options) {
  769. // 接收订单数据
  770. if (options && options.orderData) {
  771. try {
  772. this.order = JSON.parse(decodeURIComponent(options.orderData))
  773. console.log('接收到的订单数据:', this.order)
  774. // 订单数据加载完成后初始化质检结果
  775. this.$nextTick(() => {
  776. this.initInspectResult()
  777. })
  778. } catch (error) {
  779. console.error('解析订单数据失败:', error)
  780. }
  781. }
  782. if (options && options.orderId) {
  783. this.orderId = options.orderId
  784. }
  785. // 初始化加载第一个分类的商品
  786. this.$nextTick(() => {
  787. // 确保categories已经计算完成
  788. if (this.categories.length > 0) {
  789. const firstCategoryId = this.categories[0]?.id
  790. console.log('第一个分类ID:', firstCategoryId, '所有分类:', this.categories.map(c => c.id))
  791. if (firstCategoryId && firstCategoryId !== 'unrecyclable' && firstCategoryId !== 'quality_issue') {
  792. this.fetchGoodsList(firstCategoryId, 1)
  793. } else if (firstCategoryId === 'unrecyclable' || firstCategoryId === 'quality_issue') {
  794. this.updateCurrentGoods()
  795. }
  796. } else {
  797. console.log('categories为空,等待数据加载')
  798. // 如果categories为空,等待一下再尝试
  799. setTimeout(() => {
  800. if (this.categories.length > 0) {
  801. const firstCategoryId = this.categories[0]?.id
  802. if (firstCategoryId && firstCategoryId !== 'unrecyclable' && firstCategoryId !== 'quality_issue') {
  803. this.fetchGoodsList(firstCategoryId, 1)
  804. } else if (firstCategoryId === 'unrecyclable' || firstCategoryId === 'quality_issue') {
  805. this.updateCurrentGoods()
  806. }
  807. }
  808. }, 500)
  809. }
  810. })
  811. console.log(this.orderId, 'orderId')
  812. },
  813. onShow() {
  814. // 确保在页面显示时categories已经正确计算
  815. console.log('onShow - categories:', this.categories.map(c => ({ id: c.id, title: c.title, badge: c.badge })))
  816. // 强制更新视图,确保所有分类都显示
  817. this.$nextTick(() => {
  818. console.log('分类导航应该显示的分类数量:', this.categories.length)
  819. this.categories.forEach((cat, index) => {
  820. console.log(`分类 ${index}: ${cat.title} (${cat.id})`)
  821. })
  822. })
  823. },
  824. }
  825. </script>
  826. <style lang="scss" scoped>
  827. .inspect-container {
  828. min-height: 100vh;
  829. background: #f8f8f8;
  830. display: flex;
  831. flex-direction: column;
  832. }
  833. .nav-bar {
  834. display: flex;
  835. align-items: center;
  836. height: calc(150rpx + var(--status-bar-height));
  837. padding: 0 32rpx;
  838. padding-top: var(--status-bar-height);
  839. background: #fff;
  840. position: fixed;
  841. top: 0;
  842. left: 0;
  843. right: 0;
  844. z-index: 999;
  845. box-sizing: border-box;
  846. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
  847. .back {
  848. padding: 20rpx;
  849. margin-left: -20rpx;
  850. }
  851. .nav-title {
  852. flex: 1;
  853. text-align: center;
  854. font-size: 32rpx;
  855. font-weight: 500;
  856. color: #222;
  857. }
  858. .nav-icons {
  859. display: flex;
  860. align-items: center;
  861. gap: 12px;
  862. }
  863. }
  864. .main-content {
  865. margin-top: calc(200rpx + var(--status-bar-height));
  866. display: flex;
  867. background: none;
  868. height: calc(100vh - 200rpx - var(--status-bar-height));
  869. min-height: calc(100vh - 200rpx - var(--status-bar-height));
  870. }
  871. .category-nav {
  872. width: 160rpx;
  873. background: #fff;
  874. border-radius: 48rpx 0 0 48rpx;
  875. // padding: 48rpx 0;
  876. display: flex;
  877. flex-direction: column;
  878. align-items: center;
  879. box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.03);
  880. height: calc(100vh - 200rpx - var(--status-bar-height) - 160rpx);
  881. max-height: calc(100vh - 200rpx - var(--status-bar-height) - 160rpx);
  882. overflow-y: scroll;
  883. overflow-x: hidden;
  884. position: relative;
  885. z-index: 2;
  886. -webkit-overflow-scrolling: touch;
  887. scrollbar-width: thin;
  888. scrollbar-color: #ddd transparent;
  889. &::-webkit-scrollbar {
  890. width: 8rpx;
  891. }
  892. &::-webkit-scrollbar-track {
  893. background: transparent;
  894. }
  895. &::-webkit-scrollbar-thumb {
  896. background: #ddd;
  897. border-radius: 4rpx;
  898. }
  899. &::-webkit-scrollbar-thumb:hover {
  900. background: #ccc;
  901. }
  902. .category-item {
  903. width: 128rpx;
  904. height: 88rpx;
  905. border-radius: 32rpx 0 0 32rpx;
  906. display: flex;
  907. align-items: center;
  908. justify-content: flex-start;
  909. font-size: 32rpx;
  910. color: #222;
  911. margin-bottom: 24rpx;
  912. background: #fff;
  913. position: relative;
  914. transition: background 0.2s, color 0.2s, font-weight 0.2s;
  915. padding-left: 24rpx;
  916. &.active {
  917. background: linear-gradient(90deg, #fff7e6 80%, #fff 100%);
  918. color: #ffb400;
  919. font-weight: bold;
  920. &::before {
  921. content: '';
  922. position: absolute;
  923. left: 0;
  924. top: 30%;
  925. height: 40%;
  926. width: 4rpx;
  927. border-radius: 8rpx;
  928. background: #ffb400;
  929. bottom: auto;
  930. }
  931. }
  932. .category-badge {
  933. position: absolute;
  934. top: 12rpx;
  935. right: 20rpx;
  936. background: #ff4d4f;
  937. color: #fff;
  938. font-size: 24rpx;
  939. border-radius: 50%;
  940. width: 36rpx;
  941. height: 36rpx;
  942. display: flex;
  943. align-items: center;
  944. justify-content: center;
  945. }
  946. }
  947. }
  948. .goods-list {
  949. flex: 1;
  950. height: calc(100vh - 200rpx - var(--status-bar-height) - 160rpx);
  951. padding: 0 0 0 32rpx;
  952. overflow-y: auto;
  953. background: none;
  954. }
  955. .goods-card {
  956. background: #fff;
  957. border-radius: 48rpx;
  958. box-shadow: 0 8rpx 48rpx rgba(0, 0, 0, 0.06);
  959. margin-bottom: 36rpx;
  960. padding: 36rpx 36rpx 18rpx 36rpx;
  961. }
  962. .goods-header {
  963. display: flex;
  964. align-items: center;
  965. margin-bottom: 24rpx;
  966. .goods-img {
  967. width: 112rpx;
  968. height: 112rpx;
  969. border-radius: 32rpx;
  970. margin-right: 24rpx;
  971. background: #f8f8f8;
  972. object-fit: contain;
  973. }
  974. .goods-info {
  975. flex: 1;
  976. display: flex;
  977. flex-direction: column;
  978. justify-content: center;
  979. min-width: 0;
  980. .goods-title-row {
  981. display: flex;
  982. align-items: baseline;
  983. justify-content: space-between;
  984. .goods-name {
  985. font-size: 28rpx;
  986. font-weight: bold;
  987. color: #222;
  988. margin-right: 16rpx;
  989. flex: 1;
  990. overflow: hidden;
  991. text-overflow: ellipsis;
  992. white-space: nowrap;
  993. }
  994. .goods-price {
  995. font-size: 30rpx;
  996. color: #ffb400;
  997. font-weight: bold;
  998. white-space: nowrap;
  999. flex-shrink: 0;
  1000. .goods-unit {
  1001. font-size: 26rpx;
  1002. color: #bbb;
  1003. }
  1004. }
  1005. }
  1006. .goods-desc {
  1007. font-size: 26rpx;
  1008. color: #999;
  1009. margin-top: 8rpx;
  1010. }
  1011. }
  1012. }
  1013. .goods-row {
  1014. display: flex;
  1015. align-items: center;
  1016. margin-bottom: 24rpx;
  1017. .row-label {
  1018. font-size: 28rpx;
  1019. color: #888;
  1020. width: 160rpx;
  1021. flex-shrink: 0;
  1022. }
  1023. .num-ctrl {
  1024. display: flex;
  1025. align-items: center;
  1026. .num-btn {
  1027. width: 60rpx;
  1028. height: 60rpx;
  1029. padding: 0;
  1030. margin: 0;
  1031. display: flex;
  1032. align-items: center;
  1033. justify-content: center;
  1034. font-size: 28rpx;
  1035. color: #666;
  1036. background: #ffffff;
  1037. border: none;
  1038. border-radius: 50%;
  1039. &::after {
  1040. border: none;
  1041. }
  1042. &:active {
  1043. opacity: 0.8;
  1044. }
  1045. }
  1046. .num {
  1047. width: 80rpx;
  1048. text-align: center;
  1049. font-size: 32rpx;
  1050. color: #333;
  1051. }
  1052. }
  1053. .amount-input {
  1054. flex: 1;
  1055. height: 64rpx;
  1056. border-radius: 24rpx;
  1057. background: #f6f6f6;
  1058. border: none;
  1059. font-size: 30rpx;
  1060. color: #222;
  1061. padding-left: 20rpx;
  1062. margin-left: 16rpx;
  1063. }
  1064. }
  1065. .footer-btns {
  1066. position: fixed;
  1067. left: 0;
  1068. right: 0;
  1069. bottom: 0;
  1070. background: #fff;
  1071. display: flex;
  1072. gap: 32rpx;
  1073. padding: 24rpx 32rpx 48rpx 32rpx;
  1074. z-index: 101;
  1075. .btn-outline {
  1076. flex: 1;
  1077. height: 80rpx;
  1078. border-radius: 32rpx;
  1079. border: 2rpx solid #ffe09a;
  1080. color: #ffb400;
  1081. background: #fff0d2;
  1082. font-size: 30rpx;
  1083. font-weight: 500;
  1084. box-shadow: none;
  1085. padding: 0 36rpx;
  1086. }
  1087. .btn-main {
  1088. flex: 1;
  1089. height: 80rpx;
  1090. border-radius: 32rpx;
  1091. background: linear-gradient(90deg, #ffd01e 0%, #ffac04 100%);
  1092. color: #fff;
  1093. border: none;
  1094. font-size: 30rpx;
  1095. font-weight: 500;
  1096. box-shadow: none;
  1097. padding: 0 36rpx;
  1098. }
  1099. }
  1100. .loading-more {
  1101. text-align: center;
  1102. color: #999;
  1103. padding: 20rpx 0;
  1104. font-size: 26rpx;
  1105. }
  1106. // 品牌选择弹窗样式
  1107. .brand-popup-mask {
  1108. position: fixed;
  1109. left: 0;
  1110. right: 0;
  1111. top: 0;
  1112. bottom: 0;
  1113. background: rgba(0,0,0,0.35);
  1114. z-index: 3000;
  1115. display: flex;
  1116. align-items: flex-end;
  1117. justify-content: center;
  1118. }
  1119. .brand-popup {
  1120. position: relative;
  1121. width: 100%;
  1122. max-width: 1500rpx;
  1123. background: #fff;
  1124. border-radius: 64rpx 64rpx 0 0;
  1125. box-shadow: 0 -8rpx 48rpx rgba(0,0,0,0.08);
  1126. padding-bottom: 80rpx;
  1127. max-height: 90vh;
  1128. display: flex;
  1129. flex-direction: column;
  1130. overflow: hidden;
  1131. }
  1132. .brand-popup-header {
  1133. display: flex;
  1134. align-items: center;
  1135. justify-content: center;
  1136. padding: 32rpx 24rpx 0 24rpx;
  1137. font-size: 32rpx;
  1138. font-weight: bold;
  1139. position: relative;
  1140. }
  1141. .brand-popup-close {
  1142. position: absolute;
  1143. left: 24rpx;
  1144. font-size: 28rpx;
  1145. color: #888;
  1146. }
  1147. .brand-popup-title {
  1148. font-size: 32rpx;
  1149. color: #222;
  1150. font-weight: bold;
  1151. }
  1152. .brand-popup-search {
  1153. padding: 20rpx 24rpx 0 24rpx;
  1154. }
  1155. .brand-search-input {
  1156. width: 100%;
  1157. height: 60rpx;
  1158. border-radius: 30rpx;
  1159. background: #f5f5f5;
  1160. border: none;
  1161. padding-left: 40rpx;
  1162. font-size: 28rpx;
  1163. color: #888;
  1164. }
  1165. .brand-popup-list {
  1166. flex: 1;
  1167. overflow-y: auto;
  1168. max-height: 60vh;
  1169. padding: 0 24rpx;
  1170. scrollbar-width: none; /* Firefox */
  1171. -ms-overflow-style: none; /* IE and Edge */
  1172. &::-webkit-scrollbar {
  1173. width: 0 !important;
  1174. display: none; /* Chrome, Safari, Opera */
  1175. }
  1176. }
  1177. .brand-letter {
  1178. font-size: 28rpx;
  1179. color: #888;
  1180. margin: 24rpx 0 8rpx 0;
  1181. font-weight: bold;
  1182. }
  1183. .brand-item {
  1184. display: flex;
  1185. align-items: center;
  1186. padding: 16rpx 0;
  1187. border-bottom: 1px solid #f0f0f0;
  1188. }
  1189. .brand-logo {
  1190. width: 60rpx;
  1191. height: 60rpx;
  1192. margin-right: 20rpx;
  1193. border-radius: 8rpx;
  1194. background: #f8f8f8;
  1195. }
  1196. .brand-name {
  1197. font-size: 28rpx;
  1198. color: #222;
  1199. }
  1200. // 品牌确认弹窗样式
  1201. .brand-confirm-mask {
  1202. position: fixed;
  1203. left: 0;
  1204. right: 0;
  1205. top: 0;
  1206. bottom: 0;
  1207. background: rgba(0,0,0,0.25);
  1208. z-index: 5001;
  1209. display: flex;
  1210. align-items: center;
  1211. justify-content: center;
  1212. }
  1213. .brand-confirm-popup {
  1214. width: 70vw;
  1215. max-width: 540rpx;
  1216. background: #fff;
  1217. border-radius: 64rpx;
  1218. box-shadow: 0 16rpx 64rpx rgba(0,0,0,0.12);
  1219. display: flex;
  1220. flex-direction: column;
  1221. align-items: center;
  1222. padding: 96rpx 40rpx 72rpx 40rpx;
  1223. position: relative;
  1224. }
  1225. .brand-confirm-title {
  1226. font-size: 36rpx;
  1227. color: #222;
  1228. font-weight: bold;
  1229. text-align: center;
  1230. margin-bottom: 24rpx;
  1231. }
  1232. .brand-confirm-logo-wrap {
  1233. width: 120rpx;
  1234. height: 120rpx;
  1235. background: #f8f8f8;
  1236. border-radius: 50%;
  1237. display: flex;
  1238. align-items: center;
  1239. justify-content: center;
  1240. margin-bottom: 18rpx;
  1241. }
  1242. .brand-confirm-logo {
  1243. width: 80rpx;
  1244. height: 80rpx;
  1245. border-radius: 50%;
  1246. }
  1247. .brand-confirm-name {
  1248. font-size: 28rpx;
  1249. color: #222;
  1250. font-weight: bold;
  1251. text-align: center;
  1252. margin-bottom: 16rpx;
  1253. }
  1254. .brand-confirm-desc {
  1255. font-size: 24rpx;
  1256. color: #999;
  1257. text-align: center;
  1258. margin-bottom: 32rpx;
  1259. line-height: 1.6;
  1260. }
  1261. .brand-confirm-btn-row {
  1262. width: 100%;
  1263. display: flex;
  1264. justify-content: space-between;
  1265. gap: 24rpx;
  1266. }
  1267. .brand-confirm-btn {
  1268. flex: 1;
  1269. height: 72rpx;
  1270. border-radius: 36rpx;
  1271. font-size: 28rpx;
  1272. font-weight: bold;
  1273. display: flex;
  1274. align-items: center;
  1275. justify-content: center;
  1276. border: none;
  1277. margin: 0 0;
  1278. }
  1279. .brand-confirm-btn.retry {
  1280. background: #fff;
  1281. color: #ff9c00;
  1282. border: 2rpx solid #ff9c00;
  1283. }
  1284. .brand-confirm-btn.confirm {
  1285. background: linear-gradient(to right, #ffd01e, #ff8917);
  1286. color: #fff;
  1287. border: none;
  1288. }
  1289. </style>