From a203b73cd1747a629843fa3546b1673964be21fb Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Wed, 14 Jan 2026 11:38:53 +0800
Subject: [PATCH] feat:工单

---
 uniapps/work-app/src/pages/work/index.vue             |  124 ++++++++++++++++----
 uniapps/work-app/src/pages.json                       |    3 
 uniapps/work-app/src/subPackages/workDetail/index.vue |  183 ++++++++++++++++++++++++------
 3 files changed, 248 insertions(+), 62 deletions(-)

diff --git a/uniapps/work-app/src/pages.json b/uniapps/work-app/src/pages.json
index e1d4960..0e21c14 100644
--- a/uniapps/work-app/src/pages.json
+++ b/uniapps/work-app/src/pages.json
@@ -59,7 +59,8 @@
         {
           "path": "workDetail/index",
           "style": {
-            "navigationBarTitleText": "工单详情"
+            "navigationBarTitleText": "工单详情",
+            "navigationStyle": "custom"
           }
         },
         {
diff --git a/uniapps/work-app/src/pages/work/index.vue b/uniapps/work-app/src/pages/work/index.vue
index 7b2d2ab..81ba799 100644
--- a/uniapps/work-app/src/pages/work/index.vue
+++ b/uniapps/work-app/src/pages/work/index.vue
@@ -9,15 +9,23 @@
         <up-tabs :list="tabList" @click="handleClick"></up-tabs>
       </div>
 
-      <div class="eventBox">
-        <div class="eventItem"  v-for="(item,index) in dataList" :key="index">
-          <img :src="item.photo_url" alt="" @click="detailHandle(item)" />
-          <div class="informationDisplay">
-            <div class="itemTitle">{{item.event_name}}</div>
-            <div class="itemContent">{{formatDate(item.create_time) }}</div>
+      <scroll-view class="eventBox" scroll-y :lower-threshold="80" @scrolltolower="loadMore">
+        <div class="eventList">
+          <div class="eventItem"  v-for="(item,index) in dataList" :key="index">
+            <img :src="item.photo_url" alt="" @click="detailHandle(item)" />
+            <div class="informationDisplay">
+              <!--              <div class="itemTitle">{{item.event_name}}</div>-->
+              <div class="itemContent">{{formatDate(item.create_time) }}</div>
+            </div>
           </div>
         </div>
-      </div>
+
+        <!-- 加载提示 -->
+        <div class="loadingMore">
+          <text v-if="loading">加载中...</text>
+
+        </div>
+      </scroll-view>
     </div>
 
   </div>
@@ -34,6 +42,8 @@
 const userInfo = userStore.userInfo
 const dataList = ref([])
 const currentTab=ref('all')
+const loading = ref(false)
+const hasMore = ref(true)
 const tabList = ref([
   {
     name: '全部工单',
@@ -49,7 +59,7 @@
     badge: {
       value: 1
     }
-  },
+  }
 
 
 ])
@@ -59,16 +69,19 @@
 const listParams = ref({
   status: null,
   current: 1,
-  size: 9999,
+  size: 12,
   source: 1,
   department:'',
   keyword:''
 
 })
 const getDataList = () => {
+  if (loading.value || !hasMore.value) return
+
+  loading.value = true
   const params = {
-    current: 1,
-    size: 9999,
+    current: listParams.value.current,
+    size: listParams.value.size,
     source: 1,
     status:listParams.value.status,
     event_name:listParams.value.keyword,
@@ -76,10 +89,29 @@
   }
   getList(params).then(res => {
 
-    const response = res.data.data.records
-    dataList.value = response
+    const response = res.data.data
+    const records = response.records || []
+
+    // 根据当前页码决定是替换还是追加数据
+    if (listParams.value.current === 1) {
+      dataList.value = records
+    } else {
+      dataList.value = [...dataList.value, ...records]
+    }
+
+    // 判断是否还有更多数据
+    if (records.length < listParams.value.size || response.current >= response.pages) {
+      hasMore.value = false
+    } else {
+      hasMore.value = true
+    }
+  }).finally(() => {
+    loading.value = false
   })
 }
+
+
+
 // const getstatusCountData=()=>{
 // 	getstatusCount().then(res=>{
 // 		const response = res.data.data
@@ -102,8 +134,17 @@
 const handleClick = (item) => {
   currentTab.value = item.key
   listParams.value.status = item.status
+  listParams.value.current = 1
+  hasMore.value = true
+  dataList.value = []
   getDataList()
 }
+const loadMore = () => {
+  if (loading.value || !hasMore.value) return
+  listParams.value.current++
+  getDataList()
+}
+
 const detailHandle = (val) => {
   uni.navigateTo({
     url: `/subPackages/workDetail/index?eventNum=${val.event_num}`,
@@ -111,8 +152,10 @@
 }
 const topMargin = getStatusBarHeight()
 onShow(() => {
+  listParams.value.current = 1
+  hasMore.value = true
+  dataList.value = []
   getDataList()
-
 })
 </script>
 
@@ -123,6 +166,8 @@
   flex-direction: column;
   height: 100%;
   box-sizing: border-box;
+  width: 100%;
+  overflow-x: hidden;
   .searchTop {
     display: flex;
     align-items: center;
@@ -134,11 +179,13 @@
   :deep(){
 
     .u-tabs__wrapper__nav__line{
-      width: 80rpx !important;
+      // width: 80rpx !important;
       background: #1D6FE9 !important;
     }
     .u-badge {
       background-color: #1d6fe9 !important;
+      margin-top: -17px !important;
+      margin-left: -5px !important;
     }
   }
 
@@ -153,34 +200,53 @@
     display: flex;
     flex-direction: column;
     flex: 1;
+    width: 100%;
+    box-sizing: border-box;
   }
   .eventBox {
-    display: flex;
-    flex-wrap: wrap;
-    gap: 20rpx;
     padding: 20rpx 0;
     overflow-y: auto;
+    overflow-x: hidden;
     height: 0;
     flex-grow: 1;
     align-content: flex-start;
+    width: 100%;
+    box-sizing: border-box;
+  }
+
+  .eventList {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 20rpx;
+    width: 100%;
+    box-sizing: border-box;
+    justify-content: space-between;
 
     .eventItem {
       width: calc(50% - 10rpx);
       background-color: #fff;
       border-radius: 12rpx;
       overflow: hidden;
+      position: relative;
+      box-sizing: border-box;
+      max-width: 100%;
 
       img {
-        width: 341rpx;
-        height: 196rpx;
+        width: 100%;
+        height: 208rpx;
         border-radius: 12rpx;
         overflow: hidden;
       }
       .informationDisplay{
+        width: 100%;
+        position: absolute;
+        bottom: 3px;
+        background: rgba(11,11,11,0.35);
+        border-radius: 0rpx 0rpx 12rpx 12rpx;
         display: flex;
         align-items: center;
-        justify-content: space-between;
-        padding: 10rpx 20rpx 10rpx 12rpx;
+        justify-content: flex-end;
+        padding: 10rpx 0rpx 10rpx 0rpx;
         .itemTitle {
           width: 144rpx;
           font-family: Source Han Sans CN, Source Han Sans CN;
@@ -196,12 +262,22 @@
           font-family: Source Han Sans CN, Source Han Sans CN;
           font-weight: 400;
           font-size: 24rpx;
-          color: rgba(0,0,0,0.5);
+          color: #FFFFFF;
+          padding-right: 14rpx;
 
         }
       }
-
     }
   }
+
+  .loadingMore {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    height: 80rpx;
+    font-size: 28rpx;
+    color: #999;
+    width: 100%;
+  }
 }
 </style>
diff --git a/uniapps/work-app/src/subPackages/workDetail/index.vue b/uniapps/work-app/src/subPackages/workDetail/index.vue
index fcd14bd..0227f8f 100644
--- a/uniapps/work-app/src/subPackages/workDetail/index.vue
+++ b/uniapps/work-app/src/subPackages/workDetail/index.vue
@@ -1,6 +1,18 @@
 <!-- 工单详情 -->
 <template>
   <div class="workDetailContainer">
+    <!-- 自定义导航栏 -->
+    <u-navbar
+      title="工单详情"
+      :is-back="true"
+      back-text=""
+      :back-icon-size="40"
+      @left-click="onBackClick"
+    >
+      <template #right>
+        <div class="share-btn" @click="onShareClick">分享</div>
+      </template>
+    </u-navbar>
     <div class="detailTop">
       <div class="image-container">
         <u-swiper
@@ -31,12 +43,11 @@
         <div class="workOrderContainer">
           <div class="orderRow">
             <div class="rowTitle">工单编号</div>
-            <div>{{workDetailData.event_num}}</div>
+            <div>{{ workDetailData.event_num }}</div>
           </div>
           <div class="orderRow">
             <div class="rowTitle">工单处置人</div>
-            <div>{{workDetailData.event_num?.slice(0, 2) === 'AI' ? 'AI 小飞':workDetailData.creator}}
-            </div>
+            <div>{{ workDetailData.event_num?.slice(0, 2) === 'AI' ? 'AI 小飞' : workDetailData.creator }}</div>
           </div>
           <div class="orderRow">
             <div class="rowTitle">处置部门</div>
@@ -65,59 +76,57 @@
           </div>
         </div>
       </div>
-
     </div>
     <!-- 操作按钮 -->
     <div class="actionButton">
-      <div class="btngroups" >
+      <div class="btngroups">
         <up-button type="primary" color="#AEAEAE" text="退回"></up-button>
         <up-button type="primary" color="#1D6FE9" text="确认"></up-button>
       </div>
     </div>
   </div>
-
 </template>
 
 <script setup>
 // import { getShowImg, getSmallImg } from '@/utils/util'
-import {getList,flowEvent} from '/src/api/work/index.js'
+import { ref, computed } from 'vue'
+import { getList, flowEvent } from '/src/api/work/index.js'
 import dayjs from 'dayjs'
 
 const formatDate = dateString => {
   return dayjs(dateString).format('MM/DD HH:mm')
 }
-const eventNum = ref('');
+const eventNum = ref('')
 // 工单内容
 const workDetailData = ref({})
-onLoad(async (options) => {
-  eventNum.value = options.eventNum;
-  await getDataList(eventNum.value);
-
-});
-const getDataList = async (val) => {
+onLoad(async options => {
+  eventNum.value = options.eventNum
+  await getDataList(eventNum.value)
+})
+const getDataList = async val => {
   const params = {
     current: 1,
     size: 9999,
     source: 1,
-    event_name: val
+    event_name: val,
   }
-  const res = await getList(params);
-  const response = res.data.data.records;
-  workDetailData.value = response[0];
+  const res = await getList(params)
+  const response = res.data.data.records
+  workDetailData.value = response[0]
 
-  console.log('详情',response);
+  console.log('详情', response)
 }
 // 图片预览
 
-const previewImage = (index) => {
-  if (getImageList.value.length === 0) return;
-  const currentIndex = typeof index === 'number' ? index : 0;
+const previewImage = index => {
+  if (getImageList.value.length === 0) return
+  const currentIndex = typeof index === 'number' ? index : 0
   uni.previewImage({
     urls: getImageList.value,
-    current: currentIndex
-  });
-};
-const getImageList =computed(()=>{
+    current: currentIndex,
+  })
+}
+const getImageList = computed(() => {
   const imageArr = []
   const detail = workDetailData.value
   if (detail.photo_url) {
@@ -125,7 +134,7 @@
     imageArr.push(smallUrl)
   }
   if (detail.update_photo_url) {
-    const smallUrl =detail.update_photo_url
+    const smallUrl = detail.update_photo_url
     imageArr.push(smallUrl)
   }
   return imageArr
@@ -136,9 +145,112 @@
     url: `/subPackages/workDetail/mapWork/index?eventNum=${item.event_num}`,
   })
 }
+
+// 分享按钮点击事件
+const onShareClick = () => {
+  // 检查当前平台是否支持分享功能
+  const platform = uni.getSystemInfoSync().platform
+
+  // H5平台不支持uni.share API
+  if (platform === 'web') {
+    uni.showToast({
+      title: 'H5平台暂不支持分享功能',
+      icon: 'none'
+    })
+    return
+  }
+
+  uni.showActionSheet({
+    itemList: ['分享给微信好友', '分享到朋友圈'],
+    success: res => {
+      // 检查uni.share是否存在
+      if (typeof uni.share !== 'function') {
+        uni.showToast({
+          title: '当前环境不支持分享功能',
+          icon: 'none'
+        })
+        return
+      }
+
+      try {
+        switch (res.tapIndex) {
+          case 0:
+            // 分享给微信好友
+            uni.share({
+              provider: 'weixin',
+              scene: 'WXSceneSession',
+              type: 0,
+              title: '工单详情',
+              summary: workDetailData.value.event_name,
+              href: 'https://example.com/workDetail?eventNum=' + workDetailData.value.event_num,
+              imageUrl: workDetailData.value.photo_url,
+              success: () => {
+                uni.showToast({ title: '分享成功', icon: 'success' })
+              },
+              fail: (err) => {
+                console.log('分享失败', err.errMsg)
+                uni.showToast({
+                  title: err.errMsg,
+                  icon: 'none'
+                })
+              }
+            })
+            break
+          case 1:
+            // 分享到朋友圈
+            uni.share({
+              provider: 'weixin',
+              scene: 'WXSceneTimeline',
+              type: 0,
+              title: workDetailData.value.event_name,
+              summary: '查看工单详情',
+              href: 'https://example.com/workDetail?eventNum=' + workDetailData.value.event_num,
+              imageUrl: workDetailData.value.photo_url,
+              success: () => {
+                uni.showToast({ title: '分享成功', icon: 'success' })
+              },
+              fail: (err) => {
+                console.log('分享失败', err)
+                uni.showToast({
+                  title: '分享失败,请检查配置',
+                  icon: 'none'
+                })
+              }
+            })
+            break
+        }
+      } catch (error) {
+        console.error('分享出错:', error)
+        uni.showToast({
+          title: '分享功能异常',
+          icon: 'none'
+        })
+      }
+    }
+  })
+}
+
+// 返回按钮点击事件
+const onBackClick = () => {
+  uni.navigateBack()
+}
+
+// 监听导航栏右侧按钮点击事件(兼容原来的配置)
+const onNavigationBarButtonTap = e => {
+  if (e.index === 0) {
+    onShareClick()
+  }
+}
 </script>
 <style lang="scss" scoped>
 .workDetailContainer {
+  // 分享按钮样式
+  .share-btn {
+    color: #1D6FE9;
+    font-size: 14px;
+    padding: 0 10px;
+    line-height: 44px;
+  }
   .detailTop {
     .image-container {
       position: relative;
@@ -163,9 +275,8 @@
           justify-content: center;
           align-items: center;
           z-index: 10;
-
         }
-        .u-swiper-indicator__wrapper__dot--active{
+        .u-swiper-indicator__wrapper__dot--active {
           width: 5px !important;
         }
       }
@@ -177,7 +288,6 @@
         height: 60rpx;
         line-height: 60rpx;
         background: rgba(7, 7, 7, 0.4);
-
       }
 
       .titleText {
@@ -187,16 +297,17 @@
         align-items: center;
         color: #fff;
 
-        .itemName, .itemTime {
+        .itemName,
+        .itemTime {
           font-family: Source Han Sans CN, Source Han Sans CN;
           font-weight: 400;
           font-size: 28rpx;
-          color: #FFFFFF;
+          color: #ffffff;
         }
         .itemName {
           padding-left: 20rpx;
         }
-        .itemTime{
+        .itemTime {
           padding-right: 20rpx;
         }
       }
@@ -235,13 +346,12 @@
           font-size: 30rpx;
           color: #222324;
           white-space: nowrap;
-
         }
         .rowAddress {
           font-family: Source Han Sans CN, Source Han Sans CN;
           font-weight: 400;
           font-size: 28rpx;
-          color: #1D6FE9;
+          color: #1d6fe9;
           //white-space: nowrap;
           ///* 禁止换行 */
           //overflow: hidden;
@@ -268,14 +378,13 @@
       display: flex;
       justify-content: space-between;
       align-items: center;
-      :deep(.u-button){
+      :deep(.u-button) {
         width: 276rpx !important;
         height: 100rpx !important;
         &:last-child {
           margin-left: 30rpx;
         }
       }
-
     }
   }
 }

--
Gitblit v1.9.3