yangg пре 1 недеља
родитељ
комит
1456e26d00

+ 2 - 2
.env.development

@@ -5,8 +5,8 @@ ENV = 'development'
 #线下:http://192.168.100.187:8083
 # 本地环境接口地址 121.36.251.245
 
-VITE_API_URL = 'http://192.168.100.106:8086'
-#VITE_API_URL = 'http://1.94.168.85:8086'
+#VITE_API_URL = 'http://192.168.100.106:8086'
+VITE_API_URL = 'http://1.94.168.85:8086'
 # VITE_API_URL = 'https://backend.qicai321.com'
 VITE_API_WX_URL='https://api.weixin.qq.com/'
 VITE_API_URL_MINLONG='http://117.185.80.170:7861'

+ 118 - 5
src/views/system/borrow/approval/curd.tsx

@@ -18,6 +18,65 @@ import dayjs from 'dayjs';
 import { h, ref, computed ,inject,defineAsyncComponent, Ref} from "vue";
 // import ItemsList from './ItemsList/index.vue';
 
+// 审批状态处理工具函数
+const getApprovalStatusText = (adminApproverInfo: any) => {
+	if (!adminApproverInfo) return '无审批流程';
+	
+	const { approval_status, current_step, total_steps, is_approved, is_rejected, is_pending } = adminApproverInfo;
+	
+	// 优先使用布尔状态标识
+	if (is_approved) return '审批通过';
+	if (is_rejected) return '审批拒绝';
+	if (is_pending) return '审批中';
+	
+	// 回退到文本状态
+	let statusText = approval_status || '未知状态';
+	
+	// 添加进度信息
+	if (current_step && total_steps) {
+		statusText += ` (${current_step.step_order}/${total_steps})`;
+	}
+	
+	// 添加当前审批人信息
+	if (current_step && current_step.approver_name) {
+		statusText += ` - 待${current_step.approver_name}审批`;
+	}
+	
+	return statusText;
+};
+
+// 审批进度详情处理函数
+const getApprovalProgressText = (adminApproverInfo: any) => {
+	if (!adminApproverInfo || !adminApproverInfo.approval_records) {
+		return '无审批记录';
+	}
+	
+	const records = adminApproverInfo.approval_records;
+	
+	// 按审批人分组,只保留每个审批人的最新状态
+	const approverMap = new Map();
+	
+	records.forEach((record: any) => {
+		const approverName = record.approver_name;
+		const existingRecord = approverMap.get(approverName);
+		
+		// 如果没有记录,或者当前记录更新(按创建时间或审批时间)
+		if (!existingRecord || 
+			(record.approve_time && (!existingRecord.approve_time || 
+			new Date(record.approve_time) > new Date(existingRecord.approve_time)))) {
+			approverMap.set(approverName, record);
+		}
+	});
+	
+	// 转换为显示文本${timeText}
+	return Array.from(approverMap.values()).map((record: any) => {
+		const statusIcon = record.status === 1 ? '✓' : record.status === 0 ? '⏳' : '✗';
+		const statusText = record.status_label || (record.status === 1 ? '已通过' : record.status === 0 ? '待审核' : '已拒绝');
+		const timeText = record.approve_time ? ` (${dayjs(record.approve_time).format('MM-DD HH:mm')})` : '';
+		return `${statusIcon} ${record.approver_name} (${statusText})`;
+	}).join(' | ');
+};
+
 export const createCrudOptions = function ({ crudExpose ,context, showRejectDialog, rejectReason, currentFormId,expose, showWarehouseDialog, currentApprovalFormId }: CreateCrudOptionsProps& {
 	showRejectDialog: Ref<boolean>,
 	rejectReason: Ref<string>,
@@ -26,7 +85,7 @@ export const createCrudOptions = function ({ crudExpose ,context, showRejectDial
 	currentApprovalFormId: Ref<number | null>
   }): CreateCrudOptionsRet {
 
-
+/* ${statusIcon} ${record.step_name}: */
 
 
 
@@ -89,9 +148,30 @@ export const createCrudOptions = function ({ crudExpose ,context, showRejectDial
 								ElMessage.success("续借审批通过");
 								crudExpose.doRefresh();
 							} else {
-								// 普通审批需要选择仓库
-								currentApprovalFormId.value = ctx.form.id;
-								showWarehouseDialog.value = true;
+								// 检查审批流程状态
+								const adminApproverInfo = ctx.form.admin_approver_info;
+								if (adminApproverInfo && adminApproverInfo.current_step) {
+									// 显示当前审批步骤信息
+									const currentStep = adminApproverInfo.current_step;
+									const stepInfo = `当前步骤:${currentStep.step_name} (${currentStep.step_order}/${adminApproverInfo.total_steps})`;
+									console.log(stepInfo);
+									
+									// 检查是否还有后续审批步骤
+									if (currentStep.step_order < adminApproverInfo.total_steps) {
+										// 还有后续步骤,需要选择仓库
+										currentApprovalFormId.value = ctx.form.id;
+										showWarehouseDialog.value = true;
+									} else {
+										// 最后一步审批,直接通过
+										await BorrowingReview(ctx.form.id, "approve", "同意申请");
+										ElMessage.success("审批通过");
+										crudExpose.doRefresh();
+									}
+								} else {
+									// 没有审批流程信息,按原逻辑处理
+									currentApprovalFormId.value = ctx.form.id;
+									showWarehouseDialog.value = true;
+								}
 							}
 							ctx.close();
 						}
@@ -359,13 +439,46 @@ export const createCrudOptions = function ({ crudExpose ,context, showRejectDial
 					title: '当前审批人',	
 					search: { show: true },
 					type: 'input',
-					column: { minWidth: 120 },
+					column: { 
+						minWidth: 120,
+						formatter: ({ row }: any) => {
+							// 优先从 admin_approver_info 获取当前待审批人
+							if (row.admin_approver_info && row.admin_approver_info.current_step) {
+								return row.admin_approver_info.current_step.approver_name || '未知审批人';
+							}
+							
+							// 回退到原有的 approver_name 字段
+							return row.approver_name || '无审批人';
+						}
+					},
 					form: {
 						show: false,
 						component: { placeholder: '请输入审批人' },
 						rules: [{ required: false, message: '' }],
 					},
 				},
+				// 审批流程状态显示
+				/* admin_approver_info: {
+					title: '审批状态',
+					search: { show: false },
+					type: 'input',
+					column: { 
+						minWidth: 200,
+						formatter: ({ value }: any) => getApprovalStatusText(value)
+					},
+					form: { show: false }
+				}, */
+				// 审批进度详情
+				approval_progress: {
+					title: '审批进度',
+					search: { show: false },
+					type: 'input',
+					column: { 
+						minWidth: 300,
+						formatter: ({ row }: any) => getApprovalProgressText(row.admin_approver_info)
+					},
+					form: { show: false }
+				},
 				"items[0].device_category_name": {
 					title: '设备分类',
 					search: { show: false },

+ 1 - 1
src/views/system/borrow/component/CollectEquipment/SelectDeviceDialog/index.vue

@@ -50,7 +50,7 @@ watch(
 
 const search = ref('');
 const page = ref(1);
-const pageSize = ref(10);
+const pageSize = ref(20);
 const total = ref(0);
 const tableData = ref([]);
 const selectedRows = ref([]);

+ 2 - 2
src/views/system/borrow/component/CollectEquipment/SettlementDialog.vue

@@ -109,12 +109,12 @@
 
 
         </div>
-        <div v-else>
+        <!-- <div v-else>
           <div style="margin-bottom: 8px; font-weight: bold;">续借时间(天)</div>
           <div class="form-content">{{ formData.renewal_days || '-' }}</div>
           <div style="margin-bottom: 8px; font-weight: bold;">续借理由</div>
           <div class="form-content">{{ formData.return_remark || '-' }}</div>
-        </div>
+        </div> -->
       </el-form>
     </div>
 

+ 23 - 8
src/views/system/borrow/component/CollectEquipment/index.vue

@@ -314,16 +314,16 @@
                                 {{ row.return_time ? dayjs(row.return_time).format('YYYY-MM-DD HH:mm:ss') : (row.return_status?.label === '已归还' ? dayjs().format('YYYY-MM-DD HH:mm:ss') : '') }}
                               </template>
                             </el-table-column>
-                            <el-table-column label="操作" width="150" align="center">
+                            <el-table-column label="操作" width="120" align="center">
                                 <template #default="{ $index,row }">
                                  <!--  && (!returnDeviceList[$index]?.condition || returnDeviceList[$index]?.photos?.length==0)&& row.problem_records?.length ==0 -->
-                                  <el-button :disabled="isView" type="text" style="color: red"  
+                                  <el-button :disabled="isView" type="text" style="color: red;"  
                                    v-if="!isView"
                                   @click="handleAbnormal($index)">异常操作</el-button>
                                   <el-button 
                                     
                                     type="text" 
-                                    style="color: #409EFF" 
+                                    style="color: #409EFF;margin-left:0" 
                                     @click="handleViewAbnormal($index)"
                                     v-if="row.problem_records?.length || (returnDeviceList[$index]?.condition || returnDeviceList[$index]?.photos?.length)"
                                   >查看异常</el-button>
@@ -388,10 +388,11 @@
 	<SelectDeviceDialog 
     v-model:visible="showSelectDeviceDialog"  
     @confirm="onDeviceSelected" 
-    :device-ids="returnDeviceList.filter(item => item.return_status.label !== '已归还').map(item => item.device_no)"
+    :device-ids="returnDeviceList.map(item => item.device_no)"
     :return-mode="activeName === 'third'"
+    :device-status-map="deviceStatusMap"
 />
-	<SettlementDialog v-model:visible="showSettlementDialog" :settlement-data="settlementData" />
+	<SettlementDialog v-model:visible="showSettlementDialog" :settlement-data="settlementData" :modelValue="borrowForm" />
     <AbnormalDialog v-model:visible="showAbnormalDialog" @confirm="onAbnormalConfirm" />
     <ViewAbnormalDialog 
       v-model:visible="showViewAbnormalDialog" 
@@ -571,7 +572,7 @@ const shouldHideDeviceList = computed(() => {
     return true;
   }
 
-  // 强制显示:状态大于 5 或状态标签为“已借出”
+  // 强制显示:状态大于 5 或状态标签为"已借出"
   if ((typeof status === 'number' && status > 5) || statusLabel === '已借出') {
     return false;
   }
@@ -583,6 +584,17 @@ const shouldHideDeviceList = computed(() => {
   return isPendingApproval;
 });
 
+// 计算设备状态映射
+const deviceStatusMap = computed(() => {
+  const statusMap: Record<string | number, any> = {};
+  returnDeviceList.value.forEach(device => {
+    if (device.device_no && device.return_status) {
+      statusMap[device.device_no] = device.return_status;
+    }
+  });
+  return statusMap;
+});
+
 const emit = defineEmits(['update:visible', 'update:modelValue', 'submit']);
 const visible = ref(props.visible);
 const formRef = ref();
@@ -646,6 +658,7 @@ function getWarehouseName(id: any) {
 // 添加结算单相关的状态
 const showSettlementDialog = ref(false);
 const settlementData = ref<any>(null);
+const borrowForm = ref<any>(null);
 
 // 添加异常操作相关的状态
 const showAbnormalDialog = ref(false);
@@ -926,6 +939,7 @@ function onDeviceSelected(devices: Device[]) {
         returnDeviceList.value[existingDeviceIndex].return_status.label = '已归还';
         returnDeviceList.value[existingDeviceIndex].is_return = true;
         returnDeviceList.value[existingDeviceIndex].return_time = dayjs().format('YYYY-MM-DD HH:mm:ss');
+        returnDeviceList.value[existingDeviceIndex].brand = d.brand || '';
         ElMessage.success(`设备 ${d.category_name} 状态已更新为已归还`);
       } else {
         // 如果设备不存在,添加新记录
@@ -1105,7 +1119,7 @@ watch(() => props.modelValue, async (val) => {
                             device_type: item.remark,
                             device_name: item.device_name,
                             borrow_count: item.quantity,
-                            brand: '',
+                            brand: item.brand || '',
                             model: item.device_specification,
                             warehouse: item.location,
                             problem_records: item.problem_records,
@@ -1192,7 +1206,7 @@ watch(() => props.modelValue, async (val) => {
                             device_type: item.remark,
                             device_name: item.device_name,
                             borrow_count: item.quantity,
-                            brand: '',
+                            brand: item.brand || '',
                             model: item.device_specification,
                             warehouse: item.location,
                             problem_records: item.problem_records,
@@ -1375,6 +1389,7 @@ function onSubmit() {
         
         // 使用 nextTick 确保在 DOM 更新后再显示结算单
         nextTick(() => {
+          borrowForm.value = {...settlementData.value,mode: 'settlement' };
           showSettlementDialog.value = true;
         });
       }

+ 4 - 2
src/views/system/borrow/component/SpecialBorrow/index.vue

@@ -129,7 +129,7 @@
 			<!-- {{ isEdit }} -->
 			<el-table :data="!isEdit ? form.items : form.items.filter(item => item.device === null)" border style="width: 50%; margin-bottom: 12px">
 				<el-table-column type="index" label="序号" width="60" />
-				<el-table-column prop="remark" label="设备分类" />
+				<el-table-column prop="device_category_name" label="设备分类" />
 				<!-- <el-table-column prop="quantity" label="借用数量" /> -->
 				<el-table-column label="借用数量">
 				<template #default="{ row }">
@@ -722,7 +722,7 @@ function onSubmit() {
 		if (valid) {
 			form.value.items = form.value.items.map((item: any) => ({
                 ...item,
-                quantity: Number(item.quantity) || 0  
+                quantity: Number(item.quantity) || 0 ,
             }));
 			const firstLocation = form.value.items[0]?.location || '';
             form.value.return_location = firstLocation;
@@ -730,6 +730,8 @@ function onSubmit() {
 			form.value.expected_end_time = dayjs(form.value.expected_end_time).format('YYYY-MM-DD HH:mm:ss')|| now;
 			form.value.team_members_count=Number(form.value.team_members_count)||1;
 			form.value.mode = isEdit.value ? 'edit' : 'add';
+			// 确保 borrow_type 设置为 2(特殊借用)
+			form.value.borrow_type = 2;
 			console.log(form.value);
 			// return
 			emit('submit', { ...form.value });

+ 42 - 6
src/views/system/borrow/crud.tsx

@@ -42,7 +42,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 			},
 			rowHandle: {
 				fixed: 'right',
-				width: 330,
+				width: 370,
 				buttons: {
 					view: {
 						show: true,
@@ -75,7 +75,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					settlement: {
 						order:6,
 						show:compute( ({row})=>{
-							return row.status === 5 ||row.status==7;
+							return row.status === 5 ||row.status==7||row.status==8;
 						}), 
 						text: '结算单',
 						click: ({ row }) => {
@@ -317,15 +317,51 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					},
 					dict: dict({
 						data: [
-							{ label: '无异常', value: '无异常' },
-							{ label: '有损坏', value: '有损坏' },
-							{ label: '有逾期', value: '有逾期' },
-							{ label: '有损坏和逾期', value: '有损坏和逾期' },
+							{ label: '无异常', value: '无异常', color: '#67c23a', bgColor: '#f0f9ff' },
+							{ label: '有损坏', value: '有损坏', color: '#f56c6c', bgColor: '#fef0f0' },
+							{ label: '有逾期', value: '有逾期', color: '#e6a23c', bgColor: '#fdf6ec' },
+							{ label: '有损坏和逾期', value: '有损坏和逾期', color: '#f56c6c', bgColor: '#fef0f0' },
 						],
 					}),
 					column: {
 						show:true,
 						minWidth: 100,
+						cellRender: ({ value }: any) => {
+							// 根据异常状态值返回不同颜色的标签
+							const getAbnormalStatusConfig = (status: string) => {
+								switch (status) {
+									case '无异常':
+										return { color: '#67c23a', bgColor: '#f0f9ff' }
+									case '有损坏':
+										return { color: '#f56c6c', bgColor: '#fef0f0' }
+									case '有逾期':
+										return { color: '#e6a23c', bgColor: '#fdf6ec' }
+									case '有损坏和逾期':
+										return { color: '#f56c6c', bgColor: '#fef0f0' }
+									default:
+										return { color: '#606266', bgColor: '#f5f7fa' }
+								}
+							}
+							
+							const config = getAbnormalStatusConfig(value)
+							
+							return (
+								<span 
+									style={{
+										color: config.color,
+										backgroundColor: config.bgColor,
+										padding: '4px',
+										borderRadius: '4px',
+										fontSize: '12px',
+										display: 'inline-block',
+										minWidth: '60px',
+										textAlign: 'center'
+									}}
+								>
+									{value || '-'}
+								</span>
+							)
+						}
 					},  form:{
 						show:false,
 						component: { placeholder: '请选择设备编号' },

+ 1 - 0
src/views/system/borrow/index.vue

@@ -59,6 +59,7 @@ function onBorrowTypeSelected(type: number, mode: 'view' | 'edit' | 'add' |'coll
 	showBorrowTypeDialog.value = false;
 	nextTick(() => {
 		borrowForm.value = { ...(record || {}), borrow_type: type, mode };
+		console.log("borrowForm.value:::",borrowForm.value);
 	});
 	if (type === 1) {
 		console.log("mode:::",mode);

+ 4 - 4
src/views/system/borrow/workflow/WorkflowDialog/index.vue

@@ -47,12 +47,12 @@
 			</el-row>
 			<el-divider>条件选择</el-divider>
 			<el-row :gutter="20">
-				<el-col :span="8">
+				<!-- <el-col :span="8">
 					<el-form-item label="借用天数大于" prop="condition.days">
 						<el-input-number v-model="form.condition.days" :min="1" controls-position="right" style="width: 100px" />
 						<span style="margin-left: 8px">天</span>
 					</el-form-item>
-				</el-col>
+				</el-col> -->
 				<el-col :span="8">
 					<el-form-item label="用户角色" prop="condition.roles">
 						<el-checkbox-group v-model="form.condition.roles">
@@ -127,7 +127,7 @@
 										<el-option label="学院领导" value="学院领导" />
 									</el-select>
 								</el-form-item>
-								<el-form-item
+								<!-- <el-form-item
 									v-if="role.name === '学院领导'"
 									:label="'领导姓名'"
 									:label-position="'left'"
@@ -147,7 +147,7 @@
 											:value="user.id"
 											/>
 										</el-select>
-									</el-form-item>
+								</el-form-item> -->
 								<el-form-item
 									:label="'通过条件'"
 									:label-position="'left'"

+ 30 - 2
src/views/system/device/crud.tsx

@@ -353,6 +353,31 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						rules: [{ required: true, message: '' }],
 					}
 				},
+				status_list:{
+					title: '设备状态',
+					type: 'dict-select',
+					search: { show: false },
+					column: {
+						show: false,
+						minWidth: 100,
+					},
+					dict: dict({
+						data: [
+							{ value: 0, label: '停用' },
+							{ value: 1, label: '正常' },
+							{ value: 2, label: '维修中' },
+							{ value: 3, label: '报废' }
+						]
+					}),
+					form: {
+						component: { placeholder: '请选择设备状态' },
+						rules: [{ required: true, message: '请选择设备状态' }],
+					},
+					viewForm:{
+						component: { placeholder: '' },
+						rules: [{ required: true, message: '' }],
+					}
+				},
 				"inventory.borrowed_quantity":{
 						title: '设备状态',
 						type: 'text',
@@ -509,6 +534,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				status:{
 					title:'是否可见',
 					type: 'dict-switch',
+					search: { show: true },
 					column: {
 						show:true,
 						minWidth: 90,
@@ -744,7 +770,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				tags:{
 					show: false,
 					title: '设备标签',
-					search: { show: false },
+					search: { show: true },
 					type: 'dict-select',
 					column: { show: true,minWidth: 120 },
 					dict: dict({
@@ -761,11 +787,13 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						 },
 						rules: [{ required: true, message: '请选择设备标签' }],
 						valueResolve({ form, value }) {
-							form.tags = Array.from(String(value), Number);
+							form.tags =  [parseInt(value, 10)]//Array.from(String(value), Number);
+							console.log(form.tags)
 						},
 						valueBuilder({ form, value }) {
 							if(value){
 								form.tags = Array.isArray(value)? value.length > 0 ? Number(value[0]) : '': Number(value);
+								console.log(form.tags)
 							}
 
 						},

+ 2 - 2
src/views/system/devicedamage/crud.tsx

@@ -333,11 +333,11 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					},
 					form: {
 						component: { placeholder: '请填写报废原因' },
-						rules: [{ required: false, message: '请填写报废原因' }],
+						rules: [{ required: true, message: '请填写报废原因' }],
 					},
 					viewForm:{
 						component: { placeholder: '' },
-						rules: [{ required: false, message: '' }],
+						rules: [{ required: true, message: '' }],
 					}
 				},
 				estimated_loss:{

+ 14 - 1
src/views/system/devicemanual/api.ts

@@ -35,7 +35,7 @@ export function UpdateObj(obj: EditReq) {
 
 export function DelObj(id: DelReq) {
 	return request({
-		url: apiPrefix  + id + '/',
+		url: '/api/system/device-manuals/' + id + '/',
 		method: 'delete',
 		data: { id },
 	});
@@ -47,3 +47,16 @@ export function GetPermission() {
         method: 'get',
     });
 }
+
+// PDF文件上传功能
+export function uploadPdfFile(formData: FormData) {
+	return request({
+		url: '/api/system/device/upload-image/',
+		method: 'post',
+		data: formData,
+		headers: {
+			'Content-Type': 'multipart/form-data',
+		},
+		timeout: 600000
+	});
+}

+ 107 - 3
src/views/system/devicemanual/crud.tsx

@@ -2,6 +2,7 @@ import { AddReq,useCompute, CreateCrudOptionsProps, CreateCrudOptionsRet, UserPa
 import * as api from './api';
 import { auth } from '/@/utils/authFunction';
 import {request} from '/@/utils/service';
+import {getBaseURL} from '/@/utils/baseUrl';
 import {Ref} from 'vue'
 import Cookies from 'js-cookie';
 
@@ -16,6 +17,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 		form.device_id=Number(form.device);
 		form.title=form.article_title;
 		form.content=form.article_content;
+		// PDF文件字段保持不变,直接传递
 		return await api.UpdateObj(form);
 	};
 	const delRequest = async ({ row }: DelReq) => {
@@ -26,6 +28,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 		form.device_id=Number(form.device);
 		form.title=form.article_title;
 		form.content=form.article_content;
+		// PDF文件字段保持不变,直接传递
 		// console.log("sdfsdfsdfform::::",form);
 		
 		return await api.AddObj(form);
@@ -52,9 +55,9 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					buttons: {
 						ok:{
 							text:'提交',
-														show:compute((row) => {
-															return row.mode !=='view'
-														})
+							show:compute((row) => {
+								return row.mode !=='view'
+							})
 						}
 					}
 				}
@@ -334,6 +337,107 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						rules: [{ required: true, message: '' }],
 					}
 				},
+				device_operation_manual: {
+					title: 'PDF手册',
+					type: 'file-uploader',
+					column: {
+						show: false,
+						minWidth: 120,
+						formatter: ({ row, value }: { row: any; value: any }) => {
+							if (!value) return '无';
+							return value.split('/').pop() || 'PDF文件';
+						},
+					},
+					form: {
+						show: true,
+						component: {
+							limit: 1,
+							uploader: {
+								type: 'form',
+								accept: ".pdf",
+								uploadRequest: async (params: any) => {
+									const { action, file, onProgress } = params;
+									
+									// 动态获取设备ID
+									let deviceId = '';
+									try {
+										const formData = crudExpose.getFormData();
+										deviceId = formData.device;
+									} catch (error) {
+										console.warn('获取表单数据失败:', error);
+									}
+									
+									if (!deviceId) {
+										throw new Error('请先选择设备');
+									}
+									
+									const uploadUrl = `/api/system/device/${deviceId}/upload_manual/`;
+									const token = Cookies.get('token'); 
+									const data = new FormData();
+									data.append("file", file);
+									return await request({
+										url: uploadUrl,
+										method: "post",
+										timeout: 60000,
+										headers: {
+										"Content-Type": "multipart/form-data",
+										"Authorization": token ? `JWT ${token}` : ''
+										},
+										data,
+										onUploadProgress: (p: any) => {
+										onProgress({ percent: Math.round((p.loaded / p.total) * 100) });
+										}
+									});
+								},
+								successHandle(ret) {
+									// eslint-disable-next-line no-console
+									// console.log("ret.data.image_url:::",ret.data.image_url);
+
+									return {
+										url: getBaseURL(ret.data.manual_url), 
+										key: ret.data.id,
+										...ret.data
+									};
+								}
+								/* buildUrl(res: any) {
+									console.log("PDF上传响应:", res);
+									// 根据返回的数据结构,提取manual_url
+									if (res && res.code === 2000 && res.data && res.data.manual_url) {
+										return res.data.manual_url;
+									}
+									return res.url || '';
+								},
+								onSuccess: (response: any, file: any) => {
+									console.log("PDF上传成功:", response);
+									// 根据返回的数据结构,提取manual_url并设置到表单
+									if (response && response.code === 2000 && response.data && response.data.manual_url) {
+										// 将manual_url设置到pdf_file字段
+										const formData = crudExpose.getFormData();
+										formData.pdf_file = response.data.manual_url;
+										crudExpose.setFormData(formData);
+										console.log("PDF文件路径已设置:", response.data.manual_url);
+										return response.data.manual_url;
+									}
+									return response.url || '';
+								},
+								onError: (error: any) => {
+									console.error("PDF上传失败:", error);
+								} */
+							}
+						},
+						rules: [{ 
+							required: false, 
+							message: 'PDF手册为可选项' 
+						}],
+					},
+					viewForm: {
+						component: { 
+							placeholder: '',
+							disabled: true 
+						},
+						rules: [{ required: false, message: '' }],
+					}
+				},
 				publisher_name:{
 					title: '发布人',
 					type: 'input',