yangg 1 日 前
コミット
99c4a5a16f
26 ファイル変更289 行追加103 行削除
  1. 1 1
      src/utils/service.ts
  2. 5 5
      src/views/system/Inventorycount/InventoryDialog/index.vue
  3. 3 3
      src/views/system/Inventorycount/crud.tsx
  4. 40 14
      src/views/system/allusers/crud.tsx
  5. 38 1
      src/views/system/allusers/index.vue
  6. 3 2
      src/views/system/borrow/api.ts
  7. 2 1
      src/views/system/borrow/approval/SpecialBorrowApp/index.vue
  8. 1 1
      src/views/system/borrow/approval/components/WarehouseSelectDialog.vue
  9. 3 3
      src/views/system/borrow/approval/curd.tsx
  10. 3 13
      src/views/system/borrow/component/BorrowTypeSelect/index.vue
  11. 11 1
      src/views/system/borrow/component/ClassroomBorrow/index.vue
  12. 3 0
      src/views/system/borrow/component/CollectEquipment/SelectDeviceDialog/index.vue
  13. 4 4
      src/views/system/borrow/component/CollectEquipment/SettlementDialog.vue
  14. 16 9
      src/views/system/borrow/component/CollectEquipment/index.vue
  15. 1 1
      src/views/system/borrow/component/SelectCatgory/index.vue
  16. 16 6
      src/views/system/borrow/component/SpecialBorrow/index.vue
  17. 1 1
      src/views/system/borrow/crud.tsx
  18. 9 6
      src/views/system/deviceclass/crud.tsx
  19. 21 1
      src/views/system/devicedamage/crud.tsx
  20. 6 6
      src/views/system/devicemaintenance/crud.tsx
  21. 1 0
      src/views/system/devicemanual/crud.tsx
  22. 1 1
      src/views/system/devicepreserve/crud.tsx
  23. 4 4
      src/views/system/organization/api.ts
  24. 2 2
      src/views/system/storelist/crud.tsx
  25. 89 12
      src/views/system/studentInfo/crud.tsx
  26. 5 5
      src/views/system/teacherInfor/crud.tsx

+ 1 - 1
src/utils/service.ts

@@ -112,7 +112,7 @@ function createService() {
 				
 				case 400:
 					console.log(error)
-					error.message = error.response.data.msg||'请求错误';
+					error.message = error.response.data.msg||error.response.data.error||'请求错误';
 					break;
 				case 401:
 					// Local.clear();

+ 5 - 5
src/views/system/Inventorycount/InventoryDialog/index.vue

@@ -1,16 +1,16 @@
 <template>
     <el-dialog v-model="visible" title="开始盘点" width="800px" @open="onOpen" @close="onClose">
       <div class="form-row">
-        <el-input v-model="device_code" placeholder="设备ID" @keyup.enter="handleAdd" />
-        <el-input v-model="check_no" placeholder="设备编码" @keyup.enter="handleAdd" />
+        <el-input v-model="device_code" placeholder="设备编号" @keyup.enter="handleAdd" />
+        <el-input v-model="check_no" placeholder="盘点编号" @keyup.enter="handleAdd" />
         <el-button type="primary" @click="handleAdd">添加</el-button>
       </div>
   
       <el-table :data="deviceList" style="margin-top: 20px">
         <el-table-column type="index" label="序号" width="60" />
-        <el-table-column prop="id" label="盘点id" width="60" />
-        <el-table-column prop="device_code" label="设备ID" />
-        <el-table-column prop="check_no" label="设备编码" />
+        <!-- <el-table-column prop="id" label="盘点id" width="60" /> -->
+        <el-table-column prop="device_code" label="设备编号" />
+        <el-table-column prop="check_no" label="盘点编号" />
         <el-table-column prop="status_display" label="状态" />
         <!-- <el-table-column prop="productName" label="商品名称" /> -->
         <el-table-column label="操作" width="180">

+ 3 - 3
src/views/system/Inventorycount/crud.tsx

@@ -165,7 +165,7 @@ export const createCrudOptions = function ({ crudExpose , inventoryDialog}: Crea
 					}
 				},
 				start_time:{
-					title: '维护日期',
+					title: '盘点日期',
 					type: 'datetime',
 					column: {
 						minWidth: 120,
@@ -173,8 +173,8 @@ export const createCrudOptions = function ({ crudExpose , inventoryDialog}: Crea
 					},
 					form: {
 						show:false,
-						component: { placeholder: '请填写维护日期' },
-						rules: [{ required: true, message: '请填写维护日期' }],
+						component: { placeholder: '请填写盘点日期' },
+						rules: [{ required: true, message: '请填写盘点日期' }],
 					},
 					viewForm:{
 						component: { placeholder: '' },

+ 40 - 14
src/views/system/allusers/crud.tsx

@@ -144,24 +144,24 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					}
 				},
 				username:{
-					title:'账号名',
+					title:'用户名',
 					type:'input',
 					column: {
 						show: false,
 						minWidth: 120,
 					},
 					form: {
-						component: { placeholder: '请填写账号名' },
-						rules: [{ required: true, message: '请填写账号名' }],
+						component: { placeholder: '请填写用户名' },
+						rules: [{ required: true, message: '请填写用户名' }],
 					},
 					viewForm:{
 						component: { placeholder: '' },
 					}
 				},
 				name: {
-					title: '名',
+					title: '名',
 					search: {
-						show: true,
+						show: false,
 					},
 					treeNode: true,
 					type: 'input',
@@ -171,10 +171,10 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					form: {
 						rules: [
 							// 表单校验规则
-							{ required: true, message: '名必填项' },
+							{ required: true, message: '名必填项' },
 						],
 						component: {
-							placeholder: '请输入名',
+							placeholder: '请输入名',
 						},
 					},
 				},
@@ -260,24 +260,31 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						data: [
 							{ label: '学生', value: 0 },
 							{ label: '教师', value: 1 },
-							{ label: '校外团体', value: 2 },
+							{ label: '外部用户', value: 2 },
 							{ label: '学院领导', value: 3 },
 						],
 					}),
 					form: {
-						component: { placeholder: '请填写租户' },
+						component: { placeholder: '请选择用户类型' },
 
 
 						
-						rules: [{ required: false, message: '请填写租户' }],
+						rules: [{ required: false, message: '请选择用户类型' }],
 					},
 				},
+				organization_ref:{
+					title: '组织架构',
+					type: "dict-cascader",
+					column: {
+						show: false,
+					}
+				},
 				/* 组织架构*/
-				/* organization_detail:{
+				organization_detail:{
 					title: '组织架构',
-					type: 'input',
+					type: 'dict-cascader',
 					column: {
-						show: true,
+						show: false,
 						minWidth: 200,
 						formatter: ({ row, value }: { row: any; value: any }) => {
 							// 如果有 organization_detail 对象,显示 full_path
@@ -296,16 +303,20 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					viewForm:{
 						component: { placeholder: '' },
 					}
-				}, */
+				},
 				organization:{
 					title: '学院',
 					type: 'input',
+					search:{
+						show:true
+					},
 					column: {
 						show: true,
 						minWidth: 200,
 						formatter: ({ row, value }: { row: any; value: any }) => {
 							// 如果有 organization_detail 对象,显示 parent_chain 的第二项(专业)
 							if (row.organization_detail && row.organization_detail.parent_chain && row.organization_detail.parent_chain.length >= 2) {
+								if(!row.organization_detail.parent_chain[0]) return
 								const major = row.organization_detail.parent_chain[0]; // 第二项是专业
 								return major.name || major.code || '';
 							}
@@ -322,6 +333,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						}, */
 					},
 					form: {
+						show:false,
 						component: { placeholder: '请填写学院' },
 						rules: [{ required: false, message: '请填写学院' }],
 					},
@@ -332,12 +344,16 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				sub_organization:{
 					title: '专业',
 					type: 'input',
+					search:{
+						show:true
+					},
 					column: {
 						show: true,
 						minWidth: 120,
 						formatter: ({ row, value }: { row: any; value: any }) => {
 							// 如果有 organization_detail 对象,显示 parent_chain 的第二项(专业)
 							if (row.organization_detail && row.organization_detail.parent_chain && row.organization_detail.parent_chain.length >= 2) {
+								if(!row.organization_detail.parent_chain[1]) return
 								const major = row.organization_detail.parent_chain[1]; // 第二项是专业
 								return major.name || major.code || '';
 							}
@@ -346,6 +362,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						},
 					},
 					form: {
+						show:false,
 						component: { placeholder: '请填写专业' },
 						rules: [{ required: false, message: '请填写专业' }],
 					},
@@ -356,12 +373,16 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				grade_or_level:{
 					title: '年级',
 					type: 'input',
+					search:{
+						show:true
+					},
 					column: {
 						show: true,
 						minWidth: 120,
 						formatter: ({ row, value }: { row: any; value: any }) => {
 							// 如果有 organization_detail 对象,显示 parent_chain 的第二项(专业)
 							if (row.organization_detail && row.organization_detail.parent_chain && row.organization_detail.parent_chain.length >= 2) {
+								if(!row.organization_detail.parent_chain[2]) return
 								const major = row.organization_detail.parent_chain[2]; // 第二项是专业
 								return major.name || major.code || '';
 							}
@@ -370,6 +391,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						},
 					},
 					form: {
+					show:false,
 						component: { placeholder: '请填写年级' },
 						rules: [{ required: false, message: '请填写年级' }],
 					},
@@ -380,6 +402,9 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				class_or_group:{
 					title: '班级',
 					type: 'input',
+					search:{
+						show:true
+					},
 					column: {
 						show: true,
 						minWidth: 120,
@@ -393,6 +418,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						},
 					},
 					form: {
+					show:false,
 						component: { placeholder: '请填写班级' },
 						rules: [{ required: false, message: '请填写班级' }],
 					},

+ 38 - 1
src/views/system/allusers/index.vue

@@ -6,10 +6,13 @@
 				<el-button type="primary" @click="handleDownloadTemplate">下载模板</el-button>
 				<el-button type="primary" @click="handleBatchExport">批量导出</el-button>
 			</template>
+			 <template #form_organization_ref="scope"><!-- :show-all-levels="false" -->
+				<el-cascader :disabled="scope.mode=='view'" v-model="scope.form.organization_ref" :options="options" :props="props1"  />
+			 </template>
 
 		</fs-crud>
 
-		<el-dialog v-model="importDialogVisible" title="批量导入设备" width="30%">
+		<el-dialog v-model="importDialogVisible" title="导入用户信息" width="30%">
 		<el-upload
 			ref="uploadRef"
 			:auto-upload="false"
@@ -34,6 +37,7 @@
 import { useFs } from '@fast-crud/fast-crud';
 import { onMounted,ref } from 'vue';
 import { GetPermission } from './api';
+import { GetTree } from '../studentInfo/api';
 import { createCrudOptions } from './crud';
 import { handleColumnPermission } from '/@/utils/columnPermission';
 import {request, downloadFile,downloadFilePost } from '/@/utils/service';
@@ -42,6 +46,38 @@ import { ElMessage } from 'element-plus';
 
 const importDialogVisible = ref(false); 
 const fileList = ref<File[]>([]);
+const options=ref<any[]>([])
+const props1 = {
+  checkStrictly: true,
+  label: 'name',
+  value: 'id',
+  children: 'children',
+  emitPath: false // 只返回选中节点的值,不返回完整路径
+}
+
+const init=()=>{
+	GetTree().then((res:any) => { 
+			console.log('组织架构API响应:', res);
+		// 兼容多种响应格式
+		if(res && (res.code === 200 || res.code === 2000 || !res.code)){
+			// 尝试多种数据结构
+			const data = res.data || res.results || res;
+			if (Array.isArray(data)) {
+				options.value = data;
+				console.log('成功赋值组织架构数据:', options.value);
+			} else {
+				console.warn('返回的数据不是数组格式:', data);
+				options.value = [];
+			}
+		} else {
+			console.error('获取组织架构数据失败:', res);
+			options.value = [];
+		}
+	}).catch((error: any) => {
+		console.error('请求组织架构数据失败:', error);
+		options.value = [];
+	});
+}
 
 const { crudBinding, crudRef, crudExpose, crudOptions, resetCrudOptions, selectedRows } = useFs({ createCrudOptions });
 
@@ -120,6 +156,7 @@ const handleBatchExport = () => {
 
 // 页面打开后获取列表数据
 onMounted(async () => {
+	init()
 	// 设置列权限
 	const newOptions = await handleColumnPermission(GetPermission, crudOptions);
 	//重置crudBinding

+ 3 - 2
src/views/system/borrow/api.ts

@@ -112,10 +112,11 @@ export async function RenewDevice(data: any) {
 
 
 /* 获取所有用户 */
-export function GetAllUser() {
+export function GetAllUser(params:any) {
 	return request({
 		url: '/api/system/app_user/',
-		method: 'get'
+		method: 'get',
+		params
 	});
 }
 

+ 2 - 1
src/views/system/borrow/approval/SpecialBorrowApp/index.vue

@@ -101,7 +101,7 @@
 				<el-input v-model="row.quantity" type="number" :min="1" prop="quantity" size="small" :disabled="isView" />
 				</template>
 				</el-table-column>
-				<el-table-column prop="location" label="存放仓库" />
+				<!-- <el-table-column prop="location" label="存放仓库" /> -->
 				<el-table-column label="操作" width="80">
 					<template #default="{ row, $index }">
 						<el-button type="text" style="color: red" @click="removeItem($index)" :disabled="isView">移除</el-button>
@@ -115,6 +115,7 @@
 			<div style="margin: 16px 0 8px 0; font-weight: bold">附件</div>
 			<div>
 			<el-upload
+			:disabled="true"
 			list-type="picture-card"
 			:show-file-list="true"
 			:http-request="handleCustomUpload"

+ 1 - 1
src/views/system/borrow/approval/components/WarehouseSelectDialog.vue

@@ -1,7 +1,7 @@
 <template>
   <el-dialog
     v-model="visible"
-    title="选择仓库"
+    title="选择领取仓库"
     width="500px"
     :before-close="handleClose"
   >

+ 3 - 3
src/views/system/borrow/approval/curd.tsx

@@ -296,13 +296,13 @@ export const createCrudOptions = function ({ crudExpose ,context, showRejectDial
 					title: '完结时间',
 					column: { minWidth: 140, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
 				},
-				return_location: { title: '存放仓库', column: { minWidth: 120 } },
+				/* return_location: { title: '存放仓库', column: { minWidth: 120 } }, */
 				purpose: { title: '借用目的', column: { minWidth: 150 ,show:false} },
-				expected_start_time: {
+				/* expected_start_time: {
 					title: '预计开始',
 					
 					column: { minWidth: 140,show:true, formatter: ({ value }: any) => (value ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '') },
-				},
+				}, */
 			
 				
 				approve_time: {

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

@@ -34,7 +34,7 @@
 		</div>
 		<template #footer>
 			<div class="modal-footer">
-				<el-button @click="onCancel" class="btn-close">关闭</el-button>
+				<el-button @click="onCancel" class="btns-close">关闭</el-button>
 			</div>
 		</template>
 	</el-dialog>
@@ -224,28 +224,18 @@ function onCancel() {
 	padding: 0 30px 30px;
 }
 
-.btn-close {
+.btns-close {
 	padding: 14px 40px;
 	border-radius: 12px;
 	font-size: 1.1rem;
 	font-weight: 600;
 	cursor: pointer;
-	transition: all 0.3s ease;
+	
 	border: none;
 	outline: none;
 	background: #e74c3c;
 	color: white;
-	box-shadow: 0 5px 15px rgba(231, 76, 60, 0.3);
-}
-
-.btn-close:hover {
-	background: #c0392b;
-	transform: translateY(-3px);
-	box-shadow: 0 8px 20px rgba(192, 57, 43, 0.4);
-}
 
-.btn-close:active {
-	transform: translateY(0);
 }
 
 .selection-indicator {

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

@@ -132,6 +132,7 @@
 				:show-file-list="true"
 				:http-request="handleCustomUpload"
 				:file-list="fileList"
+				:on-preview="handlePictureCardPreview"
 				style="margin-top: 10px;"
 				>
 				<el-icon><Plus /></el-icon>
@@ -149,6 +150,9 @@
 		<!-- <SelectDeviceDialog v-model:visible="showSelectDeviceDialog" @confirm="onDeviceSelected" /> -->
 		<SelectCatgory v-model:visible="showSelectDeviceDialog" @confirm="onDeviceSelected" />
 	</el-dialog>
+	 <el-dialog v-model="dialogVisible">
+		<img w-full :src="dialogImageUrl" alt="Preview Image" />
+	</el-dialog>
 </template>
 
 <script setup lang="ts">
@@ -160,13 +164,19 @@ import * as apis from '../../../timetablemanage/api';
 import * as api from '../../api';
 import { provide } from 'vue';
 import dayjs from 'dayjs';
-import { ElMessage } from 'element-plus';
+import { ElMessage,UploadProps, UploadUserFile } from 'element-plus';
 import { cloneDeep } from 'lodash-es';
 import Cookies from 'js-cookie';
 import { request } from '/@/utils/service';
 import { Plus } from '@element-plus/icons-vue';
 import { getUserInfo } from '../../../login/api';
 
+const dialogImageUrl = ref('')
+const dialogVisible = ref(false)
+const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
+  dialogImageUrl.value = uploadFile.url!
+  dialogVisible.value = true
+}
 // 禁止选择今天之前的日期
 const disabledDate = (time: Date) => {
   // 获取今天的开始时间(准确到日)

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

@@ -8,8 +8,11 @@
 			<el-table-column type="selection" width="50" />
 			<el-table-column type="index" label="序号" width="60" />
 			<el-table-column prop="name" label="设备名称" />
+			<el-table-column prop="code" label="设备编号"/>
 			<el-table-column prop="inventory.available_quantity" label="可用数量" />
 			<el-table-column prop="category_name" label="设备分类" />
+			<el-table-column prop="brand" label="品牌" />
+			<el-table-column prop="specification" label="规格型号" />
 			<el-table-column prop="warehouse" label="存放仓库" />
 		</el-table>
 		<el-pagination

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

@@ -216,15 +216,15 @@ async function handlerenew(){
     try {
       const res = await api.RenewDevice(payload)
       if(res.code===2000){
-      console.log(`设备 ${payload.device} 续借成功`, res)
+      console.log(`设备 ${payload.device} 续借申请提交成功`, res)
       emit('update:visible', false);
       emit('update:modelValue', formData.value);
-      ElMessage.success("续借成功");
+      ElMessage.success("续借申请提交成功");
 
       }
     } catch (err) {
-      console.error(`设备 ${payload.device} 续借失败`, err)
-      ElMessage.success("续借失败");
+      console.error(`设备 ${payload.device} 续借申请提交失败`, err)
+      ElMessage.success("续借申请提交失败");
     }
   }
 }

+ 16 - 9
src/views/system/borrow/component/CollectEquipment/index.vue

@@ -23,6 +23,7 @@
                             <el-input v-model="form.borrower_info.name" placeholder="请输入借用人" :disabled="true" />
                           </el-form-item> -->
                           <el-form-item label="借用人" prop="admin_borrower" v-if="form.borrower_type == 0">
+                        
                             <el-select v-model="form.admin_borrower" :placeholder="isView?'':'请选择借用人'" :disabled="true" >
                               <el-option  :label="adminList.name" :value="adminList.id" />
                             </el-select>
@@ -87,6 +88,7 @@
                             </el-form-item>
                         </el-col>
                         <el-col :span="4">
+                          <!-- ||form.approver_info.name -->
                             <el-form-item label="审批人" prop="applicant_remark_type">
                                 <el-select v-model="form.applicant_remark_type" placeholder="请选择" :disabled="true" >
                                     <el-option label="管理员" value="1"/>
@@ -142,6 +144,7 @@
                     <div class="el-upload__text">将文件拖到此处,或 <em>点击上传</em></div>
                     </el-upload> -->
                      <el-upload
+                     :disabled="true"
                       class="avatar-uploader"
                       action="#"
                       :show-file-list="false"
@@ -211,11 +214,11 @@
                             <el-table-column prop="device_name" label="设备名称" align="center" />
                             <el-table-column prop="borrow_count" label="借用数量" align="center" width="150">
                                 <template #default="{ row }">
-                                    <el-input-number v-model="row.borrow_count" :disabled="isView" :min="1" :max="999" size="small" />
+                                    <el-input-number v-model="row.borrow_count" :disabled="isView" :min="1" :max="row.available_quantity" size="small" />
                                 </template>
                             </el-table-column>
                             <el-table-column prop="brand" label="品牌" align="center" />
-                            <el-table-column prop="model" label="现货型号" align="center" />
+                            <el-table-column prop="device_specification" label="规格型号" align="center" />
                             <!-- <el-table-column prop="warehouse" label="存放仓库" align="center" /> -->
                             <el-table-column label="操作" width="80" align="center">
                                 <template #default="{ $index }">
@@ -280,7 +283,7 @@
                             <el-table-column prop="device_name" label="设备名称" align="center" />
                             <el-table-column prop="borrow_count" label="借用数量" align="center" width="150">
                                 <template #default="{ row }">
-                                    <el-input-number v-model="row.borrow_count" :min="1" :max="999" size="small" :disabled="true" />
+                                    <el-input-number v-model="row.borrow_count" :min="1" :max="row.available_quantity" size="small" :disabled="true" />
                                 </template>
                             </el-table-column>
                             <el-table-column prop="brand" label="品牌" align="center" />
@@ -418,7 +421,7 @@ async function getAdminList() {
 /* 获取所有用户 */
 const allUserList = ref([]);
 async function getAllUserList() {
-	const res = await api.GetAllUser();
+	const res = await api.GetAllUser({page:1,limit:60});
 	allUserList.value = res.data;
 	// 设置默认选择第一个用户
 	if (allUserList.value.length > 0) {
@@ -460,6 +463,7 @@ interface DeviceListItem {
     data: string;
   }>;
   device_specification?: string;
+  available_quantity?:number;
 }
 
 interface FormItem {
@@ -613,7 +617,7 @@ function buildSteps(data: any) {
     },
     {
       title: '待审批',
-      description: '待审批人审批',
+      description: `待审批人:${data.approver_info.name} 审批`,
       status: data.status >= 2 ? 'finish' : 'process'
     }
   ];
@@ -624,7 +628,7 @@ function buildSteps(data: any) {
   if (data.status >= 2&&data.status!=3 && data.borrow_type!=1) {
     steps.value.push({
       title: '审批通过',
-      description: `审批人:${approverinfo.name},时 间:${data.approve_time},仓库:${getWarehouseName(data.warehouse)||'暂无仓库'}`,
+      description: `审批人:${approverinfo.name},时 间:${data.approve_time},领取仓库:${getWarehouseName(data.warehouse)||'暂无仓库'}`,
       status: 'finish'
     });
   } else if (data.status === 3) {
@@ -718,8 +722,10 @@ const handleScanSearch = async () => {
                     device_name: device.name || '',
                     borrow_count: 1,
                     brand: device.brand || '',
+                    device_specification: device.specification,
                     model: device.model || '',
-                    warehouse: device.warehouse
+                    warehouse: device.warehouse,
+                    available_quantity:device.available_quantity
                 });
                 ElMessage.success('设备已添加到列表');
             }
@@ -848,8 +854,9 @@ function onDeviceSelected(devices: Device[]) {
         borrow_count: 1,
         brand: d.brand || '',
         model: d.model,
-        device_specification: d.device_specification,
-        warehouse: d.warehouse
+        device_specification: d.specification,
+        warehouse: d.warehouse,
+        available_quantity:d.available_quantity
       }))
     );
   }else if(activeName.value === 'third'){

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

@@ -9,7 +9,7 @@
 			<el-table-column type="index" label="序号" width="60" />
             <!-- <el-table-column prop="code" label="分类编号" /> -->
 			<el-table-column prop="name" label="设备分类" />
-			<el-table-column prop="description" label="描述" />
+			<el-table-column prop="description" label="描述" min-width="160" />
 		<!-- 	<el-table-column prop="category_name" label="设备分类" /> 
 			<el-table-column prop="warehouse" label="存放仓库" />-->
 		</el-table>

+ 16 - 6
src/views/system/borrow/component/SpecialBorrow/index.vue

@@ -122,6 +122,7 @@
 			:show-file-list="true"
 			:http-request="handleCustomUpload"
 			:file-list="fileList"
+			:on-preview="handlePictureCardPreview"
 			style="margin-top: 10px;"
 			>
 			<el-icon><Plus /></el-icon>
@@ -149,6 +150,9 @@
 			<el-button @click="onCancel">关闭</el-button>
 			<el-button type="primary" @click="onSubmit" v-if="!isView">提交</el-button>
 		</template>
+	</el-dialog>
+	 <el-dialog v-model="dialogVisible">
+		<img w-full :src="dialogImageUrl" alt="Preview Image" />
 	</el-dialog>
 	<!-- <SelectDeviceDialog v-model:visible="showSelectDeviceDialog" @confirm="onDeviceSelected" /> -->
 	<SelectCatgory v-model:visible="showSelectDeviceDialog" @confirm="onDeviceSelected" />
@@ -158,7 +162,7 @@
 import { ref, watch, defineProps, defineEmits, onMounted,computed } from 'vue';
 import SelectDeviceDialog from './SelectDeviceDialog/index.vue';
 import dayjs from 'dayjs';
-import { ElMessage } from 'element-plus';
+import { ElMessage ,UploadProps, UploadUserFile } from 'element-plus';
 import * as api from '../../api';
 import Cookies from 'js-cookie';
 import { request } from '/@/utils/service';
@@ -166,6 +170,12 @@ import { Plus } from '@element-plus/icons-vue';
 import SelectCatgory from '../SelectCatgory/index.vue';
 import { getUserInfo } from '../../../login/api';
 
+const dialogImageUrl = ref('')
+const dialogVisible = ref(false)
+const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
+  dialogImageUrl.value = uploadFile.url!
+  dialogVisible.value = true
+}
 // 禁止选择今天之前的日期
 const disabledDate = (time: Date) => {
   // 获取今天的开始时间(准确到日)
@@ -186,12 +196,12 @@ async function getAdminList() {
 /* 获取所有用户 */
 const allUserList = ref([]);
 async function getAllUserList() {
-	const res = await api.GetAllUser();
+	const res = await api.GetAllUser({page:1,limit:60});
 	allUserList.value = res.data;
 	// 设置默认选择第一个用户
-	if (allUserList.value.length > 0) {
+	/* if (allUserList.value.length > 0) {
 		form.value.app_user_borrower = allUserList.value[0].id;
-	}
+	} */
 	console.log("allUserList.value:::",allUserList.value)	
 }
 
@@ -337,7 +347,7 @@ const form = ref({
 	external_borrower_phone:"",
 	emergency_contact: '111',
 	emergency_phone: '11111',
-	app_user_borrower: 1,
+	app_user_borrower: null,
 	team_type: 0,
 	team_members_count: 2,
 	team_members: '',
@@ -397,7 +407,7 @@ onMounted(() => {
 		if (userInfo) {
 			form.value.borrower_type = 1;
 			form.value.external_borrower_name = userInfo.username || '';
-			form.value.app_user_borrower = Number(userInfo.dept_info?.dept_id )|| 1;
+			form.value.app_user_borrower =  null;/* Number(userInfo.dept_info?.dept_id )|| */
 			form.value.external_borrower_phone = userInfo.mobile || '';
 			form.value.borrower_dept = userInfo.dept_info?.dept_name || '';
 		}

+ 1 - 1
src/views/system/borrow/crud.tsx

@@ -105,7 +105,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					renewdevice:{
 						order:3,
 						show:compute( ({row})=>{
-							return row.status === 5||row.status===6||row.status===8;
+							return (row.status === 5||row.status===6||row.status===8) && row.borrow_type==2;
 						}), 
 						text: '续借',
 						click: ({ row }) => {

+ 9 - 6
src/views/system/deviceclass/crud.tsx

@@ -104,7 +104,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				name: {
 					title: '分类名称',
 					search: {
-						show: true,
+						show: false,
 					},
 					treeNode: true,
 					type: 'input',
@@ -126,14 +126,14 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					}
 				},
 				description:{
-					title: '设备描述',
+					title: '分类描述',
 					type: 'input',
 					column: {
 						width: 800,
 					},
 					form: {
-						component: { placeholder: '请填写设备描述' },
-						rules: [{ required: false, message: '请填写设备描述' }],
+						component: { placeholder: '请填写分类描述' },
+						rules: [{ required: false, message: '请填写分类描述' }],
 					},
 					viewForm:{
 						component: { placeholder: '' },
@@ -178,6 +178,9 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				status:{
 					title: '状态',
 					type: 'dict-select',
+					search:{
+						show:true
+					},
 					column: {
 						width: 120,
 					},
@@ -188,8 +191,8 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						],
 					}),
 					form: {
-						component: { placeholder: '请填写状态' },
-						rules: [{ required: true, message: '请填写状态' }],
+						component: { placeholder: '请选择状态' },
+						rules: [{ required: true, message: '请选择状态' }],
 					},
 					viewForm:{
 						component: { placeholder: '' },

+ 21 - 1
src/views/system/devicedamage/crud.tsx

@@ -123,7 +123,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				damage_no: {
 					title: '编号',
 					search: {
-						show: true,
+						show: false,
 					},
 					treeNode: true,
 					type: 'input',
@@ -384,9 +384,29 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						rules: [{ required: true, message: '' }],
 					}
 				},
+				status:{
+					title: '状态',
+					type: 'dict-select',
+					dict: dict({
+						data: [
+							{ value: 4, label: '已确认' },
+							{ value: 5, label: '已撤销' }
+						]
+					}),
+					search:{
+						show:true
+					},
+					column:{
+						show:false
+					},
+					form: {
+						show:false,
+					}
+				},
 				status_display:{
 					title: '状态',
 					type: 'input',
+					
 					column: {
 						minWidth: 120,
 					},

+ 6 - 6
src/views/system/devicemaintenance/crud.tsx

@@ -275,7 +275,7 @@ export const createCrudOptions = function ({ crudExpose,  dialogId,
 							precision: 0
 						},
 						rules: [
-							{ required: false, message: '请填写维修数量' },
+							{ required: true, message: '请填写维修数量' },
 							{ 
 								type: 'number', 
 								min: 0, 
@@ -396,9 +396,9 @@ export const createCrudOptions = function ({ crudExpose,  dialogId,
 							precision: 2
 						},
 						rules: [
-							{ required: compute(({ form }) => {
+							{ required: false/* compute(({ form }) => {
 								return form && form.status === 3;
-							}), message: '请填写维修费用' },
+							}) */, message: '请填写维修费用' },
 							{ 
 								type: 'number', 
 								min: 0, 
@@ -475,9 +475,9 @@ export const createCrudOptions = function ({ crudExpose,  dialogId,
 						}),
 						component: { placeholder: '请填写维修人姓名' },
 						rules: [
-							{ required: compute(({ form }) => {
+							{ required:true /* compute(({ form }) => {
 								return form && form.status === 2;
-							}), message: '请填写维修人' },
+							}) */, message: '请填写维修人' },
 							{ min: 2, max: 20, message: '维修人姓名长度应在2-20个字符之间', trigger: 'blur' },
 							{
 								validator: (rule: any, value: any, callback: any) => {
@@ -676,7 +676,7 @@ export const createCrudOptions = function ({ crudExpose,  dialogId,
 							return form && form.status == 3;
 						}),
 						component: { placeholder: '请填写维修结果' },
-						rules: [{ required: false, message: '请填写维修结果' }],
+						rules: [{ required: true, message: '请填写维修结果' }],
 					},
 					viewForm:{
 						component: { placeholder: '' },

+ 1 - 0
src/views/system/devicemanual/crud.tsx

@@ -174,6 +174,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					form: {
 						show:true,
 						component: { placeholder: '请选择设备名称',
+									filterable: true,
 							onChange: async (context: any) => {
 								// 当选择设备时,自动回填设备编号和设备名称
 								console.log("onChange context:", context);

+ 1 - 1
src/views/system/devicepreserve/crud.tsx

@@ -92,7 +92,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					column: {show:false}
 				},
 				record_no: {
-					title: '编码',
+					title: '维护单编号',
 					search: {
 						show: false,
 					},

+ 4 - 4
src/views/system/organization/api.ts

@@ -13,10 +13,10 @@ export interface OrganizationParams {
 }
 
 export const ORG_TYPE_OPTIONS = [
-  { value: 1, label: '学' },
-  { value: 2, label: '系' },
-  { value: 3, label: '年级' },
-  { value: 4, label: '班级/组别' },
+  { value: 1, label: '学' },
+  { value: 2, label: '系' },
+  { value: 3, label: '专业' },
+  { value: 4, label: '班级' },
 ];
 
 /* 获取设备列表 */

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

@@ -158,13 +158,13 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					title: '状态',
 					type: 'dict-select',
 					column: {
-						show: false,
+						show: true,
 						minWidth: 120,
 					},
 					dict: dict({
 						data: [
 							{ label: '启用', value: true },
-							{ label: '禁用', value: false },
+							{ label: '禁用', value: false,color:'danger' },
 						],
 					}),
 					form: {

+ 89 - 12
src/views/system/studentInfo/crud.tsx

@@ -114,9 +114,9 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					}
 				},
 				name: {
-					title: '名',
+					title: '名',
 					search: {
-						show: true,
+						show: false,
 					},
 					treeNode: true,
 					type: 'input',
@@ -126,10 +126,10 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					form: {
 						rules: [
 							// 表单校验规则
-							{ required: true, message: '名必填项' },
+							{ required: true, message: '名必填项' },
 						],
 						component: {
-							placeholder: '请输入名',
+							placeholder: '请输入名',
 						},
 					},
 					viewForm:{
@@ -281,7 +281,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						rules: [{ required: false, message: '请填写租户' }],
 					},
 				},
-				organization:{
+				/* organization:{
 					title: '学院',
 					type: 'input',
 					column: {
@@ -296,10 +296,13 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					viewForm:{
 						component: { placeholder: '' },
 					}
-				},
+				}, */
 				organization_ref:{
 					title: '组织架构',
 					type: "dict-cascader",
+					column: {
+						show:false
+					}
 					/* dict: dict({
 						isTree: true,
 						url: "/api/system/organization/tree/",
@@ -324,15 +327,65 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						rules: [{ required: false, message: '请选择组织架构' }]
 					} */
 				},
+				organization:{
+					title: '学院',
+					type: 'input',
+					search:{
+						show:true
+					},
+					column: {
+						show: true,
+						minWidth: 200,
+						formatter: ({ row, value }: { row: any; value: any }) => {
+							// 如果有 organization_detail 对象,显示 parent_chain 的第二项(专业)
+							if (row.organization_detail && row.organization_detail.parent_chain && row.organization_detail.parent_chain.length >= 2) {
+								if(!row.organization_detail.parent_chain[0]) return
+								const major = row.organization_detail.parent_chain[0]; // 第二项是专业
+								return major.name || major.code || '';
+							}
+							// 否则显示原始值
+							return value || row.sub_organization;
+						},
+						/* formatter: ({ row, value }: { row: any; value: any }) => {
+							// 如果有 organization_detail 对象,显示 full_path
+							if (row.organization_detail && row.organization_detail.full_path) {
+								return row.organization_detail.full_path;
+							}
+							// 否则显示原始值
+							return value || '';
+						}, */
+					},
+					form: {
+						show:false,
+						component: { placeholder: '请填写学院' },
+						rules: [{ required: false, message: '请填写学院' }],
+					},
+					viewForm:{
+						component: { placeholder: '' },
+					}
+				},
 				sub_organization:{
 					title: '专业',
 					type: 'input',
+					search:{
+						show:true
+					},
 					column: {
-						show: false,
+						show: true,
 						minWidth: 120,
+						formatter: ({ row, value }: { row: any; value: any }) => {
+							// 如果有 organization_detail 对象,显示 parent_chain 的第二项(专业)
+							if (row.organization_detail && row.organization_detail.parent_chain && row.organization_detail.parent_chain.length >= 2) {
+								if(!row.organization_detail.parent_chain[1]) return
+								const major = row.organization_detail.parent_chain[1]; // 第二项是专业
+								return major.name || major.code || '';
+							}
+							// 否则显示原始值
+							return value || row.sub_organization;
+						},
 					},
 					form: {
-						show: false,
+						show:false,
 						component: { placeholder: '请填写专业' },
 						rules: [{ required: false, message: '请填写专业' }],
 					},
@@ -343,12 +396,25 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				grade_or_level:{
 					title: '年级',
 					type: 'input',
+					search:{
+						show:true
+					},
 					column: {
-						show: false,
+						show: true,
 						minWidth: 120,
+						formatter: ({ row, value }: { row: any; value: any }) => {
+							// 如果有 organization_detail 对象,显示 parent_chain 的第二项(专业)
+							if (row.organization_detail && row.organization_detail.parent_chain && row.organization_detail.parent_chain.length >= 2) {
+								if(!row.organization_detail.parent_chain[2]) return
+								const major = row.organization_detail.parent_chain[2]; // 第二项是专业
+								return major.name || major.code || '';
+							}
+							// 否则显示原始值
+							return value || row.grade_or_level;
+						},
 					},
 					form: {
-						show: false,
+					show:false,
 						component: { placeholder: '请填写年级' },
 						rules: [{ required: false, message: '请填写年级' }],
 					},
@@ -359,12 +425,23 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 				class_or_group:{
 					title: '班级',
 					type: 'input',
+				search:{
+						show:true
+					},
 					column: {
-						show: false,
+						show: true,
 						minWidth: 120,
+						formatter: ({ row, value }: { row: any; value: any }) => {
+							// 如果有 organization_detail 对象,显示 name
+							if (row.organization_detail && row.organization_detail.name) {
+								return row.organization_detail.name;
+							}
+							// 否则显示原始值
+							return value || row.class_or_group;
+						},
 					},
 					form: {
-						show: false,
+					show:false,
 						component: { placeholder: '请填写班级' },
 						rules: [{ required: false, message: '请填写班级' }],
 					},

+ 5 - 5
src/views/system/teacherInfor/crud.tsx

@@ -102,7 +102,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					}
 				},
 				name: {
-					title: '名',
+					title: '名',
 					search: {
 						show: true,
 					},
@@ -114,10 +114,10 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					form: {
 						rules: [
 							// 表单校验规则
-							{ required: true, message: '名必填项' },
+							{ required: true, message: '名必填项' },
 						],
 						component: {
-							placeholder: '请输入名',
+							placeholder: '请输入名',
 						},
 					},
 				},
@@ -237,7 +237,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 						data: [
 							/* { label: '学生', value: 0 }, */
 							{ label: '教师', value: 1 },
-							{ label: '校外团体', value: 2 },
+							/* { label: '校外团体', value: 2 }, */
 							{ label: '学院领导', value: 3 },
 						],
 					}),
@@ -266,7 +266,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp
 					title: '专业',
 					type: 'input',
 					column: {
-						show: true,
+						show: false,
 						minWidth: 120,
 					},
 					form: {