LNOrderDetailCardView.swift 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. //
  2. // LNOrderDetailCardView.swift
  3. // Lanu
  4. //
  5. // Created by OneeChan on 2025/12/23.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. enum LNOrderDetailCardViewType {
  11. case normal
  12. case small
  13. }
  14. class LNOrderDetailCardView: UIView {
  15. private let curType: LNOrderDetailCardViewType
  16. private let avatar = UIImageView()
  17. private let nameLabel = UILabel()
  18. private let gameLabel = UILabel()
  19. private let priceLabel = UILabel()
  20. private let countLabel = UILabel()
  21. private var extraView: UIView?
  22. private let extraLabel = UILabel()
  23. private let orderIdLabel = UILabel()
  24. private let timeLabel = UILabel()
  25. private let totalLabel = UILabel()
  26. private var discountView: UIView?
  27. private let discountLabel = UILabel()
  28. init(type: LNOrderDetailCardViewType = .normal) {
  29. curType = type
  30. super.init(frame: .zero)
  31. setupViews()
  32. }
  33. func update(_ item: LNOrderDetailResponse) {
  34. avatar.showAvatar(item.orderInfo.avatar)
  35. nameLabel.text = item.orderInfo.nickname
  36. gameLabel.text = item.orderInfo.bizCategoryName
  37. priceLabel.text = "\(item.orderInfo.price.toDisplay)"
  38. countLabel.text = "\(item.orderInfo.unit)x\(item.orderInfo.purchaseQty)"
  39. extraLabel.text = item.orderInfo.customerRemark
  40. extraView?.isHidden = item.orderInfo.customerRemark.isEmpty
  41. orderIdLabel.text = item.orderInfo.orderId
  42. timeLabel.text = (TimeInterval(item.orderInfo.createTime) / 1000.0).formattedFullDateWithTime()
  43. totalLabel.text = item.orderInfo.totalAmount.toDisplay
  44. discountView?.isHidden = item.orderInfo.totalAmount >= item.orderInfo.price * Double(item.orderInfo.purchaseQty)
  45. discountLabel.text = "\(item.orderInfo.totalAmount - item.orderInfo.price * Double(item.orderInfo.purchaseQty))"
  46. }
  47. required init?(coder: NSCoder) {
  48. fatalError("init(coder:) has not been implemented")
  49. }
  50. }
  51. extension LNOrderDetailCardView {
  52. private func setupViews() {
  53. layer.cornerRadius = 12
  54. backgroundColor = .fill
  55. let stackView = UIStackView()
  56. stackView.axis = .vertical
  57. stackView.spacing = curType == .normal ? 2 : 6
  58. addSubview(stackView)
  59. stackView.snp.makeConstraints { make in
  60. make.horizontalEdges.equalToSuperview()
  61. make.verticalEdges.equalToSuperview().inset(curType == .normal ? 8 : 10)
  62. }
  63. stackView.addArrangedSubview(buildUserInfo())
  64. if curType == .normal {
  65. stackView.addArrangedSubview(buildLine())
  66. }
  67. gameLabel.font = .body_s
  68. gameLabel.textColor = .text_5
  69. let gameInfo = buildDetailInfo(title: .init(key: "A00131"), contentView: gameLabel)
  70. stackView.addArrangedSubview(gameInfo)
  71. let priceView = buildPrice()
  72. stackView.addArrangedSubview(priceView)
  73. countLabel.font = curType == .normal ? .body_s : .body_xs
  74. countLabel.textColor = .text_5
  75. let countView = buildDetailInfo(title: .init(key: "A00122"), contentView: countLabel)
  76. stackView.addArrangedSubview(countView)
  77. let discountView = buildDiscount()
  78. stackView.addArrangedSubview(discountView)
  79. self.discountView = discountView
  80. extraLabel.font = curType == .normal ? .body_s : .body_xs
  81. extraLabel.textColor = .text_5
  82. extraLabel.numberOfLines = 0
  83. extraLabel.textAlignment = .right
  84. let extraView = buildDetailInfo(title: .init(key: "A00086"), contentView: extraLabel)
  85. stackView.addArrangedSubview(extraView)
  86. self.extraView = extraView
  87. orderIdLabel.font = curType == .normal ? .body_s : .body_xs
  88. orderIdLabel.textColor = .text_5
  89. let orderView = buildDetailInfo(title: .init(key: "A00132"), contentView: orderIdLabel)
  90. stackView.addArrangedSubview(orderView)
  91. timeLabel.font = curType == .normal ? .body_s : .body_xs
  92. timeLabel.textColor = .text_5
  93. let timeView = buildDetailInfo(title: .init(key: "A00133"), contentView: timeLabel)
  94. stackView.addArrangedSubview(timeView)
  95. stackView.addArrangedSubview(buildLine())
  96. stackView.addArrangedSubview(buildTotal())
  97. }
  98. private func buildUserInfo() -> UIView {
  99. let container = UIView()
  100. container.snp.makeConstraints { make in
  101. make.height.equalTo(curType == .normal ? 48 : 30)
  102. }
  103. avatar.layer.cornerRadius = curType == .normal ? 20 : 13
  104. avatar.clipsToBounds = true
  105. container.addSubview(avatar)
  106. avatar.snp.makeConstraints { make in
  107. make.centerY.equalToSuperview()
  108. make.leading.equalToSuperview().offset(12)
  109. make.width.height.equalTo(curType == .normal ? 40 : 26)
  110. }
  111. nameLabel.font = .heading_h4
  112. nameLabel.textColor = .text_5
  113. container.addSubview(nameLabel)
  114. nameLabel.snp.makeConstraints { make in
  115. make.centerY.equalToSuperview()
  116. make.leading.equalTo(avatar.snp.trailing).offset(8)
  117. make.trailing.lessThanOrEqualToSuperview()
  118. }
  119. return container
  120. }
  121. private func buildLine() -> UIView {
  122. let container = UIView()
  123. container.snp.makeConstraints { make in
  124. make.height.equalTo(curType == .normal ? 20 : 0.5)
  125. }
  126. let line = UIView()
  127. line.backgroundColor = .fill_2
  128. container.addSubview(line)
  129. line.snp.makeConstraints { make in
  130. make.horizontalEdges.equalToSuperview().inset(10)
  131. make.centerY.equalToSuperview()
  132. make.height.equalTo(0.5)
  133. }
  134. return container
  135. }
  136. private func buildDetailInfo(title: String, contentView: UIView) -> UIView {
  137. let container = UIView()
  138. container.snp.makeConstraints { make in
  139. make.height.equalTo(curType == .normal ? 30 : 18).priority(.medium)
  140. }
  141. let titleLabel = UILabel()
  142. titleLabel.font = curType == .normal ? .body_s : .body_xs
  143. titleLabel.textColor = .text_5
  144. titleLabel.text = title
  145. container.addSubview(titleLabel)
  146. titleLabel.snp.makeConstraints { make in
  147. make.leading.equalToSuperview().offset(12)
  148. make.top.equalToSuperview().offset(curType == .normal ? 8 : 2)
  149. }
  150. container.addSubview(contentView)
  151. contentView.snp.makeConstraints { make in
  152. make.centerY.equalToSuperview()
  153. make.trailing.equalToSuperview().offset(-12)
  154. make.leading.greaterThanOrEqualTo(titleLabel.snp.trailing).offset(24)
  155. make.top.greaterThanOrEqualToSuperview().offset(curType == .normal ? 8 : 2)
  156. }
  157. return container
  158. }
  159. private func buildPrice() -> UIView {
  160. let priceView = UIView()
  161. let coin = UIImageView.coinImageView()
  162. priceView.addSubview(coin)
  163. coin.snp.makeConstraints { make in
  164. make.leading.centerY.equalToSuperview()
  165. make.width.height.equalTo(14)
  166. }
  167. priceLabel.font = .body_s
  168. priceLabel.textColor = .text_5
  169. priceView.addSubview(priceLabel)
  170. priceLabel.snp.makeConstraints { make in
  171. make.verticalEdges.equalToSuperview()
  172. make.trailing.equalToSuperview()
  173. make.leading.equalTo(coin.snp.trailing)
  174. }
  175. return buildDetailInfo(title: .init(key: "A00128"), contentView: priceView)
  176. }
  177. private func buildDiscount() -> UIView {
  178. let discountView = UIView()
  179. let coin = UIImageView.coinImageView()
  180. discountView.addSubview(coin)
  181. coin.snp.makeConstraints { make in
  182. make.leading.centerY.equalToSuperview()
  183. make.width.height.equalTo(14)
  184. }
  185. discountLabel.font = .body_s
  186. discountLabel.textColor = .text_5
  187. discountView.addSubview(discountLabel)
  188. discountLabel.snp.makeConstraints { make in
  189. make.verticalEdges.equalToSuperview()
  190. make.trailing.equalToSuperview()
  191. make.leading.equalTo(coin.snp.trailing)
  192. }
  193. return buildDetailInfo(title: .init(key: "A00129"), contentView: discountView)
  194. }
  195. private func buildTotal() -> UIView {
  196. let container = UIView()
  197. container.snp.makeConstraints { make in
  198. make.height.equalTo(38)
  199. }
  200. totalLabel.font = .heading_h3
  201. totalLabel.textColor = .text_5
  202. container.addSubview(totalLabel)
  203. totalLabel.snp.makeConstraints { make in
  204. make.centerY.equalToSuperview()
  205. make.trailing.equalToSuperview().offset(-12)
  206. }
  207. let coin = UIImageView.coinImageView()
  208. container.addSubview(coin)
  209. coin.snp.makeConstraints { make in
  210. make.centerY.equalToSuperview()
  211. make.trailing.equalTo(totalLabel.snp.leading)
  212. make.width.height.equalTo(18)
  213. }
  214. let text = UILabel()
  215. text.font = .body_s
  216. text.textColor = .text_5
  217. text.text = .init(key: "A00124")
  218. container.addSubview(text)
  219. text.snp.makeConstraints { make in
  220. make.centerY.equalToSuperview()
  221. make.trailing.equalTo(coin.snp.leading)
  222. }
  223. return container
  224. }
  225. }