Browse Source

fix: 🐛 修复项目管理问题

@sun-chaoqun 2 years ago
parent
commit
32f9f6403f

+ 0 - 3
components.d.ts

@@ -12,9 +12,7 @@ declare module '@vue/runtime-core' {
     404: typeof import('./src/components/ErrorMessage/404.vue')['default']
     404: typeof import('./src/components/ErrorMessage/404.vue')['default']
     Dialog: typeof import('./src/components/dialog/Dialog.vue')['default']
     Dialog: typeof import('./src/components/dialog/Dialog.vue')['default']
     Drawer: typeof import('./src/components/Drawer/index.vue')['default']
     Drawer: typeof import('./src/components/Drawer/index.vue')['default']
-    ElAlert: typeof import('element-plus/es')['ElAlert']
     ElAside: typeof import('element-plus/es')['ElAside']
     ElAside: typeof import('element-plus/es')['ElAside']
-    ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
     ElAvatar: typeof import('element-plus/es')['ElAvatar']
     ElAvatar: typeof import('element-plus/es')['ElAvatar']
     ElBadge: typeof import('element-plus/es')['ElBadge']
     ElBadge: typeof import('element-plus/es')['ElBadge']
     ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
     ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
@@ -52,7 +50,6 @@ declare module '@vue/runtime-core' {
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
-    ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
     ElTabPane: typeof import('element-plus/es')['ElTabPane']
     ElTabPane: typeof import('element-plus/es')['ElTabPane']

+ 9 - 9
src/api/project/index.ts

@@ -1,20 +1,20 @@
 import $http from '../index'
 import $http from '../index'
 
 
 // 项目列表(财务)
 // 项目列表(财务)
-export const Project_Finance_List = (params: any) => $http.post('/testapi/project/Project/Finance_List', params)
+export const Project_Finance_List = (params: any) => $http.post('/api/project/Project/Finance_List', params)
 // 项目列表
 // 项目列表
-export const Project_List = (params: any) => $http.post('/testapi/project/Project/List', params)
+export const Project_List = (params: any) => $http.post('/api/project/Project/List', params)
 // 审批
 // 审批
-export const Project_Approval = (params: any) => $http.post('/testapi/project/Project/Approval', params)
+export const Project_Approval = (params: any) => $http.post('/api/project/Project/Approval', params)
 // 我的项目
 // 我的项目
-export const Project_Project_User_list = (params: any) => $http.post('/testapi/project/Project/User_list', params)
+export const Project_Project_User_list = (params: any) => $http.post('/api/project/Project/User_list', params)
 // 详情
 // 详情
-export const Project_Get = (params: any) => $http.post('/testapi/project/Project/Get', params)
+export const Project_Get = (params: any) => $http.post('/api/project/Project/Get', params)
 // 立项申请
 // 立项申请
-export const Project_Add = (params: any) => $http.post('/testapi/project/Project/Add', params)
+export const Project_Add = (params: any) => $http.post('/api/project/Project/Add', params)
 // 编辑
 // 编辑
-export const Project_Edit = (params: any) => $http.post('/testapi/project/Project/Edit', params)
+export const Project_Edit = (params: any) => $http.post('/api/project/Project/Edit', params)
 // 删除
 // 删除
-export const Project_Del = (params: any) => $http.post('/testapi/project/Project/Del', params)
+export const Project_Del = (params: any) => $http.post('/api/project/Project/Del', params)
 // 左侧用户列表
 // 左侧用户列表
-export const Project_User_List = (params: any) => $http.post('/testapi/project/User/List', params)
+export const Project_User_List = (params: any) => $http.post('/api/project/User/List', params)

+ 1 - 1
src/components/Image/index.vue

@@ -3,7 +3,7 @@ import { ref } from 'vue'
 import { Picture } from '@element-plus/icons-vue'
 import { Picture } from '@element-plus/icons-vue'
 
 
 interface PropsType {
 interface PropsType {
-  src: string
+  src?: string
 }
 }
 const props = defineProps<PropsType>()
 const props = defineProps<PropsType>()
 const src = ref(props.src)
 const src = ref(props.src)

+ 0 - 7
src/components/TableBase/index.scss

@@ -1,6 +1,5 @@
 .table-header {
 .table-header {
   background-color: #fff;
   background-color: #fff;
-  // height: 5rem;
   margin-bottom: 0.75rem;
   margin-bottom: 0.75rem;
   border: 1px solid var(--el-border-color-light);
   border: 1px solid var(--el-border-color-light);
   border-radius: 8px;
   border-radius: 8px;
@@ -10,14 +9,8 @@
   align-items: center;
   align-items: center;
 }
 }
 
 
-// .table-header,
-// .card {
-//   box-shadow: var(--el-box-shadow-light);
-// }
-
 .card {
 .card {
   flex: 1 1 0%;
   flex: 1 1 0%;
-  // height: calc(100% - 5rem - 0.75rem);
   transition: height 1.25s ease-in-out;
   transition: height 1.25s ease-in-out;
   box-sizing: border-box;
   box-sizing: border-box;
   padding: 20px;
   padding: 20px;

+ 1 - 1
src/layouts/Header/index.vue

@@ -99,7 +99,7 @@ const computedNotice = computed(() => {
           <span style="padding: 0 10px">正在切换主题</span>
           <span style="padding: 0 10px">正在切换主题</span>
         </div>
         </div>
         <template #reference>
         <template #reference>
-          <el-button class="toggle" :icon="isDark ? Moon : Sunny" circle @click="toggleDark()" />
+          <el-button class="toggle" type="primary" :icon="isDark ? Moon : Sunny" circle @click="toggleDark()" />
         </template>
         </template>
       </el-popover>
       </el-popover>
     </div>
     </div>

+ 1 - 1
src/views/account/roles/Roles.vue

@@ -65,7 +65,7 @@ const getSysList = async () => {
     res.forEach((item: any) => {
     res.forEach((item: any) => {
       const { Children, T_permission } = item.Data.Menu[0]
       const { Children, T_permission } = item.Data.Menu[0]
       item.Data.Menu[0].children = Children
       item.Data.Menu[0].children = Children
-      if (['/account', 'mangage', '/salary', '/stock'].includes(T_permission)) {
+      if (['/account', 'mangage', '/salary', '/stock', '/projectMange'].includes(T_permission)) {
         item.Data.Menu[0].father = true
         item.Data.Menu[0].father = true
         menuMap.set(T_permission, { code: item.code, children: [] })
         menuMap.set(T_permission, { code: item.code, children: [] })
       }
       }

+ 32 - 186
src/views/project/MyProject.vue

@@ -1,127 +1,29 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import { GlobalStore } from '@/stores/index'
 import { GlobalStore } from '@/stores/index'
-import { ref, reactive, nextTick } from 'vue'
+import { ref, nextTick } from 'vue'
 import TableBase from '@/components/TableBase/index.vue'
 import TableBase from '@/components/TableBase/index.vue'
 import { ColumnProps } from '@/components/TableBase/interface/index'
 import { ColumnProps } from '@/components/TableBase/interface/index'
-import Drawer from '@/components/Drawer/index.vue'
-import type { FormInstance, FormRules } from 'element-plus'
-import ProjectDetail from './ProjectDetail.vue'
-import receiveUser from '@/views/storehouse/outStock/receiveUser.vue'
 import { Edit, Delete, View } from '@element-plus/icons-vue'
 import { Edit, Delete, View } from '@element-plus/icons-vue'
-import { Project_Add, Project_Edit, Project_Del, Project_Get, Project_Project_User_list } from '@/api/project/index'
+import { Project_Del, Project_Project_User_list } from '@/api/project/index'
+import ProjectForm from './ProjectForm.vue'
 
 
-const isNew = ref(true)
 const TableRef = ref()
 const TableRef = ref()
-const disabled = ref(false)
 const globalStore = GlobalStore()
 const globalStore = GlobalStore()
-const formLabelWidth = ref('120px')
-const ruleFormRef = ref<FormInstance>()
 const User_tokey = globalStore.GET_User_tokey
 const User_tokey = globalStore.GET_User_tokey
-const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
-const receiveUserDrawerRef = ref<InstanceType<typeof receiveUser> | null>(null)
-const projectDetailRef = ref<InstanceType<typeof ProjectDetail> | null>(null)
+const projctFormRef = ref<InstanceType<typeof ProjectForm> | null>(null)
 
 
 const columns: ColumnProps[] = [
 const columns: ColumnProps[] = [
-  { prop: 'Id', label: 'ID' },
+  { type: 'index', label: '序号' },
   { prop: 'T_name', label: '项目名称' },
   { prop: 'T_name', label: '项目名称' },
   { prop: 'T_user_name', label: '项目负责人' },
   { prop: 'T_user_name', label: '项目负责人' },
   { prop: 'T_set_up_date', label: '立项日期' },
   { prop: 'T_set_up_date', label: '立项日期' },
   { prop: 'T_end_date', label: '结束时间' },
   { prop: 'T_end_date', label: '结束时间' },
   { prop: 'T_planning_cycle', label: '计划完成周期(工作日)', width: 125 },
   { prop: 'T_planning_cycle', label: '计划完成周期(工作日)', width: 125 },
   { prop: 'T_Perf', label: '绩效总金额' },
   { prop: 'T_Perf', label: '绩效总金额' },
-  { prop: 'T_State', label: '状态' },
+  { prop: 'T_State', label: '状态', name: 'T_State' },
   { prop: 'operation', label: '操作', width: 200, fixed: 'right' }
   { prop: 'operation', label: '操作', width: 200, fixed: 'right' }
 ]
 ]
-const form = ref({
-  Id: '',
-  T_name: '',
-  T_description: '',
-  T_detail: '',
-  T_planning_cycle: '',
-  T_remark: '',
-  T_approver: '',
-  T_uuid: ''
-})
-const rules = reactive<FormRules>({
-  T_name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }]
-})
-
-const openProjectDrawer = (type: string, row?: any) => {
-  isNew.value = type === 'new' ? true : false
-  nextTick(async () => {
-    if (!isNew.value || type === 'view') {
-      if (type === 'view') disabled.value = true
-      form.value = { ...row }
-      form.value.T_approver = row.T_approver_name
-      form.value.T_uuid = row.T_approver
-      const res: any = await Project_Get({ T_id: row.Id })
-      if (res.Code === 200) {
-        projectDetailRef.value?.setDetailData(res.Data.T_Detail)
-      }
-    }
-  })
-  drawerRef.value?.openDrawer()
-}
-const callbackDrawer = (done: () => void) => {
-  resetForm(ruleFormRef.value)
-  projectDetailRef.value?.clearDetail()
-  isNew.value = true
-  disabled.value = false
-  done()
-}
-const resetForm = (formEl: FormInstance | undefined) => {
-  if (!formEl) return
-  formEl.resetFields()
-}
-const getProjectInfo = ({ T_uuid, T_name }: { T_uuid: string; T_name: string }) => {
-  form.value.T_approver = T_name
-  form.value.T_uuid = T_uuid
-}
-const selectApprover = () => receiveUserDrawerRef.value?.openDrawer()
-// 计算周期
-const getPlanningCycle = (info: any[]) => {
-  form.value.T_planning_cycle = info.reduce((cur, pre) => {
-    cur = cur + pre.T_planned_time
-    return cur
-  }, 0)
-}
-
-// 提交项目
-const addProject = (formEl: FormInstance | undefined) => {
-  if (!formEl) return
-  formEl.validate(async valid => {
-    if (valid) {
-      let res: any = ''
-      let detail = ''
-      projectDetailRef.value?.getDetailInfo().forEach((item: any) => {
-        detail += `${item.T_function},${item.T_planned_time},${item.T_finish}|`
-      })
-      const params = {
-        User_tokey,
-        ...form.value,
-        T_detail: detail,
-        T_approver: form.value.T_uuid
-      }
-      if (isNew.value) {
-        res = await Project_Add(params)
-      } else {
-        res = await Project_Edit({ ...params, T_id: form.value.Id })
-      }
-
-      if (res.Code === 200) {
-        ElMessage.success(`项目${isNew.value ? '添加' : '修改'}成功!`)
-        nextTick(() => {
-          isNew.value = true
-          TableRef.value?.getTableList()
-          drawerRef.value?.closeDrawer()
-          resetForm(ruleFormRef.value)
-        })
-      }
-    } else return false
-  })
-}
-// 删除
 const DeleteProject = (Id: number) => {
 const DeleteProject = (Id: number) => {
   ElMessageBox.confirm('您确定要删除项目吗?', '警告', {
   ElMessageBox.confirm('您确定要删除项目吗?', '警告', {
     confirmButtonText: '确定',
     confirmButtonText: '确定',
@@ -133,7 +35,7 @@ const DeleteProject = (Id: number) => {
       if (res.Code === 200) {
       if (res.Code === 200) {
         ElMessage.success('删除成功!')
         ElMessage.success('删除成功!')
         nextTick(() => {
         nextTick(() => {
-          TableRef.value?.getTableList()
+          onUpdateTableList
         })
         })
       }
       }
     })
     })
@@ -141,6 +43,8 @@ const DeleteProject = (Id: number) => {
       ElMessage.warning('取消成功!')
       ElMessage.warning('取消成功!')
     })
     })
 }
 }
+const onUpdateTableList = () => TableRef.value?.getTableList()
+const openProjectDrawer = (type: string, row?: any) => projctFormRef.value?.projectFromOpen(type, row)
 </script>
 </script>
 <template>
 <template>
   <div class="my-project">
   <div class="my-project">
@@ -153,89 +57,37 @@ const DeleteProject = (Id: number) => {
           >
           >
         </el-row>
         </el-row>
       </template>
       </template>
+      <template #T_State="{ row }">
+        <el-tag v-if="row.T_State === 4" effect="dark">已发绩效</el-tag>
+        <el-tag v-else-if="row.T_State === 3" type="success" effect="dark">已完成</el-tag>
+        <el-tag v-else-if="row.T_State === 2" type="warning" effect="dark">进行中</el-tag>
+        <el-tag v-else type="danger" effect="dark">待审核</el-tag>
+      </template>
       <template #right="{ row }">
       <template #right="{ row }">
         <el-button link type="success" size="small" :icon="View" @click="openProjectDrawer('view', row)"
         <el-button link type="success" size="small" :icon="View" @click="openProjectDrawer('view', row)"
           >详情</el-button
           >详情</el-button
         >
         >
-        <el-button link type="primary" size="small" :icon="Edit" @click="openProjectDrawer('edit', row)"
+        <el-button
+          link
+          type="primary"
+          size="small"
+          :icon="Edit"
+          :disabled="[3, 4].includes(row.T_State)"
+          @click="openProjectDrawer('edit', row)"
           >编辑</el-button
           >编辑</el-button
         >
         >
-        <el-button link type="danger" size="small" :icon="Delete" @click="DeleteProject(row.Id)">删除</el-button>
+        <el-button
+          link
+          type="danger"
+          size="small"
+          :icon="Delete"
+          :disabled="[3, 4].includes(row.T_State)"
+          @click="DeleteProject(row.Id)"
+          >删除</el-button
+        >
       </template>
       </template>
     </TableBase>
     </TableBase>
-    <Drawer ref="drawerRef" :handleClose="callbackDrawer" size="50%">
-      <template #header="{ params }">
-        <h4 :id="params.titleId" :class="params.titleClass">{{ isNew ? '添加' : '编辑' }} - 项目</h4>
-      </template>
-      <el-form ref="ruleFormRef" :model="form" :rules="rules">
-        <el-form-item label="项目名称:" :label-width="formLabelWidth" prop="T_name">
-          <el-input
-            v-model="form.T_name"
-            class="w-50"
-            :disabled="disabled"
-            type="text"
-            autocomplete="off"
-            placeholder="请输入项目名称"
-          />
-        </el-form-item>
-        <el-form-item label="项目简介:" :label-width="formLabelWidth" prop="T_description">
-          <el-input
-            v-model="form.T_description"
-            :disabled="disabled"
-            :autosize="{ minRows: 6, maxRows: 8 }"
-            type="textarea"
-            placeholder="请输入项目简介"
-          />
-        </el-form-item>
-        <el-form-item label="项目明细:" :label-width="formLabelWidth" prop="T_detail">
-          <ProjectDetail
-            ref="projectDetailRef"
-            @onPlanning="getPlanningCycle"
-            :disabled="disabled"
-            :isShow="true"
-          ></ProjectDetail>
-        </el-form-item>
-        <el-form-item label="计划完成周期:" :label-width="formLabelWidth" prop="T_planning_cycle">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_planning_cycle"
-              style="flex: 0 0 33.33%"
-              :disabled="disabled"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入计划完成周期"
-            />
-            <span style="margin: 0 10px">工作日</span>
-            <span style="color: #bbb display: flex;align-items: center;"
-              ><el-icon><QuestionFilled /></el-icon>备注;根据项目明细计划时间自动计算</span
-            >
-          </div>
-        </el-form-item>
-        <el-form-item label="备注:" :label-width="formLabelWidth" prop="T_remark">
-          <el-input
-            v-model="form.T_remark"
-            :disabled="disabled"
-            :autosize="{ minRows: 4, maxRows: 6 }"
-            type="textarea"
-            placeholder="请输入备注信息"
-          />
-        </el-form-item>
-        <el-form-item label="审批人:" :label-width="formLabelWidth" prop="T_approver">
-          <el-input
-            v-model="form.T_approver"
-            :disabled="disabled"
-            placeholder="请选择审批人"
-            class="w-50"
-            @focus="selectApprover"
-          />
-        </el-form-item>
-        <el-form-item :label-width="formLabelWidth" v-if="!disabled">
-          <el-button v-if="isNew" class="btn" color="#626aef" @click="addProject(ruleFormRef)">提交</el-button>
-          <el-button v-else class="btn" color="#626aef" @click="addProject(ruleFormRef)">修改</el-button>
-        </el-form-item>
-      </el-form>
-    </Drawer>
-    <receiveUser ref="receiveUserDrawerRef" @onUserInfo="getProjectInfo" title="选择审批人"></receiveUser>
+    <ProjectForm ref="projctFormRef" projectName="myProject" @onTableList="onUpdateTableList" />
   </div>
   </div>
 </template>
 </template>
 
 
@@ -255,11 +107,5 @@ const DeleteProject = (Id: number) => {
   :deep(.el-table .cell) {
   :deep(.el-table .cell) {
     white-space: normal !important;
     white-space: normal !important;
   }
   }
-  .btn {
-    padding: 0 25px;
-  }
-  .w-50 {
-    flex: 0 0 50%;
-  }
 }
 }
 </style>
 </style>

+ 14 - 225
src/views/project/Project.vue

@@ -1,16 +1,14 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import { ElMessage } from 'element-plus'
 import { ElMessage } from 'element-plus'
 import { GlobalStore } from '@/stores/index'
 import { GlobalStore } from '@/stores/index'
-import { ref, reactive, nextTick } from 'vue'
+import { ref, reactive } from 'vue'
 import { UserFilled } from '@element-plus/icons-vue'
 import { UserFilled } from '@element-plus/icons-vue'
 import TableBase from '@/components/TableBase/index.vue'
 import TableBase from '@/components/TableBase/index.vue'
-import { ColumnProps } from '@/components/TableBase/interface/index'
-import { Project_List, Project_Get, Project_Edit, Project_User_List, Project_Approval } from '@/api/project/index'
 import { Edit, View, CircleCheck } from '@element-plus/icons-vue'
 import { Edit, View, CircleCheck } from '@element-plus/icons-vue'
-import Drawer from '@/components/Drawer/index.vue'
-import ProjectDetail from './ProjectDetail.vue'
-import type { FormInstance, FormRules } from 'element-plus'
 import { useTablePublic, Project_State } from '@/hooks/useTablePublic'
 import { useTablePublic, Project_State } from '@/hooks/useTablePublic'
+import { ColumnProps } from '@/components/TableBase/interface/index'
+import { Project_List, Project_User_List, Project_Approval } from '@/api/project/index'
+import ProjectForm from './ProjectForm.vue'
 
 
 interface UserInfoIn {
 interface UserInfoIn {
   T_name: string
   T_name: string
@@ -28,22 +26,18 @@ const userInfo = ref<UserInfoIn>({
   T_dept_name: '',
   T_dept_name: '',
   T_post_name: ''
   T_post_name: ''
 })
 })
-const isNew = ref(true)
-const disabled = ref(false)
-const formLabelWidth = ref('120px')
+
 const globalStore = GlobalStore()
 const globalStore = GlobalStore()
-const User_tokey = globalStore.GET_User_tokey
-const ruleFormRef = ref<FormInstance>()
-const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
 const TableProjectRef = ref<InstanceType<typeof TableBase> | null>(null)
 const TableProjectRef = ref<InstanceType<typeof TableBase> | null>(null)
-const projectDetailRef = ref<InstanceType<typeof ProjectDetail> | null>(null)
+const projctFormRef = ref<InstanceType<typeof ProjectForm> | null>(null)
+
 const { tableRowClassName } = useTablePublic()
 const { tableRowClassName } = useTablePublic()
 const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.T_uuid, userInfo.value.T_uuid)
 const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.T_uuid, userInfo.value.T_uuid)
 
 
 const columns: ColumnProps[] = [{ prop: 'T_name', label: '姓名' }]
 const columns: ColumnProps[] = [{ prop: 'T_name', label: '姓名' }]
 const columnsProject: ColumnProps[] = [
 const columnsProject: ColumnProps[] = [
-  { prop: 'Id', label: 'ID' },
+  { type: 'index', label: '序号' },
   { prop: 'T_name', label: '项目名称' },
   { prop: 'T_name', label: '项目名称' },
   { prop: 'T_user_name', label: '项目负责人' },
   { prop: 'T_user_name', label: '项目负责人' },
   { prop: 'T_set_up_date', label: '立项日期' },
   { prop: 'T_set_up_date', label: '立项日期' },
@@ -56,41 +50,6 @@ const columnsProject: ColumnProps[] = [
 const initParam = { User_tokey: globalStore.GET_User_tokey }
 const initParam = { User_tokey: globalStore.GET_User_tokey }
 const initParamProject = reactive({ User_tokey: globalStore.GET_User_tokey, T_uuid: userInfo.value.T_uuid, page_z: 99 })
 const initParamProject = reactive({ User_tokey: globalStore.GET_User_tokey, T_uuid: userInfo.value.T_uuid, page_z: 99 })
 
 
-const form = ref({
-  Id: '',
-  T_name: '',
-  T_end_date: '',
-  T_set_up_date: '',
-  T_description: '',
-  T_detail: '',
-  T_planning_cycle: '',
-  T_reality_cycle: '',
-  T_bonus: '',
-  T_Perf: '',
-  T_remark: '',
-  T_approver: '',
-  T_advance_day: '',
-  T_uuid: ''
-})
-const rules = reactive<FormRules>({
-  T_name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }]
-})
-
-const openProjectDrawer = (type: string, row?: any) => {
-  isNew.value = type === 'view' ? true : false
-  nextTick(async () => {
-    if (type === 'view') disabled.value = true
-    form.value = { ...row }
-    form.value.T_approver = row.T_approver_name
-    form.value.T_uuid = row.T_approver
-    const res: any = await Project_Get({ T_id: row.Id })
-    if (res.Code === 200) {
-      projectDetailRef.value?.setDetailData(res.Data.T_Detail)
-    }
-  })
-  drawerRef.value?.openDrawer()
-}
-
 const getSalaryParams = (row: any) => {
 const getSalaryParams = (row: any) => {
   userInfo.value.T_uuid = ''
   userInfo.value.T_uuid = ''
   setTimeout(() => {
   setTimeout(() => {
@@ -98,55 +57,16 @@ const getSalaryParams = (row: any) => {
     initParamProject.T_uuid = userInfo.value.T_uuid
     initParamProject.T_uuid = userInfo.value.T_uuid
   }, 100)
   }, 100)
 }
 }
-
-const callbackDrawer = (done: () => void) => {
-  resetForm(ruleFormRef.value)
-  projectDetailRef.value?.clearDetail()
-  isNew.value = true
-  disabled.value = false
-  done()
-}
-
-const resetForm = (formEl: FormInstance | undefined) => {
-  if (!formEl) return
-  formEl.resetFields()
-}
-const addProject = (formEl: FormInstance | undefined) => {
-  if (!formEl) return
-  formEl.validate(async valid => {
-    if (valid) {
-      let detail = ''
-      projectDetailRef.value?.getDetailInfo().forEach((item: any) => {
-        detail += `${item.T_function},${item.T_planned_time},${item.T_finish}|`
-      })
-      const params = {
-        User_tokey,
-        ...form.value,
-        T_detail: detail,
-        T_approver: form.value.T_uuid
-      }
-
-      const res: any = await Project_Edit({ ...params, T_id: form.value.Id })
-
-      if (res.Code === 200) {
-        ElMessage.success('项目修改成功!')
-        nextTick(() => {
-          isNew.value = true
-          TableRef.value?.getTableList()
-          drawerRef.value?.closeDrawer()
-          resetForm(ruleFormRef.value)
-        })
-      }
-    } else return false
-  })
-}
 const changeState = async (id: number, row: any) => {
 const changeState = async (id: number, row: any) => {
   const res: any = await Project_Approval({ User_tokey: globalStore.GET_User_tokey, T_id: row.Id, T_State: id })
   const res: any = await Project_Approval({ User_tokey: globalStore.GET_User_tokey, T_id: row.Id, T_State: id })
   if (res.Code === 200) {
   if (res.Code === 200) {
     ElMessage.success('审核成功!')
     ElMessage.success('审核成功!')
-    TableProjectRef.value?.getTableList()
+    onUpdateTableList()
   }
   }
 }
 }
+
+const onUpdateTableList = () => TableProjectRef.value?.getTableList()
+const openProjectDrawer = (type: string, row?: any) => projctFormRef.value?.projectFromOpen(type, row)
 </script>
 </script>
 <template>
 <template>
   <div class="project">
   <div class="project">
@@ -192,7 +112,7 @@ const changeState = async (id: number, row: any) => {
           <template #T_State="{ row }">
           <template #T_State="{ row }">
             <el-dropdown trigger="click" size="small">
             <el-dropdown trigger="click" size="small">
               <el-button type="primary" size="small" :disabled="row.T_State === 4">
               <el-button type="primary" size="small" :disabled="row.T_State === 4">
-                {{ ['待审核', '进行中', '已完成', '已完成', '已发绩效'][row.T_State]
+                {{ ['待审核', '进行中', '已完成', '已发绩效'][row.T_State - 1]
                 }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
                 }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
               </el-button>
               </el-button>
               <template #dropdown>
               <template #dropdown>
@@ -219,130 +139,7 @@ const changeState = async (id: number, row: any) => {
         </TableBase>
         </TableBase>
       </div>
       </div>
     </transition>
     </transition>
-    <Drawer ref="drawerRef" :handleClose="callbackDrawer" size="50%">
-      <template #header="{ params }">
-        <h4 :id="params.titleId" :class="params.titleClass">项目 - {{ isNew ? '详情' : '编辑' }}</h4>
-      </template>
-      <el-form ref="ruleFormRef" :model="form" :rules="rules">
-        <el-form-item label="项目名称:" :label-width="formLabelWidth" prop="T_name">
-          <el-input
-            v-model="form.T_name"
-            class="w-50"
-            :disabled="disabled"
-            type="text"
-            autocomplete="off"
-            placeholder="请输入项目名称"
-          />
-        </el-form-item>
-        <el-form-item label="项目结束日期:" :label-width="formLabelWidth" prop="T_end_date">
-          <el-date-picker
-            style="flex: 0 0 50%"
-            class="my-date-picker"
-            v-model="form.T_end_date"
-            :disabled="disabled"
-            type="date"
-            placeholder="项目结束日期"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-          />
-        </el-form-item>
-        <el-form-item label="项目立项日期:" :label-width="formLabelWidth" prop="T_set_up_date">
-          <el-date-picker
-            style="flex: 0 0 50%"
-            class="my-date-picker"
-            v-model="form.T_set_up_date"
-            :disabled="disabled"
-            type="date"
-            placeholder="项目立项日期"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-          />
-        </el-form-item>
-        <el-form-item label="项目简介:" :label-width="formLabelWidth" prop="T_description">
-          <el-input
-            v-model="form.T_description"
-            :disabled="disabled"
-            :autosize="{ minRows: 6, maxRows: 8 }"
-            type="textarea"
-            placeholder="请输入项目简介"
-          />
-        </el-form-item>
-        <el-form-item label="项目明细:" :label-width="formLabelWidth" prop="T_detail">
-          <ProjectDetail ref="projectDetailRef" :disabled="disabled" :isShow="false"></ProjectDetail>
-        </el-form-item>
-        <el-form-item label="计划完成周期:" :label-width="formLabelWidth" prop="T_planning_cycle">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_planning_cycle"
-              style="flex: 0 0 33.33%"
-              :disabled="true"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入计划完成周期"
-            />
-            <span style="margin: 0 10px">工作日</span>
-            <span style="color: #bbb"
-              ><el-icon><QuestionFilled /></el-icon>备注;根据项目明细计划时间自动计算</span
-            >
-          </div>
-        </el-form-item>
-        <el-form-item label="实际完成周期:" :label-width="formLabelWidth" prop="T_reality_cycle">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_reality_cycle"
-              class="w-50"
-              :disabled="disabled"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入实际完成周期"
-            />
-            <span style="margin: 0 10px">工作日</span>
-          </div>
-        </el-form-item>
-        <el-form-item label="提前完成天数:" :label-width="formLabelWidth" prop="T_advance_day">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_advance_day"
-              class="w-50"
-              :disabled="disabled"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入提前完成天数"
-            />
-            <span style="margin: 0 10px">工作日</span>
-          </div>
-        </el-form-item>
-        <el-form-item label="奖励金额:" :label-width="formLabelWidth" prop="T_bonus">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_bonus"
-              class="w-50"
-              :disabled="disabled"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入奖励金额"
-            />
-            <span style="margin: 0 10px">元</span>
-          </div>
-        </el-form-item>
-        <el-form-item label="绩效总金额:" :label-width="formLabelWidth" prop="T_Perf">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_Perf"
-              class="w-50"
-              :disabled="disabled"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入绩效总金额"
-            />
-            <span style="margin: 0 10px">元</span>
-          </div>
-        </el-form-item>
-        <el-form-item :label-width="formLabelWidth" v-if="!disabled">
-          <el-button class="btn" color="#626aef" @click="addProject(ruleFormRef)">提交</el-button>
-        </el-form-item>
-      </el-form>
-    </Drawer>
+    <ProjectForm ref="projctFormRef" projectName="project" @onTableList="onUpdateTableList" />
   </div>
   </div>
 </template>
 </template>
 
 
@@ -365,11 +162,6 @@ const changeState = async (id: number, row: any) => {
     .box-card {
     .box-card {
       border-radius: 8px;
       border-radius: 8px;
     }
     }
-    :deep(.el-table tr) {
-      &:hover {
-        transition: all 5s ease-in-out;
-      }
-    }
     :deep(.el-table .cell) {
     :deep(.el-table .cell) {
       white-space: normal !important;
       white-space: normal !important;
     }
     }
@@ -400,8 +192,5 @@ const changeState = async (id: number, row: any) => {
     font-size: 20px;
     font-size: 20px;
     color: #707b84;
     color: #707b84;
   }
   }
-  .w-50 {
-    flex: 0 0 50%;
-  }
 }
 }
 </style>
 </style>

+ 9 - 15
src/views/project/ProjectDetail.vue

@@ -7,7 +7,7 @@ import { generateRandom } from '@/utils/common'
 
 
 const isNew = ref(true)
 const isNew = ref(true)
 const tableData = ref<any[]>([])
 const tableData = ref<any[]>([])
-const formLabelWidth = ref('120px')
+const formLabelWidth = ref('140px')
 const ruleFormRef = ref<FormInstance>()
 const ruleFormRef = ref<FormInstance>()
 const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
 const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
 
 
@@ -26,8 +26,7 @@ const form = reactive({
 })
 })
 const rules = reactive<FormRules>({
 const rules = reactive<FormRules>({
   T_function: [{ required: true, message: '请输入功能与指标', trigger: 'blur' }],
   T_function: [{ required: true, message: '请输入功能与指标', trigger: 'blur' }],
-  T_planned_time: [{ required: true, message: '请输入计划时间(工作日)', trigger: 'blur' }],
-  T_finish: [{ required: true, message: '请选择是否完成(原因)', trigger: 'blur' }]
+  T_planned_time: [{ required: true, message: '请输入计划时间(工作日)', trigger: 'blur' }]
 })
 })
 
 
 const openProductionDetailed = (type: string, row?: any) => {
 const openProductionDetailed = (type: string, row?: any) => {
@@ -88,7 +87,7 @@ defineExpose({
   setDetailData
   setDetailData
 })
 })
 
 
-const props = defineProps<{ disabled: boolean; isShow?: boolean }>()
+const props = defineProps<{ disabled: boolean; isShow?: string }>()
 const disabled = computed(() => props.disabled)
 const disabled = computed(() => props.disabled)
 const isShow = ref(props.isShow)
 const isShow = ref(props.isShow)
 </script>
 </script>
@@ -106,7 +105,7 @@ const isShow = ref(props.isShow)
     <template v-for="item in columns" :key="item.prop">
     <template v-for="item in columns" :key="item.prop">
       <el-table-column v-bind="item" v-if="item.type === 'index'"></el-table-column>
       <el-table-column v-bind="item" v-if="item.type === 'index'"></el-table-column>
       <el-table-column v-bind="item" v-if="item.fixed !== 'right' && item.type !== 'index'"> </el-table-column>
       <el-table-column v-bind="item" v-if="item.fixed !== 'right' && item.type !== 'index'"> </el-table-column>
-      <el-table-column v-bind="item" v-if="item.fixed === 'right' && isShow">
+      <el-table-column v-bind="item" v-if="item.fixed === 'right' && isShow === 'myProject'">
         <template #default="{ row }">
         <template #default="{ row }">
           <el-button size="small" :disabled="disabled" type="primary" @click="openProductionDetailed('edit', row)"
           <el-button size="small" :disabled="disabled" type="primary" @click="openProductionDetailed('edit', row)"
             >编辑</el-button
             >编辑</el-button
@@ -117,7 +116,7 @@ const isShow = ref(props.isShow)
         </template>
         </template>
       </el-table-column>
       </el-table-column>
     </template>
     </template>
-    <template #append v-if="isShow">
+    <template #append v-if="isShow === 'myProject'">
       <el-button type="primary" :disabled="disabled" @click="openProductionDetailed('new')">
       <el-button type="primary" :disabled="disabled" @click="openProductionDetailed('new')">
         <el-icon><Plus /></el-icon><span style="margin-left: 6px">添加</span>
         <el-icon><Plus /></el-icon><span style="margin-left: 6px">添加</span>
       </el-button>
       </el-button>
@@ -131,16 +130,11 @@ const isShow = ref(props.isShow)
       <el-form-item label="功能与指标:" :label-width="formLabelWidth" prop="T_function">
       <el-form-item label="功能与指标:" :label-width="formLabelWidth" prop="T_function">
         <el-input v-model="form.T_function" type="text" autocomplete="off" placeholder="请输入功能与指标" />
         <el-input v-model="form.T_function" type="text" autocomplete="off" placeholder="请输入功能与指标" />
       </el-form-item>
       </el-form-item>
-      <el-form-item
-        label="计划时间:"
-        :label-width="formLabelWidth"
-        prop="T_planned_time"
-        :rules="[{ type: 'number', message: '必须是数字' }]"
-      >
-        <el-input v-model.number="form.T_planned_time" type="text" autocomplete="off" placeholder="请输入计划时间" />
+      <el-form-item label="计划时间:" :label-width="formLabelWidth" prop="T_planned_time">
+        <el-input v-model="form.T_planned_time" type="text" autocomplete="off" placeholder="请输入计划时间" />
       </el-form-item>
       </el-form-item>
-      <el-form-item label="是否完成:" :label-width="formLabelWidth" prop="T_finish">
-        <el-input v-model="form.T_finish" type="text" autocomplete="off" placeholder="请输入完成与否" />
+      <el-form-item label="是否完成(原因):" :label-width="formLabelWidth" prop="T_finish">
+        <el-input v-model="form.T_finish" type="text" autocomplete="off" placeholder="请输入完成与否(原因)" />
       </el-form-item>
       </el-form-item>
       <el-form-item :label-width="formLabelWidth">
       <el-form-item :label-width="formLabelWidth">
         <el-button v-if="isNew" class="btn" :disabled="disabled" type="primary" @click="addProjectDetail(ruleFormRef)"
         <el-button v-if="isNew" class="btn" :disabled="disabled" type="primary" @click="addProjectDetail(ruleFormRef)"

+ 9 - 184
src/views/project/ProjectFinance.vue

@@ -1,16 +1,14 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import { ElMessage } from 'element-plus'
 import { ElMessage } from 'element-plus'
 import { GlobalStore } from '@/stores/index'
 import { GlobalStore } from '@/stores/index'
-import { ref, reactive, nextTick } from 'vue'
+import { ref, reactive } from 'vue'
 import { UserFilled } from '@element-plus/icons-vue'
 import { UserFilled } from '@element-plus/icons-vue'
 import TableBase from '@/components/TableBase/index.vue'
 import TableBase from '@/components/TableBase/index.vue'
 import { ColumnProps } from '@/components/TableBase/interface/index'
 import { ColumnProps } from '@/components/TableBase/interface/index'
-import { Project_Finance_List, Project_Get, Project_User_List, Project_Approval } from '@/api/project/index'
+import { Project_Finance_List, Project_User_List, Project_Approval } from '@/api/project/index'
 import { View, CircleCheck } from '@element-plus/icons-vue'
 import { View, CircleCheck } from '@element-plus/icons-vue'
-import Drawer from '@/components/Drawer/index.vue'
-import ProjectDetail from './ProjectDetail.vue'
-import type { FormInstance, FormRules } from 'element-plus'
 import { useTablePublic, Project_F_State } from '@/hooks/useTablePublic'
 import { useTablePublic, Project_F_State } from '@/hooks/useTablePublic'
+import ProjectForm from './ProjectForm.vue'
 
 
 interface UserInfoIn {
 interface UserInfoIn {
   T_name: string
   T_name: string
@@ -29,18 +27,15 @@ const userInfo = ref<UserInfoIn>({
   T_post_name: ''
   T_post_name: ''
 })
 })
 
 
-const formLabelWidth = ref('120px')
 const globalStore = GlobalStore()
 const globalStore = GlobalStore()
-const ruleFormRef = ref<FormInstance>()
-const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
-const projectDetailRef = ref<InstanceType<typeof ProjectDetail> | null>(null)
+const projctFormRef = ref<InstanceType<typeof ProjectForm> | null>(null)
 const { tableRowClassName } = useTablePublic()
 const { tableRowClassName } = useTablePublic()
 const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.T_uuid, userInfo.value.T_uuid)
 const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.T_uuid, userInfo.value.T_uuid)
 
 
 const columns: ColumnProps[] = [{ prop: 'T_name', label: '姓名' }]
 const columns: ColumnProps[] = [{ prop: 'T_name', label: '姓名' }]
 const columnsProject: ColumnProps[] = [
 const columnsProject: ColumnProps[] = [
-  { prop: 'Id', label: 'ID' },
+  { type: 'index', label: '序号' },
   { prop: 'T_name', label: '项目名称' },
   { prop: 'T_name', label: '项目名称' },
   { prop: 'T_user_name', label: '项目负责人' },
   { prop: 'T_user_name', label: '项目负责人' },
   { prop: 'T_set_up_date', label: '立项日期' },
   { prop: 'T_set_up_date', label: '立项日期' },
@@ -53,39 +48,7 @@ const columnsProject: ColumnProps[] = [
 const initParam = { User_tokey: globalStore.GET_User_tokey, T_Finance: 1 }
 const initParam = { User_tokey: globalStore.GET_User_tokey, T_Finance: 1 }
 const initParamProject = reactive({ User_tokey: globalStore.GET_User_tokey, T_uuid: userInfo.value.T_uuid, page_z: 99 })
 const initParamProject = reactive({ User_tokey: globalStore.GET_User_tokey, T_uuid: userInfo.value.T_uuid, page_z: 99 })
 
 
-const form = ref({
-  Id: '',
-  T_name: '',
-  T_end_date: '',
-  T_set_up_date: '',
-  T_description: '',
-  T_detail: '',
-  T_planning_cycle: '',
-  T_reality_cycle: '',
-  T_bonus: '',
-  T_Perf: '',
-  T_remark: '',
-  T_approver: '',
-  T_advance_day: '',
-  T_uuid: ''
-})
-const rules = reactive<FormRules>({
-  T_name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }]
-})
-
-const openProjectDrawer = (type: string, row?: any) => {
-  nextTick(async () => {
-    form.value = { ...row }
-    form.value.T_approver = row.T_approver_name
-    form.value.T_uuid = row.T_approver
-    const res: any = await Project_Get({ T_id: row.Id })
-    if (res.Code === 200) {
-      projectDetailRef.value?.setDetailData(res.Data.T_Detail)
-    }
-  })
-  drawerRef.value?.openDrawer()
-}
-
+const openProjectDrawer = (type: string, row?: any) => projctFormRef.value?.projectFromOpen(type, row)
 const getSalaryParams = (row: any) => {
 const getSalaryParams = (row: any) => {
   userInfo.value.T_uuid = ''
   userInfo.value.T_uuid = ''
   setTimeout(() => {
   setTimeout(() => {
@@ -93,17 +56,6 @@ const getSalaryParams = (row: any) => {
     initParamProject.T_uuid = userInfo.value.T_uuid
     initParamProject.T_uuid = userInfo.value.T_uuid
   }, 100)
   }, 100)
 }
 }
-
-const callbackDrawer = (done: () => void) => {
-  resetForm(ruleFormRef.value)
-  projectDetailRef.value?.clearDetail()
-  done()
-}
-
-const resetForm = (formEl: FormInstance | undefined) => {
-  if (!formEl) return
-  formEl.resetFields()
-}
 // 切换状态
 // 切换状态
 const changeState = async (id: number, row: any) => {
 const changeState = async (id: number, row: any) => {
   const res: any = await Project_Approval({ User_tokey: globalStore.GET_User_tokey, T_id: row.Id, T_State: id })
   const res: any = await Project_Approval({ User_tokey: globalStore.GET_User_tokey, T_id: row.Id, T_State: id })
@@ -112,6 +64,7 @@ const changeState = async (id: number, row: any) => {
     TableRef.value?.getTableList()
     TableRef.value?.getTableList()
   }
   }
 }
 }
+const onUpdateTableList = () => TableRef.value?.getTableList()
 </script>
 </script>
 <template>
 <template>
   <div class="project-finance">
   <div class="project-finance">
@@ -156,7 +109,7 @@ const changeState = async (id: number, row: any) => {
           <template #T_State="{ row }">
           <template #T_State="{ row }">
             <el-dropdown trigger="click" size="small">
             <el-dropdown trigger="click" size="small">
               <el-button type="primary" size="small" :disabled="row.T_State === 4">
               <el-button type="primary" size="small" :disabled="row.T_State === 4">
-                {{ ['待审核', '进行中', '已完成', '已完成', '已发绩效'][row.T_State]
+                {{ ['待审核', '进行中', '已完成', '已发绩效'][row.T_State - 1]
                 }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
                 }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
               </el-button>
               </el-button>
               <template #dropdown>
               <template #dropdown>
@@ -180,127 +133,7 @@ const changeState = async (id: number, row: any) => {
         </TableBase>
         </TableBase>
       </div>
       </div>
     </transition>
     </transition>
-    <Drawer ref="drawerRef" :handleClose="callbackDrawer" size="50%">
-      <template #header="{ params }">
-        <h4 :id="params.titleId" :class="params.titleClass">项目 - 详情</h4>
-      </template>
-      <el-form ref="ruleFormRef" :model="form" :rules="rules">
-        <el-form-item label="项目名称:" :label-width="formLabelWidth" prop="T_name">
-          <el-input
-            v-model="form.T_name"
-            class="w-50"
-            :disabled="true"
-            type="text"
-            autocomplete="off"
-            placeholder="请输入项目名称"
-          />
-        </el-form-item>
-        <el-form-item label="项目结束日期:" :label-width="formLabelWidth" prop="T_end_date">
-          <el-date-picker
-            style="flex: 0 0 50%"
-            class="my-date-picker"
-            v-model="form.T_end_date"
-            :disabled="true"
-            type="date"
-            placeholder="项目结束日期"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-          />
-        </el-form-item>
-        <el-form-item label="项目立项日期:" :label-width="formLabelWidth" prop="T_set_up_date">
-          <el-date-picker
-            style="flex: 0 0 50%"
-            class="my-date-picker"
-            v-model="form.T_set_up_date"
-            :disabled="true"
-            type="date"
-            placeholder="项目立项日期"
-            format="YYYY-MM-DD"
-            value-format="YYYY-MM-DD"
-          />
-        </el-form-item>
-        <el-form-item label="项目简介:" :label-width="formLabelWidth" prop="T_description">
-          <el-input
-            v-model="form.T_description"
-            :disabled="true"
-            :autosize="{ minRows: 6, maxRows: 8 }"
-            type="textarea"
-            placeholder="请输入项目简介"
-          />
-        </el-form-item>
-        <el-form-item label="项目明细:" :label-width="formLabelWidth" prop="T_detail">
-          <ProjectDetail ref="projectDetailRef" :disabled="true" :isShow="false"></ProjectDetail>
-        </el-form-item>
-        <el-form-item label="计划完成周期:" :label-width="formLabelWidth" prop="T_planning_cycle">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_planning_cycle"
-              style="flex: 0 0 33.33%"
-              :disabled="true"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入计划完成周期"
-            />
-            <span style="margin: 0 10px">工作日</span>
-            <span style="color: #bbb"
-              ><el-icon><QuestionFilled /></el-icon>备注;根据项目明细计划时间自动计算</span
-            >
-          </div>
-        </el-form-item>
-        <el-form-item label="实际完成周期:" :label-width="formLabelWidth" prop="T_reality_cycle">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_reality_cycle"
-              class="w-50"
-              :disabled="true"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入实际完成周期"
-            />
-            <span style="margin: 0 10px">工作日</span>
-          </div>
-        </el-form-item>
-        <el-form-item label="提前完成天数:" :label-width="formLabelWidth" prop="T_advance_day">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_advance_day"
-              class="w-50"
-              :disabled="true"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入提前完成天数"
-            />
-            <span style="margin: 0 10px">工作日</span>
-          </div>
-        </el-form-item>
-        <el-form-item label="奖励金额:" :label-width="formLabelWidth" prop="T_bonus">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_bonus"
-              class="w-50"
-              :disabled="true"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入奖励金额"
-            />
-            <span style="margin: 0 10px">元</span>
-          </div>
-        </el-form-item>
-        <el-form-item label="绩效总金额:" :label-width="formLabelWidth" prop="T_Perf">
-          <div style="display: flex; white-space: nowrap; flex: 1">
-            <el-input
-              v-model="form.T_Perf"
-              class="w-50"
-              :disabled="true"
-              type="text"
-              autocomplete="off"
-              placeholder="请输入绩效总金额"
-            />
-            <span style="margin: 0 10px">元</span>
-          </div>
-        </el-form-item>
-      </el-form>
-    </Drawer>
+    <ProjectForm ref="projctFormRef" projectName="projectFinance" @onTableList="onUpdateTableList" />
   </div>
   </div>
 </template>
 </template>
 
 
@@ -323,11 +156,6 @@ const changeState = async (id: number, row: any) => {
     .box-card {
     .box-card {
       border-radius: 8px;
       border-radius: 8px;
     }
     }
-    :deep(.el-table tr) {
-      &:hover {
-        transition: all 5s ease-in-out;
-      }
-    }
     :deep(.el-table .cell) {
     :deep(.el-table .cell) {
       white-space: normal !important;
       white-space: normal !important;
     }
     }
@@ -358,8 +186,5 @@ const changeState = async (id: number, row: any) => {
     font-size: 20px;
     font-size: 20px;
     color: #707b84;
     color: #707b84;
   }
   }
-  .w-50 {
-    flex: 0 0 50%;
-  }
 }
 }
 </style>
 </style>

+ 301 - 0
src/views/project/ProjectForm.vue

@@ -0,0 +1,301 @@
+<script setup lang="ts">
+import { ElMessage } from 'element-plus'
+import { ref, reactive, nextTick, computed } from 'vue'
+import { GlobalStore } from '@/stores/index'
+import ProjectDetail from './ProjectDetail.vue'
+import Drawer from '@/components/Drawer/index.vue'
+import type { FormInstance, FormRules } from 'element-plus'
+import { Project_Get, Project_Edit, Project_Add } from '@/api/project/index'
+import receiveUser from '@/views/storehouse/outStock/receiveUser.vue'
+
+const typeTip = ref('')
+const formLabelWidth = ref('120px')
+const globalStore = GlobalStore()
+const User_tokey = globalStore.GET_User_tokey
+const ruleFormRef = ref<FormInstance>()
+const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
+const projectDetailRef = ref<InstanceType<typeof ProjectDetail> | null>(null)
+const receiveUserDrawerRef = ref<InstanceType<typeof receiveUser> | null>(null)
+const form = ref({
+  Id: '',
+  T_name: '',
+  T_end_date: '',
+  T_set_up_date: '',
+  T_description: '',
+  T_detail: '',
+  T_planning_cycle: '',
+  T_reality_cycle: '',
+  T_bonus: '',
+  T_Perf: '',
+  T_remark: '',
+  T_approver: '',
+  T_advance_day: '',
+  T_uuid: ''
+})
+const rules = reactive<FormRules>({
+  T_name: [{ required: true, message: '请输入项目名称', trigger: 'blur' }]
+})
+const resetForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return
+  formEl.resetFields()
+}
+const callbackDrawer = (done: () => void) => {
+  resetForm(ruleFormRef.value)
+  projectDetailRef.value?.clearDetail()
+  done()
+}
+const addProject = (formEl: FormInstance | undefined) => {
+  if (!formEl) return
+  formEl.validate(async valid => {
+    if (valid) {
+      let res: any = ''
+      let detail = ''
+      projectDetailRef.value?.getDetailInfo().forEach((item: any) => {
+        detail += `${item.T_function},${item.T_planned_time},${item.T_finish}|`
+      })
+      const params = {
+        User_tokey,
+        ...form.value,
+        T_detail: detail,
+        T_approver: form.value.T_uuid
+      }
+      if (typeTip.value === 'new') {
+        res = await Project_Add(params)
+      } else {
+        res = await Project_Edit({ ...params, T_id: form.value.Id })
+      }
+
+      if (res.Code === 200) {
+        ElMessage.success(`项目${typeTip.value === 'new' ? '添加' : '修改'}成功!`)
+        nextTick(() => {
+          emit('onTableList')
+          drawerRef.value?.closeDrawer()
+          resetForm(ruleFormRef.value)
+        })
+      }
+    } else return false
+  })
+}
+
+const getProjectInfo = ({ T_uuid, T_name }: { T_uuid: string; T_name: string }) => {
+  form.value.T_approver = T_name
+  form.value.T_uuid = T_uuid
+}
+const selectApprover = () => receiveUserDrawerRef.value?.openDrawer()
+// 计算周期
+const getPlanningCycle = (info: any[]) => {
+  form.value.T_planning_cycle = info.reduce((cur, pre) => {
+    cur = cur + Number(pre.T_planned_time)
+    return cur
+  }, 0)
+}
+
+const projectFromOpen = (type: string, row?: any) => {
+  typeTip.value = type
+  nextTick(async () => {
+    if (typeTip.value !== 'new') {
+      form.value = { ...row }
+      form.value.T_approver = row.T_approver_name
+      form.value.T_uuid = row.T_approver
+      const res: any = await Project_Get({ T_id: row.Id })
+      if (res.Code === 200) {
+        projectDetailRef.value?.setDetailData(res.Data.T_Detail)
+      }
+    }
+  })
+  drawerRef.value?.openDrawer()
+}
+
+const props = defineProps<{ projectName: string }>()
+const projectName = ref(props.projectName)
+
+const getTitle = (type: string) => {
+  switch (type) {
+    case 'new':
+      return '新增'
+    case 'edit':
+      return '编辑'
+    default:
+      return '详情'
+  }
+}
+
+// const isDisabled = computed(() => {
+//   console.log(typeTip.value)
+//   if ((projectName !== 'myProject' && typeTip !== 'new') ||
+//             (projectName === 'myProject' && typeTip === 'view') ||
+//             projectName !== 'project') return true
+//   else return false
+// })
+
+const emit = defineEmits<{ (event: 'onTableList'): void }>()
+
+defineExpose({
+  projectFromOpen
+})
+</script>
+<template>
+  <Drawer ref="drawerRef" :handleClose="callbackDrawer" size="50%">
+    <template #header="{ params }">
+      <h4 :id="params.titleId" :class="params.titleClass">项目 - {{ getTitle(typeTip) }}</h4>
+    </template>
+    <el-form ref="ruleFormRef" :model="form" :rules="rules">
+      <el-form-item label="项目名称:" :label-width="formLabelWidth" prop="T_name">
+        <el-input
+          v-model="form.T_name"
+          class="w-50"
+          :disabled="!(projectName === 'myProject' && (typeTip === 'new' || typeTip === 'edit'))"
+          type="text"
+          autocomplete="off"
+          placeholder="请输入项目名称"
+        />
+      </el-form-item>
+      <el-form-item label="项目结束日期:" :label-width="formLabelWidth" prop="T_end_date">
+        <el-date-picker
+          style="flex: 0 0 50%"
+          class="my-date-picker"
+          v-model="form.T_end_date"
+          :disabled="!(projectName === 'project' && typeTip === 'edit')"
+          type="date"
+          placeholder="项目结束日期"
+          format="YYYY-MM-DD"
+          value-format="YYYY-MM-DD"
+        />
+      </el-form-item>
+      <el-form-item label="项目立项日期:" :label-width="formLabelWidth" prop="T_set_up_date">
+        <el-date-picker
+          style="flex: 0 0 50%"
+          class="my-date-picker"
+          v-model="form.T_set_up_date"
+          :disabled="!(projectName === 'project' && typeTip === 'edit')"
+          type="date"
+          placeholder="项目立项日期"
+          format="YYYY-MM-DD"
+          value-format="YYYY-MM-DD"
+        />
+      </el-form-item>
+      <el-form-item label="项目简介:" :label-width="formLabelWidth" prop="T_description">
+        <el-input
+          v-model="form.T_description"
+          :disabled="!(projectName === 'myProject' && (typeTip === 'new' || typeTip === 'edit'))"
+          :autosize="{ minRows: 6, maxRows: 8 }"
+          type="textarea"
+          placeholder="请输入项目简介"
+        />
+      </el-form-item>
+      <el-form-item label="项目明细:" :label-width="formLabelWidth" prop="T_detail">
+        <ProjectDetail
+          ref="projectDetailRef"
+          :disabled="!(projectName === 'myProject' && (typeTip === 'new' || typeTip === 'edit'))"
+          :isShow="projectName"
+          @onPlanning="getPlanningCycle"
+        ></ProjectDetail>
+      </el-form-item>
+      <el-form-item label="计划完成周期:" :label-width="formLabelWidth" prop="T_planning_cycle">
+        <div style="display: flex; white-space: nowrap; flex: 1">
+          <el-input
+            v-model="form.T_planning_cycle"
+            style="flex: 0 0 33.33%"
+            :disabled="true"
+            type="text"
+            autocomplete="off"
+            placeholder="请输入计划完成周期"
+          />
+          <span style="margin: 0 10px">工作日</span>
+          <span style="color: #bbb"
+            ><el-icon><QuestionFilled /></el-icon>根据项目明细计划时间自动计算</span
+          >
+        </div>
+      </el-form-item>
+      <!-- my project -->
+      <el-form-item :label-width="formLabelWidth" prop="T_remark">
+        <el-input
+          v-model="form.T_remark"
+          :disabled="!(projectName === 'myProject' && (typeTip === 'new' || typeTip === 'edit'))"
+          :autosize="{ minRows: 4, maxRows: 6 }"
+          type="textarea"
+          placeholder="请输入备注信息"
+        />
+      </el-form-item>
+      <el-form-item v-if="projectName === 'myProject'" label="审批人:" :label-width="formLabelWidth" prop="T_approver">
+        <el-input
+          v-model="form.T_approver"
+          :disabled="typeTip === 'view'"
+          placeholder="请选择审批人"
+          class="w-50"
+          @focus="selectApprover"
+        />
+      </el-form-item>
+      <!-- my project -->
+      <el-form-item label="实际完成周期:" :label-width="formLabelWidth" prop="T_reality_cycle">
+        <div style="display: flex; white-space: nowrap; flex: 1">
+          <el-input
+            v-model="form.T_reality_cycle"
+            class="w-50"
+            :disabled="!(projectName === 'project' && typeTip === 'edit')"
+            type="text"
+            autocomplete="off"
+            placeholder="请输入实际完成周期"
+          />
+          <span style="margin: 0 10px">工作日</span>
+        </div>
+      </el-form-item>
+      <el-form-item label="提前完成天数:" :label-width="formLabelWidth" prop="T_advance_day">
+        <div style="display: flex; white-space: nowrap; flex: 1">
+          <el-input
+            v-model="form.T_advance_day"
+            class="w-50"
+            :disabled="!(projectName === 'project' && typeTip === 'edit')"
+            type="text"
+            autocomplete="off"
+            placeholder="请输入提前完成天数"
+          />
+          <span style="margin: 0 10px">工作日</span>
+        </div>
+      </el-form-item>
+      <el-form-item label="奖励金额:" :label-width="formLabelWidth" prop="T_bonus">
+        <div style="display: flex; white-space: nowrap; flex: 1">
+          <el-input
+            v-model="form.T_bonus"
+            class="w-50"
+            :disabled="!(projectName === 'project' && typeTip === 'edit')"
+            type="text"
+            autocomplete="off"
+            placeholder="请输入奖励金额"
+          />
+          <span style="margin: 0 10px">元</span>
+        </div>
+      </el-form-item>
+      <el-form-item label="绩效总金额:" :label-width="formLabelWidth" prop="T_Perf">
+        <div style="display: flex; white-space: nowrap; flex: 1">
+          <el-input
+            v-model="form.T_Perf"
+            class="w-50"
+            :disabled="!(projectName === 'project' && typeTip === 'edit')"
+            type="text"
+            autocomplete="off"
+            placeholder="请输入绩效总金额"
+          />
+          <span style="margin: 0 10px">元</span>
+        </div>
+      </el-form-item>
+      <el-form-item :label-width="formLabelWidth" v-if="projectName === 'project' || projectName === 'myProject'">
+        <el-button v-if="typeTip === 'new'" class="btn" color="#626aef" @click="addProject(ruleFormRef)"
+          >提交</el-button
+        >
+        <el-button v-if="typeTip === 'edit'" class="btn" color="#626aef" @click="addProject(ruleFormRef)"
+          >修改</el-button
+        >
+      </el-form-item>
+    </el-form>
+    <receiveUser ref="receiveUserDrawerRef" @onUserInfo="getProjectInfo" title="选择审批人"></receiveUser>
+  </Drawer>
+</template>
+<style scoped lang="scss">
+.btn {
+  padding: 0 25px;
+}
+.w-50 {
+  flex: 0 0 50%;
+}
+</style>

+ 25 - 16
src/views/storehouse/InventoryStatistics.vue

@@ -22,6 +22,7 @@ const userInfo = ref({
   Id: '',
   Id: '',
   T_name: ''
   T_name: ''
 })
 })
+const loading = ref(false)
 const globalStore = GlobalStore()
 const globalStore = GlobalStore()
 const DrawerRef = ref<InstanceType<typeof Drawer> | null>(null)
 const DrawerRef = ref<InstanceType<typeof Drawer> | null>(null)
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
@@ -29,7 +30,6 @@ const TableDetailRef = ref<InstanceType<typeof TableBase> | null>(null)
 const { tableRowClassName } = useTablePublic()
 const { tableRowClassName } = useTablePublic()
 const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.Id, userInfo.value.Id)
 const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.Id, userInfo.value.Id)
 
 
-let timeout: NodeJS.Timeout
 const initParam = reactive({
 const initParam = reactive({
   User_tokey: globalStore.GET_User_tokey,
   User_tokey: globalStore.GET_User_tokey,
   T_depot_id: '',
   T_depot_id: '',
@@ -103,7 +103,7 @@ const confirmExpor = async (project_id?: string) => {
     window.open(res.Data)
     window.open(res.Data)
   }
   }
 }
 }
-
+const NameOptions = ref<any[]>([])
 const classOptions = ref<any[]>([])
 const classOptions = ref<any[]>([])
 const modelOptions = ref<any[]>([])
 const modelOptions = ref<any[]>([])
 // 获取产品分类
 // 获取产品分类
@@ -128,16 +128,16 @@ const getNameAsync = async (str: string): Promise<any> => {
 /**
 /**
  * 模糊搜索名称
  * 模糊搜索名称
  * @param queryString 输入框的输入字符
  * @param queryString 输入框的输入字符
- * @param cb 异步搜索后的回调
  */
  */
-const querySearchAsync = async (queryString: string, cb: (arg: any) => void) => {
-  clearTimeout(timeout)
-  globalStore.SET_isloading(true)
-  timeout = setTimeout(async () => {
+const querySearchAsync = async (queryString: string) => {
+  if (queryString) {
+    loading.value = true
+    globalStore.SET_isloading(true)
     const results = await getNameAsync(queryString)
     const results = await getNameAsync(queryString)
-    cb(results)
+    NameOptions.value = results
     globalStore.SET_isloading(false)
     globalStore.SET_isloading(false)
-  }, 2000)
+    loading.value = false
+  }
 }
 }
 /**
 /**
  * 异步获取产品型号
  * 异步获取产品型号
@@ -233,16 +233,25 @@ const getSalaryParams = (row: any) => {
                   ></el-col>
                   ></el-col>
                   <el-col :span="12"
                   <el-col :span="12"
                     ><el-form-item label="产品名称">
                     ><el-form-item label="产品名称">
-                      <el-autocomplete
-                        class="w-50"
+                      <el-select
                         v-model="initParam.T_product_name"
                         v-model="initParam.T_product_name"
+                        filterable
                         clearable
                         clearable
-                        :fetch-suggestions="querySearchAsync"
+                        remote
+                        reserve-keyword
                         placeholder="按产品名称搜索"
                         placeholder="按产品名称搜索"
-                        :debounce="2000"
-                        :trigger-on-focus="false"
-                        @select="handleSelect"
-                      /> </el-form-item
+                        remote-show-suffix
+                        :remote-method="querySearchAsync"
+                        :loading="loading"
+                        @change="handleSelect"
+                      >
+                        <el-option
+                          v-for="item in NameOptions"
+                          :key="item.value"
+                          :label="item.value"
+                          :value="item.value"
+                        />
+                      </el-select> </el-form-item
                   ></el-col>
                   ></el-col>
                 </el-row>
                 </el-row>
                 <el-row class="search-bottom">
                 <el-row class="search-bottom">

+ 1 - 4
src/views/storehouse/outStock/OutStock.vue

@@ -46,9 +46,7 @@ const form = reactive({
 const rules = reactive<FormRules>({
 const rules = reactive<FormRules>({
   T_delivery_type: [{ required: true, message: '请选择送货方式', trigger: 'blur' }],
   T_delivery_type: [{ required: true, message: '请选择送货方式', trigger: 'blur' }],
   T_signer_unit: [{ required: true, message: '请输入签收单位', trigger: 'blur' }],
   T_signer_unit: [{ required: true, message: '请输入签收单位', trigger: 'blur' }],
-  T_signer: [{ required: true, message: '请输入签收人', trigger: 'blur' }],
-  T_signer_phone: [{ required: true, validator: validate_T_phone, trigger: 'blur' }],
-  T_signer_date: [{ required: true, message: '请选择签收日期', trigger: 'blur' }]
+  T_signer_phone: [{ validator: validate_T_phone, trigger: 'blur' }]
 })
 })
 
 
 /**
 /**
@@ -91,7 +89,6 @@ const addOutStock = (formEl: FormInstance | undefined) => {
         ElMessage.success('发货成功!')
         ElMessage.success('发货成功!')
         nextTick(() => {
         nextTick(() => {
           closeDrawer()
           closeDrawer()
-          // TableRef.value?.searchTable()
         })
         })
       }
       }
     }
     }

+ 7 - 3
src/views/storehouse/outStock/SaleOutStock.vue

@@ -75,7 +75,7 @@ const rules = reactive<FormRules>({
 const countBlurHandle = () => {
 const countBlurHandle = () => {
   form.value.T_product = tableData.value.map(item => {
   form.value.T_product = tableData.value.map(item => {
     if (!item.count && item.T_product_relation_sn !== 1) return undefined
     if (!item.count && item.T_product_relation_sn !== 1) return undefined
-    if (item.count > item.T_stock_total) return undefined
+    if (item.count > item.T_stock_total && item.count > item.T_product_total) return undefined
     return `${item.T_product_id},${item.count}|`
     return `${item.T_product_id},${item.count}|`
   })
   })
 }
 }
@@ -108,10 +108,14 @@ const getDeviceSnToProduct = () => {
  */
  */
 const determineSNorCount = (DeviceSnData: any) => {
 const determineSNorCount = (DeviceSnData: any) => {
   for (const item of tableData.value) {
   for (const item of tableData.value) {
-    if ((!item.count && item.T_product_relation_sn !== 1) || item.count > item.T_stock_total) return 'count'
+    if (
+      (!item.count && item.T_product_relation_sn !== 1) ||
+      (item.count > item.T_stock_total && item.count > item.T_product_total)
+    )
+      return 'count'
     if (
     if (
       (item.T_product_relation_sn === 1 && !DeviceSnData.get(item.Id) && !DeviceSnData.size) ||
       (item.T_product_relation_sn === 1 && !DeviceSnData.get(item.Id) && !DeviceSnData.size) ||
-      item.count > item.T_stock_total
+      (item.count > item.T_stock_total && item.count > item.T_product_total)
     )
     )
       return 'sn'
       return 'sn'
   }
   }