From d840ec98c37494baf79f3d05e3d2b01c76cec744 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期四, 30 十月 2025 13:05:38 +0800
Subject: [PATCH] 巡检
---
src/pages.json | 6
src/pages/routingInspection/index.vue | 153 +++++++++++++++++
src/pages/routingInspection/product_card/index.vue | 205 ++++++++++++++++++++++
src/api/routingInspection/routingInspection.ts | 23 ++
src/pages/routingInspection/list/index.vue | 111 ++++++++++++
src/pages/index/index.vue | 6
src/static/icons/routingInspection.png | 0
7 files changed, 504 insertions(+), 0 deletions(-)
diff --git a/src/api/routingInspection/routingInspection.ts b/src/api/routingInspection/routingInspection.ts
new file mode 100644
index 0000000..074de57
--- /dev/null
+++ b/src/api/routingInspection/routingInspection.ts
@@ -0,0 +1,23 @@
+import request from "@/utils/request";
+import { BaseResult } from "@/models/base";
+
+const RoutingInspectionApi = {
+ // 鏌ヨ宸℃璁板綍
+ getDeviceInspectListByPatrol(params: any) {
+ return request<BaseResult<any>>({
+ url: "/wireInspection/getDeviceInspectListByPatrol",
+ method: "GET",
+ data: params,
+ });
+ },
+ // 鑾峰彇宸℃鏁版嵁
+ getInspectListByPatrol(data: any) {
+ return request<BaseResult<any>>({
+ url: "/wireInspection/getInspectListByPatrol",
+ method: "POST",
+ data: data,
+ });
+ },
+};
+
+export default RoutingInspectionApi;
diff --git a/src/pages.json b/src/pages.json
index 55210a1..781c4b7 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -148,6 +148,12 @@
}
},
{
+ "path": "pages/routingInspection/index",
+ "style": {
+ "navigationBarTitleText": "宸℃"
+ }
+ },
+ {
"path": "pages/production/detail/wireDetail",
"style": {
"navigationBarTitleText": "鎷変笣璇︽儏"
diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue
index 2df7101..e6e6454 100644
--- a/src/pages/index/index.vue
+++ b/src/pages/index/index.vue
@@ -177,6 +177,12 @@
url: "/pages/timely/index",
show: false,
},
+ {
+ icon: "/static/icons/routingInspection.png",
+ title: "宸℃",
+ url: "/pages/routingInspection/index",
+ show: true,
+ },
]);
// 鍔犺浇璁块棶缁熻鏁版嵁
diff --git a/src/pages/routingInspection/index.vue b/src/pages/routingInspection/index.vue
new file mode 100644
index 0000000..4e9a33a
--- /dev/null
+++ b/src/pages/routingInspection/index.vue
@@ -0,0 +1,153 @@
+<template>
+ <view>
+ <wd-row>
+ <wd-col :span="21">
+ <wd-search placeholder-left hide-cancel></wd-search>
+ </wd-col>
+ <wd-col :span="3">
+ <view class="scan_box" @click="openScan">
+ <wd-icon name="scan" size="24px" color="#0D867F"></wd-icon>
+ </view>
+ </wd-col>
+ </wd-row>
+ <wd-tabs v-model="tab" auto-line-width slidable="always" map-num>
+ <wd-tab
+ v-for="(item, index) in patrolList"
+ :key="index"
+ :title="`${item.deviceModel}锛堝緟妫�鏌�${item.pendingNum}鏉★級`"
+ class="tab_bg"
+ >
+ <ProductList
+ :api="RoutingInspectionApi.getInspectListByPatrol"
+ :ProList="item"
+ />
+ </wd-tab>
+ </wd-tabs>
+ <Scan ref="scanRef" emitName="scan" />
+ <wd-toast />
+ </view>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, computed, onMounted, onUnmounted } from "vue";
+import ProductList from "./list/index.vue";
+import Scan from "@/components/scan/index.vue";
+import { useUserStore } from "@/store/modules/user";
+import reportApi from "@/api/work/report";
+import { useToast } from "wot-design-uni";
+import RoutingInspectionApi from "@/api/routingInspection/routingInspection";
+
+const scanRef = ref();
+const userStore = useUserStore();
+const userInfo: any = computed(() => userStore.userInfo);
+const toast = useToast();
+const tab = ref<number>(0);
+const patrolList = ref<any[]>([]);// 宸℃璁惧鍒楄〃鏁版嵁
+
+
+const handlePatrolData = (index: number, count: number) => {
+ // 鍙互鍦ㄨ繖閲屾洿鏂扮壒瀹氬贰妫�璁惧鐨勫緟妫�鏌ユ暟閲�
+ // 渚嬪锛歱atrolList.value[index].pendingNum = count;
+};
+
+const openScan = () => {
+ scanRef.value.triggerScan();
+};
+
+const getScanCode = async () => {
+ const { code } = await reportApi.sendWorkTime({
+ userName: userInfo.value.userName,
+ });
+ if (code == 200) {
+ toast.success("鎵爜鎴愬姛");
+ }
+};
+
+// 鑾峰彇鐗瑰畾宸℃璁惧鐨勬暟鎹�
+const getPatrolData = (item: any) => {
+ return async (params: any) => {
+ // 杩欓噷鍙互鏍规嵁item涓殑淇℃伅璋冪敤鐩稿簲鐨勬帴鍙h幏鍙栬鎯�
+ // 杩斿洖鐨勬暟鎹牸寮忛渶瑕佷笌ProductList缁勪欢鏈熸湜鐨勬牸寮忎竴鑷�
+ return {
+ code: 200,
+ data: {
+ type: "宸℃",
+ data: {
+ total: 0,
+ records: []
+ }
+ }
+ };
+ };
+};
+
+// 鑾峰彇宸℃璁惧鍒楄〃
+const loadPatrolList = async () => {
+ try {
+ const { data } = await RoutingInspectionApi.getDeviceInspectListByPatrol({});
+ if (data) {
+ patrolList.value = data;
+ }
+ } catch (error) {
+ toast.error("鑾峰彇宸℃璁惧鍒楄〃澶辫触");
+ }
+};
+
+// 纭繚鍏堢Щ闄ゅ啀娣诲姞鐩戝惉
+const setupScanListener = () => {
+ uni.$off("scan", getScanCode); // 鍏堢Щ闄ゆ棫鐨�
+ uni.$on("scan", getScanCode); // 鍐嶆坊鍔犳柊鐨�
+};
+
+onMounted(() => {
+ // 寮�鍚箍鎾洃鍚簨浠�
+ setupScanListener();
+ console.log("鏄剧ず1");
+ // 椤甸潰鍔犺浇鏃惰幏鍙栧贰妫�璁惧鍒楄〃
+ loadPatrolList();
+});
+
+onUnmounted(() => {
+ // 寮�鍚箍鎾洃鍚簨浠�
+ uni.$off("scan", getScanCode);
+ console.log("绂诲紑1");
+});
+</script>
+
+<style lang="scss" scoped>
+::v-deep .wd-search__block {
+ border-radius: unset;
+}
+.scan_box {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 38px;
+ height: 38px;
+ padding: 6px;
+ background: #fff;
+}
+::v-deep .wd-tabs__line {
+ background: #0d867f;
+}
+::v-deep .wd-tabs__nav {
+ border-bottom: 1px #dddddd solid;
+}
+.tab_bg {
+ background: #f3f9f8;
+}
+
+.icon_box {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 20px;
+ height: 20px;
+ background: #e7f4ec99;
+ border-radius: 50%;
+}
+
+.statistics_box {
+ margin: 15px;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/routingInspection/list/index.vue b/src/pages/routingInspection/list/index.vue
new file mode 100644
index 0000000..05c3bdf
--- /dev/null
+++ b/src/pages/routingInspection/list/index.vue
@@ -0,0 +1,111 @@
+<template>
+ <view class="card_box">
+ <z-paging ref="pagingRef" v-model="list" :fixed="false" :auto-show-back-to-top="true" @query="getList">
+ <ProductCard v-for="(item, index) in list" :key="index" :data="item" :map="map"
+ @click="toDetail(item.id, item.deviceType)" />
+ </z-paging>
+ <wd-toast />
+ </view>
+</template>
+
+<script setup lang="ts">
+ import ProductCard from "../product_card/index.vue";
+ import { useUserStore } from "@/store/modules/user";
+ import zPaging from "@/components/z-paging/z-paging.vue";
+ import { useToast } from "wot-design-uni";
+
+ const toast = useToast();
+ const userStore = useUserStore();
+ const userInfo : any = computed(() => userStore.userInfo);
+ const pagingRef = ref();
+const map = reactive({
+ deviceModel: "deviceModel",
+ model: "model",
+ firstNo: "firstNo",
+ recordDate: "recordDate",
+ workShift: "workShift",
+ teamName: "teamName",
+ poleModel: "poleModel",
+ poleNumber: "poleNumber",
+ outputNumber: "outputNumber",
+ inspectPerson: "inspectPerson",
+ status: "status",
+ rejectList: [
+ {
+ rejectPerson: "rejectPerson",
+ rejectTime: "rejectTime",
+ rejectReason: {
+ reason: "reason"
+ },
+ },
+ ], // 鏀逛负瀵硅薄锛屽寘鍚墍闇�鐨勫祵濂楀睘鎬�
+ });
+ const props = defineProps({
+ api: {
+ type: Function,
+ default: () => { },
+ },
+ ProList: {
+ type: Object,
+ default: () => { },
+ },
+ });
+
+ const list = ref<any[]>([]);
+
+const toDetail = (id: number, deviceType: number) => {
+ console.log('鐐瑰嚮鍗$墖', id, deviceType);
+ toast.show("鐐瑰嚮鍗$墖");
+ if (deviceType == 0) {
+ uni.navigateTo({
+ url: `/pages/production/detail/wireDetail?id=${id}`,
+ });
+ } else if (deviceType == 1) {
+ uni.navigateTo({
+ url: `/pages/production/detail/twistDetail?id=${id}`,
+ });
+ }
+ };
+
+ const getList = async () => {
+ const { code, data } = await props.api({
+ deviceModel: props.ProList.deviceModel,
+ status: "0",
+ deviceType: props.ProList.deviceType,
+ });
+ if (code == 200) {
+ map.deviceModel = "deviceModel";
+ map.model = "model";
+ map.firstNo = "firstNo";
+ map.recordDate = "recordDate";
+ map.workShift = "workShift";
+ map.teamName = "teamName";
+ map.poleModel = "poleModel";
+ map.poleNumber = "poleNumber";
+ map.outputNumber = "outputNumber";
+ map.inspectPerson = "inspectPerson";
+ map.rejectList = [
+ {
+ rejectPerson: "rejectPerson",
+ rejectTime: "rejectTime",
+ rejectReason: {
+ reason: "reason"
+ },
+ },
+ ];
+ map.status = "status";
+ if (data.total == 0) {
+ pagingRef.value.complete(true);
+ } else {
+ console.log('data.records', data.records);
+ pagingRef.value.complete(data.records);
+ }
+ }
+ };
+</script>
+
+<style lang="scss" scoped>
+ .card_box {
+ height: calc(100vh - 120px);
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/routingInspection/product_card/index.vue b/src/pages/routingInspection/product_card/index.vue
new file mode 100644
index 0000000..9b14232
--- /dev/null
+++ b/src/pages/routingInspection/product_card/index.vue
@@ -0,0 +1,205 @@
+<template>
+ <wd-card class="card_bg" @click="handleCardClick">
+ <template #title>
+ <view class="flex justify-between w-full">
+ <text class="font-medium text-[#252525]">鏈哄彴: {{ data[map.deviceModel] }}</text>
+ <wd-tag color="#0D867F" bg-color="#E7F4EC">
+ <text class="text-xs">{{ data[map.model] }}</text>
+ </wd-tag>
+ </view>
+ </template>
+ <wd-row class="my-2">
+ <wd-col :span="24">
+ <view class="flex">
+ <view class="icon_box">
+ <wd-icon name="folder" color="#0D867F"></wd-icon>
+ </view>
+ <text class="text-[#646874] mx-2">
+ 棣栨鍗曞彿:
+ <text class="text-[#252525]">{{ data[map.firstNo] }}</text>
+ </text>
+ </view>
+ </wd-col>
+ </wd-row>
+ <wd-row class="my-2">
+ <wd-col :span="24">
+ <view class="flex">
+ <view class="icon_box">
+ <wd-icon name="folder" color="#0D867F"></wd-icon>
+ </view>
+ <text class="text-[#646874] mx-2">
+ 鐝:
+ <text class="text-[#252525]">{{ data[map.workShift] }}</text>
+ </text>
+ </view>
+ </wd-col>
+ </wd-row>
+ <wd-row class="my-2">
+ <wd-col :span="24">
+ <view class="flex">
+ <view class="icon_box">
+ <wd-icon name="folder" color="#0D867F"></wd-icon>
+ </view>
+ <text class="text-[#646874] mx-2">
+ 鐝粍:
+ <text class="text-[#252525]">{{ data[map.teamName] }}</text>
+ </text>
+ </view>
+ </wd-col>
+ </wd-row>
+ <wd-row class="my-2">
+ <wd-col :span="24">
+ <view class="flex">
+ <view class="icon_box">
+ <wd-icon name="folder" color="#0D867F"></wd-icon>
+ </view>
+ <text class="text-[#646874] mx-2">
+ 棰嗙敤鏉嗗彿:
+ <text class="text-[#252525]">{{ data[map.poleNumber] }}</text>
+ </text>
+ </view>
+ </wd-col>
+ </wd-row>
+ <wd-col :span="12">
+ <view class="flex">
+ <view class="icon_box">
+ <wd-icon name="folder" color="#0D867F"></wd-icon>
+ </view>
+ <text class="text-[#646874] mx-2">
+ 鏉嗗瀷鍙�:
+ <text class="text-[#252525]">{{ data[map.poleModel] }}</text>
+ </text>
+ </view>
+ </wd-col>
+ <wd-row class="my-2">
+ <wd-col :span="12">
+ <view class="flex">
+ <view class="icon_box">
+ <wd-icon name="folder" color="#0D867F"></wd-icon>
+ </view>
+ <text class="text-[#646874] mx-2">
+ 鐢熶骇杞存暟:
+ <text class="text-[#252525]">{{ data[map.outputNumber] }}</text>
+ </text>
+ </view>
+ </wd-col>
+
+ </wd-row>
+ <wd-row class="my-2">
+ <wd-col :span="12">
+ <view class="flex">
+ <view class="icon_box">
+ <wd-icon name="folder" color="#0D867F"></wd-icon>
+ </view>
+ <text class="text-[#646874] mx-2">
+ 鑷浜�:
+ <text class="text-[#252525]">{{ data[map.inspectPerson] }}</text>
+ </text>
+ </view>
+ </wd-col>
+ <wd-col :span="12">
+ <view class="flex">
+ <view class="icon_box">
+ <wd-icon name="folder" color="#0D867F"></wd-icon>
+ </view>
+ <text class="text-[#646874] mx-2">
+ 鐘舵��:
+ <text class="text-[#252525]">{{ data[map.status] == 1 ? "琚┏鍥�" : "宸℃" }}</text>
+ </text>
+ </view>
+ </wd-col>
+ </wd-row>
+ <wd-row class="my-2">
+ <wd-col :span="16">
+ <view class="flex">
+ <view class="icon_box">
+ <wd-icon name="folder" color="#0D867F"></wd-icon>
+ </view>
+ <text class="text-[#646874] mx-2">
+ 璁板綍鏃堕棿:
+ <text class="text-[#252525]">{{ data[map.recordDate] }}</text>
+ </text>
+ </view>
+ </wd-col>
+ <wd-col :span="8">
+ <view class="flex">
+ <wd-button v-if="data[map.status] == 1" size="small" type="primary" @click.stop="showRejectPopup = true"
+ style="margin-left: auto;">
+ 鏌ョ湅椹冲洖淇℃伅
+ </wd-button>
+ </view>
+ </wd-col>
+ </wd-row>
+ </wd-card>
+<wd-popup v-model="showRejectPopup" title="椹冲洖淇℃伅" custom-style="border-radius:32rpx;height: 500rpx;width: 600rpx;">
+ <wd-card v-for="(item, index) in data.rejectList" :key="index"
+ :class="index % 2 === 0 ? 'reject-card-bg-1' : 'reject-card-bg-2'"
+ style="margin-bottom: 15px; padding: 10px; border-radius: 8px;">
+ <view class="content">
+ <view>
+ <view style="display: flex; justify-content: space-between; align-items: center; color: rgba(0,0,0,0.85); font-size: 14px; margin-bottom: 8px;">
+ <view>{{ item.rejectPerson }}</view>
+ <view>{{ item.rejectTime }}</view>
+ </view>
+ <view style="color: rgba(0,0,0,0.85); font-size: 14px; word-break: break-word; overflow-wrap: break-word; max-width: 100%; padding: 5px 0;">
+ {{ item.rejectReason.reason }}
+ </view>
+ </view>
+ </view>
+ </wd-card>
+</wd-popup>
+</template>
+
+<script setup lang="ts">
+import { ref } from "vue";
+const emit = defineEmits(['click']);
+ defineProps({
+ data: {
+ type: Object,
+ default: () => { },
+ },
+ map: {
+ type: Object,
+ default: () => { },
+ },
+ });
+const showRejectPopup = ref<boolean>(false)
+const handleCardClick = () => {
+ emit('click');
+};
+</script>
+
+<style lang="scss" scoped>
+ .card_bg {
+ box-shadow: 0px 0px 12px 0px rgba(0, 0, 0, 0.05);
+ padding-bottom: 10px;
+ }
+
+ // 娣诲姞锛氫袱绉嶄笉鍚岀殑鑳屾櫙鑹叉牱寮�
+ .reject-card-bg-1 {
+ background-color: #f5f7fa;
+ }
+
+ .reject-card-bg-2 {
+ background-color: #eef2f7;
+ }
+
+ .page-class {
+ :deep() {
+ .custom-shadow {
+ box-shadow: 0 3px 1px -2px rgb(0 0 0 / 20%), 0 2px 2px 0 rgb(0 0 0 / 14%), 0 1px 5px 0 rgb(0 0 0 / 12%);
+ }
+ }
+ }
+
+ .header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ // 淇敼锛氳皟鏁村唴瀹瑰尯鍩熺殑鏍峰紡
+ .content {
+ padding: 5px;
+ }
+</style>
\ No newline at end of file
diff --git a/src/static/icons/routingInspection.png b/src/static/icons/routingInspection.png
new file mode 100644
index 0000000..e8bb5a4
--- /dev/null
+++ b/src/static/icons/routingInspection.png
Binary files differ
--
Gitblit v1.9.3