浏览代码

程序初始化

zhuangdezheng 1 年之前
父节点
当前提交
7efa48ebc0

+ 18 - 0
App.vue

@@ -0,0 +1,18 @@
+<script>
+	export default {
+		onLaunch: function() {
+			console.log('App Launch')
+		},
+		onShow: function() {
+			console.log('App Show')
+		},
+		onHide: function() {
+			console.log('App Hide')
+		}
+	}
+</script>
+
+<style>
+	/*每个页面公共css */
+	@import url('./static/css/global.css');
+</style>

+ 3 - 0
api/base/path.js

@@ -0,0 +1,3 @@
+const baseURL = 'http://192.168.31.126:8080';
+
+export default baseURL;

+ 21 - 0
api/business/subPlanDetails.js

@@ -0,0 +1,21 @@
+import req from '../../utils/request.js'
+// import { getToken } from '@/utils/auth'
+
+// let timeout = 6000;
+// let Authorization = 'Bearer ' + getToken();
+// let reqHeader = {
+// 	'Authorization': Authorization
+// }
+
+/**
+ * 获取生产子计划列表
+ * @param {Object} data
+ */
+export function getSubPlanDetailsList(data) {
+	return req.request({
+		url:'/business/planDetailSubDetail/list',
+		// header: reqHeader,
+		method: 'GET',
+		data: data
+	})
+}

+ 13 - 0
api/login/index.js

@@ -0,0 +1,13 @@
+import req from '../../utils/request.js'
+
+/**
+ * 获取用户信息
+ * @param {Object} data
+ */
+export function getUserInfo() {
+	return req.request({
+		url:'/getUserInfo',
+		// header: reqHeader,
+		method: 'GET',
+	})
+}

+ 96 - 0
components/dialog-base/dialog-base.vue

@@ -0,0 +1,96 @@
+<template>
+	<view v-if="visible" class="dialog-container uni-column">
+		<view class="bg"></view>
+		<view class="dialog-body">
+			<view class="close-btn uni-column" @click="close">
+				<image class="close-btn-icon" src="../../static/images/login-dialog-close-icon.png" mode="widthFix" />
+			</view>
+			<view class="dialog-title">
+				<text class="label">{{props.title}}</text>
+			</view>
+			<slot></slot>
+			<slot name='footer'></slot>
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import { ref } from 'vue'
+	
+	const visible = ref(false)
+	
+	const props = defineProps({
+	  title: {
+		  type: String,
+		  default: '对话框'
+	  }
+	})
+	
+	const open = () => {
+		visible.value = true
+	}
+	
+	const close = () => {
+		visible.value = false
+	}
+	
+	/** 暴露给父组件的方法 */
+	defineExpose({
+	  open, 
+	  close
+	})
+</script>
+
+<style lang="scss">
+.dialog-container {
+	position: fixed;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	z-index: 1000;
+
+	.bg {
+		position: absolute;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		background-color: #333333;
+		opacity: 0.3;
+		z-index: 1001;
+	}
+	.dialog-body {
+		position: absolute;
+		top: 200rpx;
+		right: 64rpx;
+		left: 64rpx;
+		padding: 0 48rpx 48rpx 48rpx;
+		background-color: #FFFFFF;
+		z-index: 1002;
+	
+		.close-btn {
+			position: absolute;
+			right: 24rpx;
+			top: 24rpx;
+			width: 40rpx;
+			height: 40rpx;
+			z-index: 1003;
+	
+			.close-btn-icon {
+				width: 40rpx;
+			}
+		}
+	
+		.dialog-title {
+			align-items: center;
+			margin-top: 40rpx;
+	
+			.label {
+				font-weight: bold;
+				font-size: 40rpx;
+			}
+		}
+	}
+}
+</style>

+ 78 - 0
components/dialog-end-work/dialog-end-work.vue

@@ -0,0 +1,78 @@
+<template>
+	<dialog-base ref="baseDialog" title="结束报工">
+		<view class="list-container">
+			<view class="list-title"><text class="label">合格量</text></view>
+			<view class="table-item">
+				<input class="input" placeholder="请输入合格量" />
+			</view>
+			<view class="list-title">
+				<text class="label">废品量</text>
+			</view>
+
+			<view class="table-item"><input class="input" placeholder="请输入废品量" /></view>
+			<view class="list-title">
+				<text class="label">废品原因</text>
+			</view>
+
+			<view class="table-item"><input class="input" placeholder="请输入废品原因" /></view>
+		</view>
+		<view class="add-btn-container uni-row">
+			<button type="default" class="btn">结束报工</button>
+		</view>
+</dialog-base>
+</template>
+
+
+<script setup>
+	import {
+		ref,
+		getCurrentInstance
+	} from 'vue'
+	const baseDialog = ref(null)
+	const open = (data) => {
+		// console.log(dialog.value)
+		baseDialog.value.open()
+	}
+	defineExpose({
+		open
+	})
+</script>
+
+<style lang="scss">
+	.dialog-body {
+		.list-container {
+			width: 100%;
+			display: flex;
+			align-items: flex-start;
+			padding: 0 4rpx;
+
+			.list-title {
+				margin-top: 24rpx;
+
+				.label {
+					font-size: 32rpx;
+				}
+			}
+
+			.table-item {
+				margin-top: 24rpx;
+				.input {
+					height: 60rpx;
+					border: 1px solid #808080;
+				}
+			}
+
+		}
+
+		.add-btn-container {
+			margin-top: 32rpx;
+
+			.btn {
+				flex: 1;
+				background-color: rgb(255, 121, 1);
+				color: #FFFFFF;
+
+			}
+		}
+	}
+</style>

+ 156 - 0
components/dialog-login/dialog-login.vue

@@ -0,0 +1,156 @@
+<template>
+	<dialog-base ref="baseDialog" title="账号登录">
+		<template v-if="currentUser.nickname">
+			<view class="user-info-container uni-row">
+				<view class="user-avatar uni-row"><text class="label">{{ currentUser.nickname }}</text></view>
+				<view class="user-info">
+					<view class="nickname"><text class="label">{{ currentUser.nickname }}</text></view>
+					<view class="current-process"><text class="label">热处理</text></view>
+				</view>
+			</view>
+		</template>
+		<template v-else>
+			<input class="input-control" v-model="currentUser.userName" placeholder="员工编码" />
+		</template>
+		<input class="input-control" :password="true" v-model="currentUser.password" placeholder='密码' />
+		<view class="login-btn uni-row" @click="handleLogin"><text class="label">登录</text></view>
+	</dialog-base>
+</template>
+
+<script setup>
+	import {
+		ref,
+		getCurrentInstance
+	} from 'vue'
+	import {getUserInfo} from '@/api/login/index.js'
+	import baseURL from '@/api/base/path.js'
+	// 对话框
+	const baseDialog = ref(null)
+	const currentUser = ref({})
+	const errorMsg = ref('用户名或密码错误')
+	const successMsg = ref('登录成功')
+	const userInfo = ref ([])
+	// const { proxy } = getCurrentInstance()
+
+	const open = (data) => {
+		currentUser.value = data
+		// console.log(dialog.value)
+		baseDialog.value.open()
+	}
+	const handleLogin = () => {
+		uni.request({
+			method: 'POST',
+			url: baseURL +'/login',
+			data: {
+				username: currentUser.value.userName,
+				password: currentUser.value.password
+			},
+			success: (res) => {
+				console.log(res)
+				if (res.data.code === 200) {
+					uni.showToast({
+						title: successMsg.value,
+						icon: 'success',
+						duration: 2000
+					});
+					uni.setStorage({
+					    key: currentUser.value.userName,
+					    data:currentUser.value.password, 
+					    success: function() {
+					        uni.setStorage({
+					            key: 'token',
+					            data: res.data.token, 
+					            success: function() {
+					                console.log('success');
+					           }
+					        });
+					   }
+					});
+					getUserInfo(currentUser.value).then((res)=>{
+						if(res.code ==200) {
+							userInfo.value.push(res.data)
+							console.log(userInfo.value)
+						}
+					})
+					uni.redirectTo({
+						url: '/pages/dashboard/index'
+					})
+				} else {
+					uni.showToast({
+						title: errorMsg.value,
+						icon: 'error',
+						//显示持续时间为 2秒
+						duration: 2000
+					})
+				}
+			} 
+		})
+
+	}
+
+	/** 暴露给父组件的方法 */
+	defineExpose({
+		open
+	})
+</script>
+
+<style lang="scss">
+	.dialog-body {
+		.user-info-container {
+			margin-top: 32rpx;
+			align-items: center;
+
+			.user-avatar {
+				width: 120rpx;
+				height: 120rpx;
+				justify-content: center;
+				align-items: center;
+				border-radius: 120rpx;
+				background-color: #F5F5F5;
+
+				.label {
+					font-size: 72rpx;
+				}
+			}
+
+			.user-info {
+				flex: 1;
+				padding-left: 16rpx;
+
+				.nickname {
+					margin-bottom: 8rpx;
+
+					.label {
+						font-size: 40rpx;
+					}
+				}
+
+				.current-process {
+					.label {
+						font-size: 32rpx;
+						color: #666666;
+					}
+				}
+			}
+		}
+
+		.input-control {
+			border: 1px solid #666666;
+			padding: 16rpx 24rpx;
+			font-size: 32rpx;
+			margin-top: 40rpx;
+		}
+
+		.login-btn {
+			background-color: #999999;
+			margin-top: 32rpx;
+			justify-content: center;
+			padding: 16rpx 0;
+
+			.label {
+				font-size: 40rpx;
+				color: #FFFFFF;
+			}
+		}
+	}
+</style>

+ 131 - 0
components/dialog-lot/dialog-lot.vue

@@ -0,0 +1,131 @@
+<template>
+	<dialog-base ref="baseDialog" title="添加新批次">
+		<view class="list-title"><text class="label">批次号:{{form['batchNumber']}}</text></view>
+		<view class="list-container">
+			<view class="list-container-item uni-row">
+				<text class="label">产品描述</text>
+				<text class="label value">{{form['caseNumber']}}</text>
+			</view>
+			<view class="list-container-item uni-row">
+				<text class="label">关联箱号</text>
+				<text class="label value">{{form['caseNumber']}}</text>
+			</view>
+			<view class="list-container-item uni-row">
+				<text class="label">当前工序</text>
+				<text class="label value">{{form['totalWorkingHours']}}</text>
+			</view>
+			<view class="list-container-item uni-row" style="border-bottom: 1px solid #999999;">
+				<text class="label">投产数量</text>
+				<text class="label value">{{form['qualifiedQuantity']}}</text>
+			</view>
+		</view>
+		<view class="list-title"><text class="label">请选择设备:</text></view>
+		<!-- <scroll-view class="scroll-container" scroll-y> -->
+		<view class="equipment-container uni-row ">
+			<view v-for="(item, index) in equiments" :class="{'item':true,'selected': selectedButton === item}" :key="index" @click="selectButton(item)"><text class="label" >{{item}}</text></view>
+		</view>
+		<!-- </scroll-view> -->
+		<view class="add-btn-container uni-row">
+			<button type="primary" class="btn" style="flex: 1;">添加</button>
+		</view>
+	</dialog-base>
+</template>
+
+<script setup>
+	import {
+		ref,
+		getCurrentInstance
+	} from 'vue'
+	const baseDialog = ref(null)
+	const selectedButton = ref(null)
+	const form = ref({
+		batchNumber: "DC23727410070",
+		caseNumber: "X12522、X522、X15522、J5211、J5112",
+		totalWorkingHours: 135.5,
+		qualifiedQuantity: 600,
+		invest: 1000,
+		previousProcess: "NC车1",
+		currentProcess: "热处理",
+		NextProcess: "清洗",
+		status: 0
+	})
+	const equiments = ref(['009-21','009-22','009-23','009-24','009-25','009-26','009-27','009-28','009-29'])
+    const selectButton = (data) => {
+		 selectedButton.value = data;
+	}
+	const open = (data) => {
+		// console.log(dialog.value)
+		baseDialog.value.open()
+	}
+	defineExpose({
+		open
+	})
+</script>
+
+<style lang="scss">
+	.dialog-body {
+		.list-title {
+			margin: 40rpx 0 20rpx 0;
+
+			.label {
+				font-size: 32rpx;
+				font-weight: bold;
+			}
+		}
+
+		.list-container {
+			width: 100%;
+			display: flex;
+			align-items: flex-start;
+			padding: 0 4rpx;
+
+			.list-container-item {
+				width: 100%;
+				border: 1px solid #999999;
+				border-bottom: none;
+				padding: 12rpx 8rpx;
+				
+
+				.label {
+					font-size: 28rpx;
+					color: gray;
+					width: 144rpx;
+
+					&.value {
+						flex: 1;
+					}
+				}
+			}
+
+		}
+
+		.equipment-container {
+			 width: 100%;
+			 height: 120rpx;
+			flex-wrap: wrap;	
+			justify-content: flex-start;
+			overflow: auto;
+			.item {
+				flex: 0 0 22%;
+				border: 1rpx solid #aaaaaa;
+				border-radius: 4rpx;
+				margin:8rpx 1.2%;
+				padding: 12rpx 0;
+				justify-content: center;
+				align-items: center;
+
+				.label {
+					font-size: 32rpx;
+				}
+			}
+			.selected {
+  border: 1px solid #1684fc;
+  /* 其他选中样式 */
+}
+		}
+
+		.add-btn-container {
+			margin-top: 32rpx;
+		}
+	}
+</style>

+ 131 - 0
components/dialog-turnoverApplication/dialog-turnoverApplication.vue

@@ -0,0 +1,131 @@
+<template>
+	<dialog-base ref="baseDialog" title="周转申请">
+		<view class="list-container">
+			<view class="list-title"><text class="label">请选择周转类型</text></view>
+			<view class="btn uni-row">
+				<view :class="{ 'middle-btn': true, 'active': isLeftTurnoverType }"
+					@click="selectTurnoverType('leftType')"><text class="label">车间内周转</text></view>
+				<view :class="{ 'middle-btn': true, 'active': isRightTurnoverType }"
+					@click="selectTurnoverType('rightType')"><text class="label">车间外周转</text></view>
+			</view>
+			<view class="list-title">
+				<text class="label">请选择周转位置</text>
+			</view>
+			<view class="list-container">
+				<view class="btn uni-row">
+					<view :class="{ 'middle-btn': true, 'active': isLeftTurnoverDoor }"
+						@click="selectTurnoverDoor('leftDoor')"><text class="label">A门</text></view>
+					<view :class="{ 'middle-btn': true, 'active': isRightTurnoverDoor }"
+						@click="selectTurnoverDoor('rightDoor')"><text class="label">B门</text></view>
+				</view>
+			</view>
+		</view>
+		<view class="add-btn-container uni-row">
+			<button type="default" class="btn" >确认</button>
+		</view>
+	</dialog-base>
+</template>
+
+<script setup>
+	import {
+		ref,
+		getCurrentInstance
+	} from 'vue'
+    const baseDialog = ref(null)
+	const isLeftTurnoverType = ref(false)
+	const isRightTurnoverType = ref(false)
+	const isLeftTurnoverDoor = ref(false)
+	const isRightTurnoverDoor = ref(false)
+
+	const selectTurnoverType = (data) => {
+			if (data === 'leftType') {
+				isLeftTurnoverType.value = !isLeftTurnoverType.value;
+				isRightTurnoverType.value = false; // 右边按钮恢复为非活动状态
+			} else if (data === 'rightType') {
+				isRightTurnoverType.value = !isRightTurnoverType.value;
+				isLeftTurnoverType.value = false; // 左边按钮恢复为非活动状态
+			}
+		}
+		const selectTurnoverDoor = (data) => {
+			if (data === 'leftDoor') {
+				isLeftTurnoverDoor.value = !isLeftTurnoverDoor.value;
+				isRightTurnoverDoor.value = false; // 右边按钮恢复为非活动状态
+			} else if (data === 'rightDoor') {
+				isRightTurnoverDoor.value = !isRightTurnoverDoor.value;
+				isLeftTurnoverDoor.value = false; // 左边按钮恢复为非活动状态
+			}
+		}
+		const open = (data) => {
+			// console.log(dialog.value)
+			baseDialog.value.open()
+		}
+		defineExpose({
+		  open
+		})
+</script>
+
+<style lang="scss">
+	.dialog-body {
+		.list-container {
+			width: 100%;
+			display: flex;
+			align-items: flex-start;
+			padding: 0 4rpx;
+
+			.list-title {
+				margin-top: 24rpx;
+
+				.label {
+					font-size: 32rpx;
+				}
+			}
+
+			.btn {
+				justify-content: space-between;
+
+				margin-top: 24rpx;
+
+				.middle-btn {
+					margin-right: 32rpx;
+					align-items: center;
+					justify-content: center;
+					padding-left: 0;
+					height: 80rpx;
+					width: 240rpx;
+					border-radius: 8rpx;
+					background-color: #FFFFFF;
+					border: 1px solid #999999;
+					background-color: #FFFFFF;
+
+				}
+
+				.label {
+					font-size: 24rpx;
+					color: #000000;
+				}
+
+				.active {
+					border-color: #1684fc;
+					background-color: rgb(236, 245, 255);
+
+					.label {
+						color: #1684fc;
+					}
+				}
+
+
+			}
+
+		}
+
+		.add-btn-container {
+			margin-top: 32rpx;
+			.btn {
+				flex: 1; 
+				background-color: rgb(255, 121, 1);
+				color: #FFFFFF;
+				
+			}
+		}
+	}
+</style>

+ 122 - 0
components/dialog-turnoverTask/dialog-turnoverTask.vue

@@ -0,0 +1,122 @@
+<template>
+	<dialog-base ref="baseDialog" title="周转任务">
+		<view class="list-title uni-row"><text class="label">{{form['process']}}</text>
+		<text class="label">→</text>
+		<text class="label">{{form['car']}}</text></view>
+		<view class="list-container">
+			<view class="list-container-item uni-row">
+				<text class="label">批次</text>
+				<text class="label value">{{form['batch']}}</text>
+			</view>
+			<view class="list-container-item uni-row">
+				<text class="label">箱数</text>
+				<text class="label value">{{form['cases']}}</text>
+			</view>
+			<view class="list-container-item uni-row">
+				<text class="label">数量</text>
+				<text class="label value">{{form['amount']}}</text>
+			</view>
+			<view class="list-container-item uni-row" >
+				<text class="label">箱号</text>
+				<text class="label value">{{form['caseNumber']}}</text>
+			</view>
+			<view class="list-container-item uni-row" >
+				<text class="label">申请时间</text>
+				<text class="label value">{{form['applyTime']}}</text>
+			</view>
+			<view class="list-container-item uni-row" >
+				<text class="label">申请人</text>
+				<text class="label value">{{form['applier']}}</text>
+			</view>
+		</view>
+		
+	<view class="add-btn-container uni-row">
+		<button type="primary" class="btn" style="flex: 1;">确认周转</button>
+	</view>
+	</dialog-base>
+</template>
+
+<script setup>
+	import {
+		ref,
+		getCurrentInstance
+	} from 'vue'
+	 const baseDialog = ref(null)
+	const form = ref({
+						process: "粗磨",
+						car: "NC车",
+						batch: "DC23727410070",
+						cases: 5,
+						amount:780,
+						caseNumber: "X12522、X55222、X15522、J5211、J5211",
+						applyTime:"2023-06-15 15:52:12",
+						applier:"王伟"
+					})
+const open = (data) => {
+			// console.log(dialog.value)
+			baseDialog.value.open()
+		}
+		defineExpose({
+		  open
+		})
+</script>
+
+<style lang="scss">
+	.dialog-body {
+		.list-title {
+			margin: 40rpx 0 20rpx 0;
+		    
+			.label {
+				padding-right: 40rpx;
+				font-size: 32rpx;
+				font-weight: bold;
+			}
+		}
+		
+		.list-container {
+			width: 100%;
+			display: flex;
+			align-items: flex-start;
+			padding: 0 4rpx;
+		
+			.list-container-item {
+				width: 100%;
+				padding: 12rpx 8rpx;
+				align-items: center;
+		
+				.label {
+					font-size: 28rpx;
+					color: gray;
+					width: 144rpx;
+					
+					&.value {
+						
+						flex: 1;
+						color: #000000;
+					}
+				}
+			}
+		
+		}
+		
+		.equipment-container {
+		
+			.item {
+				flex: 1;
+				border: 1rpx solid #aaaaaa;
+				border-radius: 4;
+				margin: 0 8rpx;
+				padding: 12rpx 0;
+				justify-content: center;
+				align-items: center;
+				
+				.label {
+					font-size: 32rpx;
+				}
+			}
+		}
+	.add-btn-container {
+			margin-top: 32rpx;
+		}
+	}
+</style>

+ 20 - 0
index.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <script>
+      var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
+        CSS.supports('top: constant(a)'))
+      document.write(
+        '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
+        (coverSupport ? ', viewport-fit=cover' : '') + '" />')
+    </script>
+    <title></title>
+    <!--preload-links-->
+    <!--app-context-->
+  </head>
+  <body>
+    <div id="app"><!--app-html--></div>
+    <script type="module" src="/main.js"></script>
+  </body>
+</html>

+ 22 - 0
main.js

@@ -0,0 +1,22 @@
+import App from './App'
+
+// #ifndef VUE3
+import Vue from 'vue'
+import './uni.promisify.adaptor'
+Vue.config.productionTip = false
+App.mpType = 'app'
+const app = new Vue({
+  ...App
+})
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import { createSSRApp } from 'vue'
+export function createApp() {
+  const app = createSSRApp(App)
+  return {
+    app
+  }
+}
+// #endif

+ 72 - 0
manifest.json

@@ -0,0 +1,72 @@
+{
+    "name" : "ezhizao_dms_app",
+    "appid" : "__UNI__D96EF63",
+    "description" : "",
+    "versionName" : "1.0.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "usingComponents" : true,
+        "nvueStyleCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        /* 模块配置 */
+        "modules" : {},
+        /* 应用发布信息 */
+        "distribute" : {
+            /* android打包配置 */
+            "android" : {
+                "permissions" : [
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ]
+            },
+            /* ios打包配置 */
+            "ios" : {},
+            /* SDK配置 */
+            "sdkConfigs" : {}
+        }
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "",
+        "setting" : {
+            "urlCheck" : false
+        },
+        "usingComponents" : true
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    },
+    "vueVersion" : "3"
+}

+ 118 - 0
pages.json

@@ -0,0 +1,118 @@
+{
+	"pages": [
+		//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+		// index/index 登录页
+		{
+			"path": "pages/index/index",
+			"style": {
+				"navigationBarTitleText": "账号管理"
+			}
+		},
+		{
+			"path": "pages/dashboard/index",
+			"style": {
+				"navigationBarTitleText": "控制台"
+			}
+		},
+		{
+			"path": "pages/batchReporting/index",
+			"style": {
+				"navigationBarTitleText": "批次报工"
+			}
+		},
+		{
+			"path": "pages/handlingList/index",
+			"style": {
+				"navigationBarTitleText": "搬运列表"
+			}
+		},
+		{
+			"path": "pages/startTurnover/index",
+			"style": {
+				"navigationBarTitleText": "开始周转"
+			}
+		},
+		{
+			"path": "pages/productionPlan/index",
+			"style": {
+				"navigationBarTitleText": "生产计划单"
+			}
+		},
+		{
+			"path": "pages/changeBox/index",
+			"style": {
+				"navigationBarTitleText": "换箱"
+			}
+		},
+		{
+			"path": "pages/recerptSfprod/index",
+			"style": {
+				"navigationBarTitleText": "领取确认"
+			}
+		},
+		{
+			"path": "pages/reportingForWork/index",
+			"style": {
+				"navigationBarTitleText": "报工记录"
+			}
+		}
+		
+	],
+	"globalStyle": {
+		"navigationBarTextStyle": "black",
+		"navigationBarTitleText": "uni-app",
+		"navigationBarBackgroundColor": "rgba(255, 255, 255,1)",
+		"backgroundColor": "#F8F8F8"
+	},
+	"uniIdRouter": {},
+	"condition" : { //模式配置,仅开发期间生效
+		"current": 0, //当前激活的模式(list 的索引项)
+		"list": [
+			{
+				"name": "", //模式名称
+				"path": "pages/index/index",
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			},
+			{
+				"name": "", //模式名称
+				"path": "pages/dashboard/index",
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			},
+			{
+				"name": "", //模式名称
+				"path": "pages/batchReporting/index",
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			},
+			{
+				"name": "", //模式名称
+				"path": "pages/handlingList/index",
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			},
+			{
+				"name": "", //模式名称
+				"path": "pages/startTurnover/index",
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			},
+			{
+				"name": "", //模式名称
+				"path": "pages/productionPlan/index",
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			},
+			{
+				"name": "", //模式名称
+				"path": "pages/changeBox/index",
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			},
+			{
+				"name": "", //模式名称
+				"path": "pages/recerptSfprod/index",
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			},
+			{
+				"name": "", //模式名称
+				"path": "pages/reportingForWork/index",
+				"query": "" //启动参数,在页面的onLoad函数里面得到
+			}
+		]
+	}
+}

+ 249 - 0
pages/batchReporting/index.vue

@@ -0,0 +1,249 @@
+<template>
+	<view class="uni-column" style="height: 100%; background-color: #f5f5f5;">
+		<scroll-view class="scroll-container" scroll-y>
+			<view v-for="(item, index) in listData" :key="index" class="list-item">
+				<view class="title-container uni-row" style="justify-content: flex-start;">
+					<view class="title uni-row">
+						<text class="label">批次号:</text>
+						<text class="label code">{{ item['batchNumber'] }}</text>
+					</view>
+					<view class=" uni-row" style="margin-left: 16rpx;">
+						<view v-if="item['status'] == 0" class="tag"><text class="label">进行中</text></view>
+						<view v-else-if="item['status'] == 1" class="tag turnover "><text class="label">周转中</text>
+						</view>
+						<view v-else type="default" class="tag finished"><text class="label">已完成</text></view>
+					</view>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">箱号</text>
+					<text class="label right">{{ item['caseNumber'] }}</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">总工时</text>
+					<text class="label right">{{ item['totalWorkingHours']}}h</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">合格数/投入数</text>
+					<text class="label right">{{ item['qualifiedQuantity'] }}/{{item['invest']}}</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">上道工序</text>
+					<text class="label right">{{ item['previousProcess'] }}</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">当前工序</text>
+					<text class="label right">{{ item['currentProcess']}}</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">下道工序</text>
+					<text class="label right">{{ item['NextProcess'] }}</text>
+				</view>
+				<view class="status-btn uni-row">
+					<view v-if="item['status'] == 0" class=" uni-row">
+						<button class="turnover-tag" size="mini" @click="handleShowTurnoverApplication(null)">周转申请</button>
+						<button class="reporting-tag" size="mini">去报工</button>
+					</view>
+					<view v-else-if="item['status'] == 1" class=" uni-row">
+						<button class="turnover-tag" size="mini">取消周转</button>
+					</view>
+				</view>
+			</view>
+		</scroll-view>
+		<view class="bottom uni-row">
+			<button class="start-batch-btn" @click="handleShowLotDialog(null)">开始新批次</button>
+		</view>
+		<dialog-lot ref="lotDialog"/>
+		<dialog-turnoverApplication ref="turnoverApplicationDialog" />
+	</view>
+	
+</template>
+
+<script setup>
+	import { ref } from 'vue'
+	import { onLoad, onReady } from '@dcloudio/uni-app'
+	
+	onLoad(() => {
+
+	})
+	const turnoverApplicationDialog = ref(null)
+	const lotDialog = ref(null)
+	const listData = ref([
+		{
+			batchNumber: "DC23727410070",
+			caseNumber: "X12522、X522、X15522、J5211、J5112",
+			totalWorkingHours: 135.5,
+			qualifiedQuantity: 600,
+			invest: 1000,
+			previousProcess: "NC车1",
+			currentProcess: "热处理",
+			NextProcess: "清洗",
+			status: 0
+		},
+		{
+			batchNumber: "DC23727410070",
+			caseNumber: "X12522、X522、X15522、J5211、J5112",
+			totalWorkingHours: 135.5,
+			qualifiedQuantity: 600,
+			invest: 1000,
+			previousProcess: "NC车1",
+			currentProcess: "热处理",
+			NextProcess: "清洗",
+			status: 1
+		},
+		{
+			batchNumber: "DC23727410070",
+			caseNumber: "X12522、X522、X15522、J5211、J5112",
+			totalWorkingHours: 135.5,
+			qualifiedQuantity: 600,
+			invest: 1000,
+			previousProcess: "NC车1",
+			currentProcess: "热处理",
+			NextProcess: "清洗",
+			status: 2
+		}
+	])
+	const handleShowTurnoverApplication = (data) => {
+		let _data = data ?? {}
+		// 调用子组件中的方法
+		turnoverApplicationDialog.value.open(_data)
+	}
+	const handleShowLotDialog = (data) => {
+		let _data = data ?? {}
+		// 调用子组件中的方法
+		lotDialog.value.open(_data)
+	}
+
+</script>
+
+<style lang="scss">
+	.scroll-container {
+		width: 92%;
+		margin: 24rpx auto 0 auto;
+		height: 90%;
+	}
+
+	.list-item {
+		background-color: #fff;
+		position: relative;
+		padding: 16rpx;
+		padding-bottom: 24rpx;
+		margin-bottom: 24rpx;
+
+		.title-container {
+			
+			margin-top: 8rpx;
+			margin-bottom: 16rpx;
+
+			.title {
+				height: 48rpx;
+				align-items: center;
+
+				.label {
+					font-size: 32rpx;
+					font-weight: bold;
+
+					&.code {
+						margin-left: 8rpx;
+					}
+				}
+			}
+
+			.tag {
+				border: 1px solid #1CE5B0;
+				background-color: #F6FFFD;
+				padding: 8rpx;
+				border-radius: 8rpx;
+
+				.label {
+					color: #1CE5B0;
+					font-size: 24rpx;
+				}
+
+				&.finished {
+					border: 1px solid #BBBBBB;
+					background-color: #F5F5F5;
+
+					.label {
+						color: #BBBBBB;
+					}
+				}
+
+				&.turnover {
+					border: 1px solid #FF7901;
+					background-color: #F6FFFD;
+
+					.label {
+						color: #FF7901;
+					}
+				}
+			}
+		}
+
+		.item-info {
+			margin-bottom: 8rpx;
+
+			.label {
+				font-size: 28rpx;
+				width: 220rpx;
+				color: #808080;
+
+				&.right {
+					flex: 1;
+					color: #000000;
+				}
+			}
+		}
+
+		.status-btn {
+			justify-content: flex-end;
+			align-items: center;
+
+			.turnover-tag {
+				padding-right: 12rpx;
+				padding-left: 12rpx;
+				border-radius: 8rpx;
+				border: 1rpx solid #FF7901;
+				background-color: #FF7901;
+				font-size: 28rpx;
+				color: #FFFFFF;
+
+			}
+
+			.reporting-tag {
+				padding-right: 12rpx;
+				padding-left: 12rpx;
+				border-radius: 8rpx;
+				margin-left: 16rpx;
+				border: 1rpx solid #1684fc;
+				background-color: #1684fc;
+				font-size: 28rpx;
+				color: #FFFFFF;
+
+			}
+		}
+	}
+
+	.bottom {
+		height: 10%;
+		position: absolute;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		height: 80rpx;
+		border-top: 1px solid #999999;
+		padding: 16rpx 32rpx;
+		align-items: center;
+		background-color: #fff;
+
+		.start-batch-btn {
+			flex: 1;
+			background-color: #1684fc;
+			height: 100%;
+			justify-content: center;
+			align-items: center;
+			border-radius: 8rpx;
+			color: #FFFFFF;
+			font-size: 28rpx;
+		}
+	}
+</style>

+ 140 - 0
pages/changeBox/index.vue

@@ -0,0 +1,140 @@
+<template>
+	<view class='container'>
+		<view class='content'>
+			<view>
+				<text class='title'>{{firstTitle}}</text>
+				<view>
+					<view class="form-item uni-row">
+						<input class='inp' v-model='inpValue' />
+						<input class='inp' v-model='inpValue' />
+					</view>
+					<view class='btn-container uni-row'>
+						<button class='btn' type='primary' @click='addHandle()'>添加</button>
+						<button class='btn' type='primary' @click='scanCodeHandle()'>扫码</button>
+					</view>
+				</view>
+			</view>
+			<view class='middle'>
+				<view class='segment'></view>
+				<image class='img' src="../../static/convert.png"></image>
+				<view class='segment'></view>
+			</view>
+			<view>
+				<text class='title'>{{secondTitle}}</text>
+				<view class="form-item uni-row">
+					<input class='inp' v-model='secondInpValue' />
+					<input class='inp' v-model='secondInpValue' />
+				</view>
+				<view>
+					<button class='submit' style='background-color: rgba(0, 226, 166,1);color: white'>扫码</button>
+				</view>
+			</view>
+		</view>
+		<view class='bottom uni-row'>
+			<button class='submit' type=primary>提交</button>
+		</view>
+	</view>
+</template>
+<script setup>
+	import {
+		ref
+	} from 'vue'
+	import {
+		onLoad,
+		onReady
+	} from '@dcloudio/uni-app'
+
+
+	onLoad(() => {
+		firstTitle.value = '扫描旧箱子';
+		secondTitle.value = '扫描新箱子';
+	})
+	const firstTitle = ref(null)
+	const secondTitle = ref(null)
+	const inpValue = ref('X1523')
+	const secondInpValue = ref('X1893')
+	
+</script>
+
+<style lang="scss">
+	.container {
+		height: 100%;
+		background-color: #f5f5f5;
+	}
+
+	.bottom {
+		background-color: white;
+		width: 100%;
+		height: 10%;
+		position: absolute;
+		bottom: 0;
+		align-items: center;
+
+	}
+
+	.submit {
+		margin: 0 auto;
+		width: 80%;
+		height: 80rpx;
+		line-height: 80rpx;
+		padding-left: 0;
+	}
+
+	.content {
+		width: 90%;
+		// height: auto;
+		background-color: rgba(255, 255, 255, 1);
+		margin: 50rpx auto;
+		padding-bottom: 50rpx;
+		border-radius: 12rpx
+	}
+
+	.title {
+		margin: 30rpx auto;
+		width: 30%;
+		font-size: 36rpx;
+		font-weight: bold;
+	}
+
+	.form-item {
+		justify-content: space-between;
+		padding: 0 80rpx;
+
+		.inp {
+			width: 232rpx;
+			height: 60rpx;
+			border: 1px solid rgba(39, 138, 247, 1);
+			margin: 30rpx auto;
+			text-align: center;
+		}
+	}
+
+	.btn-container {
+		padding: 0 80rpx;
+		.btn {
+			width: 232rpx;
+			height: 80rpx;
+			line-height: 80rpx;
+			margin: 30rpx auto;
+		}
+	}
+
+	.img {
+		width: 30rpx;
+		height: 30rpx;
+		margin: 10rpx
+	}
+
+	.middle {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center
+	}
+
+	.segment {
+		width: 280rpx;
+		height: 1rpx;
+		border: 1px solid rgba(187, 187, 187, 1);
+	}
+</style>

+ 147 - 0
pages/dashboard/index.vue

@@ -0,0 +1,147 @@
+<template>
+	<view class="page-container uni-column">
+		<view class="logo-container uni-row">
+			<image class="logo" src="../../static/images/logo.png" />
+		</view>
+		<view class="title"><text class="label">德迈仕数字生产线管理平台</text></view>
+		<view class="user-info-container uni-row">
+			<view class="icon"><text class="label">张</text></view>
+			<view class="user-info uni-column">
+				<view class="nickname"><text class="label">张三 ID 15521</text> </view>
+				<view class="process"><text class="label">当前工段:热处理</text></view>
+			</view>
+		</view>
+		<view class="business-btn uni-row" @click="handleToRecerptSfprod"><text class="label">半成品接收</text></view>
+		<view class="business-btn uni-row" @click="handleToProductionPlan"><text class="label">报工</text></view>
+		<view class="business-btn uni-row" @click="handleToHandlingList"><text class="label">周转</text></view>
+		<view class="bottom-btn-container">
+			<view class="start-batch-btn uni-row"><text class="label">绑定设备</text></view>
+			<view class="start-batch-btn uni-row" @click="handleSwitchOrQuit"><text class="label">切换 / 退出账号</text></view>
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import { ref } from 'vue'
+	import { getSubPlanDetailsList } from '../../api/business/subPlanDetails'
+	
+	const name = ref('')
+	
+	const handleToRecerptSfprod = () => {
+		uni.navigateTo({
+			url: "/pages/recerptSfprod/index",
+		})
+	}
+	const handleToProductionPlan = () => {
+		uni.navigateTo({
+			url: "/pages/productionPlan/index",
+		});
+		getSubPlanDetailsList().then(res => {
+			console.log(res);
+		})
+	}
+	const handleToHandlingList = () => {
+		uni.navigateTo({
+			url: "/pages/handlingList/index",
+		});
+	}
+	const handleSwitchOrQuit = () =>{
+		uni.navigateTo({
+		    url:"/pages/index/index",
+		})
+	}
+</script>
+
+<style lang="scss">
+	.logo-container {
+		justify-content: center;
+		
+		.logo {
+			width: 120rpx;
+			height: 120rpx;
+		}
+	}
+
+	.title {
+		align-items: center;
+
+		.label {
+			font-size: 40rpx;
+			font-weight: bold;
+		}
+	}
+
+	.user-info-container {
+		margin: 64rpx 0 40rpx 8rpx;
+		
+		.icon {
+			width: 120rpx;
+			height: 120rpx;
+			justify-content: center;
+			align-items: center;
+			border-radius: 60rpx;
+			border: 1px solid #e1e1e1;
+			
+			.label {
+				font-size: 64rpx;
+			}
+		}
+
+		.user-info {
+			margin-left: 8rpx;
+			justify-content: center;
+
+			// font-size: 20rpx;
+			.nickname {
+				margin-bottom: 16rpx;
+				.label {
+					font-weight: bold;
+					font-size: 32rpx;
+				}
+			}
+
+			.process {
+				.label {
+					font-size: 32rpx;
+				}
+			}
+		}
+	}
+
+	.business-btn {
+		margin: 0 20rpx 20rpx 20rpx;
+		background-color: #fff;
+		height: 200rpx;
+		border-radius: 4;
+		align-items: center;
+		justify-content: center;
+		border: 1px solid #e1e1e1;
+		border-radius: 8rpx;
+
+		.label {
+			font-size: 40rpx;
+		}
+	}
+
+	.bottom-btn-container {
+		position: fixed;
+		right: 20rpx;
+		bottom: 0;
+		left: 20rpx;
+		
+		.start-batch-btn {
+			background-color: grey;
+			margin-bottom: 24rpx;
+			border-radius: 8rpx;
+			justify-content: center;
+			align-items: center;
+			height: 80rpx;
+		
+			.label {
+				font-size: 32rpx;
+				color: #FFFFFF;
+			}
+		}
+	}
+
+</style>

+ 425 - 0
pages/handlingList/index.vue

@@ -0,0 +1,425 @@
+<template>
+	<view class='container uni-column'>
+		<view class='nav uni-row'>
+			<text :class='pendingClass' @click='selectPending'>{{pendingTitle}}</text>
+			<text :class='turnoverClass' @click='selectTurnover'>{{turnoverTitle}}</text>
+			<image class='img' src="../../static/screen.png"></image>
+		</view>
+		<!-- 		<pending v-if='pendingShow'/>
+		<turnover v-if='turnoverShow'/> -->
+
+		<!-- 待周转页面 -->
+		<view class="padding-container" v-if='pendingShow'>
+			<scroll-view class="scroll-container" scroll-y>
+				<view v-for="(item, index) in listData" :key="index" class="list-item">
+					<view class="title-container uni-row">
+						<view class="title uni-row">
+							<text class="label">{{ item['door'] }}</text>
+							<text class="label code">{{ item['process'] }}</text>
+							<text class="label code" style="margin-left: 16rpx;">→</text>
+							<text class="label code" style="margin-left: 16rpx;">{{ item['car'] }}</text>
+						</view>
+
+						<view class="right-info uni-row">
+							<view class="uni-row"><text class="label right">待周转</text></view>
+						</view>
+					</view>
+					<view class="item-info uni-row"> <text class="label ">批次</text>
+						<text class="label right">{{ item['batch'] }}</text>
+					</view>
+					<view class="item-info uni-row"> <text class="label">箱数</text>
+						<text class="label right ">{{ item['cases'] }}</text>
+					</view>
+					<view class="item-info uni-row">
+						<text class="label">数量</text>
+						<text class="label right">{{ item['amount'] }}</text>
+					</view>
+					<view class="item-info uni-row">
+						<text class="label">箱号</text>
+						<text class="label right">{{ item['caseNumber']}}</text>
+					</view>
+					<view class="item-info uni-row">
+						<text class="label">申请时间</text>
+						<text class="label right">{{ item['applyTime']}}</text>
+					</view>
+					<view class="item-info uni-row">
+						<text class="label">申请人</text>
+						<text class="label right">{{ item['applier']}}</text>
+					</view>
+				</view>
+			</scroll-view>
+			<view class="bottom-btn-container uni-row">
+				<button class="bottom-btn">开始周转</button>
+			</view>
+		</view>
+		<!-- 周转中页面 -->
+		<view class='turnover-container' v-if='turnoverShow'>
+			<scroll-view class="scroll-container" scroll-y>
+				<!-- 循环周转中的数据 -->
+				<view class='item-container'>
+					<view class="turnover-title uni-row">
+						<view class="uni-row">
+							<view><text class='title-color'>{{turnoverContentTitle}}</text></view>
+							<view><text class="second-info">{{turnoverSecondTitle}}</text></view>
+						</view>
+						<view><text class="label">周转中</text></view>
+					</view>
+					<view class='list-container' v-for="(item,index) in products" :key='index'>
+						<view class="list-container-item product-description uni-row">
+							<text class="label left-value">产品描述</text>
+							<text class="label right-value">{{item['description']}}</text>
+						</view>
+						<view class="list-container-item uni-row">
+							<text class="label left-value">批次</text>
+							<text class="label right-value">{{item['batch']}}</text>
+						</view>
+						<view class="list-container-item uni-row">
+							<text class="label left-value">箱数</text>
+							<text class="label right-value">{{item['cases']}}</text>
+						</view>
+						<view class="list-container-item uni-row">
+							<text class="label left-value">箱号</text>
+							<text class="label right-value">{{item['boxno']}}</text>
+						</view>
+					</view>
+				</view>
+				
+				<view class='item-container'>
+					<view class="turnover-title uni-row">
+						<view class="uni-row">
+							<view><text class='title-color'>{{turnoverContentTitle}}</text></view>
+							<view><text class="second-info">{{turnoverSecondTitle}}</text></view>
+						</view>
+						<view><text class="label">周转中</text></view>
+					</view>
+					<view class='list-container' v-for="(item,index) in products" :key='index'>
+						<view class="list-container-item product-description uni-row">
+							<text class="label left-value">产品描述</text>
+							<text class="label right-value">{{item['description']}}</text>
+						</view>
+						<view class="list-container-item uni-row">
+							<text class="label left-value">批次</text>
+							<text class="label right-value">{{item['batch']}}</text>
+						</view>
+						<view class="list-container-item uni-row">
+							<text class="label left-value">箱数</text>
+							<text class="label right-value">{{item['cases']}}</text>
+						</view>
+						<view class="list-container-item uni-row">
+							<text class="label left-value">箱号</text>
+							<text class="label right-value">{{item['boxno']}}</text>
+						</view>
+					</view>
+				</view>
+			</scroll-view>
+			<view class='bottom-btn-container uni-row'>
+				<button type='primary' class='bottom-btn'>开始周转</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import { ref } from 'vue'
+	import { onLoad, onReady } from '@dcloudio/uni-app'
+	// import pending from './pending';
+	// import turnover from './turnover';
+	const pendingTitle = ref('待周转')
+	const turnoverTitle = ref('周转中')
+	const turnoverContentTitle = ref('')
+	const turnoverSecondTitle = ref('')
+	const sum = ref(0)
+	const pendingClass = ref({
+		selecter: true
+	})
+	const turnoverClass = ref({
+		selecter: false
+	})
+	const pendingShow = ref(true)
+	const turnoverShow = ref(false)
+	const listData = ref([{
+			door: "A门",
+			process: "粗磨",
+			car: "NC车",
+			batch: "MBA5444002",
+			cases: 6,
+			amount: 780,
+			caseNumber: "X12522、X55222、X15522、J5211、J5211",
+			applyTime: "2023-06-15 15:52:12",
+			applier: "王伟"
+	
+		},
+		{
+			door: "B门",
+			process: "手工校直",
+			car: "粗磨Ⅱ",
+			batch: "MBA5444002",
+			cases: 6,
+			amount: 780,
+			caseNumber: "X12522、X55222、X15522、J5211、J5211",
+			applyTime: "2023-06-15 15:52:12",
+			applier: "王伟"
+		},
+		{
+			door: "B门",
+			process: "手工校直",
+			car: "粗磨Ⅱ",
+			batch: "MBA5444002",
+			cases: 6,
+			amount: 780,
+			caseNumber: "X12522、X55222、X15522、J5211、J5211",
+			applyTime: "2023-06-15 15:52:12",
+			applier: "王伟"
+		}
+	])
+	const products = ref([{
+			description: '博士_0395614149_15*110.1',
+			batch: 'DC23727410070',
+			cases: 5,
+			boxno: 'X12522、X552222、X15522、J5211、J5112'
+		},
+		{
+			description: '博士_0395614149_15*110.1',
+			batch: 'DC23727410070',
+			cases: 5,
+			boxno: 'X12522、X552222、X15522、J5211、J5112'
+		},
+		{
+			description: '博士_0395614149_15*110.1',
+			batch: 'DC23727410070',
+			cases: 5,
+			boxno: 'X12522、X552222、X15522、J5211、J5112'
+		}
+	])
+	
+	onReady(() => {
+		init()
+	})
+	
+	const init = () => {
+		for (let i = 0; i < products.value.length; i++) {
+			sum.value += parseInt(products.value[i]['cases'].toString());
+		}
+		// this.title = '热处理' + this.sum + '箱'
+		turnoverContentTitle.value = sum.value + '箱';
+		turnoverSecondTitle.value = listData.value[0]['process'].toString() + ' → ' + listData.value[0]['car']
+			.toString();
+	}
+	const selectPending = () => {
+		pendingClass.value['selecter'] = true;
+		turnoverClass.value['selecter'] = false;
+		pendingShow.value = true;
+		turnoverShow.value = false;
+	}
+	const selectTurnover = () => {
+		pendingClass.value['selecter'] = false;
+		turnoverClass.value['selecter'] = true;
+		pendingShow.value = false;
+		turnoverShow.value = true;
+	}
+</script>
+
+<style lang="scss">
+	$navHeight: 48rpx;
+
+	/* 导航栏样式 */
+	.container {
+		height: 100%;
+		background-color: #f5f5f5;
+	}
+
+	.nav {
+		justify-content: space-around;
+		width: 100%;
+		height: $navHeight;
+		border-bottom: 3rpx solid rgba(228, 231, 237, 1);
+		background-color: rgba(255, 255, 255, 1);
+
+		.img {
+			width: 24rpx;
+			height: 24rpx;
+			position: fixed;
+			right: 10rpx;
+			top: 0;
+		}
+	}
+
+	.selecter {
+		height: 48rpx;
+		color: rgba(25, 137, 250, 1);
+		border-bottom: 3rpx solid rgba(25, 137, 250, 1);
+	}
+
+	/* 待周转样式 */
+	.padding-container,
+	.turnover-container {
+		position: absolute;
+		top: 56rpx;
+		right: 0;
+		bottom: 0rpx;
+		left: 0;
+		background-color: #f5f5f5;
+		
+		.scroll-container {
+			position: absolute;
+			top: 24rpx;
+			right: 0;
+			bottom: 136rpx;
+			left: 0;
+		}
+		
+		.bottom-btn-container {
+			height: 10%;
+			position: absolute;
+			right: 0;
+			bottom: 0;
+			left: 0;
+			height: 80rpx;
+			border-top: 1px solid #999999;
+			padding: 16rpx 32rpx;
+			align-items: center;
+			background-color: #fff;
+		
+			.bottom-btn {
+				// padding-left: 0;
+				// padding-top: 4rpx;
+				flex: 1;
+				font-size: 28rpx;
+				color: #FFFFFF;
+				background-color: #1684fc;
+			}
+		}
+	}
+	
+	.padding-container {
+		.scroll-container {
+			.list-item {
+				background-color: #fff;
+				padding: 0 24rpx;
+				padding-bottom: 24rpx;
+				margin: 0 24rpx;
+				margin-bottom: 24rpx;
+				border-radius: 8rpx;
+			
+				.title-container {
+					justify-content: space-between;
+					margin-top: 8rpx;
+					margin-bottom: 16rpx;
+			
+					.title {
+						height: 48rpx;
+						align-items: center;
+			
+						.label {
+							color: #1684fc;
+							font-size: 32rpx;
+							font-weight: bold;
+			
+							&.code {
+								color: #000000;
+								margin-left: 32rpx;
+							}
+						}
+					}
+				}
+			
+				.item-info {
+					margin-bottom: 16rpx;
+			
+					.label {
+						font-size: 28rpx;
+						width: 160rpx;
+						color: #808080;
+			
+						&.right {
+							flex: 1;
+							color: #000000;
+						}
+					}
+				}
+			
+				.right-info {
+					justify-content: flex-end;
+					margin-top: 2rpx;
+			
+					.label {
+						font-size: 28rpx;
+						color: #808080;
+					}
+				}
+			}
+		}
+	}
+	
+	/* 周转中样式 */
+	.turnover-container {
+		.scroll-container {
+			.item-container {
+				padding: 8rpx 0 32rpx 0;
+				margin: 0 24rpx;
+				margin-bottom: 24rpx;
+				background-color: rgba(255, 255, 255, 1);
+				border-radius: 8rpx;
+			
+				.turnover-title {
+					width: auto;
+					justify-content: space-between;
+					margin: 16rpx;
+					font-weight: bold;
+			
+					.label {
+						font-size: 28rpx;
+						color: #808080;
+					}
+				}
+			
+				.list-container {
+					margin: 0 24rpx 16rpx 24rpx;
+					
+					.list-container-item {
+						border-bottom: 1px solid #999999;
+						padding: 12rpx 8rpx;
+						background-color: #EEF0F5;
+						
+						&.product-description {
+							background-color: #ECF5FF;
+						}
+				
+						.label {
+							font-size: 28rpx;
+							color: #999999;
+							
+							&.left-value {
+								width: 152rpx;
+							}
+							&.right-value {
+								flex: 1;
+								color: #000000;
+							}
+						}
+					}
+				}
+			
+				.title-color {
+					color: rgba(22, 132, 252, 1);
+					font-size: 32rpx;
+					font-weight: bold;
+				}
+			
+				.second-info {
+					font-size: 32rpx;
+					font-weight: bold;
+					margin-left: 32rpx;
+				}
+			
+				.turnover-info {
+					color: rgba(128, 128, 128, 1);
+					position: absolute;
+					top: 10rpx;
+					right: 40rpx;
+					font-size: 30rpx;
+				}
+			}
+		}
+	}
+</style>

+ 169 - 0
pages/handlingList/pending.vue

@@ -0,0 +1,169 @@
+<template>
+
+        <view class="uni-column" style="height: 100%;">
+                <scroll-view class="scroll-container" scroll-y style="padding: 24rpx 24rpx 0 24rpx ;height: 90%;">
+                        <view v-for="(item, index) in listData" :key="index" class="list-item">
+                                <view class="title-container uni-row">
+                                        <view class="title uni-row">
+                                                <text class="label">{{ item['door'] }}</text>
+                                                <text class="label code">{{ item['process'] }}</text>
+                                                <text class="label code" style="margin-left: 16rpx;">→</text>
+                                                <text class="label code" style="margin-left: 16rpx;">{{ item['car'] }}</text>
+                                        </view>
+
+                                        <view class="right-info uni-row">
+                                                <view class="uni-row"><text class="label right">待周转</text></view>
+                                        </view>
+                                </view>
+                                <view class="item-info uni-row"> <text class="label ">批次</text>
+                                        <text class="label right">{{ item['batch'] }}</text>
+                                </view>
+                                <view class="item-info uni-row"> <text class="label">箱数</text>
+                                        <text class="label right ">{{ item['cases'] }}</text>
+                                </view>
+                                <view class="item-info uni-row">
+                                        <text class="label">数量</text>
+                                        <text class="label right">{{ item['amount'] }}</text>
+                                </view>
+                                <view class="item-info uni-row">
+                                        <text class="label">箱号</text>
+                                        <text class="label right">{{ item['caseNumber']}}</text>
+                                </view>
+                                <view class="item-info uni-row">
+                                        <text class="label">申请时间</text>
+                                        <text class="label right">{{ item['applyTime']}}</text>
+                                </view>
+                                <view class="item-info uni-row">
+                                        <text class="label">申请人</text>
+                                        <text class="label right">{{ item['applier']}}</text>
+                                </view>
+                        </view>
+                </scroll-view>
+                <view class="bottom uni-row">
+                        <button class="bottom-btn ">开始周转</button>
+                </view>
+        </view>
+
+
+</template>
+
+<script>
+        export default {
+                data() {
+                        return {
+                                listData: [
+                                        {
+                                                door: "A门",
+                                                process: "粗磨",
+                                                car: "NC车",
+                                                batch: "MBA5444002",
+                                                cases: 6,
+                                                amount: 780,
+                                                caseNumber: "X12522、X55222、X15522、J5211、J5211",
+                                                applyTime:"2023-06-15 15:52:12",
+                                                applier:"王伟"
+
+                                        },
+                                        {
+                                                door: "B门",
+                                                process: "手工校直",
+                                                car: "粗磨Ⅱ",
+                                                batch: "MBA5444002",
+                                                cases: 6,
+                                                amount: 780,
+                                                caseNumber: "X12522、X55222、X15522、J5211、J5211",
+                                                applyTime:"2023-06-15 15:52:12",
+                                                applier:"王伟"
+                                                
+
+                                        }
+
+                                ],
+                                onLoad() {
+
+                                },
+                                methods: {
+
+                                },
+
+                        };
+                },
+        };
+</script>
+
+<style lang="scss">
+        .list-item {
+                background-color: #fff;
+                position: relative;
+                padding: 16rpx;
+                padding-bottom: 24rpx;
+                margin-bottom: 24rpx;
+                border-radius: 8rpx;
+
+                .title-container {
+                        justify-content: space-between;
+                        margin-top: 8rpx;
+                        margin-bottom: 16rpx;
+
+                        .title {
+                                height: 48rpx;
+                                align-items: center;
+
+                                .label {
+                                        color: #1684fc;
+                                        font-size: 32rpx;
+                                        font-weight: bold;
+
+                                        &.code {
+                                                color: #000000;
+                                                margin-left: 32rpx;
+                                        }
+                                }
+                        }
+                }
+
+                .item-info {
+                        margin-bottom: 16rpx;
+
+                        .label {
+                                font-size: 28rpx;
+                                width: 220rpx;
+                                color: #808080;
+
+                                &.right {
+                                        flex: 1;
+                                        color: #000000;
+                                }
+                        }
+                }
+
+                .right-info {
+                        justify-content: flex-end;
+                        margin-top: 2rpx;
+
+                        .label {
+                                font-size: 28rpx;
+                                color: #808080;
+                        }
+                }
+        }
+
+        .bottom {
+                position: absolute;
+                bottom: 0;
+                width: 100%;
+                height: 100rpx;
+                padding: 16rpx 40rpx;
+                
+                background-color: #FFFFFF;
+
+                .bottom-btn {
+                        padding-left: 0;
+                        padding-top: 4rpx;
+                        flex: 1;
+                        font-size: 28rpx;
+                        color: #FFFFFF;
+                        background-color: #1684fc;
+                }
+        }
+</style>

+ 151 - 0
pages/handlingList/turnover.vue

@@ -0,0 +1,151 @@
+<template>
+
+	<view class='container'>
+		<view class='content'>
+			<text class='title'>{{title}}</text>
+			<view class='item-table' v-for="(item,index) in products" :key='index'>
+				<view>
+					<text class='tbhead' style='color:rgba(136, 136, 136,1)'>产品描述</text>
+					<text class='tbhead table-layout'>{{item['description']}}</text>
+				</view>
+				<view>
+					<text class='tbbody' style='color:rgba(136, 136, 136,1)'>批次</text>
+					<text class='tbbody table-layout'>{{item['batch']}}</Text>
+				</view>
+				<view>
+					<text class='tbbody' style='color:rgba(136, 136, 136,1)'>箱数</text>
+					<text class='tbbody table-layout'>{{item['cases']}}</Text>
+				</view>
+				<view>
+					<text class='tbbody' style='color:rgba(136, 136, 136,1)'>箱号</text>
+					<text class='last-tbbody table-layout'>{{item['boxno']}}</text>
+				</view>
+
+			</view>
+		</view>
+		<view class='btn uni-row'>
+			<button class='' type=primary>确定接收</button>
+		</view>
+	</view>
+</template>
+<script lang="uts">
+	export default {
+		data() {
+			return {
+				title: '热处理',
+				sum: 0,
+				products: [
+					{
+						description: '博士_0395614149_15*110.1',
+						batch: 'DC23727410070',
+						cases: 5,
+						boxno: 'X12522、X552222、X15522、J5211、J5112'
+					},
+					{
+						description: '博士_0395614149_15*110.1',
+						batch: 'DC23727410070',
+						cases: 5,
+						boxno: 'X12522、X552222、X15522、J5211、J5112'
+					},
+					{
+						description: '博士_0395614149_15*110.1',
+						batch: 'DC23727410070',
+						cases: 5,
+						boxno: 'X12522、X552222、X15522、J5211、J5112'
+					}
+				]
+			}
+		},
+		methods: {
+
+			init() {
+				for (let i = 0; i < this.products.length; i++) {
+					this.sum += parseInt(this.products[i]['cases'].toString());
+				}
+				// this.title = '热处理' + this.sum + '箱'
+				this.title = '热处理' + this.sum + '箱'
+			}
+		},
+		onReady() {
+			this.init();
+		}
+
+	}
+</script>
+
+<style>
+	.container {
+		height: 100%;
+	}
+
+	.btn {
+		background-color: white;
+		width: 100%;
+		height: 12%;
+/* 		position: absolute;
+		bottom: 0; */
+	}
+
+	.confirm {
+		width: 100%;
+		/* height: 80rpx; */
+		/* line-height: 80rpx; */
+		padding-left: 0;
+	}
+
+	.content {
+		width: 90%;
+		/* height: auto; */
+		background-color: rgba(255, 255, 255, 1);
+		margin: 50rpx auto;
+		padding-bottom: 50rpx;
+		border-radius: 12rpx
+	}
+
+	.item-table {
+		margin: 10rpx auto;
+		width: 90%;
+	}
+
+	.tbhead {
+		background-color: rgba(236, 245, 255, 1);
+		font-size: 24rpx;
+		height: 56rpx;
+		line-height: 56rpx;
+		padding-left: 6rpx;
+		border-bottom: 1px solid lightgray;
+
+	}
+
+	.tbbody {
+		font-size: 24rpx;
+		background-color: rgba(238, 240, 245, 1);
+		width: 70%;
+		height: 56rpx;
+		line-height: 56rpx;
+		padding-left: 6rpx;
+		border-bottom: 1px solid lightgray;
+	}
+
+	.last-tbbody {
+		font-size: 24rpx;
+		background-color: rgba(238, 240, 245, 1);
+		width: 70%;
+		height: 86rpx;
+		padding-left: 6rpx;
+		border-bottom: 1px solid lightgray;
+	}
+
+	.title {
+		margin: 10rpx auto;
+		width: 90%;
+		font-size: 36rpx;
+		font-weight: bold;
+	}
+
+	.table-layout {
+		position: absolute;
+		top: 0;
+		left: 30%
+	}
+</style>

+ 207 - 0
pages/index/index.vue

@@ -0,0 +1,207 @@
+<template>
+	<view class="page-container uni-column">
+		<view class="title uni-column" v-if="loggedUsers.length > 0">
+			<text>点击头像切换用户</text>
+		</view>
+
+		<view v-for="(item, index) in loggedUsers" class="item-user uni-row" @click="handleSelectUser(item)"
+			@longpress="handleLongPressUser(item)">
+			<view class="user-avatar uni-row"><text class="label">{{item['nickname']}}</text></view>
+			<view class="user-info">
+				<view class="nickname">
+					<text class="label">{{item['nickname']}}-{{index}}</text>
+				</view>
+				<view class="username">
+					<text class="label">{{item['userName']}}</text>
+				</view>
+			</view>
+		</view>
+		<view class="add-user-btn uni-row" @click="handleShowLoginDialog(null)">
+			<view class="icon uni-row">
+				<text class="label">+</text>
+			</view>
+			<view class="btn-label">
+				<text class="label">添加新账号</text>
+			</view>
+		</view>
+
+		<dialog-login ref="loginDialog" />
+	</view>
+</template>
+
+<script setup>
+	import {
+		onMounted,
+		ref
+	} from 'vue'
+	import {
+		onLoad,
+		onReady
+	} from '@dcloudio/uni-app'
+
+	// 登录过的用户
+	const loggedUsers = ref([])
+	const loginDialog = ref(null)
+
+	onLoad(() => {
+		init();
+	})
+
+	function init() {
+		uni.getStorageInfo({
+			success: function(res) {
+				console.log(res.keys)
+				for (let i = 0; i < res.keys.length; i++) {
+					let storagekey = res.keys[i];
+					console.log(storagekey)
+					uni.getStorage({
+						key: storagekey,
+						success: function(res) {
+							if (storagekey !== 'token' && storagekey !== '__DC_STAT_UUID') {
+								loggedUsers.value.push({
+									userName: storagekey,
+									password: res.data
+								})
+							}
+						}
+					});
+				}
+			}
+		});
+		console.log(loggedUsers)
+	}
+	const handleShowLoginDialog = (user) => {
+		let _user = user ?? {}
+		// 调用子组件中的方法
+		loginDialog.value.open(_user)
+	}
+	const handleSelectUser = (user) => {
+		console.log(user)
+		handleShowLoginDialog(user)
+	}
+	const handleLongPressUser = (user) => {
+		console.log(user)
+		uni.showModal({
+			title: '提示', // 标题
+			content: '是否删除此账号', // 提示内容
+			cancelText: "取消", // 取消按钮的文字
+			confirmText: "确认", // 确认按钮的文字
+			//点击确定之后执行的代码
+			success(res) {
+				if (res.confirm) {
+					uni.removeStorage({
+						key: user.userName, // 键名		
+						success: () => {
+							uni.showToast({
+								title: '删除成功',
+								icon: 'success',
+								duration: 3000,
+							});
+							loggedUsers.value = [];
+							init();
+							
+							
+						}, // 成功回调函数
+
+						fail: () => {
+
+						}, // 失败回调函数
+
+					})
+				}
+			}
+		});
+
+	}
+	const handleAddUser = () => {
+		uni.setStorage({
+			key: 'logged-users',
+			data: {
+				users: ''
+			},
+			success: () => {
+				console.log('success');
+			}
+		})
+	}
+</script>
+
+<style lang="scss">
+	.title {
+		height: 128rpx;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.item-user {
+		margin: 32rpx;
+		margin-top: 0;
+		padding: 32rpx;
+		background-color: #FFFFFF;
+		align-items: center;
+
+		.user-avatar {
+			width: 128rpx;
+			height: 128rpx;
+			border-radius: 64rpx;
+			background-color: #F1F2F3;
+			justify-content: center;
+			align-items: center;
+
+			.label {
+				font-size: 64rpx;
+			}
+		}
+
+		.user-info {
+			flex: 1;
+			height: 96rpx;
+			padding-left: 32rpx;
+
+			.nickname {
+				.label {
+					font-weight: bold;
+					font-size: 40rpx;
+				}
+			}
+
+			.username {
+				margin-top: 8rpx;
+
+				.label {
+					font-size: 32rpx;
+				}
+			}
+		}
+	}
+
+	.add-user-btn {
+		margin: 32rpx;
+		padding: 32rpx;
+		background-color: #FFFFFF;
+		align-items: center;
+
+		.icon {
+			width: 128rpx;
+			height: 128rpx;
+			align-items: center;
+			justify-content: center;
+			background-color: #F1F2F3;
+			border-radius: 64rpx;
+
+			.label {
+				color: #FFFFFF;
+				font-size: 128rpx;
+			}
+		}
+
+		.btn-label {
+			flex: 1;
+			padding-left: 32rpx;
+
+			.label {
+				font-size: 40rpx;
+			}
+		}
+	}
+</style>

+ 155 - 0
pages/productionPlan/index.vue

@@ -0,0 +1,155 @@
+<template>
+	<view class="uni-column" style="padding: 24rpx;">
+		<view v-for="(item, index) in listData" :key="index" class="list-item">
+			<view class="title-container uni-row">
+				<view class="title uni-row">
+					<text class="label">生产计划单号</text>
+					<text class="label code">{{ item['productionPlanNo'] }}</text>
+				</view>
+				<view v-if="item['status']" class="tag"><text class="label">进行中</text></view>
+				<view v-else type="default" class="tag not-start"><text class="label">未开始</text></view>
+			</view>
+			<!-- 			<view class="item-info uni-row">
+				<text class="label">当前工序</text>
+				<text class="label right">{{ item['process'] }}</text>
+			</view> -->
+			<view class="item-info uni-row">
+				<text class="label">产品描述</text>
+				<text class="label right">{{ item['productDescription']}}</text>
+			</view>
+			<view class="item-info uni-row">
+				<text class="label">总批数</text>
+				<text class="label right">{{ item['batchNumber'] }}</text>
+			</view>
+			<view class="item-info uni-row">
+				<text class="label">完成批数</text>
+				<text class="label right">{{ item['equiment']}}</text>
+			</view>
+			<view class="item-info uni-row">
+				<text class="label">投产数/合格数</text>
+				<text class="label right">{{ item['qualifiedQuantity'] }}/{{item['invest']}}</text>
+			</view>
+			<view class="item-info uni-row">
+				<text class="label">设备</text>
+				<text class="label right">{{ item['equiment']}}</text>
+			</view>
+			<!-- 			<view class="item-info uni-row">
+				<text class="label">操作人</text>
+				<text class="label right">{{ item['operator'] }}</text>
+			</view> -->
+		</view>
+	</view>
+</template>
+
+<script setup>
+	import {
+		getSubPlanDetailsList
+	} from '../../api/business/subPlanDetails'
+	import {
+		ref
+	} from 'vue'
+	import {
+		onReady,
+		onLoad
+	} from '@dcloudio/uni-app'
+	import { getToken } from '@/utils/auth'
+	
+
+	const listData = ref([])
+	onLoad(() => {
+		init();
+	})  
+
+	function init(){
+		getSubPlanDetailsList({}).then(res => {
+			console.log(res)
+			listData.value = res.rows;
+		})
+
+		// let token = 'Bearer ' + getToken();
+		// let reqHeader = {
+		//   'Authorization': token
+		// }
+		// console.log(reqHeader)	
+		// console.log(getToken())
+		// uni.request({
+		// 	url: 'http://localhost:8081/business/planDetailSubDetail/list',
+		// 	header: reqHeader,
+		// 	method: 'get',
+		// }).then( res => {
+		// 	console.log(res)
+		// 	listData.value = res.data.rows;
+		// }) 
+	} 
+	
+</script>
+
+<style lang="scss">
+	.uni-column {
+		background-color: rgba(245, 245, 245, 1);
+	}
+
+	.list-item {
+		background-color: #fff;
+		position: relative;
+		padding: 16rpx;
+		padding-bottom: 24rpx;
+		margin-bottom: 24rpx;
+
+		.title-container {
+			justify-content: space-between;
+			margin-top: 8rpx;
+			margin-bottom: 16rpx;
+
+			.title {
+				height: 48rpx;
+				align-items: center;
+
+				.label {
+					font-size: 32rpx;
+					font-weight: bold;
+
+					&.code {
+						margin-left: 8rpx;
+					}
+				}
+			}
+
+			.tag {
+				border: 1px solid #1CE5B0;
+				background-color: #F6FFFD;
+				padding: 8rpx;
+				border-radius: 8rpx;
+
+				.label {
+					color: #1CE5B0;
+					font-size: 24rpx;
+				}
+
+				&.not-start {
+					border: 1px solid #BBBBBB;
+					background-color: #F5F5F5;
+
+					.label {
+						color: #BBBBBB;
+					}
+				}
+			}
+		}
+
+		.item-info {
+			margin-bottom: 8rpx;
+
+			.label {
+				font-size: 28rpx;
+				width: 220rpx;
+				color: #808080;
+
+				&.right {
+					flex: 1;
+					color: #000000;
+				}
+			}
+		}
+	}
+</style>

+ 186 - 0
pages/recerptSfprod/index.vue

@@ -0,0 +1,186 @@
+<template>
+
+	<view class='container '>
+		<view class='content'>
+			<text class='title'>{{title}}</text>
+			<view class='item-table' scroll-y v-for="(item,index) in products" :key='index'>
+				<view class="uni-row table-layout">
+					<text class='tbhead left'>产品描述</text>
+					<text class='tbhead right'>{{item['description']}}</text>
+				</view>
+				<view class="uni-row table-layout">
+					<text class='tbbody left'>批次</text>
+					<text class='tbbody right'>{{item['batch']}}</Text>
+				</view>
+				<view class="uni-row table-layout">
+					<text class='tbbody left'>箱数</text>
+					<text class='tbbody right'>{{item['cases']}}</Text>
+				</view>
+				<view class="uni-row table-layout">
+					<text class='tbbody  left' style="height: 100%;">箱号</text>
+					<text class='last-tbbody right'>{{item['boxno']}}</text>
+				</view>
+
+			</view>
+		</view>
+		<view class='btn uni-row'>
+			<button class='bottom-btn left-btn'>取消</button>
+			<button class='bottom-btn right-btn' type="primary">确定接收</button>
+		</view>
+	</view>
+</template>
+<script setup>
+	import {
+		ref
+	} from 'vue'
+	import {
+		onLoad,
+		onReady
+	} from '@dcloudio/uni-app'
+	onLoad(() => {
+		for (let i = 0; i < products.value.length; i++) {
+			sum.value += parseInt(products.value[i]['cases'].toString());
+		}
+		// this.title = '热处理' + this.sum + '箱'
+		title.value = '热处理' + sum.value + '箱'
+	})
+	const title = ref('热处理')
+	const sum = ref(0)
+	const products = ref([{
+			description: '博士_0395614149_15*110.1',
+			batch: 'DC23727410070',
+			cases: 5,
+			boxno: 'X12522、X552222、X15522、J5211、J5112、X12522、X552222、X15522、J5211、J5112'
+		},
+		{
+			description: '博士_0395614149_15*110.1',
+			batch: 'DC23727410070',
+			cases: 5,
+			boxno: 'X12522、X552222、X15522、J5211、J5112'
+		},
+		{
+			description: '博士_0395614149_15*110.1',
+			batch: 'DC23727410070',
+			cases: 5,
+			boxno: 'X12522、X552222、X15522、J5211、J5112'
+		},
+		{
+			description: '博士_0395614149_15*110.1',
+			batch: 'DC23727410070',
+			cases: 5,
+			boxno: 'X12522、X552222、X15522、J5211、J5112'
+		},
+		{
+			description: '博士_0395614149_15*110.1',
+			batch: 'DC23727410070',
+			cases: 5,
+			boxno: 'X12522、X552222、X15522、J5211、J5112'
+		},
+		{
+			description: '博士_0395614149_15*110.1',
+			batch: 'DC23727410070',
+			cases: 5,
+			boxno: 'X12522、X552222、X15522、J5211、J5112'
+		}
+	])
+</script>
+
+<style lang="scss">
+	.container {
+		height: 100%;
+		overflow: auto;
+		background-color: rgba(245, 245, 245, 1);
+
+		.content {
+			width: 94%;
+			/* height: auto; */
+			background-color: rgba(255, 255, 255, 1);
+			margin: 50rpx auto;
+			padding-bottom: 144rpx;
+			border-radius: 12rpx;
+
+			.title {
+				margin: 10rpx auto;
+				width: 90%;
+				font-size: 36rpx;
+				font-weight: bold;
+			}
+
+			.item-table {
+				margin: 10rpx auto;
+				width: 90%;
+
+				.table-layout {
+					background-color: rgba(236, 245, 255, 1);
+					align-items: center;
+
+					.tbhead {
+						background-color: rgba(236, 245, 255, 1);
+						font-size: 28rpx;
+						height: 56rpx;
+						line-height: 56rpx;
+						padding-left: 6rpx;
+						border-bottom: 1px solid lightgray;
+					}
+
+					.tbbody {
+						font-size: 28rpx;
+						background-color: rgba(238, 240, 245, 1);
+						width: 70%;
+						height: 56rpx;
+						line-height: 56rpx;
+						padding-left: 6rpx;
+						border-bottom: 1px solid lightgray;
+					}
+
+					.left {
+						color: rgba(136, 136, 136, 1);
+						flex: 1;
+					}
+
+					.right {
+						flex: 3;
+					}
+
+					.last-tbbody {
+						font-size: 28rpx;
+						background-color: rgba(238, 240, 245, 1);
+						width: 70%;
+						height: 100%;
+						align-items: center;
+						border-bottom: 1px solid lightgray;
+					}
+
+				}
+			}
+		}
+
+		.btn {
+			position: fixed;
+			right: 0;
+			bottom: 0;
+			left: 0;
+			height: 100rpx;
+			padding: 16rpx 24rpx;
+			align-items: center;
+			background-color: #FFFFFF;
+			justify-content: space-between;
+
+			.bottom-btn {
+				flex: 1;
+				font-size: 28rpx;
+				color: #FFFFFF;
+
+				&.left-btn {
+					background-color: #a4adb3;
+				}
+
+				&.right-btn {
+					background-color: #1684fc;
+					margin-left: 24rpx;
+
+				}
+			}
+		}
+	}
+</style>

+ 270 - 0
pages/reportingForWork/index.vue

@@ -0,0 +1,270 @@
+<template>
+	<view class="uni-column" style="height: 100%; background-color: #f5f5f5;">
+		<scroll-view class="scroll-container" scroll-y>
+			<view v-for="(item, index) in listData" :key="index"
+				:class="{'list-item':true,'selected':isSelected(index)}" @click="handleSelection(item,index)">
+				<view class="title-container uni-row">
+					<view class="title uni-row">
+						<text class="label">设备:</text>
+						<text class="label code">{{ item['equipment'] }}</text>
+					</view>
+					<view class="right-info uni-row">
+						<view class="right-info uni-row"> <text class="label ">工时</text>
+							<text class="label time">{{ item['taskTime'] }}h</text>
+						</view>
+						<view class="right-info uni-row" style="margin-left:32px;"> <text class="label">合格数</text>
+							<text class="label number ">{{ item['qualifiedQuantity'] }}</text>
+						</view>
+					</view>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">操作者</text>
+					<text class="label right">{{ item['operator'] }}</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">开始时间</text>
+					<text class="label right">{{ item['startTime']}}</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">结束时间</text>
+					<text class="label right">{{ (item['endTime'] !="")?item['endTime']:'-'}}</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">废品数</text>
+					<text class="label right">{{ item['rejectNumber']}}</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">废品原因</text>
+					<text class="label right">{{ (item['refectReason'] != "")?item['refectReason']:'-'}}</text>
+				</view>
+
+				<view v-if="item['status'] == 0" class="status-btn uni-row ">
+					<button class="finished-turnover-tag" size="mini"
+						@click="handleShowEndWorkDialog(null)">结束报工</button>
+				</view>
+			</view>
+		</scroll-view>
+		<view class="bottom uni-row">
+			<button class="bottom-btn left-btn "><text class="label">更换载具</text></button>
+			<button class="bottom-btn right-btn"><text class="label">开始加工</text></button>
+		</view>
+		<dialog-end-work ref="endWorkDialog" />
+	</view>
+
+
+</template>
+
+<script setup>
+	import {
+		ref
+	} from 'vue'
+	import {
+		onLoad,
+		onReady
+	} from '@dcloudio/uni-app'
+	const listData = ref([{
+			equipment: "051-7",
+			taskTime: 2.8,
+			qualifiedQuantity: 0,
+			operator: "张三",
+			jobNumber: 15223,
+			startTime: "2023.05.06 14:23",
+			endTime: "",
+			rejectNumber: 0,
+			refectReason: "*******",
+			status: 0
+		},
+		{
+			equipment: "051-7",
+			taskTime: 3.6,
+			qualifiedQuantity: 300,
+			operator: "张三",
+			jobNumber: 15223,
+			startTime: "2023.05.06 14:23",
+			endTime: "2023.05.06 18:23",
+			rejectNumber: 0,
+			refectReason: "",
+			status: 1
+		},
+		{
+			equipment: "051-7",
+			taskTime: 3.6,
+			qualifiedQuantity: 300,
+			operator: "张三",
+			jobNumber: 15223,
+			startTime: "2023.05.06 14:23",
+			endTime: "2023.05.06 18:23",
+			rejectNumber: 0,
+			refectReason: "",
+			status: 1
+		},
+		{
+			equipment: "051-7",
+			taskTime: 3.6,
+			qualifiedQuantity: 300,
+			operator: "张三",
+			jobNumber: 15223,
+			startTime: "2023.05.06 14:23",
+			endTime: "2023.05.06 18:23",
+			rejectNumber: 0,
+			refectReason: "",
+			status: 0
+		},
+		{
+			equipment: "051-7",
+			taskTime: 3.6,
+			qualifiedQuantity: 300,
+			operator: "张三",
+			jobNumber: 15223,
+			startTime: "2023.05.06 14:23",
+			endTime: "2023.05.06 18:23",
+			rejectNumber: 0,
+			refectReason: "",
+			status: 1
+		}
+
+	])
+	const selection = ref([])
+	const endWorkDialog = ref(null)
+	const isSelected = (index) => {
+		return selection.value.includes(index)
+	}
+	const handleSelection = (item,index) => {
+		const buttonIndex = selection.value.indexOf(index);
+		if (buttonIndex > -1) {
+			selection.value.splice(buttonIndex, 1); // 取消选中
+		} else {
+			selection.value.push(index); // 选中
+		}
+	}
+	const handleShowEndWorkDialog = (data) => {
+		let _data = data ?? {}
+		// 调用子组件中的方法
+		endWorkDialog.value.open(_data)
+	}
+</script>
+
+<style lang="scss">
+	.scroll-container {
+		position: absolute;
+		top: 24rpx;
+		right: 0;
+		bottom: 144rpx;
+		left: 0;
+	}
+
+	.selected {
+		border: 1px solid #1684fc;
+	}
+
+	.list-item {
+		background-color: #fff;
+		position: relative;
+		padding: 16rpx;
+		padding-bottom: 24rpx;
+		margin: 0 24rpx;
+		margin-bottom: 24rpx;
+		border-radius: 8rpx;
+
+		.title-container {
+			justify-content: space-between;
+			margin-top: 8rpx;
+			margin-bottom: 16rpx;
+
+			.title {
+				height: 48rpx;
+				align-items: center;
+
+				.label {
+					font-size: 32rpx;
+					font-weight: bold;
+
+					&.code {
+						margin-left: 8rpx;
+					}
+				}
+			}
+		}
+
+		.item-info {
+			margin-bottom: 8rpx;
+
+			.label {
+				font-size: 28rpx;
+				width: 152rpx;
+				color: #808080;
+
+				&.right {
+					flex: 1;
+					color: #000000;
+				}
+			}
+		}
+
+		.right-info {
+			justify-content: flex-end;
+			margin-top: 5rpx;
+
+			.label {
+				font-size: 28rpx;
+
+				color: #000000;
+
+				&.time {
+					margin-left: 8rpx;
+					color: #1684fc;
+
+				}
+
+				&.number {
+					margin-left: 8rpx;
+					color: rgba(0, 226, 166, 1);
+				}
+
+			}
+		}
+	}
+
+	.bottom {
+		position: absolute;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		height: 100rpx;
+		padding: 16rpx 24rpx;
+		align-items: center;
+		background-color: #FFFFFF;
+		justify-content: space-between;
+
+		.bottom-btn {
+			flex: 1;
+			font-size: 28rpx;
+			color: #FFFFFF;
+
+			&.left-btn {
+				background-color: #1684fc;
+			}
+
+			&.right-btn {
+				background-color: rgb(255, 121, 1);
+				margin-left: 24rpx;
+
+			}
+		}
+	}
+
+	.status-btn {
+		width: 100%;
+		justify-content: flex-end;
+
+		.finished-turnover-tag {
+			margin: unset;
+
+			border-radius: 8rpx;
+			background-color: rgb(255, 85, 85);
+			font-size: 28rpx;
+			color: #FFFFFF;
+
+		}
+	}
+</style>

+ 230 - 0
pages/startTurnover/index.vue

@@ -0,0 +1,230 @@
+<template>
+	<view class="uni-column" style="height: 100%; background-color: #f5f5f5;">
+		<scroll-view class="scroll-container" scroll-y>
+			<view v-for="(item, index) in listData" :key="index" :class="{'list-item':true,'selected':isSelected(index)}"
+				@click="handleSelection(index)">
+				<view class="title-container uni-row">
+					<view class="title uni-row">
+						<text class="label">{{ item['door'] }}</text>
+						<text class="label code">{{ item['process'] }}</text>
+						<text class="label code" style="margin-left: 16rpx;">→</text>
+						<text class="label code" style="margin-left: 16rpx;">{{ item['car'] }}</text>
+					</view>
+
+					<view class="right-info uni-row">
+						<view class="uni-row"><text class="label right">删除</text></view>
+					</view>
+				</view>
+				<view class="item-info uni-row"> <text class="label ">产品描述</text>
+					<text class="label right" style="color: #000000;">{{ item['description'] }}</text>
+				</view>
+				<view class="item-info uni-row"> <text class="label">批次</text>
+					<text class="label right ">{{ item['batch'] }}</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">箱数</text>
+					<text class="label right">{{ item['cases'] }}</text>
+				</view>
+				<view class="item-info uni-row">
+					<text class="label">箱号</text>
+					<text class="label right">{{ item['caseNumber']}}</text>
+				</view>
+			</view>
+		</scroll-view>
+		<view class="bottom uni-row">
+			<button class="bottom-btn left-btn ">继续扫码</button>
+			<button class="bottom-btn right-btn" @click="handleTurnoverTask(null)">确认周转</button>
+		</view>
+		<dialog-turnoverTask ref="turnoverTaskDialog" />
+	</view>
+
+
+</template>
+
+<script setup>
+	import {
+		ref
+	} from 'vue'
+	import {
+		onLoad,
+		onReady
+	} from '@dcloudio/uni-app'
+
+
+	onLoad(() => {
+
+	})
+	const active = ref(false)
+	const selection =ref([])
+	const turnoverTaskDialog = ref(null)
+	const listData = ref([{
+			door: "A门",
+			process: "粗磨",
+			car: "NC车",
+			description: "万博_039561419_15*110.1",
+			batch: "DC23727410070",
+			cases: 5,
+			caseNumber: "X12522、X55222、X15522、J5211、J5211"
+
+		},
+		{
+			door: "A门",
+			process: "粗磨",
+			car: "NC车",
+			description: "万博_039561419_15*110.1",
+			batch: "DC23727410070",
+			cases: 5,
+			caseNumber: "X12522、X55222、X15522、J5211、J5211"
+
+		},
+		{
+			door: "A门",
+			process: "粗磨",
+			car: "NC车",
+			description: "万博_039561419_15*110.1",
+			batch: "DC23727410070",
+			cases: 5,
+			caseNumber: "X12522、X55222、X15522、J5211、J5211"
+
+		},
+		{
+			door: "A门",
+			process: "粗磨",
+			car: "NC车",
+			description: "万博_039561419_15*110.1",
+			batch: "DC23727410070",
+			cases: 5,
+			caseNumber: "X12522、X55222、X15522、J5211、J5211"
+
+		},
+		{
+			door: "A门",
+			process: "粗磨",
+			car: "NC车",
+			description: "万博_039561419_15*110.1",
+			batch: "DC23727410070",
+			cases: 5,
+			caseNumber: "X12522、X55222、X15522、J5211、J5211"
+
+		}
+
+	])
+	const handleStartTurnover = (data) => {
+		let _data = data ?? {}
+		// 调用子组件中的方法
+		turnoverTaskDialog.value.open(_data)
+	}
+	const isSelected = (index) => {
+	return	selection.value.includes(index)
+	}
+	const handleSelection = (index) => {
+		console.log(index)
+		
+		  const buttonIndex = selection.value.indexOf(index);
+		      if (buttonIndex > -1) {
+		        selection.value.splice(buttonIndex, 1); // 取消选中
+		      } else {
+		        selection.value.push(index); // 选中
+		      }
+			  console.log(selection.value)
+	}
+</script>
+
+<style lang="scss">
+	.scroll-container {
+		position: absolute;
+		top: 24rpx;
+		right: 0;
+		bottom: 160rpx;
+		left: 0;
+	}
+
+	.selected {
+		border: 1px solid #1684fc;
+	}
+
+	.list-item {
+		background-color: #fff;
+		position: relative;
+		padding: 16rpx;
+		padding-bottom: 24rpx;
+		margin: 0 24rpx;
+		margin-bottom: 24rpx;
+		border-radius: 8rpx;
+
+		.title-container {
+			justify-content: space-between;
+			margin-top: 8rpx;
+			margin-bottom: 16rpx;
+
+			.title {
+				height: 48rpx;
+				align-items: center;
+
+				.label {
+					color: #1684fc;
+					font-size: 32rpx;
+					font-weight: bold;
+
+					&.code {
+						color: #000000;
+						margin-left: 32rpx;
+					}
+				}
+			}
+		}
+
+		.item-info {
+			margin-bottom: 16rpx;
+
+			.label {
+				font-size: 28rpx;
+				width: 152rpx;
+				color: #808080;
+
+				&.right {
+					flex: 1;
+					color: #808080;
+				}
+			}
+		}
+
+		.right-info {
+			justify-content: flex-end;
+			margin-top: 2rpx;
+
+			.label {
+				font-size: 28rpx;
+				color: #ff0000;
+			}
+		}
+	}
+
+	.bottom {
+		position: absolute;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		height: 100rpx;
+		padding: 16rpx 24rpx;
+		align-items: center;
+		background-color: #FFFFFF;
+		justify-content: space-between;
+
+		.bottom-btn {
+			flex: 1;
+			font-size: 28rpx;
+			color: #FFFFFF;
+
+			&.left-btn {
+				background-color: #1684fc;
+			}
+
+			&.right-btn {
+				background-color: rgb(255, 121, 1);
+				margin-left: 24rpx;
+
+			}
+		}
+	}
+</style>

二进制
static/convert.png


+ 15 - 0
static/css/global.css

@@ -0,0 +1,15 @@
+view {
+	position: relative;
+	display: flex !important;
+	flex-direction: column;
+}
+.page-container {
+}
+/*每个页面公共css */
+.uni-row {
+	flex-direction: row;
+}
+
+.uni-column {
+	flex-direction: column;
+}

二进制
static/images/login-dialog-close-icon.png


二进制
static/images/logo.png


二进制
static/screen.png


+ 10 - 0
uni.promisify.adaptor.js

@@ -0,0 +1,10 @@
+uni.addInterceptor({
+  returnValue (res) {
+    if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
+      return res;
+    }
+    return new Promise((resolve, reject) => {
+      res.then((res) => res[0] ? reject(res[0]) : resolve(res[1]));
+    });
+  },
+});

+ 76 - 0
uni.scss

@@ -0,0 +1,76 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:12px;
+$uni-font-size-base:14px;
+$uni-font-size-lg:16;
+
+/* 图片尺寸 */
+$uni-img-size-sm:20px;
+$uni-img-size-base:26px;
+$uni-img-size-lg:40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 2px;
+$uni-border-radius-base: 3px;
+$uni-border-radius-lg: 6px;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 4px;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 12px;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:20px;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:26px;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:15px;

+ 20 - 0
utils/auth.js

@@ -0,0 +1,20 @@
+const TokenKey = 'token'
+
+export function getToken() {
+	let token = '';
+	uni.getStorage({
+		key: TokenKey,
+		success: function(res) {
+			token = res.data;
+		}
+	});
+	return token;
+}
+
+export function setToken(token) {
+	return uni.setStorageSync(TokenKey, token)
+}
+
+export function removeToken() {
+	return uni.removeStorageSync(TokenKey)
+}

+ 54 - 0
utils/common.js

@@ -0,0 +1,54 @@
+/**
+* 显示消息提示框
+* @param content 提示的标题
+*/
+export function toast(content) {
+  uni.showToast({
+    icon: 'none',
+    title: content
+  })
+}
+
+/**
+* 显示模态弹窗
+* @param content 提示的标题
+*/
+export function showConfirm(content) {
+  return new Promise((resolve, reject) => {
+    uni.showModal({
+      title: '提示',
+      content: content,
+      cancelText: '取消',
+      confirmText: '确定',
+      success: function(res) {
+        resolve(res)
+      }
+    })
+  })
+}
+
+/**
+* 参数处理
+* @param params 参数
+*/
+export function tansParams(params) {
+  let result = ''
+  for (const propName of Object.keys(params)) {
+    const value = params[propName]
+    var part = encodeURIComponent(propName) + "="
+    if (value !== null && value !== "" && typeof (value) !== "undefined") {
+      if (typeof value === 'object') {
+        for (const key of Object.keys(value)) {
+          if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
+            let params = propName + '[' + key + ']'
+            var subPart = encodeURIComponent(params) + "="
+            result += subPart + encodeURIComponent(value[key]) + "&"
+          }
+        }
+      } else {
+        result += part + encodeURIComponent(value) + "&"
+      }
+    }
+  }
+  return result
+}

+ 6 - 0
utils/errorCode.js

@@ -0,0 +1,6 @@
+export default {
+  '401': '认证失败,无法访问系统资源',
+  '403': '当前操作没有权限',
+  '404': '访问资源不存在',
+  'default': '系统未知错误,请反馈给管理员'
+}

+ 55 - 0
utils/request.js

@@ -0,0 +1,55 @@
+import { getToken } from '@/utils/auth'
+import baseURL from '@/api/base/path.js'
+
+let timeout = 6000;
+
+let token = 'Bearer ' + getToken();
+
+function request({url, data, method="GET"}) {
+	let header = {
+	    'Authorization': token
+	}
+	return new Promise((resolve, reject)=>{
+		uni.request({
+			url: baseURL + url,
+			data,
+			method,
+			header,
+			success: (res) => {
+				if (res.statusCode === 200) {
+					//请求成功
+					resolve(res.data);
+				} else if (res.statusCode === 401) {
+					uni.showToast({
+						icon: 'none',
+						title: "未登录或登录状态已超时",
+						duration: 1500
+					});
+				} else if (res.statusCode === 405) {
+					uni.showToast({
+						icon: 'none',
+						title: "请求方法错误",
+						duration: 1500
+					});
+				} else {
+					uni.showToast({
+						icon: 'none',
+						title: "请求错误:" + res.statusCode,
+						duration: 1500
+					});
+				}
+			},
+			fail: (err) => {
+				console.log("err:", err)
+				uni.showToast({
+					icon: 'none',
+					title: err.errMsg,
+					duration: 1500
+				});
+				reject(err);
+			}
+		})
+	})
+}
+export default {request}
+

+ 263 - 0
utils/ruoyi.js

@@ -0,0 +1,263 @@
+/**
+ * 通用js方法封装处理
+ * Copyright (c) 2019 ruoyi
+ */
+
+// 日期格式化
+export function parseTime(time, pattern) {
+	if (arguments.length === 0 || !time) {
+		return null
+	}
+	const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
+	let date
+	if (typeof time === 'object') {
+		date = time
+	} else {
+		if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
+			time = parseInt(time)
+		} else if (typeof time === 'string') {
+			time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
+		}
+		if ((typeof time === 'number') && (time.toString().length === 10)) {
+			time = time * 1000
+		}
+		date = new Date(time)
+	}
+	const formatObj = {
+		y: date.getFullYear(),
+		m: date.getMonth() + 1,
+		d: date.getDate(),
+		h: date.getHours(),
+		i: date.getMinutes(),
+		s: date.getSeconds(),
+		a: date.getDay()
+	}
+	const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+		let value = formatObj[key]
+		// Note: getDay() returns 0 on Sunday
+		if (key === 'a') {
+			return ['日', '一', '二', '三', '四', '五', '六'][value]
+		}
+		if (result.length > 0 && value < 10) {
+			value = '0' + value
+		}
+		return value || 0
+	})
+	return time_str
+}
+
+// 表单重置
+export function resetForm(refName) {
+	if (this.$refs[refName]) {
+		this.$refs[refName].resetFields();
+	}
+}
+
+// 添加日期范围
+export function addDateRange(params, dateRange, propName) {
+	let search = params;
+	search.params = typeof(search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ?
+		search.params : {};
+	dateRange = Array.isArray(dateRange) ? dateRange : [];
+	if (typeof(propName) === 'undefined') {
+		search.params['beginTime'] = dateRange[0];
+		search.params['endTime'] = dateRange[1];
+	} else {
+		search.params['begin' + propName] = dateRange[0];
+		search.params['end' + propName] = dateRange[1];
+	}
+	return search;
+}
+
+// 回显数据字典
+export function selectDictLabel(datas, value) {
+	if (value === undefined) {
+		return "";
+	}
+	var actions = [];
+	Object.keys(datas).some((key) => {
+		if (datas[key].value == ('' + value)) {
+			actions.push(datas[key].label);
+			return true;
+		}
+	})
+	if (actions.length === 0) {
+		actions.push(value);
+	}
+	return actions.join('');
+}
+
+/**格式化 字典数据 符合下拉框 格式 */
+export function formatDictOptions(list) {
+	const range = []
+	list.forEach(l => {
+		let dict = {}
+		dict.value = l.dictLabel
+		dict.text = l.dictLabel
+		range.push(dict)
+	})
+	return range
+}
+
+/**格式化 设备数据 符合下拉框 */
+export function formatEquipmentOptions(list) {
+	const range = []
+	list.forEach(l => {
+		let dict = {}
+		dict.value = l.id
+		dict.text = l.bizEquipmentName + '-' + l.code
+		range.push(dict)
+	})
+	return range
+}
+
+// 回显数据字典(字符串数组)
+export function selectDictLabels(datas, value, separator) {
+	if (value === undefined) {
+		return "";
+	}
+	var actions = [];
+	var currentSeparator = undefined === separator ? "," : separator;
+	var temp = value.split(currentSeparator);
+	Object.keys(value.split(currentSeparator)).some((val) => {
+		var match = false;
+		Object.keys(datas).some((key) => {
+			if (datas[key].value == ('' + temp[val])) {
+				actions.push(datas[key].label + currentSeparator);
+				match = true;
+			}
+		})
+		if (!match) {
+			actions.push(temp[val] + currentSeparator);
+		}
+	})
+	return actions.join('').substring(0, actions.join('').length - 1);
+}
+
+// 字符串格式化(%s )
+export function sprintf(str) {
+	var args = arguments,
+		flag = true,
+		i = 1;
+	str = str.replace(/%s/g, function() {
+		var arg = args[i++];
+		if (typeof arg === 'undefined') {
+			flag = false;
+			return '';
+		}
+		return arg;
+	});
+	return flag ? str : '';
+}
+
+// 转换字符串,undefined,null等转化为""
+export function parseStrEmpty(str) {
+	if (!str || str == "undefined" || str == "null") {
+		return "";
+	}
+	return str;
+}
+
+// 数据合并
+export function mergeRecursive(source, target) {
+	for (var p in target) {
+		try {
+			if (target[p].constructor == Object) {
+				source[p] = mergeRecursive(source[p], target[p]);
+			} else {
+				source[p] = target[p];
+			}
+		} catch (e) {
+			source[p] = target[p];
+		}
+	}
+	return source;
+};
+
+/**
+ * 构造树型结构数据
+ * @param {*} data 数据源
+ * @param {*} id id字段 默认 'id'
+ * @param {*} parentId 父节点字段 默认 'parentId'
+ * @param {*} children 孩子节点字段 默认 'children'
+ */
+export function handleTree(data, id, parentId, children) {
+	let config = {
+		id: id || 'id',
+		parentId: parentId || 'parentId',
+		childrenList: children || 'children'
+	};
+
+	var childrenListMap = {};
+	var nodeIds = {};
+	var tree = [];
+
+	for (let d of data) {
+		let parentId = d[config.parentId];
+		if (childrenListMap[parentId] == null) {
+			childrenListMap[parentId] = [];
+		}
+		nodeIds[d[config.id]] = d;
+		childrenListMap[parentId].push(d);
+	}
+
+	for (let d of data) {
+		let parentId = d[config.parentId];
+		if (nodeIds[parentId] == null) {
+			tree.push(d);
+		}
+	}
+
+	for (let t of tree) {
+		adaptToChildrenList(t);
+	}
+
+	function adaptToChildrenList(o) {
+		if (childrenListMap[o[config.id]] !== null) {
+			o[config.childrenList] = childrenListMap[o[config.id]];
+		}
+		if (o[config.childrenList]) {
+			for (let c of o[config.childrenList]) {
+				adaptToChildrenList(c);
+			}
+		}
+	}
+	return tree;
+}
+
+/**
+ * 参数处理
+ * @param {*} params  参数
+ */
+export function tansParams(params) {
+	let result = ''
+	for (const propName of Object.keys(params)) {
+		const value = params[propName];
+		var part = encodeURIComponent(propName) + "=";
+		if (value !== null && value !== "" && typeof(value) !== "undefined") {
+			if (typeof value === 'object') {
+				for (const key of Object.keys(value)) {
+					if (value[key] !== null && value[key] !== "" && typeof(value[key]) !== 'undefined') {
+						let params = propName + '[' + key + ']';
+						var subPart = encodeURIComponent(params) + "=";
+						result += subPart + encodeURIComponent(value[key]) + "&";
+					}
+				}
+			} else {
+				result += part + encodeURIComponent(value) + "&";
+			}
+		}
+	}
+	return result
+}
+
+// 验证是否为blob格式
+export async function blobValidate(data) {
+	try {
+		const text = await data.text();
+		JSON.parse(text);
+		return false;
+	} catch (error) {
+		return true;
+	}
+}

+ 33 - 0
utils/storage.js

@@ -0,0 +1,33 @@
+import constant from './constant'
+
+// 存储变量名
+let storageKey = 'storage_data'
+
+// 存储节点变量名
+let storageNodeKeys = [constant.avatar, constant.name, constant.roles, constant.permissions,constant.userList]
+
+// 存储的数据
+let storageData = uni.getStorageSync(storageKey) || {}
+
+const storage = {
+  set: function(key, value) {
+    if (storageNodeKeys.indexOf(key) != -1) {
+      let tmp = uni.getStorageSync(storageKey)
+      tmp = tmp ? tmp : {}
+      tmp[key] = value
+      uni.setStorageSync(storageKey, tmp)
+    }
+  },
+  get: function(key) {
+    return storageData[key] || ""
+  },
+  remove: function(key) {
+    delete storageData[key]
+    uni.setStorageSync(storageKey, storageData)
+  },
+  clean: function() {
+    uni.removeStorageSync(storageKey)
+  }
+}
+
+export default storage