zoie 2 mesiacov pred
rodič
commit
b8a9c0ba13

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

@@ -130,10 +130,17 @@ export const updateValidation = (params: any) => $http.post('/storage/validation
 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 exportOperationFile = (params: any) => $http.post('/storage/validationTool/exportOperationExcel', 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)
 
+export const validationTool_transfer = (params: any) => $http.post('/storage/validationTool/transfer', params)
+export const validationTool_confirmAccepted = (params: any) => $http.post('/storage/validationTool/confirmAccepted', params)
+export const validationTool_CancelTransfer = (params: any) => $http.post('/storage/validationTool/CancelTransfer', params)
+export const validationTool_transferRecordsList = (params: any) => $http.post('/storage/validationTool/transferRecordsList', params)
+export const validationTool_acceptedRecordsList = (params: any) => $http.post('/storage/validationTool/acceptedRecordsList', params)
+
+
 /**
  * 入库
  */

+ 1 - 0
src/hooks/useDepot.ts

@@ -119,6 +119,7 @@ export interface OutStockAuditFormType {
 	T_number: string
 	T_audit: number
 	T_approval_opinion: string
+	T_approval_img: string
 	T_type: string
 }
 

+ 8 - 0
src/layouts/Header/Breadcrumb.vue

@@ -33,6 +33,14 @@ const getExtraBreadcrumb = (name: string) => {
       return getBreadcrumb('/saleOutStock', 'ue7e8', '/outStock')
     case 'OutStockDetail':
       return getBreadcrumb('/outStockDetail', 'ue72c', '/outStock')
+	case 'OutStockApplyWarehouse':
+	  return getBreadcrumb('/outStockApplyWarehouse', 'ue72c', '/outStock')
+	case 'OutStockApplyManager':
+	  return getBreadcrumb('/outStockApplyManager', 'ue72c', '/outStock')
+	case 'OutStockApplyFinance':
+	  return getBreadcrumb('/outStockApplyFinance', 'ue72c', '/outStock')
+	case 'OutStockApply':
+	  return getBreadcrumb('/outStockApplyMy', 'ue72c', '/outStock')
     case 'VerifyContractDetail':
       return getBreadcrumb('/verifyContractDetail', 'ue679', '/verifyContract')
   }

+ 129 - 118
src/views/storehouse/ValidationTool/statValidation.vue

@@ -1,140 +1,151 @@
 <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 {validation_Stat, validation_User_List} from '@/api/storehouse'
+import {reactive, ref} 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'
+import {useTablePublic} from '@/hooks/useTablePublic'
+import {ColumnProps} from '@/components/TableBase/interface/index'
 
 interface UserInfoIn {
-  LendUser: string
-  TotalCount: number
+	LendUser: string
+	TotalCount: number
 }
+
 const userInfo = ref<UserInfoIn>({
-  LendUser: '',
-  TotalCount: 0,
+	LendUser: '',
+	TotalCount: 0,
 })
-const columns: ColumnProps[] = [{ prop: 'LendUser', label: '姓名' }]
+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: '数量' },
+	{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 {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 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)
+	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>
+	<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="warning">维修中</el-tag>
+						<el-tag v-if="row.T_state == 4" effect="dark" type="danger">已报废</el-tag>
+						<el-tag v-if="row.T_state == 5" effect="dark" type="info">已损坏</el-tag>
+						<el-tag v-if="row.T_state == 6" effect="light" type="warning">转移中</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;
-  }
+	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>

+ 765 - 0
src/views/storehouse/ValidationTool/transferValidation.vue

@@ -0,0 +1,765 @@
+<script setup lang="ts">
+import {computed, nextTick, onMounted, reactive, ref} from 'vue';
+import TableBase from '@/components/TableBase/index.vue';
+import Drawer from "@/components/Drawer/index.vue";
+import {
+	readValidation,
+	validation_Stat,
+	validationTool_acceptedRecordsList,
+	validationTool_CancelTransfer,
+	validationTool_confirmAccepted,
+	validationTool_transfer,
+	validationTool_transferRecordsList
+} from '@/api/storehouse';
+import {User_List} from '@/api/user/index';
+import {Check, Close, View} from "@element-plus/icons-vue";
+import {ElMessage, ElMessageBox, type FormInstance} from "element-plus";
+import {useTablePublic} from "@/hooks/useTablePublic";
+import {ColumnProps} from '@/components/TableBase/interface/index';
+
+const {resetForm, globalStore, searchOnTableList, updateOnTableList, tableRowClassName} = useTablePublic()
+
+
+interface TransferItem {
+	id: number;
+	TransferSn: string[];
+	AcceptedSn: string | null;
+	TransferUser: string;
+	AcceptedUser: string;
+	Status: string;
+	TransferRemark: string;
+	AcceptedRemark: string;
+	CreateTime: string;
+}
+
+const formLabelWidth = ref('100px')
+
+const activeTab = ref('transferOut'); // 默认展示我转移的
+const tableTransferRef = ref<InstanceType<typeof TableBase> | null>(null)
+const tableAcceptedRef = ref<InstanceType<typeof TableBase> | null>(null)
+const drawerSnRef = ref<any>(null);
+const tableSnData = ref<any[]>([]);
+const lendTableData = ref<any[]>([]);
+
+// 处理借出表格数据的回调函数
+const handleLendTableData = (res: any) => {
+	if (res && res.Data && res.Data.Data) {
+		lendTableData.value = res.Data.Data;
+		return res.Data.Data;
+	}
+	return [];
+};
+
+// 计算借出总数量的总和
+const totalCountSum = computed(() => {
+	// 使用lendTableData计算总和
+	return lendTableData.value.reduce((sum: number, item: any) => {
+		return sum + (item.TotalCount || 0);
+	}, 0);
+});
+
+// 初始化RecordsList为默认的API函数,避免requestApi不是函数的错误
+const showTransferForm = ref(false)
+const TransferFormRef = ref<FormInstance | null>(null)
+// 搜索条件
+const initParam = reactive({
+	User_tokey: globalStore.GET_User_tokey,
+	status: ''
+});
+const info = computed(() => globalStore.GET_User_Info)
+// 用户搜索相关
+const userOptions = ref<any[]>([]);
+const userLoading = ref(false);
+
+// 暂存列表相关
+const pendingLendItems = ref<any[]>([]);
+const lendPageSize = ref(10);
+const lendCurrentPage = ref(1);
+
+const TransferForm = reactive({
+	T_sn: '',
+	AcceptedUser: '',
+	AcceptedUserUid: '',
+	Remark: '',
+})
+
+const TransferRules = reactive({
+	T_sn: [{required: true, message: '请输入SN', trigger: 'blur'}],
+	AcceptedUser: [{required: true, message: '请选择接收人', trigger: 'blur'}]
+})
+
+// 搜索选项
+const options = reactive([
+	{name: '转移中', id: 'pending'},
+	{name: '已完成', id: 'completed'},
+	{name: '已取消', id: 'canceled'},
+]);
+
+// 表格列配置
+const columns = [
+	{type: 'index', label: '序号', width: 80},
+	{prop: 'CreateTime', label: '转移时间', width: 165},
+	{prop: 'AcceptedTime', label: '接收时间', width: 165},
+	{prop: 'TransferUser', label: '转移人'},
+	{prop: 'AcceptedUser', label: '接收人'},
+	{prop: 'Status', label: '状态', name: 'Status'},
+	{prop: 'TransferNumber', label: '转移数量'},
+	{prop: 'AcceptedNumber', label: '接收数量', name: 'AcceptedNumber'},
+	{prop: 'TransferRemark', label: '转移备注'},
+	{prop: 'AcceptedRemark', label: '接收备注'},
+	{prop: 'operation', label: '操作', width: 200, fixed: 'right', align: 'center'}
+];
+
+// 员工列表相关配置
+interface UserInfoIn {
+	LendUser: string
+	TotalCount: number
+}
+
+const userInfo = ref<UserInfoIn>({
+	LendUser: '',
+	TotalCount: 0,
+})
+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 tableLendRef = ref<InstanceType<typeof TableBase> | null>(null)
+const initParamLend = reactive({User_tokey: globalStore.GET_User_tokey, LendUser: info.value.T_name, page_z: 99})
+
+// 初始化当前用户信息
+const initUserInfo = () => {
+	if (info.value && info.value.T_name) {
+		userInfo.value = {
+			LendUser: info.value.T_name,
+			TotalCount: 0
+		}
+		initParamLend.LendUser = info.value.T_name
+	}
+}
+
+// 获取数据
+const fetchData = () => {
+	// 根据当前选中的标签页设置API
+	if (activeTab.value === 'transferOut' && tableTransferRef.value) {
+		tableTransferRef.value.searchTable();
+	} else if (activeTab.value === 'transferIn' && tableAcceptedRef.value) {
+		tableAcceptedRef.value.searchTable();
+	} else if (activeTab.value === 'transferLend' && tableLendRef.value) {
+		tableLendRef.value.searchTable();
+	}
+};
+
+// 处理查询
+const searchTransferHandle = () => {
+	if (tableTransferRef.value) {
+		tableTransferRef.value.searchTable();
+	}
+}
+const searchAcceptedHandle = () => {
+	if (tableAcceptedRef.value) {
+		tableAcceptedRef.value.searchTable();
+	}
+}
+
+
+const previewSn = (devicelist: any[]) => {
+	drawerSnRef.value?.openDrawer()
+	if (!devicelist) return
+	tableSnData.value = devicelist.map((item: string) => {
+		return {
+			sn: item
+		}
+	})
+}
+
+// 确认接收对话框显示状态
+const showConfirmDialog = ref(false);
+// 当前选中的转移单
+const currentTransferRow = ref<any>(null);
+// 确认接收表单引用
+const ConfirmFormRef = ref<FormInstance | null>(null);
+
+// 确认接收功能 - 打开对话框
+const confirmAccepted = (row: any) => {
+	currentTransferRow.value = row;
+	console.log(row);
+	// 重置表单
+	confirmForm.Project = '';
+	confirmForm.Remark = '';
+	showConfirmDialog.value = true;
+}
+
+// 提交确认接收表单
+const submitConfirmForm = async () => {
+	if (!ConfirmFormRef.value) return;
+
+	try {
+		await ConfirmFormRef.value.validate();
+		const res: any = await validationTool_confirmAccepted({
+			User_tokey: globalStore.GET_User_tokey,
+			TransferId: currentTransferRow.value.Id,
+			Number: confirmForm.Number,
+			Remark: confirmForm.Remark,
+			Project: confirmForm.Project
+		});
+		if (res.Code === 200) {
+			ElMessage.success('确认接收成功');
+			// 关闭对话框
+			showConfirmDialog.value = false;
+			// 重置表单
+			confirmForm.Project = '';
+			confirmForm.Remark = '';
+			// 更新列表
+			if (tableAcceptedRef.value) {
+				tableAcceptedRef.value.searchTable();
+			}
+		} else {
+			ElMessage.error(res.Message || '确认接收失败');
+		}
+	} catch (error: any) {
+		if (error?.name !== 'ValidationError') {
+			console.error('确认接收失败', error);
+			ElMessage.error('确认接收失败');
+		}
+	}
+}
+
+// 确认接收表单
+const confirmForm = reactive({
+	Project: '',
+	Number: '',
+	Remark: ''
+});
+
+// 确认接收表单验证规则
+const ConfirmRules = reactive({
+	Project: [
+		{required: true, message: '请输入项目', trigger: 'blur'}
+	]
+});
+
+// 关闭抽屉回调
+const callbackSnDrawer = (done: () => void) => {
+	done();
+};
+
+// 切换标签页
+const handleTabChange = (tabName: string) => {
+	initParam.status = ''
+	activeTab.value = tabName;
+	// 更新RecordsList
+	if (tabName === 'transferOut' && tableTransferRef.value) {
+		tableTransferRef.value.searchTable();
+	} else if (tabName === 'transferIn' && tableAcceptedRef.value) {
+		tableAcceptedRef.value.searchTable();
+	} else if (tabName === 'transferLend' && tableLendRef.value) {
+		tableLendRef.value.searchTable();
+	}
+};
+
+const CancelTransferOut = (row: any) => {
+	console.log(row)
+	ElMessageBox.confirm('您确定要取消该调用单吗?', '警告', {
+		confirmButtonText: '确定',
+		cancelButtonText: '取消',
+		type: 'warning'
+	})
+		.then(async () => {
+			const res: any = await validationTool_CancelTransfer({
+				User_tokey: globalStore.GET_User_tokey,
+				TransferId: row.id
+			})
+			if (res.Code === 200) {
+				ElMessage.success('提交成功!')
+				nextTick(() => updateOnTableList(tableTransferRef.value))
+			}
+		})
+		.catch(() => {
+			ElMessage.warning('取消成功!')
+		})
+}
+
+// 选择用户后的处理函数
+const handleUserChange = (value: string) => {
+	if (value) {
+		const selectedUser = userOptions.value.find(user => user.T_uuid === value);
+		if (selectedUser) {
+			TransferForm.AcceptedUser = selectedUser.T_name;
+			TransferForm.AcceptedUserUid = selectedUser.T_uuid;
+		}
+	} else {
+		TransferForm.AcceptedUser = '';
+		TransferForm.AcceptedUserUid = '';
+	}
+};
+
+// 远程搜索用户的方法
+const remoteMethod = async (query: string) => {
+	if (query.trim()) {
+		userLoading.value = true;
+		try {
+			const res: any = await User_List({
+				User_tokey: globalStore.GET_User_tokey,
+				T_name: query,
+				page_z: 100
+			});
+			if (res.Code === 200) {
+				// 确保数据格式正确
+				const formattedOptions = res.Data.Data?.map((user: any) => ({
+					T_uuid: user.T_uuid,
+					T_name: user.T_name
+				})) || [];
+				userOptions.value = formattedOptions;
+				// 添加调试信息
+				console.log('搜索结果:', formattedOptions);
+			}
+		} catch (error) {
+			ElMessage.error('搜索用户失败');
+			console.error('搜索用户错误:', error);
+		} finally {
+			userLoading.value = false;
+		}
+	} else {
+		userOptions.value = [];
+	}
+};
+
+const extractSN = (fullSN: string): string => {
+	if (fullSN.length === 24 && fullSN.startsWith('03') && fullSN.endsWith('000001')) {
+		return fullSN.substring(2, 18)
+	}
+	return fullSN
+}
+// 添加到暂存
+const submitTransferSNForm = () => {
+	TransferFormRef.value?.validate(async (valid: boolean) => {
+		if (valid) {
+			const extractedSN = extractSN(TransferForm.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 == 5) {
+				ElMessage.warning('设备已损坏')
+				if ('speechSynthesis' in window) {
+					const utterance = new SpeechSynthesisUtterance('设备已损坏')
+					window.speechSynthesis.speak(utterance)
+				} else {
+					console.warn('Web Speech API 不被支持')
+				}
+				return
+			}
+			if (result.Data.T_state != 1) {
+				ElMessage.warning('当前SN不是出库状态,不能转移!')
+				return
+			}
+
+			pendingLendItems.value.push({
+				T_sn: TransferForm.T_sn,
+				AcceptedUser: TransferForm.AcceptedUser,
+				AcceptedUserUid: TransferForm.AcceptedUserUid,
+				T_remark: TransferForm.Remark
+			});
+
+			ElMessage.success('已添加到暂存列表');
+			if ('speechSynthesis' in window) {
+				const utterance = new SpeechSynthesisUtterance('添加成功')
+				window.speechSynthesis.speak(utterance)
+			} else {
+				console.warn('Web Speech API 不被支持')
+			}
+			// 清空表单
+			TransferForm.T_sn = '';
+			TransferForm.Remark = '';
+
+		}
+	});
+};
+
+// 移除暂存项
+const removePendingLendItem = (index: number) => {
+	pendingLendItems.value.splice(index, 1);
+	if (pendingLendItems.value.length === 0) {
+		lendCurrentPage.value = 1;
+	}
+};
+
+// 处理分页
+const handleLendPageChange = (page: number) => {
+	lendCurrentPage.value = page;
+};
+
+// 计算分页后的暂存数据
+const paginatedPendingLendItems = computed(() => {
+	const start = (lendCurrentPage.value - 1) * lendPageSize.value;
+	const end = start + lendPageSize.value;
+	return pendingLendItems.value.slice(start, end);
+});
+
+// 提交转移
+const submitTransferItems = async () => {
+	if (pendingLendItems.value.length === 0) {
+		ElMessage.warning('暂存列表为空,请先添加数据');
+		return;
+	}
+
+	try {
+		const snList = pendingLendItems.value.map(item => item.T_sn);
+		const firstItem = pendingLendItems.value[0];
+
+		const res: any = await validationTool_transfer({
+			User_tokey: globalStore.GET_User_tokey,
+			T_sn: JSON.stringify(snList),
+			AcceptedUser: firstItem.AcceptedUser,
+			AcceptedUserUid: firstItem.AcceptedUserUid,
+			Remark: firstItem.T_remark
+		});
+
+		if (res.Code === 200) {
+			ElMessage.success('转移成功');
+			pendingLendItems.value = [];
+			showTransferForm.value = false;
+			nextTick(() => {
+				if (tableTransferRef.value) {
+					updateOnTableList(tableTransferRef.value);
+				}
+			});
+		} else {
+			ElMessage.error(res.Msg || '转移失败');
+		}
+	} catch (error) {
+		ElMessage.error('请求失败,请重试');
+	}
+};
+
+onMounted(() => {
+	initUserInfo(); // 初始化当前用户信息
+	fetchData(); // 页面加载时默认获取我转移的数据
+});
+</script>
+
+<template>
+	<div class="transfer-validation-container">
+		<!-- 添加回标签页切换组件 -->
+		<el-tabs v-model="activeTab" @tab-change="handleTabChange" class="mb-4">
+			<el-tab-pane label="我转移的" name="transferOut"></el-tab-pane>
+			<el-tab-pane label="我接收的" name="transferIn"></el-tab-pane>
+			<el-tab-pane label="我借出的" name="transferLend"></el-tab-pane>
+		</el-tabs>
+		<div v-if="activeTab === 'transferOut'">
+			<TableBase
+				ref="tableTransferRef"
+				:columns="columns"
+				:requestApi="validationTool_transferRecordsList"
+				:initParam="initParam"
+				:pagination="true"
+			>
+				<template #table-header>
+					<div class="input-suffix">
+						<el-row :gutter="20" style="margin-bottom: 0">
+							<el-col :xl="8" :lg="8" :md="8">
+								<span class="inline-flex items-center">状态:</span>
+								<el-select v-model="initParam.status" 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="searchTransferHandle">搜索</el-button>
+							</el-col>
+							<el-col :xl="15" :lg="15" :md="15" class="btn">
+								<el-button type="primary" @click="showTransferForm = true">发起转移</el-button>
+							</el-col>
+						</el-row>
+					</div>
+				</template>
+				<template #Status="{ row }">
+					<el-tag v-if="row.Status == 'pending'" effect="dark" type="warning"> 转移中</el-tag>
+					<el-tag v-if="row.Status == 'completed'" effect="dark" type="success">已完成</el-tag>
+					<el-tag v-if="row.Status == 'canceled'" effect="dark" type="info">已取消</el-tag>
+				</template>
+				<template #AcceptedNumber="{ row }">
+					<span v-if="row.Status == 'completed'">{{ row.AcceptedNumber }}</span>
+					<span v-else>-</span>
+				</template>
+				<template #right="{ row }">
+					<el-button link type="primary" size="small" :icon="View" @click="previewSn(row.TransferSn)">查看SN
+					</el-button>
+					<el-button link type="warning" size="small" :icon="Close" @click="CancelTransferOut(row)"
+							   :disabled="row.Status !== 'pending'">取消
+					</el-button>
+				</template>
+			</TableBase>
+		</div>
+		<div v-if="activeTab === 'transferIn'">
+			<TableBase
+				ref="tableAcceptedRef"
+				:columns="columns"
+				:requestApi="validationTool_acceptedRecordsList"
+				:initParam="initParam"
+				:pagination="true"
+			>
+				<template #table-header>
+					<div class="input-suffix">
+						<el-row :gutter="20" style="margin-bottom: 0">
+							<el-col :xl="8" :lg="8" :md="8">
+								<span class="inline-flex items-center">状态:</span>
+								<el-select v-model="initParam.status" 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="searchAcceptedHandle">搜索</el-button>
+							</el-col>
+
+						</el-row>
+					</div>
+				</template>
+				<template #Status="{ row }">
+					<el-tag v-if="row.Status == 'pending'" effect="dark" type="warning"> 转移中</el-tag>
+					<el-tag v-if="row.Status == 'completed'" effect="dark" type="success">已完成</el-tag>
+					<el-tag v-if="row.Status == 'canceled'" effect="dark" type="info">已取消</el-tag>
+				</template>
+				<template #AcceptedNumber="{ row }">
+					<span v-if="row.Status == 'completed'">{{ row.AcceptedNumber }}</span>
+					<span v-else>-</span>
+				</template>
+				<template #right="{ row }">
+					<el-button link type="primary" size="small" :icon="View" @click="previewSn(row.TransferSn)">查看SN
+					</el-button>
+					<el-button link type="success" size="small" :icon="Check" @click="confirmAccepted(row)"
+					                          :disabled="row.Status !== 'pending'">确认接收
+					</el-button>
+				</template>
+			</TableBase>
+		</div>
+
+		<!-- 我借出的标签页内容 -->
+		<div v-if="activeTab === 'transferLend'">
+			<div class="project">
+
+				<div class="project-container" v-if="userInfo.LendUser">
+					<el-card class="box-card">
+						<h3 class="text title m-b-5">借出总数量:{{ totalCountSum }}</h3>
+					</el-card>
+					<TableBase
+						ref="tableLendRef"
+						:columns="columnsStat"
+						:requestApi="validation_Stat"
+						:initParam="initParamLend"
+						:displayHeader="true"
+						:pagination="false"
+						:dataCallback="handleLendTableData"
+					>
+						<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>
+							<el-tag v-if="row.T_state == 5" effect="dark" type="info">已损坏</el-tag>
+							<el-tag v-if="row.T_state == 6" effect="light" type="warning">转移中</el-tag>
+						</template>
+
+					</TableBase>
+				</div>
+
+			</div>
+		</div>
+
+		<!-- 转移单号列表抽屉 -->
+		<Drawer ref="drawerSnRef" :handleClose="callbackSnDrawer" size="40%">
+			<div style="padding: 20px;">
+				<h3 style="margin-bottom: 20px;">数量: {{ tableSnData.length }} </h3>
+				<el-table
+					:data="tableSnData"
+					style="width: 100%;"
+					:header-cell-style="{
+            background: '#dedfe0',
+            height: '50px'
+          }"
+				>
+					<el-table-column type="index" label="序号" width="80" align="center"></el-table-column>
+					<el-table-column prop="sn" label="SN" align="center"></el-table-column>
+				</el-table>
+			</div>
+		</Drawer>
+		<el-dialog title="发起转移" v-model="showTransferForm" width="50%">
+			<el-form :model="TransferForm" :rules="TransferRules" ref="TransferFormRef">
+
+				<!-- 新增借出人和借出项目 -->
+				<el-form-item class="m-b-6" :label-width="formLabelWidth" label="接收人" prop="AcceptedUser">
+					<el-select
+						v-model="TransferForm.AcceptedUserUid"
+						filterable
+						remote
+						reserve-keyword
+						placeholder="请输入接收人"
+						:remote-method="remoteMethod"
+						:loading="userLoading"
+						class="w-50"
+						@change="handleUserChange"
+						:clearable="true"
+					>
+						<el-option
+							v-for="item in userOptions"
+							:key="item.T_uuid"
+							:label="item.T_name"
+							:value="item.T_uuid"
+						/>
+					</el-select>
+				</el-form-item>
+				<el-form-item class="m-b-6" :label-width="formLabelWidth" label="SN" prop="T_sn">
+					<el-input class="w-50" v-model="TransferForm.T_sn" placeholder="请输入SN"
+							  @keyup.enter="submitTransferSNForm"></el-input>
+				</el-form-item>
+				<el-form-item class="m-b-6" :label-width="formLabelWidth" label="备注">
+					<el-input class="w-50" v-model="TransferForm.Remark" type="textarea"
+							  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="AcceptedUser" 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="showTransferForm = false">取消</el-button>
+        <el-button type="primary" @click="submitTransferSNForm">添加到暂存</el-button>
+		  <!-- 新增提交按钮 -->
+        <el-button type="primary" @click="submitTransferItems">提交</el-button>
+      </span>
+			</template>
+		</el-dialog>
+
+		<!-- 确认接收对话框 -->
+		<el-dialog title="确认接收" v-model="showConfirmDialog" width="35%">
+			<el-form :model="confirmForm" :rules="ConfirmRules" ref="ConfirmFormRef">
+				<el-form-item label="项目" class="m-b-6" :label-width="formLabelWidth" prop="Project">
+					<el-input v-model="confirmForm.Project" placeholder="请输入项目"></el-input>
+				</el-form-item>
+				<el-form-item class="m-b-6" :label-width="formLabelWidth" label="接收数量">
+					<el-input v-model="confirmForm.Number" type="number" placeholder="请输入接收数量"></el-input>
+				</el-form-item>
+				<el-form-item class="m-b-6" :label-width="formLabelWidth" label="备注">
+					<el-input v-model="confirmForm.Remark" type="textarea" placeholder="请输入备注(选填)"></el-input>
+				</el-form-item>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="showConfirmDialog = false">取消</el-button>
+					<el-button type="primary" @click="submitConfirmForm">接收</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
+</template>
+
+
+<style scoped lang="scss">
+.transfer-validation-container {
+	padding: 20px;
+
+	.w-50 {
+		width: 50%;
+	}
+}
+
+.input-suffix {
+	width: 100%;
+
+	.inline-flex {
+		white-space: nowrap;
+	}
+
+	.w-50 {
+		width: 33.33%;
+	}
+
+	.btn {
+		display: flex;
+		justify-content: end;
+	}
+}
+
+/* 我借出的标签页样式 */
+.project {
+	width: 100%;
+	height: 100%;
+	display: flex;
+	overflow: hidden;
+
+	.project-container {
+		width: 100%;
+		z-index: 0;
+
+		.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(.card) {
+		margin: 0;
+		border-radius: 8px;
+	}
+
+	.title {
+		width: 100%;
+		text-align: center;
+		line-height: 1.7em;
+		font-size: 20px;
+		color: #707b84;
+	}
+}
+</style>

+ 111 - 47
src/views/storehouse/ValidationTool/validation.vue

@@ -1,16 +1,19 @@
 <script setup lang="ts">
 import {
 	exportFile,
+	exportOperationFile,
 	readValidation,
 	updateValidation,
 	uploadFile,
 	validation_add,
 	validation_del,
 	validation_List,
+	validation_operationList,
+	validation_recordList,
 	validation_update,
-	validationTool_class_list,
-	validation_recordList, validation_operationList, exportOperationFile
+	validationTool_class_list
 } from '@/api/storehouse'
+import {User_List} from '@/api/user/index';
 import TableBase from '@/components/TableBase/index.vue'
 import {computed, nextTick, onMounted, reactive, ref} from 'vue'
 import {GlobalStore} from '@/stores'
@@ -21,9 +24,9 @@ import {ElLoading, ElMessage, ElMessageBox} from 'element-plus'
 import snAdd from './modules/snAdd.vue'
 import Drawer from "@/components/Drawer/index.vue";
 
+const formLabelWidth = ref('100px')
 const uploadRef = ref<UploadInstance>()
 const uploadFiles = ref<File[]>([]) // 新增:用于存储上传的文件
-
 const globalStore = GlobalStore()
 const TableRef = ref<InstanceType<typeof TableBase> | null>(null)
 const recordTableRef = ref<InstanceType<typeof TableBase> | null>(null)
@@ -70,7 +73,7 @@ const columns: ColumnProps[] = [
 	{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: 'T_remark', label: '备注', ellipsis: true},
 	{prop: 'operation', label: '操作', width: 260, fixed: 'right'}
 ]
 
@@ -84,25 +87,25 @@ const recordColumns: ColumnProps[] = [
 	{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: 'CreateTime', label: '操作时间',  ellipsis: true},
+	{prop: 'T_remark', label: '备注', ellipsis: true},
+	{prop: 'CreateTime', label: '操作时间', ellipsis: true},
 ]
 const operationColumns: ColumnProps[] = [
 	{type: 'index', label: '序号', width: 80},
 	{prop: 'BatchNumber', label: '操作时间', width: 190},
 	{prop: 'T_state', label: '操作', name: 'T_state', width: 90},
 	{prop: 'LendUser', label: '借出(归还)人', ellipsis: true},
-	{prop: 'T_project', label: '关联项目', name:'T_project',  ellipsis: true,  width: 300},
-	{prop: 'T_remark', label: '备注',  ellipsis: true},
+	{prop: 'T_project', label: '关联项目', name: 'T_project', ellipsis: true, width: 300},
+	{prop: 'T_remark', label: '备注', ellipsis: true},
 	{prop: 'T_sn_quantity', label: '设备数量'},
-	{prop: 'operation', label: 'SN', width: 100, fixed: 'right', align: 'center' }
+	{prop: 'operation', label: 'SN', width: 100, fixed: 'right', align: 'center'}
 
 ]
 const snColumns = [
-	{ type: 'index', label: '序号', width: 80, align: 'center ' },
-	{ label: '关联项目', prop: 'T_project', align: 'center ' },
-	{ label: '数量', prop: 'T_number', align: 'center ' },
-	{ label: 'SN', prop: 'T_sn', align: 'center ' }
+	{type: 'index', label: '序号', width: 80, align: 'center '},
+	{label: '关联项目', prop: 'T_project', align: 'center '},
+	{label: '数量', prop: 'T_number', align: 'center '},
+	{label: 'SN', prop: 'T_sn', align: 'center '}
 ]
 // 搜索
 const options = reactive([
@@ -163,7 +166,7 @@ const exportExcel = async () => {
 		const a = document.createElement('a')
 		a.href = url
 		const now = new Date();
-		const formattedDate = `${now.getFullYear()}${(now.getMonth()+1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}_${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}`;
+		const formattedDate = `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}_${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}`;
 		a.download = `验证工具记录表_${formattedDate}.xlsx`;
 		document.body.appendChild(a)
 		a.click()
@@ -190,7 +193,7 @@ const exportOperationExcel = async () => {
 		const a = document.createElement('a')
 		a.href = url
 		const now = new Date();
-		const formattedDate = `${now.getFullYear()}${(now.getMonth()+1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}_${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}`;
+		const formattedDate = `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}_${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}`;
 		a.download = `验证工具操作记录表_${formattedDate}.xlsx`;
 		document.body.appendChild(a)
 		a.click()
@@ -398,15 +401,14 @@ const submitLendForm = () => {
 			} else {
 				console.warn('Web Speech API 不被支持')
 			}
-			pendingLendItems.value = pendingLendItems.value.filter((value:any, index:any, self:any) => {  //去重
-				return self.findIndex((t:any) => (t.T_sn === value.T_sn)) === index;
+			pendingLendItems.value = pendingLendItems.value.filter((value: any, index: any, self: any) => {  //去重
+				return self.findIndex((t: any) => (t.T_sn === value.T_sn)) === index;
 			});
 		} else {
 		}
 	})
 }
 
-
 const removePendingLendItem = (index: number) => {
 	pendingLendItems.value.splice(index, 1)
 	ElMessage.success('已从待提交列表中移除')
@@ -460,7 +462,7 @@ const previewEdit = async (row: any) => {
 		ElMessage.error('获取数据失败')
 	}
 }
-const preview = (T_sn:any) => {
+const preview = (T_sn: any) => {
 	recordInitParam.T_sn = T_sn
 	dialogTableVisible.value = true
 	recordTableRef.value?.searchTable()
@@ -481,11 +483,8 @@ const previewSn = (devicelist: any[]) => {
 			sn: item
 		}
 	})
-
-
 }
 
-
 const submitEditForm = () => {
 	editFormRef.value?.validate(async (valid: boolean): Promise<void> => {
 		if (valid) {
@@ -584,6 +583,51 @@ const successFun = () => {
 	}
 }
 
+// 远程搜索用户的方法
+const remoteMethod = async (query: string) => {
+	if (query.trim()) {
+		userLoading.value = true;
+		try {
+			const res: any = await User_List({
+				User_tokey: globalStore.GET_User_tokey,
+				T_name: query,
+				page_z: 100
+			});
+			if (res.Code === 200) {
+				// 确保数据格式正确
+				const formattedOptions = res.Data.Data?.map((user: any) => ({
+					T_uuid: user.T_uuid,
+					T_name: user.T_name
+				})) || [];
+				userOptions.value = formattedOptions;
+				// 添加调试信息
+				console.log('搜索结果:', formattedOptions);
+			}
+		} catch (error) {
+			ElMessage.error('搜索用户失败');
+			console.error('搜索用户错误:', error);
+		} finally {
+			userLoading.value = false;
+		}
+	} else {
+		userOptions.value = [];
+	}
+};
+// 选择用户后的处理函数
+const handleUserChange = (value: string) => {
+	if (value) {
+		const selectedUser = userOptions.value.find(user => user.T_uuid === value);
+		if (selectedUser) {
+			lendForm.LendUser = selectedUser.T_name;
+		}
+	} else {
+		lendForm.LendUser = '';
+	}
+};
+// 用户搜索相关
+const userOptions = ref<any[]>([]);
+const userLoading = ref(false);
+
 onMounted(() => {
 	getValidationToolClassList()
 })
@@ -705,12 +749,10 @@ onMounted(() => {
 				<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>
 				<el-tag v-if="row.T_state == 5" effect="dark" type="info">已损坏</el-tag>
-				<el-tag v-if="row.T_state == 6" effect="light" type="warning">转移</el-tag>
-				<el-tag v-if="row.T_state == 7" effect="light" type="info">取消转移</el-tag>
-				<el-tag v-if="row.T_state == 8" effect="light" type="success">已接收</el-tag>
+				<el-tag v-if="row.T_state == 6" effect="light" type="warning">转移中</el-tag>
 			</template>
 			<template #T_class="{ row }">
-				<el-tag>{{ Pruductoptions.find((option:any)=> option.Id === row.T_class)?.T_name || '' }}</el-tag>
+				<el-tag>{{ Pruductoptions.find((option: any) => option.Id === row.T_class)?.T_name || '' }}</el-tag>
 
 			</template>
 			<template #right="{ row }">
@@ -773,19 +815,37 @@ onMounted(() => {
 		</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 class="m-b-6" :label-width="formLabelWidth" label="借出人" prop="LendUser">
+					<el-select
+						v-model="lendForm.LendUser"
+						filterable
+						remote
+						reserve-keyword
+						placeholder="请输入接收人"
+						:remote-method="remoteMethod"
+						:loading="userLoading"
+						class="w-50"
+						@change="handleUserChange"
+						:clearable="true"
+					>
+						<el-option
+							v-for="item in userOptions"
+							:key="item.T_uuid"
+							:label="item.T_name"
+							:value="item.T_uuid"
+						/>
+					</el-select>
 				</el-form-item>
-				<el-form-item label="借出项目" prop="T_project">
+				<el-form-item class="m-b-6" :label-width="formLabelWidth" label="借出项目" prop="T_project">
 					<el-input v-model="lendForm.T_project" placeholder="请输入借出项目"></el-input>
 				</el-form-item>
+				<el-form-item class="m-b-6" :label-width="formLabelWidth" 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 class="m-b-6" :label-width="formLabelWidth" label="备注">
+					<el-input v-model="lendForm.T_remark" type="textarea" placeholder="请输入备注"></el-input>
+				</el-form-item>
 			</el-form>
 			<!-- 新增数据条数提示 -->
 			<div style="margin: 10px 0">
@@ -863,7 +923,7 @@ onMounted(() => {
 				<template #tip></template>
 			</el-upload>
 		</el-dialog>
-		<el-dialog title="查看记录" v-model="dialogTableVisible"  width="60%" >
+		<el-dialog title="查看记录" v-model="dialogTableVisible" width="60%">
 
 			<TableBase
 				ref="recordTableRef"
@@ -888,8 +948,10 @@ onMounted(() => {
 							</el-col>
 							<el-col :xl="4" :lg="4" :md="4">
 								<span class="inline-flex items-center">状态:</span>
-								<el-select v-model="recordInitParam.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 v-model="recordInitParam.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="4" :lg="4" :md="4">
@@ -943,11 +1005,11 @@ onMounted(() => {
 					<el-tag v-if="row.T_state == 8" effect="light" type="success">已接收</el-tag>
 				</template>
 				<template #T_class="{ row }">
-					<el-tag>{{ Pruductoptions.find((option:any)=> option.Id === row.T_class)?.T_name || '' }}</el-tag>
+					<el-tag>{{ Pruductoptions.find((option: any) => option.Id === row.T_class)?.T_name || '' }}</el-tag>
 				</template>
 			</TableBase>
 		</el-dialog>
-		<el-dialog title="操作记录" v-model="operationVisible"  width="60%" >
+		<el-dialog title="操作记录" v-model="operationVisible" width="60%">
 
 			<TableBase
 				ref="operationTableRef"
@@ -972,8 +1034,10 @@ onMounted(() => {
 							</el-col>
 							<el-col :xl="5" :lg="5" :md="5">
 								<span class="inline-flex items-center">状态:</span>
-								<el-select v-model="operationInitParam.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 v-model="operationInitParam.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="5" :lg="5" :md="5">
@@ -1016,10 +1080,10 @@ onMounted(() => {
 					<el-tag v-if="row.T_state == 8" effect="light" type="success">已接收</el-tag>
 				</template>
 				<template #T_project="{ row }">
-					<div v-for="(item, index) in row.T_project" :key="index"> {{ item }} </div>
+					<div v-for="(item, index) in row.T_project" :key="index"> {{ item }}</div>
 				</template>
 				<template #right="{ row }">
-					<el-button type="primary"  @click="previewSn(row.T_sn_List)">查看</el-button>
+					<el-button type="primary" @click="previewSn(row.T_sn_List)">查看</el-button>
 				</template>
 			</TableBase>
 		</el-dialog>
@@ -1033,7 +1097,7 @@ onMounted(() => {
         }"
 			>
 				<template v-for="item in snColumns" :key="item.prop">
-					<el-table-column show-overflow-tooltip v-if="item.type === 'index'" v-bind="item" />
+					<el-table-column show-overflow-tooltip v-if="item.type === 'index'" v-bind="item"/>
 					<el-table-column
 						show-overflow-tooltip
 						v-else-if="item.prop === 'T_project'"
@@ -1042,7 +1106,7 @@ onMounted(() => {
 						align="center"
 					>
 						<template #default="scope">
-							{{scope.row.sn.T_project}}
+							{{ scope.row.sn.T_project }}
 						</template>
 					</el-table-column>
 					<el-table-column
@@ -1064,7 +1128,7 @@ onMounted(() => {
 						align="center"
 					>
 						<template #default="scope">
-							<div v-for="(item, index) in scope.row.sn.T_sn" :key="index"> {{ item }} </div>
+							<div v-for="(item, index) in scope.row.sn.T_sn" :key="index"> {{ item }}</div>
 						</template>
 					</el-table-column>
 

+ 0 - 3
src/views/storehouse/outStock/outStockApply/OutStockApplyFinance.vue

@@ -68,8 +68,6 @@ const searchHandle = () => {
 	TableRef.value?.searchTable()
 }
 
-// 拿到仓库列表
-const {options} = depotHooks()
 
 // 保存选中的数据id,row-key就是要指定一个key标识这一行的数据
 const getRowKey = (row: any) => {
@@ -155,7 +153,6 @@ const handleSelectionChange = (val: any[]) => {
 				</el-button>
 			</template>
 		</TableBase>
-		<OutStorageEdit ref="OutStorageRef" :options="options" @onUpdateList="searchHandle"/>
 	</div>
 </template>
 

+ 1 - 4
src/views/storehouse/outStock/outStockApply/OutStockApplyManager.vue

@@ -6,7 +6,7 @@ import {Van, View,Check} from '@element-plus/icons-vue'
 import {nextTick, reactive, ref} from 'vue'
 import TableBase from '@/components/TableBase/index.vue'
 import type {ColumnProps} from '@/components/TableBase/interface'
-import {stockOutExcelBatch, Storehouse_StockOut_Manager_List,} from '@/api/storehouse'
+import {stockOutExcelBatch, Storehouse_StockOut_Manager_List} from '@/api/storehouse'
 import {depotHooks} from '@/hooks/useDepot'
 import OutStorageEdit from './modules/OutStorageEdit.vue'
 import {paymentMethodOptions} from '@/hooks/useTablePublic'
@@ -67,8 +67,6 @@ const searchHandle = () => {
 	TableRef.value?.searchTable()
 }
 
-// 拿到仓库列表
-const {options} = depotHooks()
 
 // 保存选中的数据id,row-key就是要指定一个key标识这一行的数据
 const getRowKey = (row: any) => {
@@ -155,7 +153,6 @@ const handleSelectionChange = (val: any[]) => {
 				</el-button>
 			</template>
 		</TableBase>
-		<OutStorageEdit ref="OutStorageRef" :options="options" @onUpdateList="searchHandle"/>
 	</div>
 </template>
 

+ 12 - 5
src/views/storehouse/outStock/outStockApply/OutStockApplyWarehouse.vue

@@ -8,7 +8,7 @@ import {Edit, View} from '@element-plus/icons-vue'
 import {nextTick, reactive, ref} from 'vue'
 import TableBase from '@/components/TableBase/index.vue'
 import type {ColumnProps} from '@/components/TableBase/interface'
-import {stockOutExcelBatch, Storehouse_StockOut_Apply_Del, Storehouse_StockOut_Warehouse_List,} from '@/api/storehouse'
+import {stockOutExcelBatch, Storehouse_StockOut_Apply_Del, Storehouse_StockOut_Warehouse_List} from '@/api/storehouse'
 import {depotHooks} from '@/hooks/useDepot'
 import OutStorageWarehouse from './modules/OutStorageWarehouse.vue'
 import {paymentMethodOptions} from '@/hooks/useTablePublic'
@@ -34,7 +34,11 @@ const columns: ColumnProps[] = [
 
 // 搜索
 const stateOptions = reactive([
-	{name: '待出库', id: 4},
+	{name: '待审批', id: 1},
+	{name: '财务通过', id: 2},
+	{name: '财务驳回', id: 3},
+	{name: '总经理通过', id: 4},
+	{name: '总经理驳回', id: 5},
 	{name: '已出库', id: 6},
 ])
 
@@ -110,7 +114,6 @@ const deleteFun = (row: any) => {
 	}).catch(() => {
 	})
 }
-
 // 拿到仓库列表
 const {options} = depotHooks()
 
@@ -187,13 +190,17 @@ const handleSelectionChange = (val: any[]) => {
 
 			</template>
 			<template #T_state_str="{ row }">
-				<el-text v-if="row.T_state_str === '总经理通过'" type="warning"> 待出库</el-text>
+				<el-text v-if="row.T_state_str === '待审批'" type="warning"> 待审批</el-text>
+				<el-text v-if="row.T_state_str === '财务通过'" type="primary"> 财务通过</el-text>
+				<el-text v-if="row.T_state_str === '财务驳回'" type="danger"> 财务驳回</el-text>
+				<el-text v-if="row.T_state_str === '总经理通过'" type="primary"> 总经理通过</el-text>
+				<el-text v-if="row.T_state_str === '总经理驳回'" type="danger"> 总经理驳回</el-text>
 				<el-text v-if="row.T_state_str === '已出库'" type="success"> 已出库</el-text>
 			</template>
 			<template #right="{ row }">
 				<el-button link type="success" size="small" :icon="View" @click="preview(row.T_number)">详情</el-button>
 				<el-button link type="primary" size="small" :icon="Edit" @click="previewEdit(row)"
-						   :disabled="[6].includes(row.T_state)"
+						   :disabled="row.T_state !== 4 "
 				>出库
 				</el-button>
 

+ 19 - 4
src/views/storehouse/outStock/outStockApply/OutStockAudit.vue

@@ -7,6 +7,8 @@ import {InfoType, OutStockAuditFormType} from '@/hooks/useDepot'
 import ImageCom from '@/components/Image/index.vue'
 import {paymentMethodOptions} from '@/hooks/useTablePublic'
 import {ElMessage, type FormInstance} from "element-plus";
+import {Plus} from "@element-plus/icons-vue";
+import Upload from "@/views/workAttendance/Upload/index.vue";
 
 const ruleFormRef = ref<FormInstance>()
 const info = ref<InfoType | undefined>()
@@ -15,6 +17,10 @@ const route = useRoute()
 const router = useRouter()
 const dialogVisible = ref(false)
 const auditType = ref('')
+let showWatch = ref(true)
+const disabled = ref(false)
+const formLabelWidth = ref('100px')
+const fileListImg: any = ref([])
 
 const columns = [
 	{type: 'index', label: '序号', width: 80, align: 'center '},
@@ -33,6 +39,7 @@ const initParam = reactive<OutStockAuditFormType>({
 	T_audit: 0,
 	T_approval_opinion: '',
 	T_type: '',
+	T_approval_img: ''
 })
 
 const stockOutExcelFun = async (data: any) => {
@@ -67,7 +74,7 @@ const openDrawer = (audit: string) => {
 const StockOutAudit = async () => {
 	const type = route.params.type as string
 	console.log("type---------", type, auditType.value)
-
+	initParam.T_approval_img = fileListImg.value && fileListImg.value.length > 0 ? fileListImg.value[0] : ''
 	if (type === 'Finance') {
 		// 财务审核分支
 		if (auditType.value === '通过') {
@@ -244,11 +251,19 @@ onMounted(() => {
 				<el-button type="success" round @click="openDrawer('通过')">通过</el-button>
 			</div>
 		</div>
-		<el-dialog title="审批意见" v-model="dialogVisible" width="30%" draggable>
+		<el-dialog title="审批意见"  :label-width="formLabelWidth" v-model="dialogVisible" width="30%" draggable>
 			<el-form :model="initParam" ref="approvalFormRef">
-				<el-form-item label="审批意见" prop="T_approval_opinion">
+				<el-form-item label="审批意见:" :label-width="formLabelWidth" prop="T_approval_opinion">
 					<el-input v-model="initParam.T_approval_opinion" :rows="3" type="textarea"
-							  placeholder="请输入审批意见"></el-input>
+							  placeholder="请输入审批意见(非必填)"></el-input>
+				</el-form-item>
+				<el-form-item label="审批图片:" :label-width="formLabelWidth" >
+					<Upload ref="uploadRef" :showWatch="showWatch" :limit="1" v-model="fileListImg" :disabled="disabled"
+							accept="image/*">
+						<el-icon>
+							<Plus />
+						</el-icon>
+					</Upload>
 				</el-form-item>
 			</el-form>
 			<div class="submit">

+ 1 - 0
src/views/storehouse/outStock/outStockApply/OutStockProduct.vue

@@ -107,6 +107,7 @@ const getProductList = async (depotId: number) => {
 // 获取产品分类
 const getProductClassList = async () => {
   const res: any = await Storehouse_ProductClass_List({ page: 1, page_z: 999 })
+	console.log(res)
   classOptions.value = res.Data.Data
 }
 const props = withDefaults(defineProps<{ depotId: number }>(), {

+ 1 - 1
src/views/storehouse/outStock/outStockApply/modules/OutStorageWarehouse.vue

@@ -219,7 +219,7 @@ const addDeviceSn = (obj: any) => {
  */
 const autoGetCount = (length: number, id: number, arr: any) => {
 	tableData.value.forEach((item: any) => {
-		if (item.Id === id)  {
+		if (item.Id === id && item.T_relation_sn === 1)  {
 			// 判断出库数量与扫码数量是否一致
 			if (item.count !== length) {
 				ElMessage.error('出库数量与扫码数量不一致')

+ 1 - 1
src/views/storehouse/sales/PercentageDetail1.vue

@@ -213,7 +213,7 @@ defineExpose({
             v-model="form.T_approval_opinion"
             :autosize="{ minRows: 4, maxRows: 6 }"
             type="textarea"
-            placeholder="请输入审批意见"
+            placeholder=""
           />
         </el-form-item>
       </el-form>