Bläddra i källkod

add:维修工单管理

zoie 2 månader sedan
förälder
incheckning
0982f793d6
30 ändrade filer med 2698 tillägg och 721 borttagningar
  1. 28 0
      src/api/RepairWorkOrder/index.ts
  2. 1 1
      src/api/apiMapList.ts
  3. 0 5
      src/api/mypercentage/index.ts
  4. 12 3
      src/api/storehouse/index.ts
  5. 26 8
      src/components/TableBase/index.vue
  6. 1 1
      src/hooks/useTable.ts
  7. 2 0
      src/hooks/useTablePublic.ts
  8. 1 0
      src/layouts/Header/index.vue
  9. 0 1
      src/views/Login.vue
  10. 0 8
      src/views/storehouse/ProductionList.vue
  11. 212 0
      src/views/storehouse/RepairWorkOrder/MyRepairWorkOrder.vue
  12. 171 0
      src/views/storehouse/RepairWorkOrder/RepairWorkOrder.vue
  13. 260 0
      src/views/storehouse/RepairWorkOrder/RepairWorkOrderForm.vue
  14. 182 0
      src/views/storehouse/RepairWorkOrder/Upload/index.vue
  15. 187 0
      src/views/storehouse/ValidationTool/modules/snAdd.vue
  16. 140 0
      src/views/storehouse/ValidationTool/statValidation.vue
  17. 589 608
      src/views/storehouse/ValidationTool/validation.vue
  18. 25 11
      src/views/storehouse/inventory/IOTNetworkCard.vue
  19. 8 2
      src/views/storehouse/sales/MyPercentage.vue
  20. 27 57
      src/views/storehouse/sales/MyPercentageForm.vue
  21. 13 4
      src/views/storehouse/sales/Percentage.vue
  22. 0 3
      src/views/storehouse/sales/PercentageDetail1.vue
  23. 83 0
      src/views/storehouse/sales/SelectVerifyCompany.vue
  24. 17 1
      src/views/storehouse/sales/VerifyCompany.vue
  25. 185 0
      src/views/storehouse/verifyCompany/MyVerifyPercentage.vue
  26. 4 4
      src/views/storehouse/verifyCompany/Recoveries.vue
  27. 3 3
      src/views/storehouse/verifyCompany/VerifyContract.vue
  28. 251 0
      src/views/storehouse/verifyCompany/VerifyPercentage.vue
  29. 269 0
      src/views/storehouse/verifyCompany/VerifyProductionList.vue
  30. 1 1
      src/views/storehouse/verifyItem.vue

+ 28 - 0
src/api/RepairWorkOrder/index.ts

@@ -0,0 +1,28 @@
+import $http from '../index'
+// 列表 === 维修工单
+export const RepairWorkOrder_List = (params: any) => $http.post('/storage/RepairWorkOrder/List', params)
+
+// 用户列表
+export const RepairWorkOrder_User_List = (params: any) => $http.post('/storage/RepairWorkOrder/User_List', params)
+
+// 下发工单
+export const RepairWorkOrder_Add = (params: any) => $http.post('/storage/RepairWorkOrder/Add', params)
+
+// 修改工单
+export const RepairWorkOrder_Edit = (params: any) => $http.post('/storage/RepairWorkOrder/Edit', params)
+
+// 删除维修工单
+export const RepairWorkOrder_Del = (params: any) => $http.post('/storage/RepairWorkOrder/Del', params)
+
+// 归还
+export const RepairWorkOrder_Return = (params: any) => $http.post('/storage/RepairWorkOrder/Return', params)
+
+// 转派
+export const RepairWorkOrder_Redeploy = (params: any) => $http.post('/storage/RepairWorkOrder/Redeploy', params)
+
+// 开始维修
+export const RepairWorkOrder_Start_Repair = (params: any) => $http.post('/storage/RepairWorkOrder/Start_Repair', params)
+
+// 完结
+export const RepairWorkOrder_Finish = (params: any) => $http.post('/storage/RepairWorkOrder/Finish', params)
+

+ 1 - 1
src/api/apiMapList.ts

@@ -1 +1 @@
-export const mapList = ["/salary/Reimburse/Add","/salary/Reimburse/Edit","/storage/validationTool/add","/storage/validationTool/update"]
+export const mapList = ["/salary/Reimburse/Add","/salary/Reimburse/Edit","/storage/validationTool/add","/storage/validationTool/update","/storage/validationTool/scrap","/storage/validationTool/repair"]

+ 0 - 5
src/api/mypercentage/index.ts

@@ -2,13 +2,8 @@ import $http from '../index'
 
 // 提成管理-列表
 export const percentage_UserList = (params: any) => $http.post('/storage/Percentage/User_List', params)
-// 员工-列表
-export const percentage_User_List = (params: any) => $http.post('/storage/Percentage/User/List', params)
-
 
 export const Verifyltem_List = (params: any) => $http.post('/storage/VerifyItem/List', params)
-export const VerifyContract_List = (params: any) => $http.post('/storage/VerifyContract/List', params)
-
 
 // 员工-详情
 export const percentage_Get = (params: any) => $http.post('/storage/Percentage/Get', params)

+ 12 - 3
src/api/storehouse/index.ts

@@ -107,6 +107,9 @@ export const Storehouse_Contract_Product_List = (params: any) =>
   $http.post('/storage/Contract/Product_List', params)
 // 获取为出库或为完全出库合同列表
 export const Storehouse_Contract_Out_List = (params: any) => $http.post('/storage/Contract/Out_List', params)
+// 打款
+export const Storehouse_Contract_Percentage_Remit = (params: any) => $http.post('/storage/Contract/Percentage_Remit', params)
+
 
 /**
  * 库存管理
@@ -114,14 +117,18 @@ export const Storehouse_Contract_Out_List = (params: any) => $http.post('/storag
 // 设备列表
 export const Storehouse_Device_List = (params: any) => $http.post('/storage/Device/List', params)
 export const validation_List = (params: any) => $http.post('/storage/validationTool/list', params)
-export const validation_add = (params: any) => $http.post('/storage/validationTool/add', params, { headers: { 'Content-Type': 'application/json' } })  //借出验证工具
+export const validation_Stat = (params: any) => $http.post('/storage/validationTool/stat', params)
+export const validation_add = (params: any) => $http.post('/storage/validationTool/add', params)  //借出验证工具
 export const validation_del = (params: any) => $http.post('/storage/validationTool/del', params,)
 export const validation_update = (params: any) => $http.post('/storage/validationTool/update', params,)  //借出验证工具
+export const validation_scrap= (params: any) => $http.post('/storage/validationTool/scrap', params)  //报废验证工具
+export const validation_repair= (params: any) => $http.post('/storage/validationTool/repair', params)  //维修验证工具
 export const readValidation = (params: any) => $http.post('/storage/validationTool/readValidation', params,)
 export const updateValidation = (params: any) => $http.post('/storage/validationTool/updateValidation', params,)
 export const uploadFile = (params: any) => $http.post('/storage/validationTool/ImportExcel', params,)
 export const exportFile = (params: any) => $http.post('/storage/validationTool/exportExcel', params, { responseType: 'blob' })
-
+// 左侧用户列表
+export const validation_User_List = (params: any) => $http.post('/storage/validationTool/user/list', params)
 export const validationTool_class_list = (params: any) => $http.post('/storage/validationTool/class/list', params)
 
 /**
@@ -203,7 +210,9 @@ export const Storehouse_VerifyContract_Del = (params: any) => $http.post('/stora
 //回款列表
 export const Storehouse_VerifyContract_Recover_List = (params: any) =>
   $http.post('/storage/RecoveriesContract/List', params)
-
+//导出
+export const Storehouse_VerifyContract_Recover_Export = (params: any) =>
+	$http.post('/storage/RecoveriesContract/Export', params)
 /**
  * 公司回款管理
  */

+ 26 - 8
src/components/TableBase/index.vue

@@ -19,6 +19,7 @@ interface ProTableProps extends Partial<Omit<TableProps<any>, 'data'>> {
   displayHeader?: boolean // 是否隐藏头部
   rowClick?: (row: any, column: any, event: any) => void // 点击行
   selectionChange?: (row: any) => void // 选择函数
+	selectable?: (row: any) => void // 选择函数
   getRowKey?: ((row: any) => string) | string // 用于优化select勾选框
   tableRowClassName?: (data: any) => CSSProperties
 }
@@ -37,6 +38,7 @@ const props = withDefaults(defineProps<ProTableProps>(), {
 
 const multipleTableRef = ref()
 const clearSelection = () => multipleTableRef.value?.clearSelection()
+const toggleRowSelection = () => multipleTableRef.value?.toggleRowSelection()
 // 表格操作 Hooks
 const { tableData, pageable, loading, getTableList, searchTable, handleSizeChange, handleCurrentChange } = useTable(
   props.requestApi,
@@ -53,7 +55,8 @@ onMounted(() => {
 defineExpose({
   getTableList,
   searchTable,
-  clearSelection
+  clearSelection,
+	toggleRowSelection,
 })
 </script>
 
@@ -76,13 +79,28 @@ defineExpose({
       <slot></slot>
       <template v-for="item in tableColumns" :key="item">
         <!-- selection || index -->
-        <el-table-column
-          v-bind="item"
-          :align="item.align ?? 'center'"
-          :reserve-selection="item.type == 'selection'"
-          v-if="item.type == 'selection' || item.type == 'index'"
-          show-overflow-tooltip
-        ></el-table-column>
+		  <el-table-column
+			  v-bind="item"
+			  :align="item.align ?? 'center'"
+			  :reserve-selection="item.type == 'selection'"
+			  v-if="item.type == 'selection'"
+			  :selectable="props.selectable"
+			  show-overflow-tooltip
+		  ></el-table-column>
+		  <el-table-column
+			  v-bind="item"
+			  :align="item.align ?? 'center'"
+			  v-if="item.type == 'index'"
+			  show-overflow-tooltip
+		  ></el-table-column>
+<!--        <el-table-column-->
+<!--          v-bind="item"-->
+<!--          :align="item.align ?? 'center'"-->
+<!--          :reserve-selection="item.type == 'selection'"-->
+<!--		  v-if="item.type == 'selection' || item.type == 'index'"-->
+<!--          show-overflow-tooltip-->
+<!--        ></el-table-column>-->
+
         <!-- expand 支持 tsx 语法 && 作用域插槽 (tsx > slot) -->
         <el-table-column v-bind="item" :align="item.align ?? 'center'" v-if="item.type === 'expand'" v-slot="scope" show-overflow-tooltip>
           <component :is="item.render" :row="scope.row" v-if="item.render"> </component>

+ 1 - 1
src/hooks/useTable.ts

@@ -61,7 +61,7 @@ export const useTable = (
       ...initParam
     }
     const res = await requestApi(params)
-    state.tableData = res.Data?.Data
+    state.tableData = res.Data?.Data || []
     dataCallback && (state.tableData = dataCallback(res))
     state.pageable.total = res.Data?.Num
     if (res.Data?.RemainingTime) {

+ 2 - 0
src/hooks/useTablePublic.ts

@@ -57,6 +57,8 @@ export interface MyPercentageFormType {
   T_device_type: string
   T_verify_type: string
   T_company_uuid: string
+  T_verifyCompany_name: string
+  T_money: any
   T_type: any
 }
 export interface MyPercentageFormTypeFrom {

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

@@ -14,6 +14,7 @@ const globalStore = GlobalStore()
 const router = useRouter()
 const logOut = () => {
   sessionStorage.clear()
+  localStorage.clear()
   globalStore.SET_User_Tokey('')
   globalStore.SET_User_Info({})
   globalStore.SET_Flat_Menu([])

+ 0 - 1
src/views/Login.vue

@@ -126,7 +126,6 @@ const changeType = () => {
             :prefix-icon="Lock"
             autocomplete="off"
             placeholder="请输入密码"
-            @change="submitForm(ruleFormRef)"
           >
             <template #suffix>
               <span class="view">

+ 0 - 8
src/views/storehouse/ProductionList.vue

@@ -63,7 +63,6 @@ const form = ref({
 
 const openDrawer = (type: string, row?: any) => {
   isNew.value = type === 'new' ? true : false
-  !specList.value.length && getSpecList()
   nextTick(() => {
     if (!isNew.value) {
       form.value = { ...row }
@@ -137,12 +136,6 @@ const getProductClassList = async () => {
   const res: any = await Storehouse_ProductClass_List({ page: 1, page_z: 999 })
   options.value = res.Data.Data
 }
-// 获取产品规格
-const specList = ref<any[]>([])
-const getSpecList = async () => {
-  const res: any = await Storehouse_Product_Spec_List({ User_tokey: globalStore.GET_User_tokey })
-  specList.value = res.Data
-}
 const onclickSort = async (row:any)=>{
     ElMessageBox.prompt('请输入排序号', '', {
         confirmButtonText: 'OK',
@@ -156,7 +149,6 @@ const onclickSort = async (row:any)=>{
        }
     }).catch(() => {})
 }
-const inputData = ref()
 
 onMounted(() => {
   getProductClassList()

+ 212 - 0
src/views/storehouse/RepairWorkOrder/MyRepairWorkOrder.vue

@@ -0,0 +1,212 @@
+<script setup lang="ts">
+import {
+	RepairWorkOrder_Finish,
+	RepairWorkOrder_List,
+	RepairWorkOrder_Redeploy, RepairWorkOrder_Start_Repair,
+	RepairWorkOrder_User_List,
+} from '@/api/RepairWorkOrder/index'
+import {nextTick, reactive, ref} from 'vue'
+import Upload from '@/components/Upload/index.vue'
+import Drawer from '@/components/Drawer/index.vue'
+import TableBase from '@/components/TableBase/index.vue'
+import type {FormInstance, FormRules} from 'element-plus'
+import {ElMessage} from 'element-plus'
+import {Check, Edit, Finished, View} from '@element-plus/icons-vue'
+import type {ColumnProps} from '@/components/TableBase/interface/index'
+import {useTablePublic} from '@/hooks/useTablePublic'
+import RepairWorkOrderForm from './RepairWorkOrderForm.vue'
+import ReceiveUser from "@/views/storehouse/outStock/receiveUser.vue";
+const receiveUserdialog = ref<InstanceType<typeof ReceiveUser> | null>(null)
+
+const formLabelWidth = ref('120px')
+const ruleFormRef = ref<FormInstance>()
+const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
+const uploadRef = ref<InstanceType<typeof Upload> | null>(null)
+const {resetForm, globalStore, searchOnTableList, updateOnTableList} = useTablePublic()
+const repairWorkOrderFormRef = ref<InstanceType<typeof RepairWorkOrderForm> | null>(null)
+const redeployVisible = ref(false)
+
+const columns: ColumnProps[] = [
+	{type: 'index', label: '序号', width: 60},
+	{prop: 'T_state', label: '状态', name: 'T_state', width: 100},
+	{prop: 'T_delivery_name', label: '交付人'},
+	{prop: 'T_order_date', label: '下单时间', width: 115},
+	{prop: 'T_repair_date', label: '维修时间', width: 115},
+	{prop: 'T_product', label: '产品名称', width: 110},
+	{prop: 'T_model', label: '型号'},
+	{prop: 'T_repair_num', label: '维修数量', width: 110},
+	{prop: 'T_source', label: '设备来源', width: 110},
+	{prop: 'T_repair_reason', label: '维修原因', width: 110},
+	{prop: 'T_receive_name', label: '接收人'},
+	{prop: 'T_return_name', label: '归还人'},
+	{prop: 'T_return_date', label: '归还时间', width: 110},
+	{prop: 'T_return_product', label: '产品名称(更改类型)', width: 180},
+	{prop: 'T_return_model', label: '型号(更改类型)', width: 130},
+	{prop: 'T_return_num', label: '返回数量', width: 110},
+	{prop: 'T_staging_num', label: '暂存数量 ', width: 110},
+	{prop: 'T_scrap_num', label: '报废数量 ', width: 110},
+	{prop: 'T_malfunction_reason', label: '故障原因 ', width: 110},
+	{prop: 'operation', label: '操作', width: 300, fixed: 'right'}
+]
+
+const options = [
+	{name: '已派发', id: 1},
+	{name: '维修中', id: 2},
+	{name: '已归还', id: 3},
+	{name: '已完结', id: 4},
+]
+
+const redeployRules = reactive<FormRules>({
+	T_receive: [{required: true, message: '请输入转派人', trigger: 'blur'}],
+})
+
+
+const RepairWorkOrderStartRepair = async (row: any) => {
+	const reslut: any = await RepairWorkOrder_Start_Repair({User_tokey: globalStore.GET_User_tokey, T_id: row.Id})
+	if (reslut.Code == 200 && reslut.Msg == 'ok!') {
+		searchOnTableList(TableRef.value)
+		ElMessage.success('提交成功')
+	}
+}
+const selectRedeploy = () => receiveUserdialog.value?.openDrawer()
+const getRedeployInfo = ({ T_uuid, T_name }: { T_uuid: string; T_name: string }) => {
+	redeployform.value.T_receive_name = T_name
+	redeployform.value.T_receive = T_uuid
+}
+
+const redeployform: any = ref({
+	T_id: '',
+	T_receive: '',
+	T_receive_name: '',
+})
+
+const redeploy = async (formEl: FormInstance | undefined) => {
+
+	if (!formEl) return
+	formEl.validate(async (valid: boolean) => {
+		if (valid) {
+			const reslut: any = await RepairWorkOrder_Redeploy({...redeployform.value})
+			if (reslut.Code == 200 && reslut.Msg == 'ok!') {
+				searchOnTableList(TableRef.value)
+				ElMessage.success('提交成功')
+				nextTick(() => {
+					redeployVisible.value = false
+					updateOnTableList(TableRef.value)
+				})
+
+			}
+		}
+	})
+}
+
+const openRedeployDialog =  (row: any) => {
+	redeployform.value.T_id = row.Id
+	redeployVisible.value = true
+}
+
+// 搜索
+const initParam = reactive({
+	User_tokey: globalStore.GET_User_tokey,
+	T_name: '',
+	T_state: ''
+})
+const openRepairWorkOrderFormDrawer = (type: string, row?: any) => repairWorkOrderFormRef.value?.repairWorkOrderFormOpen(type, row)
+
+</script>
+
+<template>
+	<div class="RepairWorkOrder-list">
+		<TableBase ref="TableRef" :columns="columns" :requestApi="RepairWorkOrder_User_List" :initParam="initParam">
+			<template #table-header>
+				<div class="input-suffix">
+					<el-row :gutter="20" style="margin-bottom: 0">
+						<el-col :xl="6" :lg="8" :md="10">
+							<span class="inline-flex items-center">关键字:</span>
+							<el-input
+								v-model="initParam.T_name"
+								type="text"
+								class="w-50 m-2"
+								placeholder="按产品名称、产品型号搜索"
+								@change="searchOnTableList(TableRef)"
+							/>
+						</el-col>
+						<el-col :xl="10" :md="12">
+							<span class="inline-flex items-center">状态:</span>
+							<el-select v-model="initParam.T_state" class="w-50 m-2" clearable placeholder="请选择分类~">
+								<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id"/>
+							</el-select>
+							<el-button type="primary" @click="searchOnTableList(TableRef)">搜索</el-button>
+						</el-col>
+					</el-row>
+				</div>
+			</template>
+			<template #T_state="{ row }">
+				<el-tag v-if="row.T_state === 1" type="info" effect="dark"> 已派发</el-tag>
+				<el-tag v-if="row.T_state === 2" type="warning" effect="dark"> 维修中</el-tag>
+				<el-tag v-if="row.T_state === 3" type="primary" effect="dark"> 已归还</el-tag>
+				<el-tag v-if="row.T_state === 4" type="success" effect="dark"> 已完结</el-tag>
+			</template>
+			<template #right="{ row }">
+				<el-button link type="primary" size="small" :icon="View"
+						   @click="openRepairWorkOrderFormDrawer('view', row)">详情
+				</el-button>
+				<el-button link type="warning" size="small" :icon="Finished" @click="openRedeployDialog(row)">转派
+				</el-button>
+				<el-button link type="primary" size="small" :icon="Check" @click="RepairWorkOrderStartRepair(row)">
+					开始维修
+				</el-button>
+				<el-button link type="success" size="small" :icon="Edit"
+						   @click="openRepairWorkOrderFormDrawer('return', row)">归还
+				</el-button>
+			</template>
+		</TableBase>
+		<RepairWorkOrderForm ref="repairWorkOrderFormRef" projectName="repairWorkOrder"
+							 @onTableList="updateOnTableList(TableRef)"/>
+		<el-dialog v-model="redeployVisible" title="转派" draggable :destroy-on-close=true>
+			<el-form ref="ruleFormRef" :model="redeployform" :rules="redeployRules">
+				<el-form-item label="转派人:" class="m-b-6" :label-width="formLabelWidth"
+							  prop="T_receive_name">
+					<el-input v-model="redeployform.T_receive_name" placeholder="请选择转派人" class="w-50"
+							  @focus="selectRedeploy"/>
+				</el-form-item>
+				<el-form-item :label-width="formLabelWidth">
+					<el-button color="#626aef" @click="redeploy(ruleFormRef)">提交</el-button>
+				</el-form-item>
+			</el-form>
+			<ReceiveUser ref="receiveUserdialog" :dept_leader="0" @onUserInfo="getRedeployInfo"
+						 title="选择转派人"/>
+		</el-dialog>
+
+	</div>
+</template>
+
+<style scoped lang="scss">
+@import '@/styles/var.scss';
+
+.tooltip-content {
+	max-width: 500px;
+	overflow-y: auto;
+}
+
+.RepairWorkOrder-list {
+	@include f-direction;
+
+	.input-suffix {
+		width: 100%;
+
+		.inline-flex {
+			white-space: nowrap;
+		}
+
+		.btn {
+			display: flex;
+			justify-content: end;
+		}
+
+		.w-50 {
+			width: 12.5rem;
+		}
+	}
+}
+</style>

+ 171 - 0
src/views/storehouse/RepairWorkOrder/RepairWorkOrder.vue

@@ -0,0 +1,171 @@
+<script setup lang="ts">
+import {
+	RepairWorkOrder_List,
+	RepairWorkOrder_Add,
+	RepairWorkOrder_Edit,
+	RepairWorkOrder_Del, RepairWorkOrder_Finish,
+} from '@/api/RepairWorkOrder/index'
+import { ref, reactive, nextTick } from 'vue'
+import Upload from '@/components/Upload/index.vue'
+import Drawer from '@/components/Drawer/index.vue'
+import TableBase from '@/components/TableBase/index.vue'
+import { ElMessageBox, ElMessage } from 'element-plus'
+import type { FormInstance, FormRules } from 'element-plus'
+import {Edit, Delete, Plus, View, Check, Finished} from '@element-plus/icons-vue'
+import type { ColumnProps } from '@/components/TableBase/interface/index'
+import ImageCom from '@/components/Image/index.vue'
+import RepairWorkOrderForm from './RepairWorkOrderForm.vue'
+import { useTablePublic,options3 } from '@/hooks/useTablePublic'
+import {Project_Approval} from "@/api/project";
+import {percentage_Remit} from "@/api/mypercentage";
+
+
+const isNew = ref(true)
+const formLabelWidth = ref('100px')
+const ruleFormRef = ref<FormInstance>()
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
+const uploadRef = ref<InstanceType<typeof Upload> | null>(null)
+const repairWorkOrderFormRef = ref<InstanceType<typeof RepairWorkOrderForm> | null>(null)
+const { resetForm, globalStore, searchOnTableList, updateOnTableList } = useTablePublic()
+
+const columns: ColumnProps[] = [
+  { type: 'index', label: '序号', width: 60 },
+  { prop: 'T_state', label: '状态' , name: 'T_state', width: 100 },
+  { prop: 'T_delivery_name', label: '交付人' },
+  { prop: 'T_order_date', label: '下单时间', width: 115},
+  { prop: 'T_repair_date', label: '维修时间' , width: 115},
+  { prop: 'T_product', label: '产品名称', width: 110 },
+  { prop: 'T_model', label: '型号' },
+  { prop: 'T_repair_num', label: '维修数量' , width: 110 },
+  { prop: 'T_source', label: '设备来源' , width: 110 },
+  { prop: 'T_repair_reason', label: '维修原因', width: 110  },
+  { prop: 'T_receive_name', label: '接收人' },
+  { prop: 'T_return_name', label: '归还人' },
+  { prop: 'T_return_date', label: '归还时间', width: 110  },
+  { prop: 'T_return_product', label: '产品名称(更改类型)' , width: 180 },
+  { prop: 'T_return_model', label: '型号(更改类型)' , width: 130 },
+  { prop: 'T_return_num', label: '返回数量' , width: 110 },
+  { prop: 'T_staging_num', label: '暂存数量 ' , width: 110 },
+  { prop: 'T_scrap_num', label: '报废数量 ', width: 110  },
+  { prop: 'T_malfunction_reason', label: '故障原因 ' , width: 110 },
+  { prop: 'operation', label: '操作', width: 250, fixed: 'right' }
+]
+
+const options = [
+	{ name: '已派发', id: 1 },
+	{ name: '维修中', id: 2 },
+	{ name: '已归还', id: 3 },
+	{ name: '已完结', id: 4 },
+]
+
+
+const RepairWorkOrderDelete = (row: any) => {
+  ElMessageBox.confirm('您确定要删除该维修工单吗?', '警告', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning'
+  })
+    .then(async () => {
+      const res: any = await RepairWorkOrder_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 RepairWorkOrderFinish = async (row: any) => {
+	const reslut: any = await RepairWorkOrder_Finish({ User_tokey: globalStore.GET_User_tokey,T_id: row.Id})
+	console.log('打款', reslut, row)
+	if (reslut.Code == 200 && reslut.Msg == 'ok!') {
+		searchOnTableList(TableRef.value)
+		ElMessage.success('提交成功')
+	}
+}
+
+// 搜索
+const initParam = reactive({
+  User_tokey: globalStore.GET_User_tokey,
+  T_name: '',
+  T_state: ''
+})
+
+const openRepairWorkOrderFormDrawer = (type: string, row?: any) => repairWorkOrderFormRef.value?.repairWorkOrderFormOpen(type, row)
+
+</script>
+
+<template>
+  <div class="RepairWorkOrder-list">
+    <TableBase ref="TableRef" :columns="columns" :requestApi="RepairWorkOrder_List" :initParam="initParam">
+      <template #table-header>
+        <div class="input-suffix">
+          <el-row :gutter="20" style="margin-bottom: 0">
+            <el-col :xl="6" :lg="8" :md="10">
+              <span class="inline-flex items-center">关键字:</span>
+              <el-input
+                v-model="initParam.T_name"
+                type="text"
+                class="w-50 m-2"
+                placeholder="按产品名称、产品型号搜索"
+                @change="searchOnTableList(TableRef)"
+              />
+            </el-col>
+            <el-col :xl="10" :md="12">
+              <span class="inline-flex items-center">状态:</span>
+              <el-select v-model="initParam.T_state" class="w-50 m-2" clearable placeholder="请选择分类~">
+                <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" />
+              </el-select>
+              <el-button type="primary" @click="searchOnTableList(TableRef)">搜索</el-button>
+            </el-col>
+			  <el-col :xl="6" :md="2" class="btn">
+				  <el-button type="primary" @click="openRepairWorkOrderFormDrawer('new')">下发工单</el-button>
+			  </el-col>
+          </el-row>
+        </div>
+      </template>
+      <template #T_state="{ row }">
+		  <el-tag v-if="row.T_state === 1" type="info" effect="dark"> 已派发 </el-tag>
+		  <el-tag v-if="row.T_state === 2" type="warning" effect="dark"> 维修中 </el-tag>
+		  <el-tag v-if="row.T_state === 3" type="primary" effect="dark"> 已归还 </el-tag>
+		  <el-tag v-if="row.T_state === 4" type="success" effect="dark"> 已完结 </el-tag>
+	  </template>
+      <template #right="{ row }">
+        <el-button link type="primary" size="small" :icon="View" @click="openRepairWorkOrderFormDrawer('view', row)">详情</el-button>
+        <el-button link type="primary" size="small" :icon="Edit" @click="openRepairWorkOrderFormDrawer('edit', row)">编辑</el-button>
+        <el-button link type="success" size="small" :icon="Check" @click="RepairWorkOrderFinish(row)">完结</el-button>
+        <el-button link type="danger" size="small" :icon="Delete" @click="RepairWorkOrderDelete(row)">删除</el-button>
+      </template>
+    </TableBase>
+    <RepairWorkOrderForm ref="repairWorkOrderFormRef" projectName="repairWorkOrder" @onTableList="updateOnTableList(TableRef)" />
+
+  </div>
+</template>
+
+<style scoped lang="scss">
+@import '@/styles/var.scss';
+.tooltip-content {
+  max-width: 500px;
+  overflow-y: auto;
+}
+.RepairWorkOrder-list {
+  @include f-direction;
+  .input-suffix {
+    width: 100%;
+    .inline-flex {
+      white-space: nowrap;
+    }
+    .btn {
+      display: flex;
+      justify-content: end;
+    }
+    .w-50 {
+      width: 12.5rem;
+    }
+  }
+}
+</style>

+ 260 - 0
src/views/storehouse/RepairWorkOrder/RepairWorkOrderForm.vue

@@ -0,0 +1,260 @@
+<script setup lang="ts">
+import {RepairWorkOrder_Add, RepairWorkOrder_Edit, RepairWorkOrder_Return,} from '@/api/RepairWorkOrder/index'
+import {nextTick, reactive, ref} from 'vue'
+import Upload from './Upload/index.vue'
+import Drawer from '@/components/Drawer/index.vue'
+import type {FormInstance, FormRules} from 'element-plus'
+import {ElMessage} from 'element-plus'
+import {useTablePublic} from '@/hooks/useTablePublic'
+import ContractUser from "@/views/storehouse/outStock/receiveUser.vue";
+
+const typeTip = ref('')
+const isNew = ref(true)
+const formLabelWidth = ref('120px')
+const ruleFormRef = ref<FormInstance>()
+const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
+const uploadRef = ref<InstanceType<typeof Upload> | null>(null)
+const {resetForm, globalStore} = useTablePublic()
+const receiveUser = ref<InstanceType<typeof ContractUser> | null>(null)
+const fileListImg: any = ref([])
+let showWatch = ref(true)
+let disabled = ref(true)
+
+const rules = reactive<FormRules>({
+	T_product: [{required: true, message: '请输入产品名称', trigger: 'blur'}],
+	T_repair_num: [{required: true, message: '请输入维修数量', trigger: 'blur'}],
+	T_repair_reason: [{required: true, message: '维修原因', trigger: 'blur'}],
+	T_return_product: [{required: true, message: '请输入产品名称', trigger: 'blur'}],
+	T_return_num: [{required: true, message: '请输入返回数量', trigger: 'blur'}],
+	T_staging_num: [{required: true, message: '请输入暂存数量', trigger: 'blur'}],
+	T_scrap_num: [{required: true, message: '请输入报废数量', trigger: 'blur'}],
+	// T_malfunction_reason: [{ required: true, message: '请输入故障原因', trigger: 'blur' }],
+})
+const form: any = ref({
+	T_id: '',
+	T_order_date: '',
+	T_repair_date: '',
+	T_finish_date: '',
+	T_state: '',
+	T_product: '',
+	T_model: '',
+	T_repair_num: '',
+	T_source: '',
+	T_repair_reason: '',
+	T_picture: '',
+	T_receive_name: '',
+	T_delivery_name: '',
+	T_return_name: '',
+	T_return_date: '',
+	T_return_product: '',
+	T_return_model: '',
+	T_return_num: '',
+	T_staging_num: '',
+	T_scrap_num: '',
+	T_malfunction_reason: '',
+	T_remark: '',
+	T_sn: '',
+})
+
+const repairWorkOrderFormOpen = (type: string, row?: any) => {
+	// drawerRef.value?.openDrawer()
+	isNew.value = type === 'new' ? true : false
+	showWatch.value = type == 'new' || 'edit' ? true : false
+	typeTip.value = type
+	if (type !== 'new') {
+
+			for (let key in form.value) {
+				if (row.hasOwnProperty(key)) {
+					form.value[key] = row[key];
+				}
+			}
+			if (form.value.T_return_product === '') {
+				form.value.T_return_product = form.value.T_product
+			}
+			if (form.value.T_return_model === '') {
+				form.value.T_return_model = form.value.T_model
+			}
+			form.value.T_id = row.Id
+			fileListImg.value.push({url:form.value.T_picture})
+			console.log('form.value', form.value)
+			console.log('fileListImg', fileListImg)
+
+
+	} else {
+		delete form.value.T_id
+		form.value.T_product = ''
+		form.value.T_repair_num = ''
+		form.value.T_model = ''
+		form.value.T_source = ''
+		form.value.T_repair_reason = ''
+		form.value.T_receive = ''
+		form.value.T_picture = ''
+		fileListImg.value = []
+	}
+
+	drawerRef.value && drawerRef.value.openDrawer()
+
+}
+
+const AddRepairWorkOrder = (formEl: FormInstance | undefined) => {
+	if (!formEl) return
+	formEl.validate(async (valid: boolean) => {
+		if (valid) {
+			let res: any = {}
+			if (isNew.value) {//新增
+				res = await RepairWorkOrder_Add({User_tokey: globalStore.GET_User_tokey, ...form.value})
+			} else if (typeTip.value === 'return') {
+				res = await RepairWorkOrder_Return({
+					User_tokey: globalStore.GET_User_tokey,
+					...form.value,
+				})
+			} else {//编辑
+				res = await RepairWorkOrder_Edit({
+					User_tokey: globalStore.GET_User_tokey,
+					...form.value,
+				})
+			}
+			if (res.Code === 200) {
+				ElMessage.success(`维修工单${isNew.value ? '下发' : '修改'}成功!!`)
+				nextTick(() => {
+					emit('onTableList')
+					drawerRef.value?.closeDrawer()
+					resetForm(ruleFormRef.value)
+					uploadRef.value?.clearfileList()
+					isNew.value = true
+				})
+			}
+		}
+	})
+}
+
+const selectReceive = () => receiveUser.value?.openDrawer()
+const getReceiveInfo = ({T_uuid, T_name}: { T_uuid: string; T_name: string }) => {
+	form.value.T_receive_name = T_name
+	form.value.T_receive = T_uuid
+}
+const callbackDrawer = (done: () => void) => {
+	disabled.value = false
+	isNew.value = true
+	nextTick(() => {
+		resetForm(ruleFormRef.value)
+		uploadRef.value?.clearfileList()
+		done()
+	})
+}
+
+const getTitle = (type: string) => {
+	switch (type) {
+		case 'new':
+			return '下发'
+		case 'edit':
+			return '编辑'
+		case 'return':
+			return '归还'
+		default:
+			return '详情'
+	}
+}
+
+const emit = defineEmits<{ (event: 'onTableList'): void }>()
+
+defineExpose({
+	repairWorkOrderFormOpen
+})
+</script>
+
+<template>
+	<Drawer ref="drawerRef" :handleClose="callbackDrawer" size="35%">
+		<template #header="{ params }">
+			<h4 :id="params.titleId" :class="params.titleClass">{{ getTitle(typeTip) }} - 维修工单</h4>
+		</template>
+		<el-form ref="ruleFormRef" :model="form" :rules="rules">
+			<el-form-item
+				v-if="!(typeTip === 'return')"
+				label="产品名称:" class="m-b-6" :label-width="formLabelWidth" prop="T_product">
+				<el-input v-model="form.T_product" type="text" autocomplete="off" placeholder="请填写产品名称"/>
+			</el-form-item>
+			<el-form-item
+				v-if="!(typeTip === 'return')"
+				label="型号:" class="m-b-6" :label-width="formLabelWidth" prop="T_model">
+				<el-input v-model="form.T_model" type="text" autocomplete="off" placeholder="请填写型号"/>
+			</el-form-item>
+			<el-form-item
+				v-if="!(typeTip === 'return')"
+				label="维修数量:" class="m-b-6" :label-width="formLabelWidth" prop="T_repair_num">
+				<el-input v-model="form.T_repair_num" type="text" autocomplete="off" placeholder="请填写维修数量"/>
+			</el-form-item>
+			<el-form-item
+				v-if="!(typeTip === 'return')"
+				label="设备来源:" class="m-b-6" :label-width="formLabelWidth" prop="T_source">
+				<el-input v-model="form.T_source" type="text" autocomplete="off" placeholder="请填写设备来源"/>
+			</el-form-item>
+			<el-form-item
+				v-if="!(typeTip === 'return')"
+				label="维修原因:" class="m-b-6" :label-width="formLabelWidth" prop="T_repair_reason">
+				<el-input v-model="form.T_repair_reason" type="text" autocomplete="off" placeholder="请填写维修原因"/>
+			</el-form-item>
+			<el-form-item
+				v-if="!(typeTip === 'return')"
+				label="接收人:" class="m-b-6" :label-width="formLabelWidth" prop="T_receive_name">
+				<el-input v-model="form.T_receive_name" type="text" autocomplete="off" placeholder="请选择接收人"
+						  @focus="selectReceive"/>
+			</el-form-item>
+
+			<el-divider :style="{borderColor: '#64BA3AFF' }"
+						v-if="!(typeTip === 'new' || typeTip === 'return')"
+						content-position="left">归还情况
+			</el-divider>
+			<el-form-item v-if="!isNew" label="产品名称:" class="m-b-6" :label-width="formLabelWidth"
+						  prop="T_return_product">
+				<el-input v-model="form.T_return_product" type="text" autocomplete="off" placeholder="请填写产品名称"/>
+			</el-form-item>
+			<el-form-item v-if="!isNew" label="型号:" class="m-b-6" :label-width="formLabelWidth" prop="T_return_model">
+				<el-input v-model="form.T_return_model" type="text" autocomplete="off" placeholder="请填写型号"/>
+			</el-form-item>
+			<el-form-item v-if="!isNew" label="返回数量:" class="m-b-6" :label-width="formLabelWidth"
+						  prop="T_return_num">
+				<el-input v-model="form.T_return_num" type="text" autocomplete="off" placeholder="请填写返回数量"/>
+			</el-form-item>
+			<el-form-item v-if="!isNew" label="暂存数量:" class="m-b-6" :label-width="formLabelWidth"
+						  prop="T_staging_num">
+				<el-input v-model="form.T_staging_num" type="text" autocomplete="off" placeholder="请填写暂存数量"/>
+			</el-form-item>
+			<el-form-item v-if="!isNew" label="报废数量:" class="m-b-6" :label-width="formLabelWidth"
+						  prop="T_scrap_num">
+				<el-input v-model="form.T_scrap_num" type="text" autocomplete="off" placeholder="请填写报废数量"/>
+			</el-form-item>
+			<el-form-item v-if="!isNew" label="故障原因:" class="m-b-6" :label-width="formLabelWidth"
+						  prop="T_malfunction_reason">
+				<el-input v-model="form.T_malfunction_reason" type="text" autocomplete="off"
+						  placeholder="请填写故障原因"/>
+			</el-form-item>
+			<el-form-item v-if="!isNew" label="备注:" class="m-b-6" :label-width="formLabelWidth" prop="T_remark">
+				<el-input v-model="form.T_remark" type="text" autocomplete="off" placeholder="请填写备注"/>
+			</el-form-item>
+			<el-form-item v-if="!isNew" label="SN:" class="m-b-6" :label-width="formLabelWidth" prop="T_sn">
+				<el-input v-model="form.T_sn" type="text" autocomplete="off" placeholder="请填写SN"/>
+			</el-form-item>
+
+			<el-form-item :label-width="formLabelWidth">
+				<el-button v-if="typeTip==='new'" color="#626aef" @click="AddRepairWorkOrder(ruleFormRef)">提交
+				</el-button>
+				<el-button v-if="typeTip==='edit'" color="#626aef" @click="AddRepairWorkOrder(ruleFormRef)">修改
+				</el-button>
+				<el-button v-if="typeTip==='return'" color="#626aef" @click="AddRepairWorkOrder(ruleFormRef)">归还
+				</el-button>
+			</el-form-item>
+		</el-form>
+	</Drawer>
+	<ContractUser ref="receiveUser" @onUserInfo="getReceiveInfo" title="接收人"/>
+
+</template>
+
+<style scoped lang="scss">
+@import '@/styles/var.scss';
+
+.tooltip-content {
+	max-width: 500px;
+	overflow-y: auto;
+}
+</style>

+ 182 - 0
src/views/storehouse/RepairWorkOrder/Upload/index.vue

@@ -0,0 +1,182 @@
+<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>

+ 187 - 0
src/views/storehouse/ValidationTool/modules/snAdd.vue

@@ -0,0 +1,187 @@
+<script setup lang="ts">
+import {
+	validation_add,
+	validation_repair,
+	validation_scrap,
+} from '@/api/storehouse'
+import {computed, nextTick, reactive, ref} from 'vue'
+import type {FormInstance} from 'element-plus'
+import {ElMessage} from 'element-plus'
+
+const outerVisible = ref(false)
+
+const submitFormRef = ref<FormInstance | null>(null)
+
+
+const pageSize = ref(8)
+const currentPage = ref(1)
+
+const rulesrepaid = reactive({
+	T_sn: [{required: true, message: '请输入SN', trigger: 'blur'}]
+})
+
+const extractSN = (fullSN: string): string => {
+	if (fullSN.length === 24 && fullSN.startsWith('03') && fullSN.endsWith('000001')) {
+		return fullSN.substring(2, 18)
+	}
+	return fullSN
+}
+
+const handlePageChange = (page: number) => {
+	currentPage.value = page
+}
+
+const data:any = reactive({
+	title: '',
+	snItems: [],
+	fromData: {
+		T_sn: '',
+		Validationnumber: '',
+		T_remark: '',
+	},
+})
+
+
+const paginatedItems = computed(() => {
+	if (data.snItems.length === 0) {
+		return
+	}
+	const start = (currentPage.value - 1) * pageSize.value
+	const end = start + pageSize.value
+	return data.snItems.slice(start, end)
+})
+
+const removeItem = (index: number) => {
+	data.snItems.splice(index, 1)
+	ElMessage.success('已从待提交列表中移除')
+}
+
+const resetForm = () => {
+	data.snItems = [];
+	data.fromData.T_sn = '';
+	emit('successFun', true);
+	nextTick(() => {
+		outerVisible.value = false;
+	});
+}
+
+const submitItems = async () => {
+	if (data.snItems.length === 0) {
+		ElMessage.warning('暂无数据可提交')
+		return
+	}
+	console.log("=========",data)
+	const rest = JSON.parse(JSON.stringify(data.snItems))
+
+		switch (data.title) {
+			case '维修':
+				const repairResult: any = await validation_repair(rest)
+				if (repairResult.Code == 200) {
+					ElMessage.success('提交成功')
+					resetForm()
+				} else {
+					ElMessage.error('提交失败')
+				}
+				break
+			case '报废':
+				const scrapResult: any = await validation_scrap(rest)
+				if (scrapResult.Code == 200) {
+					ElMessage.success('提交成功')
+					resetForm()
+				} else {
+					ElMessage.error('提交失败')
+				}
+				break
+			case '归还':
+				const returnResult: any = await validation_add(rest)
+				if (returnResult.Code == 200) {
+					ElMessage.success('提交成功')
+					resetForm()
+				} else {
+					ElMessage.error('提交失败')
+				}
+				break
+			default:
+				ElMessage.error('未知操作类型');
+				break;
+		}
+
+}
+
+
+const submitForm = () => {
+	submitFormRef.value?.validate(async (valid: boolean) => {
+		if (valid) {
+			const extractedSN = extractSN(data.fromData.T_sn)
+			if (data.snItems.some((item: any) => item.T_sn === extractedSN)) {
+				ElMessage.warning('已存在相同的SN,不能添加')
+				return
+			}
+			data.snItems.unshift({...data.fromData, T_sn: extractedSN})
+			data.fromData.T_sn = ''
+			ElMessage.success('已添加到待提交列表')
+			if ('speechSynthesis' in window) {
+				const utterance = new SpeechSynthesisUtterance('添加成功')
+				window.speechSynthesis.speak(utterance)
+			} else {
+				console.warn('Web Speech API 不被支持')
+			}
+		}
+	})
+}
+
+// ------------- 维修结束
+
+const emit = defineEmits<{ (event: 'successFun', value:boolean): void }>()
+
+defineExpose({
+	outerVisible, data
+})
+</script>
+
+<template>
+	<div class="">
+		<el-dialog :title="data.title" v-model="outerVisible" width="50%" draggable destroy-on-close>
+			<el-form :model="data.fromData" :rules="rulesrepaid" ref="submitFormRef">
+				<el-form-item label="SN" prop="T_sn">
+					<el-input v-model="data.fromData.T_sn" placeholder="请输入SN" @keyup.enter="submitForm"></el-input>
+				</el-form-item>
+				<el-form-item label="备注">
+					<el-input v-model="data.fromData.T_remark" type="textarea" placeholder="请输入备注"></el-input>
+				</el-form-item>
+			</el-form>
+			<!-- 新增数据条数提示 -->
+			<div style="margin: 10px 0">
+				<span>当前待提交数据条数: {{ data.snItems.length }}</span>
+			</div>
+			<el-table :data="paginatedItems" style="width: 100%; margin-top: 20px">
+				<el-table-column type="index" label="序号" width="80"></el-table-column>
+				<!-- 添加序号列 -->
+				<el-table-column prop="T_sn" label="SN"></el-table-column>
+				<el-table-column prop="T_remark" label="备注"></el-table-column>
+				<el-table-column label="操作" width="180">
+					<template #default="scope">
+						<el-button type="danger" size="small" @click="removeItem(scope.$index)">删除</el-button>
+					</template>
+				</el-table-column>
+			</el-table>
+			<el-pagination
+				background
+				layout="prev, pager, next"
+				:total="data.snItems.length"
+				:page-size="pageSize"
+				:current-page="currentPage"
+				@current-change="handlePageChange"
+				style="margin-top: 20px; text-align: right"
+			/>
+			<template #footer>
+      <span class="dialog-footer">
+        <el-button @click="outerVisible = false">取消</el-button>
+        <el-button type="primary" @click="submitForm">添加到暂存</el-button>
+		  <!-- 新增提交按钮 -->
+        <el-button type="primary" @click="submitItems">提交</el-button>
+      </span>
+			</template>
+		</el-dialog>
+	</div>
+</template>

+ 140 - 0
src/views/storehouse/ValidationTool/statValidation.vue

@@ -0,0 +1,140 @@
+<script setup lang="ts">
+import {
+	validation_User_List,
+	validation_Stat
+} from '@/api/storehouse'
+import { ref, reactive } from 'vue'
+import { UserFilled } from '@element-plus/icons-vue'
+import TableBase from '@/components/TableBase/index.vue'
+import { useTablePublic } from '@/hooks/useTablePublic'
+import { ColumnProps } from '@/components/TableBase/interface/index'
+
+interface UserInfoIn {
+  LendUser: string
+  TotalCount: number
+}
+const userInfo = ref<UserInfoIn>({
+  LendUser: '',
+  TotalCount: 0,
+})
+const columns: ColumnProps[] = [{ prop: 'LendUser', label: '姓名' }]
+const columnsStat: ColumnProps[] = [
+  { type: 'index', label: '序号', width: 80 },
+  { prop: 'LendUser', label: '借出人' },
+  { prop: 'T_project', label: '借出项目' },
+  { prop: 'T_state', label: '状态', name: 'T_state' },
+  { prop: 'TotalCount', label: '数量' },
+]
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
+const { tableRowClassName, globalStore, } = useTablePublic()
+const tableRowClassNameHandle = (data: any): any => tableRowClassName(data.row.T_uuid, userInfo.value.LendUser)
+const initParam = reactive({ User_tokey: globalStore.GET_User_tokey, LendUser: userInfo.value.LendUser, page_z: 99 })
+const getUserParams = (row: any) => {
+  userInfo.value.LendUser = ''
+  setTimeout(() => {
+    userInfo.value = { ...row }
+    initParam.LendUser = userInfo.value.LendUser
+  }, 100)
+}
+</script>
+<template>
+  <div class="project">
+    <div style="width: 290px" class="project-table">
+      <TableBase
+        :columns="columns"
+        :requestApi="validation_User_List"
+        :initParam="{ User_tokey: globalStore.GET_User_tokey }"
+        layout="prev, pager, next"
+        :rowClick="getUserParams"
+        :tableRowClassName="tableRowClassNameHandle"
+      >
+        <template #table-header>
+          <h3 class="title">员工列表</h3>
+        </template>
+      </TableBase>
+    </div>
+    <transition
+      leave-active-class="animate__animated animate__fadeOutRight"
+      enter-active-class="animate__animated animate__fadeInLeft"
+    >
+      <div class="project-container" v-if="userInfo.LendUser">
+        <el-card class="box-card">
+          <h3 class="text title m-b-5">员工基本信息</h3>
+          <div class="info-content">
+            <el-avatar shape="square" size="large" :icon="UserFilled" />
+            <div class="info-name">
+              <h4>借出人:{{ userInfo.LendUser }}</h4>
+              <h4>借出总数量: {{ userInfo.TotalCount }}</h4>
+            </div>
+          </div>
+        </el-card>
+        <TableBase
+          ref="TableRef"
+          :columns="columnsStat"
+          :requestApi="validation_Stat"
+          :initParam="initParam"
+          :displayHeader="true"
+          :pagination="false"
+        >
+          <template #T_state="{ row }">
+            <el-tag v-if="row.T_state == 1" type="success" effect="dark"> 已出库</el-tag>
+            <el-tag v-if="row.T_state == 2" effect="dark">未出库</el-tag>
+            <el-tag v-if="row.T_state == 3" effect="dark" type="danger">已损坏</el-tag>
+          </template>
+        </TableBase>
+      </div>
+    </transition>
+  </div>
+</template>
+
+<style scoped lang="scss">
+@import '@/styles/var.scss';
+.project {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  overflow: hidden;
+  .project-table {
+    z-index: 1;
+    @include f-direction;
+  }
+  .project-container {
+    @include f-direction;
+    width: calc(100% - 290px);
+    z-index: 0;
+    margin-left: 12px;
+    .box-card {
+      border-radius: 8px;
+    }
+    :deep(.el-table .cell) {
+      white-space: normal !important;
+    }
+    .text {
+      text-align: left;
+    }
+    .info-content {
+      display: flex;
+      color: #606266;
+      .info-name {
+        flex: 1;
+        display: flex;
+        justify-content: space-around;
+        align-items: center;
+        padding-left: 0.75rem;
+      }
+    }
+  }
+  :deep(.table-header),
+  :deep(.card) {
+    margin: 0;
+    border-radius: 8px;
+  }
+  .title {
+    width: 100%;
+    text-align: center;
+    line-height: 1.7em;
+    font-size: 20px;
+    color: #707b84;
+  }
+}
+</style>

+ 589 - 608
src/views/storehouse/ValidationTool/validation.vue

@@ -2,21 +2,22 @@
 import {
 	exportFile,
 	readValidation,
-	validationTool_class_list,
 	updateValidation,
 	uploadFile,
 	validation_add,
 	validation_del,
 	validation_List,
-	validation_update
+	validation_update,
+	validationTool_class_list
 } from '@/api/storehouse'
 import TableBase from '@/components/TableBase/index.vue'
-import { computed, onMounted, reactive, ref } from 'vue'
-import { GlobalStore } from '@/stores'
-import type { ColumnProps } from '@/components/TableBase/interface'
-import { Delete, Edit } from '@element-plus/icons-vue'
-import type { FormInstance, UploadInstance } from 'element-plus'
-import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
+import {computed, nextTick, onMounted, reactive, ref} from 'vue'
+import {GlobalStore} from '@/stores'
+import type {ColumnProps} from '@/components/TableBase/interface'
+import {Delete, Edit} from '@element-plus/icons-vue'
+import type {FormInstance, UploadInstance} from 'element-plus'
+import {ElLoading, ElMessage, ElMessageBox} from 'element-plus'
+import snAdd from './modules/snAdd.vue'
 
 const uploadRef = ref<UploadInstance>()
 const uploadFiles = ref<File[]>([]) // 新增:用于存储上传的文件
@@ -25,115 +26,116 @@ const globalStore = GlobalStore()
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
 
 const initParam = reactive({
-  User_tokey: globalStore.GET_User_tokey,
-  Validationnumber: '',
-  T_state: '',
-  T_sn: '',
-  T_imei: '',
-  T_iccid: '',
-  LendUser: '',
-  T_project: '',
-  T_class: ''
+	User_tokey: globalStore.GET_User_tokey,
+	Validationnumber: '',
+	T_state: '',
+	T_sn: '',
+	T_imei: '',
+	T_iccid: '',
+	LendUser: '',
+	T_project: '',
+	T_class: ''
 })
 const columns: ColumnProps[] = [
-  { type: 'index', label: '序号', width: 80 },
-  { prop: 'Validationnumber', label: '设备编号', ellipsis: true },
-  { prop: 'T_sn', label: '设备SN', ellipsis: true },
-  { prop: 'T_imei', label: '模组imei', ellipsis: true },
-  { prop: 'T_iccid', label: '物联网卡号', ellipsis: true },
-  { prop: 'T_state', label: '状态', name: 'T_state' },
-  { prop: 'T_class', label: '设备类型', name: 'T_class' },
-  { prop: 'LendUser', label: '借出人', ellipsis: true },
-  { prop: 'T_project', label: '借出项目', ellipsis: true },
-  { prop: 'T_remark', label: '备注', name: 'T_remark', ellipsis: true },
-  { prop: 'operation', label: '操作', width: 260, fixed: 'right' }
+	{type: 'index', label: '序号', width: 80},
+	{prop: 'Validationnumber', label: '设备编号', ellipsis: true},
+	{prop: 'T_sn', label: '设备SN', ellipsis: true, width: 180},
+	{prop: 'T_imei', label: '模组imei', ellipsis: true},
+	{prop: 'T_iccid', label: '物联网卡号', ellipsis: true},
+	{prop: 'T_state', label: '状态', name: 'T_state'},
+	{prop: 'T_class', label: '设备类型', name: 'T_class'},
+	{prop: 'LendUser', label: '借出人', ellipsis: true},
+	{prop: 'T_project', label: '借出项目', ellipsis: true},
+	{prop: 'T_remark', label: '备注',  ellipsis: true},
+	{prop: 'operation', label: '操作', width: 260, fixed: 'right'}
 ]
 // 搜索
 const options = reactive([
-  { name: '已出库', id: 1 },
-  { name: '未出库', id: 2 },
-  { name: '已损坏', id: 3 }
+	{name: '已出库', id: 1},
+	{name: '未出库', id: 2},
+	{name: '维修中', id: 3},
+	{name: '已报废', id: 4}
 ])
 const searchHandle = () => {
-  TableRef.value?.searchTable()
+	TableRef.value?.searchTable()
 }
 /**
  * 删除
  */
 const deleteFun = (row: any) => {
-  ElMessageBox.confirm('删除操作,是否立即删除?', '删除', {
-    confirmButtonText: '立即删除',
-    cancelButtonText: '取消',
-    type: 'warning',
-    center: true
-  })
-    .then(async () => {
-      const result: any = await validation_del({ t_sn: row })
-      if (result.Code == 200) {
-        ElMessage.success('删除成功')
-        TableRef.value?.searchTable()
-      }
-    })
-    // eslint-disable-next-line @typescript-eslint/no-empty-function
-    .catch(() => {})
+	ElMessageBox.confirm('删除操作,是否立即删除?', '删除', {
+		confirmButtonText: '立即删除',
+		cancelButtonText: '取消',
+		type: 'warning',
+		center: true
+	})
+		.then(async () => {
+			const result: any = await validation_del({t_sn: row})
+			if (result.Code == 200) {
+				ElMessage.success('删除成功')
+				TableRef.value?.searchTable()
+			}
+		})
+		// eslint-disable-next-line @typescript-eslint/no-empty-function
+		.catch(() => {
+		})
 }
 //导出文件excel
 const exportExcel = async () => {
-  try {
-    const response: any = await exportFile({
-      User_tokey: globalStore.GET_User_tokey,
-      Validationnumber: initParam.Validationnumber,
-      T_state: initParam.T_state,
-      T_sn: initParam.T_sn,
-      T_imei: initParam.T_imei,
-      T_iccid: initParam.T_iccid,
-      LendUser: initParam.LendUser,
-      T_project: initParam.T_project,
-      T_class: initParam.T_class
-    })
-    // 处理返回的二进制文件并触发下载
-    const blob = new Blob([response], { type: 'application/vnd.ms-excel;charset=utf8' })
-    const url = window.URL.createObjectURL(blob)
-    const a = document.createElement('a')
-    a.href = url
-    a.download = 'filename.xlsx' // 设置下载的文件名
-    document.body.appendChild(a)
-    a.click()
-    a.remove()
-    window.URL.revokeObjectURL(url)
-    ElMessage.success('导出成功')
-  } catch (error) {
-    ElMessage.error('导出失败,请检查网络连接')
-  }
+	try {
+		const response: any = await exportFile({
+			User_tokey: globalStore.GET_User_tokey,
+			Validationnumber: initParam.Validationnumber,
+			T_state: initParam.T_state,
+			T_sn: initParam.T_sn,
+			T_imei: initParam.T_imei,
+			T_iccid: initParam.T_iccid,
+			LendUser: initParam.LendUser,
+			T_project: initParam.T_project,
+			T_class: initParam.T_class
+		})
+		// 处理返回的二进制文件并触发下载
+		const blob = new Blob([response], {type: 'application/vnd.ms-excel;charset=utf8'})
+		const url = window.URL.createObjectURL(blob)
+		const a = document.createElement('a')
+		a.href = url
+		a.download = 'filename.xlsx' // 设置下载的文件名
+		document.body.appendChild(a)
+		a.click()
+		a.remove()
+		window.URL.revokeObjectURL(url)
+		ElMessage.success('导出成功')
+	} catch (error) {
+		ElMessage.error('导出失败,请检查网络连接')
+	}
 }
 
 const showInStorageForm = ref(false)
-const showrRepaidForm = ref(false)
 
 const inStorageFormRef = ref<FormInstance | null>(null)
 const inStorageForm = reactive({
-  T_sn: '',
-  Validationnumber: '',
-  T_remark: '',
-  T_class: null
+	T_sn: '',
+	Validationnumber: '',
+	T_remark: '',
+	T_class: null
 })
 
 interface InStorageItem {
-  T_sn: string
-  Validationnumber: string
-  T_remark: string
+	T_sn: string
+	Validationnumber: string
+	T_remark: string
 }
 
 // 获取设备类型
 const Pruductoptions = ref<any[]>([
-  {
-    Id: '',
-    T_name: ''
-  }
+	{
+		Id: '',
+		T_name: ''
+	}
 ])
 const getValidationToolClassList = async () => {
-  const res: any = await validationTool_class_list({ page: 1, page_z: 999 })
-  Pruductoptions.value = res.Data.Data
+	const res: any = await validationTool_class_list({page: 1, page_z: 999})
+	Pruductoptions.value = res.Data.Data
 }
 
 const pendingItems = ref<InStorageItem[]>([])
@@ -141,138 +143,104 @@ const pageSize = ref(8)
 const currentPage = ref(1)
 
 const paginatedPendingItems = computed(() => {
-  const start = (currentPage.value - 1) * pageSize.value
-  const end = start + pageSize.value
-  return pendingItems.value.slice(start, end)
+	const start = (currentPage.value - 1) * pageSize.value
+	const end = start + pageSize.value
+	return pendingItems.value.slice(start, end)
 })
 const rules = reactive({
-  T_sn: [{ required: true, message: '请输入SN', trigger: 'blur' }],
-  Validationnumber: [{ required: true, message: '请输入设备编号', trigger: 'blur' }],
-  T_class: [{ required: true, message: '请选择设备类型', trigger: 'blur' }]
-})
-const rulesrepaid = reactive({
-  T_sn: [{ required: true, message: '请输入SN', trigger: 'blur' }]
+	T_sn: [{required: true, message: '请输入SN', trigger: 'blur'}],
+	Validationnumber: [{required: true, message: '请输入设备编号', trigger: 'blur'}],
+	T_class: [{required: true, message: '请选择设备类型', trigger: 'blur'}]
 })
 
 const extractSN = (fullSN: string): string => {
-  if (fullSN.length === 24 && fullSN.startsWith('03') && fullSN.endsWith('000001')) {
-    return fullSN.substring(2, 18)
-  }
-  return fullSN
+	if (fullSN.length === 24 && fullSN.startsWith('03') && fullSN.endsWith('000001')) {
+		return fullSN.substring(2, 18)
+	}
+	return fullSN
 }
 
+// 入库
 const submitInStorageForm = () => {
-  inStorageFormRef.value?.validate(async (valid: boolean) => {
-    if (valid) {
-      const extractedSN = extractSN(inStorageForm.T_sn)
-      if (pendingItems.value.some((item: any) => item.T_sn === extractedSN)) {
-        ElMessage.warning('已存在相同的SN,不能添加')
-        return
-      }
-      const result: any = await readValidation({ sn: extractedSN })
-      if ((result.Code==200)&&(result.Data.T_state == 2)) {
-        //1-已出库 2-待使用  3-待维修
-        ElMessage.warning('当前SN已入库不能重复入库')
-        return
-      }
-      pendingItems.value.unshift({ ...inStorageForm, T_sn: extractedSN })
-      inStorageForm.T_sn = ''
-      inStorageForm.Validationnumber = ''
-      inStorageForm.T_remark = ''
-      ElMessage.success('已添加到待提交列表')
-      if ('speechSynthesis' in window) {
-        const utterance = new SpeechSynthesisUtterance('添加成功')
-        window.speechSynthesis.speak(utterance)
-      } else {
-        console.warn('Web Speech API 不被支持')
-      }
-    }
-  })
-}
-const submitRepaidForm = () => {
-  inStorageFormRef.value?.validate(async (valid: boolean) => {
-    if (valid) {
-      const extractedSN = extractSN(inStorageForm.T_sn)
-
-      if (pendingItems.value.some((item: any) => item.T_sn === extractedSN)) {
-        ElMessage.warning('已存在相同的SN,不能添加')
-        return
-      }
-      const result: any = await readValidation({ sn: extractedSN })
-      if (result.Code !== 200) {
-        ElMessage.warning('当前SN未入库不能归还')
-        return
-      }
-      if (result.Data.T_state != 1) {
-        //1-已出库 2-待使用  3-待维修
-        ElMessage.warning('当前SN未出库不能归还')
-        return
-      }
-
-      pendingItems.value.unshift({ ...inStorageForm, T_sn: extractedSN })
-
-      inStorageForm.T_sn = ''
-      inStorageForm.Validationnumber = ''
-      inStorageForm.T_remark = ''
-      ElMessage.success('已添加到待提交列表')
-      if ('speechSynthesis' in window) {
-        const utterance = new SpeechSynthesisUtterance('添加成功')
-        window.speechSynthesis.speak(utterance)
-      } else {
-        console.warn('Web Speech API 不被支持')
-      }
-    }
-  })
+	inStorageFormRef.value?.validate(async (valid: boolean) => {
+		if (valid) {
+			const extractedSN = extractSN(inStorageForm.T_sn)
+			if (pendingItems.value.some((item: any) => item.T_sn === extractedSN)) {
+				ElMessage.warning('已存在相同的SN,不能添加')
+				return
+			}
+			const result: any = await readValidation({sn: extractedSN})
+			if ((result.Code == 200) && (result.Data.T_state == 2)) {
+				//1-已出库 2-待使用  3-待维修
+				ElMessage.warning('当前SN已入库不能重复入库')
+				return
+			}
+			pendingItems.value.unshift({...inStorageForm, T_sn: extractedSN})
+			inStorageForm.T_sn = ''
+			inStorageForm.Validationnumber = ''
+			inStorageForm.T_remark = ''
+			ElMessage.success('已添加到待提交列表')
+			if ('speechSynthesis' in window) {
+				const utterance = new SpeechSynthesisUtterance('添加成功')
+				window.speechSynthesis.speak(utterance)
+			} else {
+				console.warn('Web Speech API 不被支持')
+			}
+		}
+	})
 }
 
 const removePendingItem = (index: number) => {
-  pendingItems.value.splice(index, 1)
-  ElMessage.success('已从待提交列表中移除')
+	pendingItems.value.splice(index, 1)
+	ElMessage.success('已从待提交列表中移除')
 }
-
+// 归还
 const submitInStoragePendingItems = async () => {
-  if (pendingItems.value.length === 0) {
-    ElMessage.warning('暂无数据可提交')
-    return
-  }
-
-  const rest = JSON.parse(JSON.stringify(pendingItems.value))
-  try {
-    const result: any = await validation_add(rest)
-    if (result.Code === 200) {
-      ElMessage.success('提交成功')
-      pendingItems.value = []
-      inStorageForm.T_sn = ''
-      inStorageForm.Validationnumber = ''
-      inStorageForm.T_remark = ''
-      searchHandle()
-    } else {
-      ElMessage.error('提交失败')
-    }
-  } catch (error) {
-    ElMessage.error('提交失败,请检查网络连接')
-  }
+	if (pendingItems.value.length === 0) {
+		ElMessage.warning('暂无数据可提交')
+		return
+	}
+
+	const rest = JSON.parse(JSON.stringify(pendingItems.value))
+	try {
+		const result: any = await validation_add(rest)
+		if (result.Code === 200) {
+			ElMessage.success('提交成功')
+			pendingItems.value = []
+			inStorageForm.T_sn = ''
+			inStorageForm.Validationnumber = ''
+			inStorageForm.T_remark = ''
+			searchHandle()
+			nextTick(() => {
+				showInStorageForm.value = false
+			})
+		} else {
+			ElMessage.error('提交失败')
+		}
+	} catch (error) {
+		ElMessage.error('提交失败,请检查网络连接')
+	}
 }
 const handlePageChange = (page: number) => {
-  currentPage.value = page
+	currentPage.value = page
 }
 
 const showLendForm = ref(false)
 const lendFormRef = ref<FormInstance | null>(null)
 const lendForm = reactive({
-  T_sn: '',
-  Validationnumber: '',
-  T_remark: '',
-  LendUser: '',
-  T_project: ''
+	T_sn: '',
+	Validationnumber: '',
+	T_remark: '',
+	LendUser: '',
+	T_project: ''
 })
 
 interface LendItem {
-  T_sn: string
-  Validationnumber: string
-  T_remark: string
-  LendUser: string
-  T_project: string
+	T_sn: string
+	Validationnumber: string
+	T_remark: string
+	LendUser: string
+	T_project: string
 }
 
 const pendingLendItems = ref<LendItem[]>([])
@@ -280,476 +248,489 @@ const lendPageSize = ref(8)
 const lendCurrentPage = ref(1)
 
 const paginatedPendingLendItems = computed(() => {
-  const start = (lendCurrentPage.value - 1) * lendPageSize.value
-  const end = start + lendPageSize.value
-  return pendingLendItems.value.slice(start, end)
+	const start = (lendCurrentPage.value - 1) * lendPageSize.value
+	const end = start + lendPageSize.value
+	return pendingLendItems.value.slice(start, end)
 })
 
 const lendRules = reactive({
-  T_sn: [{ required: true, message: '请输入SN', trigger: 'blur' }]
+	T_sn: [{required: true, message: '请输入SN', trigger: 'blur'}]
 })
 
 const submitLendForm = () => {
-  console.log()
-  lendFormRef.value?.validate(async (valid: boolean) => {
-    if (valid) {
-      const extractedSN = extractSN(lendForm.T_sn)
-      if (pendingLendItems.value.some((item: any) => item.T_sn === extractedSN)) {
-        ElMessage.warning('已存在相同的SN,不能添加')
-        return
-      }
-      const result: any = await readValidation({ sn: extractedSN })
-      if (result.Code !== 200) {
-        ElMessage.warning('当前SN未入库不能借出')
-        return
-      }
-      if (result.Data.T_state != 2) {
-        ElMessage.warning('当前SN未入库不能借出')
-        return
-      }
-      pendingLendItems.value.unshift({
-        T_sn: extractedSN,
-        Validationnumber: lendForm.Validationnumber,
-        T_remark: lendForm.T_remark,
-        LendUser: lendForm.LendUser,
-        T_project: lendForm.T_project
-      })
-      lendForm.T_sn = ''
-      lendForm.T_remark = ''
-      ElMessage.success('已添加到待提交列表')
-      if ('speechSynthesis' in window) {
-        const utterance = new SpeechSynthesisUtterance('添加成功')
-        window.speechSynthesis.speak(utterance)
-      } else {
-        console.warn('Web Speech API 不被支持')
-      }
-    } else {
-    }
-  })
+	console.log()
+	lendFormRef.value?.validate(async (valid: boolean) => {
+		if (valid) {
+			const extractedSN = extractSN(lendForm.T_sn)
+			if (pendingLendItems.value.some((item: any) => item.T_sn === extractedSN)) {
+				ElMessage.warning('已存在相同的SN,不能添加')
+				return
+			}
+			const result: any = await readValidation({sn: extractedSN})
+			if (result.Code !== 200) {
+				ElMessage.warning('当前SN未入库不能借出')
+				return
+			}
+			if (result.Data.T_state != 2) {
+				ElMessage.warning('当前SN未入库不能借出')
+				return
+			}
+			pendingLendItems.value.unshift({
+				T_sn: extractedSN,
+				Validationnumber: lendForm.Validationnumber,
+				T_remark: lendForm.T_remark,
+				LendUser: lendForm.LendUser,
+				T_project: lendForm.T_project
+			})
+			lendForm.T_sn = ''
+			lendForm.T_remark = ''
+			ElMessage.success('已添加到待提交列表')
+			if ('speechSynthesis' in window) {
+				const utterance = new SpeechSynthesisUtterance('添加成功')
+				window.speechSynthesis.speak(utterance)
+			} else {
+				console.warn('Web Speech API 不被支持')
+			}
+		} else {
+		}
+	})
 }
 
 const removePendingLendItem = (index: number) => {
-  pendingLendItems.value.splice(index, 1)
-  ElMessage.success('已从待提交列表中移除')
+	pendingLendItems.value.splice(index, 1)
+	ElMessage.success('已从待提交列表中移除')
 }
 
 const submitLendPendingItems = async () => {
-  if (pendingLendItems.value.length === 0) {
-    ElMessage.warning('暂无数据可提交')
-    return
-  }
-  const rest = JSON.parse(JSON.stringify(pendingLendItems.value))
-
-  const result: any = await validation_update(rest)
-  if (result.Code == 200) {
-    ElMessage.success('提交成功')
-    pendingLendItems.value = []
-    lendForm.T_sn = ''
-    lendForm.T_remark = ''
-    lendForm.LendUser = ''
-    lendForm.T_project = ''
-    searchHandle()
-  } else {
-    ElMessage.error('提交失败')
-  }
+	if (pendingLendItems.value.length === 0) {
+		ElMessage.warning('暂无数据可提交')
+		return
+	}
+	const rest = JSON.parse(JSON.stringify(pendingLendItems.value))
+
+	const result: any = await validation_update(rest)
+	if (result.Code == 200) {
+		ElMessage.success('提交成功')
+		pendingLendItems.value = []
+		lendForm.T_sn = ''
+		lendForm.T_remark = ''
+		lendForm.LendUser = ''
+		lendForm.T_project = ''
+		searchHandle()
+		nextTick(() => {
+			showLendForm.value = false
+		})
+	} else {
+		ElMessage.error('提交失败')
+	}
 }
+
 const handleLendPageChange = (page: number) => {
-  lendCurrentPage.value = page
+	lendCurrentPage.value = page
 }
 
 const showEditForm = ref(false)
 const ImportEdit = ref(false)
 const editFormRef = ref<FormInstance | null>(null)
 const editForm = reactive({
-  T_sn: '',
-  Validationnumber: '',
-  T_remark: '',
-  T_state: '',
-  T_class: ''
+	T_sn: '',
+	Validationnumber: '',
+	T_remark: '',
+	T_state: '',
+	T_class: ''
 })
 
-const Repaid = () => {
-  submitRepaidForm()
-}
-
 const previewEdit = async (row: any) => {
-  showEditForm.value = true
-  const result: any = await readValidation({ sn: row.T_sn })
-  if (result.Code === 200) {
-    Object.assign(editForm, result.Data)
-  } else {
-    ElMessage.error('获取数据失败')
-  }
+	showEditForm.value = true
+	const result: any = await readValidation({sn: row.T_sn})
+	if (result.Code === 200) {
+		Object.assign(editForm, result.Data)
+	} else {
+		ElMessage.error('获取数据失败')
+	}
 }
 
 const submitEditForm = () => {
-  editFormRef.value?.validate(async (valid: boolean): Promise<void> => {
-    if (valid) {
-      const result: any = await updateValidation(editForm)
-      if (result.Code === 200) {
-        ElMessage.success('编辑成功')
-        showEditForm.value = false
-        searchHandle()
-      } else {
-        ElMessage.error('编辑失败')
-      }
-    } else {
-      // do nothing
-    }
-  })
+	editFormRef.value?.validate(async (valid: boolean): Promise<void> => {
+		if (valid) {
+			const result: any = await updateValidation(editForm)
+			if (result.Code === 200) {
+				ElMessage.success('编辑成功')
+				showEditForm.value = false
+				searchHandle()
+			} else {
+				ElMessage.error('编辑失败')
+			}
+		} else {
+			// do nothing
+		}
+	})
 }
 
 const handleFileChange = (file: any, fileList: any) => {
-  uploadFiles.value = fileList.map((item: any) => item.raw) // 新增:更新上传文件列表
+	uploadFiles.value = fileList.map((item: any) => item.raw) // 新增:更新上传文件列表
 }
 
 const submitUpload = async () => {
-  if (uploadFiles.value.length === 0) {
-    // 修改:使用 uploadFiles.value
-    ElMessage.warning('请先选择文件')
-    return
-  }
-  const formData = new FormData()
-  uploadFiles.value.forEach((file: File) => {
-    // 修改:遍历 uploadFiles.value
-    formData.append('excelFile', file)
-  })
-  const loading = ElLoading.service({
-    // 新增:显示加载动画
-    lock: true,
-    text: '正在上传文件...',
-    background: 'rgba(0, 0, 0, 0.7)'
-  })
-  try {
-    const result: any = await uploadFile(formData)
-    if (result.Code === 200) {
-      ElMessage.success('文件上传成功')
-      // 处理上传成功后的逻辑
-      searchHandle()
-      uploadFiles.value = [] // 新增:清除文件上传列表
-    } else {
-      ElMessage.error('文件上传失败')
-    }
-  } catch (error) {
-    ElMessage.error('文件上传失败,请检查网络连接')
-  } finally {
-    loading.close() // 新增:关闭加载动画
-  }
+	if (uploadFiles.value.length === 0) {
+		// 修改:使用 uploadFiles.value
+		ElMessage.warning('请先选择文件')
+		return
+	}
+	const formData = new FormData()
+	uploadFiles.value.forEach((file: File) => {
+		// 修改:遍历 uploadFiles.value
+		formData.append('excelFile', file)
+	})
+	const loading = ElLoading.service({
+		// 新增:显示加载动画
+		lock: true,
+		text: '正在上传文件...',
+		background: 'rgba(0, 0, 0, 0.7)'
+	})
+	try {
+		const result: any = await uploadFile(formData)
+		if (result.Code === 200) {
+			ElMessage.success('文件上传成功')
+			// 处理上传成功后的逻辑
+			searchHandle()
+			uploadFiles.value = [] // 新增:清除文件上传列表
+		} else {
+			ElMessage.error('文件上传失败')
+		}
+	} catch (error) {
+		ElMessage.error('文件上传失败,请检查网络连接')
+	} finally {
+		loading.close() // 新增:关闭加载动画
+	}
+}
+
+const btnRef = ref()
+const openDrawer = (tit: string, row: any, snItems: any) => {
+	btnRef.value.outerVisible = true
+	btnRef.value.data.title = tit
+	btnRef.value.data.snItems = snItems
+	btnRef.value.data.fromData = row
+}
+
+interface AddSnItem {
+	T_sn: string
+	Validationnumber: string
+	T_remark: string
+}
+
+const holdRepairForm = reactive({
+	T_sn: '',
+	T_remark: '',
+})
+const holdScrapForm = reactive({
+	T_sn: '',
+	T_remark: '',
+})
+const holdReturnForm = reactive({
+	T_sn: '',
+	T_remark: '',
+})
+const ReturnSnItems = ref<AddSnItem[]>([])
+const RepairSnItems = ref<AddSnItem[]>([])
+const ScrapSnItems = ref<AddSnItem[]>([])
+const successFun = () => {
+	TableRef.value?.searchTable()
+	btnRef.value.data.fromData.T_remark = ''
+	if (btnRef.value.data.title == '归还') {
+		ReturnSnItems.value = [];
+	}
+	if (btnRef.value.data.title == '维修') {
+		RepairSnItems.value = [];
+	}
+	if (btnRef.value.data.title == '报废') {
+		ScrapSnItems.value = [];
+	}
 }
 
 onMounted(() => {
-  getValidationToolClassList()
+	getValidationToolClassList()
 })
 </script>
 <template>
-  <div class="list">
-    <TableBase
-      ref="TableRef"
-      :columns="columns"
-      :requestApi="validation_List"
-      :initParam="initParam"
-      :pagination="true"
-    >
-      <template #table-header>
-        <div class="input-suffix">
-          <el-row :gutter="20" style="margin-bottom: 0">
-            <el-col :xl="3" :lg="3" :md="3">
-              <span class="inline-flex items-center">设备编号:</span>
-              <el-input
-                v-model="initParam.Validationnumber"
-                class="w-50 m-2"
-                type="text"
-                placeholder="设备编号搜索"
-                clearable
-                @change="searchHandle"
-              />
-            </el-col>
-            <el-col :xl="3" :lg="3" :md="3">
-              <span class="inline-flex items-center">状态:</span>
-              <el-select v-model="initParam.T_state" class="w-50 m-2" clearable placeholder="请选择状态~">
-                <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" />
-              </el-select>
-            </el-col>
-            <el-col :xl="3" :lg="3" :md="3">
-              <span class="inline-flex items-center">SN:</span>
-              <el-input
-                class="w-50 m-2"
-                v-model="initParam.T_sn"
-                type="text"
-                placeholder="按SN搜索"
-                clearable
-                @change="searchHandle"
-              />
-            </el-col>
-            <el-col :xl="3" :lg="3" :md="3">
-              <span class="inline-flex items-center">设备类型:</span>
-              <el-select v-model="initParam.T_class" class="w-50 m-2" clearable placeholder="请选择设备类型~">
-                <el-option v-for="item in Pruductoptions" :key="item.Id" :label="item.T_name" :value="item.Id" />
-              </el-select>
-            </el-col>
-            <el-col :xl="3" :lg="3" :md="3">
-              <span class="inline-flex items-center">模组imei:</span>
-              <el-input
-                class="w-50 m-2"
-                v-model="initParam.T_imei"
-                type="text"
-                placeholder="按模组imei搜索"
-                clearable
-                @change="searchHandle"
-              />
-            </el-col>
-            <el-col :xl="3" :lg="3" :md="3">
-              <span class="inline-flex items-center">借出人</span>
-              <el-input
-                class="w-50 m-2"
-                v-model="initParam.LendUser"
-                type="text"
-                placeholder="按借出人搜索"
-                clearable
-                @change="searchHandle"
-              />
-            </el-col>
-            <el-col :xl="3" :lg="3" :md="3">
-              <span class="inline-flex items-center">借出项目</span>
-              <el-input
-                class="w-50 m-2"
-                v-model="initParam.T_project"
-                type="text"
-                placeholder="按借出项目搜索"
-                clearable
-                @change="searchHandle"
-              />
-            </el-col>
-            <el-col :xl="3" :lg="3" :md="3">
-              <span class="inline-flex items-center">物联网卡号:</span>
-              <el-input
-                class="w-50 m-2"
-                v-model="initParam.T_iccid"
-                type="text"
-                placeholder="按物联网卡号搜索"
-                clearable
-                @change="searchHandle"
-              />
-            </el-col>
-            <el-col :xl="10" :lg="10" :md="10" style="margin-top: 10px">
-              <el-button type="primary" @click="searchHandle">搜索</el-button>
-              <el-button type="primary" @click="showInStorageForm = true">入库</el-button>
-              <el-button type="primary" @click="showLendForm = true">借出</el-button>
-              <el-button type="primary" @click="showrRepaidForm = true">归还</el-button>
-              <el-button type="success" @click="ImportEdit = true">模板导入</el-button>
-              <el-button type="success" @click="exportExcel">导出</el-button>
-            </el-col>
-          </el-row>
-        </div>
-      </template>
-      <template #T_state="{ row }">
-        <el-tag v-if="row.T_state == 1" type="success" effect="dark"> 已出库</el-tag>
-        <el-tag v-if="row.T_state == 2" effect="dark">未出库</el-tag>
-        <el-tag v-if="row.T_state == 3" effect="dark" type="danger">已损坏</el-tag>
-      </template>
-      <template #T_class="{ row }">
-        <el-tag>{{ Pruductoptions.find(option => option.Id === row.T_class)?.T_name || '' }}</el-tag>
-      </template>
-      <template #right="{ row }">
-        <el-button link type="success" size="small" :icon="Edit" @click="previewEdit(row)">编辑</el-button>
-        <el-button link type="danger" size="small" :icon="Delete" @click="deleteFun(row.T_sn)">删除</el-button>
-      </template>
-    </TableBase>
-  </div>
-  <!-- 新增入库表单 -->
-  <el-dialog title="入库" v-model="showInStorageForm" width="50%">
-    <el-form :model="inStorageForm" :rules="rules" ref="inStorageFormRef">
-      <el-form-item label="SN" prop="T_sn">
-        <el-input v-model="inStorageForm.T_sn" placeholder="请输入SN"></el-input>
-      </el-form-item>
-      <el-form-item label="设备编号" prop="Validationnumber">
-        <el-input v-model="inStorageForm.Validationnumber" placeholder="请输入设备编号"></el-input>
-      </el-form-item>
-      <el-form-item label="设备类型" prop="T_class">
-        <el-select v-model="inStorageForm.T_class" class="w-50 m-2" clearable placeholder="请选择设备类型~">
-          <el-option v-for="item in Pruductoptions" :key="item.Id" :label="item.T_name" :value="item.Id" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="备注">
-        <el-input v-model="inStorageForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
-      </el-form-item>
-    </el-form>
-    <!-- 新增数据条数提示 -->
-    <div style="margin: 10px 0">
-      <span>当前待提交数据条数: {{ pendingItems.length }}</span>
-    </div>
-    <el-table :data="paginatedPendingItems" style="width: 100%; margin-top: 20px">
-      <el-table-column type="index" label="序号" width="80"></el-table-column>
-      <!-- 添加序号列 -->
-      <el-table-column prop="T_sn" label="SN" width="300"></el-table-column>
-      <el-table-column prop="Validationnumber" label="设备编号"></el-table-column>
-      <el-table-column prop="T_class" label="设备类型"></el-table-column>
-      <el-table-column prop="T_remark" label="备注"></el-table-column>
-      <el-table-column label="操作" width="180">
-        <template #default="scope">
-          <el-button type="danger" size="small" @click="removePendingItem(scope.$index)">删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <el-pagination
-      background
-      layout="prev, pager, next"
-      :total="pendingItems.length"
-      :page-size="pageSize"
-      :current-page="currentPage"
-      @current-change="handlePageChange"
-      style="margin-top: 20px; text-align: right"
-    />
-    <template #footer>
+	<div class="list">
+		<TableBase
+			ref="TableRef"
+			:columns="columns"
+			:requestApi="validation_List"
+			:initParam="initParam"
+			:pagination="true"
+		>
+			<template #table-header>
+				<div class="input-suffix">
+					<el-row :gutter="20" style="margin-bottom: 0">
+						<el-col :xl="3" :lg="3" :md="3">
+							<span class="inline-flex items-center">设备编号:</span>
+							<el-input
+								v-model="initParam.Validationnumber"
+								class="w-50 m-2"
+								type="text"
+								placeholder="设备编号搜索"
+								clearable
+								@change="searchHandle"
+							/>
+						</el-col>
+						<el-col :xl="3" :lg="3" :md="3">
+							<span class="inline-flex items-center">状态:</span>
+							<el-select v-model="initParam.T_state" class="w-50 m-2" clearable placeholder="请选择状态~">
+								<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id"/>
+							</el-select>
+						</el-col>
+						<el-col :xl="3" :lg="3" :md="3">
+							<span class="inline-flex items-center">SN:</span>
+							<el-input
+								class="w-50 m-2"
+								v-model="initParam.T_sn"
+								type="text"
+								placeholder="按SN搜索"
+								clearable
+								@change="searchHandle"
+							/>
+						</el-col>
+						<el-col :xl="3" :lg="3" :md="3">
+							<span class="inline-flex items-center">设备类型:</span>
+							<el-select v-model="initParam.T_class" class="w-50 m-2" clearable
+									   placeholder="请选择设备类型~">
+								<el-option v-for="item in Pruductoptions" :key="item.Id" :label="item.T_name"
+										   :value="item.Id"/>
+							</el-select>
+						</el-col>
+						<el-col :xl="3" :lg="3" :md="3">
+							<span class="inline-flex items-center">模组imei:</span>
+							<el-input
+								class="w-50 m-2"
+								v-model="initParam.T_imei"
+								type="text"
+								placeholder="按模组imei搜索"
+								clearable
+								@change="searchHandle"
+							/>
+						</el-col>
+						<el-col :xl="3" :lg="3" :md="3">
+							<span class="inline-flex items-center">借出人</span>
+							<el-input
+								class="w-50 m-2"
+								v-model="initParam.LendUser"
+								type="text"
+								placeholder="按借出人搜索"
+								clearable
+								@change="searchHandle"
+							/>
+						</el-col>
+						<el-col :xl="3" :lg="3" :md="3">
+							<span class="inline-flex items-center">借出项目</span>
+							<el-input
+								class="w-50 m-2"
+								v-model="initParam.T_project"
+								type="text"
+								placeholder="按借出项目搜索"
+								clearable
+								@change="searchHandle"
+							/>
+						</el-col>
+						<el-col :xl="3" :lg="3" :md="3">
+							<span class="inline-flex items-center">物联网卡号:</span>
+							<el-input
+								class="w-50 m-2"
+								v-model="initParam.T_iccid"
+								type="text"
+								placeholder="按物联网卡号搜索"
+								clearable
+								@change="searchHandle"
+							/>
+						</el-col>
+						<el-col :xl="10" :lg="10" :md="10" style="margin-top: 10px">
+							<el-button type="primary" @click="searchHandle">搜索</el-button>
+							<el-button type="primary" @click="showInStorageForm = true">入库
+							</el-button>
+							<el-button type="primary" @click="showLendForm = true">借出
+							</el-button>
+							<el-button type="primary" @click="openDrawer('归还',holdReturnForm,ReturnSnItems)">归还
+							</el-button>
+							<el-button type="warning" @click="openDrawer('维修',holdRepairForm,RepairSnItems)">维修
+							</el-button>
+							<el-button type="danger" @click="openDrawer('报废',holdScrapForm,ScrapSnItems)">报废
+							</el-button>
+							<el-button type="success" @click="ImportEdit = true">模板导入</el-button>
+							<el-button type="success" @click="exportExcel">导出</el-button>
+						</el-col>
+					</el-row>
+				</div>
+			</template>
+			<template #T_state="{ row }">
+				<el-tag v-if="row.T_state == 1" type="success" effect="dark"> 已出库</el-tag>
+				<el-tag v-if="row.T_state == 2" effect="dark">未出库</el-tag>
+				<el-tag v-if="row.T_state == 3" effect="dark" type="warning">维修中</el-tag>
+				<el-tag v-if="row.T_state == 4" effect="dark" type="danger">已报废</el-tag>
+			</template>
+			<template #T_class="{ row }">
+				<el-tag>{{ Pruductoptions.find(option => option.Id === row.T_class)?.T_name || '' }}</el-tag>
+
+			</template>
+			<template #right="{ row }">
+				<el-button link type="success" size="small" :icon="Edit" @click="previewEdit(row)">编辑</el-button>
+				<el-button link type="danger" size="small" :icon="Delete" @click="deleteFun(row.T_sn)">删除</el-button>
+			</template>
+		</TableBase>
+		<el-dialog title="入库" v-model="showInStorageForm" width="50%">
+			<el-form :model="inStorageForm" :rules="rules" ref="inStorageFormRef">
+				<el-form-item label="SN" prop="T_sn">
+					<el-input v-model="inStorageForm.T_sn" placeholder="请输入SN"></el-input>
+				</el-form-item>
+				<el-form-item label="设备编号" prop="Validationnumber">
+					<el-input v-model="inStorageForm.Validationnumber" placeholder="请输入设备编号"></el-input>
+				</el-form-item>
+				<el-form-item label="设备类型" prop="T_class">
+					<el-select v-model="inStorageForm.T_class" class="w-50 m-2" clearable placeholder="请选择设备类型~">
+						<el-option v-for="item in Pruductoptions" :key="item.Id" :label="item.T_name" :value="item.Id"/>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="备注">
+					<el-input v-model="inStorageForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
+				</el-form-item>
+			</el-form>
+			<!-- 新增数据条数提示 -->
+			<div style="margin: 10px 0">
+				<span>当前待提交数据条数: {{ pendingItems.length }}</span>
+			</div>
+			<el-table :data="paginatedPendingItems" style="width: 100%; margin-top: 20px">
+				<el-table-column type="index" label="序号" width="80"></el-table-column>
+				<!-- 添加序号列 -->
+				<el-table-column prop="T_sn" label="SN" width="300"></el-table-column>
+				<el-table-column prop="Validationnumber" label="设备编号"></el-table-column>
+				<el-table-column prop="T_class" label="设备类型"></el-table-column>
+				<el-table-column prop="T_remark" label="备注"></el-table-column>
+				<el-table-column label="操作" width="180">
+					<template #default="scope">
+						<el-button type="danger" size="small" @click="removePendingItem(scope.$index)">删除</el-button>
+					</template>
+				</el-table-column>
+			</el-table>
+			<el-pagination
+				background
+				layout="prev, pager, next"
+				:total="pendingItems.length"
+				:page-size="pageSize"
+				:current-page="currentPage"
+				@current-change="handlePageChange"
+				style="margin-top: 20px; text-align: right"
+			/>
+			<template #footer>
       <span class="dialog-footer">
         <el-button @click="showInStorageForm = false">取消</el-button>
         <el-button type="primary" @click="submitInStorageForm">添加到暂存</el-button>
-        <!-- 新增提交按钮 -->
+		  <!-- 新增提交按钮 -->
         <el-button type="primary" @click="submitInStoragePendingItems">提交</el-button>
       </span>
-    </template>
-  </el-dialog>
-  <!-- 新增借出表单 -->
-  <el-dialog title="借出" v-model="showLendForm" width="50%">
-    <el-form :model="lendForm" :rules="lendRules" ref="lendFormRef">
-      <el-form-item label="SN" prop="T_sn">
-        <el-input v-model="lendForm.T_sn" placeholder="请输入SN" @keyup.enter="submitLendForm"></el-input>
-      </el-form-item>
-      <el-form-item label="备注">
-        <el-input v-model="lendForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
-      </el-form-item>
-      <!-- 新增借出人和借出项目 -->
-      <el-form-item label="借出人" prop="LendUser">
-        <el-input v-model="lendForm.LendUser" placeholder="请输入借出人"></el-input>
-      </el-form-item>
-      <el-form-item label="借出项目" prop="T_project">
-        <el-input v-model="lendForm.T_project" placeholder="请输入借出项目"></el-input>
-      </el-form-item>
-    </el-form>
-    <!-- 新增数据条数提示 -->
-    <div style="margin: 10px 0">
-      <span>当前待提交数据条数: {{ pendingLendItems.length }}</span>
-    </div>
-    <el-table :data="paginatedPendingLendItems" style="width: 100%; margin-top: 20px">
-      <el-table-column type="index" label="序号" width="80"></el-table-column>
-      <!-- 添加序号列 -->
-      <el-table-column prop="T_sn" label="SN" width="300"></el-table-column>
-      <el-table-column prop="LendUser" label="借出人"></el-table-column>
-      <el-table-column prop="T_project" label="借出项目"></el-table-column>
-      <el-table-column prop="T_remark" label="备注"></el-table-column>
-      <el-table-column label="操作" width="180">
-        <template #default="scope">
-          <el-button type="danger" size="small" @click="removePendingLendItem(scope.$index)">删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <el-pagination
-      background
-      layout="prev, pager, next"
-      :total="pendingLendItems.length"
-      :page-size="lendPageSize"
-      :current-page="lendCurrentPage"
-      @current-change="handleLendPageChange"
-      style="margin-top: 20px; text-align: right"
-    />
-    <template #footer>
+			</template>
+		</el-dialog>
+		<el-dialog title="借出" v-model="showLendForm" width="50%">
+			<el-form :model="lendForm" :rules="lendRules" ref="lendFormRef">
+				<el-form-item label="SN" prop="T_sn">
+					<el-input v-model="lendForm.T_sn" placeholder="请输入SN" @keyup.enter="submitLendForm"></el-input>
+				</el-form-item>
+				<el-form-item label="备注">
+					<el-input v-model="lendForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
+				</el-form-item>
+				<!-- 新增借出人和借出项目 -->
+				<el-form-item label="借出人" prop="LendUser">
+					<el-input v-model="lendForm.LendUser" placeholder="请输入借出人"></el-input>
+				</el-form-item>
+				<el-form-item label="借出项目" prop="T_project">
+					<el-input v-model="lendForm.T_project" placeholder="请输入借出项目"></el-input>
+				</el-form-item>
+			</el-form>
+			<!-- 新增数据条数提示 -->
+			<div style="margin: 10px 0">
+				<span>当前待提交数据条数: {{ pendingLendItems.length }}</span>
+			</div>
+			<el-table :data="paginatedPendingLendItems" style="width: 100%; margin-top: 20px">
+				<el-table-column type="index" label="序号" width="80"></el-table-column>
+				<!-- 添加序号列 -->
+				<el-table-column prop="T_sn" label="SN" width="300"></el-table-column>
+				<el-table-column prop="LendUser" label="借出人"></el-table-column>
+				<el-table-column prop="T_project" label="借出项目"></el-table-column>
+				<el-table-column prop="T_remark" label="备注"></el-table-column>
+				<el-table-column label="操作" width="180">
+					<template #default="scope">
+						<el-button type="danger" size="small" @click="removePendingLendItem(scope.$index)">删除
+						</el-button>
+					</template>
+				</el-table-column>
+			</el-table>
+			<el-pagination
+				background
+				layout="prev, pager, next"
+				:total="pendingLendItems.length"
+				:page-size="lendPageSize"
+				:current-page="lendCurrentPage"
+				@current-change="handleLendPageChange"
+				style="margin-top: 20px; text-align: right"
+			/>
+			<template #footer>
       <span class="dialog-footer">
         <el-button @click="showLendForm = false">取消</el-button>
         <el-button type="primary" @click="submitLendForm">添加到暂存</el-button>
-        <!-- 新增提交按钮 -->
+		  <!-- 新增提交按钮 -->
         <el-button type="primary" @click="submitLendPendingItems">提交</el-button>
       </span>
-    </template>
-  </el-dialog>
-  <el-dialog title="编辑" v-model="showEditForm" width="50%">
-    <el-form :model="editForm" ref="editFormRef">
-      <el-form-item label="SN" prop="T_sn">
-        <el-input v-model="editForm.T_sn" placeholder="请输入SN"></el-input>
-      </el-form-item>
-      <el-form-item label="设备编号" prop="Validationnumber">
-        <el-input v-model="editForm.Validationnumber" placeholder="请输入设备编号"></el-input>
-      </el-form-item>
-      <el-form-item label="状态">
-        <el-select v-model="editForm.T_state" class="w-50 m-2" clearable placeholder="请选择状态~">
-          <el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="设备类型">
-        <el-select v-model="editForm.T_class" class="w-50 m-2" clearable placeholder="请选择设备类型~">
-          <el-option v-for="item in Pruductoptions" :key="item.Id" :label="item.T_name" :value="item.Id" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="备注">
-        <el-input v-model="editForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
-      </el-form-item>
-    </el-form>
-    <template #footer>
+			</template>
+		</el-dialog>
+		<el-dialog title="编辑" v-model="showEditForm" width="50%">
+			<el-form :model="editForm" ref="editFormRef">
+				<el-form-item label="SN" prop="T_sn">
+					<el-input v-model="editForm.T_sn" placeholder="请输入SN"></el-input>
+				</el-form-item>
+				<el-form-item label="设备编号" prop="Validationnumber">
+					<el-input v-model="editForm.Validationnumber" placeholder="请输入设备编号"></el-input>
+				</el-form-item>
+				<el-form-item label="状态">
+					<el-select v-model="editForm.T_state" class="w-50 m-2" clearable placeholder="请选择状态~">
+						<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id"/>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="设备类型">
+					<el-select v-model="editForm.T_class" class="w-50 m-2" clearable placeholder="请选择设备类型~">
+						<el-option v-for="item in Pruductoptions" :key="item.Id" :label="item.T_name" :value="item.Id"/>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="备注">
+					<el-input v-model="editForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
+				</el-form-item>
+			</el-form>
+			<template #footer>
       <span class="dialog-footer">
         <el-button @click="showEditForm = false">取消</el-button>
         <el-button type="primary" @click="submitEditForm">提交</el-button>
       </span>
-    </template>
-  </el-dialog>
-  <!-- 新增归还表单 -->
-  <el-dialog title="归还" v-model="showrRepaidForm" width="50%">
-    <el-form :model="inStorageForm" :rules="rulesrepaid" ref="inStorageFormRef">
-      <el-form-item label="SN" prop="T_sn">
-        <el-input v-model="inStorageForm.T_sn" placeholder="请输入SN" @keyup.enter="Repaid"></el-input>
-      </el-form-item>
-      <el-form-item label="备注">
-        <el-input v-model="inStorageForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
-      </el-form-item>
-    </el-form>
-    <!-- 新增数据条数提示 -->
-    <div style="margin: 10px 0">
-      <span>当前待提交数据条数: {{ pendingItems.length }}</span>
-    </div>
-    <el-table :data="paginatedPendingItems" style="width: 100%; margin-top: 20px">
-      <el-table-column type="index" label="序号" width="80"></el-table-column>
-      <!-- 添加序号列 -->
-      <el-table-column prop="T_sn" label="SN"></el-table-column>
-      <el-table-column prop="T_remark" label="备注"></el-table-column>
-      <el-table-column label="操作" width="180">
-        <template #default="scope">
-          <el-button type="danger" size="small" @click="removePendingItem(scope.$index)">删除</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <el-pagination
-      background
-      layout="prev, pager, next"
-      :total="pendingItems.length"
-      :page-size="pageSize"
-      :current-page="currentPage"
-      @current-change="handlePageChange"
-      style="margin-top: 20px; text-align: right"
-    />
-    <template #footer>
-      <span class="dialog-footer">
-        <el-button @click="showInStorageForm = false">取消</el-button>
-        <el-button type="primary" @click="submitInStorageForm">添加到暂存</el-button>
-        <!-- 新增提交按钮 -->
-        <el-button type="primary" @click="submitInStoragePendingItems">提交</el-button>
-      </span>
-    </template>
-  </el-dialog>
-  <el-dialog title="模板导入" v-model="ImportEdit" width="50%">
-    <el-upload ref="uploadRef" class="upload-demo" :auto-upload="false" @change="handleFileChange">
-      <template #trigger>
-        <el-button type="primary">模板导入</el-button>
-      </template>
-
-      <el-button class="ml-3" type="success" @click="submitUpload"> 提交文件</el-button>
-      <template #tip></template>
-    </el-upload>
-  </el-dialog>
+			</template>
+		</el-dialog>
+
+		<el-dialog title="模板导入" v-model="ImportEdit" width="50%">
+			<el-upload ref="uploadRef" class="upload-demo" :auto-upload="false" @change="handleFileChange">
+				<template #trigger>
+					<el-button type="primary">模板导入</el-button>
+				</template>
+
+				<el-button class="ml-3" type="success" @click="submitUpload"> 提交文件</el-button>
+				<template #tip></template>
+			</el-upload>
+		</el-dialog>
+		<snAdd ref="btnRef" @successFun="successFun"></snAdd>
+
+	</div>
 </template>
 
 <style scoped lang="scss">
 @import '@/styles/var.scss';
 
 .list {
-  @include f-direction;
+	@include f-direction;
 }
 
 // .input-suffix {

+ 25 - 11
src/views/storehouse/inventory/IOTNetworkCard.vue

@@ -23,7 +23,7 @@ const formLabelWidth = ref('100px')
 const ruleFormRef = ref<FormInstance>()
 const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
 const uploadRef = ref<InstanceType<typeof Upload> | null>(null)
-const {resetForm, globalStore, searchOnTableList, updateOnTableList} = useTablePublic()
+const {resetForm, globalStore, searchOnTableList} = useTablePublic()
 const receiveUserdialog = ref<InstanceType<typeof ReceiveUser> | null>(null)
 const uploadFiles = ref<File[]>([]) // 新增:用于存储上传的文件
 const ImportEdit = ref(false)
@@ -36,14 +36,14 @@ const columns: ColumnProps[] = [
 	{type: 'selection', width: '44px', fixed: 'left'},
 	{type: 'index', label: '序号', width: 80},
 	{prop: 'T_company_name', label: '公司名称'},
-	{prop: 'T_in_date', label: '入库日期'},
+	{prop: 'T_in_date', label: '入库日期',width: 120},
 	{prop: 'T_meal_type', label: '套餐类型'},
 	{prop: 'T_meal', label: '套餐'},
 	{prop: 'T_expire', label: '到期&欠费'},
 	{prop: 'T_State', label: '状态'},
-	{prop: 'T_iccid', label: '串码'},
-	{prop: 'T_MSISDN', label: 'MSISDN'},
-	{prop: 'T_out_date', label: '出库日期'},
+	{prop: 'T_iccid', label: '串码', width: 220},
+	{prop: 'T_MSISDN', label: 'MSISDN',width: 150},
+	{prop: 'T_out_date', label: '出库日期',width: 120},
 	{prop: 'T_out_project', label: '出库项目'},
 	{prop: 'T_receive_name', label: '领用人'},
 	// {prop: 'T_remark', label: '备注'},
@@ -192,6 +192,7 @@ const initParam = reactive({
 	page: 1,
 	page_z: 10,
 	T_name: '',
+	T_company_name: '',
 	T_state: ''
 })
 
@@ -292,6 +293,7 @@ const openEditStateDialog =  (state: number) => {
 	editStateform.value.T_out_date = ''
 	editStateform.value.T_out_project = ''
 	editStateform.value.T_receive = ''
+	editStateform.value.T_receive_name = ''
 	editStateform.value.T_remark = ''
 	editStateform.value.T_State = state
 	if (state === 3) {
@@ -324,6 +326,7 @@ const editState = async (formEl: FormInstance | undefined) => {
 
 			nextTick(() => {
 				multipleSelection.value = []
+				editStateVisible.value = false
 			})
 			getIOTNetworkCard_List()
 		}
@@ -342,24 +345,34 @@ const preview = (list:any) => {
 		<el-card class="m-b-3">
 			<div class="input-suffix">
 			<el-row :gutter="20" style="margin-bottom: 0">
-				<el-col :xl="6" :lg="6" :md="5">
+				<el-col :xl="5" :lg="5" :md="4">
 					<span class="inline-flex items-center">关键字:</span>
 					<el-input
 						v-model="initParam.T_name"
 						type="text"
 						class="w-50 m-2"
-						placeholder="按串码、MSISDN、公司名称搜索"
+						placeholder="按串码、MSISDN、出库项目搜索"
 						@change="searchOnTableList"
 					/>
 				</el-col>
-				<el-col :xl="6" :lg="7" :md="8">
+				<el-col :xl="5" :lg="5" :md="4">
+					<span class="inline-flex items-center">公司名称:</span>
+					<el-input
+						v-model="initParam.T_company_name"
+						type="text"
+						class="w-50 m-2"
+						placeholder="按公司名称搜索"
+						@change="searchOnTableList"
+					/>
+				</el-col>
+				<el-col :xl="6" :lg="6" :md="5">
 					<span class="inline-flex items-center">状态:</span>
 					<el-select v-model="initParam.T_state" class="w-50 m-2" clearable placeholder="请选择状态~">
 						<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id"/>
 					</el-select>
 					<el-button type="primary" @click="searchModelHandle">搜索</el-button>
 				</el-col>
-				<el-col :xl="10" :lg="11" :md="11" class="btn">
+				<el-col :xl="8" :lg="8" :md="11" class="btn">
 					<el-button type="primary" @click="openDrawer('new')">入库</el-button>
 					<el-button type="success" @click="ImportEdit = true">导入</el-button>
 					<el-button type="primary" @click="openEditStateDialog(3)">出库</el-button>
@@ -376,12 +389,13 @@ const preview = (list:any) => {
 				:row-key="getRowKey"
 				:highlight-current-row="true"
 				@selection-change="handleSelectionChange"
-				style="width: 100%; height: 100%"
+				height="580px"
+				style="width: 100%"
 			>
 				<template v-for="(item, index) in columns" :key="index">
 					<el-table-column
 						show-overflow-tooltip
-						v-if="item.type === 'index' || item.fixed === 'left' || item.type === 'selection'"
+						v-if="item.type === 'index' || item.fixed === 'left'"
 						:selectable="selectableDisable"
 						:type="item.type"
 						align="center"

+ 8 - 2
src/views/storehouse/sales/MyPercentage.vue

@@ -16,9 +16,11 @@ const {globalStore, searchOnTableList} = useTablePublic()
 
 const columns: ColumnProps[] = [
 	{type: 'index', label: '序号', width: 80},
-	{prop: 'T_task_id', label: '任务编号'},
 	{prop: 'T_verifyCompany_name', label: '公司名称', name: 'T_verifyCompany_name'},
 	{prop: 'T_verifyCompany_State', label: '回款状态', name: 'T_verifyCompany_State'},
+	{prop: 'T_recoveries_time', label: '回款时间', name: 'T_recoveries_time'},
+	{prop: 'T_task_id', label: '任务编号'},
+	{prop: 'T_task_name', label: '任务名称'},
 	{prop: 'T_reporting_pass_time', label: '统计日期'},
 	{prop: 'T_type', label: '提成类型', name: 'T_type'},
 	{prop: 'T_device_type', label: '设备类型'},
@@ -111,7 +113,7 @@ const processdel = (id: any) => {
 				<div class="input-suffix">
 					<el-row :gutter="20" style="margin-bottom: 0">
 						<el-col :xl="6" :lg="7" :md="11" style="display: flex">
-							<span class="inline-flex items-center">统计日期:</span>
+							<span class="inline-flex items-center">回款日期:</span>
 							<el-date-picker
 								v-model="T_date"
 								type="daterange"
@@ -168,11 +170,15 @@ const processdel = (id: any) => {
 				<el-tag v-if="row.T_verifyCompany.T_State === 1" type="info" effect="dark"> 未回款</el-tag>
 				<el-tag v-if="row.T_verifyCompany.T_State === 2" type="success" effect="dark"> 已回款</el-tag>
 			</template>
+			<template #T_recoveries_time="{ row }">
+				{{row.T_verifyCompany.T_recoveries_time}}
+			</template>
 			<template #right="{ row }">
 				<el-button link type="primary" size="small" :disabled="![3,6].includes(row.T_State)" :icon="Check"
 						   @click="SubmitReview(row)">提交审核
 				</el-button>
 				<el-button link type="primary" size="small" :disabled="![1,3,6].includes(row.T_State)" :icon="Edit"
+
 						   @click="openContractFormDrawer('edit', row)">编辑
 				</el-button>
 				<el-button link type="success" size="small" :icon="View" @click="processContract(row.Id,'详情')">详情

+ 27 - 57
src/views/storehouse/sales/MyPercentageForm.vue

@@ -11,14 +11,10 @@ import {
 
 import { ElMessage } from 'element-plus'
 import TableDetail from './TableDetail.vue'
-import { ref, reactive, nextTick,onMounted } from 'vue'
+import { ref, reactive, nextTick } from 'vue'
 import Drawer from '@/components/Drawer/index.vue'
 import type { FormInstance, FormRules } from 'element-plus'
-import ContractUser from '@/views/storehouse/outStock/receiveUser.vue'
-import MyPercentageFormStorage from '@/views/storehouse/inventory/MyPercentageFormStorage.vue'
-import verifyxiang from '@/views/storehouse/sales/verifyxiang.vue'
-import {verifyCompany_list} from "@/api/percentage";
-
+import SelectVerifyCompany from '@/views/storehouse/sales/SelectVerifyCompany.vue'
 const isNew = ref(true)
 const isProduct = ref(false)
 const tableData = ref<any[]>([])
@@ -26,10 +22,11 @@ const formLabelWidth = ref('120px')
 const { resetForm } = useTablePublic()
 const ruleFormRef = ref<FormInstance>()
 const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
-const receiveUserdialog = ref<InstanceType<typeof ContractUser> | null>(null)
+
 const RecoveriesRef = ref<InstanceType<typeof TableDetail> | null>(null)
 const InvoiceRef = ref<InstanceType<typeof TableDetail> | null>(null)
-let coldVerifyCompanyList: any = []
+const verifyCompany = ref<InstanceType<typeof SelectVerifyCompany> | null>(null)
+
 
 const rules = reactive<FormRules>({
   T_company_uuid: [{ required: true, message: '请输入公司', trigger: 'blur' }],
@@ -39,8 +36,7 @@ const rules = reactive<FormRules>({
 })
 
 const data: any = reactive({
-	verifyType: [{T_name:'年度定期验证'},{T_name:'使用前验证空载'},{T_name:'使用前验证满载'},{T_name:'停用超时验证'},{T_name:'极冷验证'},{T_name:'极热验证'},],
-	deviceType: [{T_name:'保温箱'},{T_name:'冷冻箱'},{T_name:'冷藏柜'},{T_name:'冷冻柜'},{T_name:'阴凉柜'},{T_name:'冷藏车'},{T_name:'冷库'},{T_name:'冰柜'},{T_name:'低温保存箱'},{T_name:'系统验证'},{T_name:'位置'}]
+	deviceType: [{T_name:'其他'}]
 })
 
 const callbackDrawer = (done: () => void) => {
@@ -56,6 +52,8 @@ const form = reactive<MyPercentageFormType>({
   T_device_type: '',
   T_verify_type: '',
   T_company_uuid: '',
+  T_verifyCompany_name: '',
+  T_money: '',
   T_type: 1,
 
 })
@@ -79,9 +77,10 @@ const editDataEcho = async (row: any) => {
   form.T_device_type = row.T_device_type
   form.T_verify_type = row.T_verify_type
   form.T_company_uuid = row.T_company_uuid
+  form.T_verifyCompany_name = row.T_verifyCompany.T_name
+  form.T_money = row.T_money
 }
 
-
 const getFomrParams = () => {
   const params = {...form}
   return params
@@ -91,7 +90,6 @@ const AddContract = (formEl: FormInstance | undefined) => {
   formEl.validate(async valid => {
     if (valid) {
       let res: any = {}
-      await blurfindFun()
       const params = getFomrParams()
       if (isNew.value) {
         res = await percentage_Add(params)
@@ -108,51 +106,25 @@ const AddContract = (formEl: FormInstance | undefined) => {
     } else false
   })
 }
-//筛选验证产品明细是否填写了数量
-const blurfindFun = async ()=>{
-  return new Promise((reslove:any)=>{
-    const reslut = tableData.value.every((item:any)=>item.count!='')
-    if(!reslut){
-      ElMessage.error('请填写验证产品明细【数量】')
-    }else{
-      reslove()
-    }
-  })
-}
-
-const drawerProductRef = ref<InstanceType<typeof MyPercentageFormStorage> | null>(null)
-const verifyxiangRef = ref<InstanceType<typeof verifyxiang> | null>(null)
 
 const closeCancle = () => {
   resetForm(ruleFormRef.value)
   isNew.value = isProduct.value = false
   tableData.value = []
-  drawerProductRef.value?.clearSelection()
   RecoveriesRef.value?.clearDetail()
   InvoiceRef.value?.clearDetail()
   drawerRef.value?.closeDrawer()
 }
 
-const getColdVerifyCompanyList = async () => {
-	const res: any = await verifyCompany_list({})
-	coldVerifyCompanyList = res.Data.Data
-}
-
-const loading = ref(false)
-interface ListItem {
-    value: string
-    label: string
-}
-const list = ref<ListItem[]>([])
-const options = ref<ListItem[]>([])
 defineExpose({
   openDrawer,
 })
-onMounted(() => {
-	if (coldVerifyCompanyList.length <= 0) {
-		getColdVerifyCompanyList()
-	}
-})
+const selectCompany = () => verifyCompany.value?.openDrawer()
+const getCompanyInfo = ({T_uuid, T_name}: { T_uuid: string; T_name: string }) => {
+	form.T_verifyCompany_name = T_name
+	form.T_company_uuid = T_uuid
+}
+
 </script>
 
 <template>
@@ -162,10 +134,9 @@ onMounted(() => {
         <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_company_uuid">
-          <el-select v-model="form.T_company_uuid" class="w-50" filterable placeholder="请选择公司">
-            <el-option v-for="item in coldVerifyCompanyList" :key="item.T_uuid" :label="item.T_name" :value="item.T_uuid" />
-          </el-select>
+        <el-form-item label="公司名称:" :label-width="formLabelWidth" prop="T_verifyCompany_name">
+			<el-input v-model="form.T_verifyCompany_name" type="text" autocomplete="off" placeholder="请选择公司"
+					  @focus="selectCompany" class="w-50" />
         </el-form-item>
         <el-form-item label="提成类型:" :label-width="formLabelWidth" prop="T_type">
           <el-radio-group v-model="form.T_type" :disabled="isNew?false:true" >
@@ -178,11 +149,12 @@ onMounted(() => {
             <el-option v-for="item in data.deviceType" :key="item.T_name" :label="item.T_name" :value="item.T_name" />
           </el-select>
         </el-form-item>
-        <el-form-item label="验证类型:" :label-width="formLabelWidth" prop="T_verify_type">
-          <el-select v-model="form.T_verify_type" class="w-50" placeholder="请选择验证类型">
-            <el-option v-for="item in data.verifyType" :key="item.T_name" :label="item.T_name" :value="item.T_name" />
-          </el-select>
-        </el-form-item>
+		  <el-form-item label="验证类型:" :label-width="formLabelWidth" prop="T_verify_type">
+			  <el-input v-model="form.T_verify_type" placeholder="请输入验证类型" class="w-50" />
+		  </el-form-item>
+		  <el-form-item label="提成金额:" :label-width="formLabelWidth" prop="T_money">
+			  <el-input v-model="form.T_money" placeholder="请输入提成金额" class="w-50" />
+		  </el-form-item>
       </el-form>
       <template #footer>
         <div>
@@ -195,10 +167,8 @@ onMounted(() => {
         </div>
       </template>
     </Drawer>
-<!--    <ContractUser ref="receiveUserdialog" @onUserInfo="getReceiveInfo" title="合同负责人" />-->
-<!--    <MyPercentageFormStorage v-if="isProduct" ref="drawerProductRef" :selectProductData="selectProductData"-->
-<!--      @ontableData="ProductselectionChange" @ontableDataAll="ProductSelectionAllChange"></MyPercentageFormStorage>-->
-<!--      <verifyxiang ref="verifyxiangRef"></verifyxiang>-->
+
+    <SelectVerifyCompany ref="verifyCompany" @onUserInfo="getCompanyInfo" title="公司列表" />
   </div>
 </template>
 

+ 13 - 4
src/views/storehouse/sales/Percentage.vue

@@ -25,9 +25,11 @@ const multipleSelection = ref<any[]>([])
 const columns: ColumnProps[] = [
   { type: 'selection', width: '44px', fixed: 'left'},
   { type: 'index', label: '序号', width: 80 },
-  { prop: 'T_task_id', label: '任务编号'},
   { prop: 'T_verifyCompany_name', label: '公司名称', name: 'T_verifyCompany_name'},
   { prop: 'T_verifyCompany_State', label: '回款状态', name: 'T_verifyCompany_State'},
+  { prop: 'T_recoveries_time', label: '回款时间', name: 'T_recoveries_time'},
+  { prop: 'T_task_id', label: '任务编号'},
+  { prop: 'T_task_name', label: '任务名称'},
   { prop: 'T_reporting_pass_time', label: '统计日期'},
   { prop: 'T_type', label: '提成类型', name: 'T_type' },
   { prop: 'T_device_type', label: '设备类型'},
@@ -87,13 +89,17 @@ const remoteMethod = async (query: string) => {
       })
     }, 200)
   } else {
-    optionsData.value = []
+    optionsData.value = list.value
   }
 }
 const click2 = async () => { optionsData.value = list.value }
 onMounted(async () => {
   const result: any = await percentage_User_List({})
-  let arr = result.Data.Data || []
+	let arr =  []
+	if (result?.Data !== null) {
+		arr = result.Data.Data
+	}
+
   list.value = arr.map((item: any) => {
     return { value: item.T_uuid, label: item.T_name }
   })
@@ -193,7 +199,7 @@ const batchSubmitApproval = async () => {
         <div class="input-suffix">
           <el-row :gutter="20" style="margin-bottom: 0">
             <el-col :xl="6" :lg="6" :md="5" style="display: flex">
-				  <span class="inline-flex items-center">统计日期:</span>
+				  <span class="inline-flex items-center">回款日期:</span>
 				  <el-date-picker
 					  v-model="T_date"
 					  type="daterange"
@@ -252,6 +258,9 @@ const batchSubmitApproval = async () => {
         <el-tag v-if="row.T_verifyCompany.T_State === 1" type="info" effect="dark"> 未回款</el-tag>
         <el-tag v-if="row.T_verifyCompany.T_State === 2" type="success" effect="dark"> 已回款</el-tag>
       </template>
+		<template #T_recoveries_time="{ row }">
+			{{row.T_verifyCompany.T_recoveries_time}}
+		</template>
       <template #right="{ row }">
         <el-button link type="warning" :disabled="![1, 3].includes(row.T_State)" size="small" :icon="Finished"
           @click="processContract('审核', row)">审核</el-button>

+ 0 - 3
src/views/storehouse/sales/PercentageDetail1.vue

@@ -151,9 +151,6 @@ const blurfindFun = async ()=>{
 }
 const drawerProductRef = ref<InstanceType<typeof MyPercentageFormStorage> | null>(null)
 
-const router = useRouter()
-
-
 const closeCancle = () => {
   resetForm(ruleFormRef.value)
   isNew.value = isProduct.value = false

+ 83 - 0
src/views/storehouse/sales/SelectVerifyCompany.vue

@@ -0,0 +1,83 @@
+<script setup lang="ts">
+import { ref, onMounted } from 'vue'
+import Drawer from '@/components/Drawer/index.vue'
+import { GlobalStore } from '@/stores/index'
+import TableBase from '@/components/TableBase/index.vue'
+import { ColumnProps } from '@/components/TableBase/interface/index'
+import {verifyCompany_list} from "@/api/percentage";
+
+const search = ref('')
+const globalStore = GlobalStore()
+const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
+const tableRef = ref<InstanceType<typeof TableBase> | null>(null)
+
+const Dialogcolumns: ColumnProps[] = [{ prop: 'T_name', label: '公司名称' }]
+const InitParam = {
+  User_tokey: globalStore.GET_User_tokey,
+  T_name: ''
+}
+const searchHandle = () => {
+  InitParam.T_name = search.value
+  tableRef.value?.searchTable()
+}
+/**
+ * 获取信息
+ */
+const getVerifyCompanyInfo = (row: any) => {
+	drawerRef.value?.closeDrawer()
+	emit('onUserInfo', row)
+}
+
+const props = withDefaults(defineProps<{ title: string }>(), {})
+const title = ref(props.title)
+
+const callbackDrawer = (done: () => void) => {
+	drawerRef.value?.closeDrawer()
+	done()
+}
+
+const emit = defineEmits<{ (event: 'onUserInfo', value: any): void }>()
+const openDrawer = () => drawerRef.value?.openDrawer()
+defineExpose({
+  openDrawer
+})
+
+</script>
+
+<template>
+  <div class="VerifyCompany">
+    <Drawer ref="drawerRef" :handleClose="callbackDrawer">
+      <template #header="{ params }">
+        <h3 :id="params.titleId" :class="params.titleClass">{{ title }}</h3>
+      </template>
+      <TableBase
+        ref="tableRef"
+        :columns="Dialogcolumns"
+        :initParam="InitParam"
+        :requestApi="verifyCompany_list"
+        layout="total, prev, pager, next"
+        :rowClick="getVerifyCompanyInfo"
+      >
+        <template #table-header>
+          <el-row :gutter="20">
+            <el-col :span="24" class="d-flex">
+              <span class="inline-flex">公司名称:</span>
+              <el-input v-model="search" type="text" placeholder="按公司名称搜索" />
+              <el-button type="primary" @click="searchHandle">搜索</el-button>
+            </el-col>
+          </el-row>
+        </template>
+      </TableBase>
+    </Drawer>
+  </div>
+</template>
+
+<style scoped>
+.inline-flex {
+  white-space: nowrap;
+}
+.d-flex {
+  display: flex;
+  align-items: center;
+}
+</style>

+ 17 - 1
src/views/storehouse/sales/VerifyCompany.vue

@@ -28,6 +28,7 @@ const columns: ColumnProps[] = [
   { type: 'index', label: '序号', width: 80 },
   { prop: 'T_name', label: '公司名称' },
   { prop: 'T_State', label: '状态' , name: 'T_State'},
+  { prop: 'T_recoveries_time', label: '回款时间'},
   { prop: 'operation', label: '操作', width: 150, fixed: 'right' }
 ]
 
@@ -47,9 +48,11 @@ const openDrawer = (type: string, row?: any) => {
     form.value.T_uuid = row.T_uuid
     form.value.T_name = row.T_name
     form.value.T_State = row.T_State
+    form.value.T_recoveries_time = row.T_recoveries_time
   }else{
     delete form.value.T_uuid
     form.value.T_name = ''
+    form.value.T_recoveries_time = ''
     form.value.T_State = 1
   }
   drawerRef.value?.openDrawer()
@@ -160,11 +163,24 @@ const initParam = reactive({
         <el-form-item label="公司名称:" class="m-b-6" :label-width="formLabelWidth" prop="T_name">
           <el-input v-model="form.T_name" type="text" :disabled=!isNew autocomplete="off" placeholder="请填写公司名称" />
         </el-form-item>
+
+
         <el-form-item label="状态:" class="m-b-6" :label-width="formLabelWidth" prop="T_State">
           <el-radio-group v-model="form.T_State" class="ml-4">
-            <el-radio :label="item.id" v-for="item,index in options4">{{item.name}}</el-radio>
+            <el-radio :label="item.id" v-for="item in options4">{{item.name}}</el-radio>
           </el-radio-group>
         </el-form-item>
+		  <el-form-item label="回款时间:" :label-width="formLabelWidth" prop="T_recoveries_time">
+			  <el-date-picker
+				  class="my-date-picker"
+				  style="width: 21.5rem"
+				  v-model="form.T_recoveries_time"
+				  type="date"
+				  placeholder="选择日期"
+				  format="YYYY-MM-DD"
+				  value-format="YYYY-MM-DD"
+			  />
+		  </el-form-item>
         
         <el-form-item :label-width="formLabelWidth">
           <el-button v-if="isNew" color="#626aef" @click="AddVerifyCompany(ruleFormRef)">提交</el-button>

+ 185 - 0
src/views/storehouse/verifyCompany/MyVerifyPercentage.vue

@@ -0,0 +1,185 @@
+<script setup lang="ts">
+import {
+	Storehouse_VerifyContract_Recover_List,
+	Storehouse_VerifyContract_Recover_Export
+} from '@/api/storehouse'
+import { useRouter } from 'vue-router'
+import { ElMessage } from 'element-plus'
+import { ref, reactive, nextTick ,defineAsyncComponent} from 'vue'
+import Drawer from '@/components/Drawer/index.vue'
+import TableBase from '@/components/TableBase/index.vue'
+import {Check, Edit, View} from '@element-plus/icons-vue'
+import type { ColumnProps } from '@/components/TableBase/interface'
+import type { FormInstance, FormRules } from 'element-plus'
+import { useTablePublic } from '@/hooks/useTablePublic'
+import { fnMd5 } from '@/utils/common'
+const router = useRouter()
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
+const { globalStore, searchOnTableList, updateOnTableList} = useTablePublic()
+
+const customer_id = ref('')
+
+const columns: ColumnProps[] = [
+  { type: 'index', label: '序号', width: 80 },
+  { prop: 'T_customer', label: '客户名称' , width: 260},
+  { prop: 'T_number', label: '合同编号' },
+  { prop: 'T_date', label: '签约时间', width: 120 },
+  { prop: 'T_recoveries_state', label: '回款状态', name:'T_recoveries_state'},
+  { prop: 'T_recoveries_time', label: '回款时间', width: 120},
+  { prop: 'T_type', label: '合同类型', name: 'T_type'},
+  { prop: 'T_discount', label: '合同金额' },
+  { prop: 'T_recoveries_money', label: '回款金额' },
+  { prop: 'T_submit_name', label: '提成人员' },
+  { prop: 'T_percentage_money', label: '提成金额', name: 'T_percentage_money'},
+  { prop: 'T_percentage_state', label: '提成状态', name: 'T_percentage_state'},
+]
+const options1 = reactive([
+  { name: '未回款', id: 1 },
+  { name: '部分回款', id: 2 },
+  { name: '全部回款', id: 3 },
+])
+
+const percentageStateOptions = reactive([
+	{ name: '未打款', id: 1 },
+	{ name: '已打款', id: 2 },
+])
+
+const ContractFormRef = ref<InstanceType<typeof ContractForm> | null>(null)
+const VerifyFormRef = ref<InstanceType<typeof VerifyForm> | null>(null)
+
+
+const ContractForm = defineAsyncComponent({
+  loader: () => import(/*webpackChunkName: 'ContractForm'*/ '../sales/ContractForm.vue'),
+  delay: 500,
+  timeout: 3000,
+  suspensible: true
+})
+const VerifyForm = defineAsyncComponent({
+  loader: () => import(/*webpackChunkName: 'ContractForm'*/ '../sales/VerifyForm.vue'),
+  delay: 500,
+  timeout: 3000,
+  suspensible: true
+})
+// 搜索
+const T_date = ref<string[]>([])
+const initParam = reactive({
+  User_tokey: globalStore.GET_User_tokey,
+  T_name: '',
+  T_percentage_state: '',//提成状态
+  T_recoveries_state: '',//回款状态
+  T_mine:1
+})
+
+const processContract = (id: string) => router.push({ name: 'ContractDetail', params: { id, type: fnMd5('contract') } })
+
+// 导出
+const exportPercentageExcel = async () => {
+	// initParam.T_end_date = T_date.value ? T_date.value[1] : ''
+	// initParam.T_start_date = T_date.value ? T_date.value[0] : ''
+	TableRef.value?.searchTable()
+	const res: any = await Storehouse_VerifyContract_Recover_Export(initParam)
+	if (res.Code === 200) {
+		window.open(res.Data)
+	}
+}
+</script>
+
+<template>
+  <div class="verify-contract">
+    <TableBase
+      ref="TableRef"
+      :columns="columns"
+      :requestApi="Storehouse_VerifyContract_Recover_List"
+      :initParam="initParam"
+    >
+
+      <template #table-header>
+        <el-row :gutter="20" style="margin-bottom: 0" class="input-suffix">
+          <el-col :xl="5" :lg="5" :md="5" style="display: flex">
+				<span class="inline-flex items-center">回款日期:</span>
+				<el-date-picker
+					v-model="T_date"
+					type="daterange"
+					range-separator="~"
+					start-placeholder="开始时间"
+					end-placeholder="结束时间"
+					format="YYYY-MM-DD"
+					value-format="YYYY-MM-DD"
+				/>
+			</el-col>
+          <el-col :xl="5" :lg="5" :md="5" class="d-flex">
+            <span class="inline-flex items-center">合同编号:</span>
+            <el-input
+              v-model="initParam.T_name"
+              type="text"
+              class="w-50 m-2"
+              placeholder="按编号搜索"
+              @change="searchOnTableList(TableRef)"
+            />
+          </el-col>
+          <el-col :xl="5" :lg="5" :md="5" class="d-flex">
+			<span class="inline-flex items-center">提成状态:</span>
+			<el-select v-model="initParam.T_percentage_state" class="w-50" clearable placeholder="请选择">
+				<el-option v-for="item in percentageStateOptions" :key="item.id" :label="item.name" :value="item.id" />
+			</el-select>
+          </el-col>
+          <el-col :xl="5" :lg="5" :md="5" class="d-flex">
+            <span class="inline-flex items-center">回款状态:</span>
+            <el-select v-model="initParam.T_recoveries_state" class="w-50" clearable placeholder="请选择">
+              <el-option v-for="item in options1" :key="item.id" :label="item.name" :value="item.id" />
+            </el-select>
+			  <el-button type="primary" @click="searchOnTableList(TableRef)">搜索</el-button>
+          </el-col>
+          <el-col :xl="4" :lg="4" :md="4"  class="d-flex">
+				<el-button type="primary" @click="exportPercentageExcel">导出表格</el-button>
+			</el-col>
+        </el-row>
+      </template>
+		<template #T_recoveries_state="{ row }">
+			<el-text v-if="row.T_recoveries_state === '全部回款'" type="success" effect="dark">全部回款</el-text>
+			<el-text v-else-if="row.T_recoveries_state === '部分回款'" type="primary" effect="dark">部分回款</el-text>
+			<el-text v-else type="info" effect="dark">未回款</el-text>
+		</template>
+      <template #T_type="{ row }">
+        <el-tag :type="row.T_type==1?'':'success'" effect="dark"> {{row.T_type==1?'销售合同':row.T_type==2?'验证合同':'-'}} </el-tag>
+      </template>
+		<template #T_percentage_money="{ row }">
+        {{row.T_discount*0.05}}
+      </template>
+		<template #T_percentage_state="{ row }">
+			<el-text v-if="row.T_percentage_state === 2" type="success" effect="dark">已打款</el-text>
+			<el-text v-else type="info" effect="dark">未打款</el-text>
+      </template>
+      <template #right="{ row }">
+         <el-button link type="success" size="small" :icon="View" @click="processContract(row.T_number)">明细</el-button>
+      </template>
+    </TableBase>
+    <ContractForm ref="ContractFormRef" @onTableList="updateOnTableList(TableRef)" />
+    <VerifyForm ref="VerifyFormRef" @onTableList="updateOnTableList(TableRef)" :verify_customer_id="customer_id" />
+  </div>
+</template>
+
+<style scoped lang="scss">
+@import '@/styles/var.scss';
+
+.verify-contract {
+  @include f-direction;
+
+  :deep(.el-drawer__header) {
+    margin-bottom: 0;
+  }
+  .input-suffix {
+    width: 100%;
+    .inline-flex {
+      white-space: nowrap;
+    }
+    .btn {
+      display: flex;
+      justify-content: end;
+    }
+    .w-50 {
+      flex: 0 0 55%;
+    }
+  }
+}
+</style>

+ 4 - 4
src/views/storehouse/sales/Recoveries.vue → src/views/storehouse/verifyCompany/Recoveries.vue

@@ -3,14 +3,14 @@ import {
   Storehouse_VerifyContract_Add_Customer,
   Storehouse_VerifyContract_Recover_List,
   Storehouse_VerifyContract_Update_Customer
-} from '@/api/storehouse/index'
+} from '@/api/storehouse'
 import { useRouter } from 'vue-router'
 import { ElMessage } from 'element-plus'
 import { ref, reactive, nextTick ,defineAsyncComponent} from 'vue'
 import Drawer from '@/components/Drawer/index.vue'
 import TableBase from '@/components/TableBase/index.vue'
 import { Edit, View } from '@element-plus/icons-vue'
-import type { ColumnProps } from '@/components/TableBase/interface/index'
+import type { ColumnProps } from '@/components/TableBase/interface'
 import type { FormInstance, FormRules } from 'element-plus'
 import { useTablePublic } from '@/hooks/useTablePublic'
 import { fnMd5 } from '@/utils/common'
@@ -63,13 +63,13 @@ const openContractFormDrawer = (type: string, row?: any) => {
 // const processContract = (id: string) => router.push({ name: 'VerifyContractDetail', params: { id } })
 
 const ContractForm = defineAsyncComponent({
-  loader: () => import(/*webpackChunkName: 'ContractForm'*/ './ContractForm.vue'),
+  loader: () => import(/*webpackChunkName: 'ContractForm'*/ '../sales/ContractForm.vue'),
   delay: 500,
   timeout: 3000,
   suspensible: true
 })
 const VerifyForm = defineAsyncComponent({
-  loader: () => import(/*webpackChunkName: 'ContractForm'*/ './VerifyForm.vue'),
+  loader: () => import(/*webpackChunkName: 'ContractForm'*/ '../sales/VerifyForm.vue'),
   delay: 500,
   timeout: 3000,
   suspensible: true

+ 3 - 3
src/views/storehouse/sales/VerifyContract.vue → src/views/storehouse/verifyCompany/VerifyContract.vue

@@ -3,14 +3,14 @@ import {
   Storehouse_VerifyContract_Add_Customer,
   Storehouse_VerifyContract_Customer_List,
   Storehouse_VerifyContract_Update_Customer
-} from '@/api/storehouse/index'
+} from '@/api/storehouse'
 import { useRouter } from 'vue-router'
 import { ElMessage } from 'element-plus'
 import { ref, reactive, nextTick } from 'vue'
 import Drawer from '@/components/Drawer/index.vue'
 import TableBase from '@/components/TableBase/index.vue'
 import { Edit, View } from '@element-plus/icons-vue'
-import type { ColumnProps } from '@/components/TableBase/interface/index'
+import type { ColumnProps } from '@/components/TableBase/interface'
 import type { FormInstance, FormRules } from 'element-plus'
 import { useTablePublic } from '@/hooks/useTablePublic'
 
@@ -137,7 +137,7 @@ const AddContract = (formEl: FormInstance | undefined) => {
       </template>
       <el-form ref="ruleFormRef" :model="form" :rules="rules">
         <el-form-item label="客户名称:" label-width="100px" prop="T_customer">
-          <el-input v-model="form.T_customer" type="text" autocomplete="off" placeholder="请输入仓库名称" />
+          <el-input v-model="form.T_customer" type="text" autocomplete="off" placeholder="请输入客户名称" />
         </el-form-item>
         <el-form-item label-width="100px">
           <el-button v-if="isNew" color="#626aef" @click="AddContract(ruleFormRef)">提交</el-button>

+ 251 - 0
src/views/storehouse/verifyCompany/VerifyPercentage.vue

@@ -0,0 +1,251 @@
+<script setup lang="ts">
+import {
+	Storehouse_Contract_Percentage_Remit,
+	Storehouse_VerifyContract_Recover_Export,
+	Storehouse_VerifyContract_Recover_List,
+} from '@/api/storehouse'
+import { useRouter } from 'vue-router'
+import { ElMessage } from 'element-plus'
+import { ref, reactive, nextTick ,defineAsyncComponent} from 'vue'
+import Drawer from '@/components/Drawer/index.vue'
+import TableBase from '@/components/TableBase/index.vue'
+import {Check, Edit, View} from '@element-plus/icons-vue'
+import type { ColumnProps } from '@/components/TableBase/interface'
+import type { FormInstance } from 'element-plus'
+import { useTablePublic } from '@/hooks/useTablePublic'
+import { fnMd5 } from '@/utils/common'
+const router = useRouter()
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
+const { resetForm, globalStore, searchOnTableList, updateOnTableList } = useTablePublic()
+
+const customer_id = ref('')
+
+const columns: ColumnProps[] = [
+  { type: 'selection', width: '44px', fixed: 'left'},
+  { type: 'index', label: '序号', width: 80 },
+  { prop: 'T_customer', label: '客户名称' , width: 260},
+  { prop: 'T_number', label: '合同编号' },
+  { prop: 'T_date', label: '签约时间', width: 120 },
+  { prop: 'T_recoveries_state', label: '回款状态', name:'T_recoveries_state'},
+  { prop: 'T_recoveries_time', label: '回款时间', width: 120},
+  { prop: 'T_type', label: '合同类型', name: 'T_type'},
+  { prop: 'T_discount', label: '合同金额' },
+  { prop: 'T_recoveries_money', label: '回款金额' },
+  { prop: 'T_submit_name', label: '提成人员' },
+  { prop: 'T_percentage_money', label: '提成金额', name: 'T_percentage_money'},
+  { prop: 'T_percentage_state', label: '提成状态', name: 'T_percentage_state'},
+  { prop: 'operation', label: '操作', width: 260, fixed: 'right' }
+]
+const options1 = reactive([
+  { name: '未回款', id: 1 },
+  { name: '部分回款', id: 2 },
+  { name: '全部回款', id: 3 },
+
+])
+const percentageStateOptions = reactive([
+	{ name: '未打款', id: 1 },
+	{ name: '已打款', id: 2 },
+])
+
+const ContractFormRef = ref<InstanceType<typeof ContractForm> | null>(null)
+const VerifyFormRef = ref<InstanceType<typeof VerifyForm> | null>(null)
+
+// const processContract = (id: string) => router.push({ name: 'VerifyContractDetail', params: { id } })
+
+const ContractForm = defineAsyncComponent({
+  loader: () => import(/*webpackChunkName: 'ContractForm'*/ '../sales/ContractForm.vue'),
+  delay: 500,
+  timeout: 3000,
+  suspensible: true
+})
+const VerifyForm = defineAsyncComponent({
+  loader: () => import(/*webpackChunkName: 'ContractForm'*/ '../sales/VerifyForm.vue'),
+  delay: 500,
+  timeout: 3000,
+  suspensible: true
+})
+
+// 搜索
+const T_date = ref<string[]>([])
+const initParam = reactive({
+  User_tokey: globalStore.GET_User_tokey,
+  T_name: '',
+  T_percentage_state: '',//提成状态
+  T_recoveries_state: '',//回款状态
+  T_end_date: '',
+  T_start_date: ''
+})
+
+const searchHandle = () => {
+	initParam.T_end_date = T_date.value ? T_date.value[1] : ''
+	initParam.T_start_date = T_date.value ? T_date.value[0] : ''
+	TableRef.value?.searchTable()
+}
+
+
+const processContract = (id: string) => router.push({ name: 'ContractDetail', params: { id, type: fnMd5('contract') } })
+
+//打款
+const SubmitRemit = async (T_number: string) => {
+	const reslut: any = await Storehouse_Contract_Percentage_Remit({T_number: T_number})
+	console.log('打款', reslut, T_number)
+	if (reslut.Code == 200 && reslut.Msg == 'ok!') {
+		searchOnTableList(TableRef.value)
+		ElMessage.success(reslut.Msg)
+	}
+}
+const multipleSelection = ref<any[]>([])
+// 保存选中的数据id,row-key就是要指定一个key标识这一行的数据
+const getRowKey = (row: any) => {
+	return row.T_number
+}
+const handleSelectionChange = (val: any[]) => {
+	multipleSelection.value = val
+	console.log(multipleSelection.value)
+}
+const selectable = (row: any) => {
+	console.log(row)
+	if (row.T_recoveries_state === '全部回款') {
+		return true
+	} else  {
+		return false
+	}
+}
+
+// 批量提交打款
+const batchSubmitRemit = async () => {
+	if (multipleSelection.value.length === 0) {
+		ElMessage.warning('请选择提成!!!')
+		return
+	}
+
+	for await (let item of multipleSelection.value) {
+		Storehouse_Contract_Percentage_Remit({ T_number: item.T_number })
+	}
+
+	ElMessage.success('打款成功!!!')
+	nextTick(() => {
+		multipleSelection.value = []
+		searchOnTableList(TableRef.value)
+		TableRef.value?.clearSelection()
+	})
+}
+
+// 导出
+const exportPercentageExcel = async () => {
+	initParam.T_end_date = T_date.value ? T_date.value[1] : ''
+	initParam.T_start_date = T_date.value ? T_date.value[0] : ''
+	TableRef.value?.searchTable()
+	const res: any = await Storehouse_VerifyContract_Recover_Export(initParam)
+	if (res.Code === 200) {
+		window.open(res.Data)
+	}
+}
+
+</script>
+
+<template>
+  <div class="verify-contract">
+    <TableBase
+      ref="TableRef"
+      :columns="columns"
+      :requestApi="Storehouse_VerifyContract_Recover_List"
+      :initParam="initParam"
+	  selectId="Id"
+	  :getRowKey="getRowKey"
+	  :selection-change="handleSelectionChange"
+	  :selectable="selectable"
+    >
+
+      <template #table-header>
+        <el-row :gutter="20" style="margin-bottom: 0" class="input-suffix">
+			<el-col :xl="5" :lg="5" :md="5" style="display: flex">
+				<span class="inline-flex items-center">回款日期:</span>
+				<el-date-picker
+					v-model="T_date"
+					type="daterange"
+					range-separator="~"
+					start-placeholder="开始时间"
+					end-placeholder="结束时间"
+					format="YYYY-MM-DD"
+					value-format="YYYY-MM-DD"
+				/>
+			</el-col>
+			<el-col :xl="5" :lg="5" :md="5" class="d-flex">
+            <span class="inline-flex items-center">合同编号:</span>
+            <el-input
+              v-model="initParam.T_name"
+              type="text"
+              class="w-50 m-2"
+              placeholder="按编号搜索"
+              @change="searchOnTableList(TableRef)"
+            />
+          </el-col>
+			<el-col :xl="5" :lg="5" :md="4" class="d-flex">
+			<span class="inline-flex items-center">提成状态:</span>
+			<el-select v-model="initParam.T_percentage_state" class="w-50" clearable placeholder="请选择">
+				<el-option v-for="item in percentageStateOptions" :key="item.id" :label="item.name" :value="item.id" />
+			</el-select>
+		</el-col>
+			<el-col :xl="5" :lg="5" :md="5" class="d-flex">
+            <span class="inline-flex items-center">回款状态:</span>
+            <el-select v-model="initParam.T_recoveries_state" class="w-50" clearable placeholder="请选择">
+              <el-option v-for="item in options1" :key="item.id" :label="item.name" :value="item.id" />
+            </el-select>
+			  <el-button type="primary" @click="searchHandle">搜索</el-button>
+          </el-col>
+			<el-col :xl="4" :lg="4" :md="4"  class="d-flex">
+				<el-button type="success" @click="batchSubmitRemit">批量打款</el-button>
+				<el-button type="primary" @click="exportPercentageExcel">导出表格</el-button>
+			</el-col>
+        </el-row>
+      </template>
+		<template #T_recoveries_state="{ row }">
+			<el-text v-if="row.T_recoveries_state === '全部回款'" type="success" effect="dark">全部回款</el-text>
+			<el-text v-else-if="row.T_recoveries_state === '部分回款'" type="primary" effect="dark">部分回款</el-text>
+			<el-text v-else type="info" effect="dark">未回款</el-text>
+		</template>
+      <template #T_type="{ row }">
+        <el-tag :type="row.T_type==1?'':'success'" effect="dark"> {{row.T_type==1?'销售合同':row.T_type==2?'验证合同':'-'}} </el-tag>
+      </template>
+		<template #T_percentage_money="{ row }">
+        {{row.T_discount*0.05}}
+      </template>
+		<template #T_percentage_state="{ row }">
+			<el-text v-if="row.T_percentage_state === 2" type="success" effect="dark">已打款</el-text>
+			<el-text v-else type="info" effect="dark">未打款</el-text>
+      </template>
+      <template #right="{ row }">
+         <el-button link type="success" size="small" :disabled="(![1].includes(row.T_percentage_state) || !['全部回款'].includes(row.T_recoveries_state))" :icon="Check" @click="SubmitRemit(row.T_number)">打款</el-button>
+         <el-button link type="primary" size="small" :icon="View" @click="processContract(row.T_number)">明细</el-button>
+      </template>
+    </TableBase>
+    <ContractForm ref="ContractFormRef" @onTableList="updateOnTableList(TableRef)" />
+    <VerifyForm ref="VerifyFormRef" @onTableList="updateOnTableList(TableRef)" :verify_customer_id="customer_id" />
+  </div>
+</template>
+
+<style scoped lang="scss">
+@import '@/styles/var.scss';
+
+.verify-contract {
+  @include f-direction;
+
+  :deep(.el-drawer__header) {
+    margin-bottom: 0;
+  }
+  .input-suffix {
+    width: 100%;
+    .inline-flex {
+      white-space: nowrap;
+    }
+    .btn {
+      display: flex;
+      justify-content: end;
+    }
+    .w-50 {
+      flex: 0 0 55%;
+    }
+  }
+}
+</style>

+ 269 - 0
src/views/storehouse/verifyCompany/VerifyProductionList.vue

@@ -0,0 +1,269 @@
+<script setup lang="ts">
+import {
+	stockInEditSort,
+	Storehouse_Product_Add,
+	Storehouse_Product_Del,
+	Storehouse_Product_Edit,
+	Storehouse_Product_List,
+	Storehouse_ProductClass_List
+} from '@/api/storehouse'
+import {nextTick, onMounted, reactive, ref} from 'vue'
+import Upload from '@/components/Upload/index.vue'
+import Drawer from '@/components/Drawer/index.vue'
+import TableBase from '@/components/TableBase/index.vue'
+import type {FormInstance, FormRules} from 'element-plus'
+import {ElMessage, ElMessageBox} from 'element-plus'
+import {Delete, Edit} from '@element-plus/icons-vue'
+import type {ColumnProps} from '@/components/TableBase/interface'
+import ImageCom from '@/components/Image/index.vue'
+import {useTablePublic} from '@/hooks/useTablePublic'
+
+const isNew = ref(true)
+const formLabelWidth = ref('100px')
+const ruleFormRef = ref<FormInstance>()
+const drawerRef = ref<InstanceType<typeof Drawer> | null>(null)
+const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
+const uploadRef = ref<InstanceType<typeof Upload> | null>(null)
+const {resetForm, globalStore, searchOnTableList, updateOnTableList} = useTablePublic()
+
+const columns: ColumnProps[] = [
+	{type: 'index', label: '序号', width: 80},
+	{prop: 'T_class_name', label: '产品分类'},
+	{prop: 'T_name', label: '产品名称'},
+	{prop: 'T_price', label: '单价'},
+	{prop: 'T_remark', label: '备注', name: 'T_remark'},
+	{prop: 'operation', label: '操作', width: 150, fixed: 'right'}
+]
+
+const rules = reactive<FormRules>({
+	T_name: [{required: true, message: '请输入产品名称', trigger: 'blur'}],
+	T_class: [{required: true, message: '请选择产品分类', trigger: 'blur'}],
+	T_price: [{required: true, message: '请输入单价', trigger: 'blur'}],
+})
+const form = ref({
+	Id: '',
+	T_name: '',
+	T_class: '',
+	T_remark: '',
+	T_price: ''
+})
+
+const openDrawer = (type: string, row?: any) => {
+	isNew.value = type === 'new' ? true : false
+	// !specList.value.length && getSpecList()
+	nextTick(() => {
+		if (!isNew.value) {
+			form.value = {...row}
+		}
+	})
+	drawerRef.value?.openDrawer()
+}
+
+const AddProduction = (formEl: FormInstance | undefined) => {
+	if (!formEl) return
+	formEl.validate(async valid => {
+		if (valid) {
+			let res: any = {}
+			if (isNew.value) {
+				res = await Storehouse_Product_Add({User_tokey: globalStore.GET_User_tokey, ...form.value})
+			} else {
+				res = await Storehouse_Product_Edit({
+					User_tokey: globalStore.GET_User_tokey,
+					...form.value,
+					T_id: form.value.Id
+				})
+			}
+			if (res.Code === 200) {
+				ElMessage.success(`验证产品${isNew.value ? '添加' : '修改'}成功!!`)
+				nextTick(() => {
+					drawerRef.value?.closeDrawer()
+					updateOnTableList(TableRef.value)
+					resetForm(ruleFormRef.value)
+					isNew.value = true
+				})
+			}
+		}
+	})
+}
+
+const ProductDelete = (row: any) => {
+	ElMessageBox.confirm('您确定要删除该验证产品吗?', '警告', {
+		confirmButtonText: '确定',
+		cancelButtonText: '取消',
+		type: 'warning'
+	})
+		.then(async () => {
+			const res: any = await Storehouse_Product_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 callbackDrawer = (done: () => void) => {
+	resetForm(ruleFormRef.value)
+	uploadRef.value?.clearfileList()
+	done()
+}
+// 搜索
+const initParam = reactive({
+	User_tokey: globalStore.GET_User_tokey,
+	T_name: '',
+	T_class: '',
+	T_VerifyContract: 1
+})
+// 获取产品分类
+const options = ref<any[]>([])
+const getProductClassList = async () => {
+	const res: any = await Storehouse_ProductClass_List({T_Verify: 1, page: 1, page_z: 999})
+	options.value = res.Data.Data
+}
+
+const onclickSort = async (row: any) => {
+	ElMessageBox.prompt('请输入排序号', '', {
+		confirmButtonText: 'OK',
+		cancelButtonText: 'Cancel',
+		inputValue: `${row.T_sort}`
+	}).then(async ({value}) => {
+		const result: any = await stockInEditSort({T_id: row.Id, T_sort: value})
+		if (result.Code == 200) {
+			ElMessage.success('编辑成功')
+			TableRef.value?.getTableList()
+		}
+	}).catch(() => {
+	})
+}
+
+onMounted(() => {
+	getProductClassList()
+})
+</script>
+
+<template>
+	<div class="production-list">
+		<TableBase ref="TableRef" :columns="columns" :requestApi="Storehouse_Product_List" :initParam="initParam">
+			<template #table-header>
+				<div class="input-suffix">
+					<el-row :gutter="20" style="margin-bottom: 0">
+						<el-col :xl="6" :lg="8" :md="10">
+							<span class="inline-flex items-center">产品分类:</span>
+							<el-select v-model="initParam.T_class" class="w-50 m-2" clearable placeholder="请选择分类~">
+								<el-option v-for="item in options" :key="item.Id" :label="item.T_name"
+										   :value="item.Id"/>
+							</el-select>
+						</el-col>
+						<el-col :xl="10" :md="12">
+							<span class="inline-flex items-center">产品名称:</span>
+							<el-input
+								v-model="initParam.T_name"
+								type="text"
+								class="w-50 m-2"
+								placeholder="按产品名称、产品型号搜索"
+								@change="searchOnTableList(TableRef)"
+							/>
+							<el-button type="primary" @click="searchOnTableList(TableRef)">搜索</el-button>
+						</el-col>
+						<el-col :xl="6" :md="2" class="btn"
+						>
+							<el-button type="primary" @click="openDrawer('new')">添加</el-button>
+						</el-col
+						>
+					</el-row>
+				</div>
+			</template>
+
+			<template #T_img="{ row }">
+				<ImageCom :src="row.T_img"/>
+			</template>
+			<template #T_sort="{ row }">
+				<div @dblclick="onclickSort(row)" style="cursor: pointer;">
+					{{ row.T_sort }}
+				</div>
+			</template>
+			<template #T_remark="{ row }">
+				<el-tooltip effect="customized" placement="left">
+					<template #content>
+						<div class="tooltip-content">{{ row.T_remark }}</div>
+					</template>
+					{{ row.T_remark }}
+				</el-tooltip>
+			</template>
+			<template #T_relation_sn="{ row }">
+				<el-tag v-if="row.T_relation_sn === 1" effect="dark">是</el-tag>
+				<el-tag v-else type="success" effect="dark">否</el-tag>
+			</template>
+			<template #right="{ row }">
+				<el-button link type="primary" size="small" :icon="Edit" @click="openDrawer('edit', row)">编辑
+				</el-button>
+				<el-button link type="danger" size="small" :icon="Delete" @click="ProductDelete(row)">删除</el-button>
+			</template>
+		</TableBase>
+		<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="产品名称:" class="m-b-6" :label-width="formLabelWidth" prop="T_name">
+					<el-input v-model="form.T_name" type="text" autocomplete="off" placeholder="请输入验证产品名称"/>
+				</el-form-item>
+				<el-form-item label="产品分类:" class="m-b-6" :label-width="formLabelWidth" prop="T_class">
+					<el-select v-model="form.T_class" placeholder="请选择产品分类~">
+						<el-option v-for="item in options" :key="item.Id" :label="item.T_name" :value="item.Id"/>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="单价:" class="m-b-6" :label-width="formLabelWidth" prop="T_price">
+					<el-input v-model="form.T_price" type="number" autocomplete="off" placeholder="请收入单价"/>
+				</el-form-item>
+				<el-form-item label="备注:" class="m-b-6" :label-width="formLabelWidth" prop="T_remark">
+					<el-input
+						v-model="form.T_remark"
+						:autosize="{ minRows: 4, maxRows: 6 }"
+						type="textarea"
+						placeholder="请输入备注信息"
+					/>
+				</el-form-item>
+				<el-form-item :label-width="formLabelWidth">
+					<el-button v-if="isNew" color="#626aef" @click="AddProduction(ruleFormRef)">提交</el-button>
+					<el-button v-else color="#626aef" @click="AddProduction(ruleFormRef)">修改</el-button>
+				</el-form-item>
+			</el-form>
+		</Drawer>
+	</div>
+</template>
+
+<style scoped lang="scss">
+@import '@/styles/var.scss';
+
+.tooltip-content {
+	max-width: 500px;
+	overflow-y: auto;
+}
+
+.production-list {
+	@include f-direction;
+
+	.input-suffix {
+		width: 100%;
+
+		.inline-flex {
+			white-space: nowrap;
+		}
+
+		.btn {
+			display: flex;
+			justify-content: end;
+		}
+
+		.w-50 {
+			width: 12.5rem;
+		}
+	}
+}
+</style>

+ 1 - 1
src/views/storehouse/verifyItem.vue

@@ -132,7 +132,7 @@ const initParam = reactive({
                 v-model="initParam.T_name"
                 type="text"
                 class="w-50 m-2"
-                placeholder="按产品名称、产品型号搜索"
+                placeholder="按项目名称搜索"
                 @change="searchOnTableList(TableRef)"
               />
             </el-col>