Browse Source

240726报告生成错误sn回显生成报告错误

YangJian0701 8 months ago
parent
commit
31bbaaff83

+ 1 - 0
.env.development

@@ -10,3 +10,4 @@ NODE_ENV = 'development'
 VITE_APP_TITLE = 'ERP宝智达'
 VITE_APP_BASE_API = '/api'
 VITE_SERVE = 'https://erptest.baozhida.cn'
+VITE_BZD_ERPOSS_APP_API = 'https://erposs.baozhida.cn'

BIN
ERP.rar


+ 1 - 0
components.d.ts

@@ -14,6 +14,7 @@ declare module '@vue/runtime-core' {
     Drawer: typeof import('./src/components/Drawer/index.vue')['default']
     EchartBar: typeof import('./src/components/echart/echart-bar.vue')['default']
     EchartLine: typeof import('./src/components/echart/echart-line.vue')['default']
+    ElAlert: typeof import('element-plus/es')['ElAlert']
     ElAside: typeof import('element-plus/es')['ElAside']
     ElAvatar: typeof import('element-plus/es')['ElAvatar']
     ElBadge: typeof import('element-plus/es')['ElBadge']

+ 60 - 0
src/api/contractReview/index.ts

@@ -0,0 +1,60 @@
+import $http from '../index'
+
+/**
+ * 
+ * @param params 服务类型
+ * @returns 
+ */
+export const ServiceType_List_Post = (params: any) => $http.post('/storage/ServiceType/List', params)
+export const ServiceType_Add_Post = (params: any) => $http.post('/storage/ServiceType/Add', params)
+export const ServiceType_Edit_Post = (params: any) => $http.post('/storage/ServiceType/Edit', params)
+export const ServiceType_Del_Post = (params: any) => $http.post('/storage/ServiceType/Del', params)
+
+/**
+ * 
+ * @param params 服务内容
+ * @returns 
+ */
+export const ServiceItem_List_Post = (params: any) => $http.post('/storage//ServiceItem/List', params)
+export const ServiceItem_Add_Post = (params: any) => $http.post('/storage/ServiceItem/Add', params)
+export const ServiceItem_Edit_Post = (params: any) => $http.post('/storage/ServiceItem/Edit', params)
+export const ServiceItem_Del_Post = (params: any) => $http.post('/storage/ServiceItem/Del', params)
+
+
+/**
+ * 
+ * @param params 合同评审
+ * @returns 
+ */
+export const ContractReview_List_Post = (params: any) => $http.post('/storage//ContractReview/List', params)
+export const ContractReview_Edit_Post = (params: any) => $http.post('/storage//ContractReview/Edit', params)
+export const ContractReview_Add_Post = (params: any) => $http.post('/storage//ContractReview/Add', params)
+export const ContractReview_Del_Post = (params: any) => $http.post('/storage//ContractReview/Del', params)
+export const ContractReview_Submit_Post = (params: any) => $http.post('/storage//ContractReview/Submit_Audit', params)
+
+
+
+
+/**
+ * 合同评审(财务)
+ * @param params 
+ * @returns 
+ */
+export const Review_Finance_List_Post = (params: any) => $http.post('/storage//ContractReview/Finance_List', params)
+export const Review_Submit_User_Post = (params: any) => $http.post('/storage//ContractReview/Submit_User_List', params)
+export const Review_Excel_Post = (params: any) => $http.post('/storage//ContractReview/Stock_Detail_Excel', params)
+
+export const Review_Finance_Audit = (params: any) => $http.post('/storage//ContractReview/Finance_Audit', params)//财务审核
+export const Review_Manager_Audit = (params: any) => $http.post('/storage//ContractReview/Manager_Audit', params)//总经理审核
+
+
+
+
+/**
+ * 
+ * @param params 合同评审(总经理)
+ * @returns 
+ */
+export const ContractReview_Manager_List_Post = (params: any) => $http.post('/storage//ContractReview/Manager_List', params)
+export const ContractReview_Manager_sub_List_Post = (params: any) => $http.post('/storage//ContractReview/Submit_User_List', params)
+

+ 5 - 3
src/api/index.ts

@@ -12,9 +12,9 @@ type LoadingType = {
 let loadingInstance: LoadingType = {}
 const config = {
   // 默认地址请求地址,可在 .env.*** 文件中修改
-  // baseURL: process.env.NODE_ENV ?(import.meta.env.VITE_BZD_ERP_APP_API as string) : '' ,
+//   baseURL: process.env.NODE_ENV ?(import.meta.env.VITE_BZD_ERP_APP_API as string) : '' ,
   // baseURL:'https://erptest.baozhida.cn/api',//测试
-
+    
   baseURL:import.meta.env.VITE_SERVE + import.meta.env.VITE_APP_BASE_API,
 
 
@@ -61,7 +61,9 @@ class RequestHttp {
           }
         }
         // config.data = Qs(config.data)
-        mapList.includes(config.url as string)?config.headers['Content-Type'] = ContentType.JSON:config.headers['Content-Type'] = ContentType.URLENCODED
+        mapList.includes(config.url as string)?
+        config.headers['Content-Type'] = ContentType.JSON:
+        config.headers['Content-Type'] = ContentType.URLENCODED
         return config
       },
       (err: any) => err

+ 1 - 1
src/api/storehouse/index.ts

@@ -126,7 +126,7 @@ export const Storehouse_StockOut_Add = (params: any) => $http.post('/storage/Sto
 // 详情
 export const Storehouse_StockOut_Get = (params: any) => $http.post('/storage/StockOut/Get', params)
 // 修改发货订单
-export const Storehouse_StockOut_Edit = (params: any) => $http.post('/storage/StockOut/Edit', params)
+export const Storehouse_StockOut_Edit = (params: any) => $http.post('/storage/StockOut/Edit_Delivery', params)
 
 /**
  * 库存统计

+ 1 - 0
src/components/Drawer/index.vue

@@ -33,6 +33,7 @@ defineExpose({ closeDrawer, openDrawer })
       :before-close="handleClose"
       :direction="direction"
       :size="size"
+      :destroy-on-close="true"
     >
       <template #header="{ close, titleId, titleClass }">
         <div class="header">

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

@@ -76,7 +76,7 @@ const onSuccess = (response: any, uploadFile: UploadFile, uploadFiles: UploadFil
   }
   ElMessage.success(props.successText)
   loadingInstance.close()
-  console.log('onSuccess')
+  console.log('上传成功onSuccess',response,uploadFile,uploadFiles)
 }
 // 图片上传失败
 const onError = () => {

+ 1 - 1
src/hooks/useTablePublic.ts

@@ -24,7 +24,7 @@ export interface OvertimeUserInfoIn {
   T_text: string
   Id: string
   T_duration: string
-  T_prove_img: string
+  T_prove_img: any
 }
 
 export interface ContractFormType {

+ 2 - 1
src/views/Login.vue

@@ -29,10 +29,11 @@ const validatePass = (rule: any, value: any, callback: any) => {
 const rules = reactive<FormRules>({
   username: [{ required: true, message: '请输入用户账号', trigger: 'blur' }],
   password: [{ required: true, validator: validatePass, trigger: 'blur' }]
-})
+}) 
 
 const submitForm = (formEl: FormInstance | undefined) => {
   if (!formEl) return
+  console.log('验证')
   formEl.validate(async valid => {
     if (valid) {
       try {

+ 25 - 60
src/views/account/roles/Roles.vue

@@ -58,7 +58,8 @@ const menuDir:any = reactive({
   activeName:null,//选中的tabs
   MenuData:[],//tabs导航栏
   tabsMenu:[],//tab展开导航
-  defaultKeys:[]//默认选中
+  defaultKeys:[],//默认选中
+  selectData:[]//勾选项
 })
 const getSysList = async () => {
   const { Data } = await User_Sys_List({ User_tokey })
@@ -66,7 +67,7 @@ const getSysList = async () => {
   menuDir.MenuData = Data
   menuDir.activeName = menuDir.MenuData[0].T_sys
   const {Data:resIt} = await getMenuList(menuDir.activeName)
-  menuDir.tabsMenu = resIt.Menu[0].Children
+  menuDir.tabsMenu = resIt.Menu
   menuDir.defaultKeys = resIt.Menu_checked?resIt.Menu_checked:[]
 }
 //点击切换tabs调用导航
@@ -74,8 +75,9 @@ const handleClick = async(tab: TabsPaneContext, event: Event) => {
   menuDir.defaultKeys = []
   menuDir.activeName = tab.props.name
   const {Data:resIt} = await getMenuList(menuDir.activeName)
-  menuDir.tabsMenu = resIt.Menu[0].Children
+  menuDir.tabsMenu = resIt.Menu
   menuDir.defaultKeys = resIt.Menu_checked?resIt.Menu_checked:[]
+
 }
 
 //调用当前权限的子选项
@@ -220,7 +222,8 @@ const getMontageRole = (children: any[]) => {
  * 提交
  */
 const submit = async (data: any) => {
-  let T_menu = getMontageRole(menuDir.defaultKeys)
+  let T_menu = getMontageRole([...menuDir.defaultKeys])
+  console.log('提交',menuDir.defaultKeys,T_menu)
   const params = {
     User_tokey,
     T_id: currentVal.T_id,
@@ -260,60 +263,23 @@ const getFatherData = (T_permission: string) => {
   return fatherData
 }
 
+const extractIds = (obj:any)=>{
+    let ids = [obj.Id]; // 初始化数组,包含当前对象的Id  
+    // 检查Children是否存在且为数组  
+    if (Array.isArray(obj.Children)) {  
+        // 遍历Children数组  
+        obj.Children.forEach((child:any) => {  
+            // 递归调用extractIds,并将返回的ids数组与当前ids数组合并  
+            ids = ids.concat(extractIds(child));  
+        });  
+    }  
 
-const checkChange = (data: any, check: boolean) => {
-  // console.log('选中',menuDir.defaultKeys,data,check)
-  if(check){//当前选中操作
-    const j = menuDir.defaultKeys.includes(data.Id)
-    if(!j)menuDir.defaultKeys.push(data.Id)//不在加入
-  }else{//当前取消操作
-    menuDir.defaultKeys.map((item: any, index: any) => {
-        if (item == data.Id) menuDir.defaultKeys.splice(index, 1)
-    })
-  }
-  return
-  // let fatherData = getFatherData(data.T_permission)
-  // if (fatherData) {
-  //   fatherDataCopy = fatherData
-  // }
-  // if (check && fatherDataCopy) {
-  //   const { children } = fatherDataCopy
-  //   if (!data.Children) {
-  //     const index = children.findIndex((child: any) => data.T_permission === child.T_permission)
-  //     if (index === -1) children.push({ ...data })
-  //   } else {
-  //   }
-  // }
-
-  // if (!check && fatherDataCopy) {
-  //   let { children } = fatherDataCopy
-  //   if (['/base', '/property', '/inventory', '/salesManage'].includes(data.T_permission)) {
-  //     fatherData = menuMap.get('/stock')
-  //     if (data.T_permission === '/base') {
-  //       children = children.filter((item: any) => {
-  //         return !['/list', '/classify', '/productionList', '/base'].includes(item.T_permission)
-  //       })
-  //     } else if (data.T_permission === '/property') {
-  //       children = children.filter((item: any) => {
-  //         return !['/ioTNetworkCard', '/property'].includes(item.T_permission)
-  //       })
-  //     } else if (data.T_permission === '/inventory') {
-  //       children = children.filter((item: any) => {
-  //         return !['/device', '/inStorage', '/outStock', '/inventoryStatistics', '/inventory'].includes(
-  //           item.T_permission
-  //         )
-  //       })
-  //     } else {
-  //       children = children.filter((item: any) => {
-  //         return !['/contract', '/contractSale', '/salesManage'].includes(item.T_permission)
-  //       })
-  //     }
-  //     fatherData.children = children
-  //     return
-  //   }
-  //   const index = children.findIndex((child: any) => data.T_permission === child.T_permission)
-  //   if (index === -1) children.splice(index, 1)
-  // }
+    return ids; 
+}
+
+
+const checkChange = (data: any, check:any) => {
+    menuDir.defaultKeys = check!.checkedKeys
 }
 
 /**
@@ -358,14 +324,13 @@ const dialogCloseCallback = () => {
       <el-tabs v-model="menuDir.activeName" class="demo-tabs" tabPosition="left" @tab-click="handleClick">
         <el-tab-pane :label="item.T_name" :name="item.T_sys" v-for="item,index in menuDir.MenuData" :key="index">
           <el-tree
+            :data="menuDir.tabsMenu"
             :props="{ label: 'T_name', children: 'Children' }"
             node-key="Id"
-            accordion
             :default-expanded-keys="menuDir.defaultKeys"
             :default-checked-keys="menuDir.defaultKeys"
-            :data="menuDir.tabsMenu"
             show-checkbox
-            @check-change="checkChange"
+            @check="checkChange"
           />
         </el-tab-pane>
       </el-tabs>

+ 169 - 0
src/views/contractReview/contractReviewFinance.vue

@@ -0,0 +1,169 @@
+<template>
+    <div class="">
+        <TableBase ref="TableRef" border :columns="columns" :requestApi="Review_Finance_List_Post" :initParam="data.initParam">
+            <template #table-header>
+                <div style="display: flex;justify-content: space-between;flex: 1;flex-wrap: wrap;">
+                    <el-form :inline="true" :model="data.initParam" class="demo-form-inline">
+                        <el-form-item label="项目名称">
+                            <el-input v-model="data.initParam.T_name" placeholder="搜索项目名称" />
+                        </el-form-item>
+                        <el-form-item label="状态">
+                            <el-select v-model="data.initParam.T_audit" style="width: 160px;" laceholder="请选择状态">
+                                <el-option v-for="item in optionReviewFinance" :key="item.value" :label="item.name" :value="item.value" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="项目负责人">
+                            <el-select v-model="data.initParam.T_submit" style="width: 160px;" placeholder="请选择项目负责人">
+                                <el-option v-for="item in data.optionSubmit" :key="item.T_submit" :label="item.T_name" :value="item.T_submit" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item>
+                            <el-button type="primary" @click="onclicksearch">查询</el-button>
+                        </el-form-item>
+                    </el-form>
+                    <el-button type="primary" icon="Download" @click="onclickExcel">导出</el-button>
+                </div> 
+            </template>
+            <template #T_audit="{ row }">
+                <el-tag :type="
+                    [1,2].includes(row.T_audit)?'warning':
+                    [3,5].includes(row.T_audit)?'primary':
+                     [4,6].includes(row.T_audit)?'danger':''">
+                    {{ 
+                        row.T_audit=='1'?'待提交审核':
+                        row.T_audit=='2'?'待审核':
+                        row.T_audit=='3'?'财务通过':
+                        row.T_audit=='4'?'财务驳回':
+                        row.T_audit=='5'?'总经理通过':
+                        row.T_audit=='6'?'总经理驳回':''
+                    }}
+                </el-tag>
+            </template>
+            <template #T_have_brokerage_fee="{ row }">
+                <el-tag :type="row.T_have_brokerage_fee?'primary':'success'">
+                    {{ row.T_have_brokerage_fee?'是':'否' }}
+                </el-tag>
+            </template>
+            <template #right="{ row }">
+                <el-button link type="primary" size="small" :icon="View" @click="openDrawer('详情', row)">详情</el-button>
+                <el-button link type="primary" size="small" :disabled="[2].includes(row.T_audit)?false:true" 
+                icon="Check" @click="openDrawer('审核', row)" >审核</el-button>
+                <el-button link type="danger" size="small" :icon="Delete" @click="openDelect(row)">删除</el-button>
+            </template>
+        </TableBase>
+        <particulars ref="btnRef" :fromData="data.fromData" :audit="<any>[3,4]" types="Finance" @successFun="successFun"></particulars>
+    </div>
+</template>
+
+<script setup lang='ts'>
+import { ref, reactive,onMounted } from 'vue';
+import { View,Delete} from '@element-plus/icons-vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { GlobalStore } from '@/stores/index'
+import particulars from './modules/particulars.vue'
+import { optionReviewFinance } from './modules/optionsData'
+
+import { 
+    Review_Submit_User_Post,//项目负责人
+    Review_Finance_List_Post,//财务列表
+    Review_Excel_Post,//导出
+    ContractReview_Del_Post,//删除
+    ContractReview_Submit_Post} from '@/api/contractReview/index'
+
+import TableBase from '@/components/TableBase/index.vue'
+
+const globalStore = GlobalStore()
+const TableRef = ref()
+const btnRef = ref()
+
+const successFun = async (data:any)=>{
+    TableRef.value?.getTableList()
+}
+
+const data = reactive({
+    initParam :{
+        // User_tokey: globalStore.GET_User_tokey,
+        T_name: '',
+        T_submit: '',
+        T_audit: '',
+    },
+    fromData:{},
+    optionSubmit:<any>[]
+})
+// 搜索以及参数
+const columns = [
+    { type: 'index', label: '序号', width: 80, align: 'center ' },
+    { prop: 'T_audit', label: '状态', name: 'T_audit'},
+    { prop: 'T_name', label: '项目名称' },
+    { prop: 'T_address', label: '项目地址' },
+    { prop: 'T_submit_name', label: '项目负责人' },
+    { prop: 'T_predict_sign_time', label: '预计签约时间' },
+    { prop: 'T_money', label: '总金额' },
+    { prop: 'T_have_brokerage_fee', label: '是否有居间费', name: 'T_have_brokerage_fee' },
+    { prop: 'T_brokerage_fee_money', label: '居间费金额' },
+    { prop: 'operation', label: '操作', fixed: 'right',width:'300px' }
+]
+
+const onclicksearch = (row: any) => {
+    TableRef.value?.getTableList()
+}
+
+/**
+ * Excel
+ */
+const onclickExcel = async ()=>{
+    const result:any = await Review_Excel_Post(data.initParam)
+    if (result.Code === 200) {
+        window.open(result.Data)
+  }
+    console.log('导出',result)
+}
+
+/**
+ * 编辑
+ * @param tit 
+ * @param row 
+ */
+ const openDrawer = (tit:string,row: any) => {
+    btnRef.value.outerVisible = true
+    btnRef.value.data.drawerTiti = tit
+    data.fromData = row
+}
+/**
+ * 项目负责人
+ * @param row 
+ */
+const SubmituserApi = async() => {
+    const result:any = await Review_Submit_User_Post({T_type:'Finance'})
+    if(result.Code==200){
+        console.log('项目负责人',result)
+        let obj = { T_name: "全部", T_submit:""}
+        let arr = result.Data.Data || []
+        data.optionSubmit = [obj,...arr]
+    }
+}
+/**
+ * 删除
+ * @param row 
+ */
+ const openDelect = (row: any) => {
+    ElMessageBox.confirm('删除操作,是否执行操作?','删除',{
+        confirmButtonText: '立即删除',
+        cancelButtonText: '取消',
+        type: 'warning',
+        center: true,
+    }).then(async() => {
+        const result:any = await ContractReview_Del_Post({T_id:row.Id})
+        if(result.Code==200){
+            ElMessage.success('删除成功')
+            TableRef.value?.getTableList()
+        }
+    }).catch(() => {})
+}
+onMounted(()=>{
+    SubmituserApi()
+})
+</script>
+<style lang="scss">
+/* @import url(); 引入css类 */
+</style>

+ 147 - 0
src/views/contractReview/contractReviewList.vue

@@ -0,0 +1,147 @@
+<template>
+    <div class="">
+        <TableBase ref="TableRef" border :columns="columns" :requestApi="ContractReview_List_Post" :initParam="data.initParam">
+            <template #table-header>
+                <div style="display: flex;justify-content: space-between;flex-wrap: wrap;flex: 1;">
+                    <el-form :inline="true" :model="data.initParam" class="demo-form-inline">
+                        <el-form-item label="项目名称">
+                            <el-input v-model="data.initParam.T_name" placeholder="搜索项目名称" />
+                        </el-form-item>
+                        <el-form-item label="状态">
+                            <el-select v-model="data.initParam.T_audit" placeholder="请选择状态">
+                                <el-option v-for="item in optionReviewList" :key="item.value" :label="item.name" :value="item.value" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item>
+                            <el-button type="primary" @click="onclicksearch">查询</el-button>
+                        </el-form-item>
+                    </el-form>
+                    <contractReviewListAdd ref="btnRef" :fromData="data.fromData" @successFun="successFun"></contractReviewListAdd>
+                </div> 
+            </template>
+            <template #T_audit="{ row }">
+                <el-tag :type="
+                    [1,2].includes(row.T_audit)?'warning':
+                    [3,5].includes(row.T_audit)?'primary':
+                     [4,6].includes(row.T_audit)?'danger':''">
+                    {{ 
+                        row.T_audit=='1'?'待提交审核':
+                        row.T_audit=='2'?'待审核':
+                        row.T_audit=='3'?'财务通过':
+                        row.T_audit=='4'?'财务驳回':
+                        row.T_audit=='5'?'总经理通过':
+                        row.T_audit=='6'?'总经理驳回':''
+                    }}
+                </el-tag>
+            </template>
+            <template #T_have_brokerage_fee="{ row }">
+                <el-tag :type="row.T_have_brokerage_fee?'primary':'success'">
+                    {{ row.T_have_brokerage_fee?'是':'否' }}
+                </el-tag>
+            </template>
+            <template #right="{ row }">
+                {{  }}
+                <el-button link type="primary" size="small" :icon="View" @click="openDrawer('详情', row)">详情</el-button>
+                <el-button link type="primary" size="small" :disabled="[1,4,6].includes(row.T_audit)?false:true" 
+                icon="Check" @click="SubmitAudit(row)" >提交审核</el-button>
+                <el-button link type="primary" size="small" :disabled="[1,2,4,6].includes(row.T_audit)?false:true" 
+                 :icon="Edit" @click="openDrawer('编辑', row)">编辑</el-button>
+                <el-button link type="danger" size="small" :disabled="[1,2,4,6].includes(row.T_audit)?false:true" 
+                 :icon="Delete" @click="openDelect(row)">删除</el-button>
+            </template>
+        </TableBase>
+    </div>
+</template>
+
+<script setup lang='ts'>
+import { ref, reactive,computed } from 'vue';
+import { View,Check,Edit, Delete } from '@element-plus/icons-vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { GlobalStore } from '@/stores/index'
+import contractReviewListAdd from './modules/contractReviewListAdd.vue'
+import { optionReviewList } from './modules/optionsData'
+import { ContractReview_Del_Post,ContractReview_Submit_Post} from '@/api/contractReview/index'
+
+import TableBase from '@/components/TableBase/index.vue'
+import { ContractReview_List_Post} from '@/api/contractReview/index'
+
+const globalStore = GlobalStore()
+const TableRef = ref()
+const btnRef = ref()
+
+const successFun = async (data:any)=>{
+    TableRef.value?.getTableList()
+}
+
+const data = reactive({
+    initParam :{
+        User_tokey: globalStore.GET_User_tokey,
+        T_name: '',
+        T_submit: '',
+        T_audit: '',
+        page: 1,
+        page_z: 10,
+    },
+    fromData:{},
+})
+// 搜索以及参数
+const columns = [
+    { type: 'index', label: '序号', width: 80, align: 'center ' },
+    { prop: 'T_audit', label: '状态', name: 'T_audit'},
+    { prop: 'T_name', label: '项目名称' },
+    { prop: 'T_address', label: '项目地址' },
+    { prop: 'T_submit_name', label: '项目负责人' },
+    { prop: 'T_predict_sign_time', label: '预计签约时间' },
+    { prop: 'T_money', label: '总金额' },
+    { prop: 'T_have_brokerage_fee', label: '是否有居间费', name: 'T_have_brokerage_fee' },
+    { prop: 'T_brokerage_fee_money', label: '居间费金额' },
+    { prop: 'operation', label: '操作', fixed: 'right',width:'300px' }
+]
+
+const onclicksearch = (row: any) => {
+    TableRef.value?.getTableList()
+}
+
+/**
+ * 编辑
+ * @param tit 
+ * @param row 
+ */
+const openDrawer = (tit:string,row: any) => {
+    btnRef.value.outerVisible = true
+    btnRef.value.data.drawerTiti = tit
+    data.fromData = row
+}
+/**
+ * 删除
+ * @param row 
+ */
+const openDelect = (row: any) => {
+    ElMessageBox.confirm('删除操作,是否执行操作?','删除',{
+        confirmButtonText: '立即删除',
+        cancelButtonText: '取消',
+        type: 'warning',
+        center: true,
+    }).then(async() => {
+        const result:any = await ContractReview_Del_Post({T_id:row.Id})
+        if(result.Code==200){
+            ElMessage.success('删除成功')
+            TableRef.value?.getTableList()
+        }
+    }).catch(() => {})
+}
+/**
+ * 提交审核
+ */
+const SubmitAudit = async(row: any) => {
+    const result:any = await ContractReview_Submit_Post({T_id:row.Id})
+    if(result.Code==200){
+        ElMessage.success('审核提交成功')
+        TableRef.value?.getTableList()
+    }
+}
+
+</script>
+<style lang="scss">
+/* @import url(); 引入css类 */
+</style>

+ 156 - 0
src/views/contractReview/contractReviewManager.vue

@@ -0,0 +1,156 @@
+<template>
+    <div class="">
+        <TableBase ref="TableRef" border :columns="columns" :requestApi="ContractReview_Manager_List_Post" :initParam="data.initParam" >
+            <template #table-header>
+                <div style="display: flex;justify-content: space-between;align-items: center;flex: 1;">
+                    <el-form :inline="true" :model="data.initParam" class="demo-form-inline">
+                        <el-form-item label="项目名称">
+                            <el-input v-model="data.initParam.T_name" placeholder="搜索项目名称" clearable />
+                        </el-form-item>
+                        <el-form-item label="状态">
+                            <el-select style="width: 160px;" v-model="data.initParam.T_audit" placeholder="请选择销售类型">
+                                <el-option v-for="item in optionReviewManager" :key="item.value" :label="item.name" :value="item.value" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="项目负责人">
+                            <el-select style="width: 160px;" v-model="data.initParam.T_submit" placeholder="请选择项目负责人">
+                                <el-option v-for="item in data.optionSubmit" :key="item.T_submit" :label="item.T_name" :value="item.T_submit" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item>
+                            <el-button type="primary" @click="onclicksearch">查询</el-button>
+                        </el-form-item>
+                    </el-form>
+                </div> 
+            </template>
+            <template #T_audit="{ row }">
+                <el-tag :type="
+                    [1,2].includes(row.T_audit)?'warning':
+                    [3,5].includes(row.T_audit)?'primary':
+                     [4,6].includes(row.T_audit)?'danger':''">
+                    {{ 
+                        row.T_audit=='1'?'待提交审核':
+                        row.T_audit=='2'?'待审核':
+                        row.T_audit=='3'?'财务通过':
+                        row.T_audit=='4'?'财务驳回':
+                        row.T_audit=='5'?'总经理通过':
+                        row.T_audit=='6'?'总经理驳回':''
+                    }}
+                </el-tag>
+            </template>
+            <template #T_have_brokerage_fee="{ row }">
+                <el-tag :type="row.T_have_brokerage_fee?'primary':'success'">
+                    {{ row.T_have_brokerage_fee?'是':'否' }}
+                </el-tag>
+            </template>
+            <template #right="{ row }">
+                <el-button link type="primary" size="small" :icon="View" @click="openDrawer('详情', row)">详情</el-button>
+                <el-button link type="primary" size="small" :disabled="[3].includes(row.T_audit)?false:true" 
+                icon="Check" @click="openDrawer('审核', row)" >审核</el-button>
+                <el-button link type="danger" size="small" :icon="Delete" @click="openDelect(row)">删除</el-button>
+            </template>
+        </TableBase>
+
+        <particulars ref="btnRef" :fromData="data.fromData" :audit="<any>[5,6]" types="Manager" @successFun="successFun"></particulars>
+
+    </div>
+</template>
+
+<script setup lang='ts'>
+import { ref, reactive,onMounted } from 'vue';
+import { View,Delete} from '@element-plus/icons-vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { GlobalStore } from '@/stores/index'
+import particulars from './modules/particulars.vue'
+import { optionReviewManager } from './modules/optionsData'
+import TableBase from '@/components/TableBase/index.vue'
+import { ContractReview_Manager_List_Post,
+    ContractReview_Manager_sub_List_Post,
+    ContractReview_Del_Post,//删除
+} from '@/api/contractReview/index'
+
+const globalStore = GlobalStore()
+const TableRef = ref()
+const btnRef = ref()
+
+const data = reactive({
+    optionSubmit:<any>[],
+    initParam :{
+        User_tokey: globalStore.GET_User_tokey,
+        T_name: '',
+        T_submit: '',
+        T_audit: '',
+        page: 1,
+        page_z: 10,
+    },
+    fromData:{}
+})
+// 搜索以及参数
+const columns = [
+    { type: 'index', label: '序号', width: 80, align: 'center ' },
+    { prop: 'T_audit', label: '状态', name: 'T_audit'},
+    { prop: 'T_name', label: '项目名称' },
+    { prop: 'T_address', label: '项目地址' },
+    { prop: 'T_submit_name', label: '项目负责人' },
+    { prop: 'T_predict_sign_time', label: '预计签约时间' },
+    { prop: 'T_money', label: '总金额' },
+    { prop: 'T_have_brokerage_fee', label: '是否有居间费', name: 'T_have_brokerage_fee' },
+    { prop: 'T_brokerage_fee_money', label: '居间费金额' },
+    { prop: 'operation', label: '操作', fixed: 'right',width:'200px'}
+]
+/**
+ * 项目负责人
+ * @param row 
+ */
+ const SubmituserApi = async() => {
+    const result:any = await ContractReview_Manager_sub_List_Post({T_type:'Manager'})
+    if(result.Code==200){
+        console.log('项目负责人',result)
+        let obj = { T_name: "全部", T_submit:""}
+        let arr = result.Data.Data || []
+        data.optionSubmit = [obj,...arr]
+    }
+}
+onMounted(()=>{
+    SubmituserApi()
+})
+
+const onclicksearch = (row: any) => {
+    TableRef.value?.getTableList()
+}
+const successFun = async ()=>{
+    TableRef.value?.getTableList()
+}
+/**
+ * 编辑
+ * @param tit 
+ * @param row 
+ */
+ const openDrawer = (tit:string,row: any) => {
+    console.log('ss',tit,row,btnRef.value)
+    btnRef.value.outerVisible = true
+    btnRef.value.data.drawerTiti = tit
+    data.fromData = row
+}
+/**
+ * 删除
+ * @param row 
+ */
+ const openDelect = (row: any) => {
+    ElMessageBox.confirm('删除操作,是否执行操作?','删除',{
+        confirmButtonText: '立即删除',
+        cancelButtonText: '取消',
+        type: 'warning',
+        center: true,
+    }).then(async() => {
+        const result:any = await ContractReview_Del_Post({T_id:row.Id})
+        if(result.Code==200){
+            ElMessage.success('删除成功')
+            TableRef.value?.getTableList()
+        }
+    }).catch(() => {})
+}
+</script>
+<style lang="scss">
+/* @import url(); 引入css类 */
+</style>

+ 74 - 0
src/views/contractReview/index.scss

@@ -0,0 +1,74 @@
+@import '@/styles/var.scss';
+
+.salary {
+  height: 100%;
+  display: flex;
+  overflow: hidden;
+  .salary-table {
+    @include f-direction;
+  }
+}
+
+.submit {
+  padding: 0.5rem 1.875rem;
+  // margin-top: 1.25rem;
+}
+.form-card {
+  overflow: auto;
+  .form-card-right,
+  .form-card-left {
+    display: flex;
+    flex-direction: column;
+  }
+  .form-card-right {
+    align-items: end;
+  }
+  .form-card-left {
+    align-items: start;
+  }
+}
+.d-flex {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  flex-wrap: nowrap;
+}
+.justify-start {
+  justify-content: start;
+}
+.input-suffix {
+  width: 100%;
+  flex-direction: column;
+  .w-50 {
+    width: 12.5rem;
+  }
+
+  .inline-flex {
+    white-space: nowrap;
+    display: inline-flex;
+  }
+}
+.title {
+  text-align: center;
+}
+.info-content {
+  display: flex;
+  color: #303133;
+  .info-name {
+    display: flex;
+    flex-direction: column;
+    padding-left: 0.75rem;
+    span:first-child {
+      margin-right: 2rem;
+    }
+  }
+}
+
+.b-r,
+.form-card {
+  border-radius: 8px;
+}
+
+.demonstration {
+  margin-left: 8px;
+}

+ 358 - 0
src/views/contractReview/modules/contractReviewListAdd.vue

@@ -0,0 +1,358 @@
+<template>
+    <div class="">
+        <el-button type="primary" icon="Plus" @click="searchHandle('添加')" style="margin-left: 5px;">添加</el-button>
+        <el-dialog v-model="outerVisible" :title="data.drawerTiti" width="1200" style="max-height: 900px;overflow-y: auto;" draggable destroy-on-close>
+            <el-form :model="data.initParam"
+            ref="ruleFormRef"
+            :rules="rules"
+            :disabled="data.drawerTiti=='详情'?true:false"
+            label-width="160px">
+                <el-form-item label="项目名称" prop="T_name">
+                    <el-input v-model="data.initParam.T_name" />
+                </el-form-item>
+                <el-form-item label="项目地址" prop="T_address">
+                    <el-input v-model="data.initParam.T_address" />
+                </el-form-item>
+                <el-form-item label="预计签约时间" prop="T_predict_sign_time">
+                    <el-date-picker v-model="data.initParam.T_predict_sign_time" value-format="YYYY-MM-DD" type="date" placeholder="预计签约时间" />
+                </el-form-item>
+                <el-form-item label="服务内容" prop="ServiceItems">
+                    <el-table :data="data.initParam.ServiceItems"  border style="width: 100%">
+                        <el-table-column type="index" label="序号" width="60"/>
+                        <el-table-column prop="address" label="服务类型" show-overflow-tooltip  width="100">
+                            <template #default="scope">
+                                {{ scope.row.ServiceItem.ServiceType.T_name }}
+                            </template>
+                        </el-table-column>
+                        <el-table-column prop="address" label="销售类型" show-overflow-tooltip  width="100">
+                            <template #default="scope">
+                                {{ scope.row.ServiceItem.T_sale_type }}
+                            </template>
+                        </el-table-column>
+                        <el-table-column prop="address" label="服务内容" show-overflow-tooltip >
+                            <template #default="scope">
+                                {{ scope.row.ServiceItem.T_name }}
+                            </template>
+                        </el-table-column>
+                        <el-table-column prop="address" label="型号" show-overflow-tooltip >
+                            <template #default="scope">
+                                {{ scope.row.ServiceItem.T_model }}
+                            </template>
+                        </el-table-column>
+                        <el-table-column prop="address" label="规格" show-overflow-tooltip  width="80">
+                            <template #default="scope">
+                                {{ scope.row.ServiceItem.T_spec }}
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="数量"  width="100">
+                            <template #default="scope">
+                                <el-input v-model.number="scope.row.T_quantity" style="width:75px" />
+                            </template>
+                        </el-table-column>
+                        <el-table-column label="单价"  width="100">
+                            <template #default="scope">
+                                <!-- <el-input v-model.number="scope.row.T_unit_price" style="width:75px" /> -->
+                                <el-input v-model.number="scope.row.T_unit_price" type="number" style="width:75px"></el-input>
+                            </template>
+                        </el-table-column>
+                        <el-table-column prop="address" label="金额" show-overflow-tooltip >
+                            <template #default="scope">
+                                {{ scope.row.T_quantity *  scope.row.T_unit_price}}
+                            </template>
+                        </el-table-column>
+                        <el-table-column prop="T_remark" label="备注" show-overflow-tooltip>
+                            <template #default="scope">
+                                <el-input v-model="scope.row.T_remark" style="width:100%" />
+                            </template>
+                        </el-table-column>
+                        <!-- <el-table-column prop="address" label="操作" width="80" fixed="right">
+                            <template #default="scope">
+                                <el-button link type="danger" size="small" :icon="Delete" @click="onclickdelete(scope)">删除</el-button>
+                            </template>
+                        </el-table-column> -->
+                    </el-table>
+                    <el-button icon="Plus" v-if="data.drawerTiti!='详情'" style="margin-top: 10px;" @click="showinnerVisible">添加</el-button>
+                </el-form-item>
+                <el-form-item label="总金额">
+                    {{ moneyFun() }}
+                </el-form-item>
+                <el-form-item label="是否有居间费" prop="T_have_brokerage_fee">
+                    <el-radio-group v-model="data.initParam.T_have_brokerage_fee">
+                        <el-radio :label="true">是</el-radio>
+                        <el-radio :label="false">否</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="居间费金额" prop="T_brokerage_fee_money">
+                    <el-input v-model="data.initParam.T_brokerage_fee_money" />
+                </el-form-item>
+                <el-form-item label="状态" v-if="data.drawerTiti=='详情'">
+                    <el-tag :type="
+                                ['1','2'].includes(props.fromData.T_audit)?'info':
+                                ['3','5'].includes(props.fromData.T_audit)?'primary':
+                                ['4','6'].includes(props.fromData.T_audit)?'danger':''">
+                                {{ 
+                                    props.fromData.T_audit=='1'?'待提交审核':
+                                    props.fromData.T_audit=='2'?'待审核':
+                                    props.fromData.T_audit=='3'?'财务通过':
+                                    props.fromData.T_audit=='4'?'财务驳回':
+                                    props.fromData.T_audit=='5'?'总经理通过':
+                                    props.fromData.T_audit=='6'?'总经理驳回':''
+                                }}
+                            </el-tag>
+                </el-form-item>
+                <el-form-item label="成本会计审批意见" v-if="data.drawerTiti=='详情'">
+                    <el-tag type="info">
+                        {{ props.fromData.T_finance_approval_opinion?props.fromData.T_finance_approval_opinion:'暂无' }}
+                    </el-tag>
+                </el-form-item>
+                <el-form-item label="总经理审批意见" v-if="data.drawerTiti=='详情'">
+                    <el-tag type="info">
+                        {{ props.fromData.T_manager_approval_opinion?props.fromData.T_manager_approval_opinion:'暂无'}}
+                    </el-tag>
+                </el-form-item>
+                <el-form-item v-if="data.drawerTiti!='详情'">
+                    <el-button type="primary" @click="onSubmit(ruleFormRef)">立即提交</el-button>
+                    <el-button @click="outerVisible = false">取消</el-button>
+                </el-form-item>
+            </el-form>
+            <el-dialog v-model="innerVisible" draggable destroy-on-close title="服务内容"  width="800" append-to-body>
+                <div>
+                    <el-form :model="data.initParam" :inline="true">
+                        <el-form-item label="服务类型" prop="T_service_type_id">
+                            <el-select v-model="data.initParamType.T_service_type_id" clearable placeholder="请选择服务类型">
+                                <el-option v-for="item in data.options" :key="item.Id" :label="item.T_name" :value="item.Id" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item label="销售类型">
+                            <el-select v-model="data.initParamType.T_sale_type" clearable placeholder="请选择销售类型">
+                                <el-option v-for="item in data.optionsType" :key="item.T_name" :label="item.T_name" :value="item.T_name" />
+                            </el-select>
+                        </el-form-item>
+                        <el-form-item>
+                            <el-button type="primary" @click="onclicksearch">查询</el-button>
+                        </el-form-item>
+                    </el-form>
+                    <el-table :data="data.tableDataType"
+                    :row-key="(row:any)=>row.Id"
+                     ref="multipleTableRef" 
+                     @select="handleChange"
+                    style="width: 100%" max-height="500" border>
+                        <el-table-column type="selection" label="服务内容" width="55" :reserve-selection="true"/>
+                        <el-table-column label="服务类型" width="120">
+                            <template #default="scope">{{ scope.row.ServiceType.T_name }}</template>
+                        </el-table-column>
+                        <el-table-column label="销售类型" width="120">
+                            <template #default="scope">{{ scope.row.T_sale_type }}</template>
+                        </el-table-column>
+                        <el-table-column label="服务内容" width="120" show-overflow-tooltip >
+                            <template #default="scope">{{ scope.row.T_name }}</template>
+                        </el-table-column>
+                        <el-table-column label="型号" prop="T_model" width="120" />
+                        <el-table-column label="规格" prop="T_spec" show-overflow-tooltip />
+                    </el-table>
+                </div>
+            </el-dialog>
+        </el-dialog>
+    </div>
+</template>
+
+<script setup lang='ts'>
+import { ref, reactive,watch} from 'vue';
+import type { ComponentSize, FormInstance, FormRules } from 'element-plus'
+import { ElMessage } from 'element-plus'
+
+import { ServiceType_List_Post,ServiceItem_List_Post,
+    ContractReview_Add_Post,
+    ContractReview_Edit_Post} from '@/api/contractReview/index'
+const outerVisible = ref(false)
+const innerVisible = ref(false)
+
+const ruleFormRef = ref<FormInstance>()
+const props:any = defineProps({
+    fromData:{}
+})
+watch(()=>outerVisible.value,(newData)=>{
+    if(newData && data.drawerTiti!='新增'){//打开
+        let arr = {...props.fromData}
+        for (let key in arr) {  
+            if (data.initParam.hasOwnProperty(key)) {  
+                data.initParam[key] = arr[key];
+            }
+        }  
+        data.initParam.ServiceItems = arr.ServiceItemList
+    }
+},{deep:true})
+const data:any = reactive({
+    drawerTiti: '',
+    initParam: {
+        T_name: '',
+        T_address: '',
+        T_predict_sign_time: '',
+        T_money:0,
+        T_have_brokerage_fee: false,
+        T_brokerage_fee_money:0,
+        ServiceItems:[]
+    },
+    fromData: {},
+    options: [],
+    optionsType: [{ T_name: '/' }, { T_name: '软件' }, { T_name: '硬件' }],
+    initParamType:{
+        T_service_type_id:'',
+        T_sale_type:'',
+        page:1,
+        page_z:999999
+    },
+    tableData:[],
+    tableDataType:[]
+})
+const rules = reactive({
+    T_name: [{ required: true, message: '必填项', trigger: 'blur' }],
+    T_address: [{ required: true, message: '必填项', trigger: 'blur' }],
+    T_predict_sign_time: [{ required: true, message: '必填项', trigger: 'blur' }],
+    T_have_brokerage_fee: [{ required: true, message: '必填项', trigger: 'blur' }],
+    T_brokerage_fee_money: [{  
+        validator: (rule:any, value:any, callback:any) => {  
+            if (data.initParam.T_have_brokerage_fee && !value) {  
+            return callback(new Error('居间费金额不能为空'));  
+            }  
+            callback();  
+        },  
+        trigger: ['blur','change'],  
+        }],
+    ServiceItems: [{ required: true, message: '必填项', trigger: 'change' }],
+})
+
+const multipleTableRef = ref()
+const handleChange = async (row:any)=>{
+    let arr:any = []
+    let repeats = [...new Map(row.map((item:any) => [item.Id, item])).values()]//去重
+    let ServiceItems = [...data.initParam.ServiceItems]
+    repeats.forEach((item:any) => {
+        const flag = ServiceItems.find((obj:any) => item.Id === obj.ServiceItem.Id); 
+        if(flag){//已经存在
+            arr.push({...flag})
+        }else{//不存在
+            arr.push({
+                ServiceItem:item,
+                T_quantity:0,
+                T_remark: "",
+                T_unit_price:0,
+                T_service_item_id:item.Id
+            })
+        }
+    })
+    data.initParam.ServiceItems = arr.sort((a:any, b:any) => a.ServiceItem.Id - b.ServiceItem.Id);  
+}
+const showinnerVisible = async (row:any) => {
+    innerVisible.value = true
+    await ServiceItemApi()
+    await getServiceList()
+    //打开时勾选上对应的选项
+    if(data.initParam.ServiceItems){
+        data.initParam.ServiceItems.map((item:any) => {  
+            data.tableDataType.map((row:any) => {
+                if(item.ServiceItem.Id === row.Id){
+                    multipleTableRef.value!.toggleRowSelection(row)
+                }
+            })
+        }); 
+    }
+}
+
+
+const moneyFun = ()=>{
+    let total = data.initParam.ServiceItems.reduce((acc:any, item:any) => {  
+      return acc + item.T_quantity * item.T_unit_price;  
+    }, 0);  
+    data.initParam.T_money = total
+    return total+'元'; 
+}
+/**
+ * 
+ * @param row 删除列
+ */
+const onclickdelete = async (row:any) => data.initParam.ServiceItems.splice(row.$index,1)
+
+
+
+const getServiceList = async () => {
+    const result: any = await ServiceType_List_Post({ page: 1, page_z: 9999, })
+    if (result.Code == 200) {
+        data.options = result.Data.Data || []
+    }
+}
+const searchHandle = (row: any) => {
+    data.initParam = {
+        T_name: '',
+        T_address: '',
+        T_predict_sign_time: '',
+        T_money:0,
+        T_have_brokerage_fee: false,
+        T_brokerage_fee_money:null,
+        ServiceItems:[]
+    }
+    outerVisible.value = true
+    data.drawerTiti = '新增'
+}
+const ServiceItemApi = async ()=>{
+    const result:any = await ServiceItem_List_Post(data.initParamType)
+    if(result.Code==200){
+        data.tableDataType = result.Data.Data || []
+    }
+}
+const onSubmit = async (formEl: FormInstance | undefined) => {
+  if (!formEl) return
+  await formEl.validate((valid:any, fields:any) => {
+    if (valid) {
+        console.log('submit!',data.initParam)
+        if(data.drawerTiti=='新增'){
+            ContractReview_AddtApi()
+        }else{
+            ContractReview_EditApi()
+        }
+    }
+  })
+}
+
+const emit = defineEmits<{ (event: 'successFun', value:boolean): void }>()
+/**
+ * 新增
+ */
+ const ContractReview_AddtApi = async ()=>{
+    let obj = {...data.initParam}
+    obj.ServiceItems = JSON.stringify(obj.ServiceItems)
+    const result:any = await ContractReview_Add_Post(obj)
+    if(result.Code==200){
+        ElMessage.success('新增成功')
+        emit('successFun',true)
+        outerVisible.value = false
+    }
+}
+/**
+ * 编辑
+ */
+const ContractReview_EditApi = async ()=>{
+    let obj = {...data.initParam}
+    obj.T_id = props.fromData.Id
+    obj.ServiceItems = JSON.stringify(obj.ServiceItems)
+    const result:any = await ContractReview_Edit_Post(obj)
+    if(result.Code==200){
+        ElMessage.success('编辑成功')
+        emit('successFun',true)
+        outerVisible.value = false
+    }
+}
+const onclicksearch = async ()=>{
+    ServiceItemApi()
+}
+defineExpose({
+    outerVisible, data
+})
+</script>
+
+<style lang="scss" scoped>
+/* 隐藏全选框 */
+::v-deep .el-table__header-wrapper .el-checkbox {
+  display: none;
+}
+</style>

+ 67 - 0
src/views/contractReview/modules/optionsData.ts

@@ -0,0 +1,67 @@
+/**
+ * 合同评审
+ */
+export const optionReviewList = [{
+    name:'全部',
+    value:''
+},{
+    name:'待提交审核',
+    value:'1'
+},{
+    name:'待审核',
+    value:'2'
+},{
+    name:'财务通过',
+    value:'3'
+},{
+    name:'财务驳回',
+    value:'4'
+},{
+    name:'总经理通过',
+    value:'5'
+},{
+    name:'总经理驳回',
+    value:'6'
+}]
+
+
+/**
+ * 合同评审(财务)
+ */
+export const optionReviewFinance = [{
+    name:'全部',
+    value:''
+},{
+    name:'待审核',
+    value:'2'
+},{
+    name:'财务通过',
+    value:'3'
+},{
+    name:'财务驳回',
+    value:'4'
+},{
+    name:'总经理通过',
+    value:'5'
+},{
+    name:'总经理驳回',
+    value:'6'
+}]
+
+
+/**
+ * 合同评审(总经理)
+ */
+export const optionReviewManager = [{
+    name:'全部',
+    value:''
+},{
+    name:'财务通过',
+    value:'3'
+},{
+    name:'总经理通过',
+    value:'5'
+},{
+    name:'总经理驳回',
+    value:'6'
+}]

+ 220 - 0
src/views/contractReview/modules/particulars.vue

@@ -0,0 +1,220 @@
+<template>
+    <div class="particulars">
+        <el-dialog v-model="outerVisible" :title="data.drawerTiti" draggable destroy-on-close>
+            <div style="border-top:1px solid #ccc;padding-top: 20px;">
+                <el-form ref="ruleFormRef" label-width="160px">
+                    <el-form-item label="项目名称">
+                        <el-input v-model="fromData.T_name" style="width: 350px;" :disabled="true"/>
+                    </el-form-item>
+                    <el-form-item label="项目地址">
+                        <el-input v-model="fromData.T_address" style="width: 350px;" :disabled="true"/>
+                    </el-form-item>
+                    <el-form-item label="项目负责人">
+                        <el-input v-model="fromData.T_submit_name" style="width: 350px;" :disabled="true"/>
+                    </el-form-item>
+                    <el-form-item label="预计签约时间">
+                        <el-date-picker v-model="fromData.T_predict_sign_time" :disabled="true" value-format="YYYY-MM-DD" type="date" placeholder="预计签约时间" />
+                    </el-form-item>
+                    <el-form-item label="服务内容">
+                        <el-table :data="fromData.ServiceItemList" border style="width: 100%">
+                            <el-table-column type="index" label="序号" width="60" />
+                            <el-table-column prop="address" label="服务类型" show-overflow-tooltip width="100">
+                                <template #default="scope">
+                                    {{ scope.row.ServiceItem.ServiceType.T_name }}
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="address" label="销售类型" show-overflow-tooltip width="100">
+                                <template #default="scope">
+                                    {{ scope.row.ServiceItem.T_sale_type }}
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="address" label="服务内容" show-overflow-tooltip>
+                                <template #default="scope">
+                                    {{ scope.row.ServiceItem.T_name }}
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="address" label="型号" show-overflow-tooltip>
+                                <template #default="scope">
+                                    {{ scope.row.ServiceItem.T_model }}
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="address" label="规格" show-overflow-tooltip width="80">
+                                <template #default="scope">
+                                    {{ scope.row.ServiceItem.T_spec }}
+                                </template>
+                            </el-table-column>
+                            <el-table-column label="数量" width="100" show-overflow-tooltip>
+                                <template #default="scope">
+                                    {{ scope.row.T_quantity }}
+                                </template>
+                            </el-table-column>
+                            <el-table-column label="单价" width="100">
+                                <template #default="scope">
+                                    {{ scope.row.T_unit_price }}
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="address" label="金额" show-overflow-tooltip>
+                                <template #default="scope">
+                                    {{ scope.row.T_quantity * scope.row.T_unit_price }}
+                                </template>
+                            </el-table-column>
+                            <el-table-column prop="T_remark" label="备注" show-overflow-tooltip>
+                                <template #default="scope">
+                                    {{ scope.row.T_remark }}
+                                </template>
+                            </el-table-column>
+                            <!-- <el-table-column prop="address" label="操作" width="80" fixed="right">
+                                <template #default="scope">
+                                    <el-button link type="danger" size="small" :icon="Delete" @click="onclickdelete(scope)">删除</el-button>
+                                </template>
+                            </el-table-column> -->
+                        </el-table>
+                    </el-form-item>
+                    <el-form-item label="总金额">
+                        {{ moneyFun() }}
+                    </el-form-item>
+                    <el-form-item label="是否有居间费">
+                        <el-radio-group v-model="fromData.T_have_brokerage_fee" :disabled="true">
+                            <el-radio :label="true">是</el-radio>
+                            <el-radio :label="false">否</el-radio>
+                        </el-radio-group>
+                    </el-form-item>
+                    <el-form-item label="居间费金额">
+                        {{ fromData.T_brokerage_fee_money }}
+                    </el-form-item>
+                    <el-form-item label="状态">
+                        <el-tag :type="[1,2].includes(fromData.T_audit) ? 'warning' :
+                            [3,5].includes(fromData.T_audit) ? 'primary' :
+                            [4,6].includes(fromData.T_audit) ? 'danger' : ''">
+                            {{
+                                fromData.T_audit == '1' ? '待提交审核' :
+                                fromData.T_audit == '2' ? '待审核' :
+                                fromData.T_audit == '3' ? '财务通过' :
+                                fromData.T_audit == '4' ? '财务驳回' :
+                                fromData.T_audit == '5' ? '总经理通过' :
+                                fromData.T_audit == '6' ? '总经理驳回' : ''
+                            }}
+                        </el-tag>
+                    </el-form-item>
+                    <el-form-item label="成本会计审批意见" v-if="data.drawerTiti == '详情' ||  types=='Manager'">
+                        <el-alert :title="
+                            fromData.T_finance_approval_opinion?fromData.T_finance_approval_opinion:'暂无' " 
+                         :type="[4].includes(fromData.T_audit)?'error':'success'" :closable="false" />
+                    </el-form-item>
+                    <el-form-item label="成本会计审批意见" v-if="data.drawerTiti == '审核' && types=='Finance'">
+                         <el-input v-model="data.initParam.T_approval_opinion" :rows="3" type="textarea" placeholder="审批意见" />
+                    </el-form-item>
+
+                    <el-form-item label="总经理审批意见" v-if="data.drawerTiti == '详情'">
+                        <el-alert :title=" fromData.T_manager_approval_opinion?fromData.T_manager_approval_opinion:'暂无'"
+                        :type="[6].includes(fromData.T_audit)?'error':'success'" :closable="false" />
+                    </el-form-item>
+                    <el-form-item label="总经理审批意见" v-if="data.drawerTiti == '审核' && types=='Manager'">
+                        <el-input v-model="data.initParam.T_approval_opinion" :rows="3" type="textarea" placeholder="审批意见" />
+                    </el-form-item>
+                </el-form>
+            </div>
+            <template #footer v-if="data.drawerTiti != '详情'">
+                <div class="dialog-footer"
+                    style="border-top:1px solid #ccc;padding-top: 20px;display: flex;justify-content: center;gap: 40px;">
+                    <el-button type="primary" @click="onSubmit(audit[0])">同意</el-button>
+                    <el-button type="danger" @click="onSubmit(audit[1])">驳回</el-button>
+                </div>
+            </template>
+        </el-dialog>
+    </div>
+</template>
+
+<script setup lang='ts'>
+import { ref, reactive, watch } from 'vue';
+import type {FormInstance } from 'element-plus'
+import { ElMessage } from 'element-plus'
+
+import {
+    Review_Finance_Audit,
+    Review_Manager_Audit
+} from '@/api/contractReview/index'
+const outerVisible = ref(false)
+
+const ruleFormRef = ref<FormInstance>()
+const props = defineProps({
+    fromData: {
+        type: Object,
+        default: () => { },
+    },
+    types: {
+        type: String,
+        default: () => '',
+    },
+    audit:{
+        type: Array,
+        default: () => [0,0],
+    }
+})
+
+watch(()=>outerVisible.value,(newData:any)=>{
+    if(newData){
+        console.log('展示', props.fromData)
+    }
+})
+
+const data: any = reactive({
+    drawerTiti: '',
+    initParam: {
+        T_id: null,
+        T_audit: '',
+        T_approval_opinion: '',
+    },
+    fromData: {},
+    optionsType: [{ T_name: '/' }, { T_name: '软件' }, { T_name: '硬件' }],
+})
+
+const moneyFun = () => {
+    let total = props.fromData.ServiceItemList.reduce((acc: any, item: any) => {
+        return acc + item.T_quantity * item.T_unit_price;
+    }, 0);
+    props.fromData.T_money = total
+    return total + '元';
+}
+const onSubmit = async (audit:any) => {
+    data.initParam.T_id = props.fromData.Id
+    data.initParam.T_audit = audit
+    props.types=='Finance'?financeAuditApi():managerAuditApi()
+}
+const emit = defineEmits<{ (event: 'successFun', value: boolean): void }>()
+
+//财务
+const financeAuditApi = async ()=>{
+    const result:any = await Review_Finance_Audit(data.initParam)
+    console.log('财务提交',result)
+    if(result.Code==200){
+        ElMessage.success('审核成功')
+        emit('successFun', true)
+        outerVisible.value = false
+    }
+}
+//总经理
+const managerAuditApi = async ()=>{
+    const result:any = await Review_Manager_Audit(data.initParam)
+    if(result.Code==200){
+        ElMessage.success('审核成功')
+        emit('successFun', true)
+        outerVisible.value = false
+    }
+    console.log('总经理提交',result)
+}
+
+
+
+defineExpose({
+    outerVisible, data
+})
+</script>
+<style lang="scss" scoped>
+::v-deep .el-checkbox__input.is-indeterminate .el-checkbox__inner {
+    display: none !important;
+}
+
+// ::v-deep .el-dialog__body {
+//     padding: 0;
+// }</style>

+ 206 - 0
src/views/contractReview/serviceItem.vue

@@ -0,0 +1,206 @@
+<script setup lang="ts">
+import { ref, reactive } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import ServiceItemFrom from './serviceItemFrom.vue'
+import { Edit, Delete, Plus } from '@element-plus/icons-vue'
+
+import { GlobalStore } from '@/stores/index'
+import TableBase from '@/components/TableBase/index.vue'
+import { ColumnProps } from '@/components/TableBase/interface/index'
+import { useTablePublic } from '@/hooks/useTablePublic'
+import type { FormInstance } from 'element-plus'
+import { ServiceType_List_Post, ServiceType_Add_Post, ServiceType_Edit_Post, ServiceType_Del_Post } from '@/api/contractReview/index'
+
+const data:any = reactive({
+    fromDatas: { 
+        T_name: '',
+        T_service_type_id: '',
+    },
+    drawer: false,
+    drawerTiti: ''
+})
+
+const getSalaryParams = (row: any) => {
+    data.fromDatas.T_service_type_id = row.Id
+    ServiceItemFromRef.value?.getDataFn()
+}
+
+const ruleFormRef = ref()
+interface RuleForm {
+    T_id: number
+    T_name: string
+}
+const ruleForm = reactive<RuleForm>({
+    T_id: 0,
+    T_name: '',
+})
+const rules:any = reactive({
+    T_name: [
+        { required: true, message: '请输入服务类型', trigger: 'change' }
+    ]
+})
+const submitForm = async (formEl: FormInstance | undefined) => {
+    if (!formEl) return
+    await formEl.validate((valid, fields) => {
+        if (valid) data.drawerTiti == '编辑' ? ServiceTypeEditApi() : ServiceTypeAddApi()
+    })
+}
+/**
+ * 新增
+ */
+const ServiceTypeAddApi = async () => {
+    const result: any = await ServiceType_Add_Post(ruleForm)
+    if (result.Code == 200) {
+        TableRef.value?.getTableList()
+        data.drawer = false
+        ElMessage.success('添加成功')
+    }
+}
+/**
+ * 编辑
+ */
+const ServiceTypeEditApi = async () => {
+    const result: any = await ServiceType_Edit_Post(ruleForm)
+    if (result.Code == 200) {
+        TableRef.value?.getTableList()
+        data.drawer = false
+        ElMessage.success('编辑成功')
+    }
+}
+const UserDelete = async (row: any) => {
+    let {Id} = row
+    ElMessageBox.confirm(
+        '删除服务类型,是否确认删除?', 'Warning',
+        {
+            confirmButtonText: '立即删除',
+            cancelButtonText: '取消',
+            type: 'warning',
+            center: true,
+        }).then(() => {
+            ServiceTypeDelApi({T_id:Id})
+        }).catch(() => {})
+}
+/**
+ * 删除
+ */
+const ServiceTypeDelApi = async (obj:any) => {
+    const result:any = await ServiceType_Del_Post(obj)
+    if (result.Code == 200) {
+        TableRef.value?.getTableList()
+        ElMessage.success('删除成功')
+    }
+}
+
+
+
+let date = new Date()
+const year = date.getFullYear()
+const month = date.getMonth()
+const salaryFromData = reactive({
+    year: year + '',
+    month: (month < 10 ? '0' : '') + month,
+    T_uuid: ''
+})
+const globalStore = GlobalStore()
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
+const ServiceItemFromRef = ref<InstanceType<typeof ServiceItemFrom> | null>(null)
+const { tableRowClassName } = useTablePublic()
+// 搜索以及参数
+const columns: ColumnProps[] = [
+    { prop: 'T_name', label: '服务类型' },
+    { prop: 'operation', label: '操作', fixed: 'right' }
+]
+const initParam = {
+    User_tokey: globalStore.GET_User_tokey,
+    T_name: '',
+    page: 1,
+    page_z: 9999,
+}
+
+const searchHandle = (title: string, obj?: any) => {
+    ruleForm.T_name = obj?.T_name
+    ruleForm.T_id = obj?.Id
+    data.drawer = true
+    data.drawerTiti = title
+}
+const showFrom = ref(false)
+const dataCallback = (res:any)=>{
+    if(res.Data?.Data && res?.Data?.Data.lenght!=0){
+        data.fromDatas.T_service_type_id = res?.Data?.Data[0].Id
+    }
+    showFrom.value = true
+    return res?.Data?.Data
+}
+const onClicksearch = async ()=>{
+    ServiceItemFromRef.value?.getDataFn()
+}
+const onClickAdd = async ()=>{
+    ServiceItemFromRef.value!.data.drawer = true
+    ServiceItemFromRef.value!.data.drawerTiti = '新增服务内容'
+    ServiceItemFromRef.value!.getServiceList()
+}
+
+
+</script>
+
+<template>
+    <div class="salary">
+        <div style="width: 290px" class="salary-table">
+            <TableBase ref="TableRef" :columns="columns" :requestApi="ServiceType_List_Post" :initParam="initParam"
+                layout="prev, pager, next" :rowClick="getSalaryParams" :pagination="false"
+                :dataCallback="dataCallback"
+                >
+                <template #table-header>
+                    <div style="display: flex;justify-content: space-between;align-items: center;flex: 1;">
+                        <div style="display: flex;align-items: center;">
+                            <el-icon size="22">
+                                <Menu />
+                            </el-icon>
+                            <el-text tag="b" size="large" style="margin-left: 5px;">服务类型</el-text>
+                        </div>
+                        <el-button type="primary" icon="Plus" @click="searchHandle('添加')"
+                            style="margin-left: 5px;">添加</el-button>
+                    </div>
+                </template>
+                <template #right="{ row }">
+                    <el-button link type="primary" size="small" :icon="Edit"
+                        @click.stop="searchHandle('编辑', row)"></el-button>
+                    <el-button link type="danger" size="small" :icon="Delete" @click.stop="UserDelete(row)"></el-button>
+                </template>
+            </TableBase>
+        </div>
+        <el-row class="h-100 f-1 margin-left-3">
+            <el-col :span="24" class="h-100" style="overflow: hidden; display: flex; flex-direction: column">
+                <el-card class="b-r m-b-3">
+                    <div style="display: flex;justify-content: space-between">
+                        <div>
+                            <el-button type="primary" @click="onClickAdd" icon="Plus" style="margin-left: 5px;">新增服务内容</el-button>
+                        </div>
+                        <div>
+                            <el-input v-model="data.fromDatas.T_name" style="width: 240px" placeholder="搜索服务内容" />
+                            <el-button type="primary" style="margin-left: 5px;" @click="onClicksearch">搜索</el-button>
+                        </div>
+                    </div>
+                </el-card>
+                <ServiceItemFrom v-if="showFrom" ref="ServiceItemFromRef" :fromDatas="data.fromDatas"></ServiceItemFrom>
+            </el-col>
+        </el-row>
+        <el-drawer v-model="data.drawer" :title="data.drawerTiti" direction="rtl" destroy-on-close>
+            <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-position="top" label-width="90">
+                <el-form-item label="服务类型" prop="T_name">
+                    <el-input v-model="ruleForm.T_name" />
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="submitForm(ruleFormRef)">
+                        提交
+                    </el-button>
+                    <el-button @click="data.drawer = false">Reset</el-button>
+                </el-form-item>
+            </el-form>
+        </el-drawer>
+    </div>
+</template>
+
+<style scoped lang="scss">
+@import './index.scss';
+</style>

+ 230 - 0
src/views/contractReview/serviceItemFrom.vue

@@ -0,0 +1,230 @@
+<template>
+    <div class="ReimburseFrom">
+        <TableBase border ref="TableRef" :columns="columns" :requestApi="ServiceItem_List_Post" :initParam="props.fromDatas"
+            :displayHeader="true" :tableRowClassName="tableRowClassNameHandle">
+            <template #right="{ row }">
+                <el-button link type="primary" size="small" :icon="Edit" @click="openDrawer('编辑', row)"></el-button>
+                <el-button link type="danger" size="small" :icon="Delete" @click="UserDelete(row)"></el-button>
+            </template>
+        </TableBase>
+        <el-drawer v-model="data.drawer" :title="data.drawerTiti" direction="rtl" destroy-on-close>
+            <el-form ref="ruleFormRef" :model="data.initParam" :rules="rules" label-position="top">
+                <el-form-item label="服务类型" prop="T_service_type_id">
+                    <el-select v-model="data.initParam.T_service_type_id" placeholder="请选择服务类型">
+                        <el-option v-for="item in data.options" :key="item.Id" :label="item.T_name" :value="item.Id"/>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="销售类型">
+                    <el-select v-model="data.initParam.T_sale_type" placeholder="请选择销售类型">
+                        <el-option v-for="item in data.optionsType" :key="item.T_name" :label="item.T_name" :value="item.T_name" />
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="服务内容" prop="T_name">
+                    <el-input v-model="data.initParam.T_name" />
+                </el-form-item>
+                <el-form-item label="型号">
+                    <el-input v-model="data.initParam.T_model" />
+                </el-form-item>
+                <el-form-item label="规格">
+                    <el-input v-model="data.initParam.T_spec" />
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="submitForm(ruleFormRef)">
+                        提交
+                    </el-button>
+                    <el-button @click="data.drawer = false">Reset</el-button>
+                </el-form-item>
+            </el-form>
+        </el-drawer>
+    </div>
+</template>
+<script lang="ts" setup>
+import { reactive, ref } from "vue";
+import TableBase from '@/components/TableBase/index.vue'
+import { ServiceItem_List_Post, ServiceItem_Add_Post, ServiceItem_Edit_Post, ServiceItem_Del_Post,ServiceType_List_Post } from '@/api/contractReview/index'
+import { ElMessage , ElMessageBox} from 'element-plus'
+import type { FormInstance } from 'element-plus'
+import { Edit, Delete, Plus } from '@element-plus/icons-vue'
+import { ColumnProps } from '@/components/TableBase/interface/index'
+// 接受父组件参数,配置默认值
+const props = defineProps<{
+    fromDatas: {},
+}>()
+
+const ruleFormRef = ref()
+const data: any = reactive({
+    drawer: false,
+    drawerTiti: '',
+    initParam: {
+        T_service_type_id: '',
+        T_sale_type: '',
+        T_name: '',
+        T_model: '',
+        T_spec: '',
+    },
+    options: [],
+    optionsType: [{T_name:'/'},{T_name:'软件'},{T_name:'硬件'}]
+})
+
+
+const getServiceList = async ()=>{
+    const result:any =await ServiceType_List_Post({page: 1,page_z: 9999,})
+    if(result.Code==200){
+        data.options = result.Data.Data || []
+    }
+}
+const rules:any = reactive({
+    T_service_type_id:[
+        { required: true, message: '请选择服务类型', trigger: 'change' }
+    ],
+    T_name: [
+        { required: true, message: '请填写服务内容', trigger: 'change' }
+    ]
+    
+})
+const submitForm = async (formEl: FormInstance | undefined) => {
+    if (!formEl) return
+    await formEl.validate((valid, fields) => {
+        if (valid) {
+            console.log('确定')
+            if (valid) data.drawerTiti == '编辑' ? ServiceItemEditApi() : ServiceItemAddApi()
+        }
+    })
+}
+/**
+ * 新增
+ */
+ const  ServiceItemAddApi = async () => {
+    const result: any = await ServiceItem_Add_Post(data.initParam)
+    if (result.Code == 200) {
+        TableRef.value?.getTableList()
+        data.drawer = false
+        ElMessage.success('添加成功')
+    }
+}
+/**
+ * 编辑
+ */
+const  ServiceItemEditApi = async () => {
+    const result: any = await ServiceItem_Edit_Post(data.initParam)
+    if (result.Code == 200) {
+        TableRef.value?.getTableList()
+        data.drawer = false
+        ElMessage.success('编辑成功')
+    }
+}
+
+
+const tableRowClassNameHandle = (data: any): any => { }
+
+const openDrawer = async (tit:string, row:any) => {
+    getServiceList()
+    data.drawerTiti = tit
+    data.drawer = true
+    
+    for (let key in row) {  
+        if (data.initParam.hasOwnProperty(key)) {  
+            data.initParam[key] = row[key];  
+        }  
+    } 
+    data.initParam.T_id = row.Id
+ }
+const UserDelete = async (row: any) => {
+    let {Id} = row
+    ElMessageBox.confirm('删除服务内容,是否确认删除?', 'Warning',
+        {
+            confirmButtonText: '立即删除',
+            cancelButtonText: '取消',
+            type: 'warning',
+            center: true,
+        }).then(() => {
+            ServiceTypeDelApi({T_id:Id})
+        }).catch(() => {})
+}
+/**
+ * 删除
+ */
+const ServiceTypeDelApi = async (obj:any) => {
+    const result:any = await ServiceItem_Del_Post(obj)
+    if (result.Code == 200) {
+        TableRef.value?.getTableList()
+        ElMessage.success('删除成功')
+    }
+}
+
+// 搜索以及参数
+const columns: ColumnProps[] = [
+    { prop: 'ServiceType.T_name', label: '服务类型' },
+    { prop: 'T_sale_type', label: '销售类型' },
+    { prop: 'T_name', label: '服务内容' },
+    { prop: 'T_model', label: '型号' },
+    { prop: 'T_spec', label: '规格' },
+    { prop: 'operation', label: '操作', fixed: 'right' }
+]
+const TableRef = ref()
+const getDataFn = async () => {
+    TableRef.value?.getTableList()
+}
+defineExpose({
+    getDataFn, data,getServiceList
+})
+</script>
+<style scoped lang="scss">
+.newMingxi {
+    display: flex;
+    align-items: center;
+    border-bottom: 1px solid #409EFC;
+    cursor: pointer;
+    line-height: 0;
+    padding: 10px 0 2px 0;
+    color: #409EFC;
+    user-select: none;
+}
+
+// 上传图片框样式
+.el-upload--picture-card {
+    border: 1px dashed #13C3C7;
+}
+
+.el-upload--picture-card:hover {
+    border-color: #13C3C7;
+    color: #13C3C7;
+}
+
+.el-upload--picture-card {
+    width: 50px;
+    height: 50px;
+    font-size: 16px !important;
+}
+
+.el-upload {
+    width: 50px;
+    height: 50px;
+    line-height: 50px;
+    font-size: 16px;
+}
+
+.el-upload-list--picture-card .el-upload-list__item {
+    width: 50px;
+    height: 50px;
+    line-height: 50px;
+    font-size: 16px;
+}
+
+.el-upload-list--picture-card .el-upload-list__item-actions:hover {
+    opacity: 1;
+    font-size: 16px;
+}
+
+.el-upload-list--picture-card .el-upload-list__item-thumbnail {
+    width: 50px;
+    height: 50px;
+    line-height: 50px;
+    font-size: 16px;
+}
+
+.avatar {
+    width: 50px;
+    height: 50px;
+}
+</style>

+ 1 - 0
src/views/home/Home.vue

@@ -5,6 +5,7 @@ import { useRouter } from 'vue-router'
 import { GlobalStore } from '@/stores/index'
 import type { TabsPaneContext } from 'element-plus'
 import { User_News_See } from '@/api/user/index'
+import { icons } from '@/utils/common'
 
 interface NoticeType {
   CreateTime: string

+ 34 - 1
src/views/storehouse/inventory/InStorage.vue

@@ -1,7 +1,8 @@
 <script setup lang="ts">
 import { useRouter } from 'vue-router'
 import { GlobalStore } from '@/stores/index'
-import { View } from '@element-plus/icons-vue'
+import { View,Edit,Delete } from '@element-plus/icons-vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
 import InStorageForm from './InStorageForm.vue'
 import { ref, reactive } from 'vue'
 import TableBase from '@/components/TableBase/index.vue'
@@ -50,6 +51,35 @@ const searchHandle = () => {
  */
 const openInStorageFormDrawer = () => InStorageFormRef.value?.openDrawer()
 
+/**
+ * 删除
+ */
+const deleteFun = async (row:any)=>{
+    ElMessageBox.confirm(
+    'proxy will permanently delete the file. Continue?',
+    'Warning',
+    {
+      confirmButtonText: 'OK',
+      cancelButtonText: 'Cancel',
+      type: 'warning',
+      center: true,
+    }
+  )
+    .then(() => {
+      ElMessage({
+        type: 'success',
+        message: 'Delete completed',
+      })
+    })
+    .catch(() => {
+      ElMessage({
+        type: 'info',
+        message: 'Delete canceled',
+      })
+    })
+}
+
+
 // 拿到仓库列表
 const { options } = depotHooks()
 </script>
@@ -87,6 +117,9 @@ const { options } = depotHooks()
       </template>
       <template #right="{ row }">
         <el-button link type="success" size="small" :icon="View" @click="preview(row.T_number)">详情</el-button>
+        <el-button link type="success" size="small" :icon="Edit" @click="preview(row.T_number)">编辑</el-button>
+        <el-button link type="danger" size="small" :icon="Delete" @click="deleteFun(row.T_number)">删除</el-button>
+
       </template>
     </TableBase>
     <InStorageForm ref="InStorageFormRef" :options="options" @onUpdateList="searchHandle" />

+ 265 - 307
src/views/workAttendance/MyOvertime.vue

@@ -1,13 +1,13 @@
 <script setup lang="ts">
 import {
-  Overtime_User_list,
-  Overtime_Stat,
-  Overtime_Add,
-  Overtime_Del,
-  Overtime_Edit
+    Overtime_User_list,
+    Overtime_Stat,
+    Overtime_Add,
+    Overtime_Del,
+    Overtime_Edit
 } from '@/api/workAttendance/index'
 import { User_List } from '@/api/user/index'
-import Upload from '@/components/Upload/index.vue'
+import Upload from './Upload/index.vue'
 import Drawer from '@/components/Drawer/index.vue'
 import Dialog from '@/components/dialog/Dialog.vue'
 import { floatReg } from '@/views/salary/salary/relus'
@@ -20,6 +20,8 @@ import type { FormInstance, FormRules } from 'element-plus'
 import { Edit, Delete, View, Plus } from '@element-plus/icons-vue'
 import { ColumnProps } from '@/components/TableBase/interface/index'
 
+
+let showWatch = ref(true)
 let isNew = ref(true)
 const search = ref('')
 const TableStatRef = ref()
@@ -34,368 +36,324 @@ const uploadRef = ref<InstanceType<typeof Upload> | null>(null)
 const { resetForm, globalStore, updateOnTableList } = useTablePublic()
 
 const columns: ColumnProps[] = [
-  { prop: 'T_start_time', label: '开始时间', ellipsis: true },
-  { prop: 'T_end_time', label: '结束时间', ellipsis: true },
-  { prop: 'T_duration', label: '时长', width: '100px', name: 'T_duration' },
-  { prop: 'T_State', label: '审核', width: '100px', name: 'T_State' },
-  { prop: 'operation', label: '操作', width: 200, fixed: 'right' }
+    { prop: 'T_start_time', label: '开始时间', ellipsis: true },
+    { prop: 'T_end_time', label: '结束时间', ellipsis: true },
+    { prop: 'T_duration', label: '时长', width: '100px', name: 'T_duration' },
+    { prop: 'T_State', label: '审核', width: '100px', name: 'T_State' },
+    { prop: 'operation', label: '操作', width: 200, fixed: 'right' }
 ]
 const columns_Stat: ColumnProps[] = [
-  { prop: 'T_duration', label: '时长', width: '100px', name: 'T_duration' },
-  { prop: 'RemainingTime', label: '剩余时长', width: '100px', name: 'RemainingTime' },
-  { prop: 'T_type_name', label: '事项' },
-  { prop: 'T_approver_name', label: '处理人' },
-  { prop: 'UpdateTime', label: '时间', ellipsis: true }
+    { prop: 'T_duration', label: '时长', width: '100px', name: 'T_duration' },
+    { prop: 'RemainingTime', label: '剩余时长', width: '100px', name: 'RemainingTime' },
+    { prop: 'T_type_name', label: '事项' },
+    { prop: 'T_approver_name', label: '处理人' },
+    { prop: 'UpdateTime', label: '时间', ellipsis: true }
 ]
-
-const form = ref({
-  uuid: '',
-  T_id: '',
-  T_text: '',
-  T_duration: 0,
-  T_end_time: '',
-  T_approver: '',
-  T_prove_img: '',
-  T_start_time: ''
+const fileListImg: any = ref([])
+const form:any = ref({
+    uuid: '',
+    T_id: '',
+    T_text: '',
+    T_duration: 0,
+    T_end_time: '',
+    T_approver: '',
+    T_prove_img: '',
+    T_start_time: ''
 })
 const validate_float = (rule: any, value: any, callback: any) => {
-  if (value === '') {
-    callback(new Error('请输入加班时长'))
-  } else {
-    if (floatReg.test(value) || /\d+/.test(value)) {
-      callback()
+    if (value === '') {
+        callback(new Error('请输入加班时长'))
     } else {
-      callback(new Error('时间必须是数字或小数'))
+        if (floatReg.test(value) || /\d+/.test(value)) {
+            callback()
+        } else {
+            callback(new Error('时间必须是数字或小数'))
+        }
     }
-  }
 }
 const rules = reactive<FormRules>({
-  T_type: [{ required: true, message: '请选择请假类型', trigger: 'blur' }],
-  T_start_time: [{ required: true, message: '请选择开始时间', trigger: 'blur' }],
-  T_end_time: [{ required: true, message: '请选择结束时间', trigger: 'blur' }],
-  T_duration: [{ required: true, validator: validate_float, trigger: 'blur' }],
-  T_approver: [{ required: true, message: '请选择审批人', trigger: 'blur' }]
+    T_type: [{ required: true, message: '请选择请假类型', trigger: 'blur' }],
+    T_start_time: [{ required: true, message: '请选择开始时间', trigger: 'blur' }],
+    T_end_time: [{ required: true, message: '请选择结束时间', trigger: 'blur' }],
+    T_duration: [{ required: true, validator: validate_float, trigger: 'blur' }],
+    T_approver: [{ required: true, message: '请选择审批人', trigger: 'blur' }]
 })
 
 const openDrawerOvertime = (str: string, row?: any) => {
-  isNew.value = str === 'new' ? true : false
+    isNew.value = str === 'new' ? true : false
+    showWatch.value = str == 'new' ? true : false
+    if (!isNew.value) {
+        nextTick(() => {
+            form.value = { ...row }
+            form.value.uuid = row.T_approver
+            form.value.T_approver = row.T_approver_name
+            form.value.T_id = row.Id
+            form.value.T_duration = row.T_duration / 60
+            fileListImg.value = row.T_prove_img.split('|')
+        })
+    }else{
+        fileListImg.value = []
+    }
+    drawerRef.value && drawerRef.value.openDrawer()
+    
 
-  if (!isNew.value) {
-    nextTick(() => {
-      form.value = { ...row }
-      form.value.uuid = row.T_approver
-      form.value.T_approver = row.T_approver_name
-      form.value.T_id = row.Id
-      form.value.T_duration = row.T_duration / 60
-    })
-  }
 
-  drawerRef.value && drawerRef.value.openDrawer()
 }
 
 const OvertimeView = (row: any) => {
-  disabled.value = true
-  drawerRef.value && drawerRef.value.openDrawer()
-  nextTick(() => {
-    form.value = { ...row }
-    form.value.T_approver = row.T_approver_name
-  })
+    showWatch.value = false
+    disabled.value = true
+    drawerRef.value && drawerRef.value.openDrawer()
+    nextTick(() => {
+        fileListImg.value = row.T_prove_img.split('|')
+        form.value = { ...row }
+        form.value.T_approver = row.T_approver_name
+    })
 }
 const OvertimeDelete = (row: any) => {
-  ElMessageBox.confirm('您确定要删除加班申请吗?', '警告', {
-    confirmButtonText: '确定',
-    cancelButtonText: '取消',
-    type: 'warning'
-  })
-    .then(async () => {
-      const res: any = await Overtime_Del({ User_tokey: globalStore.GET_User_tokey, T_id: row.Id })
-      if (res.Code === 200) {
-        ElMessage.success('删除成功!')
-        nextTick(() => updateOnTableList(TableRef.value))
-      }
-    })
-    .catch(() => {
-      ElMessage.warning('取消成功!')
+    ElMessageBox.confirm('您确定要删除加班申请吗?', '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
     })
+        .then(async () => {
+            const res: any = await Overtime_Del({ User_tokey: globalStore.GET_User_tokey, T_id: row.Id })
+            if (res.Code === 200) {
+                ElMessage.success('删除成功!')
+                nextTick(() => updateOnTableList(TableRef.value))
+            }
+        })
+        .catch(() => {
+            ElMessage.warning('取消成功!')
+        })
 }
 const AddOvertime = (formEl: FormInstance | undefined) => {
-  if (!formEl) return
-  formEl.validate(async valid => {
-    if (valid) {
-      let res: any = {}
-      let time = duration.value * 60 + minutes.value
-      console.log('提交minutes',duration.value,minutes.value,time)
-      if(time<0){ElMessage.error('时间选择错误,请重新选择');return}
-      if (isNew.value) {
-        res = await Overtime_Add({ ...form.value, T_approver: form.value.uuid, T_duration: time })
-      } else {
-        res = await Overtime_Edit({ ...form.value, T_approver: form.value.uuid, T_duration: time })
-      }
-      if (res.Code === 200) {
-        ElMessage.success(`${isNew.value ? '申请' : '修改'}成功!`)
-        nextTick(() => {
-          drawerRef.value?.closeDrawer()
-          updateOnTableList(TableRef.value)
-          resetForm(ruleFormRef.value)
-          uploadRef.value?.clearfileList()
-          isNew.value = true
-        })
-      }
-    } else {
-      return false
-    }
-  })
+    if (!formEl) return
+    formEl.validate(async valid => {
+        if (valid) {
+            if (fileListImg.value.length < 3) {
+                ElMessage.error(`取证图片至少3张以上`)
+                return
+            }
+            let mapImg = [...fileListImg.value]
+            form.value.T_prove_img = mapImg.join('|')
+            let res: any = {}
+            let time = duration.value * 60 + minutes.value
+            console.log('提交minutes', duration.value, minutes.value, time)
+            if (time < 0) { ElMessage.error('时间选择错误,请重新选择'); return }
+            if (isNew.value) {
+                res = await Overtime_Add({ ...form.value, T_approver: form.value.uuid, T_duration: time })
+            } else {
+                res = await Overtime_Edit({ ...form.value, T_approver: form.value.uuid, T_duration: time })
+            }
+            if (res.Code === 200) {
+                ElMessage.success(`${isNew.value ? '申请' : '修改'}成功!`)
+                nextTick(() => {
+                    drawerRef.value?.closeDrawer()
+                    updateOnTableList(TableRef.value)
+                    resetForm(ruleFormRef.value)
+                    uploadRef.value?.clearfileList()
+                    isNew.value = true
+                })
+            }
+        } else {
+            return false
+        }
+    })
 }
 
 // Drawer
 const callbackDrawer = (done: () => void) => {
-  disabled.value = false
-  isNew.value = true
-  nextTick(() => {
-    resetForm(ruleFormRef.value)
-    uploadRef.value?.clearfileList()
-    done()
-  })
+    disabled.value = false
+    isNew.value = true
+    nextTick(() => {
+        resetForm(ruleFormRef.value)
+        uploadRef.value?.clearfileList()
+        done()
+    })
 }
 
 // dialog
 const Dialogcolumns: ColumnProps[] = [{ prop: 'T_name', label: '名字', name: 'T_name' }]
 const approverInitParam = {
-  User_tokey: globalStore.GET_User_tokey,
-  T_name: '',
-  T_dept_leader: 1
+    User_tokey: globalStore.GET_User_tokey,
+    T_name: '',
+    T_dept_leader: 1
 }
 const searchHandle = () => {
-  approverInitParam.T_name = search.value
-  tableApproverRef.value.searchTable()
+    approverInitParam.T_name = search.value
+    tableApproverRef.value.searchTable()
 }
 const selectApprover = () => {
-  dialog.value?.DialogOpen()
+    dialog.value?.DialogOpen()
 }
 const getApproverInfo = (row: any) => {
-  form.value.uuid = row.T_uuid
-  form.value.T_approver = row.T_name
-  dialog.value?.DialogClose()
+    form.value.uuid = row.T_uuid
+    form.value.T_approver = row.T_name
+    dialog.value?.DialogClose()
 }
 
 
 const duration = computed(() => {
-  if (!form.value.T_start_time || !form.value.T_end_time) { return 0 }
-  let strTime = form.value.T_start_time
-  let endTime = form.value.T_end_time
-  var endDate:any = new Date(strTime) //开始时间 
-  var nowDate:any = new Date(endTime) //结束时间 
-  let h:any = (nowDate - endDate) / (60 * 60 * 1000)
-  return parseInt(h) //获取小时部分 
+    if (!form.value.T_start_time || !form.value.T_end_time) { return 0 }
+    let strTime = form.value.T_start_time
+    let endTime = form.value.T_end_time
+    var endDate: any = new Date(strTime) //开始时间 
+    var nowDate: any = new Date(endTime) //结束时间 
+    let h: any = (nowDate - endDate) / (60 * 60 * 1000)
+    return parseInt(h) //获取小时部分 
 })
 const minutes = computed(() => {
-  if (!form.value.T_start_time || !form.value.T_end_time) {return 0}
-  let strTime = form.value.T_start_time
-  let endTime = form.value.T_end_time
-  var endDate:any = new Date(strTime) //开始时间 
-  var nowDate:any = new Date(endTime) //结束时间 
-  let m:any = (nowDate - endDate) % (60 * 60 * 1000) / (60 * 1000); //获取分钟部分
-  return parseInt(m)
+    if (!form.value.T_start_time || !form.value.T_end_time) { return 0 }
+    let strTime = form.value.T_start_time
+    let endTime = form.value.T_end_time
+    var endDate: any = new Date(strTime) //开始时间 
+    var nowDate: any = new Date(endTime) //结束时间 
+    let m: any = (nowDate - endDate) % (60 * 60 * 1000) / (60 * 1000); //获取分钟部分
+    return parseInt(m)
 })
 </script>
 
 <template>
-  <el-row :gutter="24" class="h-100">
-    <el-col :span="12" class="padding-right-0 h-100 my-overtime-table-left">
-      <TableBase
-        ref="TableRef"
-        :columns="columns"
-        :requestApi="Overtime_User_list"
-        :initParam="{ User_tokey: globalStore.GET_User_tokey }"
-        layout="total,sizes,prev, pager, next"
-      >
-        <template #table-header>
-          <div class="table-header">
-            <h4>我的加班</h4>
-            <el-button type="primary" @click="openDrawerOvertime('new')">申请加班</el-button>
-          </div>
-        </template>
-        <template #T_duration="{ row }"> {{ getFormatDuration(row.T_duration) }} </template>
-        <template #T_State="{ row }">
-          <el-tag v-if="row.T_State === 1" type="success">通过</el-tag>
-          <el-tag v-else-if="row.T_State === 2" type="warning">未通过</el-tag>
-          <el-tag v-else type="danger">待审核</el-tag>
-        </template>
-        <template #right="{ row }">
-          <el-button
-            :disabled="row.T_State === 1"
-            link
-            type="primary"
-            size="small"
-            :icon="Edit"
-            @click="openDrawerOvertime('edit', row)"
-            >编辑</el-button
-          >
-          <el-button
-            :disabled="row.T_State === 1"
-            link
-            type="danger"
-            size="small"
-            :icon="Delete"
-            @click="OvertimeDelete(row)"
-            >删除</el-button
-          >
-          <el-button link type="success" size="small" :icon="View" @click="OvertimeView(row)">查看</el-button>
-        </template>
-      </TableBase></el-col
-    >
-    <el-col :span="12" class="h-100 my-overtime-table-right" style="overflow: hidden">
-      <TableBase
-        ref="TableStatRef"
-        :columns="columns_Stat"
-        :requestApi="Overtime_Stat"
-        :initParam="{ User_tokey: globalStore.GET_User_tokey }"
-        layout="total,sizes,prev, pager, next"
-      >
-        <template #table-header="{ pageable }">
-          <el-button text
-            ><h4>
-              <el-text class="mx-1" type="primary"
-                >剩余总时长:{{ getFormatDuration(pageable.RemainingTime as number) }}</el-text
-              >
-            </h4></el-button
-          ></template
-        >
-        <template #T_duration="{ row }">{{ getFormatDuration(row.T_duration) }} </template>
-        <template #RemainingTime="{ row }">{{ getFormatDuration(row.RemainingTime) }} </template>
-      </TableBase>
-    </el-col>
-    <Drawer ref="drawerRef" :handleClose="callbackDrawer">
-      <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_start_time">
-          <el-date-picker
-            style="width: 100%"
-            class="my-date-picker"
-            v-model="form.T_start_time"
-            type="datetime"
-            :disabled="disabled"
-            placeholder="选择开始时间"
-            format="YYYY-MM-DD HH:mm"
-            value-format="YYYY-MM-DD HH:mm:ss"
-          />
-        </el-form-item>
-        <el-form-item label="结束时间:" :label-width="formLabelWidth" prop="T_end_time">
-          <el-date-picker
-            style="width: 100%"
-            class="my-date-picker"
-            v-model="form.T_end_time"
-            type="datetime"
-            :disabled="disabled"
-            placeholder="选择结束时间"
-            format="YYYY-MM-DD HH:mm"
-            value-format="YYYY-MM-DD HH:mm:ss"
-          />
-        </el-form-item>
-        <el-form-item label="加班时长:" :label-width="formLabelWidth" prop="T_duration">
-          <template style="display: flex;align-items: center;gap:20px">
-            <el-input v-model="duration" autocomplete="off" placeholder="请假时长">
-            <template #suffix> 小时 </template>
-          </el-input>
-          <el-input v-model="minutes" autocomplete="off" placeholder="请假时长">
-            <template #suffix> 分钟 </template>
-          </el-input>
-          </template>
-        </el-form-item>
-        <el-form-item label="取证:" :label-width="formLabelWidth" prop="T_prove_img">
-          <Upload
-            ref="uploadRef"
-            :isImg="true"
-            :limit="1"
-            v-model="form.T_prove_img"
-            :disabled="disabled"
-            accept="image/*"
-          >
-            <el-icon><Plus /></el-icon>
-          </Upload>
-        </el-form-item>
-        <el-form-item label="内容:" :label-width="formLabelWidth" prop="T_text">
-          <el-input
-            v-model="form.T_text"
-            :disabled="disabled"
-            autocomplete="off"
-            type="textarea"
-            :autosize="{ minRows: 4, maxRows: 6 }"
-            placeholder="请输入内容"
-          />
-        </el-form-item>
-        <el-form-item label="审批:" :label-width="formLabelWidth" prop="T_approver">
-          <el-input
-            :disabled="disabled"
-            v-model="form.T_approver"
-            autocomplete="off"
-            placeholder="审批人"
-            @focus="selectApprover"
-          />
-        </el-form-item>
-        <el-form-item :label-width="formLabelWidth">
-          <el-button v-if="isNew" color="#626aef" @click="AddOvertime(ruleFormRef)" :disabled="disabled"
-            >添加</el-button
-          >
-          <el-button v-else color="#626aef" @click="AddOvertime(ruleFormRef)">修改</el-button>
-        </el-form-item>
-      </el-form>
-    </Drawer>
-    <Dialog ref="dialog" width="30%">
-      <template #header>
-        <h3>选择审批人</h3>
-      </template>
-      <TableBase
-        ref="tableApproverRef"
-        :columns="Dialogcolumns"
-        :initParam="approverInitParam"
-        :requestApi="User_List"
-        layout="total, prev, pager, next"
-      >
-        <template #table-header>
-          <el-row :gutter="20">
-            <el-col :span="20" class="d-flex">
-              <span class="inline-flex">账户查询:</span>
-              <el-input v-model="search" type="text" class="w-50 m-2" />
-              <el-button type="primary" @click="searchHandle">搜索</el-button>
-            </el-col>
-          </el-row>
-        </template>
-        <template #T_name="{ row }">
-          <el-button type="primary" link @click="getApproverInfo(row)">{{ row.T_name }}</el-button>
-        </template>
-      </TableBase>
-    </Dialog>
-  </el-row>
+    <el-row :gutter="24" class="h-100">
+        <el-col :span="12" class="padding-right-0 h-100 my-overtime-table-left">
+            <TableBase ref="TableRef" :columns="columns" :requestApi="Overtime_User_list"
+                :initParam="{ User_tokey: globalStore.GET_User_tokey }" layout="total,sizes,prev, pager, next">
+                <template #table-header>
+                    <div class="table-header">
+                        <h4>我的加班</h4>
+                        <el-button type="primary" @click="openDrawerOvertime('new')">申请加班</el-button>
+                    </div>
+                </template>
+                <template #T_duration="{ row }"> {{ getFormatDuration(row.T_duration) }} </template>
+                <template #T_State="{ row }">
+                    <el-tag v-if="row.T_State === 1" type="success">通过</el-tag>
+                    <el-tag v-else-if="row.T_State === 2" type="warning">未通过</el-tag>
+                    <el-tag v-else type="danger">待审核</el-tag>
+                </template>
+                <template #right="{ row }">
+                    <el-button :disabled="row.T_State === 1" link type="primary" size="small" :icon="Edit"
+                        @click="openDrawerOvertime('edit', row)">编辑</el-button>
+                    <el-button :disabled="row.T_State === 1" link type="danger" size="small" :icon="Delete"
+                        @click="OvertimeDelete(row)">删除</el-button>
+                    <el-button link type="success" size="small" :icon="View" @click="OvertimeView(row)">查看</el-button>
+                </template>
+            </TableBase>
+        </el-col>
+        <el-col :span="12" class="h-100 my-overtime-table-right" style="overflow: hidden">
+            <TableBase ref="TableStatRef" :columns="columns_Stat" :requestApi="Overtime_Stat"
+                :initParam="{ User_tokey: globalStore.GET_User_tokey }" layout="total,sizes,prev, pager, next">
+                <template #table-header="{ pageable }">
+                    <el-button text>
+                        <h4>
+                            <el-text class="mx-1" type="primary">剩余总时长:{{ getFormatDuration(pageable.RemainingTime as number) }}</el-text>
+                        </h4>
+                    </el-button></template>
+                <template #T_duration="{ row }">{{ getFormatDuration(row.T_duration) }} </template>
+                <template #RemainingTime="{ row }">{{ getFormatDuration(row.RemainingTime) }} </template>
+            </TableBase>
+        </el-col>
+        <Drawer ref="drawerRef" :handleClose="callbackDrawer">
+            <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_start_time">
+                    <el-date-picker style="width: 100%" class="my-date-picker" v-model="form.T_start_time"
+                        type="datetime" :disabled="disabled" placeholder="选择开始时间" format="YYYY-MM-DD HH:mm"
+                        value-format="YYYY-MM-DD HH:mm:ss" />
+                </el-form-item>
+                <el-form-item label="结束时间:" :label-width="formLabelWidth" prop="T_end_time">
+                    <el-date-picker style="width: 100%" class="my-date-picker" v-model="form.T_end_time" type="datetime"
+                        :disabled="disabled" placeholder="选择结束时间" format="YYYY-MM-DD HH:mm"
+                        value-format="YYYY-MM-DD HH:mm:ss" />
+                </el-form-item>
+                <el-form-item label="加班时长:" :label-width="formLabelWidth" prop="T_duration">
+                    <template style="display: flex;align-items: center;gap:20px">
+                        <el-input v-model="duration" autocomplete="off" placeholder="请假时长">
+                            <template #suffix> 小时 </template>
+                        </el-input>
+                        <el-input v-model="minutes" autocomplete="off" placeholder="请假时长">
+                            <template #suffix> 分钟 </template>
+                        </el-input>
+                    </template>
+                </el-form-item>
+                <el-form-item label="取证:" :label-width="formLabelWidth" >
+                    <Upload ref="uploadRef" :showWatch="showWatch" :limit="10" v-model:modelValue="fileListImg" :disabled="disabled"
+                        accept="image/*">
+                        <el-icon>
+                            <Plus />
+                        </el-icon>
+                    </Upload>
+                </el-form-item>
+                <el-form-item label="内容:" :label-width="formLabelWidth" prop="T_text">
+                    <el-input v-model="form.T_text" :disabled="disabled" autocomplete="off" type="textarea"
+                        :autosize="{ minRows: 4, maxRows: 6 }" placeholder="请输入内容" />
+                </el-form-item>
+                <el-form-item label="审批:" :label-width="formLabelWidth" prop="T_approver">
+                    <el-input :disabled="disabled" v-model="form.T_approver" autocomplete="off" placeholder="审批人"
+                        @focus="selectApprover" />
+                </el-form-item>
+                <el-form-item :label-width="formLabelWidth">
+                    <el-button v-if="isNew" color="#626aef" @click="AddOvertime(ruleFormRef)"
+                        :disabled="disabled">添加</el-button>
+                    <el-button v-else color="#626aef" @click="AddOvertime(ruleFormRef)">修改</el-button>
+                </el-form-item>
+            </el-form>
+        </Drawer>
+        <Dialog ref="dialog" width="30%">
+            <template #header>
+                <h3>选择审批人</h3>
+            </template>
+            <TableBase ref="tableApproverRef" :columns="Dialogcolumns" :initParam="approverInitParam"
+                :requestApi="User_List" layout="total, prev, pager, next">
+                <template #table-header>
+                    <el-row :gutter="20">
+                        <el-col :span="20" class="d-flex">
+                            <span class="inline-flex">账户查询:</span>
+                            <el-input v-model="search" type="text" class="w-50 m-2" />
+                            <el-button type="primary" @click="searchHandle">搜索</el-button>
+                        </el-col>
+                    </el-row>
+                </template>
+                <template #T_name="{ row }">
+                    <el-button type="primary" link @click="getApproverInfo(row)">{{ row.T_name }}</el-button>
+                </template>
+            </TableBase>
+        </Dialog>
+    </el-row>
 </template>
 
 <style scoped lang="scss">
 @import '@/styles/var.scss';
+
 .my-overtime-table-left,
 .my-overtime-table-right {
-  @include f-direction;
+    @include f-direction;
 }
 
 .table-header {
-  width: 100%;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
 }
+
 .full-img {
-  width: 100%;
-  height: 100%;
+    width: 100%;
+    height: 100%;
 }
+
 .d-flex {
-  display: flex;
-  align-items: center;
-  .inline-flex {
-    white-space: nowrap;
-  }
+    display: flex;
+    align-items: center;
+
+    .inline-flex {
+        white-space: nowrap;
+    }
 }
+
 .mx-1 {
-  letter-spacing: 1px;
+    letter-spacing: 1px;
 }
 </style>

+ 13 - 4
src/views/workAttendance/Overtime.vue

@@ -17,7 +17,7 @@ const columns: ColumnProps[] = [{ prop: 'T_user_name', label: '姓名' }]
 const { tableRowClassName } = useTablePublic()
 const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.Id, userInfo.value.Id)
 
-const userInfo = ref<OvertimeUserInfoIn>({
+const userInfo:any = ref<OvertimeUserInfoIn>({
   T_uid: '',
   T_user_name: '',
   T_dept: '',
@@ -27,7 +27,7 @@ const userInfo = ref<OvertimeUserInfoIn>({
   T_end_time: '',
   T_text: '',
   Id: '',
-  T_prove_img: '',
+  T_prove_img: [],
   T_duration: ''
 })
 
@@ -35,7 +35,10 @@ const getSalaryParams = (row: any) => {
   userInfo.value.Id = ''
   setTimeout(() => {
     userInfo.value = { ...row }
+    let str = { ...row }.T_prove_img.split('|')
+    userInfo.value.T_prove_img = str
   }, 100)
+
 }
 
 const LeaveUser = async (T_State: number) => {
@@ -108,8 +111,13 @@ const LeaveUser = async (T_State: number) => {
             </div>
             <div style="display: flex">
               <span>取证:</span>
-              <ImageCom v-if="userInfo.T_prove_img" :src="userInfo.T_prove_img" />
-              <span v-else>无</span>
+              <div v-if="userInfo.T_prove_img" style="display:flex; flex-wrap: wrap;gap: 10px;">
+                <ImageCom v-for="item,index in userInfo.T_prove_img" :key="index" :src="item" />
+              </div>
+              <template v-else>
+                <span>无</span>
+              </template>
+
             </div>
             <div>
               <span class="ml-3 w-35 text-gray-600 inline-flex items-center">内容:</span>
@@ -135,6 +143,7 @@ const LeaveUser = async (T_State: number) => {
   height: 100%;
   display: flex;
   justify-content: center;
+  flex-wrap: wrap;
   .el-card {
     width: 50%;
     height: 60%;

+ 180 - 0
src/views/workAttendance/Upload/index.vue

@@ -0,0 +1,180 @@
+<script setup lang="ts">
+import { ref, watch } from 'vue'
+import { UpFileToken } from '@/api/public/index'
+import { ElMessage, genFileId, ElLoading } from 'element-plus'
+import { GlobalStore } from '@/stores/index'
+import type { UploadProps, UploadRawFile, UploadFile, UploadFiles } from 'element-plus'
+
+interface FileListType {
+    url?: string
+    name?: string | number
+}
+
+interface ProTableProps {
+    showWatch?: boolean
+    // isImg?: boolean // 是否只能上传图片
+    disabled?: boolean
+    limit: number
+    accept: string
+    modelValue: string | string[]
+    listType?: string
+    errorText?: string
+    successText?: string
+}
+
+const upload = ref()
+const globalStore = GlobalStore()
+const dialogImageUrl = ref('')
+const dialogVisible = ref(false)
+const uploadData = {
+    token: '',
+    key: ''
+}
+let loadingInstance: any = null
+const emit = defineEmits<{ (event: 'update:modelValue', value: string | string[]): void }>()
+
+// 图片查看 放大
+const handlePictureCardPreview = async (file: any) => {
+    dialogImageUrl.value = file.url as string
+    dialogVisible.value = true
+}
+// 图片上传之前
+const beforeUpload = (file: any) => {
+    loadingInstance = ElLoading.service({
+        lock: true,
+        text: 'Loading',
+        background: 'rgba(0, 0, 0, 0.7)'
+    })
+    uploadData.key = file.name
+}
+
+const clickToken = async () => {
+
+    UpFileToken({ User_tokey: globalStore.GET_User_tokey }).then(res => {
+        uploadData.token = res.Data as string
+    })
+
+
+
+}
+// 图片上传超出界限
+const handleExceed: UploadProps['onExceed'] = (files: any) => {
+    upload.value.clearFiles()
+    const file = files[0] as UploadRawFile
+    file.uid = genFileId()
+    upload.value.handleStart(file)
+    upload.value.submit()
+}
+let isWatch = ref(false)
+// 图片上传成功
+const onSuccess = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
+    console.log('上传成功onSuccess1', response,uploadFiles)
+    let ERPOSS = import.meta.env.VITE_BZD_ERPOSS_APP_API
+    let keys:any = []
+    uploadFiles.forEach((item: any,j:number) =>{
+        if(item.response){
+            keys.push(ERPOSS + item.response.key)
+        }else{
+            keys.push(item.url)
+        }
+    })
+    emit('update:modelValue', keys)
+    ElMessage.success(props.successText)
+    loadingInstance.close()
+    isWatch.value = true
+}
+// 图片上传失败
+const onError = () => {
+    ElMessage.error(props.errorText)
+    console.log('onError')
+}
+// 图片移除
+const handleRemove: UploadProps['onRemove'] = (uploadFile: any, uploadFiles: UploadFiles) => {
+    if (limit.value === 1) {
+        emit('update:modelValue', '')
+    } else {
+        let keys = uploadFiles.map((item: any) => {
+            console.log('移除',uploadFile,item)
+            if (item.url !== uploadFile.url) {
+                return item.url
+            }
+        })
+        console.log('keys',keys)
+        emit('update:modelValue', keys)
+    }
+}
+
+// 接受父组件参数,配置默认值
+const props = withDefaults(defineProps<ProTableProps>(), {
+    showWatch: false,
+    disabled: false,
+    listType: 'picture-card',
+    errorText: '图片上传失败!!',
+    successText: '图片上传成功!!'
+})
+
+const fileList = ref<FileListType[]>([])
+
+// const isImg = ref<boolean>(props.isImg)
+const limit = ref<number>(props.limit)
+
+watch(() => props.modelValue, pre => {
+    let arr:any = []
+    if (!props.showWatch && !isWatch.value) {
+        (pre as string[]).forEach((item: any) => {
+            arr.push({
+                url: item,
+                name: genFileId()
+            })
+        })
+        fileList.value = arr
+    }
+})
+
+const clearfileList = () => {
+    fileList.value = []
+}
+defineExpose({
+    clearfileList
+})
+</script>
+
+<template>
+    <div>
+        <el-upload ref="upload" :accept="accept" :disabled="disabled" v-model:file-list="fileList"
+            action="https://up-z2.qiniup.com" :list-type="listType" :limit="limit" :before-upload="beforeUpload"
+            :auto-upload="true" :on-success="onSuccess" :on-error="onError" :on-exceed="handleExceed"
+            :on-remove="handleRemove" :on-preview="handlePictureCardPreview" :data="uploadData" @click="clickToken">
+
+            <!-- <el-upload v-model:file-list="data.fileList" style="width: 50px;height: 50px;" action="https://up-z2.qiniup.com"
+        :disabled="data.drawerTiti == '详情' ? true : false" list-type="picture-card" :on-preview="handlePictureCardPreview"
+        :on-remove="handleRemove">
+        <el-icon>
+          <Plus />
+        </el-icon>
+      </el-upload> -->
+
+            <slot></slot>
+            <template #tip>
+                <div class="el-upload__tip">
+                    <slot name="tip"></slot>
+                </div>
+            </template>
+        </el-upload>
+        <el-dialog v-model="dialogVisible" style="z-index: 10;" :append-to-body="true">
+            <img w-full :src="dialogImageUrl" class="full-img" alt="Preview Image" />
+        </el-dialog>
+    </div>
+</template>
+
+<style scoped>
+.full-img {
+    width: 100%;
+    height: 100%;
+}
+
+.el-upload--picture-card {
+    height: 50px;
+    width: 50px;
+}
+</style>