detail.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. <template>
  2. <view class="detail" @click="handleClickOutside">
  3. <u-navbar class="nav-bar" title="商品详情档案" :autoBack="true" :placeholder="true" rightIcon="more-dot-fill" v-hideNav></u-navbar>
  4. <u-swiper :list="imgs" keyName="url" indicator indicatorMode="line" circular>
  5. <!-- <template v-slot:item="{ item, index }">
  6. <view style="width: 100%; height: 600rpx;">
  7. <image :src="item.url" mode="aspectFill" style="width: 100%; height: 100%; object-fit: cover;"></image>
  8. </view>
  9. </template> -->
  10. </u-swiper>
  11. <!-- 立即下架按钮 -->
  12. <view class="immediate-off-shelf">
  13. <u-button type="error" shape="circle" size="large" @click="handleOffShelf">
  14. <u-icon name="download" size="38rpx" color="#ffffff"></u-icon>
  15. <text>立即下架</text>
  16. </u-button>
  17. </view>
  18. <!-- 轮播图下方操作按钮 -->
  19. <view class="swiper-actions">
  20. <view class="action-item">
  21. <u-icon name="download" size="44rpx" color="#606266"></u-icon>
  22. <text class="action-text">下载图文</text>
  23. </view>
  24. <view class="action-item">
  25. <u-icon name="share" size="44rpx" color="#606266"></u-icon>
  26. <text class="action-text">分享</text>
  27. </view>
  28. <view class="action-item">
  29. <u-icon name="camera" size="44rpx" color="#606266"></u-icon>
  30. <text class="action-text">切换单图</text>
  31. </view>
  32. <view class="action-item">
  33. <u-icon name="cut" size="44rpx" color="#606266"></u-icon>
  34. <text class="action-text">智能抠图</text>
  35. </view>
  36. </view>
  37. <!-- 核心信息区域 -->
  38. <view class="core-info">
  39. <view class="section-title">核心信息</view>
  40. <view class="info-row">
  41. <view class="info-label">品牌</view>
  42. <view class="info-value" @click.stop="toggleEditField('brand', coreInfo.brand)">
  43. <u-input v-if="editMode.brand" v-model="tempValues.brand" @blur="saveEditField('brand', tempValues.brand, 'core', 'brand')" :autoFocus="true" />
  44. <span v-else>{{ coreInfo.brand }}</span>
  45. </view>
  46. </view>
  47. <view class="info-row">
  48. <view class="info-label">型号</view>
  49. <view class="info-value" @click.stop="toggleEditField('model', coreInfo.model)">
  50. <u-input v-if="editMode.model" v-model="tempValues.model" @blur="saveEditField('model', tempValues.model, 'core', 'model')" :autoFocus="true" />
  51. <span v-else>{{ coreInfo.model }}</span>
  52. </view>
  53. </view>
  54. <view class="info-row">
  55. <view class="info-label">独立编码</view>
  56. <view class="info-value code" @click.stop="toggleEditField('code', coreInfo.code)">
  57. <u-input v-if="editMode.code" v-model="tempValues.code" @blur="saveEditField('code', tempValues.code, 'core', 'code')" :autoFocus="true" />
  58. <span v-else>{{ coreInfo.code }}</span>
  59. </view>
  60. </view>
  61. <view class="info-row">
  62. <view class="info-label">入库日期</view>
  63. <view class="info-value">{{ coreInfo.warehouseDate }}</view>
  64. </view>
  65. <view class="info-row">
  66. <view class="info-label">付款方式</view>
  67. <view class="info-value">{{ coreInfo.paymentMethod }}</view>
  68. </view>
  69. <view class="info-row col">
  70. <view class="info-label">备注信息</view>
  71. <view class="info-value note" @click.stop="toggleEditField('note', coreInfo.note)">
  72. <textarea v-if="editMode.note" v-model="tempValues.note" @blur="saveEditField('note', tempValues.note, 'core', 'note')" :autoFocus="true" rows="3" />
  73. <span v-else>{{ coreInfo.note }}</span>
  74. </view>
  75. </view>
  76. </view>
  77. <!-- 财务与价格区域 -->
  78. <view class="finance-price">
  79. <view class="section-title">财务与价格</view>
  80. <view class="price-group">
  81. <view class="price-item">
  82. <view class="price-label">原始成本</view>
  83. <view class="price-value original" @click.stop="toggleEditField('originalCost', financePrice.originalCost)">
  84. <u-input v-if="editMode.originalCost" v-model="tempValues.originalCost" @blur="saveEditField('originalCost', tempValues.originalCost, 'finance', 'originalCost')" :autoFocus="true" />
  85. <span v-else>¥{{ financePrice.originalCost }}</span>
  86. </view>
  87. </view>
  88. <view class="price-item">
  89. <view class="price-label">附加成本</view>
  90. <view class="price-value additional" @click.stop="toggleEditField('additionalCost', financePrice.additionalCost)">
  91. <u-input v-if="editMode.additionalCost" v-model="tempValues.additionalCost" @blur="saveEditField('additionalCost', tempValues.additionalCost, 'finance', 'additionalCost')" :autoFocus="true" />
  92. <span v-else>¥{{ financePrice.additionalCost }}</span>
  93. </view>
  94. </view>
  95. </view>
  96. <view class="price-group">
  97. <view class="price-item">
  98. <view class="price-label">代理价格</view>
  99. <view class="price-value agent" @click.stop="toggleEditField('agentPrice', financePrice.agentPrice)">
  100. <u-input v-if="editMode.agentPrice" v-model="tempValues.agentPrice" @blur="saveEditField('agentPrice', tempValues.agentPrice, 'finance', 'agentPrice')" :autoFocus="true" />
  101. <span v-else>¥{{ financePrice.agentPrice }}</span>
  102. </view>
  103. </view>
  104. <view class="price-item">
  105. <view class="price-label">建议售价</view>
  106. <view class="price-value suggested" @click.stop="toggleEditField('suggestedPrice', financePrice.suggestedPrice)">
  107. <u-input v-if="editMode.suggestedPrice" v-model="tempValues.suggestedPrice" @blur="saveEditField('suggestedPrice', tempValues.suggestedPrice, 'finance', 'suggestedPrice')" :autoFocus="true" />
  108. <span v-else>¥{{ financePrice.suggestedPrice }}</span>
  109. </view>
  110. </view>
  111. </view>
  112. </view>
  113. <!-- 溯源与位置区域 -->
  114. <view class="traceability-location">
  115. <view class="section-title">溯源与位置</view>
  116. <view class="info-row">
  117. <view class="info-label">商品位置</view>
  118. <view class="info-value" @click.stop="toggleEditField('location', traceability.location)">
  119. <u-input v-if="editMode.location" v-model="tempValues.location" @blur="saveEditField('location', tempValues.location, 'trace', 'location')" :autoFocus="true" />
  120. <span v-else>{{ traceability.location }}</span>
  121. </view>
  122. </view>
  123. <view class="info-row">
  124. <view class="info-label">回收人员</view>
  125. <view class="info-value" @click.stop="toggleEditField('recoveryPerson', traceability.recoveryPerson)">
  126. <u-input v-if="editMode.recoveryPerson" v-model="tempValues.recoveryPerson" @blur="saveEditField('recoveryPerson', tempValues.recoveryPerson, 'trace', 'recoveryPerson')" :autoFocus="true" />
  127. <span v-else>{{ traceability.recoveryPerson }}</span>
  128. </view>
  129. </view>
  130. <view class="info-row">
  131. <view class="info-label">鉴定人员</view>
  132. <view class="info-value" @click.stop="toggleEditField('authenticationPerson', traceability.authenticationPerson)">
  133. <u-input v-if="editMode.authenticationPerson" v-model="tempValues.authenticationPerson" @blur="saveEditField('authenticationPerson', tempValues.authenticationPerson, 'trace', 'authenticationPerson')" :autoFocus="true" />
  134. <span v-else>{{ traceability.authenticationPerson }}</span>
  135. </view>
  136. </view>
  137. <view class="action-button">
  138. <u-button type="primary" plain size="mini" @click="viewLog">查看操作日志(12条)</u-button>
  139. </view>
  140. </view>
  141. <!-- 底部功能按钮栏 -->
  142. <view class="bottom-bar">
  143. <view class="bar-item" @click.stop="enterGlobalEdit">
  144. <u-icon name="edit-pen" size="46rpx" color="#9ca3af"></u-icon>
  145. <text class="bar-text">编辑</text>
  146. </view>
  147. <view class="bar-item">
  148. <u-icon name="lock" size="46rpx" color="#9ca3af"></u-icon>
  149. <text class="bar-text">锁单</text>
  150. </view>
  151. <view class="bar-item">
  152. <i class="iconfont icon-crm-dayin" style="font-size:46rpx;color: #9ca3af;"></i>
  153. <text class="bar-text">打印</text>
  154. </view>
  155. <view class="bar-item">
  156. <view class="primary">
  157. <u-icon name="bag" size="44rpx" color="#fff"></u-icon>
  158. <text class="bar-text">开单</text>
  159. </view>
  160. </view>
  161. </view>
  162. </view>
  163. </template>
  164. <script>
  165. export default {
  166. data() {
  167. return {
  168. imgs: [
  169. {
  170. url: 'https://img2.baidu.com/it/u=2737617573,3814711807&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800'
  171. },
  172. {
  173. url: 'https://img2.baidu.com/it/u=3621921167,4010012360&fm=253&fmt=auto?w=760&h=760'
  174. },
  175. {
  176. url: 'https://img2.baidu.com/it/u=1250952949,1454201719&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1067'
  177. }
  178. ],
  179. // 核心信息模拟数据
  180. coreInfo: {
  181. brand: 'Rolex',
  182. model: 'Submariner Date 126610LN',
  183. code: 'AUTO_1002391',
  184. warehouseDate: '2025-12-14 10:00',
  185. paymentMethod: '线上转账',
  186. note: '单包 附件齐全 成色极好'
  187. },
  188. // 财务与价格模拟数据
  189. financePrice: {
  190. originalCost: '82,000',
  191. additionalCost: '500',
  192. agentPrice: '85,500',
  193. suggestedPrice: '89,000'
  194. },
  195. // 溯源与位置模拟数据
  196. traceability: {
  197. location: '上海A仓',
  198. recoveryPerson: 'IT秦',
  199. authenticationPerson: '中检-刘师傅'
  200. },
  201. // 编辑状态管理
  202. editMode: {
  203. // 核心信息编辑状态
  204. brand: false,
  205. model: false,
  206. code: false,
  207. note: false,
  208. // 财务与价格编辑状态
  209. originalCost: false,
  210. additionalCost: false,
  211. agentPrice: false,
  212. suggestedPrice: false,
  213. // 溯源与位置编辑状态
  214. location: false,
  215. recoveryPerson: false,
  216. authenticationPerson: false
  217. },
  218. // 全局编辑模式
  219. globalEditMode: false,
  220. // 临时存储编辑值
  221. tempValues: {}
  222. }
  223. },
  224. methods: {
  225. // 查看操作日志的方法
  226. viewLog() {
  227. // 查看操作日志的方法
  228. console.log('查看操作日志');
  229. },
  230. // 立即下架按钮处理方法
  231. handleOffShelf() {
  232. // 处理下架逻辑
  233. uni.showModal({
  234. title: '确认下架',
  235. content: '确定要将此商品下架吗?',
  236. success: (res) => {
  237. if (res.confirm) {
  238. console.log('商品已下架');
  239. uni.showToast({
  240. title: '已下架',
  241. icon: 'success'
  242. });
  243. }
  244. }
  245. });
  246. },
  247. // 切换单个字段的编辑状态
  248. toggleEditField(field, value) {
  249. // 如果不是全局编辑模式
  250. if (!this.globalEditMode) {
  251. // 重置所有编辑状态
  252. this.resetEditMode();
  253. // 设置当前字段为编辑状态
  254. this.editMode[field] = true;
  255. // 保存临时值
  256. this.tempValues[field] = value;
  257. }
  258. },
  259. // 保存单个字段的编辑值
  260. saveEditField(field, newValue, type, fieldName) {
  261. // 更新对应的数据
  262. if (type === 'core') {
  263. this.coreInfo[fieldName] = newValue;
  264. } else if (type === 'finance') {
  265. this.financePrice[fieldName] = newValue;
  266. } else if (type === 'trace') {
  267. this.traceability[fieldName] = newValue;
  268. }
  269. // 退出编辑状态
  270. this.editMode[field] = false;
  271. // 清空临时值
  272. delete this.tempValues[field];
  273. // 模拟保存操作
  274. console.log(`保存${field}字段值: ${newValue}`);
  275. },
  276. // 进入全局编辑模式
  277. enterGlobalEdit() {
  278. this.globalEditMode = true;
  279. // 设置所有可编辑字段为编辑状态
  280. this.editMode = {
  281. brand: true,
  282. model: true,
  283. code: true,
  284. note: true,
  285. originalCost: true,
  286. additionalCost: true,
  287. agentPrice: true,
  288. suggestedPrice: true,
  289. location: true,
  290. recoveryPerson: true,
  291. authenticationPerson: true
  292. };
  293. // 保存所有字段的临时值
  294. this.tempValues = {
  295. brand: this.coreInfo.brand,
  296. model: this.coreInfo.model,
  297. code: this.coreInfo.code,
  298. note: this.coreInfo.note,
  299. originalCost: this.financePrice.originalCost,
  300. additionalCost: this.financePrice.additionalCost,
  301. agentPrice: this.financePrice.agentPrice,
  302. suggestedPrice: this.financePrice.suggestedPrice,
  303. location: this.traceability.location,
  304. recoveryPerson: this.traceability.recoveryPerson,
  305. authenticationPerson: this.traceability.authenticationPerson
  306. };
  307. },
  308. // 保存全局编辑模式下的所有修改
  309. saveGlobalEdit() {
  310. // 保存所有临时值到原始数据
  311. // 核心信息
  312. if (this.tempValues.brand !== undefined) this.coreInfo.brand = this.tempValues.brand;
  313. if (this.tempValues.model !== undefined) this.coreInfo.model = this.tempValues.model;
  314. if (this.tempValues.code !== undefined) this.coreInfo.code = this.tempValues.code;
  315. if (this.tempValues.note !== undefined) this.coreInfo.note = this.tempValues.note;
  316. // 财务与价格
  317. if (this.tempValues.originalCost !== undefined) this.financePrice.originalCost = this.tempValues.originalCost;
  318. if (this.tempValues.additionalCost !== undefined) this.financePrice.additionalCost = this.tempValues.additionalCost;
  319. if (this.tempValues.agentPrice !== undefined) this.financePrice.agentPrice = this.tempValues.agentPrice;
  320. if (this.tempValues.suggestedPrice !== undefined) this.financePrice.suggestedPrice = this.tempValues.suggestedPrice;
  321. // 溯源与位置
  322. if (this.tempValues.location !== undefined) this.traceability.location = this.tempValues.location;
  323. if (this.tempValues.recoveryPerson !== undefined) this.traceability.recoveryPerson = this.tempValues.recoveryPerson;
  324. if (this.tempValues.authenticationPerson !== undefined) this.traceability.authenticationPerson = this.tempValues.authenticationPerson;
  325. this.globalEditMode = false;
  326. // 退出所有编辑状态
  327. this.resetEditMode();
  328. // 清空临时值
  329. this.tempValues = {};
  330. // 模拟保存操作
  331. console.log('保存所有字段值');
  332. },
  333. // 重置所有编辑状态
  334. resetEditMode() {
  335. Object.keys(this.editMode).forEach(key => {
  336. this.editMode[key] = false;
  337. });
  338. },
  339. // 点击页面其他地方保存所有编辑
  340. handleClickOutside() {
  341. if (this.globalEditMode) {
  342. this.saveGlobalEdit();
  343. } else {
  344. // 保存当前正在编辑的字段
  345. Object.keys(this.editMode).forEach(key => {
  346. if (this.editMode[key]) {
  347. // 根据字段名确定类型和字段名
  348. if (['brand', 'model', 'code', 'note'].includes(key)) {
  349. this.saveEditField(key, this.tempValues[key], 'core', key);
  350. } else if (['originalCost', 'additionalCost', 'agentPrice', 'suggestedPrice'].includes(key)) {
  351. this.saveEditField(key, this.tempValues[key], 'finance', key);
  352. } else if (['location', 'recoveryPerson', 'authenticationPerson'].includes(key)) {
  353. this.saveEditField(key, this.tempValues[key], 'trace', key);
  354. }
  355. }
  356. });
  357. }
  358. }
  359. }
  360. }
  361. </script>
  362. <style lang="scss" scoped>
  363. @import "./styles/detail.scss";
  364. </style>