yzx vor 5 Monaten
Ursprung
Commit
2376b9aa5c

+ 246 - 8
app/admin/controller/borrow/BorrowApp.php

@@ -10,6 +10,7 @@ use ba\Random;
 use modules\notification\Notification;
 use think\facade\Db;
 use app\common\controller\SnowflakeId;
+use think\migration\command\migrate\Status;
 use Throwable;
 use app\admin\controller\borrow\BorrowTools;
 use app\common\library\xmwechat\offiaccount\OaService;
@@ -70,6 +71,12 @@ class BorrowApp extends Backend
                             ['college_leader_id', '=',  $this->auth->id]
                         ]);
                     })
+                    ->whereOr(function($query) {
+                        $query->where([
+                            ["status", "in", [0,2,6]],
+                            ['user_id', '=', $this->auth->id]
+                        ]);
+                    })
                     ->order($order)
                     ->paginate($limit);
             } else if ($user_group_id == 4) {
@@ -78,8 +85,8 @@ class BorrowApp extends Backend
                     ->where($where)
                     ->where(function($query) {
                         $query->where([
-                            ["status", "=", [0,2,6]],
-                            ['user_id', '=', $user_id]
+                            ["status", "in", [0,2,6]],
+                            ['user_id', '=', $this->auth->id]
                         ]);
                     })
                     ->order($order)
@@ -108,6 +115,12 @@ class BorrowApp extends Backend
                             ['college_leader_id', '=',  $this->auth->id]
                         ]);
                     })
+                    ->whereOr(function($query) {
+                        $query->where([
+                            ["status", "in", [3,5]],
+                            ['user_id', '=', $this->auth->id]
+                        ]);
+                    })
                     ->order($order)
                     ->paginate($limit);
             } else if ($user_group_id == 4) {
@@ -116,8 +129,8 @@ class BorrowApp extends Backend
                     ->where($where)
                     ->where(function($query) {
                         $query->where([
-                            ["status", "=", [3,5]],
-                            ['user_id', '=', $user_id]
+                            ["status", "in", [3,5]],
+                            ['user_id', '=', $this->auth->id]
                         ]);
                     })
                     ->order($order)
@@ -130,7 +143,7 @@ class BorrowApp extends Backend
                     ->where($where)
                     ->where(function($query) {
                         $query->where([
-                            ["status", "in", [1,4,7]]
+                            ["status", "in", [1,4,7,8]]
                         ]);
                     })
                     ->order($order)
@@ -141,11 +154,17 @@ class BorrowApp extends Backend
                     ->where($where)
                     ->where(function($query) {
                         $query->where([
-                            ["status", "in",  [1,4,7]],
+                            ["status", "in",  [1,4,7,8]],
                             ['purpose', '=', 0],
                             ['college_leader_id', '=',  $this->auth->id]
                         ]);
                     })
+                    ->whereOr(function($query) {
+                        $query->where([
+                            ["status", "in", [1,4,7,8]],
+                            ['user_id', '=', $this->auth->id]
+                        ]);
+                    })
                     ->order($order)
                     ->paginate($limit);
             } else if ($user_group_id == 4) {
@@ -154,8 +173,8 @@ class BorrowApp extends Backend
                     ->where($where)
                     ->where(function($query) {
                         $query->where([
-                            ["status", "=", [1,4,7]],
-                            ['user_id', '=', $user_id]
+                            ["status", "in", [1,4,7,8]],
+                            ['user_id', '=', $this->auth->id]
                         ]);
                     })
                     ->order($order)
@@ -443,6 +462,225 @@ class BorrowApp extends Backend
         ]);
     }
 
+
+    public function editAccessories($id = null): void
+    {
+        if ($this->request->isPost()) {
+            $data = $this->request->post()['data'];
+            //获取用户类型
+            $user_id = $this->auth->id;
+            $this->model->startTrans();
+            $result = false;
+            //判断是否是科研类借取并判断是否需要领导审核
+            try {
+                $open_id = Db::name('oauth_log')->where('user_id',$user_id)->value('opid');
+                if ($open_id !== null) {
+                    $text = [
+                        "openid" => $open_id,
+                        "pagepath" => "pages/login/index",
+                        "data" => [
+                            'character_string1' => $data['id'],
+                            'thing5' => $this->auth->nickname,
+                        ]
+                    ];
+                }
+                //判断是否是科研类借取并判断是否需要领导审核
+                if ($data['purpose'] == 0) {
+                    $text['data']['const3'] = '科研借单';
+                    $text['data']['const4'] = ['需要修改配件数量'];
+                    $data['status'] = 8;
+                    try {
+                        $result = $this->model->update($data);
+                        $this->model->commit();
+                    } catch (Throwable $e) {
+                        $this->model->rollback();
+                        $this->error($e->getMessage());
+                    }
+                } else {
+                    $data['approval_person'] = $this->auth->nickname;
+                    $data['approval_person_id'] = $this->auth->id;
+                    $text['data']['const3'] = ['教学借单'];
+                    $text['data']['const4'] = ['需要修改配件数量'];
+                    $data['status'] = 8;
+                    try {
+                        $result = $this->model->update($data);
+                        $this->model->commit();
+                    } catch (Throwable $e) {
+                        $this->model->rollback();
+                        $this->error($e->getMessage());
+                    }
+                }
+
+                // 提交事务
+                $this->model->commit();
+            } catch (Throwable $e) {
+                // 回滚事务
+                $this->model->rollback();
+                $this->error($e->getMessage());
+            }
+
+            if ($result !== false) {
+//                $this->success(__('Update successful'));
+                $open_id = Db::name('oauth_log')->where('user_id',$user_id)->value('opid');
+                if ($open_id !== null) {
+                    // halt($text);
+                    $res = self::wxResultMessage($text);
+
+                    if ($res  === true) {
+                        $this->success(__('Update successful'));
+                    } else {
+                        $this->success("更新成功,但消息发送失败,请检查网络或联系管理员");
+                    }
+                }else{
+                    $this->success('更新成功!但对方未配置公众号,消息提示失败!');
+                }
+            } else {
+                $this->error(__('No rows updated'));
+            }
+        }
+
+    }
+
+
+    public function changeAssetNum($id = null): void
+    {
+        if ($this->request->isPost()) {
+            $data = $this->request->post()['data'];
+            // 调整仪器的变化
+            if($data['status'] != 8){
+                $this->BorrowTools->checkRules($data);
+                $data = $this->BorrowTools->checkText($data);
+                $this->BorrowTools->checkAsset($data);
+
+                $asset_userArr = [];
+                $admin_idArr = [];
+                $open_idArr = [];
+
+                //获取消息推送目标人
+                foreach ($data['asset'] as $k => $v){
+                    $asset_user = Db::name('asset')->where('asset_name',$data['asset'][$k]['model'])->value('user');
+                    $admin_id = Db::name('admin')->where('nickname',$asset_user)->value('id');
+                    $open_id = Db::name('oauth_log')->where('user_id', $admin_id)->value('opid');
+                    if(!in_array($asset_user,$asset_userArr)){
+                        $asset_userArr[] = $asset_user;
+                    }
+                    if(!in_array($admin_id,$admin_idArr)){
+                        $admin_idArr[] = $admin_id;
+                    }
+                    if(!in_array($open_id,$open_idArr)){
+                        $open_idArr[] = $open_id;
+                    }
+                }
+                $data['approval_person_id'] = implode(',',$admin_idArr);
+                $data['approval_person'] = implode(',',$asset_userArr);
+
+                if (!empty($open_idArr) && $open_idArr !== null ) {
+                    $text = [
+                        "pagepath" => "pages/login/index",
+                        "data" => [
+                            'character_string7' => $this->model->id,
+                            'thing4' => $data['username'],
+                        ]
+                    ];
+                }
+            }
+            //获取用户类型
+            $user_id = $this->auth->id;
+            $user_group_id = Db::name('admin_group_access')->where('uid', $user_id)->value("group_id");
+
+            $data = $this->excludeFields($data);
+
+            $this->model->startTrans();
+            $result = false;
+            //判断是否是科研类借取并判断是否需要领导审核
+            try {
+                if($data['status'] == 8){
+                    $data['status'] = 2;
+                }else{
+                    $data['status'] = 0;
+                }
+                //判断是否是科研类借取并判断是否需要领导审核
+                if ($data['purpose'] == 0) {
+                    $text['data']['const6'] = ['科研借单'];
+                    $leader = Db::name('admin')->where('switch', 1)->find();
+                    $data['college_leader'] = $leader['nickname'];
+                    if ($user_group_id !== 3) {
+                        try {
+                            $result = $this->model->update($data);
+                            $this->model->commit();
+                        } catch (Throwable $e) {
+                            $this->model->rollback();
+                            $this->error($e->getMessage());
+                        }
+                    } else {
+                        $data['college_leader_id'] = $user_id;
+                        $data['college_leader'] = $this->auth->nickname;
+                        if ($data['status'] == '1') {
+                            $data['status'] = 7;
+                        }
+                        $result = false;
+                        $this->model->startTrans();
+                        try {
+                            $result = $this->model->update($data);
+                            $this->model->commit();
+                        } catch (Throwable $e) {
+                            $this->model->rollback();
+                            $this->error($e->getMessage());
+                        }
+                    }
+                } else {
+                    $text['data']['const6'] = ['教学借单'];
+                    $result = $this->model->update($data);
+                }
+                Db::name('accessories')->update($data['accessories']);
+                // 提交事务
+                $this->model->commit();
+            } catch (Throwable $e) {
+                // 回滚事务
+                $this->model->rollback();
+                $this->error($e->getMessage());
+            }
+
+            if ($result !== false) {
+                if (!empty($open_idArr) && $open_idArr !== null && $data['status'] != 8) {
+                    foreach ($open_idArr as $k => $v){
+                        $text['open_id'] = $open_idArr[$k];
+                        if ( $open_idArr[$k] !== [] &&  $open_idArr[$k] !== null) {
+                            //  halt($text);
+                            $res = self::wxAuditMessage($text);
+                        }
+                    }
+                    if ($res  === true) {
+                        $this->success(__('Update successful'));
+                    } else {
+                        $this->success("更新成功,但消息发送失败,请检查网络或联系管理员");
+                    }
+                } else {
+                    $this->success('更新成功!但对方未配置公众号,消息提示失败!');
+                }
+            } else {
+                $this->error(__('No rows were added'));
+            }
+        }
+
+        $row = $this->model->find($id);
+        if (!$row) {
+            $this->error(__('Record not found'));
+        }
+        if ($row['status'] == 0 || $row['status'] == 1 || $row['status'] == 6 || $row['status'] == 7) {
+            $rows = $this->BorrowNumber->field('*,asset_name as model')->where('borrow_id', $id)->select();
+        } else {
+            $rows = $this->BorrowAccess->field('a.*,s.student_name,a.asset_name as model')->alias('a')->leftjoin('student s', 'a.student_id = s.id')->where('borrow_id', $id)->select();
+        }
+        $row['accessories'] = Db::name('accessories')->where('borrow_id', $id)->find();
+        $row['asset'] = $rows;
+        $row['borrowImg'] = Db::name('borrow_img')->where('borrow_id', $id)->select();
+
+        $this->success('', [
+            'row' => $row
+        ]);
+    }
+
     public function add(): void
     {
         if ($this->request->isPost()) {

+ 30 - 33
app/admin/controller/borrow/BorrowApply.php

@@ -49,7 +49,7 @@ class BorrowApply extends Backend
             $res = $this->model
                 ->alias($alias)
                 ->where($where)
-                ->where("status", 'in', [0, 1, 6,7])
+                ->where("status", 'in', [0,1,6,7,8])
                 ->where("user_id",$user_id)
                 ->order($order)
                 ->paginate($limit);
@@ -57,7 +57,7 @@ class BorrowApply extends Backend
             $res = $this->model
                 ->alias($alias)
                 ->where($where)
-                ->where("status", 'in', [0,1, 6,7])
+                ->where("status", 'in', [0,1, 6,7,8])
                 ->where('purpose', 0)
                 ->where("user_id",$user_id)
                 ->order($order)
@@ -80,7 +80,7 @@ class BorrowApply extends Backend
     public function add(): void
     {
         if ($this->request->isPost()) {
-            
+
             $data = $this->request->post();
             $this->BorrowTools->checkRules($data);
             $data = $this->BorrowTools->checkText($data);
@@ -88,8 +88,8 @@ class BorrowApply extends Backend
             $asset_userArr = [];
             $admin_idArr = [];
             $open_idArr = [];
-            
-            
+
+
             //获取消息推送目标人
             foreach ($data['asset'] as $k => $v){
                 $asset_user = Db::name('asset')->where('asset_name', $data['asset'][$k]['model'])->value('user');
@@ -105,16 +105,16 @@ class BorrowApply extends Backend
                     $open_idArr[] = $open_id;
                 }
             }
-            
-         
+
+
             $data['approval_person_id'] = implode(',',$admin_idArr);
             $data['approval_person'] = implode(',',$asset_userArr);
-          
+
             //获取借单编号
             $uniID = new SnowflakeId;
             $data['user_id'] = $this->auth->id;
 
-            
+
             //尝试存储
             try {
                 $data['status'] = 0;
@@ -128,7 +128,7 @@ class BorrowApply extends Backend
                             'thing4' => $data['username'],
                         ]
                     ];
-                    
+
                 }
                 if ($data['purpose'] == 0) {
                     $text['data']['const6'] = ['科研借单'];
@@ -137,8 +137,8 @@ class BorrowApply extends Backend
                 } else {
                     $text['data']['const6'] = ['教学借单'];
                 }
-                
-               
+
+
                 $groupAccess = [];
                 foreach ($data['asset'] as $datum) {
                     $groupAccess[] = [
@@ -157,7 +157,7 @@ class BorrowApply extends Backend
                 $this->model->rollback();
                 $this->error($e->getMessage());
             }
-           
+
             if ($result !== false) {
                 if (!empty($open_idArr) && $open_idArr !== null) {
                     foreach ($open_idArr as $k => $v){
@@ -219,35 +219,33 @@ class BorrowApply extends Backend
         if (!$row) {
             $this->error(__('Record not found'));
         }
- 
+
         if ($row['status'] == 0 || $row['status'] == 1 || $row['status'] == 6 || $row['status'] == 7) {
-//             halt(1);
             $rows = $this->BorrowNumber->field('*,asset_name as model')->where('borrow_id', $id)->select();
         } else {
-//             halt($id);
             $rows = $this->BorrowAccess->field('*,asset_name as model')->where('borrow_id', $id)->select();
         }
-        
+
         $row['asset'] = $rows;
         $row['accessories'] = Db::name('accessories')->where('borrow_id', $id)->find();
 
 //        halt(123);
         if ($this->request->isPost()) {
             $data = $this->request->post();
-            $this->BorrowTools->checkRules($data);
-            $data = $this->BorrowTools->checkText($data);
-            if (!isset($data['status']) && ($data['status'] !== 0 || $data['status'] !== 1)) {
-                $this->error("仅待实验室审核与被驳回状态可以修改!!");
+            if (!isset($data['status']) && ($data['status'] !== 0 || $data['status'] !== 1 || $data['status'] == 8)) {
+                $this->error("当前状态不可修改!!");
             }
-            $data['status'] = 0;
             $data = $this->excludeFields($data);
+            if($data['status'] != 8){
+                $this->BorrowTools->checkRules($data);
+                $data = $this->BorrowTools->checkText($data);
+                $this->BorrowTools->checkAsset($data);
+            }
+            $data['status'] = 0;
             $this->model->startTrans();
             $result = false;
             try {
-                $this->BorrowTools->checkAsset($data);
-
                 $result = $this->model->update($data);
-
                 Db::name('accessories')->update($data['accessories']);
                 // 提交事务
                 $this->model->commit();
@@ -309,7 +307,6 @@ class BorrowApply extends Backend
      */
     public function wxAuditMessage($res = null): bool
     {
-        
         $openid = $res["openid"];
         $template_id = 'xsYnur6koCvgu1nUQwHmu8DX5SoL06P_nYMyK_oThGU';
         $data = [
@@ -329,25 +326,25 @@ class BorrowApply extends Backend
         $result = OaService::getInstance()->sendTemplateMessage($openid, $template_id, $data, $url, $miniprogram);
         return $result;
     }
-    
+
     function getPlainTextFromHtml($html)
     {
-    
+
         // Remove the HTML tags
         $html = strip_tags($html);
-    
+
         // Convert HTML entities to single characters
         $html     = html_entity_decode($html, ENT_QUOTES, 'UTF-8');
         $html_len = mb_strlen($html, 'UTF-8');
-    
+
         // Make the string the desired number of characters
         // Note that substr is not good as it counts by bytes and not characters
         $html = mb_substr($html, 0, strlen($html), 'UTF-8');
-    
+
         return $html;
     }
- 
-     public function  getProtocol(){
+
+    public function  getProtocol(){
         $data = Db::name('protocol')->where("switch",1)->value('editor');
         if($data){
             $this->success('', [

+ 176 - 0
uniapp/components/swiper-list-item/swiper-list-item.vue

@@ -0,0 +1,176 @@
+<!-- 在这个文件对每个tab对应的列表进行渲染 -->
+<template>
+	<view class="content">
+		<!--  :enable-back-to-top="currentIndex===tabIndex" 在微信小程序上可以多加这一句,因为默认是允许点击返回顶部的,但是这个页面有多个scroll-view,会全部返回顶部,所以需要控制是当前index才允许点击返回顶部 -->
+		<!-- 如果当前页已经加载过数据或者当前切换到的tab是当前页,才展示当前页数据(懒加载) -->
+		<z-paging v-if="firstLoaded || isCurrentPage" ref="paging" v-model="dataList" @query="queryList" :fixed="false">
+			<!-- 如果希望其他view跟着页面滚动,可以放在z-paging标签内 -->
+					<view class="" style="overflow-y: scroll !important;height: 94vh;">
+							<block v-for="(items, indexs) in dataList" :key="indexs" v-if="dataList">
+									<view class="jie_card" @click="detail(items.id,items.status)">
+										<view class="jie_card_title">
+											<text class="jie_card_title_text">借单号:{{items.encoding}}</text>
+											<text class="jie_tags" v-if="items.purpose===1">教学借单</text>
+											<text class="jie_tags jie_tags2" v-if="items.purpose===0">科研借单</text>
+										</view>
+										<uv-line></uv-line>
+										<view class="jie_contend">
+											<view class="jie_contend_text">
+												<text class="jie_contend_text1">借取人:</text>
+												<text class="jie_contend_text2">{{items.username}}</text>
+											</view>
+											<view class="jie_contend_text">
+												<text class="jie_contend_text1">联系电话:</text>
+												<text class="jie_contend_text2">{{items.mobile}}</text>
+											</view>
+											<view class="jie_contend_text">
+												<text class="jie_contend_text1">申请时间:</text>
+												<text class="jie_contend_text2">{{items.create_time}}</text>
+											</view>
+										</view>
+										<view class="jie_card_ztai" v-if="items.status===6">学院审批</view>
+										<view class="jie_card_ztai" v-if="items.status===0">待审批</view>
+										<view class="jie_card_ztai jie_card_ztai2" v-if="items.status===2">待使用</view>
+										<view class="jie_card_ztai" v-if="items.status===5">已逾期</view>
+										<view class="jie_card_ztai jie_card_ztai2" v-if="items.status===3">使用中</view>
+										<view class="jie_card_ztai" v-if="items.status===1">已驳回</view>
+										<view class="jie_card_ztai" v-if="items.status===7">学院驳回</view>
+										<view class="jie_card_ztai jie_card_ztai2" v-if="items.status===4">已归还</view>
+										<view class="jie_card_ztai" v-if="items.status===8">修改配件</view>
+									</view>
+							</block>
+						<view v-else>
+							<uv-empty text="暂无数据" icon="https://cdn.uviewui.com/uview/empty/list.png"></uv-empty>
+						</view>
+						<view style="width: 100%; height: 5vh;"></view>
+					</view>
+		</z-paging>
+	</view>
+</template>
+
+<script>
+	import { requestApi } from '@/api/request.js';
+	export default {
+		data() {
+			return {
+				// v-model绑定的这个变量不要在分页请求结束中自己赋值!!!
+				pageNo: 1,
+				pageSize: 10,
+				dataList: [],
+				// 当前组件是否已经加载过了
+				firstLoaded: false,
+				// 是否滚动到当前页
+				isCurrentPage: false
+			}
+		},
+		props:{
+			// 当前组件的index,也就是当前组件是swiper中的第几个
+			tabIndex: {
+				type: Number,
+				default: function(){
+					return 0
+				}
+			},
+			// 当前swiper切换到第几个index
+			currentIndex: {
+				type: Number,
+				default: function(){
+					return 0
+				}
+			}
+		},
+		watch: {
+			currentIndex: {
+				handler(newVal) {
+					if(newVal === this.tabIndex){
+						// 懒加载,当滑动到当前的item时,才去加载
+						if(!this.firstLoaded){
+							// 这里需要延迟渲染z-paging的原因是为了避免在一些平台上立即渲染可能引发的底层报错问题
+							this.$nextTick(() => {
+								setTimeout(() => {
+									this.isCurrentPage = true;
+								}, 100);
+							})
+						}
+					}
+				},
+				immediate: true
+			},
+		},
+		methods: {
+			detail(id , status) {
+				if(this.tabIndex + 1 == 3 && (status ==1 || status == 7 || status == 8) ){ 
+					wx.navigateTo({
+						url: '/pages/teacher/edit?data=' + JSON.stringify(id)
+					})
+				
+				}else{ 
+					wx.navigateTo({ 
+						url: '/pages/index/detail?data=' + JSON.stringify(id)
+					})
+				}
+			},
+			// 接收父组件传过来的刷新列表要求
+			reload() {
+				this.$nextTick(() => {
+					// 刷新列表数据(如果不希望列表pageNo被重置可以用refresh代替reload方法)
+					this.$refs.paging && this.$refs.paging.reload();	
+				})
+			},
+			async queryList(pageNo, pageSize) {
+				
+				wx.showLoading({ title: '加载中' });
+				const params = {
+					page: pageNo,
+					limit: pageSize,
+					type: this.tabIndex + 1
+				};
+				await requestApi('index.php/admin/borrow.borrowApp/apply', params).then(res => {
+					//将请求的结果数组传递给z-paging
+					this.$refs.paging.complete(res.data.list.data);
+					console.log(res.data.list.data)
+					this.firstLoaded = true;
+					wx.hideLoading();
+				}).catch(res => {
+					this.$refs.paging.complete(false);
+				})
+			},
+			itemClick(item) {
+				console.log('点击了', item.title);
+			}
+		}
+	}
+</script>
+
+<style>
+	/* 注意:父节点需要固定高度,z-paging的height:100%才会生效 */
+	.content {
+		height: 100%;
+	}
+	
+	.item {
+		position: relative;
+		height: 150rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding: 0rpx 30rpx;
+	}
+
+	.item-detail {
+		padding: 5rpx 15rpx;
+		border-radius: 10rpx;
+		font-size: 28rpx;
+		color: white;
+		background-color: #007AFF;
+	}
+
+	.item-line {
+		position: absolute;
+		bottom: 0rpx;
+		left: 0rpx;
+		height: 1px;
+		width: 100%;
+		background-color: #eeeeee;
+	}
+</style>

+ 9 - 0
uniapp/pages.json

@@ -102,6 +102,15 @@
 				"enablePullDownRefresh" : false
 			}
 		},
+		{
+			"path" : "pages/teacher/edit",
+			"style" : 
+			{
+				"navigationBarTitleText" : "仪器借取修改",
+				"enablePullDownRefresh" : false,
+				"navigationBarBackgroundColor":"#ffffff"
+			}
+		},
 		{
 			"path" : "pages/student/index",
 			"style" : 

+ 35 - 7
uniapp/pages/index/detail.vue

@@ -339,6 +339,9 @@
 								<uni-td>{{ datailData.accessories.r_usb }}</uni-td>
 							</uni-tr>	   
 						</block>
+						<!-- 占位 -->
+						<view class="" style="height: 200rpx; width: 100%;">
+						</view>
 					</uni-table>
 				</block>
 			
@@ -381,7 +384,12 @@
 						<!-- 						<view class="detail_topbox_1">
 							<text>操作</text>
 						</view> -->
+						
+						
 						<view class="jiechu">
+							<button v-if="isUseing" @click="editAccessories" type="warn"
+								style="background-color: #ff5500; margin-bottom: 20rpx;">驳回修改配件</button>
+							
 							<!-- 科研借单 -->
 							<button v-if="datailData.purpose==0" @click="jiechuscan" type="primary"
 								style="background-color: #2d8cf0; margin-bottom: 20rpx;">借出扫码</button>
@@ -446,7 +454,7 @@
 
 <script setup>
 	import {
-		ref
+		ref , watch 
 	} from 'vue'
 	import {
 		onLoad,
@@ -467,7 +475,7 @@
 	let return_data2 = ref(null)
 	let damage_data = ref(null)
 	let replace_data = ref(null)
-	const status = ref(['待审批', '已驳回', '待使用', '使用中', '已归还', '已逾期', '学院审批', '领导驳回'])
+	const status = ref(['待审批', '已驳回', '待使用', '使用中', '已归还', '已逾期', '学院审批', '学院驳回','修改配件'])
 	const remark = ref(null)
 	var analyze = ref(null)
 	// var datailData = ref(null)
@@ -528,10 +536,9 @@
 			title: '加载中',
 			mask: false,
 		})
-		// console.log(event)
+		
 		analyze = JSON.parse(event.data)
-		// console.log(analyze)
-
+		
 		xiangqinData.value = await requestApi('admin/borrow.BorrowApp/edit?id=' +
 			analyze + '&server=1')
 		datailData.value = xiangqinData.value.data.row
@@ -625,7 +632,21 @@
 		
 		
 	}
-
+	async function editAccessories() {
+		wx.showLoading({
+			title: '审批完成',
+			icon: 'success',
+			// duration: 2000
+		})
+		await requestApi(
+			'admin/borrow.BorrowApp/editAccessories?server=1', {
+				data: datailData.value
+			},
+			'POST'
+		)
+		jiazhai()
+		wx.hideLoading()
+	}
 	// 科研借出扫码
 	function jiechuscan() {
 		wx.scanCode({
@@ -972,7 +993,7 @@
 					reject(err);
 				}
 			});
-		});
+		});X
 	};
 	async function jiazhai(){
 		xiangqinData.value = await requestApi('admin/borrow.BorrowApp/edit?id=' +
@@ -980,6 +1001,12 @@
 		datailData.value = xiangqinData.value.data.row
 		console.log('我更新了')
 	}
+	let isUseing = ref(false);
+ 
+    watch(() => datailData.value.asset, (newVal) => {
+        isUseing.value = !newVal.some(item => item.asset_id !== null);
+    }, { deep: true, immediate: true });
+   
 	// console.log(data_scan.value)
 </script>
 
@@ -1099,6 +1126,7 @@
 	}
 
 	.biaoge_box {
+		 
 		width: 100%;
 		overflow-y: auto
 	}

+ 171 - 190
uniapp/pages/teacher/index.vue

@@ -1,244 +1,225 @@
 <template>
-		<view class="teacher_box" >
-			<view class=""  v-if="data == 0">
-				<uv-empty text="暂无数据"  icon="https://cdn.uviewui.com/uview/empty/list.png"></uv-empty>
-			</view>
-			<block v-for="(items, indexs) in data" :key="indexs">
-				<!-- <block v-if="items.status==0 || items.status==2"> -->
-				<view class="jie_card" @click="detail(items.id)">
-					<view class="jie_card_title">
-						<text class="jie_card_title_text">借单号:{{items.encoding}}</text>
-						<text class="jie_tags" v-if="items.purpose==1">教学借单</text>
-						<text class="jie_tags jie_tags2" v-if="items.purpose==0">科研借单</text>
-					</view>
-					<uv-line></uv-line>
-					<view class="jie_contend">
-						<view class="jie_contend_text">
-							<text class="jie_contend_text1">借取人:</text>
-							<text class="jie_contend_text2">{{items.username}}</text>
-						</view>
-						<view class="jie_contend_text">
-							<text class="jie_contend_text1">联系电话:</text>
-							<text class="jie_contend_text2">{{items.mobile}}</text>
-						</view>
-						<view class="jie_contend_text">
-							<text class="jie_contend_text1">申请时间:</text>
-							<text class="jie_contend_text2">{{items.create_time}}</text>
-						</view>
-					</view>
-					<view class="jie_card_ztai" v-if="items.status==0">待审批</view>
-					<view class="jie_card_ztai jie_card_ztai2" v-else-if="items.status==2">待使用</view>
-					<view class="jie_card_ztai" v-else-if="items.status==1">已驳回</view>
-					<view class="jie_card_ztai jie_card_ztai2" v-else-if="items.status==4">已归还</view>
-					<view class="jie_card_ztai" v-else-if="items.status==5">已逾期</view>
-					<view class="jie_card_ztai jie_card_ztai2" v-else-if="items.status==3">使用中</view>
-					<view class="jie_card_ztai" v-else-if="items.status==7">领导驳回</view>
-				</view>
-				<!-- </block> -->
-			</block>
-			<view style="width: 100%; height:9vh;">
-			
-			</view>
+
+	<view class="">
+<!-- 		<view class="search">
+			<uv-search placeholder="请输入搜索内容" v-model="keyword"></uv-search>
+		</view> -->
+		<view class="">
+			   
+		<!-- 使用z-paging-swiper为根节点可以免计算高度 -->
+		 <z-paging-swiper>
+  			<template #top>
+				<z-tabs ref="tabs" :list="tabList" :current="current" @change="tabsChange" />
+			</template>
+			<!-- swiper必须设置height:100%,因为swiper有默认的高度,只有设置高度100%才可以铺满页面  -->
+			<swiper class="swiper" :current="current" @transition="swiperTransition" @animationfinish="swiperAnimationfinish">
+				<swiper-item class="swiper-item" v-for="(item, index) in tabList" :key="index">
+					<!-- 这里的swiper-list-item为demo中为演示用定义的组件,列表及分页代码在swiper-list-item组件内 -->
+					<!-- 请注意,swiper-list-item非z-paging内置组件,在自己的项目中必须自己创建,若未创建则会报组件不存在的错误 -->
+					<swiper-list-item ref="listItem" :tabIndex="index" :currentIndex="current"> 
+					</swiper-list-item>
+				</swiper-item>
+			</swiper>
+		</z-paging-swiper>
 		</view>
+	</view>
+	<view class="">
+	        <uni-popup ref="wxpopup" type="bottom">
+	            <view class="tihuan_box" style="height: 650rpx;">
+	                <view class="" style="text-align: center; margin-bottom: 20rpx; font-size: 35rpx; font-weight: bold;margin-bottom: 30rpx;">
+	                    请长按识别二维码关注公众号
+	                    <br />
+	                    方便信息及时通知
+	                </view>
+	                <view class="" style="width: 80%; margin: 0 auto;">
+	                    <image :show-menu-by-longpress="true" src="../../static/img/erweima.jpg" mode="widthFix" style="width: 100%;"></image>
+	                </view>
+	            </view>
+	        </uni-popup>
+	    </view>
 		<view class="yiqijie" @click="application">
 			<image src="../../static/img/sqi.png" mode="widthFix" style="width: 50rpx;margin-bottom: -12rpx;"></image>
 			仪器借用
 		</view>
 </template>
 <script setup>
-	import {
-		ref
-	} from 'vue'
+    import { ref } from 'vue';
+
 	import {
 		requestApi
 	} from '@/api/request.js'
 	// onShow是uni-app中的一个全局生命周期函数,当页面从后台进入前台显示时会被触发。
 	import {
 		onShow,
-		onUnload
 	} from '@dcloudio/uni-app'
 	// import {Base64} from 'js-base64'
-	
+	let wxpopup = ref(null)
+	let userInfo =wx.getStorageSync('userInfos')
+	let stuts = ref(false)
+	let current =ref(0);
+	// console.log('w',userInfo)
 	// 获取后端需要的token认证
 	// 使用wx.getStorageSync('userInfo')从本地存储中获取用户令牌信息并将其赋值给user_Token变量。
 	const data = ref([])
 	onShow(async () => {
-		wx.showLoading({
-		  title: '加载中',
-		})
-		const res = await requestApi('index.php/admin/borrow.borrowApp/apply')
-		wx.hideLoading()
-		// console.log(res)
-		data.value = res.data.list
-		console.log(res )
+		// reloadCurrentList()
+		const ress= await requestApi(
+		'api/xmwechat.Offiaccount/isBind?server=1',
+		{
+			id:userInfo.userInfo.id,
+		},
+		'POST'
+		)
+		// console.log(ress)
+		if(ress.data.isBind=='ture'){
+			// console.log(ress)
+		}else{
+			wxpopup.value.open('top');
+		}
 	})
-	// 进详情页
-	function detail(id) {
-		wx.navigateTo({
-			url: '/pages/index/detail?data='+ JSON.stringify(id)
-		})
-	}
+	const paging = ref(null);
+	const dataList = ref([])
+	const listItem = ref();
+	 
 	// 进借单申请页
 	function application() {
 		wx.navigateTo({
 			url: '/pages/teacher/application'
 		})
 	}
+	
+	const tabs = ref(null); 
+	const tabList = ref(['待审批/待使用', '使用中/逾期', '已驳回/已归还']);
+	
+	
+	// tabs通知swiper切换
+	const tabsChange = (index) => {
+		current.value = index;
+	}
+
+	// swiper滑动中
+	const swiperTransition = (e) => {
+		tabs.value.setDx(e.detail.dx);
+	}
 
+	// swiper滑动结束
+	const swiperAnimationfinish = (e) => {
+		current.value = e.detail.current;
+		tabs.value.unlockDx();
+	}
+	const reloadCurrentList = () => {
+		listItem.value[current.value].reload();
+	}
 </script>
 
 <style lang="less">
 	page {
-		background-color: rgb(244, 245, 249);
+		background-color: #fff;
 		overflow: hidden;
 	}
-	.yiqijie{
-		width: 280rpx;
-		height: 90rpx;
-		background-color:#2d8cf0;
-		position: absolute;
-		bottom: 230rpx;
-		right: 50%;
-		transform:translate(50%,50%);
-		border-radius: 50rpx;
-		line-height: 90rpx;
-		text-align: center;
-		color: #fff;
-		font-size: 35rpx;
-	}
-	.yijiey{
-		// float: right;
-		width: 90%;
-		margin: 0 auto;
-	}
-	
-	.jiedanss{
-		float: left;
-		width: 73%;
+	.zp-swiper-super.data-v-bd8ff6a5 {
+		background-color: rgb(244, 245, 249);
 	}
-	
 	.search {
-		height: 45px;
-		padding: 20rpx 20rpx 20rpx 20rpx;
-		background-color: #fff;
+		margin: 20rpx 20rpx 0 20rpx;
+	}
+	.zp-swiper-container-fixed.data-v-bd8ff6a5 {
+		// top: 100rpx !important;
 	}
 
 	swiper {
 		min-height: 95vh;
 		// overflow-y:auto;
 	}
+	 
+	.jie_card {
+		width: 94%;
+		margin: 30rpx auto;
+		height: 270rpx;
+		border-radius: 20rpx;
+		background-color: #fff;
+		// padding: 10rpx 0;
+	}
+	.tihuan_box {
+		width: 84%;
+		height: 500rpx;
+		padding: 30rpx;
+		background-color: #fff;
+		margin: 30% auto;
+		border-radius: 20rpx;
+	}
+	.jie_card_title {
+		width: 100%;
+		height: 84rpx;
+		line-height: 84rpx;
+	}
 
-	
-	.teacher_box{
-		height: 90vh;
-		overflow-y:auto
-		
+	.jie_swiper {
+		// min-height: 1000rpx;
+		background-color: rgb(244, 245, 249);
+	}
+
+	.jie_card_title_text {
+		margin-left: 15rpx;
+		line-height: center;
+		// color: #606266;
+		font-size: 28rpx;
 	}
+
+	.jie_tags {
+		float: right;
+		background-color: #E1F3D8;
+		width: 104rpx;
+		height: 42rpx;
+		margin-top: 22rpx;
+		border-radius: 23rpx 0 0 23rpx;
+		font-size: 25rpx;
+		padding-left: 10rpx;
+		line-height: 40rpx;
+		color: #529B2E;
+	}
+
+	.jie_tags2 {
+		color: #B88230;
+		background-color: #FAECD8;
+	}
+
+	.jie_contend {
+		margin-left: 15rpx;
+		margin-top: 15rpx;
+		float: left;
+		font-size: 31rpx;
+		line-height: 42rpx;
+	}
+
+
+	.jie_contend_text {
+		margin-bottom: 10rpx;
+	}
+
+	.jie_contend_text1 {
+		color: #606266;
+	}
+
+	.jie_contend_text2 {
+		color: #000;
+	}
+
 	.jie_card_ztai {
-		width: 120rpx;
-		height: 120rpx;
+		width: 134rpx;
+		height: 134rpx;
 		background-color: #F89898;
 		border-radius: 50%;
-		line-height: 120rpx;
+		line-height: 134rpx;
 		float: right;
 		color: #fff;
-		font-size: 25rpx;
+		font-size: 32rpx;
 		text-align: center;
-		margin-top: 30rpx;
+		margin-top: 25rpx;
 		margin-right: 40rpx;
 	}
-	.yijiey button{
-		height: 44px !important;
-	}
-	.jie_card_ztai2{
+
+	.jie_card_ztai2 {
 		background-color: #A0CFFF;
 	}
-	.jie_card {
-			width: 94%;
-			margin: 30rpx auto;
-			height: 270rpx;
-			border-radius: 20rpx;
-			background-color: #fff;
-			// padding: 10rpx 0;
-		}
-		.tihuan_box {
-			width: 84%;
-			height: 500rpx;
-			padding: 30rpx;
-			background-color: #fff;
-			margin: 30% auto;
-			border-radius: 20rpx;
-		}
-		.jie_card_title {
-	width: 100%;
-	    height: 84rpx;
-	    line-height: 84rpx;
-		}
-	
-		.jie_swiper {
-			// min-height: 1000rpx;
-			background-color: rgb(244, 245, 249);
-		}
-	
-		.jie_card_title_text {
-			margin-left: 15rpx;
-			line-height: center;
-			// color: #606266;
-			font-size: 28rpx;
-		}
-	
-	.jie_tags {
-	    float: right;
-	    background-color: #E1F3D8;
-	    width: 104rpx;
-	    height: 42rpx;
-	    margin-top: 22rpx;
-	    border-radius: 23rpx 0 0 23rpx;
-	    font-size: 25rpx;
-	    padding-left: 10rpx;
-	    line-height: 40rpx;
-	    color: #529B2E;
-	}
-	
-		.jie_tags2 {
-			color: #B88230;
-			background-color: #FAECD8;
-		}
-	
-		.jie_contend {
-			margin-left: 15rpx;
-			margin-top: 15rpx;
-			float: left;
-			font-size: 31rpx;
-			line-height: 42rpx;
-		}
-		.jie_contend_text {
-			margin-bottom: 10rpx;
-		}
-	
-		.jie_contend_text1 {
-			color: #606266;
-		}
-	
-		.jie_contend_text2 {
-			color: #000;
-		}
-	
-	.jie_card_ztai {
-	    width: 134rpx;
-	    height: 134rpx;
-	    background-color: #F89898;
-	    border-radius: 50%;
-	    line-height: 134rpx;
-	    float: right;
-	    color: #fff;
-	    font-size: 32rpx;
-	    text-align: center;
-	    margin-top: 25rpx;
-	    margin-right: 40rpx;
-	}
-	
-		.jie_card_ztai2 {
-			background-color: #A0CFFF;
-		}
-</style>
+</style>

+ 124 - 3
uniapp/pages/teacher/navigation.vue

@@ -9,11 +9,132 @@
 
 <script setup>
 	import {ref} from 'vue'
-	import Index from '@/pages/teacher/index.vue'
+	import Index from '@/pages/index/index.vue'
 	import User from '@/pages/user/index.vue'
 	const value=ref(0)
 </script>
+<style lang="less">
+	page {
+		background-color: #fff;
+		overflow: hidden;
+	}
+	.zp-swiper-super.data-v-bd8ff6a5 {
+		background-color: rgb(244, 245, 249);
+	}
+	.search {
+		margin: 20rpx 20rpx 0 20rpx;
+	}
+	.zp-swiper-container-fixed.data-v-bd8ff6a5 {
+		// top: 100rpx !important;
+	}
 
-<style>
+	swiper {
+		min-height: 95vh;
+		// overflow-y:auto;
+	}
+	.yiqijie{
+		width: 280rpx;
+		height: 90rpx;
+		background-color: #2d8cf0;
+		position: absolute;
+		bottom: 250rpx !important;
+		right: 50%;
+		transform: translate(50%, 50%);
+		border-radius: 50rpx;
+		line-height: 90rpx;
+		text-align: center;
+		color: #fff;
+		font-size: 35rpx;
+		z-index: 99999;
+	}
+	.jie_card {
+		width: 94%;
+		margin: 30rpx auto;
+		height: 270rpx;
+		border-radius: 20rpx;
+		background-color: #fff;
+		// padding: 10rpx 0;
+	}
+	.tihuan_box {
+		width: 84%;
+		height: 500rpx;
+		padding: 30rpx;
+		background-color: #fff;
+		margin: 30% auto;
+		border-radius: 20rpx;
+	}
+	.jie_card_title {
+		width: 100%;
+		height: 84rpx;
+		line-height: 84rpx;
+	}
 
-</style>
+	.jie_swiper {
+		// min-height: 1000rpx;
+		background-color: rgb(244, 245, 249);
+	}
+
+	.jie_card_title_text {
+		margin-left: 15rpx;
+		line-height: center;
+		// color: #606266;
+		font-size: 28rpx;
+	}
+
+	.jie_tags {
+		float: right;
+		background-color: #E1F3D8;
+		width: 104rpx;
+		height: 42rpx;
+		margin-top: 22rpx;
+		border-radius: 23rpx 0 0 23rpx;
+		font-size: 25rpx;
+		padding-left: 10rpx;
+		line-height: 40rpx;
+		color: #529B2E;
+	}
+
+	.jie_tags2 {
+		color: #B88230;
+		background-color: #FAECD8;
+	}
+
+	.jie_contend {
+		margin-left: 15rpx;
+		margin-top: 15rpx;
+		float: left;
+		font-size: 31rpx;
+		line-height: 42rpx;
+	}
+
+
+	.jie_contend_text {
+		margin-bottom: 10rpx;
+	}
+
+	.jie_contend_text1 {
+		color: #606266;
+	}
+
+	.jie_contend_text2 {
+		color: #000;
+	}
+
+	.jie_card_ztai {
+		width: 134rpx;
+		height: 134rpx;
+		background-color: #F89898;
+		border-radius: 50%;
+		line-height: 134rpx;
+		float: right;
+		color: #fff;
+		font-size: 32rpx;
+		text-align: center;
+		margin-top: 25rpx;
+		margin-right: 40rpx;
+	}
+
+	.jie_card_ztai2 {
+		background-color: #A0CFFF;
+	}
+</style>

+ 3 - 1
uniapp/uni_modules/q-sign/pages/q-sign.vue

@@ -120,7 +120,9 @@
 				this.ctx.draw();
 				//设置canvas背景
 				this.setCanvasBg('#fff');
-				
+				this.ctx2.clearRect(0, 0, 700, 730);
+				this.ctx2.draw();
+				this.setCanvasP()
  			},
 
 	

+ 723 - 0
uniapp/uni_modules/z-paging/global.d.ts

@@ -0,0 +1,723 @@
+type _Arrayable<T> = T | T[];
+
+declare global {
+    /**
+     * z-paging返回数据
+     *
+     * @since 2.5.3
+     */
+    interface ZPagingReturnData<T> {
+        /**
+         * 总列表
+         */
+        totalList: T[];
+        /**
+         * 是否没有更多数据
+         */
+        noMore: boolean;
+    }
+
+    /**
+     * 嵌套父容器信息 [list组件](https://uniapp.dcloud.net.cn/component/list.html)
+     *
+     * @since 2.0.4
+     */
+    interface ZPagingSetSpecialEffectsArgs {
+        /**
+         * 和list同时滚动的组件id,应为外层的scroller
+         */
+        id?: string;
+        /**
+         * 要吸顶的header顶部距离scroller顶部的距离
+         * - Android暂不支持
+         *
+         * @default 0
+         */
+        headerHeight?: number;
+    }
+
+    /**
+     * z-paging组件实例
+     */
+    interface ZPagingInstance<T = any> {
+        /**
+         * 重新加载分页数据,pageNo恢复为默认值,相当于下拉刷新的效果
+         *
+         * @param [animate=false] 是否展示下拉刷新动画
+         */
+        reload: (animate?: boolean) => Promise<ZPagingReturnData<T>>;
+
+        /**
+         * 刷新列表数据,pageNo和pageSize不会重置,列表数据会重新从服务端获取
+         *
+         * @since 2.0.4
+         */
+        refresh: () => Promise<ZPagingReturnData<T>>;
+
+        /**
+         * 刷新列表数据至指定页
+         *
+         * @since 2.5.9
+         * @param page 目标页数
+         */
+        refreshToPage: (page: number) => Promise<ZPagingReturnData<T>>;
+
+        /**
+         * 请求结束
+         * - 当通过complete传进去的数组长度小于pageSize时,则判定为没有更多了
+         *
+         * @param [data] 请求结果数组
+         * @param [success=true] 是否请求成功
+         */
+        complete: (data?: T[] | false, success?: boolean) => Promise<ZPagingReturnData<T>>;
+
+        /**
+         * 请求结束
+         * - 通过total判断是否有更多数据
+         *
+         * @since 2.0.6
+         * @param data 请求结果数组
+         * @param total 列表总长度
+         * @param [success=true] 是否请求成功
+         */
+        completeByTotal: (data: T[], total: number, success?: boolean) => Promise<ZPagingReturnData<T>>;
+
+        /**
+         * 请求结束
+         * - 自行判断是否有更多数据
+         *
+         * @since 1.9.2
+         * @param data 请求结果数组
+         * @param noMore 是否没有更多数据
+         * @param [success=true] 是否请求成功
+         */
+        completeByNoMore: (data: T[], noMore: boolean, success?: boolean) => Promise<ZPagingReturnData<T>>;
+
+        /**
+         * 请求失败
+         * - 通过方法传入请求失败原因,将请求失败原因传递给z-paging展示
+         *
+         * @since 2.6.3
+         * @param cause 请求失败原因
+         */
+        completeByError: (cause: string) => Promise<ZPagingReturnData<T>>;
+
+        /**
+         * 请求结束
+         * - 保证数据一致
+         *
+         * @since 1.6.4
+         * @param data 请求结果数组
+         * @param key dataKey,需与:data-key绑定的一致
+         * @param [success=true] 是否请求成功
+         */
+        completeByKey: (data: T[], key: string, success?: boolean) => Promise<ZPagingReturnData<T>>;
+
+        /**
+         * 清空分页数据,pageNo恢复为默认值
+         *
+         * @since 2.1.0
+         */
+        clear: () => void;
+
+        /**
+         * 从顶部添加数据,不会影响分页的pageNo和pageSize
+         *
+         * @param data 需要添加的数据,可以是一条数据或一组数据
+         * @param [scrollToTop=true] 是否滚动到顶部,不填默认为true
+         * @param [animate=true] 是否使用动画滚动到顶部
+         */
+        addDataFromTop: (data: _Arrayable<T>, scrollToTop?: boolean, animate?: boolean) => void;
+
+        /**
+         * 【不推荐】重新设置列表数据,调用此方法不会影响pageNo和pageSize,也不会触发请求
+         * - 适用场景:当需要删除列表中某一项时,将删除对应项后的数组通过此方法传递给z-paging
+         *
+         * @param data 修改后的列表数组
+         */
+        resetTotalData: (data: T[]) => void;
+
+        /**
+         * 终止下拉刷新状态
+         *
+         * @since 2.1.0
+         */
+        endRefresh: () => void;
+
+        /**
+         * 手动更新自定义下拉刷新view高度
+         * - 常用于某些情况下使用slot="refresher"插入的view高度未能正确计算导致异常时手动更新其高度
+         *
+         * @since 2.6.1
+         */
+        updateCustomRefresherHeight: () => void;
+
+        /**
+         * 手动关闭二楼
+         *
+         * @since 2.7.7
+         */
+        closeF2: () => void;
+
+        /**
+         * 手动触发上拉加载更多
+         * - 非必须,可依据具体需求使用,例如当z-paging未确定高度时,内部的scroll-view会无限增高,此时z-paging无法得知是否滚动到底部,您可以在页面的onReachBottom中手动调用此方法触发上拉加载更多
+         *
+         * @param [source] 触发加载更多的来源类型
+         */
+        doLoadMore: (source?: "click" | "toBottom") => void;
+
+        /**
+         * 当使用页面滚动并且自定义下拉刷新时,请在页面的onPageScroll中调用此方法,告知z-paging当前的pageScrollTop,否则会导致在任意位置都可以下拉刷新
+         * - 若引入了mixins,则不需要调用此方法
+         *
+         * @param scrollTop 从page的onPageScroll中获取的scrollTop
+         */
+        updatePageScrollTop: (scrollTop: number) => void;
+
+        /**
+         * 在使用页面滚动并且设置了slot="top"时,默认初次加载会自动获取其高度,并使内部容器下移,当slot="top"的view高度动态改变时,在其高度需要更新时调用此方法
+         */
+        updatePageScrollTopHeight: () => void;
+
+        /**
+         * 在使用页面滚动并且设置了slot="bottom"时,默认初次加载会自动获取其高度,并使内部容器下移,当slot="bottom"的view高度动态改变时,在其高度需要更新时调用此方法
+         */
+        updatePageScrollBottomHeight: () => void;
+
+        /**
+         * 更新slot="left"和slot="right"宽度,当slot="left"或slot="right"宽度动态改变后调用
+         *
+         * @since 2.3.5
+         */
+        updateLeftAndRightWidth: () => void;
+
+        /**
+         * 更新fixed模式下z-paging的布局,在onShow时候调用,以修复在iOS+h5+tabbar+fixed+底部有安全区域的设备中从tabbar页面跳转到无tabbar页面后返回,底部有一段空白区域的问题
+         *
+         * @since 2.6.5
+         */
+        updateFixedLayout: () => void;
+
+        /**
+         * 在使用动态高度虚拟列表时,若在列表数组中需要插入某个item,需要调用此方法
+         *
+         * @since 2.5.9
+         * @param item 插入的数据项
+         * @param index 插入的cell位置,若为2,则插入的item在原list的index=1之后,从0开始
+         */
+        doInsertVirtualListItem: (item: T, index: number) => void;
+
+        /**
+         * 在使用动态高度虚拟列表时,手动更新指定cell的缓存高度
+         * - 当cell高度在初始化之后再次改变时调用
+         *
+         * @since 2.4.0
+         * @param index 需要更新的cell在列表中的位置,从0开始
+         */
+        didUpdateVirtualListCell: (index: number) => void;
+
+        /**
+         * 在使用动态高度虚拟列表时,若删除了列表数组中的某个item,需要调用此方法以更新高度缓存数组
+         *
+         * @since 2.4.0
+         * @param index 需要更新的cell在列表中的位置,从0开始
+         */
+        didDeleteVirtualListCell: (index: number) => void;
+
+        /**
+         * 手动触发虚拟列表渲染更新,可用于解决例如修改了虚拟列表数组中元素,但展示未更新的情况
+         *
+         * @since 2.7.10
+         */
+        updateVirtualListRender: () => void;
+		
+        /**
+         * 设置本地分页,请求结束(成功或者失败)调用此方法,将请求的结果传递给z-paging作分页处理
+         * - 若调用了此方法,则上拉加载更多时内部会自动分页,不会触发@query所绑定的事件
+         *
+         * @param data 请求结果数组
+         * @param [success=true] 是否请求成功
+         */
+        setLocalPaging: (data: T[], success?: boolean) => Promise<ZPagingReturnData<T>>;
+
+        /**
+         * 手动触发滚动到顶部加载更多,聊天记录模式时有效
+         */
+        doChatRecordLoadMore: () => void;
+
+        /**
+         * 添加聊天记录,use-chat-record-mode为true时有效
+         *
+         * @param data 需要添加的聊天数据,可以是一条数据或一组数据
+         * @param [scrollToBottom=true] 是否滚动到底部
+         * @param [animate=true] 是否使用动画滚动到底部
+         */
+        addChatRecordData: (data: _Arrayable<T>, scrollToBottom?: boolean, animate?: boolean) => void;
+
+        /**
+         * 滚动到顶部
+         *
+         * @param [animate=true] 是否有动画效果
+         */
+        scrollToTop: (animate?: boolean) => void;
+
+        /**
+         * 滚动到底部
+         *
+         * @param [animate=true] 是否有动画效果
+         */
+        scrollToBottom: (animate?: boolean) => void;
+
+        /**
+         * 滚动到指定view
+         * - vue中有效,若此方法无效,请使用scrollIntoViewByNodeTop
+         *
+         * @param id 需要滚动到的view的id值,不包含"#"
+         * @param [offset=0] 偏移量,单位为px
+         * @param [animate=false] 是否有动画效果
+         */
+        scrollIntoViewById: (id: string, offset?: number, animate?: boolean) => void;
+
+        /**
+         * 滚动到指定view
+         * - vue中有效
+         *
+         * @since 1.7.4
+         * @param top 需要滚动的view的top值(通过uni.createSelectorQuery()获取)
+         * @param [offset=0] 偏移量,单位为px
+         * @param [animate=false] 是否有动画效果
+         */
+        scrollIntoViewByNodeTop: (top: number, offset?: number, animate?: boolean) => void;
+
+        /**
+         * 滚动到指定view
+         * - vue中有效
+         * - 与scrollIntoViewByNodeTop的不同之处在于,scrollToY传入的是view相对于屏幕的top值,而scrollIntoViewByNodeTop传入的top值并非是固定的,通过uni.createSelectorQuery()获取到的top会因列表滚动而改变
+         *
+         * @param top 需要滚动到的view的top值,单位为px
+         * @param [offset=0] 偏移量,单位为px
+         * @param [animate=false] 是否有动画效果
+         */
+        scrollToY: (top: number, offset?: number, animate?: boolean) => void;
+
+        /**
+         * 滚动到指定view
+         * - nvue或虚拟列表中有效
+         * - 在nvue中的cell必须设置 :ref="`z-paging-${index}`"
+         *
+         * @param index 需要滚动到的view的index(第几个)
+         * @param [offset=0] 偏移量,单位为px
+         * @param [animate=false] 是否有动画效果
+         */
+        scrollIntoViewByIndex: (index: number, offset?: number, animate?: boolean) => void;
+
+        /**
+         * 滚动到指定view
+         * - nvue中有效
+         *
+         * @param view 需要滚动到的view(通过this.$refs.xxx获取)
+         * @param [offset=0] 偏移量,单位为px
+         * @param [animate=false] 是否有动画效果
+         */
+        scrollIntoViewByView: (view: any, offset?: number, animate?: boolean) => void;
+
+        /**
+         * 设置nvue List的specialEffects
+         *
+         * @since 2.0.4
+         * @param args 参见https://uniapp.dcloud.io/component/list?id=listsetspecialeffects
+         */
+        setSpecialEffects: (args: ZPagingSetSpecialEffectsArgs) => void;
+
+        /**
+         * 与{@link setSpecialEffects}相同
+         *
+         * @since 2.0.4
+         */
+        setListSpecialEffects: (args: ZPagingSetSpecialEffectsArgs) => void;
+
+        /**
+         * 手动更新列表缓存数据,将自动截取v-model绑定的list中的前pageSize条覆盖缓存,请确保在list数据更新到预期结果后再调用此方法
+         *
+         * @since 2.3.9
+         */
+        updateCache: () => void;
+
+        /**
+         * 获取当前版本号
+         */
+        getVersion: () => string;
+    }
+
+    /**
+     * z-paging全局数据
+     * - uni.$zp
+     *
+     * @since 2.6.5
+     */
+    interface ZPagingGlobal {
+        /**
+         * 配置
+         */
+        config: Record<string, any>;
+    }
+
+    /**
+     * 虚拟列表数据项
+     *
+     * @since 2.7.7
+     */
+    type ZPagingVirtualItem<T> = T & {
+        /**
+         * 元素真实索引
+         */
+        zp_index: number;
+    };
+    
+    namespace ZPagingEvent {
+        /**
+         * query的触发来源:0.用户主动下拉刷新 1.通过reload触发 2.通过refresh触发 3.通过滚动到底部加载更多或点击底部加载更多触发
+         */
+        type _QueryFrom = 0 | 1 | 2 | 3;
+        /**
+         * 下拉刷新或滚动到底部时会自动触发此方法
+         * 
+         * @param pageNo 当前第几页
+         * @param pageSize 每页多少条
+         * @param from query的触发来源:0.用户主动下拉刷新 1.通过reload触发 2.通过refresh触发 3.通过滚动到底部加载更多或点击底部加载更多触发
+         */
+        interface Query {
+            (pageNo: number, pageSize: number, from: _QueryFrom): void;
+        }
+
+        /**
+         * 分页渲染的数组改变时触发
+         * 
+         * @param list 最终的分页数据数组
+         */
+        interface ListChange {
+            (list: []): void;
+        }
+
+        /**
+         * 下拉刷新状态:0-默认状态 1.松手立即刷新 2.刷新中 3.刷新成功(默认情况下看不到此状态,如果需要展示刷新成功状态,请设置刷新结束以后延时收回的时间,如:refresher-complete-delay="200")
+         */
+        type _RefresherStatus = 0 | 1 | 2 | 3;
+        /**
+         * 自定义下拉刷新状态改变
+         * - use-custom-refresher为false时无效
+         * 
+         * @param status 下拉刷新状态:0-默认状态 1.松手立即刷新 2.刷新中 3.刷新成功(默认情况下看不到此状态,如果需要展示刷新成功状态,请设置刷新结束以后延时收回的时间,如:refresher-complete-delay="200")
+         */
+        interface RefresherStatusChange {
+            (status: _RefresherStatus): void;
+        }
+
+        /**
+         * 自定义下拉刷新下拉开始
+         * - use-custom-refresher为false时无效,nvue无效
+         * 
+         * @param y 当前触摸开始的屏幕点的y值(单位px)
+         */
+        interface RefresherTouchstart {
+            (y: number): void;
+        }
+
+        /**
+         * touchmove信息
+         */
+        interface _RefresherTouchmoveInfo {
+            /** 下拉的距离 */
+            pullingDistance: number;
+            /** 前后两次回调滑动距离的差值 */
+            dy: number;
+            /** refresh组件高度 */
+            viewHeight: number;
+            /** pullingDistance/viewHeight的比值 */
+            rate: number;
+        }
+        /**
+         * 自定义下拉刷新下拉拖动中
+         * - use-custom-refresher为false时无效
+         * - 在使用wxs的平台上,为减少wxs与js通信折损,只有在z-paging添加@refresherTouchmove时,wxs才会实时将下拉拖动事件传给js,在微信小程序和QQ小程序中,因$listeners无效,所以必须设置:watch-refresher-touchmove="true"方可使此事件被触发
+         * 
+         * @param info touchmove信息
+         */
+        interface RefresherTouchmove {
+            (info: _RefresherTouchmoveInfo): void;
+        }
+
+        /**
+         * 自定义下拉刷新下拉结束
+         * - use-custom-refresher为false时无效,nvue无效
+         * 
+         * @param y 当前触摸开始的屏幕点的y值(单位px)
+         */
+        interface RefresherTouchend {
+            (y: number): void;
+        }
+
+        /**
+         * 下拉进入二楼状态:go-二楼开启 close-二楼关闭
+         */
+        type _RefresherF2ChangeStatus = 'go' | 'close';
+        /**
+         * 下拉进入二楼状态改变
+         * 
+         * @since 2.7.7
+         * @param status 下拉进入二楼状态:go-二楼开启 close-二楼关闭
+         */
+        interface RefresherF2Change {
+            (status: _RefresherF2ChangeStatus): void;
+        }
+
+        /**
+         * 自定义下拉刷新被触发
+         */
+        interface OnRefresh {
+            (): void;
+        }
+
+        /**
+         * 自定义下拉刷新被复位
+         */
+        interface OnRestore {
+            (): void;
+        }
+
+        /**
+         * 底部加载更多状态:0-默认状态 1.加载中 2.没有更多数据 3.加载失败
+         */
+        type _LoadingStatus = 0 | 1 | 2 | 3;
+        /**
+         * 下拉进入二楼状态改变
+         * 
+         * @param status 底部加载更多状态:0-默认状态 1.加载中 2.没有更多数据 3.加载失败
+         */
+        interface LoadingStatusChange {
+            (status: _LoadingStatus): void;
+        }
+
+        /**
+         * 点击空数据图中重新加载后是否进行reload操作,默认为是。如果需要禁止reload事件,则调用handler(false)
+         */
+        type _EmptyViewReloadHandler = (value: boolean) => void;
+        /**
+         * 点击了空数据图中的重新加载按钮
+         * 
+         * @since 1.8.0
+         * @param handler 点击空数据图中重新加载后是否进行reload操作,默认为是。如果需要禁止reload事件,则调用handler(false)
+         */
+        interface EmptyViewReload {
+            (handler: _EmptyViewReloadHandler): void;
+        }
+
+        /**
+         * 点击了空数据图view
+         * 
+         * @since 2.3.3
+         */
+        interface EmptyViewClick {
+            (): void;
+        }
+
+        /**
+         * 请求失败状态改变
+         * 
+         * @since 2.5.0
+         * @param isLoadFailed 当前是否是请求失败状态,为true代表是,反之为否;默认状态为否
+         */
+        interface IsLoadFailedChange {
+            (isLoadFailed: boolean): void;
+        }
+
+        /**
+         * 点击返回顶部按钮后是否滚动到顶部,默认为是。如果需要禁止滚动到顶部事件,则调用handler(false)
+         */
+        type _BackToTopClickHandler = (value: boolean) => void;
+        /**
+         * 点击了返回顶部按钮
+         * 
+         * @since 2.6.1
+         * @param handler 点击返回顶部按钮后是否滚动到顶部,默认为是。如果需要禁止滚动到顶部事件,则调用handler(false)
+         */
+        interface BackToTopClick {
+            (handler: _BackToTopClickHandler): void;
+        }
+
+        /**
+         * 虚拟列表当前渲染的数组改变时触发,在虚拟列表中只会渲染可见区域内+预加载页面的数据
+         * -nvue无效
+         * 
+         * @since 2.2.7
+         * @param list 虚拟列表当前渲染的数组
+         */
+        interface VirtualListChange {
+            (list: []): void;
+        }
+
+        /**
+         * 使用虚拟列表或内置列表时点击了cell的信息
+         */
+        interface _InnerCellClickInfo<T> {
+            /** 当前点击的item */
+            item: T;
+            /** 当前点击的index */
+            index: number;
+        }
+        /**
+         * 使用虚拟列表或内置列表时点击了cell
+         * -nvue无效
+         * 
+         * @since 2.4.0
+         * @param info 点击cell的信息
+         */
+        interface InnerCellClick {
+            (info: _InnerCellClickInfo<any>): void;
+        }
+
+        /**
+         * 在聊天记录模式下,触摸列表隐藏了键盘
+         * 
+         * @since 2.3.6
+         */
+        interface HidedKeyboard {
+            (): void;
+        }
+
+        /**
+         * 键盘的高度信息
+         */
+        interface _KeyboardHeightInfo {
+            /** 键盘的高度 */
+            height: number;
+        }
+        /**
+         * 键盘高度改变
+         * -聊天记录模式启用时才有效,如果在聊天记录模式页面需要监听键盘高度改变,请不要直接通过uni.onKeyboardHeightChange监听,否则可能导致z-paging内置的键盘高度改变监听失效。ps:H5、百度小程序、抖音小程序、飞书小程序不支持
+         * 
+         * @since 2.7.1
+         * @param info 键盘高度信息
+         */
+        interface KeyboardHeightChange {
+            (info: _KeyboardHeightInfo): void;
+        }
+
+        /**
+         * 列表滚动信息(vue)
+         */
+        interface _ScrollInfo {
+            detail: {
+                scrollLeft: number;
+                scrollTop: number;
+                scrollHeight: number;
+                scrollWidth: number;
+                deltaX: number;
+                deltaY: number;
+            }
+        }
+        /**
+         * 列表滚动信息(nvue)
+         */
+        interface _ScrollInfoN {
+            contentSize: {
+                width: number;
+                height: number;
+            };
+            contentOffset: {
+                x: number;
+                y: number;
+            };
+            isDragging: boolean;
+        }
+        /**
+         * 列表滚动时触发
+         * 
+         * @param event 滚动事件信息,vue使用_ScrollInfo,nvue使用_ScrollInfoN
+         */
+        interface Scroll {
+            (event: _ScrollInfo | _ScrollInfoN): void;
+        }
+
+        /**
+         * scrollTop改变时触发,使用点击返回顶部时需要获取scrollTop时可使用此事件
+         * 
+         * @param scrollTop
+         */
+        interface ScrollTopChange {
+            (scrollTop: number): void;
+        }
+
+        /**
+         * 内置的scroll-view滚动底部时的来源(toBottom滚动到底部;click点击了加载更多view)
+         */
+        type _ScrolltolowerFrom = 'toBottom' | 'click';
+        /**
+         * 内置的scroll-view滚动底部时触发
+         * 
+         * @param from 来源(toBottom滚动到底部;click点击了加载更多view)
+         */
+        interface Scrolltolower {
+            (from: _ScrolltolowerFrom): void;
+        }
+
+        /**
+         * 内置的scroll-view滚动顶部时触发
+         */
+        interface Scrolltoupper {
+            (): void;
+        }
+
+        /**
+         * 滚动结束时触发事件信息
+         */
+        interface _ScrollendEvent {
+            contentSize: {
+                width: number;
+                height: number;
+            };
+            contentOffset: {
+                x: number;
+                y: number;
+            };
+            isDragging: boolean;
+        }
+        /**
+         * 内置的list滚动结束时触发
+         * -仅nvue有效
+         * 
+         * @since 2.7.3
+         * @param event 滚动结束时触发事件信息
+         */
+        interface Scrollend {
+            (event: _ScrollendEvent): void;
+        }
+
+        /**
+         * z-paging中内容高度改变时触发
+         * 
+         * @since 2.1.3
+         * @param height 改变后的高度
+         */
+        interface ContentHeightChanged {
+            (height: number): void;
+        }
+
+        /**
+         * 列表触摸的方向,top代表用户将列表向上移动(scrollTop不断减小),bottom代表用户将列表向下移动(scrollTop不断增大)
+         */
+        type _TouchDirection = 'top' | 'bottom';
+        /**
+         * 监听列表触摸方向改变
+         * 
+         * @since 2.3.0
+         * @param direction 列表触摸的方向,top代表用户将列表向上移动(scrollTop不断减小),bottom代表用户将列表向下移动(scrollTop不断增大)
+         */
+        interface TouchDirectionChange {
+            (direction: _TouchDirection): void;
+        }
+    }
+}
+
+export {};

+ 3 - 0
web/src/views/backend/borrow/borrowApply/index.vue

@@ -42,6 +42,9 @@
                         <div v-else-if="scope.row.status == '7'">
                             <el-tag type="info">学院驳回</el-tag>
                         </div>
+                        <div v-else-if="scope.row.status == '8'">
+                            <el-tag type="info">驳回修改配件</el-tag>
+                        </div>
                         <div v-else>
                             <el-tag type="danger">未知状态</el-tag>
                         </div>

+ 27 - 4
web/src/views/backend/borrow/borrowApply/popupForm.vue

@@ -44,6 +44,7 @@
                         :input-attr="{
                             readonly : true
                         }"
+
                     />
                     <FormItem
                         :label="t('borrow.borrowapply.username')"
@@ -51,6 +52,9 @@
                         type="string"
                         prop="username"
                         :placeholder="t('borrow.borrowapply.username')"
+                        :input-attr="{
+                             readonly: baTable.form.items!.status == 8
+                        }"
                     />
                     <FormItem
                         :label="t('borrow.borrowapply.mobile')"
@@ -58,6 +62,9 @@
                         type="string"
                         prop="mobile"
                         :placeholder="t('borrow.borrowapply.mobile')"
+                        :input-attr="{
+                             readonly: baTable.form.items!.status == 8
+                        }"
                     />
                     <FormItem
                         :label="t('borrow.borrowapply.purpose')"
@@ -68,6 +75,9 @@
                             content: { '0': t('borrow.borrowapply.purpose 0'), '1': t('borrow.borrowapply.purpose 1') },
                             childrenAttr: { border: true },
                         }"
+                        :input-attr="{
+                             readonly: baTable.form.items!.status == 8
+                        }"
                     />
                     <FormItem
                         :label="t('borrow.borrowapply.project number')"
@@ -76,6 +86,9 @@
                         prop="project_number"
                         :placeholder="t('borrow.borrowapply.project number')"
                         v-if="baTable.form.items!.purpose == 0"
+                        :input-attr="{
+                             readonly: baTable.form.items!.status == 8
+                        }"
                     />
                     <FormItem
                         :label="t('borrow.borrowapply.borrow time')"
@@ -87,6 +100,7 @@
                         value-format="YYYY-MM-DD HH:mm:ss"
                         :input-attr="{
                             disabledDate: expireTimeOption,
+                            readonly: baTable.form.items!.status == 8
                         }"
                     />
                     <FormItem
@@ -99,12 +113,12 @@
                         value-format="YYYY-MM-DD HH:mm:ss"
                         :input-attr="{
                             disabledDate: expireTimeOption,
+                            readonly: baTable.form.items!.status == 8
                         }"
                     />
 
-
                     <asset-selection-record
-                        v-if="[2, 3, 4, 5].includes(baTable.form.items!.status)"></asset-selection-record>
+                        v-if="[2, 3, 4, 5 , 8].includes(baTable.form.items!.status)"></asset-selection-record>
                     <assetSelection v-else></assetSelection>
 
                     <FormItem
@@ -112,14 +126,20 @@
                         prop="borrow_reason"
                         type="textarea"
                         v-model="baTable.form.items!.borrow_reason"
-                        :input-attr="{ maxlength: 200, clearable: true, 'show-password': true }"
+                        :input-attr="{ maxlength: 200, clearable: true, 'show-password': true ,
+                            readonly: baTable.form.items!.status == 8}"
                     />
                     <FormItem
                         :label="t('borrow.borrowapply.reamrk')"
                         prop="remarks"
                         type="textarea"
                         v-model="baTable.form.items!.remarks"
-                        :input-attr="{ maxlength: 200, clearable: true, 'show-password': true }"
+                        :input-attr="{ maxlength: 200,
+                            clearable: true,
+                            'show-password': true ,
+                            readonly: baTable.form.items!.status == 8
+                        }"
+
                     />
 
                     <FormItem
@@ -129,6 +149,9 @@
                         prop="approval_person"
                         :placeholder="t('borrow.borrowapply.approval person')"
                         v-if="baTable.form.items!.status !== 0 && baTable.form.operate !== 'Add'"
+                        :input-attr="{
+                            readonly: baTable.form.items!.status == 8
+                        }"
                     />
 
                     <FormItem

+ 4 - 4
web/src/views/backend/borrow/common/assetSelection.vue

@@ -18,7 +18,7 @@
                             v-model="item!.model"
                             :fetch-suggestions="querySearchAsync"
                             placeholder="请输入仪器类型"
-                            :readonly="[0,6].includes(baTable.form.items!.status)"
+                            :readonly="[0,6,8].includes(baTable.form.items!.status)"
                             @select="
                                         (item: Record<string, any>) => {
                                             handleSelect(item, idx)
@@ -28,11 +28,11 @@
                     </el-col>
                     <el-col :span="4">
                         <el-input v-model="item.num" class="el-input"
-                                  placeholder="请填写数量" :readonly="[0,6].includes(baTable.form.items!.status)"></el-input>
+                                  placeholder="请填写数量" :readonly="[0,6,8].includes(baTable.form.items!.status)"></el-input>
                     </el-col>
-                    <el-col :span="3" v-if="![0,6].includes(baTable.form.items!.status)">
+                    <el-col :span="3" v-if="![0,6,8].includes(baTable.form.items!.status)">
                         <el-button @click="onDelArrayItem(idx)" size="small" icon="el-icon-Delete"
-                                   circle/>
+                                   circle />
                     </el-col>
                 </el-row>
                 <el-row :gutter="10" v-if="![0,6].includes(baTable.form.items!.status)">