This commit is contained in:
2026-03-06 16:50:46 +08:00
commit 0704be4c9f
249 changed files with 46365 additions and 0 deletions

View File

@@ -0,0 +1,223 @@
<template>
<view class="container">
<uv-notice-bar :text="dataList[0] || ''"></uv-notice-bar>
<view style="margin: 10rpx 0;display: flex;align-items: center;justify-content: space-between;">
<view>当前扫描到{{ dataList.length - 1 }}</view>
<view>总条目{{ scanTotal || "暂无" }}</view>
</view>
<uv-list>
<uv-list-item :title="item" v-for="(item, index) in dataList" :key="index" v-show="index > 0"></uv-list-item>
</uv-list>
<uv-button type="primary" text="确定" size="large" class="btn" @tap="startScan" v-show="status == 0">
</uv-button>
<uv-button type="primary" text="确定" size="large" class="btn" @tap="goMatch" v-show="status == 1"> </uv-button>
</view>
</template>
<script setup>
import { BASE_URL } from "@/api/request";
import { ref } from "vue";
import { onLoad, onUnload } from "@dcloudio/uni-app";
import { getScan, stopScan, getMatch, getTaskCount } from "@/api/inventory"
const deviceInfo = ref({})
const taskInfo = ref({})
const status = ref(0)
const taskModalRef = ref("")
const scanTotal = ref("")
const getTotal = () => {
let obj = {
taskId: taskInfo.value.id
}
getTaskCount(obj).then(res => {
scanTotal.value = res.data
})
}
// 开始盘点
const startScan = () => {
let obj = {
deviceId: deviceInfo.value.deviceId
}
getScan(obj).then(() => {
console.log("开始盘点")
status.value = 1
taskModalRef.value.close()
})
}
// 开始匹配
const goMatch = () => {
let list = JSON.parse(JSON.stringify(dataList.value))
let arr = list.splice(1)
let obj = {
ids: arr,
taskId: taskInfo.value.id,
deviceId: deviceInfo.value.deviceId,
}
getMatch(obj).then(res => {
console.log("保存数据")
stopTask(1)
})
}
const stopTask = (status) => {
console.log("停止")
let obj = {
deviceId: deviceInfo.value.deviceId,
showLoading: true
}
console.log("deviceId", deviceInfo.value.deviceId)
stopScan(obj).then(res => {
console.log("停止盘点")
if (status == 1) {
uni.hideLoading()
uni.redirectTo({
url: '/pagesInventory/matchResult?taskId=' + taskInfo.value.id
})
// uni.closeSocket()
}
if (status != 2) {
socketTask.value.close();
clearInterval(reconnectTimeOut.value)
}
})
}
const dataList = ref([])
const reconnectTimeOut = ref(null)
const isOpenSocket = ref(true)
const socketTask = ref(null)
const connectSocketInit = () => {
socketTask.value = uni.connectSocket({
url: BASE_URL + '/ws/socket',
success: () => {
console.log('WebSocket连接创建成功');
}
});
socketTask.value.onOpen(() => {
console.log('WebSocket连接已打开');
send()
});
socketTask.value.onError(() => {
console.log('WebSocket连接打开失败请检查', res)
reconnect()
})
socketTask.value.onClose(() => {
console.log('WebSocket连接已关闭');
});
socketTask.value.onMessage((res) => {
if (status.value == 0) {
stopTask(2)
}
uni.hideLoading()
if (((status.value == 0 && res.data.includes("连接")) || (status.value == 1 && !res.data.includes("连接"))) && !(dataList.value.some(e => e == res.data))) {
// if (((status.value == 0 && res.data.includes("连接")) || (status.value == 1 && !res.data.includes("连接"))) && !(dataList.value.some(e => e == res.data))) {
dataList.value.push(res.data)
console.log("存储", dataList.value)
}
})
}
const send = () => {
let obj = {
deviceId: deviceInfo.value.deviceId,
ip: deviceInfo.value.ipAddress,
port: deviceInfo.value.port
}
console.log("发送参数", obj)
socketTask.value.send({
data: JSON.stringify(obj)
})
}
//重新连接
const reconnect = () => {
console.log("重连")
//停止发送心跳
clearInterval(reconnectTimeOut.value)
//如果不是人为关闭的话,进行重连
if (isOpenSocket.value) {
reconnectTimeOut.value = setInterval(() => {
connectSocketInit();
}, 5000)
}
}
onLoad(() => {
deviceInfo.value = uni.getStorageSync("deviceInfo")
taskInfo.value = uni.getStorageSync("taskInfo")
connectSocketInit()
getTotal()
})
onUnload(() => {
console.log("销毁")
// uni.closeSocket()
stopTask(0)
})
</script>
<style scoped lang="scss">
.container {
padding: 32rpx;
position: relative;
.tableBox {
padding-bottom: 120rpx;
}
.paginationBox {
margin-top: 20rpx;
}
.btn {
// height: 100rpx;
position: fixed;
width: calc(100vw - 64rpx);
bottom: 0;
left: 32rpx;
z-index: 9999;
}
}
::v-deep .uni-select {
border: unset;
border-bottom: unset;
}
::v-deep .uv-popup .uv-popup__content {
overflow: unset !important;
}
::v-deep .uv-modal {
overflow: unset !important;
}
::v-deep .uv-input__content {
flex-direction: column;
align-items: flex-start;
}
::v-deep .uni-select__input-placeholder {
font-size: unset;
color: #c0c4cc;
}
::v-deep .uni-select {
padding: 0 !important;
}
</style>

101
pagesInventory/autoMenu.vue Normal file
View File

@@ -0,0 +1,101 @@
<template>
<view class="iconBox">
<view class="iconItem">
<view @tap="goDevice">
<view class="icon">
<image src="../static/iconfont/boundDevice.svg" mode="scaleToFill" />
</view>
<view class="text">设备绑定</view>
</view>
</view>
<view class="iconItem">
<view @tap="goInventory">
<view class="icon">
<image src="../static/iconfont/inventory.svg" mode="scaleToFill" />
</view>
<view class="text">仓库盘点</view>
</view>
</view>
<!-- <view class="iconItem">
<view @tap="goHistory">
<view class="icon">
<image src="../../static/iconfont/history.svg" mode="scaleToFill" />
</view>
<view class="text">盘点清单</view>
</view>
</view> -->
</view>
</template>
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
onLoad(() => {
})
const goDevice = () => {
uni.navigateTo({
url: '/pagesInventory/boundDevice',
})
}
const goInventory = () => {
if (uni.getStorageSync("deviceInfo") && Object.keys(uni.getStorageSync("deviceInfo")).length > 0) {
uni.navigateTo({
url: '/pagesInventory/autoInventory',
})
console.log("有数据")
} else {
console.log("无数据")
uni.showToast({
title: '请先去绑定设备',
icon: 'none'
})
}
}
const goHistory = () => {
uni.navigateTo({
url: '/pagesInventory/history',
})
}
</script>
<style scoped lang="scss">
.iconBox {
display: flex;
align-items: center;
flex-wrap: wrap;
.iconItem {
width: 25%;
display: flex;
align-items: center;
justify-items: center;
flex-direction: column;
margin: 20rpx 0;
.icon {
width: 110rpx;
height: 110rpx;
display: flex;
align-items: center;
justify-content: center;
// background: #199793;
// border-radius: 50%;
image {
width: 60rpx;
height: 60rpx;
}
}
.text {
margin-top: 14rpx;
font-size: 28rpx;
}
}
}
</style>

View File

@@ -0,0 +1,135 @@
<template>
<view class="container">
<view v-if="Object.keys(deviceInfo).length" style="margin-bottom: 20rpx;">当前设备地址:{{ deviceInfo.ipAddress + ":" +
deviceInfo.port }}({{ warehouseList[deviceInfo.warehouseId - 1].label }}) </view>
<view class="tableBox">
<uni-table ref="tableRef" :loading="deviceLoading" border stripe type="selection" emptyText="暂无更多数据"
@selection-change="selectionChange">
<uni-tr>
<uni-th align="center" width="100">设备IP地址</uni-th>
<uni-th align="center" width="100">设备端口</uni-th>
<uni-th align="center" width="100">所属仓库</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in tableData" :key="index">
<uni-td align="center">{{ item.ipAddress }}</uni-td>
<uni-td align="center">{{ item.port }}</uni-td>
<uni-td align="center">{{ warehouseList[item.warehouseId - 1].label }}</uni-td>
</uni-tr>
</uni-table>
<!-- <view class="paginationBox">
<uni-pagination show-icon :page-size="deviceParams.pageSize" :current="deviceParams.pageNum" :total="deviceTotal" @change="deviceChange" />
</view> -->
</view>
<uv-button type="primary" text="确定" size="large" class="btn" @tap="bindDevice"> </uv-button>
</view>
</template>
<script setup>
import { deviceList } from "@/api/device"
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
const tableRef = ref("")
// 当前页
const deviceParams = ref({
pageNum: 1,
pageSize: 100
})
// 数据总量
const deviceTotal = ref(0)
const deviceLoading = ref(false)
const warehouseList = ref([
{ value: 1, label: '1号仓库' },
{ value: 2, label: '2号仓库' },
{ value: 3, label: '3号仓库' },
{ value: 4, label: '4号仓库' },
{ value: 5, label: '5号仓库' }
]);
const tableData = ref([])
const selectedIndexs = ref([])
// 选择设备
const selectionChange = (e) => {
selectedIndexs.value = e.detail.index
}
// 获取列表
const getList = () => {
deviceList(deviceParams.value).then(res => {
if (deviceParams.value.pageNum == 1) {
tableData.value = res.rows
} else {
tableData.value = tableData.value.concat(res.rows)
}
deviceTotal.value = res.total
})
}
// 分页触发
const deviceChange = (e) => {
tableRef.value.clearSelection()
deviceParams.value.pageNum = e.current
getList()
}
const deviceInfo = ref({})
// 绑定设备
const bindDevice = () => {
console.log(selectedIndexs.value)
if (selectedIndexs.value.length == 0) {
uni.showToast({
title: '请至少选择一个设备绑定!',
icon: 'none'
});
} else if (selectedIndexs.value.length > 1) {
uni.showToast({
title: '只能选择一个设备绑定!',
icon: 'none'
});
} else {
uni.setStorageSync("deviceInfo", tableData.value[selectedIndexs.value[0]])
deviceInfo.value = tableData.value[selectedIndexs.value[0]]
}
}
// 判断是否绑定了设备
const judgeBinded = () => {
if (uni.getStorageSync("deviceInfo") && Object.keys(uni.getStorageSync("deviceInfo")).length > 0) {
deviceInfo.value = uni.getStorageSync("deviceInfo")
// uni.removeStorageSync('deviceInfo');
console.log("有数据")
} else {
console.log("无数据")
}
}
onLoad(() => {
judgeBinded()
getList()
})
</script>
<style scoped lang="scss">
.container {
padding: 32rpx;
position: relative;
.tableBox {
padding-bottom: 120rpx;
}
.paginationBox {
margin-top: 20rpx;
}
.btn {
position: fixed;
width: calc(100vw - 64rpx);
bottom: 0;
left: 32rpx;
z-index: 9999;
}
}
</style>

View File

@@ -0,0 +1,130 @@
<template>
<view class="container">
<view v-if="Object.keys(deviceInfo).length" style="margin-bottom: 20rpx;">当前设备地址:{{ deviceInfo.ipAddress + ":" +
deviceInfo.port }}({{ deviceInfo.warehouseName }}) </view>
<view class="tableBox">
<uni-table ref="tableRef" :loading="deviceLoading" border stripe type="selection" emptyText="暂无更多数据"
@selection-change="selectionChange">
<uni-tr>
<uni-th align="center" width="100">设备IP地址</uni-th>
<uni-th align="center" width="100">设备端口</uni-th>
<uni-th align="center" width="100">所属仓库</uni-th>
<uni-th align="center" width="100">所属场景</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in tableData" :key="index">
<uni-td align="center">{{ item.ipAddress }}</uni-td>
<uni-td align="center">{{ item.port }}</uni-td>
<uni-td align="center">{{ item.warehouseName }}</uni-td>
<uni-td align="center">{{ item.sceneName }}</uni-td>
</uni-tr>
</uni-table>
<!-- <view class="paginationBox">
<uni-pagination show-icon :page-size="deviceParams.pageSize" :current="deviceParams.pageNum" :total="deviceTotal" @change="deviceChange" />
</view> -->
</view>
<uv-button type="primary" text="确定" size="large" class="btn mainBtn" @tap="bindDevice"> </uv-button>
</view>
</template>
<script setup>
import { deviceList } from "@/api/device"
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
const tableRef = ref("")
// 当前页
const deviceParams = ref({
pageNum: 1,
pageSize: 100
})
// 数据总量
const deviceTotal = ref(0)
const deviceLoading = ref(false)
const tableData = ref([])
const selectedIndexs = ref([])
// 选择设备
const selectionChange = (e) => {
selectedIndexs.value = e.detail.index
}
// 获取列表
const getList = () => {
deviceList(deviceParams.value).then(res => {
if (deviceParams.value.pageNum == 1) {
tableData.value = res.rows
} else {
tableData.value = tableData.value.concat(res.rows)
}
deviceTotal.value = res.total
})
}
// 分页触发
const deviceChange = (e) => {
tableRef.value.clearSelection()
deviceParams.value.pageNum = e.current
getList()
}
const deviceInfo = ref({})
// 绑定设备
const bindDevice = () => {
console.log(selectedIndexs.value)
if (selectedIndexs.value.length == 0) {
uni.showToast({
title: '请至少选择一个设备绑定!',
icon: 'none'
});
} else if (selectedIndexs.value.length > 1) {
uni.showToast({
title: '只能选择一个设备绑定!',
icon: 'none'
});
} else {
uni.setStorageSync("deviceInfo", tableData.value[selectedIndexs.value[0]])
deviceInfo.value = tableData.value[selectedIndexs.value[0]]
}
}
// 判断是否绑定了设备
const judgeBinded = () => {
if (uni.getStorageSync("deviceInfo") && Object.keys(uni.getStorageSync("deviceInfo")).length > 0) {
deviceInfo.value = uni.getStorageSync("deviceInfo")
// uni.removeStorageSync('deviceInfo');
console.log("有数据")
} else {
console.log("无数据")
}
}
onLoad(() => {
judgeBinded()
getList()
})
</script>
<style scoped lang="scss">
.container {
padding: 32rpx;
position: relative;
.tableBox {
padding-bottom: 120rpx;
}
.paginationBox {
margin-top: 20rpx;
}
.btn {
position: fixed;
width: calc(100vw - 64rpx);
bottom: 0;
left: 32rpx;
z-index: 9999;
}
}
</style>

View File

@@ -0,0 +1,173 @@
<template>
<view class="container">
<view style="display: flex;align-items: center;justify-content: space-between;">
<view>当前扫描到{{ searchList.length }}</view>
<view>总条目{{ scanTotal || '暂无' }}</view>
</view>
<uni-list style="margin-bottom: 80rpx;margin-top: 20rpx;">
<uni-list-item v-for="item in searchList" :title="item"></uni-list-item>
</uni-list>
<view class="bottom">
<button type="primary" v-show="!pandianStatus" @click="startScan">开始盘点</button>
<button type="primary" v-show="pandianStatus" @click="stopInventory(1)">开始匹配</button>
<button v-show="pandianStatus" style="margin-left: 20rpx;" @click="stopInventory(0)">取消盘点</button>
</view>
</view>
</template>
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { getHandMatch, getTaskCount } from "@/api/inventory"
const scanTotal = ref("")
const taskInfo = ref({})
const getTotal = () => {
let obj = {
taskId: taskInfo.value.id,
showLoading: true
}
getTaskCount(obj).then(res => {
scanTotal.value = res.data
})
}
// 开始盘点
const startScan = () => {
uni.showToast({
title: '开始盘点',
duration: 2000,
icon: "none"
});
pandianStatus.value = true
startInventory()
}
// 加载插件 获取 module
var rfidManager = uni.requireNativePlugin("TH-PlatformRFID")
console.log("rfidManager", rfidManager)
// 扫码数组
const searchList = ref([]);
// 盘点状态对应显示按钮
const pandianStatus = ref(false)
// 页面
onLoad(() => {
var ret = rfidManager.soundInit();//初始时插件中的声音播放资源,可按自己实际需求看是否调用,如果有自己的声音播放资源,可以不用这个
//监听读取标签的数据回调
rfidManager.onInventoryTag((result) => {
if (!searchList.value.some(e => e == result.epc) && pandianStatus.value) {
console.log(JSON.stringify(result))
searchList.value.push(result.epc)
//16进制的epc 转 ASCII 码字符串
// var ascii = rfidManager.hexToASCII(result.epc);
// var epc = ascii;
rfidManager.soundPlay(1);
}
});
taskInfo.value = uni.getStorageSync("taskInfo")
getTotal()
init()
})
// 插件初始化
const init = function () {
uni.showLoading({
title: '正在初始化...',
mask: true
})
rfidManager.init((ret) => {
if (ret) {
uni.hideLoading()
} else {
uni.showToast({
title: ret,
duration: 2000,
icon: "none"
});
}
});
}
// 开始盘点
const startInventory = function () {
console.log('startInventory')
var ret = rfidManager.startInventory(0);
}
// 结束盘点
const stopInventory = function (status) {
console.log('stopInventory');
rfidManager.stopInventory();
if (status == 1) {
let obj = {
ids: searchList.value,
taskId: taskInfo.value.id,
}
getHandMatch(obj).then(res => {
console.log("res", res)
scanTotal.value = ""
pandianStatus.value = false
searchList.value = []
uni.redirectTo({
url: '/pagesInventory/matchResult?taskId=' + taskInfo.value.id
})
})
} else {
searchList.value = []
scanTotal.value = ""
pandianStatus.value = false
}
}
</script>
<style scoped lang="scss">
.container {
position: relative;
padding: 32rpx;
.bottom {
display: flex;
align-items: center;
position: fixed;
bottom: 0;
width: 100vw;
padding: 10rpx 32rpx;
left: 0;
box-sizing: border-box;
::v-deep uni-button {
flex: 1;
}
}
}
::v-deep .uni-select{
border: unset;
border-bottom: unset;
}
::v-deep .uv-popup .uv-popup__content {
overflow: unset !important;
}
::v-deep .uv-modal {
overflow: unset !important;
}
::v-deep .uv-input__content{
flex-direction: column;
}
::v-deep .uni-select__input-placeholder{
font-size: unset;
color: #c0c4cc;
}
::v-deep .uni-select{
padding: 0 !important;
}
</style>

211
pagesInventory/history.vue Normal file
View File

@@ -0,0 +1,211 @@
<template>
<view>
<z-paging ref="pagingRef" class="container" v-model="historyData" :default-page-size="queryParams.pageSize" @query="queryList">
<template #top>
<uv-search v-model="queryParams.taskName" placeholder="请输入" :showAction="true" actionText="搜索" @search="searchList"
@custom="searchList"></uv-search>
<uv-drop-down ref="dropDown" sign="dropDown_1" text-active-color="#3c9cff"
:extra-icon="{ name: 'arrow-down-fill', color: '#666', size: '26rpx' }"
:extra-active-icon="{ name: 'arrow-up-fill', color: '#3c9cff', size: '26rpx' }" :defaultValue="defaultValue"
:custom-style="{ padding: '0 30rpx' }" @click="selectMenu">
<uv-drop-down-item name="scanType" type="2" :label="dropItem('scanType').label" :value="dropItem('scanType').value">
</uv-drop-down-item>
</uv-drop-down>
<uv-drop-down-popup sign="dropDown_1" :click-overlay-on-close="true" :currentDropItem="currentDropItem"
@clickItem="clickItem" @popupChange="change"></uv-drop-down-popup>
</template>
<uv-list>
<uv-list-item :title="item.taskName" :note="scanTypeItem('scanType', item.scanType)" border :rightText="item.createdAt" clickable v-for="item in historyData" @click="goMathchResult(item)" />
</uv-list>
</z-paging>
</view>
</template>
<script setup>
import { ref, computed } from "vue";
import { onLoad, onPageScroll } from "@dcloudio/uni-app";
import { historyList } from "@/api/history"
const queryParams = ref({
taskName: "",
pageNum: 1,
pageSize: 10
})
const pagingRef = ref(null)
const historyData = ref([])
// 搜索按钮
const searchList = () => {
pagingRef.value.reload()
}
// 获取列表
const queryList = (pageNo, pageSize) => {
queryParams.value.pageNum = pageNo
console.log(pageNo, pageSize)
historyList(queryParams.value).then(res => {
// historyData.value = res.data.rows
pagingRef.value.complete(res.data.rows)
}).catch(res => {
pagingRef.value.complete(false)
})
}
const goMathchResult = (item) => {
uni.navigateTo({
url: "/pagesInventory/matchResult-old?taskName=" + item.taskName
})
}
onLoad(() => {
})
// 获取到对应的盘点方式
const scanTypeItem = (name, value) => {
const scanTypeObj = getPropertyByName(name);
if (scanTypeObj && scanTypeObj.child) {
const item = scanTypeObj.child.find(item => item.value === value);
return item ? item.label : null;
}
return null;
}
// 数据状态
const dropDown = ref(null);
// 默认值
const defaultValue = ref([]);
// 选择结果
const result = ref([{ name: 'scanType', label: '全部', value: '' }]);
const activeName = ref('');
// 筛选条件配置
const scanType = ref({
label: '文档格式',
value: '',
activeIndex: 0,
color: '#333',
activeColor: '#2878ff',
child: [{
label: '全部',
value: ''
}, {
label: '手动盘点',
value: 0
}, {
label: '自动盘点',
value: 1
}]
});
// 计算属性
const dropItem = computed(() => {
return (name) => {
const resultObj = {};
const find = result.value.find(item => item.name === name);
if (find) {
resultObj.label = find.label;
resultObj.value = find.value;
} else {
resultObj.label = getPropertyByName(name).label;
resultObj.value = getPropertyByName(name).value;
}
return resultObj;
}
});
const currentDropItem = computed(() => {
return getPropertyByName(activeName.value);
});
// 工具函数:根据名称获取对应的响应式对象
function getPropertyByName(name) {
switch (name) {
case 'scanType': return scanType.value;
default: return {};
}
}
// 生命周期钩子
onPageScroll(() => {
// 滚动后及时更新位置
dropDown.value?.init();
});
const selectMenu = (e) => {
const { name, active, type } = e;
activeName.value = name;
// type 等于1 的需要特殊处理type不等于1可以忽略
if (type == 1) {
clickItem({
name: 'vip_type',
label: 'VIP文档',
value: e.active ? 1 : 0
});
} else {
const find = result.value.find(item => item.name == activeName.value);
if (find) {
const findIndex = getPropertyByName(activeName.value).child.findIndex(item =>
item.label == find.label && item.value == find.value
);
getPropertyByName(activeName.value).activeIndex = findIndex;
} else {
getPropertyByName(activeName.value).activeIndex = 0;
}
}
};
const clickItem = (e) => {
// 下面有重新赋值所以用let
let { label, value } = e;
const findIndex = result.value.findIndex(item => item.name == activeName.value);
if (defaultValue.value.indexOf(value) > -1 && getPropertyByName(activeName.value).label) {
label = getPropertyByName(activeName.value).label;
}
// 已经存在筛选项
if (findIndex > -1) {
result.value[findIndex] = {
name: activeName.value,
label,
value
}
} else {
result.value.push({
name: activeName.value,
label,
value
});
}
result.value = result.value.filter(item => defaultValue.value.indexOf(item.value) == -1);
result.value.forEach(item=> {
queryParams.value[item.name] = item.value
})
pagingRef.value.reload()
console.log("筛选的值:", queryParams.value)
};
const change = (e) => {
console.log('弹窗打开状态:', e);
}
</script>
<style scoped lang="scss">
.container {
padding: 32rpx;
}
::v-deep .uv-search {
flex: unset;
}
::v-deep .uv-drop-down{
padding: 0 !important;
}
</style>

View File

@@ -0,0 +1,311 @@
<template>
<view class="container">
<uv-notice-bar :text="dataList[0] || ''"></uv-notice-bar>
<view style="margin: 10rpx 0;display: flex;align-items: center;justify-content: space-between;">
<view>当前扫描到{{ dataList.length - 1 }}</view>
<view>总条目{{ scanTotal || "暂无" }}</view>
</view>
<uv-list>
<uv-list-item :title="item" v-for="(item, index) in dataList" :key="index" v-show="index > 0"></uv-list-item>
</uv-list>
<uv-button type="primary" text="确定" size="large" class="btn" @tap="openTaskModal" v-show="status == 0"> </uv-button>
<uv-button type="primary" text="确定" size="large" class="btn" @tap="goMatch" v-show="status == 1"> </uv-button>
<uv-modal ref="taskModalRef" title="任务名称" @confirm="startScan" asyncClose>
<view class="slot-content" style="width: 100%;">
<uv-form labelPosition="left" :model="taskForm" labelWidth="80" :rules="rules" ref="formRef">
<uv-form-item label="任务名称" prop="taskName" borderBottom>
<uv-input v-model="taskForm.taskName" border="none" placeholder="请输入任务名称" />
</uv-form-item>
<uv-form-item label="盘点场景" prop="beLong" borderBottom>
<uni-data-select
v-model="taskForm.beLong"
:localdata="beLongList"
placeholder="请选择盘点场景"
></uni-data-select>
</uv-form-item>
</uv-form>
</view>
</uv-modal>
</view>
</template>
<script setup>
import { BASE_URL } from "@/api/request";
import { ref } from "vue";
import { onLoad, onUnload } from "@dcloudio/uni-app";
import { getScan, stopScan, getMatch, listScene, getScene } from "@/api/inventory"
const deviceInfo = ref({})
const status = ref(0)
const taskModalRef = ref("")
const scanTotal = ref("")
const formRef = ref(null)
const beLongList = ref([])
const openTaskModal = () => {
taskModalRef.value.open();
}
const taskForm = ref({
taskName: '',
beLong: ""
})
const rules = ref({
'taskName': {
type: 'string',
required: true,
message: '请填写任务名称',
trigger: ['blur', 'change']
},
'beLong': {
type: 'string',
required: true,
message: '请选择盘点场景',
trigger: ['blur', 'change']
},
})
// 开始盘点
const startScan = () => {
formRef.value.validate().then(res => {
let obj = {
beLong: taskForm.value.beLong
}
getScene(obj).then(res => {
scanTotal.value = res.data
let obj = {
deviceId: deviceInfo.value.deviceId
}
getScan(obj).then(() => {
console.log("开始盘点")
status.value = 1
taskModalRef.value.close()
})
})
}).catch(errors => {
taskModalRef.value.closeLoading()
})
}
// 开始匹配
const goMatch = () => {
let list = JSON.parse(JSON.stringify(dataList.value))
let arr = list.splice(1)
let obj = {
pageNum: 1,
pageSize: 10,
ids: arr,
status: 0,
taskName: taskForm.value.taskName,
deviceId: deviceInfo.value.deviceId,
showLoading: true,
beLong: taskForm.value.beLong,
}
uni.showLoading({
title: '加载中',
mask: true
})
getMatch(obj).then(res => {
console.log("保存数据")
stopTask(1)
})
}
const stopTask = (status) => {
console.log("停止")
let obj = {
deviceId: deviceInfo.value.deviceId,
showLoading: true
}
console.log("deviceId",deviceInfo.value.deviceId)
stopScan(obj).then(res => {
console.log("停止盘点")
if (status == 1) {
uni.hideLoading()
uni.redirectTo({
url: '/pagesInventory/matchResult-old?taskName=' + taskForm.value.taskName
})
// uni.closeSocket()
}
if (status != 2) {
socketTask.value.close();
clearInterval(reconnectTimeOut.value)
}
})
}
const dataList = ref([])
const reconnectTimeOut = ref(null)
const isOpenSocket = ref(true)
const socketTask = ref(null)
const connectSocketInit = () => {
socketTask.value = uni.connectSocket({
url: BASE_URL + '/ws/socket',
success: () => {
console.log('WebSocket连接创建成功');
}
});
socketTask.value.onOpen(() => {
console.log('WebSocket连接已打开');
send()
});
socketTask.value.onError(() => {
console.log('WebSocket连接打开失败请检查', res)
reconnect()
})
socketTask.value.onClose(() => {
console.log('WebSocket连接已关闭');
});
socketTask.value.onMessage((res) => {
if (status.value == 0) {
stopTask(2)
}
uni.hideLoading()
if (((status.value == 0 && res.data.includes("连接")) || (status.value == 1 && !res.data.includes("连接"))) && !(dataList.value.some(e => e == res.data))) {
// if (((status.value == 0 && res.data.includes("连接")) || (status.value == 1 && !res.data.includes("连接"))) && !(dataList.value.some(e => e == res.data))) {
dataList.value.push(res.data)
console.log("存储", dataList.value)
}
})
// uni.connectSocket({
// url: BASE_URL + '/ws/socket',
// success: () => {
// uni.showLoading({
// title:'正在连接设备...',
// mask: true
// })
// console.log("正准备建立websocket中...");
// // 返回实例
// },
// });
// uni.onSocketOpen(function (res) {
// console.log('WebSocket连接已打开', res)
// send()
// })
// uni.onSocketError(function (res) {
// console.log('WebSocket连接打开失败请检查', res)
// reconnect()
// })
// uni.onSocketMessage(function (res) {
// console.log('收到服务器内容:', res)
// if (status.value == 0) {
// stopTask()
// }
// uni.hideLoading()
// if (((status.value == 0 && res.data.includes("连接")) || (status.value == 1 && !res.data.includes("连接"))) && !(dataList.value.some(e => e == res.data))) {
// // if (((status.value == 0 && res.data.includes("连接")) || (status.value == 1 && !res.data.includes("连接"))) && !(dataList.value.some(e => e == res.data))) {
// dataList.value.push(res.data)
// console.log("存储", dataList.value)
// }
// })
}
const send = () => {
let obj = {
deviceId: deviceInfo.value.deviceId,
ip: deviceInfo.value.ipAddress,
port: deviceInfo.value.port
}
console.log("发送参数",obj)
// uni.sendSocketMessage({
// data: JSON.stringify(obj)
// })
socketTask.value.send({
data: JSON.stringify(obj)
})
}
//重新连接
const reconnect = () => {
console.log("重连")
//停止发送心跳
clearInterval(reconnectTimeOut.value)
//如果不是人为关闭的话,进行重连
if (isOpenSocket.value) {
reconnectTimeOut.value = setInterval(() => {
connectSocketInit();
}, 5000)
}
}
onLoad(() => {
deviceInfo.value = uni.getStorageSync("deviceInfo")
console.log(BASE_URL)
connectSocketInit()
let obj = {
pageNum: 1,
pageSize: 100
}
listScene(obj).then(res => {
res.rows.forEach(item => {
item.value = item.sceneCode
item.text = item.sceneName
});
beLongList.value = res.rows
})
})
onUnload(() => {
console.log("销毁")
// uni.closeSocket()
stopTask(0)
})
</script>
<style scoped lang="scss">
.container {
padding: 32rpx;
position: relative;
.tableBox{
padding-bottom: 120rpx;
}
.paginationBox {
margin-top: 20rpx;
}
.btn{
// height: 100rpx;
position: fixed;
width: calc(100vw - 64rpx);
bottom: 0;
left: 32rpx;
z-index: 9999;
}
}
::v-deep .uni-select{
border: unset;
border-bottom: unset;
}
::v-deep .uv-popup .uv-popup__content {
overflow: unset !important;
}
::v-deep .uv-modal {
overflow: unset !important;
}
::v-deep .uv-input__content{
flex-direction: column;
align-items: flex-start;
}
::v-deep .uni-select__input-placeholder{
font-size: unset;
color: #c0c4cc;
}
::v-deep .uni-select{
padding: 0 !important;
}
</style>

View File

@@ -0,0 +1,90 @@
<template>
<view class="iconBox">
<view class="iconItem"@tap="goDevice">
<view class="icon">
<image src="../static/iconfont/autoDevice.svg" mode="scaleToFill" />
</view>
<view class="text">自动盘点</view>
</view>
<view class="iconItem"@tap="goInventory">
<view class="icon">
<image src="../static/iconfont/handDevice.svg" style="width: 108rpx;height: 108rpx;" mode="scaleToFill" />
</view>
<view class="text">手持盘点</view>
</view>
</view>
</template>
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
onLoad(() => {
})
const goDevice = () => {
uni.navigateTo({
url: '/pagesInventory/inventoryTask',
})
}
// const goInventory = () => {
// if (uni.getStorageSync("deviceInfo") && Object.keys(uni.getStorageSync("deviceInfo")).length > 0) {
// uni.navigateTo({
// url: '/pagesInventory/inventory',
// })
// console.log("有数据")
// } else {
// console.log("无数据")
// uni.showToast({
// title: '请先去绑定设备',
// icon: 'none'
// })
// }
// }
const goHistory = () => {
uni.navigateTo({
url: '/pagesInventory/history',
})
}
</script>
<style scoped lang="scss">
.iconBox {
display: flex;
justify-content: space-evenly;
margin-top: 440rpx;
.iconItem {
width: 40%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin: 20rpx;
background-color: #f8f9fa;
height: 300rpx;
border-radius: 20rpx;
.icon {
width: 110rpx;
height: 110rpx;
display: flex;
align-items: center;
justify-content: center;
image {
width: 90rpx;
height: 90rpx;
}
}
.text {
margin-top: 14rpx;
// font-size: 28rpx;
}
}
}
</style>

View File

@@ -0,0 +1,365 @@
<template>
<view>
<z-paging ref="pagingRef" class="container" v-model="taskData" :default-page-size="queryParams.pageSize" :auto="false"
@query="queryList">
<template #top>
<uv-search v-model="queryParams.taskName" placeholder="请输入" :showAction="true" actionText="搜索"
@search="searchList" @custom="searchList"></uv-search>
<uv-drop-down ref="dropDown" sign="dropDown_1" text-active-color="#3c9cff"
:extra-icon="{ name: 'arrow-down-fill', color: '#666', size: '26rpx' }"
:extra-active-icon="{ name: 'arrow-up-fill', color: '#3c9cff', size: '26rpx' }" :defaultValue="defaultValue"
:custom-style="{ padding: '0 30rpx' }" @click="selectMenu">
<uv-drop-down-item name="taskType" type="2" :label="dropItem('taskType').label"
:value="dropItem('taskType').value">
</uv-drop-down-item>
<uv-drop-down-item name="status" type="2" v-if="type == 'all'" :label="dropItem('status').label" :value="dropItem('status').value">
</uv-drop-down-item>
</uv-drop-down>
<uv-drop-down-popup sign="dropDown_1" :click-overlay-on-close="true" :currentDropItem="currentDropItem"
@clickItem="clickItem" @popupChange="change"></uv-drop-down-popup>
</template>
<view>
<view v-for="item in taskData" class="box">
<view class="section-title">
<view class="title">{{ item.taskName }}</view>
<view class="section-status status1" v-show="item.status == 0">待执行</view>
<view class="section-status status2" v-show="item.status == 1">已完成</view>
<view class="section-status status3" v-show="item.status == 2">已超时</view>
</view>
<view><text>盘点类型</text>{{ scanTypeItem('taskType', item.taskType) }}</view>
<view><text>所属仓库</text>{{ item.warehouseName }}</view>
<view><text>所属场景</text>{{ item.sceneName }}</view>
<view><text>截止时间</text>{{ item.requireTime }}</view>
<view><text>备注</text>{{ item.remark || '-' }}</view>
<view class="itemBtn">
<uv-button type="primary" text="去盘点" v-show="item.status == 0" @tap="goInventory(item)"></uv-button>
<uv-button type="primary" text="去查看" v-show="item.status == 1" @tap="goView(item)"></uv-button>
</view>
</view>
</view>
</z-paging>
</view>
</template>
<script setup>
import { ref, computed } from "vue";
import { onLoad, onShow, onPageScroll } from "@dcloudio/uni-app";
import { taskList } from "@/api/inventory"
const queryParams = ref({
taskName: "",
pageNum: 1,
pageSize: 10,
taskType: null,
status: null,
})
const type = ref("")
const pagingRef = ref(null)
const taskData = ref([])
// 搜索按钮
const searchList = () => {
pagingRef.value.reload()
}
// 获取列表
const queryList = (pageNo, pageSize) => {
queryParams.value.pageNum = pageNo
console.log(pageNo, pageSize)
taskList(queryParams.value).then(res => {
console.log(res, "res")
// taskData.value = res.data.rows
pagingRef.value.complete(res.rows)
}).catch(res => {
pagingRef.value.complete(false)
})
}
const goInventory = (item) => {
if (item.taskType == 0) {
uni.setStorageSync('taskInfo', item)
uni.navigateTo({
url: "/pagesInventory/handInventory"
})
} else {
uni.setStorageSync('taskInfo', item)
uni.navigateTo({
url: "/pagesInventory/autoMenu"
})
}
}
const goView = (item) => {
uni.navigateTo({
url: '/pagesInventory/matchResult?taskId=' + item.id
})
}
onLoad((options) => {
type.value = options.type
if (type.value !== 'all') {
queryParams.value.status = 0
result.value[1].value = 0
}
})
onShow(() => {
queryList(1)
})
// 获取到对应的盘点方式
const scanTypeItem = (name, value) => {
const scanTypeObj = getPropertyByName(name);
if (scanTypeObj && scanTypeObj.child) {
const item = scanTypeObj.child.find(item => item.value === parseInt(value));
return item ? item.label : null;
}
return null;
}
// 数据状态
const dropDown = ref(null);
// 默认值
const defaultValue = ref([]);
// 选择结果
const result = ref([{ name: 'taskType', label: '全部', value: '' }, { name: 'status', label: '全部', value: '' }]);
const activeName = ref('');
// 筛选条件配置
const taskType = ref({
label: '文档格式',
value: '',
activeIndex: 0,
color: '#333',
activeColor: '#2878ff',
child: [{
label: '全部',
value: ''
}, {
label: '手持盘点',
value: 0
}, {
label: '自动盘点',
value: 1
}]
});
// 筛选条件配置
const status = ref({
label: '文档格式',
value: '',
activeIndex: 0,
color: '#333',
activeColor: '#2878ff',
child: [{
label: '全部',
value: ''
}, {
label: '待执行',
value: 0
}, {
label: '已完成',
value: 1
}, {
label: '已超时',
value: 2
}]
});
// 计算属性
const dropItem = computed(() => {
return (name) => {
const resultObj = {};
const find = result.value.find(item => item.name === name);
if (find) {
resultObj.label = find.label;
resultObj.value = find.value;
} else {
resultObj.label = getPropertyByName(name).label;
resultObj.value = getPropertyByName(name).value;
}
return resultObj;
}
});
const currentDropItem = computed(() => {
return getPropertyByName(activeName.value);
});
// 工具函数:根据名称获取对应的响应式对象
function getPropertyByName(name) {
switch (name) {
case 'taskType': return taskType.value;
case 'status': return status.value;
default: return {};
}
}
// 生命周期钩子
onPageScroll(() => {
// 滚动后及时更新位置
dropDown.value?.init();
});
const selectMenu = (e) => {
const { name, active, type } = e;
activeName.value = name;
// type 等于1 的需要特殊处理type不等于1可以忽略
// if (type == 1) {
// clickItem({
// name: 'vip_type',
// label: 'VIP文档',
// value: e.active ? 1 : 0
// });
// } else {
const find = result.value.find(item => item.name == activeName.value);
if (find) {
const findIndex = getPropertyByName(activeName.value).child.findIndex(item =>
item.label == find.label && item.value == find.value
);
getPropertyByName(activeName.value).activeIndex = findIndex;
} else {
getPropertyByName(activeName.value).activeIndex = 0;
}
// }
};
const clickItem = (e) => {
// 下面有重新赋值所以用let
let { label, value } = e;
const findIndex = result.value.findIndex(item => item.name == activeName.value);
if (defaultValue.value.indexOf(value) > -1 && getPropertyByName(activeName.value).label) {
label = getPropertyByName(activeName.value).label;
}
// 已经存在筛选项
if (findIndex > -1) {
result.value[findIndex] = {
name: activeName.value,
label,
value
}
} else {
result.value.push({
name: activeName.value,
label,
value
});
}
result.value = result.value.filter(item => defaultValue.value.indexOf(item.value) == -1);
result.value.forEach(item => {
queryParams.value[item.name] = item.value
})
pagingRef.value.reload()
console.log("筛选的值:", queryParams.value)
};
const change = (e) => {
console.log('弹窗打开状态:', e);
}
</script>
<style scoped lang="scss">
.container {
padding: 32rpx;
// background-color: #F5F5f5;
.box {
background: #efefef;
border-radius: 8rpx;
margin-top: 20rpx;
padding: 20rpx;
line-height: 50rpx;
font-size: 28rpx;
color: #333;
.section-title {
display: flex;
justify-content: space-between;
.section-status {
padding: 0 20rpx;
border-radius: 10rpx;
}
.status1 {
background-color: #FFFFFF;
}
.status2 {
background-color: #199793;
color: #FFFFFF;
}
.status3 {
background-color: #f56c6c;
color: #FFFFFF;
}
}
.title {
font-size: 36rpx;
font-weight: bold;
}
text {
color: #666;
}
.itemBtn {
display: flex;
justify-content: flex-end
}
:deep(.uv-button) {
height: 56rpx !important;
}
}
}
::v-deep .uv-search {
flex: unset;
}
::v-deep .uv-drop-down {
padding: 0 !important;
justify-content: unset;
}
.uv-drop-down-item {
width: 160rpx;
justify-content: center;
position: relative;
::v-deep .uv-text {
flex: unset;
width: unset;
}
}
.uv-drop-down-item::after {
content: "";
/* 必须设置content否则伪类不显示 */
position: absolute;
right: 0;
/* 定位到元素右侧 */
top: 50%;
/* 垂直居中 */
transform: translateY(-50%);
/* 修正垂直定位 */
width: 1px;
/* 竖线宽度 */
height: 50%;
/* 竖线高度 */
background-color: #ccc;
/* 竖线颜色 */
}
</style>

View File

@@ -0,0 +1,223 @@
<template>
<view>
<z-paging ref="pagingRef" class="container" v-model="listArr" :default-page-size="queryParams.pageSize" @query="queryList">
<template #top>
<view style="margin-bottom: 20rpx;display: flex;align-items: center;justify-content: space-between;">
<view>
<text v-show="queryParams.status == 0">当前正常数据</text>
<text v-show="queryParams.status == 1">未扫描到数据库里有数据</text>
<text v-show="queryParams.status == 2">已扫描到数据库里无数据</text>
:{{ total }}
</view>
<!-- <uni-icons @tap="exportArr" type="cloud-download-filled" size="30" style="color: #007aff;"></uni-icons> -->
</view>
<uv-tabs :list="tabList" @change="tabChange"></uv-tabs>
</template>
<view class="list-item" v-for="(item, index) in listArr" :key="index">
<view class="item-top">
<view class="item-name"><text v-show="queryParams.status !== 2">存放位置</text>{{ item.pcde }}</view>
<view class="status1 status" v-if="queryParams.status == 1">未扫到</view>
<view class="status2 status" v-else-if="queryParams.status == 2">无数据</view>
<view class="status3 status" v-else>正常数据</view>
</view>
<view class="item-name" v-show="queryParams.status !== 2">数量{{ item.count }}</view>
<!-- <view class="item-name">{{ item.des_pro }}</view>
<view class="item-desc" v-show="item.des_mat">{{ item.des_mat }}</view>
<view class="item-time" v-show="item.tme">{{ item.tme }}</view> -->
</view>
</z-paging>
</view>
</template>
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { getTaskName } from "@/api/history";
const listArr = ref([])
const pagingRef = ref(null)
// 获取列表
const queryParams = ref({
pageNum: 1,
pageSize: 10,
status: 0,
taskName: ''
})
const total = ref(0)
// const dbExtra = ref(0) // 未扫描到,数据库里有
// const requestExtra = ref(0) // 扫描到,数据库里没有
const current = ref(0) // tab切换
const tabList = ref([
{name: '正常'},
{name: '未扫到'},
{name: '无数据'}
]) // tab切换
// 初始化请求
onLoad((e) => {
console.log(e)
queryParams.value.taskName = e.taskName
// queryParams.value.taskName = "手持08.10"
// 可以在这里进行数据请求、初始化操作等
});
// 切换tab
const tabChange = (e) => {
console.log(e)
queryParams.value.status = e.index
pagingRef.value.reload()
}
// 获取列表
const queryList = (pageNo, pageSize) => {
queryParams.value.pageNum = pageNo
console.log(pageNo, pageSize)
getTaskName(queryParams.value).then(res => {
// historyData.value = res.data.rows
if (queryParams.value.status == 2) {
res.data.rows.forEach(e => {
e.pcde = e.pcdeGroup
});
}
total.value = res.data.total
pagingRef.value.complete(res.data.rows)
}).catch(res => {
pagingRef.value.complete(false)
})
}
// 导出
const exportArr = function () {
exportByData(listArr.value).then(res => {
uni.showLoading({
title: '下载中'
})
console.log("数据", res)
uni.downloadFile({
url: res.data,
success: (downloadResult) => {
console.log("downloadResult", downloadResult)
if (downloadResult.statusCode === 200) {
// 保存文件
uni.saveFile({
tempFilePath: downloadResult.tempFilePath,
success: (saveResult) => {
uni.hideLoading();
console.log('文件保存成功,保存路径:', saveResult.savedFilePath);
const oldFilePath = saveResult.savedFilePath;
const fileExtension = oldFilePath.split('.').pop();
// 创建一个Date对象
const now = new Date();
// 获取当前的年、月、日
const year = now.getFullYear();
const month = now.getMonth() + 1; // 月份是从0开始的需要加1
const date = now.getDate();
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');
const newFileName = year + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds + '_盘点结果.xls'; // 新的文件名
const newFilePath = oldFilePath.replace(/[^\/]*$/, newFileName);
uni.showToast({
icon: 'none',
mask: true,
title: `文件已保存`, //保存路径
duration: 3000,
});
console.log("newFilePath", oldFilePath, newFilePath)
plus.io.resolveLocalFileSystemURL(oldFilePath, entry => {
entry.getParent(_oldFile => {
entry.moveTo(_oldFile, '/' + newFileName, newFilePath => {
console.log('newFilePath', newFilePath.fullPath)
})
})
})
},
fail: (saveError) => {
console.error('文件保存失败:', saveError);
}
});
} else {
console.error('文件下载失败,状态码:', downloadResult.statusCode);
}
},
fail: (downloadError) => {
console.error('文件下载失败:', downloadError);
}
});
})
}
</script>
<style scoped lang="scss">
.container {
padding: 32rpx;
.list-item {
padding: 20rpx 10rpx;
border-bottom: 1rpx solid #eee;
.item-top {
display: flex;
align-items: center;
justify-content: space-between;
.status {
padding: 8rpx 15rpx;
background: #E5E5E5;
border-radius: 10rpx;
font-size: 18rpx;
}
.status1 {
background: #748041;
color: white;
}
.status2 {
background: #88413c;
color: white;
}
}
.item-name {
font-size: 32rpx;
color: #3b4144;
font-weight: 400;
}
.item-desc {
color: #999;
font-size: 28rpx;
font-weight: 400;
}
.item-time {
color: #999;
font-size: 24rpx;
font-weight: 400;
text-align: right;
margin-top: 10rpx;
}
}
.page {
padding: 40rpx 80rpx;
}
}
</style>

View File

@@ -0,0 +1,224 @@
<template>
<view>
<z-paging ref="pagingRef" class="container" v-model="listArr" :default-page-size="queryParams.pageSize" @query="queryList">
<template #top>
<view style="margin-bottom: 20rpx;display: flex;align-items: center;justify-content: space-between;">
<view>
<text v-show="queryParams.status == 0">当前正常数据</text>
<text v-show="queryParams.status == 1">未扫描到数据库里有数据</text>
<text v-show="queryParams.status == 2">已扫描到数据库里无数据</text>
:{{ total }}
</view>
<!-- <uni-icons @tap="exportArr" type="cloud-download-filled" size="30" style="color: #007aff;"></uni-icons> -->
</view>
<uv-tabs :list="tabList" @change="tabChange"></uv-tabs>
</template>
<view class="list-item" v-for="(item, index) in listArr" :key="index">
<view class="item-top">
<view class="item-name"><text v-show="queryParams.status !== 2">存放位置</text>{{ item.rkPcode }}</view>
<view class="status1 status" v-if="queryParams.status == 1">未扫到</view>
<view class="status2 status" v-else-if="queryParams.status == 2">无数据</view>
<view class="status3 status" v-else>正常数据</view>
</view>
<view class="item-name" v-show="queryParams.status !== 2">数量{{ item.realQty }}</view>
<!-- <view class="item-name">{{ item.des_pro }}</view>
<view class="item-desc" v-show="item.des_mat">{{ item.des_mat }}</view>
<view class="item-time" v-show="item.tme">{{ item.tme }}</view> -->
</view>
</z-paging>
</view>
</template>
<script setup>
import { ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { getScanResult } from "@/api/inventory";
const listArr = ref([])
const pagingRef = ref(null)
// 获取列表
const queryParams = ref({
pageNum: 1,
pageSize: 10,
status: 0,
taskId: ''
})
const total = ref(0)
// const dbExtra = ref(0) // 未扫描到,数据库里有
// const requestExtra = ref(0) // 扫描到,数据库里没有
const current = ref(0) // tab切换
const tabList = ref([
{name: '正常'},
{name: '未扫到'},
{name: '无数据'}
]) // tab切换
// 初始化请求
onLoad((e) => {
console.log(e)
queryParams.value.taskId = e.taskId
// queryParams.value.taskName = "手持08.10"
// 可以在这里进行数据请求、初始化操作等
});
// 切换tab
const tabChange = (e) => {
console.log(e)
queryParams.value.status = e.index
pagingRef.value.reload()
}
// 获取列表
const queryList = (pageNo, pageSize) => {
queryParams.value.pageNum = pageNo
console.log(pageNo, pageSize)
getScanResult(queryParams.value).then(res => {
console.log(res, "RES")
// historyData.value = res.data.rows
// if (queryParams.value.status == 2) {
// res.data.rows.forEach(e => {
// e.pcde = e.pcdeGroup
// });
// }
total.value = res.total
pagingRef.value.complete(res.rows)
}).catch(res => {
pagingRef.value.complete(false)
})
}
// 导出
const exportArr = function () {
exportByData(listArr.value).then(res => {
uni.showLoading({
title: '下载中'
})
console.log("数据", res)
uni.downloadFile({
url: res.data,
success: (downloadResult) => {
console.log("downloadResult", downloadResult)
if (downloadResult.statusCode === 200) {
// 保存文件
uni.saveFile({
tempFilePath: downloadResult.tempFilePath,
success: (saveResult) => {
uni.hideLoading();
console.log('文件保存成功,保存路径:', saveResult.savedFilePath);
const oldFilePath = saveResult.savedFilePath;
const fileExtension = oldFilePath.split('.').pop();
// 创建一个Date对象
const now = new Date();
// 获取当前的年、月、日
const year = now.getFullYear();
const month = now.getMonth() + 1; // 月份是从0开始的需要加1
const date = now.getDate();
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');
const newFileName = year + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds + '_盘点结果.xls'; // 新的文件名
const newFilePath = oldFilePath.replace(/[^\/]*$/, newFileName);
uni.showToast({
icon: 'none',
mask: true,
title: `文件已保存`, //保存路径
duration: 3000,
});
console.log("newFilePath", oldFilePath, newFilePath)
plus.io.resolveLocalFileSystemURL(oldFilePath, entry => {
entry.getParent(_oldFile => {
entry.moveTo(_oldFile, '/' + newFileName, newFilePath => {
console.log('newFilePath', newFilePath.fullPath)
})
})
})
},
fail: (saveError) => {
console.error('文件保存失败:', saveError);
}
});
} else {
console.error('文件下载失败,状态码:', downloadResult.statusCode);
}
},
fail: (downloadError) => {
console.error('文件下载失败:', downloadError);
}
});
})
}
</script>
<style scoped lang="scss">
.container {
padding: 32rpx;
.list-item {
padding: 20rpx 10rpx;
border-bottom: 1rpx solid #eee;
.item-top {
display: flex;
align-items: center;
justify-content: space-between;
.status {
padding: 8rpx 15rpx;
background: #E5E5E5;
border-radius: 10rpx;
font-size: 18rpx;
}
.status1 {
background: #748041;
color: white;
}
.status2 {
background: #88413c;
color: white;
}
}
.item-name {
font-size: 32rpx;
color: #3b4144;
font-weight: 400;
}
.item-desc {
color: #999;
font-size: 28rpx;
font-weight: 400;
}
.item-time {
color: #999;
font-size: 24rpx;
font-weight: 400;
text-align: right;
margin-top: 10rpx;
}
}
.page {
padding: 40rpx 80rpx;
}
}
</style>