Sfoglia il codice sorgente

feat: 人员数据统计发送消息和设置工作量

chenhao 2 anni fa
parent
commit
cbd2628a63

+ 6 - 1
src/api/system.ts

@@ -39,7 +39,12 @@ const SystemApi: DefineApiModule<System.ApiMap> = {
     download: true,
   },
   /** 任务设置 - 按评卷员设置 */
-  markerSetCount: '/api/user/marker/add/count',
+  markerSetCount: {
+    url: '/api/user/marker/add/count',
+    headers: {
+      'Content-Type': 'multipart/form-data',
+    },
+  },
   /** 任务设置 - 按小组追加 */
   markGroupUpdateCount: '/api/user/marker/update/count',
   /** 任务设置-获取任务计划 */

+ 4 - 1
src/components/shared/MarkHeader.vue

@@ -17,7 +17,9 @@
 
     <div class="flex flex-1 items-center mark-header">
       <slot></slot>
-      <span class="data-item"><message :paper-path="props.paperPath"></message></span>
+      <span class="data-item">
+        <message :reply-user-id="props.replyUserId" :paper-path="props.paperPath"></message>
+      </span>
       <span class="data-item"><user-info></user-info></span>
     </div>
   </div>
@@ -91,6 +93,7 @@ const buttons: HeaderButton[] = [
 const props = defineProps<{
   excludeOperations?: ButtonType[]
   includeOperations?: ButtonType[]
+  replyUserId?: number | null
   paperPath?: string | null
 }>()
 

+ 29 - 3
src/components/shared/message/Message.vue

@@ -44,7 +44,7 @@
     <message-window
       v-model="visibleMessageWindow"
       v-model:type="messageWindowType"
-      :reply-user-id="props.replyUserId"
+      v-model:replyUserId="replyUserId"
       :paper-path="props.paperPath"
     ></message-window>
   </message-component>
@@ -52,7 +52,7 @@
 
 <script setup lang="ts" name="Message">
 /** 头部消息组件 */
-import { defineComponent, withDefaults, ref, useSlots } from 'vue'
+import { defineComponent, withDefaults, ref, useSlots, watch, inject } from 'vue'
 import { ElPopover } from 'element-plus'
 import dayjs from 'dayjs'
 import useVW from '@/hooks/useVW'
@@ -67,9 +67,10 @@ const props = withDefaults(
   defineProps<{
     type?: 'view' | 'send'
     replyUserId?: number | null
+    messageVisible?: boolean | null
     paperPath?: string | null
   }>(),
-  { type: 'view', replyUserId: null, paperPath: null }
+  { type: 'view', replyUserId: null, paperPath: null, messageVisible: false }
 )
 
 const MessageComponent = defineComponent({
@@ -85,15 +86,40 @@ const MessageComponent = defineComponent({
   },
 })
 
+const setMessageVisible = inject<(visible: boolean) => void>('setMessageVisible')
+const setReplyUserId = inject<(replyUserId: number | null) => void>('setReplyUserId')
+
 const messageIcon = ref<HTMLDivElement>()
 
 const unReadMessages = useMessageLoop()
 
 const messageWindowType = useVModel(props, 'type')
 
+const replyUserId = useVModel(props, 'replyUserId')
+
 /** 发送/查看消息Modal */
 const visibleMessageWindow = ref<boolean>(false)
 
+watch(
+  () => props.messageVisible,
+  () => {
+    if (props.messageVisible) {
+      visibleMessageWindow.value = true
+      messageWindowType.value = 'send'
+    }
+  }
+)
+
+watch(visibleMessageWindow, () => {
+  if (!visibleMessageWindow.value) {
+    setMessageVisible?.(false)
+  }
+})
+
+watch(replyUserId, () => {
+  setReplyUserId?.(replyUserId.value)
+})
+
 /** 收消息 */
 const onReceiveMessage = () => {
   messageWindowType.value = 'view'

+ 6 - 1
src/layout/main/MainHeader.vue

@@ -8,7 +8,7 @@
     </div>
     <div class="flex items-center header-info-view">
       <div class="m-r-base">
-        <message></message>
+        <message :reply-user-id="props.replyUserId" :message-visible="props.messageVisible"></message>
       </div>
       <div class="m-r-base">
         <user-info></user-info>
@@ -28,6 +28,11 @@ import useMainLayoutStore from '@/store/layout'
 import Message from '@/components/shared/message/Message.vue'
 import UserInfo from '@/components/shared/UserInfo.vue'
 
+const props = defineProps<{
+  replyUserId?: number | null
+  messageVisible?: boolean
+}>()
+
 const mainLayoutStore = useMainLayoutStore()
 </script>
 

+ 17 - 1
src/layout/main/index.vue

@@ -10,7 +10,7 @@
       </div>
     </div>
     <div class="flex flex-1 direction-column scroll-auto main-layout-right">
-      <main-header></main-header>
+      <main-header :reply-user-id="replyUserId" :message-visible="messageVisible"></main-header>
       <div class="flex-1 scroll-auto main-layout-right-content">
         <RouterView></RouterView>
       </div>
@@ -19,11 +19,27 @@
 </template>
 
 <script setup lang="ts" name="MainLayout">
+import { ref, provide } from 'vue'
 import LeftMenu from './LeftMenu.vue'
 import MainHeader from './MainHeader.vue'
 import useMainLayoutStore from '@/store/layout'
 
 const mainLayoutStore = useMainLayoutStore()
+
+const replyUserId = ref<number>()
+
+const messageVisible = ref<boolean>(false)
+
+const setReplyUserId = (id: number) => {
+  replyUserId.value = id
+}
+
+const setMessageVisible = (visible: boolean) => {
+  messageVisible.value = visible
+}
+
+provide('setReplyUserId', setReplyUserId)
+provide('setMessageVisible', setMessageVisible)
 </script>
 
 <style scoped lang="scss">

+ 43 - 12
src/modules/analysis/personnel-statistics/components/SetWorkload.vue

@@ -1,6 +1,12 @@
 <template>
-  <base-dialog title="设置工作量" :width="useVW(400)" @update:model-value="(v) => emit('update:modelValue', v)">
-    <base-form :items="items" :model="model" :label-width="useVW(80)">
+  <base-dialog
+    title="设置工作量"
+    :width="useVW(500)"
+    :footer="false"
+    destroy-on-close
+    @update:model-value="(v) => emit('update:modelValue', v)"
+  >
+    <base-form ref="formRef" :rules="rules" :items="items" :model="model" :label-width="useVW(100)" :disabled="loading">
       <template #form-item-markerName>
         {{ data?.markerName }}
       </template>
@@ -15,24 +21,36 @@
 </template>
 
 <script setup lang="ts" name="SetWorkload">
-import { reactive, ref } from 'vue'
-import { ElFormItem } from 'element-plus'
+import { reactive } from 'vue'
+import { ElFormItem, ElMessage } from 'element-plus'
 import BaseDialog from '@/components/element/BaseDialog.vue'
 import BaseForm from '@/components/element/BaseForm.vue'
 import useForm from '@/hooks/useForm'
 import useVW from '@/hooks/useVW'
+import useFetch from '@/hooks/useFetch'
 import ConfirmButton from '@/components/common/ConfirmButton.vue'
 
-import type { EpFormItem } from 'global-type'
-import type { ExtractApiResponse } from 'api-type'
+import type { EpFormItem, EpFormRules } from 'global-type'
+import type { ExtractApiParams, ExtractApiResponse } from 'api-type'
 
 const props = defineProps<{ data?: ExtractArrayValue<ExtractApiResponse<'getStatisticsByGroup'>> }>()
 
 const emit = defineEmits(['update:modelValue'])
 
-const { formRef } = useForm()
+const { fetch: markerSetCount, loading } = useFetch('markerSetCount')
 
-const model = reactive({})
+const { formRef, elFormRef } = useForm()
+
+const model = reactive<ExtractApiParams<'markerSetCount'>>({
+  markDayCount: void 0,
+  markTotalCount: void 0,
+  userId: [],
+})
+
+const rules: EpFormRules = {
+  markTotalCount: [{ required: true, message: '请填写评卷员工作量' }],
+  markDayCount: [{ required: true, message: '请填写评卷员每日工作量' }],
+}
 
 const items: EpFormItem[] = [
   {
@@ -42,19 +60,32 @@ const items: EpFormItem[] = [
   {
     label: '工作量',
     slotType: 'input',
+    prop: 'markTotalCount',
   },
   {
     label: '每日工作量',
     slotType: 'input',
+    prop: 'markDayCount',
   },
 ]
 
-function onConfirm() {
-  console.log('onConfirm', props.data)
+const onConfirm = async () => {
+  try {
+    if (!props.data?.markerId) {
+      return
+    }
+    const valid = await elFormRef?.value?.validate()
+    if (valid) {
+      await markerSetCount({ ...model, userId: [props.data.markerId] })
+    }
+    ElMessage.success('设置成功')
+    emit('update:modelValue', false)
+  } catch (error) {
+    console.error(error)
+  }
 }
 
-function onCancel() {
-  console.log('onCancel')
+const onCancel = () => {
   emit('update:modelValue', false)
 }
 </script>

+ 6 - 1
src/modules/analysis/personnel-statistics/components/StatisticsPersonnel.vue

@@ -30,7 +30,7 @@
 
 <script setup lang="tsx" name="StatisticsPersonnel">
 /** 人员数据统计-按人员展开 */
-import { reactive, ref } from 'vue'
+import { reactive, ref, inject } from 'vue'
 import { ElButton, ElPopover, ElMenu, ElMenuItem } from 'element-plus'
 import BaseTable from '@/components/element/BaseTable.vue'
 import SetWorkload from './SetWorkload.vue'
@@ -42,6 +42,9 @@ import type { PopoverInstance } from 'element-plus'
 
 defineProps<{ data: ExtractApiResponse<'getStatisticsByGroup'> }>()
 
+const setMessageVisible = inject<(visible: boolean) => void>('setMessageVisible')
+const setReplyUserId = inject<(id: number) => void>('setReplyUserId')
+
 const columns: EpTableColumn<ExtractArrayValue<ExtractApiResponse<'getStatisticsByGroup'>>>[] = [
   {
     label: '小组',
@@ -112,6 +115,8 @@ function onSetWorkload(data: ExtractArrayValue<ExtractApiResponse<'getStatistics
 function onSendMessage(data: ExtractArrayValue<ExtractApiResponse<'getStatisticsByGroup'>>) {
   popovers[`popovers-${data.markerId}`]?.hide()
   console.log('发送消息', data)
+  setReplyUserId?.(data.markerId)
+  setMessageVisible?.(true)
 }
 </script>
 

+ 0 - 5
src/store/admin.ts

@@ -1,5 +0,0 @@
-import { defineStore } from 'pinia'
-
-const useAdminStore = defineStore('admin', {})
-
-export default useAdminStore