yanghao hace 1 mes
padre
commit
37538ed940
Se han modificado 2 ficheros con 202 adiciones y 206 borrados
  1. 199 206
      src/views/flow/ehrTodoList.vue
  2. 3 0
      src/views/index.vue

+ 199 - 206
src/views/flow/ehrTodoList.vue

@@ -26,64 +26,59 @@
           />&#36820;&#22238;</el-button
         >
       </div>
-      <div v-loading="loading" class="table-wrapper">
-        <el-table
-          v-loading="loading"
-          :data="oaTasks"
-          style="width: 100%"
-          stripe
-          height="70vh"
-          element-loading-text="加载中..."
-          :empty-text="loading ? '' : '暂无数据'"
-          :header-cell-style="{
-            backgroundColor: 'var(--bg-table-head) !important',
-            color: 'var(--text-primary)',
-            fontWeight: '400',
-          }"
-        >
-          <el-table-column
-            type="index"
-            label="&#24207;&#21495;"
-            width="80"
-            fixed="left"
-            align="center"
-            :index="getIndex"
-          />
-          <el-table-column prop="title" label="请求标题" align="center" />
-
-          <el-table-column
-            prop="createTime"
-            label="&#21019;&#24314;&#26102;&#38388;"
-            align="center"
-          />
-
-          <el-table-column
-            label="&#25805;&#20316;"
-            width="120"
-            fixed="right"
-            align="center"
+
+      <div v-loading="loading && oaTasks.length === 0" class="table-wrapper">
+        <div class="table-summary mb-4 text-var(--text-secondary)!">
+          共 {{ pagination.total }} 条待办
+        </div>
+
+        <div class="task-scroll-list">
+          <div
+            v-for="(item, index) in oaTasks"
+            :key="item.id || item.h5_url || item.web_url || `${item.title}-${index}`"
+            class="task-card"
           >
-            <template #default="scope">
-              <span
-                class="text-[#1e90ff] cursor-pointer text-[13px]"
-                @click="goBackPage(scope.row)"
-                >&#22788;&#29702;</span
-              >
+            <div class="task-card__header">
+              <span class="task-card__index">{{ index + 1 }}</span>
+              <span class="task-card__action" @click="goBackPage(item)">
+                处理
+              </span>
+            </div>
+
+            <div class="task-card__title">
+              {{ item.title || "--" }}
+            </div>
+
+            <div class="task-card__grid">
+              <div class="task-card__field task-card__field--full">
+                <span class="task-card__label">请求标题</span>
+                <span class="task-card__value">{{ item.title || "--" }}</span>
+              </div>
+              <div class="task-card__field task-card__field--full">
+                <span class="task-card__label">创建时间</span>
+                <span class="task-card__value">{{
+                  item.createTime || "--"
+                }}</span>
+              </div>
+            </div>
+          </div>
+
+          <InfiniteLoading
+            :identifier="infiniteId"
+            spinner="spiral"
+            @infinite="loadMore"
+          >
+            <template #no-more>
+              <div class="infinite-status">没有更多数据了</div>
             </template>
-          </el-table-column>
-        </el-table>
-      </div>
-      <div class="pagination-container">
-        <el-pagination
-          v-model:current-page="pagination.pageNum"
-          v-model:page-size="pagination.pageSize"
-          :total="pagination.total"
-          :page-sizes="[10, 20, 50, 100]"
-          layout="total, sizes, prev, pager, next"
-          background
-          @current-change="handleCurrentChange"
-          @size-change="handleSizeChange"
-        />
+            <template #no-results>
+              <div class="infinite-status">暂无数据</div>
+            </template>
+            <template #error>
+              <div class="infinite-status">加载失败,请稍后重试</div>
+            </template>
+          </InfiniteLoading>
+        </div>
       </div>
     </div>
 
@@ -99,11 +94,13 @@ import { getEHRTasks, ehrLogin } from "@/api/user";
 import { useUserStore } from "@/stores/useUserStore";
 import { Icon } from "@iconify/vue";
 import router from "@/router";
+import InfiniteLoading from "vue-infinite-loading";
+
 const userStore = useUserStore();
-import { ElLoading, ElMessage } from "element-plus";
 
 const oaTasks = ref([]);
 const loading = ref(false);
+const infiniteId = ref(Date.now());
 
 const pagination = ref({
   pageNum: 1,
@@ -111,24 +108,77 @@ const pagination = ref({
   total: 0,
 });
 
+const loadTaskPage = async () => {
+  const res = await getEHRTasks({
+    id: userStore.getUser.username,
+    pageNum: pagination.value.pageNum,
+    pageSize: pagination.value.pageSize,
+  });
+
+  pagination.value.total = Number(res?.todoCount || 0);
+  return Array.isArray(res?.todoList) ? res.todoList : [];
+};
+
+const resetList = () => {
+  oaTasks.value = [];
+  pagination.value.pageNum = 1;
+  pagination.value.total = 0;
+  infiniteId.value = Date.now();
+};
+
+const loadMore = async ($state) => {
+  if (!userStore.getUser.username) {
+    $state.complete();
+    return;
+  }
+
+  loading.value = pagination.value.pageNum === 1;
+
+  try {
+    const list = await loadTaskPage();
+
+    if (pagination.value.pageNum === 1) {
+      oaTasks.value = list;
+    } else {
+      oaTasks.value = [...oaTasks.value, ...list];
+    }
+
+    const loadedCount = oaTasks.value.length;
+    const hasMore =
+      list.length === pagination.value.pageSize &&
+      loadedCount < pagination.value.total;
+
+    if (hasMore) {
+      pagination.value.pageNum += 1;
+      $state.loaded();
+    } else {
+      $state.complete();
+    }
+  } catch (error) {
+    $state.error();
+  } finally {
+    loading.value = false;
+  }
+};
+
 const goBackPage = async (row) => {
   const res = await ehrLogin({
     username: userStore.getUser.username,
   });
 
   if (res) {
-    const ua = window.navigator.userAgent; // const ua = navigator.userAgent;
+    const ua = window.navigator.userAgent;
     const isDesktop =
       ua.includes("DingTalk") &&
       (ua.includes("Windows") || ua.includes("Macintosh"));
 
-    let ua2 = navigator.userAgent.toLowerCase();
-    var isMobile = ua2.indexOf("dingtalk") > -1;
+    const ua2 = navigator.userAgent.toLowerCase();
+    const isMobile = ua2.indexOf("dingtalk") > -1;
+
     if (ua2.includes("dingtalk") || ua2.includes("dingtalkwork")) {
       if (isMobile && !isDesktop) {
         dd.biz.util.openLink({
           url: `${res.ehrUrl}/gateway/login/free?loginfree_licence=${res.licence}&signature=${res.sign}&redirect_url=/proxy/h5/home`,
-
           onSuccess: () => {
             setTimeout(() => {
               dd.biz.util.openLink({
@@ -141,69 +191,24 @@ const goBackPage = async (row) => {
         const newTab = window.open("", "_blank");
         newTab.location.href = `${res.ehrUrl}/gateway/login/free?loginfree_licence=${res.licence}&signature=${res.sign}&redirect_url=${res.redirect}`;
 
-        setTimeout(function () {
+        setTimeout(() => {
           newTab.location.href = `${res.ehrUrl}/gateway/login/free?loginfree_licence=${res.licence}&signature=${res.sign}&redirect_url=${row.web_url}`;
-          setTimeout(() => {}, 500);
         }, 500);
       }
     } else {
       const newTab = window.open("", "_blank");
       newTab.location.href = `${res.ehrUrl}/gateway/login/free?loginfree_licence=${res.licence}&signature=${res.sign}&redirect_url=${res.redirect}`;
 
-      setTimeout(function () {
+      setTimeout(() => {
         newTab.location.href = `${res.ehrUrl}/gateway/login/free?loginfree_licence=${res.licence}&signature=${res.sign}&redirect_url=${row.web_url}`;
-        setTimeout(() => {}, 500);
       }, 500);
     }
   }
 };
 
-const handleCurrentChange = async (page) => {
-  pagination.value.pageNum = page;
-  try {
-    const res = await getEHRTasks({
-      id: userStore.getUser.username,
-      pageNum: pagination.value.pageNum,
-      pageSize: pagination.value.pageSize,
-    });
-    oaTasks.value = res.todoList;
-    pagination.value.total = Number(res.todoCount);
-  } finally {
-    loading.value = false;
-  }
-};
-
-const handleSizeChange = async (size) => {
-  pagination.value.pageSize = size;
-  pagination.value.pageNum = 1;
-
-  try {
-    const res = await getEHRTasks({
-      id: userStore.getUser.username,
-      pageNum: pagination.value.pageNum,
-      pageSize: pagination.value.pageSize,
-    });
-    oaTasks.value = res.todoList;
-    pagination.value.total = Number(res.todoCount);
-  } finally {
-    loading.value = false;
-  }
-};
-
-onMounted(async () => {
+onMounted(() => {
   if (userStore.getUser.username) {
-    loading.value = true;
-    try {
-      const res = await getEHRTasks({
-        id: userStore.getUser.username,
-        pageNum: pagination.value.pageNum,
-        pageSize: pagination.value.pageSize,
-      });
-      oaTasks.value = res.todoList;
-      pagination.value.total = Number(res.todoCount);
-    } finally {
-      loading.value = false;
-    }
+    resetList();
   }
 });
 </script>
@@ -297,6 +302,7 @@ onMounted(async () => {
 .nav {
   background-color: var(--bg-table);
 }
+
 .todo-list {
   min-height: 100vh;
   display: flex;
@@ -324,7 +330,6 @@ onMounted(async () => {
 .content-wrapper {
   flex: 1;
   max-width: 1200px;
-  /* margin: 0 auto; */
   padding: 20px;
   width: 100%;
   box-sizing: border-box;
@@ -338,7 +343,7 @@ onMounted(async () => {
 }
 
 .table-wrapper {
-  min-height: 400px;
+  min-height: 300px;
   background: #fff;
   padding: 20px;
   border-radius: 4px;
@@ -350,136 +355,124 @@ onMounted(async () => {
 }
 
 .table-summary {
-  color: #606266;
   font-size: 13px;
 }
 
-.pagination-container {
-  display: flex;
-  justify-content: center;
-  margin-top: 0px;
-  padding: 20px 0;
-}
-
-:deep(.el-table) {
-  background-color: var(--bg-table) !important;
-  color: var(--text-primary) !important;
-}
-
-:deep(.table-wrapper) {
-  background: var(--bg-table) !important;
-}
-
-:deep(.el-table__header-wrapper thead) {
-  background: var(--bg-table-head) !important;
-  color: var(--text-primary) !important;
+.task-scroll-list {
+  padding-right: 4px;
+  background-color: transparent;
 }
 
-:deep(.el-table__header-wrapper .el-table__header) {
-  border-bottom: none;
-  background: var(--bg-table-head) !important;
-}
-:deep(.el-table__inner-wrapper) {
-  background: var(--bg-table) !important;
-  color: var(--text-primary) !important;
-}
-:deep(.el-table__body-wrapper .el-table__row) {
-  background: var(--bg-table);
-  color: var(--text-primary) !important;
+.task-card {
+  background: var(--bg-card-2) !important;
+  border: 1px solid var(--item-card-border);
+  border-radius: 18px;
+  padding: 16px;
+  margin-bottom: 14px;
+  box-shadow: var(--portal-shadow);
 }
 
-:deep(.el-table__body-wrapper .el-table__row .hover-row) {
-  background: var(--bg-table) !important;
-  color: var(--text-primary) !important;
+.task-card__header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  margin-bottom: 12px;
+  gap: 12px;
 }
 
-:deep(.el-table__body-wrapper .el-table__row .el-table__cell) {
-  background: var(--bg-table) !important;
-  color: var(--text-primary) !important;
-  border-bottom: 1px solid var(--border-color) !important;
+.task-card__index {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  width: 28px;
+  height: 28px;
+  border-radius: 999px;
+  background: var(--portal-accent-soft);
+  color: var(--portal-accent);
+  font-size: 13px;
+  font-weight: 600;
+  flex-shrink: 0;
 }
 
-:deep(.el-loading-mask) {
-  background-color: var(--bg-table) !important; /* 半透明深色遮罩 */
+.task-card__action {
+  color: var(--portal-accent);
+  font-size: 13px;
+  cursor: pointer;
 }
 
-:deep(.el-table__body-wrapper .el-table__row .el-table__cell) {
-  border-bottom: 1px solid #313849;
+.task-card__title {
+  font-size: 16px;
+  font-weight: 600;
+  line-height: 1.5;
+  color: var(--portal-title);
+  margin-bottom: 12px;
+  word-break: break-word;
 }
 
-:deep(.el-pagination is-background) {
-  background: var(--bg-table) !important;
+.task-card__grid {
+  display: grid;
+  grid-template-columns: repeat(2, minmax(0, 1fr));
+  gap: 12px;
 }
 
-:deep(.el-pagination .el-pager li) {
-  background: var(--bg-table) !important;
-  color: var(--text-tertiary) !important;
+.task-card__field {
+  display: flex;
+  flex-direction: column;
+  gap: 4px;
+  min-width: 0;
 }
 
-:deep(.el-pagination .el-pager li.is-active) {
-  /* background: #2d8cf0 !important; */
-  color: var(--portal-accent) !important;
+.task-card__field--full {
+  grid-column: 1 / -1;
 }
 
-:deep(.el-select .el-select__wrapper) {
-  background: var(--bg-table) !important;
-  border: 1px solid #313849 !important;
-  outline: none !important;
+.task-card__label {
+  font-size: 12px;
+  color: var(--portal-text-soft);
 }
 
-:deep(.el-input) {
-  border: 1px solid #313849 !important;
-  outline: none !important;
+.task-card__value {
+  font-size: 13px;
+  line-height: 1.5;
+  color: var(--portal-text);
+  word-break: break-all;
 }
 
-:deep(.btn-next) {
-  background: var(--bg-table) !important;
-  color: var(--text-tertiary) !important;
+.infinite-status {
+  color: var(--portal-text-soft);
+  text-align: center;
+  padding: 12px 0;
+  font-size: 13px;
 }
 
-:deep(.btn-prev) {
+:deep(.table-wrapper) {
   background: var(--bg-table) !important;
-  color: var(--text-tertiary) !important;
 }
 
-/* 下拉菜单弹出层的背景 */
-:deep(.el-select-dropdown) {
+:deep(.el-loading-mask) {
   background-color: var(--bg-table) !important;
-  border: 1px solid #313849 !important;
-}
-
-/* 下拉菜单项 */
-:deep(.el-select-dropdown__item) {
-  color: var(--bg-table) !important;
 }
 
-:deep(.el-select-dropdown__item.hover),
-:deep(.el-select-dropdown__item:hover) {
-  background-color: var(--bg-table) !important; /* 悬停深色背景 */
-}
+@media (max-width: 640px) {
+  .content-wrapper {
+    padding: 16px;
+  }
 
-/* 关键:修复下拉选择框 (PageSize) 的白色边框/背景 */
-:deep(.el-pagination .el-select .el-select__wrapper) {
-  background-color: var(--bg-table) !important;
-  box-shadow: none !important; /* 去掉可能的阴影 */
-  border: 1px solid #313849 !important; /* 统一边框颜色 */
-}
+  .table-wrapper {
+    padding: 16px;
+  }
 
-/* 去掉聚焦时的白色/蓝色轮廓 */
-:deep(.el-pagination .el-select .el-select__wrapper.is-focused),
-:deep(.el-pagination .el-select .el-select__wrapper:hover) {
-  box-shadow: none !important;
-  border-color: #409eff !important; /* 聚焦时变为主题蓝,或者保持 #313849 */
-}
+  .task-card {
+    padding: 14px;
+    border-radius: 16px;
+  }
 
-/* 通用输入框边框修复 (如果其他地方也有) */
-:deep(.el-input__wrapper) {
-  background-color: var(--bg-table) !important;
-  box-shadow: none !important; /* 去掉默认的白色/灰色阴影边框 */
-  border: 1px solid #313849 !important;
-}
+  .task-card__grid {
+    grid-template-columns: 1fr;
+  }
 
-:deep(.el-input__inner) {
-  color: var(--bg-primary) !important;
+  .task-card__field--full {
+    grid-column: auto;
+  }
 }
 </style>

+ 3 - 0
src/views/index.vue

@@ -778,6 +778,7 @@ const handleQuickAccessCommand = (command: string) => {
     "done-crm": "/crm-done-list?type=crm",
     "todo-srm": "/mobile-srm-todo-list?type=srm",
     "done-srm": "/srm-done-list?type=srm",
+    "todo-ehr": "/ehr-todo-list?type=ehr",
   };
 
   let target = null;
@@ -790,6 +791,7 @@ const handleQuickAccessCommand = (command: string) => {
 
         onSuccess: () => {},
       });
+      return;
     }
 
     if (command === "done-oa") {
@@ -798,6 +800,7 @@ const handleQuickAccessCommand = (command: string) => {
 
         onSuccess: () => {},
       });
+      return;
     }
   }