master
LAPTOP-S9HJSOEB\昊天 6 months ago
parent ab90dfb8cc
commit c35fbceb34

@ -1,6 +1,6 @@
{
"name" : "uniApp",
"appid" : "",
"name" : "智能盘点",
"appid" : "__UNI__20007E5",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
@ -41,9 +41,43 @@
]
},
/* ios */
"ios" : {},
"ios" : {
"dSYMs" : false
},
/* SDK */
"sdkConfigs" : {}
"sdkConfigs" : {},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
}
}
},
/* */

@ -2,28 +2,24 @@
"pages": [{
"path": "pages/login/login",
"style": {
"topWindow": false,
"leftWindow": false,
"rightWindow": false
"navigationStyle": "custom"
}
},
{
"path": "pages/tabbar/order/order",
"needLogin": true,
"style": {
"navigationBarTitleText": "随行记录"
}
},
{
"path": "pages/tabbar/stock/stock",
"needLogin": true,
"style": {
"navigationBarTitleText": "盘点记录"
}
},
{
"path": "pages/tabbar/video/video",
"needLogin": true,
"style": {
"navigationBarTitleText": "视频直播"
}

@ -1,10 +1,11 @@
<template>
<view class="login-container">
<image class="logo" src="/static/login.png"></image>
<image class="logo" src="/static/login.png" @dblclick="toggleIpInput"></image>
<view class="login-card">
<text class="login-title">欢迎登录</text>
<u-input v-model="username" placeholder="请输入用户名" class="input-field"></u-input>
<u-input v-model="password" placeholder="请输入密码" type="password" class="input-field"></u-input>
<u-input v-if="showIpInput" v-model="ip" placeholder="请输入IP地址" class="input-field"></u-input>
<u-button type="primary" @click="handleLogin" class="login-button">登录</u-button>
</view>
</view>
@ -16,10 +17,19 @@
data() {
return {
username: '',
password: ''
password: '',
showIpInput: false,
ip: ''
}
},
methods: {
/**
* 切换IP输入框的显示状态
* 该方法用于控制是否显示IP输入框通过切换 `showIpInput` 的值实现
*/
toggleIpInput() {
this.showIpInput = !this.showIpInput;
},
formatTime(timestamp) {
const date = new Date(timestamp);
const year = date.getFullYear();
@ -39,6 +49,10 @@
return;
}
if (this.ip) {
uni.setStorageSync('IP_ADDRESS', this.ip);
}
try {
const res = await request({
url: '/admin-api/system/auth/login',
@ -54,9 +68,21 @@
if (res.data.code === 200) {
// token
uni.setStorageSync('HANDLE_KEY', res.data.data.accessToken);
try {
uni.switchTab({
url: '/pages/tabbar/video/video'
url: '/pages/tabbar/video/video',
success(){
},
fail() {
uni.showToast({
title: '进入失败',
icon: 'none'
});
}
});
} catch (error) {
console.error('跳转失败:', error);
}
} else {
uni.showToast({
title: res.data.msg || '登录失败',
@ -77,6 +103,8 @@
<style>
.login-container {
height: var(--status-bar-height);
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;

@ -1,5 +1,14 @@
<template>
<view class="order-page">
<uni-data-select
v-model="value"
:localdata="range"
style="
margin-bottom: 5px;
"
placeholder="请选择巷道"
@change="change"
></uni-data-select>
<!-- 下拉刷新 -->
<u-pull-refresh
:refreshing="refreshing" @refresh="onRefresh">
@ -7,18 +16,18 @@
<view v-for="(item, index) in orderList" :key="index" class="order-card">
<view class="order-info">
<!-- 详情链接 -->
<text class="detail-link" @click="goToDetail(item)"></text>
<!-- <text class="detail-link" @click="goToDetail(item)"></text> -->
<text class="order-name">任务号:{{ item.taskId }}</text>
<text class="order-time">状态:{{ item.statusName }}</text>
<!-- <text class="order-time">状态:{{ item.statusName }}</text> -->
<text class="order-time">地址:{{ this.position(item) }}</text>
<text class="order-time">时间:{{ this.formatTime(item.startTime) }}</text>
<!-- 图片显示 -->
<view class="pics-container" v-if="item.urlResources">
<view class="pics-container" v-if="item.pics">
<u-image
v-for="(pic, picIndex) in item.urlResources"
v-for="(pic, picIndex) in item.pics.split(';')"
:key="picIndex"
:title="pic.url"
:src="pic.url" width="80px" height="80px"
:src="pic.url" width="73px" height="73px"
class="order-pic"
mode="aspectFill"
/>
@ -40,15 +49,27 @@ export default {
pageNum: 1, //
pageSize: 15, //
streetId:null,
range: [
],
refreshing: false,
loadStatus: 'loadmore', // loadmore/loading/nomore
total: 0 //
}
},
onLoad() {
this.getStreetList();
this.loadOrders(); //
},
methods: {
change(e) {
// console.log(e);
this.streetId = e;
this.pageNum = 1;
this.loadOrders();
// this.onRefresh()
},
formatTime(timestamp) {
const date = new Date(timestamp);
const year = date.getFullYear();
@ -60,10 +81,36 @@ export default {
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
position(row) {
const from = row.fromSide == 2 ? "库外" : row.srmNumber + "-" + (row.fromDirection ? "左侧-" : "右侧-") + row.fromRow + '层-' + row.fromColumn + '列' + (row.fromSeparation == 2 ? "深货位" : "");
const to = row.toSide == 2 ? "库外" : row.srmNumber + "-" + (row.toDirection ? "左侧-" : "右侧-") + row.toRow + '层-' + row.toColumn + '列' + (row.toSeparation == 2 ? "深货位" : "");
const from = row.fromSide == 2 ? "库外" : row.streetName + "-" + (row.fromDirection ? "左侧-" : "右侧-") + row.fromRow + '层-' + row.fromColumn + '列' + (row.fromSeparation == 2 ? "深货位" : "");
const to = row.toSide == 2 ? "库外" : row.streetName + "-" + (row.toDirection ? "左侧-" : "右侧-") + row.toRow + '层-' + row.toColumn + '列' + (row.toSeparation == 2 ? "深货位" : "");
return from + "->" + to;
},
async getStreetList() {
try {
const res = await request({
url: '/admin-api/logistics/street/list',
method: 'GET',
data: {
}
});
if (res.data.code === 200) {
// console.log(res.data.data);
console.log(res.data.data.map(item => ({ value: item.id, text: item.name })));
this.range = res.data.data.map(item => ({ value: item.id, text: item.name }));
console.log(this.range);
} else {
uni.showToast({ title: res.data.msg || '加载失败', icon: 'none' });
this.loadStatus = 'loadmore';
}
} catch (error) {
console.error('加载订单失败:', error);
uni.showToast({ title: '网络错误', icon: 'none' });
this.loadStatus = 'loadmore';
}
},
//
goToDetail(item) {
uni.navigateTo({
@ -79,7 +126,8 @@ export default {
method: 'GET',
data: {
pageNo: this.pageNum,
pageSize: this.pageSize
pageSize: this.pageSize,
srmNumber: this.streetId
}
});

@ -62,6 +62,13 @@ export default {
this.loadOrders(); //
},
methods: {
change(e) {
// console.log(e);
this.streetId = e;
this.pageNum = 1;
this.loadOrders();
// this.onRefresh()
},
formatTime(timestamp) {
const date = new Date(timestamp);
const year = date.getFullYear();
@ -92,9 +99,12 @@ export default {
});
if (res.data.code === 200) {
console.log(res.data.data);
// console.log(res.data.data);
console.log(res.data.data.map(item => ({ value: item.id, text: item.name })));
this.range = res.data.data.map(item => ({ value: item.id, text: item.name }));
console.log(this.range);
this.range = res.data.data;
} else {
uni.showToast({ title: res.data.msg || '加载失败', icon: 'none' });
this.loadStatus = 'loadmore';

@ -1,56 +1,83 @@
<template>
<view class="container">
<picker mode="selector" :range="cameras" range-key="name" @change="handleCameraChange">
<button>选择相机</button>
<button>{{ currentCamera ? currentCamera.name : '选择相机' }}</button>
</picker>
<video id="myVideo" ref="videoPlayer" :src="streamUrl" autoplay muted controls
style="width: 100%; height: 50%;" @fullscreenchange="handleFullscreenChange"></video>
<video id="myVideo" ref="videoPlayer" :src="streamUrl" autoplay muted controls style="width: 100%; height: 50%;"
@fullscreenchange="handleFullscreenChange"></video>
<!-- 云台控制面板 -->
<view class="ptz-control" :class="{ 'ptz-control-fullscreen': isFullscreen }">
<view class="direction-list">
<view class="operation-item">
<u-icon name="minus" :size=" 40" @touchstart="handleControl('zoomSub', 'start')" @touchend="handleControl('zoomSub', 'stop')" @touchcancel="handleControl('zoomSub', 'stop')"></u-icon>
<u-icon name="minus" :size="40" @touchstart="handleControl('zoomSub', 'start')"
@touchend="handleControl('zoomSub', 'stop')"
@touchcancel="handleControl('zoomSub', 'stop')"></u-icon>
</view>
<span>变倍</span>
<view class="operation-item">
<u-icon name="plus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('zoomAdd', 'start')" @touchend="handleControl('zoomAdd', 'stop')" @touchcancel="handleControl('zoomAdd', 'stop')"></u-icon>
<u-icon name="plus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('zoomAdd', 'start')"
@touchend="handleControl('zoomAdd', 'stop')"
@touchcancel="handleControl('zoomAdd', 'stop')"></u-icon>
</view>
<view class="operation-item">
<u-icon name="minus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('focusSub', 'start')" @touchend="handleControl('focusSub', 'stop')" @touchcancel="handleControl('focusSub', 'stop')"></u-icon>
<u-icon name="minus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('focusSub', 'start')"
@touchend="handleControl('focusSub', 'stop')"
@touchcancel="handleControl('focusSub', 'stop')"></u-icon>
</view>
<span>变焦</span>
<view class="operation-item">
<u-icon name="plus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('focusAdd', 'start')" @touchend="handleControl('focusAdd', 'stop')" @touchcancel="handleControl('focusAdd', 'stop')"></u-icon>
<u-icon name="plus" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('focusAdd', 'start')"
@touchend="handleControl('focusAdd', 'stop')"
@touchcancel="handleControl('focusAdd', 'stop')"></u-icon>
</view>
<view class="direction-item">
<image src="@/static/tabbar/icon/箭头_左上.png" :style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }" @touchstart="handleControl('leftUp', 'start')" @touchend="handleControl('leftUp', 'stop')" @touchcancel="handleControl('leftUp', 'stop')"></image>
<image src="@/static/tabbar/icon/l_u.png"
:style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px', opacity: activeButton === 'leftUp' ? 0.7 : 1 }"
@touchstart="handleControl('leftUp', 'start')" @touchend="handleControl('leftUp', 'stop')"
@touchcancel="handleControl('leftUp', 'stop')"></image>
</view>
<view class="direction-item">
<u-icon name="arrow-up" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('up', 'start')" @touchend="handleControl('up', 'stop')" @touchcancel="handleControl('up', 'stop')"></u-icon>
<u-icon name="arrow-up" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('up', 'start')"
@touchend="handleControl('up', 'stop')" @touchcancel="handleControl('up', 'stop')"></u-icon>
</view>
<view class="direction-item">
<image src="@/static/tabbar/icon/箭头_右上.png" :style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }" @touchstart="handleControl('rightUp', 'start')" @touchend="handleControl('rightUp', 'stop')" @touchcancel="handleControl('rightUp', 'stop')"></image>
<image src="@/static/tabbar/icon/r_u.png"
:style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }"
@touchstart="handleControl('rightUp', 'start')" @touchend="handleControl('rightUp', 'stop')"
@touchcancel="handleControl('rightUp', 'stop')"></image>
</view>
<view class="direction-item">
<u-icon name="arrow-left" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('left', 'start')" @touchend="handleControl('left', 'stop')" @touchcancel="handleControl('left', 'stop')"></u-icon>
<u-icon name="arrow-left" :size="isFullscreen ? 40 : 40"
@touchstart="handleControl('left', 'start')" @touchend="handleControl('left', 'stop')"
@touchcancel="handleControl('left', 'stop')"></u-icon>
</view>
<view class="direction-item">
<u-icon :size="isFullscreen ? 40 : 40" @click="refresh"></u-icon>
</view>
<view class="direction-item">
<u-icon name="arrow-right" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('right', 'start')" @touchend="handleControl('right', 'stop')" @touchcancel="handleControl('right', 'stop')"></u-icon>
<u-icon name="arrow-right" :size="isFullscreen ? 40 : 40"
@touchstart="handleControl('right', 'start')" @touchend="handleControl('right', 'stop')"
@touchcancel="handleControl('right', 'stop')"></u-icon>
</view>
<view class="direction-item">
<image src="@/static/tabbar/icon/箭头_左下.png" :style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }" @touchstart="handleControl('leftDown', 'start')" @touchend="handleControl('leftDown', 'stop')" @touchcancel="handleControl('leftDown', 'stop')"></image>
<image src="@/static/tabbar/icon/l_d.png"
:style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }"
@touchstart="handleControl('leftDown', 'start')" @touchend="handleControl('leftDown', 'stop')"
@touchcancel="handleControl('leftDown', 'stop')"></image>
</view>
<view class="direction-item">
<u-icon name="arrow-down" :size="isFullscreen ? 40 : 40" @touchstart="handleControl('down', 'start')" @touchend="handleControl('down', 'stop')" @touchcancel="handleControl('down', 'stop')"></u-icon>
<u-icon name="arrow-down" :size="isFullscreen ? 40 : 40"
@touchstart="handleControl('down', 'start')" @touchend="handleControl('down', 'stop')"
@touchcancel="handleControl('down', 'stop')"></u-icon>
</view>
<view class="direction-item">
<image src="@/static/tabbar/icon/箭头_右下.png" :style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }" @touchstart="handleControl('rightDown', 'start')" @touchend="handleControl('rightDown', 'stop')" @touchcancel="handleControl('rightDown', 'stop')"></image>
<image src="@/static/tabbar/icon/r_d.png"
:style="{ width: isFullscreen ? '40px' : '40px', height: isFullscreen ? '40px' : '40px' }"
@touchstart="handleControl('rightDown', 'start')" @touchend="handleControl('rightDown', 'stop')"
@touchcancel="handleControl('rightDown', 'stop')"></image>
</view>
</view>
</view>
@ -103,11 +130,11 @@
}
},
updateStreamUrl() {
const currentIp = window.location.hostname;
const ipAddres = uni.getStorageSync('IP_ADDRESS');
const isH5 = uni.getSystemInfoSync().platform === 'h5';
const protocol = isH5 ? 'http' : 'rtmp';
const ext = isH5 ? '.m3u8' : '';
this.streamUrl = `${protocol}://${currentIp}/live/camera${this.currentCamera.id}${ext}`;
this.streamUrl = `${protocol}://${ipAddres}/live/camera${this.currentCamera.id}${ext}`;
console.log(this.streamUrl)
this.$nextTick(() => {
this.videoPlayer.play();
@ -119,9 +146,19 @@
this.updateStreamUrl();
},
//
handleControl(action, state) {
async handleControl(action, state) {
console.log(`${action}-${state}`);
const data = { id: this.currentCamera.id };
const data = {
id: this.currentCamera.id
};
const res = await request({
url: '/admin-api/camera/control/' + action + '/' + state,
method: 'POST',
data: {
id: this.currentCamera.id
}
});
},
//
refresh() {
@ -141,6 +178,7 @@
width: 100%;
height: 85vh;
}
/* 云台控制面板样式 */
.ptz-control {
margin-top: 10px;
@ -149,6 +187,7 @@
padding: 5px;
border-radius: 5px;
}
.ptz-control-fullscreen {
position: fixed;
bottom: 10px;
@ -157,19 +196,24 @@
width: 80%;
z-index: 1000;
}
.direction-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 3px;
justify-items: center;
}
.operation-item, .direction-item {
.operation-item,
.direction-item {
display: flex;
flex-direction: column;
align-items: center;
margin: 3px;
}
.operation-item span, .direction-item span {
.operation-item span,
.direction-item span {
font-size: 10px;
margin-top: 3px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

@ -1,13 +1,13 @@
{
"hash": "a949376a",
"configHash": "aab60916",
"hash": "b89d9ac4",
"configHash": "d8ec3184",
"lockfileHash": "d2d97049",
"browserHash": "f4313551",
"browserHash": "6e74292b",
"optimized": {
"dayjs/esm/index": {
"src": "../../../../../node_modules/dayjs/esm/index.js",
"file": "dayjs_esm_index.js",
"fileHash": "6d0da006",
"fileHash": "1e6fad4c",
"needsInterop": false
}
},

@ -1,4 +1,4 @@
// ../../../../git/测试/mobileSoftwareUniApp/uniApp/node_modules/dayjs/esm/constant.js
// ../../../../git/测试/qianduan-app/node_modules/dayjs/esm/constant.js
var SECONDS_A_MINUTE = 60;
var SECONDS_A_HOUR = SECONDS_A_MINUTE * 60;
var SECONDS_A_DAY = SECONDS_A_HOUR * 24;
@ -23,7 +23,7 @@ var INVALID_DATE_STRING = "Invalid Date";
var REGEX_PARSE = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/;
var REGEX_FORMAT = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g;
// ../../../../git/测试/mobileSoftwareUniApp/uniApp/node_modules/dayjs/esm/locale/en.js
// ../../../../git/测试/qianduan-app/node_modules/dayjs/esm/locale/en.js
var en_default = {
name: "en",
weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
@ -35,7 +35,7 @@ var en_default = {
}
};
// ../../../../git/测试/mobileSoftwareUniApp/uniApp/node_modules/dayjs/esm/utils.js
// ../../../../git/测试/qianduan-app/node_modules/dayjs/esm/utils.js
var padStart = function padStart2(string, length, pad) {
var s = String(string);
if (!s || s.length >= length)
@ -88,7 +88,7 @@ var utils_default = {
u: isUndefined
};
// ../../../../git/测试/mobileSoftwareUniApp/uniApp/node_modules/dayjs/esm/index.js
// ../../../../git/测试/qianduan-app/node_modules/dayjs/esm/index.js
var L = "en";
var Ls = {};
Ls[L] = en_default;

@ -1,6 +1,6 @@
// 全局配置
const config = {
port: '48081' // 默认端口
port: '48080' // 默认端口
};
// 动态更新配置
@ -27,11 +27,15 @@ export default async function request(options) {
} = options;
// 优先使用传入IP否则用页面域名
const targetIp = ip || (typeof window !== 'undefined' ? window.location.hostname : '127.0.0.1');
// 获取登录句柄请替换YOUR_HANDLE_KEY为实际使用的key
const handle = uni.getStorageSync('HANDLE_KEY');
console.log('handle', handle);
const ipAddres = uni.getStorageSync('IP_ADDRESS');
console.log('ipAddres', ipAddres);
const targetIp = ip || ipAddres || (typeof window !== 'undefined' ? window.location.hostname : '127.0.0.1');
try {
@ -42,7 +46,9 @@ export default async function request(options) {
method,
data,
header: {
...(handle ? { 'Authorization': `Bearer ${handle}` } : {}),
...(handle ? {
'Authorization': `Bearer ${handle}`
} : {}),
...(rest.header || {})
},
...rest

Loading…
Cancel
Save