Bladeren bron

接维修工

lmc 2 jaren geleden
bovenliggende
commit
a1b101a49f
11 gewijzigde bestanden met toevoegingen van 658 en 422 verwijderingen
  1. 71 1
      src/App.vue
  2. 1 1
      src/router/index.js
  3. 3 0
      src/store/index.js
  4. 20 1
      src/utils/api.js
  5. 2 6
      src/utils/request.js
  6. 263 189
      src/views/home.vue
  7. 1 32
      src/views/login.vue
  8. 4 2
      src/views/rentBill.vue
  9. 161 135
      src/views/repairList.vue
  10. 121 50
      src/views/repairOnline.vue
  11. 11 5
      src/views/userInfo.vue

+ 71 - 1
src/App.vue

@@ -3,7 +3,72 @@
   <!-- 开启底部安全区适配 -->
   <van-number-keyboard safe-area-inset-bottom />
 </template>
+<script>
+import Api from "./utils/api";
+export default {
+  data() {
+    return {};
+  },
+  created() {
+    if (localStorage.getItem("token")) {
+      this.getUserInfo();
+    } else {
+      let username = this.getUrlKey("username");
+      let pwd = this.getUrlKey("pwd");
+      this.login(username, pwd);
+    }
+  },
+  methods: {
+    getUrlKey(name) {
+      return (
+        decodeURIComponent(
+          (new RegExp("[?|&]" + name + "=" + "([^&;]+?)(&|#|;|$)").exec(
+            location.href
+          ) || [, ""])[1].replace(/\+/g, "%20")
+        ) || null
+      );
+    },
+    login(username, pwd) {
+      this.loading = true;
+      Api.loginByPwd({
+        username: username,
+        password: pwd,
+      }).then((res) => {
+        this.loading = false;
+        if (res.code == 0) {
+          this.$toast.clear();
+          window.localStorage.setItem("token", res.data.token);
+          this.$store.state.password = this.pwd;
+          this.getUserInfo();
+        } else {
+          this.$notify({ type: "danger", message: res.msg });
+        }
+      });
+    },
+    getUserInfo() {
+      Api.getUserInfo().then((res) => {
+        if (res.code == 0) {
+          this.$store.state.username = res.data.username;
+          this.$store.state.userMobile = res.data.mobile;
+          if (res.data.roleCodes.length == 0) {
+            // 1:admin、check:巡检人员、repair:维修工、rent:租户
+            localStorage.setItem("role", "admin");
+          } else {
+            localStorage.setItem("role", res.data.roleCodes[0]);
+          }
+        } else {
+          this.$notify({ type: "danger", message: res.msg });
+        }
+      });
+    },
+  },
+};
+</script>
 <style lang="scss">
+html,
+body {
+  height: 100%;
+}
 #app {
   font-weight: 400;
   font-family: PingFangSC-Regular, PingFang SC;
@@ -12,7 +77,7 @@
   text-align: center;
   color: #0c1935;
   background: #f6f6f6;
-  height: 100vh;
+  height: 100%;
   box-sizing: border-box;
 }
 
@@ -37,6 +102,10 @@
     width: calc(100% - 32px);
   }
 }
+.van-tab--active,
+.van-cascader {
+  --van-font-weight-bold: 500;
+}
 :root {
   --van-gray-3: unset;
   --van-gray-5: #999999;
@@ -49,5 +118,6 @@
   --van-font-size-lg: 16px;
   --van-border-radius-sm: 4px;
   --van-border-width-base: 0;
+  --van-tabs-bottom-bar-height: 4px !important;
 }
 </style>

+ 1 - 1
src/router/index.js

@@ -3,7 +3,7 @@ import { createRouter, createWebHashHistory } from 'vue-router'
 const routes = [
   {
     path: '/',
-    redirect: '/login'
+    redirect: '/home'
   },
   {
     name: 'login',

+ 3 - 0
src/store/index.js

@@ -3,6 +3,9 @@ import { createStore } from 'vuex'
 
 export default createStore({
   state: {
+    username:'',
+    userMobile:'',
+    password:''
   },
   mutations: {
   },

+ 20 - 1
src/utils/api.js

@@ -1,6 +1,25 @@
 
 import { service } from './request'
 export default {
+
+    //账号密码登录
     loginByPwd: (params) => service.post("/app/login", params),
-    getUserInfo: (params) => service.get("/app/login", params)
+
+    //获取用户信息
+    getUserInfo: (params) => service.get("/app/user/userInfo", { params: params }),
+
+    // 获取空间树
+    getBuildInfo: (params) => service.get("/app/control/getOrgStructureTree", { params: params }),
+
+    // 首页信息
+    homedata: (params) => service.get("/app/home/homedata", params),
+
+    //上传图片
+    uploadFile: (params) => service.post("/app/uploadFile", params, { header: { "Content-Type": "multipart/form-data" } }),
+
+    //工单维修--保存
+    repairInfoSave: (params) => service.post("/app/repairorder", params),
+
+    //工单维修--分页查询
+    repairInfoQuery: (params) => service.get("/app/repairorder/page", { params: params }),
 }

+ 2 - 6
src/utils/request.js

@@ -1,4 +1,3 @@
-
 import axios from "axios";
 import { Notify } from "vant";
 import axiosRetry from "axios-retry";
@@ -9,11 +8,8 @@ export const getBaseURI = () => {
 
   //    开发环境
   if (env === "dev" || env == "development") {
-    //    return 'http://112.30.213.162:8082/stayhome-app'
-    //return 'http://192.168.1.101:9013/stayhome-app';
-    // return 'https://s-stg.ringzle.com/stayhome-app'
-    //    return 'http://192.168.1.102:9013/stayhome-app';
-    return "https://s.ringzle.com/stayhome-app";
+    // return 'http://192.168.1.51:9013/witcarbon-app';
+    return "http://gpu.ringzle.com:8082/witcarbon-app";
   }
 
   // 集成测试环境

+ 263 - 189
src/views/home.vue

@@ -6,7 +6,10 @@
     style="background-color: #5c8fff"
   />
   <div class="page_info">
-    <div class="info_bg">
+    <div
+      class="info_bg"
+      :style="{ 'margin-bottom': role == 'repair' ? 0 : '42px' }"
+    >
       <van-row align="center" class="title">
         <van-col>
           <van-image
@@ -23,7 +26,7 @@
             fit="contain"
           />
         </van-col>
-        <van-col @click="toPath">
+        <van-col @click="toPath('/userInfo', 'account')">
           <van-image
             :src="require('@/assets/user.svg')"
             width="16"
@@ -34,13 +37,14 @@
       </van-row>
     </div>
     <!-- 维修工没有此块功能 -->
-    <template v-if="role != 3">
+    <template v-if="role && role != 'repair'">
       <div class="info_function">
         <div
           class="function_item"
           v-for="(item, index) in functionList"
           :key="index"
           :style="{ display: !item.role.includes(role) ? 'none' : '' }"
+          @click="toPath(item.path)"
         >
           <template v-if="item.role.includes(role)">
             <van-image :src="item.src" width="36" height="36" fit="contain" />
@@ -49,142 +53,196 @@
         </div>
       </div>
     </template>
-    <div class="info_list">
+    <div
+      class="info_list"
+      :style="{
+        'max-height':
+          role == 'repair'
+            ? 'calc(100% - 102px - 20px)'
+            : 'calc(100% - 102px - 42px - 20px);',
+      }"
+    >
       <!-- 实时巡检begin -->
-      <van-row align="center" justify="space-between" class="sub_title">
-        <van-col class="title">实时巡检</van-col>
-        <van-col class="function_btn">
-          <van-col>立即巡检</van-col>
-          <van-image
-            :src="require('@/assets/btn-arrow-right.svg')"
-            width="24"
-            height="24"
-            fit="contain"
-          />
-        </van-col>
-      </van-row>
-      <van-row align="center" justify="space-between" class="list_item">
-        <van-row
-          align="center"
-          justify="space-between"
-          style="flex-direction: column"
-          v-for="(item, index) in checkList"
-          :key="item + '_' + index"
-        >
-          <van-col>{{ item.label }}</van-col>
-          <v-count-up
-            :end-val="Number(item['count'])"
-            class="count_up"
-            :options="item['options']"
-          />
+      <template v-if="role == 'check'">
+        <van-row align="center" justify="space-between" class="sub_title">
+          <van-col class="title">实时巡检</van-col>
+          <van-col class="function_btn" @click="toPath('/')">
+            <van-col>立即巡检</van-col>
+            <van-image
+              :src="require('@/assets/btn-arrow-right.svg')"
+              width="24"
+              height="24"
+              fit="contain"
+            />
+          </van-col>
         </van-row>
-      </van-row>
+        <van-row align="center" justify="space-around" class="list_item">
+          <van-row
+            align="center"
+            justify="center"
+            style="flex-direction: column"
+            v-for="(item, index) in checkList"
+            :key="item + '_' + index"
+          >
+            <van-col>{{ item.label }}</van-col>
+            <v-count-up
+              :end-val="Number(item['count'])"
+              class="count_up"
+              :options="item['options']"
+            />
+          </van-row>
+        </van-row>
+      </template>
       <!-- 实时巡检end -->
 
       <!-- 工单待办begin -->
-      <van-row align="center" justify="space-between" class="sub_title">
-        <van-col class="title">工单待办</van-col>
-        <van-col class="function_btn">
-          <van-col>立即处理</van-col>
-          <van-image
-            :src="require('@/assets/btn-arrow-right.svg')"
-            width="24"
-            height="24"
-            fit="contain"
-          />
-        </van-col>
-      </van-row>
-      <van-row align="center" justify="space-between" class="list_item">
-        <van-row
-          align="center"
-          justify="space-between"
-          style="flex-direction: column"
-          v-for="(item, index) in workList"
-          :key="item + '_' + index"
-        >
-          <van-col>{{ item.label }}</van-col>
-          <v-count-up
-            :end-val="Number(item['count'])"
-            class="count_up"
-            :options="item['options']"
-          />
+      <template v-if="role && role != 'check'">
+        <van-row align="center" justify="space-between" class="sub_title">
+          <van-col class="title">{{
+            role == "admin" ? "工单待办" : "实时报修"
+          }}</van-col>
+          <van-col class="function_btn" @click="toPath('/repairList')">
+            <van-col>{{ role == "admin" ? "立即处理" : "立即查看" }}</van-col>
+            <van-image
+              :src="require('@/assets/btn-arrow-right.svg')"
+              width="24"
+              height="24"
+              fit="contain"
+            />
+          </van-col>
         </van-row>
-      </van-row>
+        <van-row align="center" justify="space-around" class="list_item">
+          <van-row
+            align="center"
+            justify="center"
+            style="flex-direction: column"
+            v-for="(item, index) in workList"
+            :key="item + '_' + index"
+            :style="{ display: !item.role.includes(role) ? 'none' : '' }"
+          >
+            <van-col>{{ item.label }}</van-col>
+            <v-count-up
+              :end-val="Number(item['count'])"
+              class="count_up"
+              :options="item['options']"
+            />
+          </van-row>
+        </van-row>
+      </template>
       <!-- 工单待办end -->
 
       <!-- 设备异常begin -->
-      <van-row align="center" justify="space-between" class="sub_title">
-        <van-col class="title">设备异常</van-col>
-        <van-col class="function_btn">
-          <van-col>立即处理</van-col>
-          <van-image
-            :src="require('@/assets/btn-arrow-right.svg')"
-            width="24"
-            height="24"
-            fit="contain"
-          />
-        </van-col>
-      </van-row>
-      <van-row align="center" justify="space-between" class="list_item">
-        <van-row
-          align="center"
-          justify="space-between"
-          style="flex-direction: column"
-          v-for="(item, index) in deviceErrorList"
-          :key="item + '-' + index"
-        >
-          <van-col>{{ item.label }}</van-col>
-          <v-count-up
-            :end-val="Number(item['count'])"
-            class="count_up"
-            :options="item['options']"
-            style="color: #fa5555"
-          />
+      <template v-if="role && role != 'rent'">
+        <van-row align="center" justify="space-between" class="sub_title">
+          <van-col class="title">设备异常</van-col>
+          <van-col class="function_btn">
+            <van-col>立即查看</van-col>
+            <van-image
+              :src="require('@/assets/btn-arrow-right.svg')"
+              width="24"
+              height="24"
+              fit="contain"
+            />
+          </van-col>
         </van-row>
-      </van-row>
+        <van-row align="center" justify="space-around" class="list_item">
+          <van-row
+            align="center"
+            justify="center"
+            style="flex-direction: column"
+          >
+            <van-col>{{ abnormalNum.label }}</van-col>
+            <v-count-up
+              :end-val="Number(abnormalNum['count'])"
+              class="count_up"
+              style="color: #fa5555"
+            />
+          </van-row>
+          <van-row
+            align="center"
+            justify="space-between"
+            style="flex-direction: column"
+            v-for="(item, index) in deviceErrorList"
+            :key="item + '_' + index"
+          >
+            <van-col>{{ item.label }}</van-col>
+            <v-count-up :end-val="Number(item['count'])" class="count_up" />
+          </van-row>
+        </van-row>
+      </template>
       <!-- 设备异常end -->
 
       <!-- 欠费待收begin -->
-      <van-row align="center" justify="space-between" class="sub_title">
-        <van-col class="title">欠费待收</van-col>
-        <van-col class="function_btn">
-          <van-col>立即处理</van-col>
-          <van-image
-            :src="require('@/assets/btn-arrow-right.svg')"
-            width="24"
-            height="24"
-            fit="contain"
-          />
-        </van-col>
-      </van-row>
-      <div class="list_item list_table">
-        <van-row align="center" justify="space-between" class="table_header">
-          <van-col span="8">欠费类型</van-col>
-          <van-col span="8">欠费租户数</van-col>
-          <van-col span="8">累计欠费</van-col>
-        </van-row>
-        <van-row
-          align="center"
-          justify="space-between"
-          v-for="item in list"
-          :key="item.id"
-          class="table_body"
-        >
-          <van-col span="8" style="color: #999999; font-size: 12px">
-            {{ `${feeType_filter(item && item.feeType)}` }}
-          </van-col>
-          <van-col span="8" style="color: #0c1935; font-size: 16px">
-            {{ item.rentNum }}
-          </van-col>
-          <van-col span="8" style="color: #0c1935; font-size: 16px">
-            {{ item.totalFee }}
+      <template v-if="role == 'admin'">
+        <van-row align="center" justify="space-between" class="sub_title">
+          <van-col class="title">欠费待收</van-col>
+          <van-col class="function_btn">
+            <van-col>立即催收</van-col>
+            <van-image
+              :src="require('@/assets/btn-arrow-right.svg')"
+              width="24"
+              height="24"
+              fit="contain"
+            />
           </van-col>
         </van-row>
-      </div>
+        <div class="list_item list_table">
+          <van-row class="table_header">
+            <van-col span="8">欠费类型</van-col>
+            <van-col span="8">欠费租户数</van-col>
+            <van-col span="8">累计欠费(元)</van-col>
+          </van-row>
+          <van-row
+            v-for="(item, index) in billPaymentList"
+            :key="index"
+            class="table_body"
+          >
+            <van-col span="8" style="color: #999999; font-size: 12px">{{
+              item.payType
+            }}</van-col>
+            <van-col span="8">{{ item.arrearageNum }}</van-col>
+            <van-col span="8">{{ item.arrearageAmount }}</van-col>
+          </van-row>
+        </div>
+      </template>
       <!-- 欠费待收end -->
+
+      <!-- 账单待缴begin -->
+      <template v-if="role == 'rent'">
+        <van-row align="center" justify="space-between" class="sub_title">
+          <van-col class="title">账单待缴</van-col>
+          <van-col class="function_btn">
+            <van-col>立即缴费</van-col>
+            <van-image
+              :src="require('@/assets/btn-arrow-right.svg')"
+              width="24"
+              height="24"
+              fit="contain"
+            />
+          </van-col>
+        </van-row>
+        <div class="list_item list_table">
+          <van-row class="table_header">
+            <van-col span="8">缴费类型</van-col>
+            <van-col span="8">本期待缴金额(元)</van-col>
+            <van-col span="8">累计待缴金额(元)</van-col>
+          </van-row>
+          <van-row
+            v-for="(item, index) in billPaymentList"
+            :key="index"
+            class="table_body"
+          >
+            <van-col span="8" style="color: #999999; font-size: 12px">{{
+              item.payType
+            }}</van-col>
+            <van-col span="8">{{ item.arrearageNum }}</van-col>
+            <van-col span="8">{{ item.arrearageAmount }}</van-col>
+          </van-row>
+        </div>
+      </template>
+      <!-- 账单待缴end -->
     </div>
   </div>
-
   <!-- 底部tabbar -->
   <van-tabbar
     v-model="activeTabBar"
@@ -225,7 +283,7 @@
   </van-tabbar>
 </template>
 <script>
-import { isEmpty } from "@/utils/index.js";
+import api from "../utils/api";
 import VCountUp from "./CountUp";
 export default {
   components: {
@@ -233,24 +291,27 @@ export default {
   },
   data() {
     return {
-      role: 1, //1:admin、2:巡检人员、3:维修工、4:租户
+      role: "admin",
       name: "电商园四期-B座",
       activeTabBar: "home",
       functionList: [
         {
+          path: "/repairOnline",
           src: require("@/assets/repair-online.svg"),
           label: "线上报修",
-          role: [1, 2, 4],
+          role: ["admin", "check", "rent"],
         },
         {
+          path: "/checkRecord",
           src: require("@/assets/check-review.svg"),
           label: "巡检记录",
-          role: [1, 2],
+          role: ["admin", "check"],
         },
         {
+          path: "/reduceRecord",
           src: require("@/assets/reduce-record.svg"),
           label: "扣缴记录",
-          role: [1, 4],
+          role: ["admin", "rent"],
         },
       ],
       checkList: [
@@ -269,83 +330,90 @@ export default {
           },
         },
       ],
+      billPaymentList: [
+        { id: 1, payType: "电费", arrearageNum: 3000, arrearageAmount: 900000 },
+      ],
+      abnormalNum: { label: "异常总数", count: "" },
       workList: [
         {
           label: "待指派",
           count: 3,
-          options: {
-            separator: ",",
-          },
+          role: ["admin"],
         },
         {
           label: "待维修",
           count: 2,
-          options: {
-            separator: ",",
-          },
+          role: ["admin", "repair", "rent"],
         },
         {
           label: "已维修",
-          count: 1,
-          options: {
-            separator: ",",
-          },
-        },
-      ],
-      deviceErrorList: [
-        {
-          label: "异常总数",
-          count: 7,
-          options: {
-            separator: ",",
-          },
-        },
-        {
-          label: "电表异常",
-          count: 5,
-          options: {
-            separator: ",",
-          },
-        },
-        {
-          label: "水表异常",
-          count: 2,
-          options: {
-            separator: ",",
-          },
+          count: 0,
+          role: ["admin", "repair", "rent"],
         },
       ],
-      list: [
-        { feeType: 1, rentNum: 23, totalFee: 12636 },
-        { feeType: 2, rentNum: 7, totalFee: 462 },
-        { feeType: 3, rentNum: 132, totalFee: 24634 },
-        { feeType: 1, rentNum: 23, totalFee: 12636 },
-        { feeType: 2, rentNum: 7, totalFee: 462 },
-        { feeType: 3, rentNum: 132, totalFee: 24634 },
-      ],
+      deviceErrorList: [],
+      loading: false,
     };
   },
+  created() {
+    this.getHomeData();
+    // this.role = localStorage.getItem("role");
+  },
   methods: {
-    feeType_filter(val) {
-      if (isEmpty(val)) {
-        return "";
-      }
-      if (val == 1) {
-        return "电费";
-      }
-      if (val == 2) {
-        return "水费";
-      }
-      if (val == 3) {
-        return "物业相关";
-      }
+    getHomeData() {
+      api.homedata().then((res) => {
+        if (res.code == 0) {
+          //工单代办数据
+          for (let k in res.data.workOrder) {
+            this.workList[k - 1].count = res.data.workOrder[k];
+          }
+          //设备异常数据
+          let mapsArr = [];
+          for (let k in res.data.equip.maps) {
+            let json = {};
+            json.label = k;
+            json.count = res.data.equip.maps[k];
+            mapsArr.push(json);
+          }
+          this.deviceErrorList = mapsArr;
+          //赋值异常总数
+          this.abnormalNum.count = res.data.equip.abnormalNum;
+          //欠费待收数据
+          this.billPaymentList = res.data.billPaymentList;
+        }
+      });
     },
-    toPath() {
+    onLoad() {
+      setTimeout(() => {
+        if (this.refreshing.value) {
+          this.list.value = [];
+          this.refreshing.value = false;
+        }
+
+        for (let i = 0; i < 10; i++) {
+          this.list.value.push(this.list.value.length + 1);
+        }
+        this.loading.value = false;
+
+        if (this.list.value.length >= 40) {
+          this.finished.value = true;
+        }
+      }, 1000);
+    },
+    onRefresh() {
+      // 清空列表数据
+      this.finished.value = false;
+
+      // 重新加载数据
+      // 将 loading 设置为 true,表示处于加载状态
+      this.loading.value = true;
+      this.onLoad();
+    },
+    toPath(path, val) {
       this.$router.push({
-        path: "/userInfo",
+        path: path,
         query: {
-          title: "账号中心",
-          source: "account",
+          source: val,
         },
       });
     },
@@ -397,6 +465,7 @@ export default {
     align-items: center;
     justify-content: space-around;
     padding: 16px 0;
+    box-sizing: border-box;
     .function_item {
       display: flex;
       flex-direction: column;
@@ -417,7 +486,7 @@ export default {
     padding: 0 16px;
     overflow-y: auto;
     .sub_title {
-      margin: 12px 0 6px 0;
+      margin: 16px 0 6px 0;
       .title {
         height: 20px;
         font-size: 14px;
@@ -441,7 +510,7 @@ export default {
       background: #ffffff;
       box-shadow: 0px 0px 4px 0px rgba(51, 51, 51, 0.08);
       border-radius: 4px;
-      padding: 16px 30px;
+      padding: 16px 0;
       .van-col {
         height: 16px;
         font-size: 12px;
@@ -452,14 +521,13 @@ export default {
       .count_up {
         margin-top: 4px;
         height: 22px;
-        font-size: 20px;
-        font-weight: 500;
+        font-size: 16px;
         color: #0c1935;
         line-height: 22px;
       }
     }
     .list_table {
-      padding: 8px 16px;
+      padding: 8px 16px 4px 16px;
       .table_header {
         padding: 8px 0;
         border-bottom: 1px solid #eeeeee;
@@ -474,6 +542,12 @@ export default {
       .table_body {
         padding: 12px 0;
         border-bottom: 1px solid #eeeeee;
+        .van-col {
+          height: 16px;
+          font-size: 16px;
+          color: #0c1935;
+          line-height: 16px;
+        }
       }
     }
   }

+ 1 - 32
src/views/login.vue

@@ -72,7 +72,6 @@
 </template>
 
 <script>
-import { getUserInfo } from "../utils/api";
 export default {
   data() {
     return {
@@ -87,37 +86,7 @@ export default {
   },
   methods: {
     onSubmit() {
-      this.loading = true;
-      setTimeout(() => {
-        this.loading = false;
-        this.$router.push("/home");
-      }, 2000);
-      // Api.loginByPwd({
-      //   username: this.tel,
-      //   password: this.password,
-      //   captcha: "1",
-      //   uuid: "1",
-      // }).then((res) => {
-      // this.loading = false
-      //   if (res.code == 0) {
-      //     this.$toast.clear();
-      //     window.localStorage.setItem("token", res.data.token);
-      // this.getUserInfo();
-      //   } else {
-      //     this.$notify({ type: "danger", message: res.msg });
-      //   }
-      // });
-    },
-    getUserInfo() {
-      Api.getUserInfo({
-        username: this.tel,
-        password: this.password,
-      }).then((res) => {
-        if (res.code == 0) {
-        } else {
-          this.$notify({ type: "danger", message: res.msg });
-        }
-      });
+       window.location.href = "/?username=" + this.tel + "&&pwd=" + this.password;
     },
   },
 };

+ 4 - 2
src/views/rentBill.vue

@@ -31,7 +31,7 @@
         />
       </div>
     </div>
-    <div class="drop_down">
+    <div class="drop_down" style="display: flex">
       <van-dropdown-menu active-color="#1989fa">
         <van-dropdown-item
           v-model="rentStatus"
@@ -108,6 +108,9 @@ export default {
   },
   data() {
     return {
+      minDate: new Date(2020, 0, 1),
+      maxDate: new Date(2025, 5, 1),
+      currentDate: "",
       loading: false,
       name: "电商园四期-B座",
       rentStatus: "",
@@ -162,7 +165,6 @@ export default {
         }
       }, 1000);
     },
-
     onRefresh() {
       // 清空列表数据
       this.finished = false;

+ 161 - 135
src/views/repairList.vue

@@ -1,66 +1,78 @@
 <template>
-  <van-nav-bar
-    :title="title"
-    left-arrow
-    @click-left="onClickLeft"
-    safe-area-inset-top
-  />
-  <div class="page_check">
-    <div class="search_pannel">
-      <van-tabs
-        v-model:active="activeTab"
-        title-active-color="#2E69EB"
-        title-inactive-color="#0C1935"
-      >
-        <van-tab title="待指派" />
-        <van-tab title="已指派(待维修)" />
-        <van-tab title="已维修" />
-      </van-tabs>
-    </div>
-    <div class="list_total">
-      <span>共有</span>
-      <v-count-up
-        :end-val="total"
-        class="count_up"
-        options="{ separator: ',' }"
+  <van-nav-bar :title="title" safe-area-inset-top>
+    <template #left>
+      <van-icon
+        :name="require('@/assets/arrow-left.svg')"
+        size="24"
+        @click="backPath"
       />
-      <span>条记录</span>
-    </div>
-    <div class="check_info">
+    </template>
+  </van-nav-bar>
+  <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
+    <div class="page_info">
+      <div class="search_pannel">
+        <van-tabs
+          v-model:active="activeTab"
+          title-active-color="#2E69EB"
+          title-inactive-color="#0C1935"
+        >
+          <van-tab name="1" title="待指派" />
+          <van-tab name="2" title="已指派(待维修)" />
+          <van-tab name="3" title="已维修" />
+        </van-tabs>
+      </div>
+      <van-row align="center" class="list_total">
+        <van-col>共有</van-col>
+        <v-count-up
+          :end-val="dataList.length"
+          class="count_up"
+          options="{ separator: ',' }"
+        />
+        <van-col>条记录</van-col>
+      </van-row>
       <div class="info_list">
-        <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
-          <van-list
-            v-model:loading="loading"
-            :finished="finished"
-            :error="error"
-            error-text="请求失败,点击重新加载"
-            finished-text="没有更多了"
-            @load="onLoad"
+        <van-list
+          v-model:loading="loading"
+          :finished="finished"
+          :error="error"
+          error-text="请求失败,点击重新加载"
+          finished-text="没有更多了"
+          @load="onLoad"
+        >
+          <div
+            v-for="item in dataList"
+            :key="item.id"
+            class="list_item"
+            @click="toPath(item.id)"
           >
-            <div v-for="item in list" :key="item.id" class="list_item">
-              <template v-if="item.repairStatus != 1">
-                <div
-                  class="urgency_type"
-                  :style="{
-                    'background-color': `${
-                      urgency_filter(item.urgency)['color']
-                    }`,
-                  }"
-                >
-                  <span>{{ `${urgency_filter(item.urgency)["label"]}` }}</span>
-                </div>
-              </template>
-              <span class="header">{{ item.position }}</span>
-              <span>报修类型:{{ item.repairType }}</span>
-              <span>维修完成时间:{{ item.repairFinishTime }}</span>
-            </div>
-          </van-list>
-        </van-pull-refresh>
+            <template v-if="item.status != 1">
+              <van-row
+                align="center"
+                class="urgency_type"
+                :style="{
+                  'background-color': `${
+                    urgency_filter(item.urgency)['color']
+                  }`,
+                }"
+              >
+                <van-col>{{
+                  `${urgency_filter(item.urgency)["label"]}`
+                }}</van-col>
+              </van-row>
+            </template>
+            <van-col class="header">{{ item.repairPosition }}</van-col>
+            <van-col
+              >报修类型:{{ `${repairType_filter(item.repairType)}` }}</van-col
+            >
+            <van-col>维修完成时间:{{ item.repairFinishTime }}</van-col>
+          </div>
+        </van-list>
       </div>
     </div>
-  </div>
+  </van-pull-refresh>
 </template>
 <script>
+import Api from "../utils/api";
 import { isEmpty } from "@/utils/index.js";
 import VCountUp from "./CountUp";
 export default {
@@ -69,19 +81,11 @@ export default {
   },
   data() {
     return {
-      loading: false,
       title: "",
-      activeTab: 0,
-      total: 3,
-      list: [
-        {
-          position: "B座13楼1301",
-          urgency: 1,
-          repairType: 1,
-          repairStatus: 1,
-          repairFinishTime: "2022/12/04 13:32:22",
-        },
-      ],
+      activeTab: 1,
+      page: 1,
+      limit: 10,
+      dataList: [],
       loading: false,
       refreshing: false,
       finished: false,
@@ -90,11 +94,12 @@ export default {
   watch: {
     activeTab: {
       handler(newval, oldval) {
-        if (newval == 1 || newval == 2) {
+        if (newval == 2 || newval == 3) {
           this.title = "报修工单";
         } else {
           this.title = "工单待办";
         }
+        this.onRefresh();
       },
       deep: true,
       immediate: true,
@@ -130,39 +135,68 @@ export default {
         return { label: "普通", color: "#30D3A2" };
       }
     },
-    onLoad() {
-      setTimeout(() => {
-        if (this.refreshing) {
-          this.list = [];
-          this.refreshing = false;
-        }
-
-        for (let i = 0; i < 10; i++) {
-          this.list.push(this.list.length + 1);
+    // 获取列表数据方法
+    async getDataList() {
+      Api.repairInfoQuery({
+        page: this.page,
+        limit: this.limit,
+        status: this.activeTab,
+      }).then((res) => {
+        if (res.code == 0) {
+          if (res.data && res.data.list.length == 0) {
+            // 判断获取数据条数若等于0
+            this.dataList = []; // 清空数组
+            this.finished = true; // 停止加载
+          }
+          // 若数据条数不等于0
+          this.dataList.push(...res.data.list); // 将数据放入list中
+          this.loading = false; // 加载状态结束
+          // 如果list长度大于等于总数据条数,数据全部加载完成
+          if (this.dataList.length >= res.data.total) {
+            this.finished = true; // 结束加载状态
+          }
+        } else {
+          this.loading = false; // 加载状态结束
+          this.finished = true; // 停止加载
         }
-        this.loading = false;
+      });
+    },
 
-        if (this.list.length >= 40) {
-          this.finished = true;
-        }
-      }, 1000);
+    // 被 @load调用的方法
+    onLoad() {
+      // 定时器仅针对本地数据渲染动画效果,项目中axios请求不需要定时器
+      this.getDataList(); // 调用上面方法,请求数据
+      this.page++; // 分页数加一
+      this.finished;
     },
 
+    // 下拉调用方法
     onRefresh() {
       // 清空列表数据
       this.finished = false;
-
       // 重新加载数据
       // 将 loading 设置为 true,表示处于加载状态
       this.loading = true;
+      this.page = 1; // 分页数赋值为1
+      this.dataList = []; // 清空数组
       this.onLoad();
     },
-    onClickLeft() {},
+    toPath(id) {
+      this.$router.push({
+        path: "/repairDetail",
+        query: {
+          id: id,
+        },
+      });
+    },
+    backPath() {
+      this.$router.back();
+    },
   },
 };
 </script>
 <style lang="scss" scoped>
-.page_check {
+.page_info {
   height: 100%;
   .search_pannel {
     background: #ffffff;
@@ -177,7 +211,7 @@ export default {
     margin: 8px 0;
     display: flex;
     text-align: left;
-    span {
+    .van-col {
       height: 16px;
       font-size: 12px;
       font-weight: 400;
@@ -191,60 +225,52 @@ export default {
       margin: 0 2px;
     }
   }
-  .check_info {
+  .info_list {
     padding: 0 16px;
-    height: calc(
-      100% - var(--van-nav-bar-height) - var(--van-dropdown-menu-height) - 76px
-    );
-    .info_list {
-      height: 100%;
-      overflow-y: auto;
-      .list_item {
-        background: #ffffff;
-        box-shadow: 0px 0px 10px 0px rgba(153, 153, 153, 0.15);
-        border-radius: 4px;
-        margin-bottom: 12px;
-        padding: 12px 16px;
-        display: flex;
-        flex-direction: column;
-        align-items: flex-start;
-        position: relative;
+    .list_item {
+      background: #ffffff;
+      box-shadow: 0px 0px 10px 0px rgba(153, 153, 153, 0.15);
+      border-radius: 4px;
+      margin-bottom: 12px;
+      padding: 12px 16px;
+      display: flex;
+      flex-direction: column;
+      align-items: flex-start;
+      position: relative;
+      &:nth-last-child(1) {
+        margin-bottom: 0;
+      }
+      .header {
+        height: 22px;
+        font-size: 16px;
+        font-weight: 600;
+        color: #313836;
+        line-height: 22px;
+        margin-bottom: 8px;
+      }
+      .van-col {
+        height: 18px;
+        font-size: 14px;
+        font-weight: 400;
+        color: #999999;
+        line-height: 18px;
+        margin-bottom: 4px;
         &:nth-last-child(1) {
           margin-bottom: 0;
         }
-        .header {
-          height: 22px;
-          font-size: 16px;
-          font-weight: 600;
-          color: #313836;
-          line-height: 22px;
-          margin-bottom: 8px;
-        }
-        span {
-          height: 18px;
-          font-size: 14px;
+      }
+      .urgency_type {
+        position: absolute;
+        top: 0;
+        right: 0;
+        height: 24px;
+        padding: 0 12px;
+        border-radius: 0px 4px 0px 10px;
+        .van-col {
+          font-size: 12px;
           font-weight: 400;
-          color: #999999;
-          line-height: 18px;
-          margin-bottom: 4px;
-          &:nth-last-child(1) {
-            margin-bottom: 0;
-          }
-        }
-        .urgency_type {
-          position: absolute;
-          top: 0;
-          right: 0;
-          height: 24px;
-          padding: 0 12px;
-          border-radius: 0px 4px 0px 10px;
-          span {
-            height: 16px;
-            font-size: 12px;
-            font-weight: 400;
-            color: #ffffff;
-            line-height: 16px;
-          }
+          color: #ffffff;
+          line-height: 16px;
         }
       }
     }

+ 121 - 50
src/views/repairOnline.vue

@@ -1,12 +1,15 @@
 <template>
-  <van-nav-bar
-    title="线上报修"
-    left-arrow
-    @click-left="onClickLeft"
-    safe-area-inset-top
-  />
-  <div class="page_repair">
-    <div class="repair_info">
+  <van-nav-bar title="线上报修" safe-area-inset-top>
+    <template #left>
+      <van-icon
+        :name="require('@/assets/arrow-left.svg')"
+        size="24"
+        @click="backPath"
+      />
+    </template>
+  </van-nav-bar>
+  <div class="page_info">
+    <div class="info_list">
       <van-form
         input-align="right"
         error-message-align="right"
@@ -21,23 +24,21 @@
             placeholder="请选择报修位置"
             clearable
             :rules="[{ required: true, message: '请选择报修位置' }]"
-             @click="showRepairPositionPicker = true"
+            @click="showRepairPositionPicker = true"
           />
           <van-popup
             v-model:show="showRepairPositionPicker"
             round
             position="bottom"
           >
-            <van-picker
-              :columns="repairPositionList"
-              @cancel="showRepairPositionPicker = false"
-              @confirm="
-                (value) => {
-                  dataForm.repairPosition = value.value;
-                  dataForm.repairPositionName = value.text;
-                  showRepairPositionPicker = false;
-                }
-              "
+            <van-cascader
+              v-model="dataForm.repairPosition"
+              title="请选择报修位置"
+              active-color="#2e69eb"
+              :options="positionList"
+              :field-names="fieldNames"
+              @close="showRepairPositionPicker = false"
+              @finish="onFinish"
             />
           </van-popup>
           <van-field
@@ -133,6 +134,7 @@
                 :max-count="10"
                 accept="image/jpeg,image/jpg,image/png"
                 :before-read="beforeRead"
+                :before-delete="beforeDelete"
                 :after-read="afterRead"
                 @oversize="onOversize"
               />
@@ -140,14 +142,7 @@
           </van-cell>
         </van-cell-group>
         <div class="save_btn">
-          <van-button
-            block
-            type="primary"
-            :loading="loading"
-            loading-type="spinner"
-            native-type="submit"
-            loading-text="提交"
-          >
+          <van-button block type="primary" native-type="submit">
             提交
           </van-button>
         </div>
@@ -156,19 +151,22 @@
   </div>
 </template>
 <script>
+import Api from "../utils/api";
 export default {
   data() {
     return {
       loading: false,
       fileList: [],
+      tempFileList: [],
+      positionList: [],
+      fieldNames: {
+        text: "orgName",
+        value: "orgId",
+        children: "childrenList",
+      },
       showRepairPositionPicker: false,
       showRepairRegionPicker: false,
       showRepairTypePicker: false,
-      repairPositionList: [
-        { text: "水", value: 1 },
-        { text: "电", value: 2 },
-        { text: "其他", value: 3 },
-      ],
       repairRegionList: [
         {
           text: "公共区域",
@@ -186,6 +184,9 @@ export default {
       ],
       dataForm: {
         id: "",
+        buildingId: "",
+        storeyId: "",
+        houseId: "",
         repairPosition: "",
         repairPositionName: "",
         repairRegion: 1,
@@ -199,10 +200,32 @@ export default {
       },
     };
   },
+  created() {
+    this.getBuildList();
+  },
   methods: {
-    onClickLeft() {},
+    //获取楼栋
+    getBuildList() {
+      Api.getBuildInfo().then((res) => {
+        if (res.code == 0) {
+          this.positionList = res.data[0].childrenList;
+        }
+      });
+    },
+    onFinish(val) {
+      this.dataForm.buildingId = val.selectedOptions[0].orgId;
+      this.dataForm.storeyId = val.selectedOptions[1].orgId;
+      this.dataForm.houseId = val.selectedOptions[2].orgId;
+      this.dataForm.repairPositionName =
+        val.selectedOptions[0].orgName +
+        "/" +
+        val.selectedOptions[1].orgName +
+        "/" +
+        val.selectedOptions[2].orgName;
+      this.showRepairPositionPicker = false;
+    },
     onOversize() {
-      this.$toast("文件大小不能超过 500kb");
+      this.$toast("单个文件大小不能超过 500kb");
     },
     beforeRead(file) {
       if (file instanceof Array) {
@@ -229,34 +252,82 @@ export default {
       }
       return true;
     },
+    beforeDelete(file) {
+      this.tempFileList = this.tempFileList.filter(
+        (item) => item.name != file.file.name
+      );
+      this.fileList = this.fileList.filter(
+        (item) => item.file.name != file.file.name
+      );
+    },
     afterRead(file) {
-      console.log(file);
-      file.status = "uploading";
-      file.message = "上传中...";
+      if (file instanceof Array) {
+        file.forEach((file) => {
+          file.status = "uploading";
+          file.message = "上传中...";
+          setTimeout(async () => {
+            await this.uploadFile(file);
+          }, 1000);
+        });
+      } else {
+        file.status = "uploading";
+        file.message = "上传中...";
+        setTimeout(() => {
+          this.uploadFile(file);
+        }, 1000);
+      }
+    },
+    uploadFile(file) {
+      //  这时候我们创建一个formData对象实例
+      const formData = new FormData();
+      // 通过append方法添加需要的file
+      // 这里需要注意 append(key, value)来添加数据,如果指定的key不存在则会新增一条数据,如果key存在,则添加到数据的末尾
+      formData.append("file", file.file);
 
-      setTimeout(() => {
-        file.status = "failed";
-        file.message = "上传失败";
-      }, 1000);
+      // 上传文件、成功后, 把Url 赋值给 field
+      Api.uploadFile(formData).then((res) => {
+        if (res.code == 0) {
+          file.status = "done";
+          file.message = "上传成功";
+          this.tempFileList.push({ name: file.file.name, url: res.data });
+        } else {
+          file.status = "failed";
+          file.message = "上传失败";
+        }
+      });
     },
     onSubmit() {
-      this.loading = true;
-      setTimeout(() => {
-        this.loading = false;
-        this.$router.push("/");
-      }, 2000);
+      let tempArr = [];
+      this.tempFileList.forEach((item) => {
+        tempArr.push(item.url);
+      });
+      this.dataForm.faultPics = tempArr.join(",");
+      this.$toast.loading({
+        message: "保存中...",
+        forbidClick: true,
+      });
+      Api.repairInfoSave(this.dataForm).then((res) => {
+        if (res.code == 0) {
+          this.$toast.success("保存成功");
+        } else {
+          this.$toast.fail("保存失败");
+        }
+      });
+    },
+    backPath() {
+      this.$router.back();
     },
   },
 };
 </script>
 <style lang="scss" scoped>
-.page_repair {
+.page_info {
   height: calc(
-    100% - var(--van-button-default-height) - var(--van-nav-bar-height) - 28px
+    100% - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 12px - 60px -46px
   );
   margin-top: 12px;
-  .repair_info {
-    height: 100%;
+  .info_list {
+    max-height: 100%;
     overflow-y: auto;
     /deep/ {
       .upload_cell {

+ 11 - 5
src/views/userInfo.vue

@@ -84,17 +84,21 @@ export default {
       title: "",
       loading: false,
       dataForm: {
-        username: "张浩",
-        tel: 158304802928,
-        password: "123456",
+        username: "",
+        tel: "",
+        password: "",
         newpassword: "",
         confirmpassword: "",
       },
     };
   },
   created() {
-    this.title = this.$route.query.title;
     this.source = this.$route.query.source;
+    this.title =
+      (this.source && (this.source == "account" ? "账号中心" : "更改密码")) ||
+      "";
+    this.dataForm.username = this.$store.state.username;
+    this.dataForm.tel = this.$store.state.userMobile;
     this.dataForm.password = this.plusXing(this.dataForm.password, 0, 0, "*");
   },
   methods: {
@@ -123,7 +127,9 @@ export default {
         this.$router.push("/");
       }, 2000);
     },
-    loginOut() {},
+    loginOut() {
+      localStorage.clear();
+    },
     backPath() {
       this.$router.back();
     },