Kaynağa Gözat

🎨 优化采集管理逻辑

快乐的梦鱼 1 ay önce
ebeveyn
işleme
f3587018d4

+ 1 - 1
src/api/agent/Agent.ts

@@ -2,7 +2,7 @@ import { DataModel, type KeyValue } from "@imengyu/js-request-transform";
 import { appendGetUrlParams, assertNotNull, RandomUtils } from "@imengyu/imengyu-utils";
 import { useAuthStore } from "@/store/auth";
 import { RestfulApi } from "../restful";
-import { SSE } from "@/pages/home/chat/core/speical/ssemp";
+import { SSE } from "@/api/agent/ssemp";
 import type OpenAI from "openai";
 import { CommonPageResult } from "@/api/restful/types";
 import { AgentChatFile } from "./AgentChatFile";

src/pages/home/chat/core/speical/ssemp.ts → src/api/agent/ssemp.ts


+ 4 - 1
src/common/composeabe/UserTools.ts

@@ -27,8 +27,11 @@ export function useUserTools() {
     if (!authStore.isLogged) {
       return false;
     }
+    if (!authStore.isAdmin) {
+      return true;
+    }
     try {
-      return await OfficialApi.checkTopicRule(villageId);
+      return villageStore.myJoinedVillages.find(v => v.id === villageId)?.type === 'staff';
     } catch (e) {
       return false;
     }

+ 4 - 3
src/pages/dig/components/CollectModuleList.vue

@@ -14,7 +14,7 @@
       :title="item.title"
       :desc="item.desc"
       :extra="item.extra"
-      :goButtonText="isView ? '查看' : '去完成'"
+      :goButtonText="isView ? '查看' : (isManagement ? '管理' : '去完成')"
       :enable="item.enable"
       @click="handleClick(item)"
     />
@@ -57,7 +57,7 @@ async function loadList() {
 
   const res = (await VillageApi.getCatalogList(
     props.villageId, 
-    authStore.isAdmin || props.isManagement ? undefined : props.villageVolunteerId,
+    props.isManagement ? undefined : props.villageVolunteerId,
     props.taskPid
   ));
   if (res.length === 0)
@@ -68,7 +68,7 @@ async function loadList() {
         const formDefine = item.collectModuleId ? getVillageInfoForm(item.collectModuleId, -1) : undefined;
         return {
           ...item,
-          extra: authStore.isAdmin || props.isManagement && item.total >= 0 ? `已采编 ${item.total}` : '',
+          extra: props.isManagement && item.total >= 0 ? `已采编 ${item.total}` : '',
           enable: canCollectCatalog(item.id) || item.haschild,
           catalogItem: item,
           collectModuleId: item.collectModuleId,
@@ -135,6 +135,7 @@ const handleClick = (item: TaskMenuDefItem) => {
       taskName: item.goForm.name,
       taskTitle: item.title,
       taskPid: (item as any).id,
+      isManagement: props.isManagement,
       isView: props.isView,
     })
     return;

+ 16 - 10
src/pages/dig/details.vue

@@ -1,13 +1,21 @@
 <template>
   <CommonTopBanner title="共编村史">
-    <FlexCol v-if="isJoined || authStore.isAdmin || isManagement" :padding="30" :gap="20">
+    <FlexCol v-if="isJoined || isManagement" :padding="30" :gap="20">
       <Image
         :src="bannerLoader.content.value?.[0].image"
         mode="widthFix"
         radius="radius.md"
-        :width="690" 
+        :width="690"
       />
-      <FlexRow justify="space-between" align="center" :gap="10" backgroundColor="white" :padding="20" radius="radius.md">
+      
+      <FlexCol v-if="isManagement" center padding="padding.md" gap="gap.lg" >
+        <Image src="https://xy.wenlvti.net/app_static/images/mine/IconArchive.png" :width="100" :height="100" />
+        <Text
+          text="尊敬的用户,您已经是村社管理员,您可以为村社做出管理贡献,管理已采编的数据"
+          fontConfig="contentText" :fontSize="30" textAlign="center" 
+        />
+      </FlexCol>
+      <FlexRow v-else justify="space-between" align="center" :gap="10" backgroundColor="white" :padding="20" radius="radius.md">
         <FlexRow>
           <Text :fontSize="30" :text="isJoined ? '已认领:' : '未认领:'" />
           <Width :width="20" />
@@ -25,7 +33,7 @@
           </Touchable>
         </FlexRow>
       </FlexRow>
-      <BoxMid :padding="24">
+      <BoxMid v-if="!isManagement" :padding="24">
         <Touchable 
           direction="column" 
           touchable 
@@ -54,6 +62,7 @@
           :taskName="''"
           :taskTitle="''"
           :taskPid="0"
+          :isManagement="isManagement"
         />
       </FlexCol>
       <XBarSpace />
@@ -69,8 +78,10 @@ import { useAuthStore } from '@/store/auth';
 import { useCollectStore } from '@/store/collect';
 import { useTaskEntryForm } from './forms/composeable/TaskEntryForm';
 import { useUserTools } from '@/common/composeabe/UserTools';
+import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
 import { onMounted, ref } from 'vue';
-import { back, navTo } from '@/components/utils/PageAction';
+import { navTo } from '@/components/utils/PageAction';
+import { CollectableModulesIdMap } from './forms/forms';
 import BannerApi from '@/api/system/Banner';
 import Icon from '@/components/basic/Icon.vue';
 import Text from '@/components/basic/Text.vue';
@@ -83,14 +94,9 @@ import CollectModuleList from './components/CollectModuleList.vue';
 import XBarSpace from '@/components/layout/space/XBarSpace.vue';
 import Width from '@/components/layout/space/Width.vue';
 import Alert from '@/components/feedback/Alert.vue';
-import Result from '@/components/feedback/Result.vue';
-import Button from '@/components/basic/Button.vue';
-import { CollectableModulesIdMap } from './forms/forms';
-import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
 import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
 import NotVolTip from '../home/components/NotVolTip.vue';
 import BoxMid from '@/common/components/box/BoxMid.vue';
-import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
 
 const { querys } = useLoadQuerys({ 
   name: '',

+ 1 - 2
src/pages/dig/forms/list-ordinary.vue

@@ -69,8 +69,7 @@
               <FlexCol>
                 <FlexRow gap="gap.md">
                   <FrameButton :text="item.statusText" size="midium" @click="navTo('/pages/dig/about/goving')" />
-                  <FrameButton v-if="item.villageVolunteerId === volunteerInfo?.id" text="编辑" size="midium" @click="goEdit(item)" />
-                  <FrameButton v-if="isManagement" text="管理" size="midium" @click="goEdit(item)" />
+                  <FrameButton v-if="item.villageVolunteerId === volunteerInfo?.id || isManagement" :text="isManagement ? '管理' : '编辑'" size="midium" @click="goEdit(item)" />
                 </FlexRow>
                 <FlexRow justify="flex-end" gap="gap.md">
                   <IconButton icon="appreciate-light-fill" size="30" :text="item.likes" color="primary" />

+ 7 - 3
src/pages/dig/forms/list.vue

@@ -52,6 +52,7 @@
               <FlexCol>
                 <FlexRow>
                   <FrameButton :text="item.statusText" size="midium" @click="navTo('/pages/dig/about/goving')" />
+                  <FrameButton v-if="item.villageVolunteerId === volunteerInfo?.id || isManagement" :text="isManagement ? '管理' : '编辑'" size="midium" @click="goEdit(item)" />
                 </FlexRow>
                 <FlexRow justify="flex-end" gap="gap.md">
                   <IconButton icon="appreciate-light-fill" size="30" :text="item.likes" color="primary" />
@@ -179,6 +180,12 @@ function newData() {
   });
 }
 function goDetail(item: { id: number, villageVolunteerId: number }) {
+  navTo('/pages/home/discover/details', {
+    villageId: querys.value.villageId,
+    id: item.id,
+  });
+}
+function goEdit(item: { id: number, villageVolunteerId: number }) {
   navTo('common', { 
     id: item.id,
     villageId: querys.value.villageId,
@@ -188,9 +195,6 @@ function goDetail(item: { id: number, villageVolunteerId: number }) {
     subKey: querys.value.subKey,
     subId: querys.value.subId,
     subTitle: querys.value.subTitle,
-    //非当前村社志愿者或者不是自己提交的文章,只能查看详情
-    isView: querys.value.isView ? true : (!authStore.isAdmin 
-      && (!isJoined.value || item.villageVolunteerId !== volunteerInfo.value?.id) ? true : false),
   });
 }
 function search() {

+ 2 - 0
src/pages/dig/forms/task.vue

@@ -7,6 +7,7 @@
         :taskTitle="querys.taskTitle"
         :taskPid="querys.taskPid"
         :isView="querys.isView"
+        :isManagement="querys.isManagement"
       />
     </FlexCol>
   </CommonTopBanner>
@@ -24,5 +25,6 @@ const { querys } = useLoadQuerys({
   taskTitle: '',
   taskPid: 0,
   isView: false,
+  isManagement: false,
 });
 </script>

+ 1 - 1
src/pages/home/chat/core/Chat.ts

@@ -9,7 +9,7 @@ import { useChatStaticMessages } from "./StaticMessages";
 import { useChatContext, type ContextMemoryConfig, type ContextMemorySetting } from "./Context";
 import { useChatTools, type ChatToolsManager } from "./Tools";
 import type { ChatSessionManager } from "../composables/useChatSession";
-import type { SSE } from "./speical/ssemp";
+import type { SSE } from "../../../../api/agent/ssemp";
 import type OpenAI from "openai";
 import { requireNotNull } from "@imengyu/imengyu-utils";
 

+ 47 - 0
src/pages/home/village/dialogs/StaffInfoDialog.vue

@@ -0,0 +1,47 @@
+<template>
+  <CommonDialog v-model:show="show" title="管理员信息">
+    <template #titleHeader>    
+      <Image src="https://xy.wenlvti.net/app_static/images/mine/IconArchive.png" :width="100" :height="100" />
+    </template>
+    <FlexCol gap="gap.md">
+      
+      <FlexCol padding="padding.md" center>
+        <Text
+          text="尊敬的用户,您已经是村社管理员,您可以为村社做出管理贡献"
+          fontConfig="contentText" :fontSize="30" textAlign="center" 
+        />
+      </FlexCol>
+
+      <FlexCol padding="padding.md">
+        <Text
+          v-if="staffTimeType === 2"
+          :text="`您的管理员套餐到期时间 ${DateUtils.formatDate(staffEndTime, 'YYYY-MM-DD')}`"
+          fontConfig="contentText" :fontSize="30" textAlign="center"
+        />
+      </FlexCol>
+
+    </FlexCol>
+  </CommonDialog>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import CommonDialog from '@/common/components/CommonDialog.vue';
+import Image from '@/components/basic/Image.vue';
+import FlexCol from '@/components/layout/FlexCol.vue';
+import Text from '@/components/basic/Text.vue';
+import { DateUtils } from '@imengyu/imengyu-utils';
+
+const show = ref(false);
+const props = defineProps<{
+  staffEndTime: Date,
+  staffSource: number,
+  staffTimeType: number,
+}>();
+
+defineExpose({
+  show: () => {
+    show.value = true;
+  },
+});
+</script>

+ 49 - 38
src/pages/home/village/introd/card.vue

@@ -51,8 +51,16 @@
               :size="65"
               defaultAvatar="https://xy.wenlvti.net/app_static/images/mine/DefaultAvatar.png"
             />
-            <FlexCol gap="gap.sm" :padding="[0,30,0,0]">
-              <Text :text="displayMyName" fontSize="23" :lines="1" :maxWidth="200" fontConfig="lightImportantTitle" />
+            <FlexCol position="relative" gap="gap.sm" :padding="[0,30,0,0]">
+              <FlexRow align="center" :gap="10">
+                <Text :text="displayMyName" fontSize="23" :lines="1" :maxWidth="150" fontConfig="lightImportantTitle" />
+                <Button 
+                  v-if="isStaff" 
+                  :innerStyle="{ position: 'absolute', right: 0, top: 0, transform: 'translate(5%,-50%)' }"
+                  text="管理" size="mini" radius="radius.md" type="danger" 
+                  @click="staffInfoRef?.show()" 
+                />
+              </FlexRow>
               <IconButton icon="edit-filling" size="26" @click="changeNickRef?.show()">
                 <Text text="改昵称" fontSize="22" fontConfig="subText" />
               </IconButton>
@@ -298,6 +306,14 @@
     :villageId="villageStore.currentVillage.id"
     ref="changeNickRef"
   />  
+  <StaffInfoDialog 
+    v-if="villageStore.currentVillage && staffInfo"
+    :villageId="villageStore.currentVillage.id"
+    :staffEndTime="staffInfo.staffEndTime"
+    :staffSource="staffInfo.staffSource"
+    :staffTimeType="staffInfo.staffTimeType"
+    ref="staffInfoRef"
+  />  
   <Popup 
     :show="showUnLight"
     :zIndex="100"
@@ -375,6 +391,7 @@ import Popup from '@/components/dialog/Popup.vue';
 import Image from '@/components/basic/Image.vue';
 import Avatar from '@/components/display/Avatar.vue';
 import ChangeNickDialog from '../dialogs/ChangeNickDialog.vue';
+import StaffInfoDialog from '../dialogs/StaffInfoDialog.vue';
 
 const emit = defineEmits<{
   (e: 'goTree'): void;
@@ -430,10 +447,15 @@ const villageInfoLoader = useSimpleDataLoader(async () => {
 const isLight = computed(() => {
   return villageStore.currentVillage?.isLight ?? false;
 });
-const displayMyName = computed(() => {
-  const villageInfoInList = villageStore.myJoinedVillages.find(v => v.id === villageStore.currentVillage?.id);
-  return villageInfoInList?.villageNickname || authStore.userInfo?.nickname || authStore.userInfo?.username || '暂无昵称';
-});
+const extraInfoInList = computed(() => villageStore.myJoinedVillages.find(v => v.id === villageStore.currentVillage?.id));
+const displayMyName = computed(() => extraInfoInList.value?.villageNickname || authStore.userInfo?.nickname || authStore.userInfo?.username || '暂无昵称');
+const staffInfo = computed(() => extraInfoInList.value ? {
+  type: extraInfoInList.value.type as string,
+  staffEndTime: extraInfoInList.value.staffEndTime as Date,
+  staffSource: extraInfoInList.value.staffSource as number,
+  staffTimeType: extraInfoInList.value.staffTimeType as number,
+} : null);
+const isStaff = computed(() => staffInfo.value?.type === 'staff');
 
 const rankActiveTag = ref('文化积分');
 const listActiveTag = ref('广场');
@@ -525,13 +547,21 @@ function handleGoGallery() {
     maxCount: villageStore.currentVillage?.imageLimit || 3,
   });
 }
-async function handleGoOfficalManage() {
+
+const staffInfoRef = ref<InstanceType<typeof StaffInfoDialog>>();
+
+async function checkIsStaff(needTopic?: boolean) {
   assertNotNull(villageStore.currentVillage?.id)
-  const isAdmin = await OfficialApi.checkTopicRule(villageStore.currentVillage.id);
+  const isAdmin = needTopic ? 
+    await OfficialApi.checkTopicRule(villageStore.currentVillage.id)
+    : (authStore.isAdmin || isStaff.value);
   if (!isAdmin) {
     const goUpgrade = await confirm({
       title: '提示',
-      content: '您还不是管理员,无法管理贴图哦。您可以联系村社管理员将你添加为管理员,若当前村社暂无管理员,您可以点击“去升级”将您升级为管理员。',
+      content: '您还不是管理员' 
+        + (needTopic ? '/或暂无管理贴图权限' : '') 
+        + ',无法管理贴图哦。' 
+        + '您可以联系村社管理员将你添加为管理员,若当前村社暂无管理员,您可以点击“去升级”将您升级为管理员。',
       confirmText: '去升级',
       cancelText: '取消',
     });
@@ -540,8 +570,15 @@ async function handleGoOfficalManage() {
         villageId: villageStore.currentVillage.id,
       });
     }
-    return;
+    return false;
   }
+  return true;
+}
+
+async function handleGoOfficalManage() {
+  assertNotNull(villageStore.currentVillage?.id)
+  if (!await checkIsStaff(true)) 
+    return;
   navTo('/pages/home/village/post/management-list', {
     villageId: villageStore.currentVillage.id,
     topic: recommendTagName.value,
@@ -549,42 +586,16 @@ async function handleGoOfficalManage() {
 }
 async function handleGoEdit() {
   assertNotNull(villageStore.currentVillage?.id)
-  /* const isAdmin = (authStore.isAdmin || await OfficialApi.checkTopicRule(villageStore.currentVillage.id));
-  if (!isAdmin) {
-    const goUpgrade = await confirm({
-      title: '提示',
-      content: '您还不是管理员,您可以联系村社管理员将你添加为管理员,若当前村社暂无管理员,您可以点击“去升级”将您升级为管理员。',
-      confirmText: '去升级',
-      cancelText: '取消',
-    });
-    if (goUpgrade) {
-      navTo('/pages/home/village/upgrade/my-upgrade-management', {
-        villageId: villageStore.currentVillage.id,
-      });
-    }
+  if (!await checkIsStaff())
     return;
-  } */
   navTo('/pages/home/village/introd/edit', {
     villageId: villageStore.currentVillage.id,
   });
 }
 async function handleGoDigManage() {
   assertNotNull(villageStore.currentVillage?.id)
-  const isAdmin = (authStore.isAdmin || await OfficialApi.checkTopicRule(villageStore.currentVillage.id));
-  if (!isAdmin) {
-    const goUpgrade = await confirm({
-      title: '提示',
-      content: '您还不是管理员,您可以联系村社管理员将你添加为管理员,若当前村社暂无管理员,您可以点击“去升级”将您升级为管理员。',
-      confirmText: '去升级',
-      cancelText: '取消',
-    });
-    if (goUpgrade) {
-      navTo('/pages/home/village/upgrade/my-upgrade-management', {
-        villageId: villageStore.currentVillage.id,
-      });
-    }
+  if (!await checkIsStaff())
     return;
-  }
   navTo('/pages/dig/details', {
     name: villageStore.currentVillage.title,
     villageId: villageStore.currentVillage.id,