yyb
2026-05-12 324f1e7a665780eb432c3494b0c9d2f694e4f749
合格出库增加发货信息样式修改
已修改2个文件
767 ■■■■■ 文件已修改
src/pages/inventoryManagement/scanIn/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/inventoryManagement/scanOut/index.vue 762 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/inventoryManagement/scanIn/index.vue
@@ -584,6 +584,9 @@
  .module-icon {
    width: 140rpx;
    height: 140rpx;
    min-width: 140rpx;
    min-height: 140rpx;
    flex-shrink: 0;
    border-radius: 32rpx;
    display: flex;
    justify-content: center;
@@ -604,6 +607,8 @@
  .module-info {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
  }
  .module-label {
src/pages/inventoryManagement/scanOut/index.vue
@@ -26,9 +26,9 @@
        <view class="module-info">
          <text class="module-label">合格发货</text>
          <text class="module-label">合格出库</text>
          <text class="module-desc">扫描销售订单,填写发货数量、车牌与审批人后提交发货审批(通过后自动发货)</text>
          <text class="module-desc">记录合格品的出库流向,销售二维码扫描发货</text>
        </view>
@@ -237,19 +237,31 @@
        <view class="scan-ship-title">发货信息</view>
        <u-form label-width="160rpx">
        <u-form label-width="220rpx">
          <u-form-item label="发货方式"
                       class="scan-ship-type-form-item"
                       required>
            <view class="scan-ship-type-trigger"
                  @tap.stop="openScanShipTypeSheet">
            <u-input v-model="scanShipTypeLabel"
                     readonly
                     placeholder="请选择"
                       placeholder="请选择" />
                     @click="scanShipTypeSheetShow = true" />
              <u-icon name="arrow-right"
                      color="#c0c4cc"
                      size="18" />
            </view>
          </u-form-item>
@@ -283,31 +295,91 @@
        </u-form>
        <view class="scan-ship-approval">
        <view class="approval-process">
          <text class="scan-ship-subtitle">审批人</text>
          <view class="approval-header">
          <view v-if="scanShipApprover.nickName"
            <text class="approval-title">审批流程</text>
                class="scan-ship-approver-pill">
            <text>{{ scanShipApprover.nickName }}</text>
            <text class="scan-ship-remove"
                  @click="clearScanShipApprover">×</text>
            <text class="approval-desc">每个步骤只能选择一个审批人</text>
          </view>
          <u-button v-else
          <view class="approval-steps">
                    size="small"
            <view v-for="(step, stepIndex) in scanShipApproverNodes"
                    type="primary"
                  :key="step.id"
                  class="approval-step">
              <view class="step-title">
                <text>审批人</text>
              </view>
              <view class="approver-container">
                <view v-if="step.nickName"
                      class="approver-item">
                  <view class="approver-avatar">
                    <text class="avatar-text">{{ step.nickName.charAt(0) }}</text>
                  </view>
                  <view class="approver-info">
                    <text class="approver-name">{{ step.nickName }}</text>
                  </view>
                  <view class="delete-approver-btn"
                        @tap.stop="removeScanShipApproverUser(stepIndex)">×</view>
                </view>
                <view v-else
                      class="add-approver-btn"
                      @tap.stop="openScanShipContactSelect(stepIndex)">
                  <view class="add-circle">+</view>
                  <text class="add-label">选择审批人</text>
                </view>
              </view>
              <view class="delete-step-btn"
                    v-if="scanShipApproverNodes.length > 1"
                    @tap.stop="removeScanShipApproverNode(stepIndex)">删除节点</view>
            </view>
          </view>
          <view class="add-step-btn">
            <u-button icon="plus"
                    plain
                    @click="openScanShipContactSelect">选择审批人</u-button>
                      type="primary"
                      style="width: 100%"
                      @click="addScanShipApproverNode">新增节点</u-button>
          </view>
        </view>
@@ -315,7 +387,9 @@
          <text class="scan-ship-subtitle">发货附件(选填,最多10张)</text>
          <u-button size="small"
          <u-button class="scan-ship-add-img-btn"
                    size="small"
                    type="primary"
@@ -462,7 +536,8 @@
  ]);
  const scanShipCarNumber = ref("");
  const scanShipExpress = ref("");
  const scanShipApprover = ref({ userId: null, nickName: null });
  let nextScanShipApproverNodeId = 2;
  const scanShipApproverNodes = ref([{ id: 1, userId: null, nickName: "" }]);
  const scanShipFiles = ref([]);
  const scanShipUploading = ref(false);
@@ -484,15 +559,35 @@
    else scanShipCarNumber.value = "";
  };
  const openScanShipContactSelect = () => {
    uni.setStorageSync("stepIndex", 0);
    uni.navigateTo({
      url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect?approveType=7&source=scanShip",
  const openScanShipTypeSheet = () => {
    scanShipTypeSheetShow.value = true;
  };
  const addScanShipApproverNode = () => {
    scanShipApproverNodes.value.push({
      id: nextScanShipApproverNodeId++,
      userId: null,
      nickName: "",
    });
  };
  const clearScanShipApprover = () => {
    scanShipApprover.value = { userId: null, nickName: null };
  const removeScanShipApproverNode = stepIndex => {
    if (scanShipApproverNodes.value.length <= 1) return;
    scanShipApproverNodes.value.splice(stepIndex, 1);
  };
  const removeScanShipApproverUser = stepIndex => {
    const step = scanShipApproverNodes.value[stepIndex];
    if (!step) return;
    step.userId = null;
    step.nickName = "";
  };
  const openScanShipContactSelect = stepIndex => {
    uni.setStorageSync("stepIndex", stepIndex);
    uni.navigateTo({
      url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect?approveType=7&source=scanShip",
    });
  };
  const handleScanShipSelectContact = data => {
@@ -500,7 +595,12 @@
    if (!needScanShipFlow.value) return;
    const c = data?.contact;
    if (!c) return;
    scanShipApprover.value = { userId: c.userId, nickName: c.nickName };
    const idx = Number(data.stepIndex);
    const i = Number.isNaN(idx) ? 0 : idx;
    if (i < 0 || i >= scanShipApproverNodes.value.length) return;
    const row = scanShipApproverNodes.value[i];
    row.userId = c.userId;
    row.nickName = c.nickName || c.userName || "";
  };
  const scanShipFileUrl = file => {
@@ -600,18 +700,23 @@
      modal.msgError("请输入快递单号");
      return;
    }
    if (!scanShipApprover.value?.userId) {
      modal.msgError("请选择审批人");
    const hasEmptyStep = scanShipApproverNodes.value.some(s => !s?.userId);
    if (hasEmptyStep) {
      modal.msgError("请为每个审批步骤选择审批人");
      return;
    }
    if (scanShipUploading.value) {
      modal.msgError("附件上传中,请稍候");
      return;
    }
    const approveUserIds = scanShipApproverNodes.value
      .map(s => s.userId)
      .filter(id => id != null && id !== "")
      .join(",");
    const payload = {
      salesLedgerId: scanLedgerId.value,
      salesLedgerProductList,
      approveUserIds: String(scanShipApprover.value.userId),
      approveUserIds,
      shipType: scanShipTypeValue.value,
      shippingCarNumber:
        scanShipTypeValue.value === "货车" ? String(scanShipCarNumber.value || "").trim() : "",
@@ -1009,7 +1114,8 @@
    scanShipTypeValue.value = "货车";
    scanShipCarNumber.value = "";
    scanShipExpress.value = "";
    scanShipApprover.value = { userId: null, nickName: null };
    nextScanShipApproverNodeId = 2;
    scanShipApproverNodes.value = [{ id: 1, userId: null, nickName: "" }];
    scanShipFiles.value = [];
    scanShipUploading.value = false;
    scanShipTypeSheetShow.value = false;
@@ -1368,6 +1474,12 @@
    height: 140rpx;
    min-width: 140rpx;
    min-height: 140rpx;
    flex-shrink: 0;
    border-radius: 32rpx;
    display: flex;
@@ -1407,6 +1519,10 @@
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
  }
@@ -1678,6 +1794,588 @@
  }
  /* 发货信息:与扫码入库审批区、台账发货页表单风格一致 */
  .scan-ship-card {
    background-color: #fff;
    margin: 20rpx;
    padding: 0 0 24rpx;
    border-radius: 16rpx;
    box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
    overflow: hidden;
  }
  .scan-ship-title {
    font-size: 30rpx;
    font-weight: 600;
    color: #333;
    padding: 28rpx 28rpx 20rpx;
    border-bottom: 1rpx solid #eee;
  }
  .scan-ship-card :deep(.u-form) {
    background: transparent;
    margin: 0;
    padding: 0;
  }
  .scan-ship-card :deep(.u-form-item) {
    background: #fff;
    padding: 0 28rpx;
    border-bottom: 1rpx solid #f0f0f0;
  }
  .scan-ship-card :deep(.u-form-item:last-child) {
    border-bottom: none;
  }
  .scan-ship-card :deep(.u-form-item__body) {
    padding: 24rpx 0;
    min-height: 88rpx;
    display: flex;
    align-items: center;
    border: none;
  }
  .scan-ship-card :deep(.u-form-item__label) {
    font-size: 28rpx;
    color: #888;
    font-weight: 400;
    flex-shrink: 0;
  }
  .scan-ship-card :deep(.u-form-item__content) {
    flex: 1;
    min-width: 0;
    display: flex;
    justify-content: flex-end;
    align-items: center;
  }
  .scan-ship-card :deep(.u-input),
  .scan-ship-card :deep(.u-input input),
  .scan-ship-card :deep(.u-input__content__field-wrapper__field),
  .scan-ship-card :deep(.u-input__input) {
    border: none !important;
    box-shadow: none !important;
    background: transparent !important;
    font-size: 28rpx;
    color: #1a1a1a;
    text-align: right;
  }
  .scan-ship-card :deep(.u-input input[readonly]),
  .scan-ship-card :deep(.u-input__input[readonly]) {
    color: #666;
  }
  .scan-ship-card :deep(.scan-ship-type-form-item .u-form-item__content) {
    justify-content: flex-start;
    align-items: center;
  }
  .scan-ship-type-trigger {
    display: flex;
    flex-direction: row;
    align-items: center;
    width: 100%;
    min-height: 72rpx;
    padding: 8rpx 0;
    box-sizing: border-box;
  }
  .scan-ship-type-trigger :deep(.u-input) {
    flex: 1;
    min-width: 0;
  }
  .scan-ship-type-trigger :deep(input),
  .scan-ship-type-trigger :deep(.u-input__input) {
    pointer-events: none;
  }
  .scan-ship-card :deep(.u-input input::placeholder),
  .scan-ship-card :deep(.u-input__input::placeholder) {
    color: #c0c4cc;
    font-size: 28rpx;
  }
  .scan-ship-card :deep(.scan-ship-type-form-item .u-input input),
  .scan-ship-card :deep(.scan-ship-type-form-item .u-input__input) {
    text-align: left;
  }
  .scan-ship-card .approval-process {
    background: transparent;
    margin: 0;
    padding: 24rpx 28rpx 8rpx;
    border-radius: 0;
    box-shadow: none;
    border-top: 1rpx solid #f0f0f0;
    margin-top: 8rpx;
  }
  .scan-ship-card .approval-header {
    margin-bottom: 16rpx;
  }
  .scan-ship-card .approval-title {
    font-size: 30rpx;
    font-weight: 600;
    color: #333;
    display: block;
  }
  .scan-ship-card .approval-desc {
    font-size: 24rpx;
    color: #999;
    margin-top: 6rpx;
  }
  .scan-ship-card .approval-step {
    margin-bottom: 18rpx;
  }
  .scan-ship-card .step-title text {
    font-size: 24rpx;
    color: #666;
  }
  .scan-ship-card .approver-container {
    display: flex;
    align-items: center;
    margin-top: 10rpx;
  }
  .scan-ship-card .approver-item {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 12rpx;
    padding: 12rpx 0;
  }
  .scan-ship-card .approver-avatar {
    width: 64rpx;
    height: 64rpx;
    border-radius: 50%;
    background: #f3f4f6;
    border: 2rpx solid #e5e7eb;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .scan-ship-card .avatar-text {
    font-size: 24rpx;
    color: #374151;
    font-weight: 600;
  }
  .scan-ship-card .approver-info {
    flex: 1;
  }
  .scan-ship-card .approver-name {
    font-size: 28rpx;
    color: #333;
  }
  .scan-ship-card .delete-approver-btn {
    font-size: 32rpx;
    color: #ff4d4f;
    padding: 0 8rpx;
  }
  .scan-ship-card .add-approver-btn {
    display: flex;
    align-items: center;
    gap: 10rpx;
    color: #3b82f6;
    padding: 10rpx 0;
  }
  .scan-ship-card .add-circle {
    width: 52rpx;
    height: 52rpx;
    border: 2rpx dashed #a0aec0;
    border-radius: 50%;
    color: #6b7280;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 34rpx;
    line-height: 1;
  }
  .scan-ship-card .add-label {
    font-size: 26rpx;
  }
  .scan-ship-card .delete-step-btn {
    color: #ff4d4f;
    font-size: 24rpx;
    margin-top: 8rpx;
  }
  .scan-ship-card .add-step-btn {
    margin-top: 8rpx;
  }
  .scan-ship-subtitle {
    display: block;
    font-size: 24rpx;
    color: #666;
    margin-bottom: 16rpx;
  }
  .scan-ship-files {
    padding: 28rpx 28rpx 0;
    border-top: 1rpx solid #f0f0f0;
    margin-top: 16rpx;
  }
  .scan-ship-files :deep(.scan-ship-add-img-btn) {
    width: 100% !important;
    margin-top: 8rpx;
    border-radius: 16rpx !important;
    min-height: 88rpx;
  }
  .scan-ship-file-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 24rpx;
    margin-top: 24rpx;
  }
  .scan-ship-thumb-wrap {
    position: relative;
    width: calc(50% - 12rpx);
    min-width: 200rpx;
    padding: 16rpx;
    box-sizing: border-box;
    background: #fff;
    border-radius: 16rpx;
    border: 1rpx solid #e9ecef;
    box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.05);
  }
  .scan-ship-thumb {
    width: 100%;
    height: 200rpx;
    border-radius: 12rpx;
    display: block;
    border: 2rpx solid #f0f0f0;
    background: #f5f5f5;
  }
  .scan-ship-thumb-del {
    position: absolute;
    top: 8rpx;
    right: 8rpx;
    width: 44rpx;
    height: 44rpx;
    background: #ff4757;
    color: #fff;
    font-size: 28rpx;
    line-height: 44rpx;
    text-align: center;
    border-radius: 50%;
    box-shadow: 0 4rpx 8rpx rgba(255, 71, 87, 0.35);
  }
  .scan-ship-qty-readonly {
    font-size: 30rpx;