初稿提交,包含登录页面,主页面,测试页面,空载具入库和手动入库页面

This commit is contained in:
李宇奇 2025-10-07 19:35:58 +08:00
parent 1fa4ad08d9
commit 3bf36f8e11
28 changed files with 3558 additions and 0 deletions

2
.gitignore vendored
View File

@ -44,3 +44,5 @@ google-services.json
# Android Profiling
*.hprof
unpackage/

19
App.vue Normal file
View File

@ -0,0 +1,19 @@
<script>
export default {
onLaunch() {
console.log('App Launch');
},
onShow() {
console.log('App Show');
},
onHide() {
console.log('App Hide');
}
}
</script>
<style lang="scss">
@import './common/uni.css';
@import '/static/mui-icons.css';
page { background-color: #F5F5F5; min-height: 100%; }
</style>

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 DCloud
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

186
changelog.md Normal file
View File

@ -0,0 +1,186 @@
## 3.4.92025-06-25
- 适配 鸿蒙元服务
- 更新 uni-swipe-action
- 新增 crypto 示例和测试例
- 新增 css 变量示例和测试例
- 新增 web-view点击位置偏移测试例
## 3.4.82025-04-10
- 调整 renderjs示例的平台兼容性
## 3.4.72025-01-08
- 新增 uni-calendar显示
- 更新 uniui 组件
- 更新uni-id至3.3.33版本
- 替换示例中失效图片资源地址
## 3.4.62023-06-30
- 更新 video组件引用的视频链接
## 3.4.42022-07-25
- 新增 同步 uni-ui@1.4.20
- uni-forms 【重要】组件逻辑重构,部分用法旧版本不兼容,请注意兼容问题
- uni-section 新增组件
## 3.4.32022-07-14
- 修复 HBuilderX 拉取 hello uni-app 项目直接运行提示无服务空间关联的bug
## 3.4.22022-07-06
- 新增 同步 uni-ui@1.4.18
- uni-forms 【重要】组件逻辑重构,部分用法旧版本不兼容,请注意兼容问题
- uni-forms 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力
- uni-forms 新增 更多表单示例
- uni-forms 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃
- uni-forms 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效
- uni-forms 新增 onFieldChange 方法可以对子表单进行校验可替代binddata方法
- uni-forms 新增 子表单的 setRules 方法,配合自定义校验函数使用
- uni-forms 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则
- uni-forms 修复 由 1.4.0 引发的 label 插槽不生效的bug
- uni-forms 修复 子组件找不到 setValue 报错的bug
- uni-forms 修复 uni-data-picker 在 uni-forms-item 中报错的bug
- uni-forms 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
- uni-forms 修复 表单校验顺序无序问题
- uni-forms 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式
- uni-forms 优化 动态表单校验方式废弃拼接name的方式
- uni-breadcrumb 修复 微信小程序 separator 不显示问题
- uni-data-checkbox 优化 在 uni-forms 中的依赖注入方式
- uni-data-picker 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
- uni-data-picker 优化 显示样式
- uni-data-select 优化 显示样式
- uni-datetime-picker 修复 日历顶部年月及底部确认未国际化 bug
- uni-datetime-picker 优化 组件样式调整了组件图标大小、高度、颜色等与uni-ui风格保持一致
- uni-easyinput 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容
- uni-easyinput 新增 clear 事件,点击右侧叉号图标触发
- uni-easyinput 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发
- uni-easyinput 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等
- uni-easyinput 优化 clearable 显示策略
- uni-file-picker 修复 在uni-forms下样式不生效的bug
- uni-nav-bar 修复 组件示例中插槽用法无法显示内容的bug
- uni-swipe-action 修复 vue3 下使用组件不能正常运行的Bug
- uni-swipe-action 修复 h5端点击click触发两次的Bug
- uni-table 修复 微信小程序存在无使用组件的问题
## 3.4.12022-06-30
- 新增 支持 ios 安全区
## 3.3.82022-05-08
- 新增 同步 uni-ui@1.4.15
- uni-data-picker 修复 字节小程序 本地数据无法选择下一级的Bug
- uni-data-select 新增 记住上次的选项(仅 collection 存在时有效)
- uni-search-bar 修复 vue3 input 事件不生效的bug
- uni-search-bar 修复 多余代码导致的bug
- uni-tooltip 更新 text 属性变更为 content
- uni-tooltip 更新 移除 width 属性
- uni-tooltip 修复 组件根 text 嵌套组件 warning
## 3.3.72022-04-06
- 新增 更新扩展组件 uni-nav-bar、uni-list 的展示页面
## 3.3.62022-03-31
- 更新 uni-ui 组件及示例
## 3.3.52022-03-30
- 修复 插槽兼容 vue3 slot -> v-slot
- 新增 更新 uni-ui
## 3.3.42022-02-25
- 修复 编译到 App 平台的控制台报错
## 3.3.32022-02-23
- 修复 模板城市选择 vue3 报错的bug
- 修复 删除 map.nvue 中多余的 enableOverlooking 变量
- 修复 swipe-dot.nvue 中条件编译媒体查询
## 3.3.22022-01-26
- 修复 默认运行到 vue2
## 3.3.12022-01-26
- 新增 同步 uni-ui@1.4.11
- uni-collapse 修复 微信小程序resize后组件收起的bug
- uni-countdown 修复 在微信小程序中样式不生效的bug
- uni-countdown 新增 update 方法 ,在动态更新时间后,刷新组件
- uni-load-more 新增 showText属性 ,是否显示文本
- uni-load-more 修复 nvue 平台下不显示文本的bug
- uni-load-more 修复 微信小程序平台样式选择器报警告的问题
- uni-nav-bar 修复 在vue下标题不垂直居中的bug
- uni-nav-bar 修复 height 属性类型错误
- uni-nav-bar 新增 height 属性,可修改组件高度
- uni-nav-bar 新增 dark 属性可可开启暗黑模式
- uni-nav-bar 优化 标题字数过多显示省略号
- uni-nav-bar 优化 插槽,插入内容可完全覆盖
- uni-popup 修复 isMaskClick 失效的bug
- uni-popup 新增 cancelText \ confirmText 属性 ,可自定义文本
- uni-popup 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
- uni-popup 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
## 3.3.02022-01-04
- 修复 开发时在 vue3 下由 pc 端切换到手机端,不能返回上一级页面的 bug
- 优化 去掉 pc 端 topwindow 右上角用于演示的 url 导航
## 3.2.122021-12-20
- 新增 适配京东小程序
## 3.2.112021-12-07
- 修复 uni-ui 在 hello-uniapp 中丢失图标、ui 受到公共样式影响等问题
- 修复 微信登录取值报错的问题
## 3.2.102021-11-30
- 修复 map 组件示例不显示的 bug
## 3.2.92021-11-19
- 新增 uni-ui 以 uni_modules 方式引入,方便开发者从 hello-uniapp 中 copy 组件及示例
- 优化 uni-ui 示例页面,完善组件示例
## 3.2.82021-11-10
- 新增 适配飞书平台lark
## 3.2.72021-10-26
- 修复 uni-popup 示例的 button 文字在 iPhone 5 上换行的 bug
- 修复 uni-table 示例,页面顶部距离不对的 bug
- 修复 GlobalData示例在vue3是无效的 bug
- 优化 删除无用的 project.swan.json 文件
## 3.2.62021-10-08
- 由于体验问题,暂时撤销 uni-ui 以 uni_modules 方式引入的修改
## 3.2.42021-09-07
- 修复 vue3 在 H5 编译报错的 bug
- 新增 同步 uni-ui
- 新增 uni-ui 组件支持国际化 i18n
- uni-data-checkbox 修复 在uni-forms中 modelValue 中不存在当前字段,当前字段必填写也不参与校验的问题
- uni-datetime-picker 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
- uni-datetime-picker 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
- uni-datetime-picker 优化 调整字号大小,美化日历界面
- uni-datetime-picker 修复 因国际化导致的 placeholder 失效的 bug
- uni-file-picker 修复 return-type="object" 时且存在v-model时无法删除文件的Bug
- uni-file-picker 新增 参数中返回 fileID 字段
- uni-file-picker 修复 腾讯云传入fileID 不能回显的bug
- uni-file-picker 修复 选择图片后,不能放大的问题
- uni-link 修复 在 nvue 下不显示的 bug
- uni-list 修复 在vue3中to属性在发行应用的时候报错的bug
- uni-search-bar 修复 value 属性与 modelValue 属性不兼容的Bug
- uni-swipe-action 优化 close-all 方法
- uni-collapse 优化 show-arrow 属性默认为true
- uni-collapse 新增 show-arrow 属性,控制是否显示右侧箭头
- uni-data-checkbox 修复 单选 list 模式下 icon 为 left 时,选中图标不显示的问题
- uni-easyinput 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
- uni-file-picker 修复 由于 0.2.11 版本引起的不能回显图片的Bug
- uni-file-picker 新增 clearFiles(index) 方法,可以手动删除指定文件
- uni-file-picker 修复 v-model 值设为 null 报错的Bug
- uni-swipe-action 新增 close-all 方法,关闭所有已打开的组件
- uni-swipe-action 新增 resize() 方法在非微信小程序、h5、app-vue端出现不能滑动的问题的时候重置组件
- uni-swipe-action 修复 app 端偶尔出现类似 Page[x][-x,xx;-x,xx,x,x-x] 的问题
- uni-swipe-action 优化 微信小程序、h5、app-vue 滑动逻辑,避免出现动态新增组件后不能滑动的问题
## 3.2.32021-08-27
- 优化 tabbar 页面移除 vuex 相关代码
- 新增 适配 vue3 (app)
## 3.2.22021-08-10
- 新增 适配快手小程序
- 新增 同步 uni-ui
- uni-datetime-picker 新增 return-type 属性支持返回 date 日期对象
- uni-file-picker 修复 fileExtname属性不指定值报错的Bug
- uni-file-picker 修复 在某种场景下图片不回显的Bug
- uni-link 支持自定义插槽
- uni-calendar 修复 弹出层被 tabbar 遮盖 bug
- uni-dateformat 调整 默认时间不再是当前时间,而是显示'-'字符
- uni-datetime-picker 新增 适配 vue3
- uni-datetime-picker 新增 支持作为 uni-forms 子组件相关功能
- uni-datetime-picker 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug
- uni-datetime-picker 修复 type 属性动态赋值无效的 bug
- uni-datetime-picker 修复 ‘确认’按钮被 tabbar 遮盖 bug
- uni-datetime-picker 修复 组件未赋值时范围选左、右日历相同的 bug
- uni-datetime-picker 修复 范围选未正确显示当前值的 bug
- uni-datetime-picker 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug
- uni-file-picker 修复 auto-upload 属性失效的Bug
## 3.2.12021-07-31
- 新增 同步 uni-ui@1.3.8
## 3.2.02021-07-30
- 新增 同时兼容 vue2 & vue3
## 3.1.202021-07-30
- 新增 同时兼容 vue2 & vue3
## 3.1.172021-05-26
- 修复 3.1.16 依赖 sass 的问题
- 条件编译 nuve 不支持 css 属性
## 3.1.162021-05-26
- 修复 uni-data-checkbox 不关联服务空间的情况下组件报错的 Bug
## 3.1.122021-05-07
- hello-uniapp 发布插件市场

5
common/env.js Normal file
View File

@ -0,0 +1,5 @@
export const ENV = {
API_URL: 'http://10.0.2.2:12315',
APP_NAME: 'PdaRnTemplate',
VERSION: '1.0.0'
};

40
common/http.js Normal file
View File

@ -0,0 +1,40 @@
// Lightweight wrapper around uni.request to mimic ApiResponse<T>
import { ENV } from './env.js';
export async function httpGet(url, params = {}, extra = {}) {
const fullUrl = ENV.API_URL + url;
return new Promise((resolve, reject) => {
uni.request({
url: fullUrl,
method: 'GET',
data: params,
header: { 'Content-Type': 'application/json' },
timeout: extra.timeout || 5000,
success: (res) => {
resolve({ code: res.statusCode, data: res.data, message: res.errMsg });
},
fail: (err) => {
reject({ code: 500, data: null, message: err.errMsg || 'network error' });
},
});
});
}
export async function httpPost(url, data = {}, extra = {}) {
const fullUrl = ENV.API_URL + url;
return new Promise((resolve, reject) => {
uni.request({
url: fullUrl,
method: 'POST',
data,
header: { 'Content-Type': 'application/json' },
timeout: extra.timeout || 5000,
success: (res) => {
resolve({ code: res.statusCode, data: res.data, message: res.errMsg });
},
fail: (err) => {
reject({ code: 500, data: null, message: err.errMsg || 'network error' });
},
});
});
}

69
common/theme.js Normal file
View File

@ -0,0 +1,69 @@
export const theme = {
colors: {
aqua: '#05DCEF',
background: '#ffffff',
backgroundGray: '#F5F5F5',
text: '#333333',
textLight: '#666666',
border: '#dddddd',
error: '#ff3b30',
cyan: '#00FFFF',
lightGreen: '#7FFFAA',
gradients: {
primary: ['#05DCEF', '#7DE2F5', '#B8F2FF'],
contrast: ['#00F5A0', '#00D9F5'],
header: ['#05DCEF', '#7DE2F5'],
button: ['#05DCEF', '#7DE2F5']
},
chart: {
cyan: '#00FFFF',
lightGreen: '#7FFFAA'
}
},
fontSize: {
small: 12,
regular: 14,
medium: 16,
large: 18,
xlarge: 20,
xxlarge: 24,
title: 32
},
spacing: {
xs: 4,
small: 8,
medium: 16,
large: 24,
xl: 32
},
borderRadius: {
small: 4,
medium: 8,
large: 12,
xl: 16,
circle: 999
},
shadow: {
small: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 2
},
medium: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 4.65,
elevation: 4
},
large: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 6 },
shadowOpacity: 0.37,
shadowRadius: 7.49,
elevation: 6
}
}
};

1458
common/uni.css Normal file

File diff suppressed because it is too large Load Diff

58
common/wmsApi.js Normal file
View File

@ -0,0 +1,58 @@
import { httpGet, httpPost } from './http.js';
export const WmsApiClient = {
async test(timeout = 5000) {
const response = await httpGet('/wms/test/hello', {}, { timeout });
return response;
},
async emptyVehicleIn(vehicleNo, timeout = 5000) {
const response = await httpPost('/api/mobile/stockIn/emptyVehicleIn', { vehicleNo }, { timeout });
return response;
},
async getCanUseGoods(orderId, goodsId, timeout = 5000) {
const response = await httpPost('/api/mobile/stockIn/getCanUseGoods', { orderId, goodsId }, { timeout });
return response;
},
async getGoodsDetail(boxNo, timeout = 5000) {
const response = await httpGet('/api/mobile/stockIn/getGoodsDetail', { boxNo }, { timeout });
return response;
},
async bindingVehicleIn(data, timeout = 5000) {
const response = await httpPost('/api/mobile/stockIn/bindingVehicleIn', data, { timeout });
return response;
},
async getCuxData(timeout = 5000) {
const response = await httpGet('/api/mobile/stockIn/getCuxData', {}, { timeout });
return response;
},
async bindingVehicleInEbsOld(data, timeout = 5000) {
const response = await httpPost('/api/mobile/stockIn/bindingVehicleInEbsOld', data, { timeout });
return response;
},
async bindingVehicleInEbs(data, timeout = 5000) {
const response = await httpPost('/api/mobile/stockIn/bindingVehicleInEbs', data, { timeout });
return response;
},
async getOrderLines(data, timeout = 10000) {
const response = await httpPost('/api/mobile/stockIn/getOrderLines', data, { timeout });
return response;
},
async getSubInventory(timeout = 10000) {
const response = await httpGet('/api/mobile/stockIn/getSubInventory', {}, { timeout });
return response;
},
async getInventoryTask(vehicleNo, timeout = 5000) {
const response = await httpGet('/api/mobile/inventory/getInventoryTask', { vehicleNo }, { timeout });
return response;
},
};

42
index.html Normal file

File diff suppressed because one or more lines are too long

11
jest.config.js Normal file
View File

@ -0,0 +1,11 @@
module.exports = {
testTimeout: 20000,
reporters: [
'default'
],
watchPathIgnorePatterns: ['/node_modules/', '/dist/', '/.git/'],
moduleFileExtensions: ['js', 'json'],
rootDir: __dirname,
testMatch: ["<rootDir>/pages/**/*test.[jt]s?(x)"],
testPathIgnorePatterns: ['/node_modules/']
}

7
main.js Normal file
View File

@ -0,0 +1,7 @@
import App from './App'
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return { app }
}

191
manifest.json Normal file
View File

@ -0,0 +1,191 @@
{
"name" : "pda-uni-app-template",
"appid" : "com.baokai.pdaUniAppTemplate",
"description" : "应用描述",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"nvueCompiler" : "uni-app",
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"nvueLaunchMode" : "fast",
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {
"OAuth" : {},
"Payment" : {},
"Push" : {},
"Share" : {},
"Speech" : {},
"VideoPlayer" : {}
},
"distribute" : {
"android" : {
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.READ_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
"<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
]
},
"ios" : {
"UIBackgroundModes" : [ "audio" ],
"urlschemewhitelist" : [ "baidumap", "iosamap" ]
},
"sdkConfigs" : {
"speech" : {
"ifly" : {}
}
},
"orientation" : [ "portrait-primary" ]
},
"uniStatistics" : {
"enable" : true
}
},
"quickapp" : {},
"quickapp-native" : {
"icon" : "/static/logo.png",
"package" : "com.example.demo",
"features" : [
{
"name" : "system.clipboard"
}
]
},
"quickapp-webview" : {
"icon" : "/static/logo.png",
"package" : "com.example.demo",
"minPlatformVersion" : 1070,
"versionName" : "1.0.0",
"versionCode" : 100
},
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "演示定位能力"
}
},
"uniStatistics" : {
"enable" : true
}
},
"mp-alipay" : {
"usingComponents" : true,
"uniStatistics" : {
"enable" : true
}
},
"mp-baidu" : {
"usingComponents" : true,
"uniStatistics" : {
"enable" : true
},
"dynamicLib" : {
"editorLib" : {
"provider" : "swan-editor"
}
}
},
"mp-toutiao" : {
"usingComponents" : true,
"uniStatistics" : {
"enable" : true
}
},
"mp-jd" : {
"usingComponents" : true,
"uniStatistics" : {
"enable" : true
}
},
"h5" : {
"template" : "template.h5.html",
"router" : {
"mode" : "history",
"base" : ""
},
"sdkConfigs" : {
"maps" : {
"qqmap" : {
"key" : "TKUBZ-D24AF-GJ4JY-JDVM2-IBYKK-KEBCU"
}
}
},
"async" : {
"timeout" : 20000
},
"uniStatistics" : {
"enable" : true
}
},
"vueVersion" : "3",
"mp-kuaishou" : {
"uniStatistics" : {
"enable" : true
}
},
"mp-lark" : {
"uniStatistics" : {
"enable" : true
}
},
"mp-qq" : {
"uniStatistics" : {
"enable" : true
}
},
"quickapp-webview-huawei" : {
"uniStatistics" : {
"enable" : true
}
},
"quickapp-webview-union" : {
"uniStatistics" : {
"enable" : true
}
},
"uniStatistics" : {
"version" : "2",
"enable" : true
}
}

133
package.json Normal file
View File

@ -0,0 +1,133 @@
{
"id": "hello-uniapp",
"name": "hello-uniapp",
"displayName": "hello-uniapp 示例工程",
"version": "3.4.9",
"description": "uni-app 框架示例一套代码同时发行到iOS、Android、H5、小程序等多个平台请使用手机扫码快速体验 uni-app 的强大功能",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": "https://github.com/dcloudio/hello-uniapp.git",
"keywords": [
"hello-uniapp",
"uni-app",
"uni-ui",
"示例工程"
],
"author": "",
"license": "MIT",
"bugs": {
"url": "https://github.com/dcloudio/hello-uniapp/issues"
},
"homepage": "https://github.com/dcloudio/hello-uniapp#readme",
"dependencies": {},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "",
"type": "uniapp-template-project",
"darkmode": "x",
"i18n": "x",
"widescreen": "x"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "√",
"aliyun": "√",
"alipay": "x"
},
"client": {
"uni-app": {
"vue": {
"vue2": "√",
"vue3": "√"
},
"web": {
"safari": "√",
"chrome": "√"
},
"app": {
"vue": "√",
"nvue": "√",
"android": "√",
"ios": "√",
"harmony": "√"
},
"mp": {
"weixin": "√",
"alipay": "√",
"toutiao": "√",
"baidu": "√",
"kuaishou": "√",
"jd": "√",
"harmony": "√",
"qq": "√",
"lark": "√"
},
"quickapp": {
"huawei": "-",
"union": "-"
}
},
"uni-app-x": {
"web": {
"safari": "-",
"chrome": "-"
},
"app": {
"android": "-",
"ios": "-",
"harmony": "-"
},
"mp": {
"weixin": "-"
}
}
}
}
},
"uni-app": {
"scripts": {
"mp-dingtalk": {
"title": "钉钉小程序",
"env": {
"UNI_PLATFORM": "mp-alipay"
},
"define": {
"MP-DINGTALK": true
}
},
"hello-uniapp-demo": {
"title": "hello-uniapp 演示网站",
"env": {
"UNI_PLATFORM": "h5"
},
"define": {
"H5-DEMO": true
}
}
}
},
"engines": {
"HBuilderX": "^3.1.0",
"uni-app": "^4.03",
"uni-app-x": ""
}
}

71
pages.json Normal file
View File

@ -0,0 +1,71 @@
{
"pages": [
{
"path": "pages/login/index",
"style": {
"navigationBarTitleText": "登录",
"app-plus": {
"titleNView": false
},
"h5": {
"titleNView": false
}
}
},
{
"path": "pages/home/index",
"style": {
"navigationBarTitleText": "首页",
"app-plus": {
"titleNView": false
},
"h5": {
"titleNView": false
}
}
},
{
"path": "pages/stock-in/empty",
"style": {
"navigationBarTitleText": "空载具入库",
"app-plus": {
"titleNView": false
},
"h5": {
"titleNView": false
}
}
},
{
"path": "pages/stock-in/manual",
"style": {
"navigationBarTitleText": "手动码盘入库",
"app-plus": {
"titleNView": false
},
"h5": {
"titleNView": false
}
}
},
{
"path": "pages/test/index",
"style": {
"navigationBarTitleText": "测试页面",
"app-plus": {
"titleNView": false
},
"h5": {
"titleNView": false
}
}
}
],
"globalStyle": {
"pageOrientation": "portrait",
"navigationBarTitleText": "PDA",
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#05DCEF",
"backgroundColor": "#F5F5F5"
}
}

275
pages/home/index.vue Normal file
View File

@ -0,0 +1,275 @@
<template>
<view class="container">
<view class="header">
<view class="header-bg">
<view class="wave w1" />
<view class="wave w2" />
</view>
<button class="icon-btn" @click="toggleDrawer">
<i class="icon icon-menu" style="font-size:40rpx;color:#fff"></i>
</button>
<text class="header-title">WMS移动终端模板</text>
<button class="icon-btn" @click="noop">
<i class="icon icon-notifications" style="font-size:40rpx;color:#fff"></i>
</button>
</view>
<!-- Drawer Overlay -->
<view class="drawer-mask" :class="{ show: showDrawer }" @click="closeDrawer" />
<view class="drawer" :class="{ open: showDrawer }">
<view class="drawer-top">
<text class="drawer-title">导航</text>
</view>
<view class="drawer-list">
<button class="drawer-link" @click="nav('/pages/test/index')">
<i class="icon icon-menu"></i>
<text class="drawer-text">测试页面</text>
</button>
<button class="drawer-link" @click="nav('/pages/stock-in/empty')">
<i class="icon icon-local_shipping"></i>
<text class="drawer-text">空载具入库</text>
</button>
<button class="drawer-link" @click="nav('/pages/stock-in/manual')">
<i class="icon icon-local_shipping"></i>
<text class="drawer-text">手动入库</text>
</button>
</view>
</view><view class="content">
<view class="grid">
<view class="card" @click="go('/pages/test/index')">
<view class="action-icon">
<i class="icon icon-menu" style="font-size:48rpx;color:#fff"></i>
</view>
<text class="action-title">test</text>
</view>
<view class="card" @click="go('/pages/stock-in/empty')">
<view class="action-icon">
<i class="icon icon-local_shipping" style="font-size:48rpx;color:#fff"></i>
</view>
<text class="action-title">空载具入库</text>
</view>
<view class="card single" @click="go('/pages/stock-in/manual')">
<view class="action-icon">
<i class="icon icon-local_shipping" style="font-size:48rpx;color:#fff"></i>
</view>
<text class="action-title">手动入库</text>
</view>
</view>
<view class="section">
<text class="section-title">库存占用情况</text>
<view class="chart-row">
<view class="pie" />
<view class="legend">
<view class="legend-item">
<view class="dot" style="background:#00FFFF" />
<text class="legend-text">40 空闲</text>
</view>
<view class="legend-item">
<view class="dot" style="background:#7FFFAA" />
<text class="legend-text">60 占用</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
chartSize: 260, showDrawer: false
}
},
methods: {
noop() {}, toggleDrawer() { this.showDrawer = !this.showDrawer }, closeDrawer() { this.showDrawer = false }, nav(url) { this.showDrawer = false; this.go(url) },
go(url) {
uni.navigateTo({
url
})
},
arcPath(startRatio, endRatio) {
const start = this.polar(50, 50, 40, startRatio * 2 * Math.PI)
const end = this.polar(50, 50, 40, endRatio * 2 * Math.PI)
const large = endRatio - startRatio > 0.5 ? 1 : 0
return `M 50 50 L ${start.x} ${start.y} A 40 40 0 ${large} 1 ${end.x} ${end.y} Z`
},
polar(cx, cy, r, ang) {
return {
x: cx + r * Math.cos(ang),
y: cy + r * Math.sin(ang)
}
}
}
}
</script>
<style scoped>
.container {
min-height: 100vh;
background: var(--bg-gray);
}
.header {
height: 200rpx;
position: relative;
padding: 24rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.header-bg {
position: absolute;
inset: 0;
background: linear-gradient(180deg, var(--grad-primary-start), var(--grad-primary-mid));
}
.wave {
position: absolute;
left: 0;
right: 0;
height: 120rpx;
background: radial-gradient(ellipse at 50% 30%, rgba(255, 255, 255, .25), rgba(255, 255, 255, 0) 60%);
opacity: .6;
}
.w1 {
top: 10rpx
}
.w2 {
top: 80rpx
}
.icon-btn {
z-index: 1;
width: 64rpx;
height: 64rpx;
border-radius: 32rpx;
background: transparent;
border: none;
display: flex;
align-items: center;
justify-content: center;
}
.header-title {
z-index: 1;
color: #fff;
font-size: 34rpx;
font-weight: 600;
}
.content {
padding: 24rpx;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 24rpx;
}
.card {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 180rpx;
border-radius: 20rpx;
background: linear-gradient(90deg, var(--grad-contrast-start), var(--grad-contrast-end));
box-shadow: 0 8rpx 22rpx rgba(5, 220, 239, .25);
}
.card.single {
grid-column: span 2;
height: 180rpx;
}
.action-icon {
width: 96rpx;
height: 96rpx;
border-radius: 48rpx;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, .25);
margin-bottom: 12rpx;
}
.action-icon .icon {
color: #fff;
font-size: 48rpx
}
.action-title {
color: #fff;
font-size: 28rpx;
}
.section {
margin-top: 24rpx;
border-radius: 16rpx;
padding: 24rpx;
background: #fff;
}
.section-title {
color: var(--text-color);
font-size: 32rpx;
font-weight: 600;
margin-bottom: 16rpx;
}
.chart-row {
display: flex;
align-items: center;
}
.legend {
margin-left: 24rpx;
}
.legend-item {
display: flex;
align-items: center;
margin-bottom: 24rpx;
}
.dot {
width: 20rpx;
height: 20rpx;
border-radius: 10rpx;
margin-right: 12rpx;
}
.legend-text {
color: var(--text-light);
font-size: 28rpx;
}
.pie {
width: 280rpx;
height: 280rpx;
border-radius: 50%;
background: conic-gradient(#7FFFAA 0 60%, #00FFFF 60% 100%);
box-shadow: inset 0 0 0 0 #fff;
}
/* Drawer */
.drawer-mask { position: fixed; left:0; top:0; right:0; bottom:0; background: rgba(0,0,0,.28); opacity: 0; pointer-events: none; transition: opacity .22s ease; z-index: 998; }
.drawer-mask.show { opacity: 1; pointer-events: auto; }
.drawer { position: fixed; left:0; top:0; bottom:0; width: 460rpx; background: linear-gradient(180deg, #05DCEF 0%, #7DE2F5 60%, #FFFFFF 100%); box-shadow: 16rpx 0 32rpx rgba(0,0,0,.15); transform: translateX(-104%); transition: transform .26s cubic-bezier(.2,.8,.2,1); z-index: 999; border-top-right-radius: 24rpx; border-bottom-right-radius: 24rpx; overflow: hidden; display:flex; flex-direction: column; }
.drawer.open { transform: translateX(0); }
.drawer-top { padding: calc(env(safe-area-inset-top, 0) + 24rpx) 16rpx 8rpx 24rpx; }
.drawer-title { color:#fff; font-size: 44rpx; font-weight: 800; letter-spacing: 1rpx; }
.drawer-list { flex:1; overflow:auto; padding: 8rpx 0 24rpx 0; display:flex; flex-direction:column; }
.drawer-link { width:100%; height: 110rpx; border:none; border-radius: 0; background: transparent; display:flex; align-items:center; justify-content:flex-start; padding: 0 24rpx; }
.drawer-link:active { background: rgba(255,255,255,.12); }
.drawer-link .icon { color:#ffffff; font-size: 38rpx; margin-right: 16rpx; }
.drawer-text { color:#fff; font-size: 34rpx; font-weight: 600; }</style>

159
pages/login/index.vue Normal file
View File

@ -0,0 +1,159 @@
<template>
<view class="container">
<view class="hero">
<view class="hero-bg">
<view class="wave w1" />
<view class="wave w2" />
</view>
<text class="title">仓库模板</text>
<text class="subtitle">智能仓储管理系统</text>
<view class="logo-wrap">
<view class="logo"><text>BK</text></view>
</view>
<button class="login-btn" @click="goHome">进入系统</button>
</view>
<view class="footer"><text>© 2025 菲达宝开</text></view>
</view>
</template>
<script>
export default {
methods: {
goHome() {
uni.reLaunch({
url: '/pages/home/index'
})
}
}
}
</script>
<style scoped>
.container {
min-height: 100vh;
background: linear-gradient(180deg, #9BEAF8 0%, #E6FBFF 60%, #FFFFFF 100%);
display: flex;
flex-direction: column;
}
.hero {
flex: 1;
align-items: center;
display: flex;
flex-direction: column;
position: relative;
}
.hero-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 68vh;
background: linear-gradient(180deg, #05DCEF 0%, #7DE2F5 60%, #FFFFFF 100%);
z-index: 0;
}
.hero-bg::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 65%, rgba(255, 255, 255, .18) 80%, rgba(255, 255, 255, .32) 92%, rgba(255, 255, 255, .45) 100%);
pointer-events: none;
}
.wave {
position: absolute;
left: 0;
right: 0;
height: 140rpx;
background: radial-gradient(ellipse at 50% 0%, rgba(255, 255, 255, .35), rgba(255, 255, 255, 0) 60%);
opacity: .5;
}
.w1 {
bottom: 200rpx;
}
.w2 {
bottom: 120rpx;
}
.title {
margin-top: 160rpx;
color: #fff;
font-size: 64rpx;
font-weight: 700;
position: relative;
z-index: 1;
}
.subtitle {
color: #fff;
font-size: 30rpx;
opacity: .95;
margin-top: 12rpx;
position: relative;
z-index: 1;
}
.logo {
width: 180rpx;
height: 180rpx;
background: #fff;
border-radius: 90rpx;
align-items: center;
justify-content: center;
display: flex;
box-shadow: 0 12rpx 28rpx rgba(0, 0, 0, .12);
}
.logo text {
color: var(--grad-primary-start);
font-size: 56rpx;
font-weight: 700;
}
.login-btn {
position: absolute;
top: 70vh;
transform: translateY(-10%);
width: 600rpx;
height: 96rpx;
line-height: 96rpx;
text-align: center;
color: #fff;
border: none;
border-radius: 48rpx;
background: linear-gradient(90deg, var(--grad-primary-start), var(--grad-primary-mid));
box-shadow: 0 10rpx 24rpx rgba(5, 220, 239, .35);
font-size: 32rpx;
z-index: 1;
}
.footer {
padding: 40rpx 0 60rpx;
align-items: center;
display: flex;
justify-content: center;
}
.footer text {
color: #8a8a8a;
font-size: 24rpx;
}
.logo-wrap {
position: absolute;
top: 56vh;
transform: translateY(-50%);
z-index: 2;
}
</style>

202
pages/stock-in/empty.vue Normal file
View File

@ -0,0 +1,202 @@
<template>
<view class="container">
<view class="header">
<button class="back" @click="back"><i class="icon icon-arrow_back"
style="color:#05DCEF;font-size:36rpx"></i></button>
<text class="title">空载具入库</text>
</view>
<view class="content">
<view class="tip">
<view class="tip-icon"><i class="icon icon-info" style="color:#05DCEF"></i></view>
<text class="tip-text">请扫描或输入载具号进行空载具入库操作</text>
</view>
<view class="field">
<text class="label">载具号 <text class="required">*</text></text>
<view class="input-wrap">
<i class="left-icon icon icon-qr_code_2" style="font-size:36rpx"></i>
<input class="input" placeholder="请扫描或输入载具号" v-model="vehicleNo" />
</view>
</view>
<button class="submit" :disabled="loading || !vehicleNo.trim()" @click="submit">
<i class="icon icon-save" style="margin-right:12rpx"></i> 确认入库
</button>
</view>
</view>
</template>
<script>
import {
WmsApiClient
} from '@/common/wmsApi.js';
import {
DialogUtils
} from '@/utils/dialog.js';
export default {
data() {
return {
vehicleNo: '',
loading: false
}
},
methods: {
back() {
uni.navigateBack()
},
async submit() {
const plate = (this.vehicleNo || '').trim();
if (!plate) {
return
}
this.loading = true
try {
const res = await WmsApiClient.emptyVehicleIn(plate)
if (res.code === 200) {
DialogUtils.showSuccessMessage('成功', '空载具入库成功')
this.vehicleNo = ''
} else {
DialogUtils.showWarningMessage('提示', res.message || '提交失败')
}
} catch (e) {
DialogUtils.showErrorMessage('错误', typeof e === 'string' ? e : (e.message || '网络错误'))
} finally {
this.loading = false
}
}
}
}
</script>
<style scoped>
.header {
position: relative;
height: 120rpx;
padding: 0;
background: linear-gradient(90deg, var(--grad-primary-start), var(--grad-primary-mid));
display: flex;
align-items: center;
justify-content: center;
}
.container {
min-height: 100vh;
background: #F5F5F5;
}
.title {
color: #fff;
font-size: 32rpx;
font-weight: 600;
}
.content {
padding: 24rpx;
}
.tip {
flex-direction: row;
display: flex;
align-items: center;
background: #f2fdff;
border-radius: 12rpx;
padding: 24rpx;
color: #333;
margin-bottom: 28rpx;
}
.tip-icon {
width: 40rpx;
height: 40rpx;
border-radius: 20rpx;
background: #e6f7ff;
text-align: center;
line-height: 40rpx;
margin-right: 12rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
}
.tip-text {
color: #333;
font-size: 26rpx;
}
.field {
margin-bottom: 20rpx;
}
.label {
color: #333;
font-size: 30rpx;
margin-bottom: 12rpx;
display: block;
}
.required {
color: #ff4d4f
}
.input-wrap {
height: 96rpx;
border-radius: 12rpx;
border: 1px solid #e6e6e6;
background: #fff;
padding: 0 20rpx;
display: flex;
align-items: center;
}
.left-icon {
color: #05DCEF;
font-size: 36rpx;
margin-right: 12rpx;
}
.input {
flex: 1;
height: 100%;
font-size: 30rpx;
}
.submit {
width: 100%;
height: 92rpx;
border: none;
color: #fff;
border-radius: 46rpx;
background: linear-gradient(90deg, var(--grad-primary-start), var(--grad-primary-mid));
font-size: 32rpx;
box-shadow: 0 8rpx 22rpx rgba(5, 220, 239, .25);
text-align: center;
margin-top: 28rpx;
display: flex;
align-items: center;
justify-content: center;
}
.submit[disabled] {
opacity: .6
}
.back {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 80rpx;
height: 64rpx;
line-height: 64rpx;
border: none;
color: #05DCEF;
background: #fff;
border-radius: 12rpx;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
</style>

394
pages/stock-in/manual.vue Normal file
View File

@ -0,0 +1,394 @@
<template>
<view class="container">
<view class="header">
<button class="back" @click="back"><i class="icon icon-arrow_back"
style="color:#05DCEF;font-size:36rpx"></i></button>
<text class="title">手动码盘入库</text>
</view>
<view class="content">
<!-- 顶部提示 -->
<view class="tip">
<view class="tip-icon"><i class="icon icon-info" style="color:#05DCEF"></i></view>
<text class="tip-text">请先扫描载具号然后添加物料信息进行码盘入库</text>
</view>
<!-- 载具条码 -->
<view class="field">
<text class="label">载具号</text>
<view class="input-wrap">
<i class="left-icon icon icon-qr_code_2" style="font-size:36rpx"></i>
<input class="input" placeholder="请扫描或输入载具号" v-model="vehicleCode" @blur="resolveVehicle" />
</view>
</view>
<!-- 物料条码 -->
<view class="field">
<text class="label">物料条码</text>
<view class="input-wrap">
<i class="left-icon icon icon-qr_code_2" style="font-size:36rpx"></i>
<input class="input" placeholder="请扫描物料二维码" v-model="goodsCode" @blur="resolveCode" />
</view>
</view>
<!-- 操作按钮组 -->
<view class="button-row">
<button class="btn" @click="addGoods"><i class="icon icon-add"
style="margin-right:8rpx"></i>添加物料</button>
<button class="btn" @click="finish"><i class="icon icon-task_alt"
style="margin-right:8rpx"></i>码盘完成</button>
</view>
<!-- 列表统计 -->
<view class="list-header"><text>已添加物料 ({{ packageData.length }})</text></view>
<!-- 物料卡片列表尽量还原 RN 的布局与字段 -->
<view class="list">
<view v-for="item in packageData" :key="item.id" class="card">
<view class="card-header">
<view class="card-header-left">
<text class="card-header-text">批次{{ item.batch }}</text>
<text class="card-header-text">物料{{ item.segment1 }}</text>
</view>
<view class="card-actions">
<button class="card-action-button" @click="editItem(item)"><i
class="icon icon-edit"></i></button>
<button class="card-action-button" @click="deleteItem(item.id)"><i
class="icon icon-delete"></i></button>
</view>
</view>
<view class="card-content">
<view class="card-row">
<view class="card-field">
<text class="card-label">物料编码</text>
<text class="card-value">{{ item.segment1 }}</text>
</view>
<view class="card-field">
<text class="card-label">物料ID</text>
<text class="card-value">{{ item.itemId }}</text>
</view>
</view>
<view class="card-row">
<view class="card-field">
<text class="card-label">数量</text>
<view class="editable-value">
<input class="num-input" type="number" v-model="item.quantity" />
</view>
</view>
<view class="card-field">
<text class="card-label">重量(kg)</text>
<view class="editable-value">
<input class="num-input" type="number" v-model="item.weight" />
</view>
</view>
</view>
<view class="card-row">
<view class="card-field">
<text class="card-label">产品数据</text>
<text class="card-value">{{ item.productData }}</text>
</view>
<view class="card-field">
<text class="card-label">区域/库位</text>
<text class="card-value">{{ item.area || '-' }}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
DialogUtils
} from '@/utils/dialog.js'
let nextId = 1
export default {
data() {
return {
vehicleCode: '',
goodsCode: '',
packageData: []
}
},
methods: {
back() {
uni.navigateBack()
},
resolveVehicle() {
const code = (this.vehicleCode || '').trim()
if (!code) return
if (code.length === 15) {
DialogUtils.showSuccessMessage('扫描成功', `车辆码: ${code}`)
} else {
DialogUtils.showErrorMessage('校验失败', '无效的车辆码长度')
}
},
resolveCode() {
const code = (this.goodsCode || '').trim()
if (!code) return
const parts = code.split(',')
if (![6, 7, 8].includes(parts.length)) {
DialogUtils.showWarningMessage('提示', '物料条码格式不正确')
return
}
const p = parts.slice(0, 6)
const item = {
id: String(nextId++),
segment1: p[0],
itemId: p[1],
batch: p[2],
quantity: p[3],
weight: p[4],
productData: p[5],
area: ''
}
if (this.packageData.some(x => x.batch === item.batch)) {
DialogUtils.showWarningMessage('重复', '该物料已在列表中')
} else {
this.packageData.push(item)
}
this.goodsCode = ''
},
addGoods() {
this.resolveCode()
},
deleteItem(id) {
this.packageData = this.packageData.filter(x => x.id !== id)
},
editItem(item) {
DialogUtils.toast('可编辑数量与重量')
},
finish() {
DialogUtils.toast('码盘完成')
}
}
}
</script>
<style scoped>
.header {
position: relative;
height: 120rpx;
padding: 0;
background: linear-gradient(90deg, var(--grad-primary-start), var(--grad-primary-mid));
display: flex;
align-items: center;
justify-content: center;
}
.container {
min-height: 100vh;
background: #F5F5F5;
}
.title {
color: #fff;
font-size: 32rpx;
font-weight: 600;
}
.content {
padding: 24rpx;
}
.tip {
flex-direction: row;
display: flex;
align-items: center;
background: #f2fdff;
border-radius: 12rpx;
padding: 24rpx;
color: #333;
margin-bottom: 28rpx;
}
.tip-icon {
width: 40rpx;
height: 40rpx;
border-radius: 20rpx;
background: #e6f7ff;
text-align: center;
line-height: 40rpx;
margin-right: 12rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
}
.tip-text {
color: #333;
font-size: 26rpx;
}
.field {
margin-bottom: 20rpx;
}
.label {
color: #333;
font-size: 30rpx;
margin-bottom: 12rpx;
display: block;
}
.input-wrap {
height: 96rpx;
border-radius: 12rpx;
border: 1px solid #e6e6e6;
background: #fff;
padding: 0 20rpx;
display: flex;
align-items: center;
}
.left-icon {
color: #05DCEF;
font-size: 36rpx;
margin-right: 12rpx;
}
.input {
flex: 1;
height: 100%;
font-size: 30rpx;
}
.button-row {
display: flex;
gap: 24rpx;
margin: 24rpx 0;
}
.btn {
flex: 1;
height: 92rpx;
border: none;
color: #fff;
border-radius: 46rpx;
background: linear-gradient(90deg, var(--grad-primary-start), var(--grad-primary-mid));
font-size: 30rpx;
box-shadow: 0 8rpx 22rpx rgba(5, 220, 239, .25);
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.list-header {
margin-top: 8rpx;
color: #333;
font-size: 28rpx;
}
.card {
background: #fff;
border-radius: 12rpx;
padding: 0;
margin-top: 16rpx;
overflow: hidden;
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, .06)
}
.card-header {
flex-direction: row;
display: flex;
align-items: center;
justify-content: space-between;
padding: 16rpx;
border-bottom: 1px solid rgba(0, 0, 0, .08);
background: linear-gradient(90deg, var(--grad-primary-start), var(--grad-primary-mid));
}
.card-header-left {
flex: 1
}
.card-header-text {
color: #fff;
font-size: 24rpx;
margin-right: 16rpx
}
.card-actions {
display: flex;
gap: 8rpx
}
.card-action-button {
width: 64rpx;
height: 64rpx;
border: none;
border-radius: 8rpx;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.card-content {
padding: 16rpx;
background: #fff
}
.card-row {
display: flex;
gap: 16rpx;
margin-bottom: 12rpx
}
.card-field {
flex: 1
}
.card-label {
color: #888;
font-size: 24rpx;
margin-bottom: 4rpx;
display: block
}
.card-value {
color: #333;
font-size: 28rpx
}
.editable-value {
display: flex;
align-items: center;
gap: 8rpx
}
.num-input {
width: 220rpx;
height: 64rpx;
border: 1px solid #e6e6e6;
border-radius: 8rpx;
padding: 0 12rpx;
font-size: 28rpx
}
.back {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 80rpx;
height: 64rpx;
line-height: 64rpx;
border: none;
color: #05DCEF;
background: #fff;
border-radius: 12rpx;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
</style>

Binary file not shown.

BIN
static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

28
static/mui-icons.css Normal file
View File

@ -0,0 +1,28 @@
@font-face {
font-family: 'muiicon';
src: url('/static/fonts/MaterialIcons-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
.icon { font-family: 'muiicon' !important; font-style: normal; font-weight: normal; display: inline-block; line-height: 1; text-transform: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
.icon-menu:before { content: "\e5d2"; }
.icon-notifications:before { content: "\e7f4"; }
.icon-local_shipping:before { content: "\e558"; }
.icon-inventory:before { content: "\e179"; }
.icon-arrow_back:before { content: "\e5c4"; }
.icon-save:before { content: "\e161"; }
.icon-qr_code_2:before { content: "\f00a"; }
.icon-info:before { content: "\e88e"; }
.icon-add:before { content: "\e145"; }
.icon-task_alt:before { content: "\e2e6"; }
.icon-edit:before { content: "\e3c9"; }
.icon-delete:before { content: "\e872"; }
@font-face {
font-family: 'Material Icons Local';
src: url('/static/fonts/MaterialIcons-Regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
font-display: swap;
}
.mi{font-family:'Material Icons Local','Material Icons';font-weight:normal;font-style:normal;font-size:inherit;display:inline-block;line-height:1;letter-spacing:normal;text-transform:none;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-feature-settings:'liga';-webkit-font-feature-settings:'liga';text-rendering:optimizeLegibility}

BIN
static/uni.ttf Normal file

Binary file not shown.

1
static/web/image-resize-3.0.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

7
static/web/quill-1.3.7.min.js vendored Normal file

File diff suppressed because one or more lines are too long

61
template.h5.html Normal file
View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<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>
<%= htmlWebpackPlugin.options.title %>
</title>
<!-- 正式发布的时候使用,开发期间不启用。↓ -->
<!-- <script src="/h5/touch-emulator.js"></script>
<script>
TouchEmulator();
if (document.documentElement.clientWidth > 1024) {
window.location.href = '/h5/pcguide.html#'+location.pathname+location.search;
}
</script>
<style>
::-webkit-scrollbar{
display: none;
}
</style>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?";// 百度统计key
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script> -->
<!-- 正式发布的时候使用,开发期间不启用。↑ -->
<script>
// document.addEventListener('DOMContentLoaded', function() {
// document.documentElement.style.fontSize = document.documentElement.clientWidth / 20 + 'px'
// })
</script>
<script src="<%= BASE_URL %>static/web/image-resize-3.0.1.min.js"></script>
<script src="<%= BASE_URL %>static/web/quill-1.3.7.min.js"></script>
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
</head>
<body>
<!-- 该文件为 H5 平台的模板 HTML并非应用入口。 -->
<!-- 请勿在此文件编写页面代码或直接运行此文件。 -->
<!-- 详见文档https://uniapp.dcloud.io/collocation/manifest?id=h5-template -->
<noscript>
<strong>Please enable JavaScript to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script>
/*BAIDU_STAT*/
</script>
</body>
</html>

86
uni.scss Normal file
View File

@ -0,0 +1,86 @@
/**
* 这里是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:#e5e5e5;
/* 尺寸变量 */
/* 文字尺寸 */
$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;
:root {
--grad-primary-start: #05DCEF;
--grad-primary-mid: #7DE2F5;
--grad-primary-end: #B8F2FF;
--grad-contrast-start: #00F5A0;
--grad-contrast-end: #00D9F5;
--bg-gray: #F5F5F5;
--text-color: #333333;
--text-light: #666666;
}

32
utils/dialog.js Normal file
View File

@ -0,0 +1,32 @@
export const DialogUtils = {
showSuccessMessage(title = '成功', message = '', confirmText = '我知道了') {
uni.showModal({
title,
content: message,
showCancel: false,
confirmText
});
},
showWarningMessage(title = '提示', message = '', confirmText = '我知道了') {
uni.showModal({
title,
content: message,
showCancel: false,
confirmText
});
},
showErrorMessage(title = '错误', message = '', confirmText = '我知道了') {
uni.showModal({
title,
content: message,
showCancel: false,
confirmText
});
},
toast(message, icon = 'none') {
uni.showToast({
title: message,
icon
});
},
};