zhangwencui
4 天以前 b973bcee308e99b5fd8a69640f11069e810346f4
src/pages/cooperativeOffice/collaborativeApproval/index.vue
@@ -1,467 +1,367 @@
// 审批管理主页面
<template>
   <view class="sales-account">
      <!-- 使用通用页面头部组件 -->
      <PageHeader title="审批管理" @back="goBack" />
      <!-- 搜索和筛选区域 -->
      <view class="search-filter-section">
         <view class="search-bar">
            <view class="search-input">
               <input
                  class="search-text"
                  placeholder="请输入流程编号"
                  v-model="searchForm.approveId"
               />
            </view>
            <view class="search-button" @click="getList">
               <up-icon name="search" size="24" color="#999"></up-icon>
            </view>
         </view>
      </view>
      <!-- 审批列表 -->
      <view class="ledger-list" v-if="ledgerList.length > 0">
         <view v-for="(item, index) in ledgerList" :key="index">
            <view class="ledger-item">
               <view class="item-header">
                  <view class="item-left">
                     <view class="document-icon">
                        <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
                     </view>
                     <text class="item-id">{{ item.approveId }}</text>
                  </view>
                  <view class="item-tag">
                     <van-tag :type="getTagClass(item.approveStatus)" size="medium">{{ formatReceiptType(item.approveStatus) }}</van-tag>
                  </view>
               </view>
               <up-divider></up-divider>
               <view class="item-details">
                  <view class="detail-row">
                     <text class="detail-label">申请人</text>
                     <text class="detail-value">{{ item.approveUserName }}</text>
                  </view>
                  <view class="detail-row">
                     <text class="detail-label">申请部门</text>
                     <text class="detail-value">{{ item.approveDeptName }}</text>
                  </view>
                  <view class="detail-row-approveReason">
                     <text class="detail-label">审批事由</text>
                     <text class="detail-value highlightBlue">{{ item.approveReason }}</text>
                  </view>
                  <view class="detail-row">
                     <text class="detail-label">申请日期</text>
                     <text class="detail-value">{{ item.approveTime }}</text>
                  </view>
                  <view class="detail-row">
                     <text class="detail-label">结束日期</text>
                     <text class="detail-value">{{ item.approveOverTime }}</text>
                  </view>
                  <up-divider></up-divider>
                  <view class="detail-info">
                     <view class="detail-row-user">
                        <text class="detail-label">当前审批人</text>
                        <view class="detail-value approver-value">
                           <view class="approver-chip">
                              <text class="approver-name">{{ item.approveUserCurrentName || '未分配' }}</text>
                           </view>
                        </view>
                     </view>
                     <view class="detail-row">
                        <view class="actions">
                           <van-button
                              type="primary"
                              size="small"
                              class="action-btn edit"
                              :disabled="item.approveStatus == 2 || item.approveStatus == 1 || item.approveStatus == 4"
                              @click="handleItemClick(item)"
                           >
                              编辑
                           </van-button>
                           <van-button
                              type="success"
                              size="small"
                              class="action-btn approve"
                              :disabled="item.approveUserCurrentId == null || item.approveStatus == 2 || item.approveStatus == 3 || item.approveStatus == 4 || item.approveUserCurrentId !== userStore.id"
                              @click="approve(item)"
                           >
                              审核
                           </van-button>
                        </view>
                     </view>
                  </view>
               </view>
            </view>
         </view>
      </view>
      <view v-else class="no-data">
         <text>暂无审批数据</text>
      </view>
<!--      <van-floating-bubble icon="plus" @click="handleAdd"/>-->
      <!-- 浮动操作按钮 -->
      <view class="fab-button" @click="handleAdd">
         <up-icon name="plus" size="24" color="#ffffff"></up-icon>
      </view>
   </view>
  <view class="sales-account">
    <!-- 使用通用页面头部组件 -->
    <PageHeader :title="pageTitle"
                @back="goBack" />
    <!-- 搜索和筛选区域 -->
    <view class="search-section">
      <view class="search-bar">
        <view class="search-input">
          <up-input class="search-text"
                    placeholder="请输入流程编号"
                    v-model="searchForm.approveId"
                    clearable />
        </view>
        <view class="search-button"
              @click="getList">
          <up-icon name="search"
                   size="24"
                   color="#999"></up-icon>
        </view>
      </view>
    </view>
    <!-- 审批列表 -->
    <view class="ledger-list"
          v-if="ledgerList.length > 0">
      <view v-for="(item, index) in ledgerList"
            :key="index">
        <view class="ledger-item">
          <view class="item-header">
            <view class="item-left">
              <view class="document-icon">
                <up-icon name="file-text"
                         size="16"
                         color="#ffffff"></up-icon>
              </view>
              <text class="item-id">{{ item.approveId }}</text>
            </view>
            <view class="item-tag">
              <u-tag :type="getTagClass(item.approveStatus)">{{ formatReceiptType(item.approveStatus) }}</u-tag>
            </view>
          </view>
          <up-divider></up-divider>
          <view class="item-details">
            <view class="detail-row">
              <text class="detail-label">申请人</text>
              <text class="detail-value">{{ item.approveUserName }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">申请部门</text>
              <text class="detail-value">{{ item.approveDeptName }}</text>
            </view>
            <view class="detail-row-approveReason">
              <text class="detail-label">审批事由</text>
              <text class="detail-value highlightBlue">{{ item.approveReason }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">申请日期</text>
              <text class="detail-value">{{ item.approveTime }}</text>
            </view>
            <!-- approveType=2 请假相关字段 -->
            <template v-if="item.approveType === 2">
              <view class="detail-row">
                <text class="detail-label">请假开始时间</text>
                <text class="detail-value">{{ item.startDate || '-' }}</text>
              </view>
              <view class="detail-row">
                <text class="detail-label">请假结束时间</text>
                <text class="detail-value">{{ item.endDate || '-' }}</text>
              </view>
            </template>
            <!-- approveType=3 出差相关字段 -->
            <view v-if="item.approveType === 3"
                  class="detail-row">
              <text class="detail-label">出差地点</text>
              <text class="detail-value">{{ item.location || '-' }}</text>
            </view>
            <!-- approveType=4 报销相关字段 -->
            <view v-if="item.approveType === 4"
                  class="detail-row">
              <text class="detail-label">报销金额</text>
              <text class="detail-value highlightYellow">{{ item.price ? `¥${item.price}` : '-' }}</text>
            </view>
            <view class="detail-row">
              <text class="detail-label">结束日期</text>
              <text class="detail-value">{{ item.approveOverTime }}</text>
            </view>
            <up-divider></up-divider>
            <view class="detail-info">
              <view class="detail-row-user">
                <text class="detail-label">当前审批人</text>
                <view class="detail-value approver-value">
                  <view class="approver-chip">
                    <text class="approver-name">{{ item.approveUserCurrentName || '未分配' }}</text>
                  </view>
                </view>
              </view>
              <view class="detail-row">
                <view class="actions">
                  <u-button type="primary"
                            size="small"
                            class="action-btn edit"
                            :disabled="item.approveStatus == 2 || item.approveStatus == 1 || item.approveStatus == 4"
                            @click="handleItemClick(item)">
                    编辑
                  </u-button>
                  <u-button type="success"
                            size="small"
                            class="action-btn approve"
                            :disabled="item.approveUserCurrentId == null || item.approveStatus == 2 || item.approveStatus == 3 || item.approveStatus == 4 || item.approveUserCurrentId !== userStore.id"
                            @click="approve(item)">
                    审核
                  </u-button>
                </view>
              </view>
            </view>
          </view>
        </view>
      </view>
    </view>
    <view v-else
          class="no-data">
      <text>暂无审批数据</text>
    </view>
    <!-- 浮动操作按钮 -->
    <view class="fab-button"
          @click="handleAdd">
      <up-icon name="plus"
               size="24"
               color="#ffffff"></up-icon>
    </view>
  </view>
</template>
<script setup>
   import {
      ref,
      toRefs,
      reactive
   } from "vue";
   import PageHeader from "@/components/PageHeader.vue";
   import {approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess";
   import {onShow} from "@dcloudio/uni-app";
   import useUserStore from "@/store/modules/user";
   const userStore = useUserStore()
   // 数据
   const ledgerList = ref([]);
   const data = reactive({
      searchForm: {
         approveId: "",
      },
   });
   const { searchForm } = toRefs(data);
  import { ref, toRefs, reactive } from "vue";
  import PageHeader from "@/components/PageHeader.vue";
  import { approveProcessListPage } from "@/api/collaborativeApproval/approvalProcess";
  import { onShow } from "@dcloudio/uni-app";
  import useUserStore from "@/store/modules/user";
   // 返回上一页
   const goBack = () => {
      uni.navigateBack();
   };
   // 查询列表
   const getList = () => {
      const page = {
         current: -1,
         size: -1,
      };
      approveProcessListPage({
            ...page,approveType: 0,...searchForm.value
         })
         .then((res) => {
            ledgerList.value = res.data.records;
         })
         .catch(() => {
            // tableLoading.value = false;
         });
   };
   // 显示筛选选项
   const showFilterOptions = () => {
      uni.showActionSheet({
         itemList: ["按日期筛选", "按状态筛选", "按金额筛选"],
         success: (res) => {
            console.log("选择了筛选选项:", res.tapIndex);
         },
      });
   };
   // 格式化回款方式
   const formatReceiptType = (params) => {
      if (params == 0) {
         return "待审核";
      } else if (params == 1) {
         return "审核中";
      } else if (params == 2) {
         return "审核完成";
      } else if (params == 4) {
         return "已重新提交";
      } else {
         return '不通过';
      }
   };
   // 获取标签样式类
   const getTagClass = (type) => {
      if (type == 0) {
         return "warning";
      } else if (type == 1) {
         return "primary";
      } else if (type == 2) {
         return "success";
      } else if (type == 4) {
         return "primary";
      } else {
         return "danger";
      }
   };
  // 接收父组件传递的 approveType 参数
  const props = defineProps({
    approveType: {
      type: Number,
      default: 0,
    },
  });
   // 点击列表项
   const handleItemClick = (item) => {
      // 使用本地存储传递数据
      uni.setStorageSync('invoiceLedgerEditRow', JSON.stringify(item));
      uni.navigateTo({
         url: `/pages/cooperativeOffice/collaborativeApproval/detail?operationType=edit&approveId=${item.approveId}`,
      });
   };
  // 映射 approveType 到对应的页面标题
  const getPageTitle = type => {
    const titleMap = {
      1: "公出管理",
      2: "请假管理",
      3: "出差管理",
      4: "报销管理",
      5: "采购管理",
      6: "报价管理",
      7: "出库管理",
    };
    return titleMap[type] || "审批管理";
  };
   // 添加新记录
   const handleAdd = () => {
      uni.navigateTo({
         url: "/pages/cooperativeOffice/collaborativeApproval/detail?operationType=add",
      });
   };
   // 点击审核
   const approve = (item) => {
      uni.navigateTo({
         url: `/pages/cooperativeOffice/collaborativeApproval/approve?approveId=${item.approveId}`
      })
   }
  const pageTitle = getPageTitle(props.approveType);
   onShow(() => {
      // 页面加载完成后的初始化逻辑
      getList();
   });
  const userStore = useUserStore();
  // 数据
  const ledgerList = ref([]);
  const data = reactive({
    searchForm: {
      approveId: "",
    },
  });
  const { searchForm } = toRefs(data);
  // 返回上一页
  const goBack = () => {
    uni.navigateBack();
  };
  // 查询列表
  const getList = () => {
    showLoadingToast("加载中...");
    const page = {
      current: -1,
      size: -1,
    };
    approveProcessListPage({
      ...page,
      approveType: props.approveType,
      ...searchForm.value,
    })
      .then(res => {
        ledgerList.value = res.data.records;
        closeToast();
      })
      .catch(() => {
        closeToast();
      });
  };
  // 显示加载提示
  const showLoadingToast = message => {
    uni.showLoading({
      title: message,
      mask: true,
    });
  };
  // 关闭提示
  const closeToast = () => {
    uni.hideLoading();
  };
  // 显示筛选选项
  const showFilterOptions = () => {
    uni.showActionSheet({
      itemList: ["按日期筛选", "按状态筛选", "按金额筛选"],
      success: res => {
        console.log("选择了筛选选项:", res.tapIndex);
      },
    });
  };
  // 格式化回款方式
  const formatReceiptType = params => {
    if (params == 0) {
      return "待审核";
    } else if (params == 1) {
      return "审核中";
    } else if (params == 2) {
      return "审核完成";
    } else if (params == 4) {
      return "已重新提交";
    } else {
      return "不通过";
    }
  };
  // 获取标签样式类
  const getTagClass = type => {
    if (type == 0) {
      return "warning";
    } else if (type == 1) {
      return "primary";
    } else if (type == 2) {
      return "success";
    } else if (type == 4) {
      return "primary";
    } else {
      return "error";
    }
  };
  // 点击列表项
  const handleItemClick = item => {
    // 使用本地存储传递数据
    uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(item));
    uni.setStorageSync("operationType", "edit");
    uni.setStorageSync("approveId", item.approveId);
    uni.setStorageSync("approveType", props.approveType);
    uni.navigateTo({
      url: "/pages/cooperativeOffice/collaborativeApproval/detail",
    });
  };
  // 添加新记录
  const handleAdd = () => {
    uni.setStorageSync("operationType", "add");
    uni.setStorageSync("approveType", props.approveType);
    uni.navigateTo({
      url: `/pages/cooperativeOffice/collaborativeApproval/detail?approveType=${props.approveType}`,
    });
  };
  // 点击审核
  const approve = item => {
    uni.setStorageSync("approveId", item.approveId);
    uni.setStorageSync("approveType", props.approveType);
    uni.navigateTo({
      url:
        "/pages/cooperativeOffice/collaborativeApproval/approve?approveType=" +
        props.approveType,
    });
  };
  onShow(() => {
    // 页面加载完成后的初始化逻辑
    getList();
  });
</script>
<style scoped lang="scss">
   .u-divider {
      margin: 0 !important;
   }
  @import "../../../styles/sales-common.scss";
   .sales-account {
      min-height: 100vh;
      background: #f8f9fa;
      position: relative;
   }
   .search-input {
      flex: 1;
      background: #f5f5f5;
      border-radius: 24px;
      padding: 10px 16px;
      display: flex;
      align-items: center;
      gap: 8px;
   }
   .search-text {
      flex: 1;
      font-size: 14px;
      color: #333;
      background: transparent;
      border: none;
      outline: none;
   }
   .search-text::placeholder {
      color: #999;
   }
  .u-divider {
    margin: 0 !important;
  }
  // 文档图标样式 - 覆盖公共样式中的背景色
  .document-icon {
    background: #ed8d05;
  }
   .search-filter-section {
      padding: 10px 20px;
      background: #ffffff;
   }
  // 浮动按钮样式 - 覆盖公共样式中的背景色
  .fab-button {
    background: #ed8d05;
  }
   .search-bar {
      display: flex;
      align-items: center;
      gap: 12px;
   }
   .search-input {
      flex: 1;
      background: #f5f5f5;
      border-radius: 24px;
      padding: 10px 16px;
      display: flex;
      align-items: center;
      gap: 8px;
   }
   .search-text {
      flex: 1;
      font-size: 14px;
      color: #333;
      background: transparent;
      border: none;
      outline: none;
   }
   .search-text::placeholder {
      color: #999;
   }
  // 特有样式
  .detail-row-user {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
   .filter-button {
      width: 40px;
      height: 40px;
      border-radius: 8px;
      display: flex;
      align-items: center;
      justify-content: center;
   }
  .detail-row-approveReason {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
  }
   .ledger-list {
      padding: 20px;
   }
  .detail-value.highlightBlue {
    color: #2979ff;
    font-weight: 500;
  }
   .ledger-item {
      background: #ffffff;
      border-radius: 12px;
      margin-bottom: 16px;
      overflow: hidden;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
      padding: 0 16px;
   }
  .detail-value.highlightYellow {
    color: #ed8d05;
    font-weight: 500;
  }
   .item-header {
      padding: 16px 0;
      display: flex;
      align-items: center;
      justify-content: space-between;
   }
  .approver-value {
    display: flex;
    justify-content: flex-end;
  }
   .item-left {
      display: flex;
      align-items: center;
      gap: 8px;
   }
  .approver-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: #f0f6ff;
    color: #2b7cff;
    border: 1px solid #e0efff;
    border-radius: 999px;
    padding: 4px 10px;
    max-width: 100%;
  }
   .document-icon {
      width: 24px;
      height: 24px;
      background: #ed8d05;
      border-radius: 4px;
      display: flex;
      align-items: center;
      justify-content: center;
   }
  .approver-name {
    font-size: 12px;
    color: #2b7cff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
   .item-id {
      font-size: 14px;
      color: #333;
      font-weight: 500;
   }
  .actions {
    display: flex;
    gap: 10px;
    align-items: center;
    justify-content: flex-end;
  }
   .item-tag {
      border-radius: 4px;
      padding: 2px 4px;
   }
   .tag-text {
      font-size: 11px;
      color: #ffffff;
      font-weight: 500;
   }
   .item-details {
      padding: 16px 0;
   }
   .detail-row {
      display: flex;
      align-items: flex-end;
      justify-content: space-between;
      margin-bottom: 8px;
      &:last-child {
         margin-bottom: 0;
      }
   }
   .detail-row-user {
      display: flex;
      align-items: center;
      justify-content: space-between;
   }
   .detail-row-approveReason {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 8px;
   }
   .detail-info {
      margin-top: 10px;
      display: flex;
      align-items: flex-start;
      justify-content: space-between;
   }
   .detail-label {
      font-size: 12px;
      color: #777777;
      min-width: 60px;
   }
   .detail-value {
      font-size: 12px;
      color: #000000;
      text-align: right;
      flex: 1;
      margin-left: 16px;
   }
   .detail-value.highlightBlue {
      color: #2979ff;
      font-weight: 500;
   }
   .detail-value.highlightYellow {
      color: #ed8d05;
      font-weight: 500;
   }
   .no-data {
      padding: 40px 0;
      text-align: center;
      color: #999;
   }
   .fab-button {
      position: fixed;
      bottom: 30px;
      right: 30px;
      width: 56px;
      height: 56px;
      background: #ed8d05;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      box-shadow: 0 4px 16px rgba(41, 121, 255, 0.3);
      z-index: 1000;
   }
   .approver-value {
      display: flex;
      justify-content: flex-end;
   }
   .approver-chip {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      background: #f0f6ff;
      color: #2b7cff;
      border: 1px solid #e0efff;
      border-radius: 999px;
      padding: 4px 10px;
      max-width: 100%;
   }
   .approver-name {
      font-size: 12px;
      color: #2b7cff;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
   }
   .actions {
      display: flex;
      gap: 10px;
      align-items: center;
      justify-content: flex-end;
   }
   .action-btn {
      border-radius: 16px;
      height: 28px;
      line-height: 28px;
      padding: 0 12px;
   }
   .action-btn.edit {
      /* primary 样式来自组件,这里保留钩子以便后续需要扩展 */
   }
   .action-btn.approve {
      /* success 样式来自组件,这里保留钩子以便后续需要扩展 */
   }
   :deep(.van-floating-bubble) {
      background: #ed8d05;
   }
  .action-btn {
    border-radius: 16px;
    height: 28px;
    line-height: 28px;
    padding: 0 12px;
  }
</style>