pageFour.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. <template>
  2. <view class="page-container">
  3. <!-- 入库信息卡片 -->
  4. <view class="card_wrap">
  5. <view class="address-section">
  6. <view class="address-header">
  7. <u-icon name="car-fill" size="36rpx" color="#108cff" class="location-icon"></u-icon>
  8. <text class="address-title">入库信息</text>
  9. </view>
  10. <!-- 编码和快递单号同一行 -->
  11. <u-row class="info-row" justify="space-between">
  12. <u-col span="4.5">
  13. <view class="info-label">编码</view>
  14. <u--input v-model="warehouseInfo.accountHolder" placeholder="请输入编码" class="info-input" />
  15. </u-col>
  16. <u-col span="4.5">
  17. <view class="info-label">快递单号</view>
  18. <u--input v-model="warehouseInfo.bankName" placeholder="请输入快递单号" class="info-input" />
  19. </u-col>
  20. <u-col span="2">
  21. <view class="info-label">物流图片</view>
  22. <view class="image-uploader" @click="selectImage">
  23. <u-icon v-if="!warehouseInfo.uploadedImage" name="camera-fill" size="48rpx" color="#909399"
  24. class="camera-icon"></u-icon>
  25. <image v-else :src="warehouseInfo.uploadedImage" mode="aspectFill" class="image-preview">
  26. </image>
  27. </view>
  28. </u-col>
  29. </u-row>
  30. <!-- 单独一行的收单物品 -->
  31. <u-row class="info-row">
  32. <u-col span="12">
  33. <view class="info-label">收单物品</view>
  34. <u--input v-model="warehouseInfo.item" placeholder="请输入收单物品" class="info-input" />
  35. </u-col>
  36. </u-row>
  37. <!-- 查码费和表款同一行 -->
  38. <u-row class="info-row" justify="space-between">
  39. <u-col span="5.8">
  40. <view class="info-label">查码费</view>
  41. <u--input v-model="warehouseInfo.checkCodeFee" placeholder="请输入查码费" class="info-input"
  42. type="number" />
  43. </u-col>
  44. <u-col span="5.8">
  45. <view class="info-label">表款</view>
  46. <u--input v-model="warehouseInfo.tableFee" placeholder="请输入表款" class="info-input"
  47. type="number" />
  48. </u-col>
  49. </u-row>
  50. <!-- 维修金额和毛业绩同一行 -->
  51. <u-row class="info-row" justify="space-between">
  52. <u-col span="5.8">
  53. <view class="info-label">维修金额</view>
  54. <u--input v-model="warehouseInfo.repairAmount" placeholder="请输入维修金额" class="info-input"
  55. type="number" />
  56. </u-col>
  57. <u-col span="5.8">
  58. <view class="info-label">毛业绩</view>
  59. <u--input v-model="warehouseInfo.grossPerformance" placeholder="请输入毛业绩" class="info-input"
  60. type="number" />
  61. </u-col>
  62. </u-row>
  63. <!-- 收单备注 -->
  64. <u-row class="info-row">
  65. <u-col span="12">
  66. <view class="info-label">收单备注</view>
  67. <u--textarea v-model="warehouseInfo.remarks" placeholder="请输入收单备注" class="info-input"
  68. confirmType="done" rows="4" />
  69. </u-col>
  70. </u-row>
  71. </view>
  72. </view>
  73. <!-- 新添加的卡片 -->
  74. <view class="card_wrap">
  75. <view class="address-section">
  76. <view class="address-header">
  77. <u-icon name="list" size="36rpx" color="#108cff" class="location-icon"></u-icon>
  78. <text class="address-title">分成信息</text>
  79. <u-button type="primary" plain shape="circle" size="mini" class="add-button" @click="addSplit">
  80. <u-icon name="plus" size="24rpx" color="#108cff"></u-icon>
  81. <text>添加</text>
  82. </u-button>
  83. </view>
  84. </view>
  85. <!-- 分成信息表格 -->
  86. <view class="split-table">
  87. <u-row class="split-table-header">
  88. <u-col span="2">
  89. <text class="header-text">关联</text>
  90. </u-col>
  91. <u-col span="2">
  92. <text class="header-text">账户类型</text>
  93. </u-col>
  94. <u-col span="2">
  95. <text class="header-text">分成人</text>
  96. </u-col>
  97. <u-col span="2">
  98. <text class="header-text">比例(%)</text>
  99. </u-col>
  100. <u-col span="2">
  101. <text class="header-text">归属公司</text>
  102. </u-col>
  103. <u-col span="2" class="action-column">
  104. <text class="header-text">操作</text>
  105. </u-col>
  106. </u-row>
  107. <u-row v-for="(item, index) in profitSharingList" :key="item.id" class="split-table-row">
  108. <u-col span="2">
  109. <view class="table-cell">
  110. <select v-model="item.association" class="custom-select">
  111. <option value="">无</option>
  112. <option v-for="option in associationOptions" :key="option" :value="option">
  113. {{ option }}
  114. </option>
  115. </select>
  116. </view>
  117. </u-col>
  118. <u-col span="2">
  119. <view class="table-cell">
  120. <view :class="['account-type', item.accountType === 'frontend' ? 'frontend' : 'backend']"
  121. @click="toggleAccountType(item)" style="cursor: pointer;">
  122. {{ item.accountType === 'frontend' ? '前' : '后' }}
  123. </view>
  124. </view>
  125. </u-col>
  126. <u-col span="2">
  127. <view class="table-cell">
  128. <select v-model="item.person" class="custom-select">
  129. <option value="">无</option>
  130. <option v-for="person in personOptions" :key="person" :value="person">
  131. {{ person }}
  132. </option>
  133. </select>
  134. </view>
  135. </u-col>
  136. <u-col span="2">
  137. <view class="table-cell">
  138. <u--input v-model="item.percentage" type="number" class="percentage-input"
  139. @input="handlePercentageInput(item)" min="0" max="100" precision="0" />
  140. </view>
  141. </u-col>
  142. <u-col span="2">
  143. <view class="table-cell">
  144. <view class="radio-wrapper" @click="toggleBelongToCompany(item)">
  145. <view :class="['radio-circle', item.belongToCompany ? 'active' : '']">
  146. <u-icon v-if="item.belongToCompany" name="checkmark" size="20rpx"
  147. color="#fff"></u-icon>
  148. </view>
  149. </view>
  150. </view>
  151. </u-col>
  152. <u-col span="2" class="action-column">
  153. <view class="table-cell">
  154. <u-button type="error" plain shape="circle" size="mini" @click="deleteSplit(index)"
  155. :disabled="profitSharingList.length <= 1">
  156. <u-icon name="trash" size="20rpx" color="#ff6b6b"></u-icon>
  157. </u-button>
  158. </view>
  159. </u-col>
  160. </u-row>
  161. </view>
  162. </view>
  163. </view>
  164. </template>
  165. <script>
  166. export default {
  167. data() {
  168. return {
  169. // 入库信息相关的数据
  170. warehouseInfo: {
  171. accountHolder: '',
  172. bankName: '',
  173. item: '',
  174. checkCodeFee: '',
  175. tableFee: '',
  176. repairAmount: '',
  177. grossPerformance: '',
  178. remarks: '',
  179. uploadedImage: ''
  180. },
  181. // 分成信息相关的数据
  182. profitSharingList: [
  183. {
  184. id: Date.now() + '_1', // 唯一ID
  185. association: '', // 关联
  186. accountType: 'frontend', // 账户类型:frontend(前端)/backend(后端)
  187. person: '', // 分成人
  188. percentage: 100, // 分成比例
  189. belongToCompany: false // 归属公司
  190. }
  191. ],
  192. // 关联选项列表
  193. associationOptions: ['选项1', '选项2', '选项3'],
  194. // 分成人选项列表
  195. personOptions: ['人员A', '人员B', '人员C']
  196. };
  197. },
  198. methods: {
  199. // 选择图片
  200. selectImage() {
  201. uni.chooseImage({
  202. count: 1,
  203. sizeType: ['original', 'compressed'],
  204. sourceType: ['album', 'camera'],
  205. success: (res) => {
  206. const tempFilePath = res.tempFilePaths[0];
  207. this.warehouseInfo.uploadedImage = tempFilePath;
  208. }
  209. });
  210. },
  211. // 添加分成行
  212. addSplit() {
  213. // 生成唯一ID
  214. const newId = Date.now() + '_' + (this.profitSharingList.length + 1);
  215. // 添加新行
  216. this.profitSharingList.push({
  217. id: newId,
  218. association: '',
  219. accountType: 'frontend',
  220. person: '',
  221. percentage: 0,
  222. belongToCompany: false
  223. });
  224. // 重新计算所有行的比例
  225. this.recalculatePercentage();
  226. },
  227. // 删除分成行
  228. deleteSplit(index) {
  229. if (this.profitSharingList.length <= 1) {
  230. return; // 至少保留一行
  231. }
  232. // 删除对应行
  233. this.profitSharingList.splice(index, 1);
  234. // 重新计算所有行的比例
  235. this.recalculatePercentage();
  236. },
  237. // 重新计算分成比例
  238. recalculatePercentage() {
  239. const totalRows = this.profitSharingList.length;
  240. if (totalRows > 0) {
  241. // 计算平均比例(向下取整)
  242. const avgPercentage = Math.floor(100 / totalRows);
  243. // 设置所有行的比例
  244. this.profitSharingList.forEach(item => {
  245. item.percentage = avgPercentage;
  246. });
  247. }
  248. },
  249. // 切换账户类型
  250. toggleAccountType(item) {
  251. item.accountType = item.accountType === 'frontend' ? 'backend' : 'frontend';
  252. },
  253. // 处理百分比输入
  254. handlePercentageInput(item) {
  255. // 确保输入是数字
  256. let value = Number(item.percentage);
  257. // 验证输入值是否在有效范围内(0-100)
  258. if (isNaN(value)) {
  259. item.percentage = 0;
  260. } else if (value < 0) {
  261. item.percentage = 0;
  262. } else if (value > 100) {
  263. item.percentage = 100;
  264. } else {
  265. // 确保是整数
  266. item.percentage = Math.floor(value);
  267. }
  268. },
  269. // 切换归属公司状态
  270. toggleBelongToCompany(item) {
  271. item.belongToCompany = !item.belongToCompany;
  272. }
  273. }
  274. }
  275. </script>
  276. <style lang="scss" scoped>
  277. // 导入公共样式
  278. @import './common.scss';
  279. // 主样式
  280. .page-container {
  281. box-sizing: border-box;
  282. padding: 0;
  283. background-color: map-get($colors, bg);
  284. font-family: map-get($font, family);
  285. -webkit-font-smoothing: map-get($font, smoothing);
  286. font-smoothing: map-get($font, smoothing);
  287. }
  288. .address-section {
  289. padding: map-get($sizes, padding-sm) map-get($sizes, padding);
  290. .u-col {
  291. padding: 0;
  292. box-sizing: border-box;
  293. }
  294. .u-col:first-child {
  295. padding-right: 15rpx;
  296. }
  297. .u-col:last-child {
  298. padding-left: 15rpx;
  299. }
  300. }
  301. // 表单行样式
  302. .info-row {
  303. margin-bottom: 20rpx;
  304. box-sizing: border-box;
  305. padding: 0;
  306. }
  307. // 表单标签样式
  308. .info-label {
  309. @include font-styles($size: tiny, $weight: regular, $color: tertiary);
  310. margin-bottom: 8rpx;
  311. display: block;
  312. }
  313. // 输入框样式
  314. .info-input {
  315. height: 65rpx;
  316. border-radius: 8rpx;
  317. border: 1rpx solid #e5e7eb;
  318. padding: 20rpx 16rpx;
  319. width: 100%;
  320. box-sizing: border-box;
  321. @include font-styles($size: small, $weight: regular, $color: secondary);
  322. // textarea特殊样式
  323. &[type="textarea"] {
  324. min-height: 160rpx;
  325. resize: vertical;
  326. padding-top: 20rpx;
  327. padding-bottom: 20rpx;
  328. }
  329. }
  330. // 图片上传样式
  331. .image-uploader {
  332. width: 100%;
  333. height: 65rpx;
  334. border: 2rpx dashed #409eff;
  335. border-radius: 8rpx;
  336. display: flex;
  337. align-items: center;
  338. justify-content: center;
  339. cursor: pointer;
  340. background-color: #ecf5ff;
  341. box-sizing: border-box;
  342. overflow: hidden;
  343. transition: all 0.3s ease;
  344. &:hover {
  345. border-color: #66b1ff;
  346. background-color: #f0f9ff;
  347. transform: scale(1.02);
  348. }
  349. }
  350. .camera-icon {
  351. margin: 0;
  352. font-size: 32rpx;
  353. color: #409eff;
  354. transition: all 0.3s ease;
  355. }
  356. .image-uploader:hover .camera-icon {
  357. color: #66b1ff;
  358. transform: scale(1.1);
  359. }
  360. .image-preview {
  361. width: 100%;
  362. height: 100%;
  363. object-fit: cover;
  364. border-radius: 10rpx;
  365. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  366. transition: all 0.3s ease;
  367. }
  368. .image-uploader:hover .image-preview {
  369. transform: scale(1.02);
  370. box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
  371. }
  372. .hidden-input {
  373. display: none;
  374. }
  375. // 分成信息卡片样式
  376. .address-header {
  377. display: flex;
  378. align-items: center;
  379. justify-content: space-between;
  380. margin-bottom: 20rpx;
  381. .address-title {
  382. @include font-styles($size: small, $weight: medium, $color: primary);
  383. margin-left: 10rpx;
  384. }
  385. }
  386. .split-content {
  387. padding: 10rpx 0;
  388. }
  389. .split-item {
  390. display: flex;
  391. justify-content: space-between;
  392. align-items: center;
  393. padding: 15rpx 0;
  394. border-bottom: 1rpx solid map-get($colors, border);
  395. &:last-child {
  396. border-bottom: none;
  397. }
  398. }
  399. .split-label {
  400. @include font-styles($size: tiny, $weight: regular, $color: tertiary);
  401. }
  402. .split-value {
  403. @include font-styles($size: small, $weight: regular, $color: secondary);
  404. }
  405. .add-button {
  406. padding: 0;
  407. width: 50rpx;
  408. height: 50rpx;
  409. display: flex;
  410. align-items: center;
  411. justify-content: center;
  412. }
  413. /* 分成信息表格样式 */
  414. .split-table {
  415. width: 100%;
  416. margin-top: 20rpx;
  417. background-color: #fff;
  418. border-radius: 8rpx;
  419. overflow: hidden;
  420. }
  421. .split-table-header {
  422. background-color: #f5f7fa;
  423. padding: 15rpx 0;
  424. border-bottom: 1rpx solid #e4e7ed;
  425. }
  426. .split-table-row {
  427. padding: 15rpx 0;
  428. border-bottom: 1rpx solid #e4e7ed;
  429. align-items: center;
  430. &:last-child {
  431. border-bottom: none;
  432. }
  433. }
  434. .header-text {
  435. @include font-styles($size: tiny, $weight: regular, $color: tertiary);
  436. text-align: center;
  437. display: block;
  438. }
  439. .table-cell {
  440. display: flex;
  441. align-items: center;
  442. justify-content: center;
  443. padding: 0 10rpx;
  444. box-sizing: border-box;
  445. }
  446. .action-column {
  447. display: flex;
  448. align-items: center;
  449. justify-content: center;
  450. }
  451. /* 自定义下拉框样式 - 隐藏原生箭头 */
  452. .custom-select {
  453. width: 100%;
  454. height: 50rpx;
  455. border-radius: 0;
  456. border: 1rpx solid #e5e7eb;
  457. padding: 0 25rpx 0 12rpx;
  458. /* 增加右侧内边距,为自定义箭头留出空间 */
  459. @include font-styles($size: tiny, $weight: regular, $color: secondary);
  460. background-color: #fff;
  461. /* 确保隐藏所有浏览器的原生箭头 */
  462. appearance: none !important;
  463. -webkit-appearance: none !important;
  464. -moz-appearance: none !important;
  465. -o-appearance: none !important;
  466. cursor: pointer;
  467. /* 使用自定义SVG箭头 */
  468. background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23909399' d='M6 8l-4-4h8z'/%3E%3C/svg%3E");
  469. background-repeat: no-repeat;
  470. background-position: right 8rpx center;
  471. background-size: 12rpx 12rpx;
  472. box-sizing: border-box;
  473. position: relative;
  474. /* 防止箭头在焦点状态下显示 */
  475. &:focus {
  476. outline: none;
  477. border-color: #409eff;
  478. box-shadow: 0 0 0 2rpx rgba(64, 158, 255, 0.2);
  479. }
  480. /* 针对IE/Edge浏览器的特殊处理 */
  481. &::-ms-expand {
  482. display: none !important;
  483. }
  484. /* 针对某些旧版浏览器的额外处理 */
  485. &::-webkit-select-arrow {
  486. display: none !important;
  487. }
  488. /* 添加伪元素覆盖可能残留的箭头 */
  489. &::after {
  490. content: '';
  491. position: absolute;
  492. right: 8rpx;
  493. top: 50%;
  494. transform: translateY(-50%);
  495. width: 12rpx;
  496. height: 12rpx;
  497. background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23909399' d='M6 8l-4-4h8z'/%3E%3C/svg%3E");
  498. background-repeat: no-repeat;
  499. background-size: 100% 100%;
  500. pointer-events: none;
  501. z-index: 1;
  502. }
  503. }
  504. /* 百分比输入框样式 */
  505. .percentage-input {
  506. text-align: center;
  507. background-color: #f9f9f9;
  508. color: #606266;
  509. }
  510. /* 账户类型标签样式 */
  511. .account-type {
  512. padding: 4rpx 16rpx;
  513. border-radius: 12rpx;
  514. font-size: 24rpx;
  515. font-weight: 500;
  516. color: #fff;
  517. text-align: center;
  518. }
  519. .account-type.frontend {
  520. background-color: #409eff;
  521. }
  522. .account-type.backend {
  523. background-color: #909399;
  524. }
  525. /* 调整表格布局,使其更紧凑 */
  526. .split-table {
  527. width: 100%;
  528. margin-top: 10rpx;
  529. }
  530. .split-table-header,
  531. .split-table-row {
  532. padding: 10rpx 0;
  533. }
  534. .table-cell {
  535. padding: 0 5rpx;
  536. }
  537. /* 调整输入框样式 */
  538. .percentage-input {
  539. width: 80%;
  540. height: 50rpx;
  541. font-size: 28rpx;
  542. }
  543. /* 归属公司单选框样式 */
  544. .radio-wrapper {
  545. cursor: pointer;
  546. display: flex;
  547. align-items: center;
  548. justify-content: center;
  549. }
  550. .radio-circle {
  551. width: 32rpx;
  552. height: 32rpx;
  553. border-radius: 50%;
  554. border: 2rpx solid #dcdfe6;
  555. display: flex;
  556. align-items: center;
  557. justify-content: center;
  558. transition: all 0.3s ease;
  559. }
  560. .radio-circle.active {
  561. border-color: #67c23a;
  562. background-color: #67c23a;
  563. }
  564. /* 响应式布局调整 */
  565. @media screen and (max-width: 750rpx) {
  566. .split-table {
  567. overflow-x: auto;
  568. }
  569. .custom-select {
  570. width: 100%;
  571. }
  572. .account-type {
  573. padding: 2rpx 10rpx;
  574. font-size: 22rpx;
  575. }
  576. }
  577. @media screen and (min-width: 751rpx) {
  578. .table-cell {
  579. padding: 0 10rpx;
  580. }
  581. }
  582. </style>