Bladeren bron

修改部分功能

qaz 3 dagen geleden
bovenliggende
commit
f6c5a4b2ce

+ 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.179:8085'
-VITE_API_URL = 'http://1.94.168.85:8086'
+VITE_API_URL = 'http://192.168.100.179: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'

BIN
.yarn/install-state.gz


+ 1 - 0
.yarnrc.yml

@@ -0,0 +1 @@
+nodeLinker: node-modules

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

@@ -27,7 +27,7 @@
 						<div class="option-title">{{ item.label }}</div>
 					</div>
 					<div class="option-description">
-						{{ item.value === 1 ? '课堂教学活动、实验操作、课程项目等教学时段的正式使用' : '突发紧急情况、非常规教学需求或特殊事件下的临时性借用' }}
+						{{ item.value === 1 ? '课堂教学活动、实验操作、课程项目等教学时段的正式使用' : '适用于线下申请借用或其它特殊情况下的临时借用' }}
 					</div>
 				</div>
 			</div>

+ 185 - 92
src/views/system/borrow/component/CollectEquipment/index.vue

@@ -317,9 +317,43 @@
                             <el-table-column prop="device_code" label="设备编号" align="center" />
                             <!-- <el-table-column prop="device_type" label="设备分类" align="center" /> -->
                             <el-table-column prop="device_name" label="设备名称" align="center" />
-                            <el-table-column prop="borrow_count" label="借用数量" align="center" width="150">
+                            <el-table-column label="已归还数量" width="110" align="center">
+                                <template #default="{ row }">
+                                    {{ row.returned_quantity ?? 0 }}
+                                </template>
+                            </el-table-column>
+                            <el-table-column
+                                v-if="showUnreturnedReturnTableColumns"
+                                label="未归还可还"
+                                width="110"
+                                align="center"
+                            >
+                                <template #default="{ row }">
+                                    {{ row.available_quantity ?? 0 }}
+                                </template>
+                            </el-table-column>
+                            <el-table-column
+                                v-if="showUnreturnedReturnTableColumns"
+                                prop="borrow_count"
+                                label="归还数量"
+                                align="center"
+                                width="150"
+                            >
                                 <template #default="{ row }">
-                                    <el-input-number v-model="row.borrow_count" :min="1" :max="row.available_quantity" size="small" :disabled="true" />
+                                    <el-input-number
+                                        v-if="!isView && isReturnLinePendingReturn(row)"
+                                        v-model="row.borrow_count"
+                                        :min="0"
+                                        :max="(row.available_quantity ?? 0) > 0 ? (row.available_quantity ?? 0) : 0"
+                                        :disabled="(row.available_quantity ?? 0) <= 0"
+                                        size="small"
+                                        @change="() => clampReturnBorrowCount(row)"
+                                    />
+                                    <span
+                                        v-else-if="isView && isReturnLinePendingReturn(row)"
+                                        class="return-cell-text"
+                                    >{{ row.borrow_count ?? 0 }}</span>
+                                    <span v-else class="return-cell-placeholder">—</span>
                                 </template>
                             </el-table-column>
                             <el-table-column prop="brand" label="品牌" align="center" />
@@ -553,7 +587,12 @@ interface DeviceListItem {
     data: string;
   }>;
   device_specification?: string;
-  available_quantity?:number;
+  /** 归还页签:可归还上限,来自 items.pending_quantity */
+  available_quantity?: number;
+  /** 截止当前已在库登记归还的数量,来自 items.returned_quantity */
+  returned_quantity?: number;
+  problem_records?: any[];
+  damage_type?: number;
 }
 
 interface FormItem {
@@ -879,13 +918,81 @@ const displayReturnRemark = computed({
   }
 });
 
-// 统一判定设备是否已归还
+/** 从借用单明细行解析待归还数量:优先用 pending_quantity,缺省时用借出-已还推算(与后端 items 一致,避免硬编码) */
+function getPendingUnreturnedFromItem(item: any): number {
+  if (item == null) return 0;
+  const raw = item.pending_quantity;
+  if (raw !== undefined && raw !== null && String(raw) !== '') {
+    const n = Math.floor(Number(raw));
+    if (!Number.isNaN(n)) return Math.max(0, n);
+  }
+  const borrowed = Number(item.borrowed_quantity) || 0;
+  const returned = Number(item.returned_quantity) || 0;
+  return Math.max(0, borrowed - returned);
+}
+
+/** 将 form.items 单行映射为归还列表行:上限为待归还;归还数量由扫码/手工录入,从 0 起算 */
+function mapFormItemToReturnDeviceListRow(item: any): DeviceListItem {
+  const pending = getPendingUnreturnedFromItem(item);
+  return {
+    device_no: item.device,
+    device_code: item.device_code,
+    device_type: item.remark,
+    device_name: item.device_name,
+    borrow_count: 0,
+    brand: item.brand || item.device_brand || '',
+    model: item.device_specification,
+    warehouse: item.location || item.device_storage_location || '',
+    problem_records: item.problem_records,
+    return_status: item.return_status,
+    return_time: item.return_times,
+    available_quantity: pending,
+    returned_quantity: Math.max(0, Number(item.returned_quantity) || 0)
+  };
+}
+
+function clampReturnBorrowCount(row: DeviceListItem) {
+  const max = row.available_quantity ?? 0;
+  if (max <= 0) {
+    row.borrow_count = 0;
+    return;
+  }
+  let n = Number(row.borrow_count) || 0;
+  if (n < 0) n = 0;
+  if (n > max) n = max;
+  row.borrow_count = n;
+}
+
+/** 是否仍有待归还(有未归还可还):用于表格列在「只展示已归还」与「展示待还+本次归还」间切换 */
+function isReturnLinePendingReturn(row: DeviceListItem) {
+  return (Number(row.available_quantity) || 0) > 0;
+}
+
+/** 扫码命中列表中的设备时:归还数量 +1,不超过待归还数 available_quantity */
+function applyReturnScanIncrement(row: DeviceListItem): boolean {
+  const cap = row.available_quantity ?? 0;
+  if (cap <= 0) {
+    ElMessage.warning('该设备无待归还数量');
+    return false;
+  }
+  const current = Number(row.borrow_count) || 0;
+  if (current >= cap) {
+    ElMessage.warning('该设备归还数量已达待归还上限');
+    return false;
+  }
+  row.borrow_count = current + 1;
+  if (row.borrow_count >= cap) {
+    row.is_return = true;
+    row.return_time = dayjs().format('YYYY-MM-DD HH:mm:ss');
+  }
+  return true;
+}
+
+// 统一判定「该明细是否已把本次可归还数记满」:用于选设备白名单/全部完成判断(不依赖硬编码业务状态值)
 const isDeviceReturned = (device: any) => {
-  if (device?.is_return === true) return true;
-  const rs = device?.return_status;
-  if (rs && (rs.value === 2 || rs.label === '已归还')) return true;
-  if (device?.status === '已归还') return true;
-  return false;
+  const cap = Number(device?.available_quantity) || 0;
+  if (cap <= 0) return true;
+  return (Number(device?.borrow_count) || 0) >= cap;
 };
 
 // 过滤未归还设备的 device_no 列表,用于设备选择弹窗的排除
@@ -898,6 +1005,11 @@ const unreturnedDeviceIds = computed(() =>
 // 是否全部已归还(仅在归还页签生效)
 const allReturned = computed(() => unreturnedDeviceIds.value.length === 0);
 
+/** 列表中是否仍有「待归还」行:为 false 时整表隐藏「未归还可还」「归还数量」两列(仅保留已归还数量等) */
+const showUnreturnedReturnTableColumns = computed(() =>
+  returnDeviceList.value.some((d) => (Number(d.available_quantity) || 0) > 0)
+);
+
 //审批步骤
 const steps = ref<any[]>([]);
 // 仓库映射(id -> name)
@@ -1948,19 +2060,6 @@ const handleScanSearch = async (event?: Event) => {
     }
 };
 
-const normalizeReturnStatus = (status?: { value?: number | string; label?: string }) => {
-  const candidate = status?.value;
-  const numericValue =
-    candidate === undefined || candidate === null || candidate === ''
-      ? 2
-      : Number(candidate);
-
-  return {
-    value: Number.isNaN(numericValue) ? 2 : numericValue,
-    label: status?.label || '已归还'
-  };
-};
-
 // 处理归还流程RFID标签数组,逐个检索并提交
 const processReturnRfidTagArray = async () => {
   if (returnRfidTagArray.value.length === 0 || isProcessingReturnTagArray.value) return;
@@ -2064,15 +2163,13 @@ const processReturnRfidTagArray = async () => {
               
               if (res.data && res.data.length > 0) {
                 const device = res.data[0];
-                const normalizedStatus = normalizeReturnStatus(device.return_status);
-                
                 // 检查是否已存在
                 const existingDeviceIndex = returnDeviceList.value.findIndex(d => d.device_no === device.id);
                 if (existingDeviceIndex !== -1) {
-                  // 如果设备已存在,更新其状态
-                  returnDeviceList.value[existingDeviceIndex].return_status = normalizedStatus;
-                  returnDeviceList.value[existingDeviceIndex].is_return = true;
-                  returnDeviceList.value[existingDeviceIndex].return_time = dayjs().format('YYYY-MM-DD HH:mm:ss');
+                  const row = returnDeviceList.value[existingDeviceIndex];
+                  if (!applyReturnScanIncrement(row)) {
+                    return { success: false, code, message: '归还数量未增加(已达待归还上限或无待还)' };
+                  }
                   return { success: true, code };
                 } else {
                   // 设备不存在于归还列表中
@@ -2127,17 +2224,17 @@ const processReturnRfidTagArray = async () => {
       
       if (uniqueCodes.length > 1) {
         if (successCount > 0 && failCount === 0) {
-          ElMessage.success(`标签 ${trimmedTag}: 成功更新 ${successCount} 个设备状态为已归还`);
+          ElMessage.success(`标签 ${trimmedTag}: 成功增加 ${successCount} 个设备的归还数量`);
         } else if (successCount > 0 && failCount > 0) {
-          ElMessage.warning(`标签 ${trimmedTag}: 成功更新 ${successCount} 个设备状态,失败 ${failCount} 个`);
+          ElMessage.warning(`标签 ${trimmedTag}: 成功增加 ${successCount} 个设备的归还数量,失败 ${failCount} 个`);
           if (errorMessages.length > 0) {
             console.warn('[processReturnRfidTagArray] 批量处理错误详情:', errorMessages.slice(0, 3));
           }
         } else if (failCount > 0) {
-          ElMessage.error(`标签 ${trimmedTag}: 更新失败,共 ${failCount} 个设备编号`);
+          ElMessage.error(`标签 ${trimmedTag}: 处理失败,共 ${failCount} 个设备编号`);
         }
       } else if (successCount > 0) {
-        ElMessage.success(`标签 ${trimmedTag}: 设备状态已更新为已归还`);
+        ElMessage.success(`标签 ${trimmedTag}: 已增加 1 个归还数量`);
       } else if (failCount > 0 && errorMessages.length > 0) {
         ElMessage.warning(`标签 ${trimmedTag}: ${errorMessages[0]}`);
       }
@@ -2715,15 +2812,12 @@ const handleReturnScanSearch = async (event?: Event) => {
         
         if (res.data && res.data.length > 0) {
             const device = res.data[0];
-            const normalizedStatus = normalizeReturnStatus(device.return_status);
-            
-            // 检查是否已存在
             const existingDeviceIndex = returnDeviceList.value.findIndex(d => d.device_no === device.id);
             if (existingDeviceIndex !== -1) {
-                // 如果设备已存在,更新其状态
-                returnDeviceList.value[existingDeviceIndex].return_status = normalizedStatus;
-                returnDeviceList.value[existingDeviceIndex].is_return = true;
-                returnDeviceList.value[existingDeviceIndex].return_time = dayjs().format('YYYY-MM-DD HH:mm:ss');
+                const row = returnDeviceList.value[existingDeviceIndex];
+                if (!applyReturnScanIncrement(row)) {
+                  return { success: false, code, message: '归还数量未增加(已达待归还上限或无待还)' };
+                }
                 return { success: true, code };
             } else {
                 // 设备不存在于归还列表中
@@ -2767,18 +2861,18 @@ const handleReturnScanSearch = async (event?: Event) => {
       // 显示批量处理结果
       if (uniqueCodes.length > 1) {
         if (successCount > 0 && failCount === 0) {
-          ElMessage.success(`成功更新 ${successCount} 个设备状态为已归还`);
+          ElMessage.success(`成功增加 ${successCount} 个设备的归还数量`);
         } else if (successCount > 0 && failCount > 0) {
-          ElMessage.warning(`成功更新 ${successCount} 个设备状态,失败 ${failCount} 个`);
+          ElMessage.warning(`成功增加 ${successCount} 个设备的归还数量,失败 ${failCount} 个`);
           // 只显示前3个错误信息,避免消息过多
           if (errorMessages.length > 0) {
             console.warn('批量处理错误详情:', errorMessages.slice(0, 3));
           }
         } else if (failCount > 0) {
-          ElMessage.error(`更新失败,共 ${failCount} 个设备编号`);
+          ElMessage.error(`处理失败,共 ${failCount} 个设备编号`);
         }
       } else if (successCount > 0) {
-        ElMessage.success('设备状态已更新为已归还');
+        ElMessage.success('已增加 1 个归还数量');
       } else if (failCount > 0 && errorMessages.length > 0) {
         ElMessage.warning(errorMessages[0]);
       }
@@ -2936,17 +3030,24 @@ function onDeviceSelected(devices: Device[]) {
       }))
     );
   }else if(activeName.value === 'third'){
-    // 在添加前检查每个设备是否已存在
+    // 在添加前检查每个设备是否已存在;手动选设备:将本次归还数量记满至「待归还」上限
     devices.forEach(d => {
       const existingDeviceIndex = returnDeviceList.value.findIndex(item => item.device_no === d.id);
       if (existingDeviceIndex !== -1) {
-        // 如果设备已存在,更新其状态
-        returnDeviceList.value[existingDeviceIndex].return_status.value = 2;
-        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} 状态已更新为已归还`);
+        const row = returnDeviceList.value[existingDeviceIndex];
+        const cap = row.available_quantity ?? 0;
+        if (cap <= 0) {
+          ElMessage.warning('该设备无待归还数量');
+          return;
+        }
+        row.borrow_count = cap;
+        row.is_return = true;
+        row.return_time = dayjs().format('YYYY-MM-DD HH:mm:ss');
+        row.brand = d.brand || row.brand || '';
+        if (row.return_status) {
+          row.return_status = { value: 2, label: '已归还' };
+        }
+        ElMessage.success(`已将该设备本次归还记为 ${cap} 件`);
       } else {
         // 如果设备不存在,添加新记录
         /* returnDeviceList.value.push({
@@ -3168,22 +3269,9 @@ watch(() => props.modelValue, async (val) => {
 
                 // 同步 form.items 到 returnDeviceList
                 if (form.value.items && form.value.items.length > 0) {
-                    returnDeviceList.value = form.value.items
-                        .filter(item => item.device !== null)
-                        .map(item => ({
-                            device_no: item.device,
-                            device_code: item.device_code,
-                            device_type: item.remark,
-                            device_name: item.device_name,
-                            borrow_count: item.quantity,
-                            brand: item.brand ||item.device_brand || '',
-                            model: item.device_specification,
-                            warehouse: item.location,
-                            problem_records: item.problem_records,
-                            /* status: '未归还' */
-                            return_status:item.return_status,
-                            return_time:item.return_times
-                        }));
+                    returnDeviceList.value = (form.value.items as any[])
+                        .filter((item) => item.device !== null)
+                        .map(mapFormItemToReturnDeviceListRow);
                 }
                 // 同步 form.records 到 returnAbnormalList
                 if (form.value.records && form.value.records.length > 0) {
@@ -3192,7 +3280,7 @@ watch(() => props.modelValue, async (val) => {
                         application_no: form.value.application_no,
                         operator_name: form.value.app_user_borrower?.name||form.value.external_borrower_name||'',
                         user_code: form.value.borrower_info?.user_code || form.value.app_user_borrower?.user_code||'',
-                        emergency_phone: form.value.external_borrower_phone || form.value.app_user_borrower?.mobile||'',
+                        emergency_phone: form.value.app_user_borrower?.mobile||form.value.external_borrower_phone || '',
                         type: '损坏',
                         condition: form.value.borrower_damage_count || 0,
                         create_time: dayjs().format('YYYY-MM-DD HH:mm:ss')
@@ -3203,7 +3291,7 @@ watch(() => props.modelValue, async (val) => {
                         application_no: form.value.application_no,
                         operator_name: form.value.app_user_borrower?.name||form.value.external_borrower_name||'',
                         user_code: form.value.borrower_info?.user_code || form.value.app_user_borrower?.user_code||'',
-                        emergency_phone: form.value.external_borrower_phone || form.value.app_user_borrower?.mobile||'',
+                        emergency_phone: form.value.app_user_borrower?.mobile||form.value.external_borrower_phone || '',
                         type: '逾期',
                         condition: form.value.borrower_overdue_count || 0, // 逾期数量设为1
                         create_time: dayjs().format('YYYY-MM-DD HH:mm:ss')
@@ -3256,20 +3344,9 @@ watch(() => props.modelValue, async (val) => {
 
                 // 同步 form.items 到 returnDeviceList
                 if (form.value.items && form.value.items.length > 0) {
-                    returnDeviceList.value = form.value.items
-                        .filter(item => item.device !== null)
-                        .map(item => ({
-                            device_no: item.device,
-                            device_type: item.remark,
-                            device_name: item.device_name,
-                            borrow_count: item.quantity,
-                            brand: item.brand ||item.device_brand || '',
-                            model: item.device_specification,
-                            warehouse: item.location,
-                            problem_records: item.problem_records,
-                            return_status:item.return_status,
-                            return_time:item.return_times
-                        }));
+                    returnDeviceList.value = (form.value.items as any[])
+                        .filter((item) => item.device !== null)
+                        .map(mapFormItemToReturnDeviceListRow);
                 }
                 
                 // 处理附件回显 (编辑模式)
@@ -3498,19 +3575,29 @@ function onSubmit() {
       }
     });
   } else {
-    // 归还逻辑修改
-    // 使用所有设备列表而不是选中的设备
-    const allDevices = returnDeviceList.value
-  .filter(item => item.is_return === true)  // 只选择 return_status 为 2 的设备
-  .map(item => ({
+    // 归还:按每行「归还数量」提交,须大于 0 且不超过待归还
+    const toReturn = returnDeviceList.value.filter(
+      (item) => (Number(item.borrow_count) || 0) > 0
+    );
+    if (toReturn.length === 0) {
+      ElMessage.warning('请通过扫码/输入填写归还数量,或从手动归还中确认设备');
+      return;
+    }
+    const over = toReturn.find(
+      (item) => (Number(item.borrow_count) || 0) > (Number(item.available_quantity) || 0)
+    );
+    if (over) {
+      ElMessage.error('存在归还数量超过待归还数量,请检查');
+      return;
+    }
+    const allDevices = toReturn.map((item) => ({
       device: item.device_no,
       quantity: item.borrow_count,
       remark: returnRemark.value,
       device_id: Number(item.device_no) || 0,
-       // 添加异常相关字段
-       condition: item.condition, // 异常说明
-       damage_type:item.damage_type,
-       photo_urls: item.photos || [], // 异常照片
+      condition: item.condition,
+      damage_type: item.damage_type,
+      photo_urls: item.photos || [],
     }));
     
     const submitData = {
@@ -3618,6 +3705,12 @@ onBeforeUnmount(() => {
     height: 178px;
     display: block;
   }
+  .return-cell-placeholder {
+    color: #c0c4cc;
+  }
+  .return-cell-text {
+    color: #606266;
+  }
   .device-code-input {
     padding: 8px 12px;
     font-size: 14px;

+ 204 - 198
src/views/system/borrow/crud.tsx

@@ -1,5 +1,5 @@
 import * as api from './api';
-import { UserPageQuery, AddReq, DelReq, EditReq, CreateCrudOptionsProps, CreateCrudOptionsRet,dict ,useCompute} from '@fast-crud/fast-crud';
+import { UserPageQuery, AddReq, DelReq, EditReq, CreateCrudOptionsProps, CreateCrudOptionsRet, dict, useCompute } from '@fast-crud/fast-crud';
 import dayjs from 'dayjs';
 
 const { compute } = useCompute();
@@ -9,7 +9,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 		console.log(query);
 		return await api.GetList(query);
 	};
-		
+
 	const editRequest = async ({ form, row }: EditReq) => {
 		form.id = row.id;
 		return await api.UpdateObj(form);
@@ -36,11 +36,11 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 			actionbar: {
 				buttons: {
 					add: {
-					show: false,
-					text: '创建借用单',
-					click: () => {
-						window.dispatchEvent(new CustomEvent('borrow-add'))
-					}
+						show: false,
+						text: '创建借用单',
+						click: () => {
+							window.dispatchEvent(new CustomEvent('borrow-add'))
+						}
 					}
 				}
 			},
@@ -50,7 +50,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				buttons: {
 					view: {
 						show: true,
-						order:1,
+						order: 1,
 						click: ({ row }) => {
 							// eslint-disable-next-line no-console
 							// console.log("row:::",row);
@@ -58,59 +58,59 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						},
 					},
 					edit: {
-						show:compute( ({row})=>{
-							return row.status == 1 && row.borrow_type!==0;
-						}), 
-						order:4,
-						disabled:compute( ({row})=>{
+						show: compute(({ row }) => {
+							return row.status == 1 && row.borrow_type !== 0;
+						}),
+						order: 4,
+						disabled: compute(({ row }) => {
 							return row.status !== 1;
-						}), 
+						}),
 						click: ({ row }) => {
 							window.dispatchEvent(new CustomEvent('borrow-edit', { detail: row }));
 						}
 					},
 					remove: {
-						order:10,
-						show: compute( ({row})=>{
-							return row.status !== 5||row.status===6 ;
+						order: 10,
+						show: compute(({ row }) => {
+							return row.status !== 5 || row.status === 6;
 						}),
 					},
 					/* 查看结算单 */
 					settlement: {
-						order:6,
-						show:compute( ({row})=>{
-							return row.status === 5 ||row.status==7||row.status==8;
-						}), 
+						order: 6,
+						show: compute(({ row }) => {
+							return row.status === 5 || row.status == 7 || row.status == 8;
+						}),
 						text: '结算单',
 						click: ({ row }) => {
 							window.dispatchEvent(new CustomEvent('borrow-settlement', { detail: row }));
 						}
 					},
-					collectEquipment:{
-						order:2,
-						show:compute( ({row})=>{
+					collectEquipment: {
+						order: 2,
+						show: compute(({ row }) => {
 							return row.status === 2;
-						}), 
+						}),
 						text: '领取',
 						click: ({ row }) => {
 							window.dispatchEvent(new CustomEvent('borrow-collect', { detail: row }));
 						}
 					},
-					returnEquipment:{
-						order:3,
-						show:compute( ({row})=>{
-							return row.status === 5||row.status===6||row.status===8;
-						}), 
+					returnEquipment: {
+						order: 3,
+						show: compute(({ row }) => {
+							return row.status === 5 || row.status === 6 || row.status === 8;
+						}),
 						text: '归还',
 						click: ({ row }) => {
 							window.dispatchEvent(new CustomEvent('borrow-return', { detail: row }));
 						}
 					},
-					renewdevice:{
-						order:3,
-						show:compute( ({row})=>{
-							return (row.status === 5||row.status===6||row.status===8) && row.borrow_type==2;
-						}), 
+					renewdevice: {
+						order: 3,
+						show: compute(({ row }) => {
+							return (row.status === 5 || row.status === 6 || row.status === 8) && row.borrow_type == 2;
+						}),
 						text: '续借',
 						click: ({ row }) => {
 							window.dispatchEvent(new CustomEvent('renew-device', { detail: row }));
@@ -119,11 +119,11 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 
 				},
 			},
-			search:{
-				show:true,
+			search: {
+				show: true,
 			},
-			toolbar:{
-				show:false,
+			toolbar: {
+				show: false,
 			},
 			columns: {
 				_index: {
@@ -140,39 +140,41 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						},
 					},
 				},
-				search:{
+				search: {
 					title: '关键字搜索',
-					search: { show: true,type: 'input', },
+					search: { show: true, type: 'input', },
 					type: 'input',
 					form: {
 						component: { placeholder: '请输入关键字' },
-						show:false},
-					column: {show:false}
+						show: false
+					},
+					column: { show: false }
 				},
-				application_no: { 
+				application_no: {
 					search: { show: false },
 					title: '借用单编号',
-					column: { minWidth: 140 } ,
-					form:{
-					component: { placeholder: '请输入借用单编号' },
-					search:{
+					column: { minWidth: 140 },
+					form: {
 						component: { placeholder: '请输入借用单编号' },
-						rules: [{ required: true, message: '' }],
+						search: {
+							component: { placeholder: '请输入借用单编号' },
+							rules: [{ required: true, message: '' }],
+						}
 					}
-				}},
-				borrower_type_label: { title: '借用人角色', column: { minWidth: 120,sortable: true } },
-				borrow_type_label: { search: { show: false },title: '借用性质', column: { minWidth: 100 } },
-				user_code:{
+				},
+				borrower_type_label: { title: '借用人角色', column: { minWidth: 120, sortable: true } },
+				borrow_type_label: { search: { show: false }, title: '借用性质', column: { minWidth: 100 } },
+				user_code: {
 					title: '学号/工号',
-					search:{
-						show:true,		
+					search: {
+						show: true,
 					},
 					column: {
-						show:false,
+						show: false,
 						minWidth: 100,
 					},
-					form:{
-						show:false,
+					form: {
+						show: false,
 						component: { placeholder: '请输入学号/工号' },
 					}
 				},
@@ -183,27 +185,27 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				},column: { minWidth: 100 },form:{
 					component: { placeholder: '请输入学号/工号' },
 				}}, */
-				borrower_name:{
+				borrower_name: {
 					title: '借用人',
-					search:{
-						show:true,		
+					search: {
+						show: true,
 					},
 					column: {
-						show:false,
+						show: false,
 						minWidth: 100,
 					},
-					form:{
-						show:false,
+					form: {
+						show: false,
 						component: { placeholder: '请输入借用人' },
 					}
 				},
-				borrow_type:{
+				borrow_type: {
 					title: '借用性质',
 					type: 'dict-select',
-					search:{
-						show:false,		
-						
-						
+					search: {
+						show: false,
+
+
 					},
 					dict: dict({
 						data: [
@@ -213,172 +215,175 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						],
 					}),
 					column: {
-						show:false,
+						show: false,
 						minWidth: 100,
 					},
-					form:{
-						show:false,
+					form: {
+						show: false,
 						component: { placeholder: '请选择借用性质' },
 					}
 				},
-				borrower_phone:{
-					title:"联系方式",
-					search:{
-					show:true,		
-				},column: { show:false, minWidth: 100 },form:{
-					show:false,
-					component: { placeholder: '请输入联系方式' },
-				}}, 
+				borrower_phone: {
+					title: "联系方式",
+					search: {
+						show: true,
+					}, column: { show: false, minWidth: 100 }, form: {
+						show: false,
+						component: { placeholder: '请输入联系方式' },
+					}
+				},
 				"borrower_info.name": {
 					title: '借用人',
-					search:{
-						show:false,		
+					search: {
+						show: false,
 					},
 					column: {
-						show:true,
+						show: true,
 						minWidth: 100,
-					},  form:{
+					}, form: {
 						component: { placeholder: '请输入借用人' },
 					}
 				},
-				external_borrower_name: { 
-					title: '借用人', 
-					
-					column: { show:false, minWidth: 100 }, 
-					form:{
-					component: { 
-						placeholder: '请输入借用人',
-						search:{
-						component: { placeholder: '请输入借用人' },
-						
+				external_borrower_name: {
+					title: '借用人',
+
+					column: { show: false, minWidth: 100 },
+					form: {
+						component: {
+							placeholder: '请输入借用人',
+							search: {
+								component: { placeholder: '请输入借用人' },
+
+							}
+						},
 					}
-					 },
-				}
-			},
-			
-				"borrower_info.mobile": { 
-					title: '联系方式',	
-					search:{show:false}, column: { minWidth: 120 },  form:{
-					component: { placeholder: '请输入联系方式' },
-				}
-			    },
+				},
+
+				"borrower_info.mobile": {
+					title: '联系方式',
+					search: { show: false }, column: { minWidth: 120 }, form: {
+						component: { placeholder: '请输入联系方式' },
+					}
+				},
 				team_type_label: { title: '个人/团队', column: { minWidth: 90 } },
-				team_members: { title: '团队成员', column: { show:false,minWidth: 120 } },
-				team_members_count: { title: '团队人数', column: { show:false,minWidth: 80 }},
+				team_members: { title: '团队成员', column: { show: false, minWidth: 120 } },
+				team_members_count: { title: '团队人数', column: { show: false, minWidth: 80 } },
 				create_datetime: {
 					title: '创建时间',
-					column: { minWidth: 160, sortable: true,formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
+					column: { minWidth: 160, sortable: true, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
 				},
-				status_label: { 
-				title: '当前状态', 
-				column: { 
-					minWidth: 110, 
-					sortable: true,
-					cellRender: ({ value }: any) => {
-						// 根据状态值返回不同颜色的标签
-						const getStatusConfig = (status: string) => {
-							switch (status) {
-								case '待审批':
-									return { color: '#909399', bgColor: '#f4f4f5' }
-								case '已批准':
-									return { color: '#67c23a', bgColor: '#f0f9ff' }
-								case '已拒绝':
-									return { color: '#f56c6c', bgColor: '#fef0f0' }
-								case '已取消':
-									return { color: '#909399', bgColor: '#f4f4f5' }
-								case '已借出':
-									return { color: '#409eff', bgColor: '#ecf5ff' }
-								case '已归还':
-									return { color: '#67c23a', bgColor: '#f0f9ff' }
-								case '已逾期':
-									return { color: '#e6a23c', bgColor: '#fdf6ec' }
-								case '续借待审批':
-									return { color: '#909399', bgColor: '#f4f4f5' }
-								default:
-									return { color: '#606266', bgColor: '#f5f7fa' }
+				status_label: {
+					title: '当前状态',
+					column: {
+						minWidth: 110,
+						sortable: true,
+						cellRender: ({ value }: any) => {
+							// 根据状态值返回不同颜色的标签
+							const getStatusConfig = (status: string) => {
+								switch (status) {
+									case '待审批':
+										return { color: '#909399', bgColor: '#f4f4f5' }
+									case '已批准':
+										return { color: '#67c23a', bgColor: '#f0f9ff' }
+									case '已拒绝':
+										return { color: '#f56c6c', bgColor: '#fef0f0' }
+									case '已取消':
+										return { color: '#909399', bgColor: '#f4f4f5' }
+									case '已借出':
+										return { color: '#409eff', bgColor: '#ecf5ff' }
+									case '已归还':
+										return { color: '#67c23a', bgColor: '#f0f9ff' }
+									case '部分归还':
+										return { color: '#e6a23c', bgColor: '#fdf6ec' }
+									case '已逾期':
+										return { color: '#e6a23c', bgColor: '#fdf6ec' }
+									case '续借待审批':
+										return { color: '#909399', bgColor: '#f4f4f5' }
+									default:
+										return { color: '#606266', bgColor: '#f5f7fa' }
+								}
 							}
+
+							const config = getStatusConfig(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>
+							)
 						}
-						
-						const config = getStatusConfig(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>
-						)
 					}
-				} 
-			},
+				},
 				actual_start_time: {
 					title: '借出时间',
-					column: { minWidth: 140,sortable: true, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
+					column: { minWidth: 140, sortable: true, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
 				},
 				expected_end_time: {
 					title: '预计归还',
-					column: { minWidth: 140, sortable: true,formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD') : '') },
+					column: { minWidth: 140, sortable: true, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD') : '') },
 				},
 				actual_end_time: {
 					title: '完结时间',
-					column: { minWidth: 140,sortable: true, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
+					column: { minWidth: 140, sortable: true, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
 				},
 				/* return_location: { title: '存放仓库', column: { minWidth: 120 } }, */
-				
 
 
 
-				
-				purpose: { title: '借用目的', column: { minWidth: 150 ,show:false} },
+
+
+				purpose: { title: '借用目的', column: { minWidth: 150, show: false } },
 				expected_start_time: {
 					title: '预计开始',
-					
-					column: { minWidth: 140,show:false, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
+
+					column: { minWidth: 140, show: false, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
 				},
-			
-				
+
+
 				approve_time: {
 					title: '审批时间',
-					column: { show:false,minWidth: 140, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm') : '') },
+					column: { show: false, minWidth: 140, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm') : '') },
 				},
-				approve_remark: { title: '审批备注', column: {show:false, minWidth: 120 } },
-				total_items: { title: '设备数量', column: { show:false,minWidth: 80 } },
-				
-				
-				applicant_remark: { title: '申请备注', column: { show:false, minWidth: 120 } },
-				
+				approve_remark: { title: '审批备注', column: { show: false, minWidth: 120 } },
+				total_items: { title: '设备数量', column: { show: false, minWidth: 80 } },
+
+
+				applicant_remark: { title: '申请备注', column: { show: false, minWidth: 120 } },
+
 				update_datetime: {
 					title: '更新时间',
-					column: { show:false,minWidth: 160, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
+					column: { show: false, minWidth: 160, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
 				},
 				"items.device_code": {
 					title: '设备编号',
-					search:{
-						show:true,		
+					search: {
+						show: true,
 					},
 					column: {
-						show:false,
+						show: false,
 						minWidth: 100,
-					},  form:{
-						show:false,
+					}, form: {
+						show: false,
 						component: { placeholder: '请输入设备编号' },
 					}
 				},
 				abnormal_status: {
 					title: '异常记录',
 					type: 'dict-select',
-					search:{
-						show:true,		
+					search: {
+						show: true,
 					},
 					dict: dict({
 						data: [
@@ -389,7 +394,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						],
 					}),
 					column: {
-						show:true,
+						show: true,
 						minWidth: 110,
 						cellRender: ({ value }: any) => {
 							// 根据异常状态值返回不同颜色的标签
@@ -407,11 +412,11 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 										return { color: '#606266', bgColor: '#f5f7fa' }
 								}
 							}
-							
+
 							const config = getAbnormalStatusConfig(value)
-							
+
 							return (
-								<span 
+								<span
 									style={{
 										color: config.color,
 										backgroundColor: config.bgColor,
@@ -427,35 +432,36 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 								</span>
 							)
 						}
-					},  form:{
-						show:false,
+					}, form: {
+						show: false,
 						component: { placeholder: '请选择异常记录' },
 					}
 				},
 				status: {
 					title: '当前状态',
 					type: 'dict-select',
-					search:{
-						show:true,		
+					search: {
+						show: true,
 					},
 					dict: dict({
 						data: [
 							{ label: '待审批', value: 1 },
-							{ label: '已批准', value:2},
+							{ label: '已批准', value: 2 },
 							{ label: '已拒绝', value: 3 },
-							{ label: '已取消', value: 4},
-							{ label: '已借出', value: 5},
+							{ label: '已取消', value: 4 },
+							{ label: '已借出', value: 5 },
 							// { label: '有损坏和逾期', value: 6},
-							{ label: '已归还', value: 7},
-							{ label: '已逾期', value: 8},
-							{ label: '续借待审批', value: 9},
+							{ label: '部分归还', value: 6 },
+							{ label: '已归还', value: 7 },
+							{ label: '已逾期', value: 8 },
+							{ label: '续借待审批', value: 9 },
 						],
 					}),
 					column: {
-						show:false,
+						show: false,
 						minWidth: 100,
-					},  form:{
-						show:false,
+					}, form: {
+						show: false,
 						component: { placeholder: '请选择当前状态' },
 					}
 				},

+ 2 - 1
src/views/system/screenconsole/component/StatusCards.vue

@@ -81,8 +81,9 @@ const props = defineProps({
 
 
 const statusList = computed(() => [
+ { label: '已借出', value: props.statusData.pending_return, icon: Timer, color: '#E6A23C' },
   { label: '待审批', value: props.statusData.pending_approval, icon: DocumentChecked, color: '#409EFF' },
-  { label: '已借出', value: props.statusData.pending_return, icon: Timer, color: '#E6A23C' },
+ 
   { label: '待维修', value: props.statusData.pending_maintenance, icon: Tools, color: '#67C23A' },
   { label: '已逾期', value: props.statusData.pending_overdue, icon: Warning, color: '#F56C6C' },
 ])

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

@@ -57,6 +57,7 @@
 					>
 						{{ course.classdetail }} 老师:({{ course.teacher_name }}) 教室:{{ course.classroom }}
 					<el-link
+						v-if="!isEmbedded"
 						type="danger"
 						style="font-size: 12px;  top: 0; right: 0"
 						@click.stop="deleteCourse(course.id)"