diff --git a/shierfeng-fastapi-app/README.md b/shierfeng-fastapi-app/README.md index c113185..ee0578a 100644 --- a/shierfeng-fastapi-app/README.md +++ b/shierfeng-fastapi-app/README.md @@ -23,6 +23,18 @@ > > 另外谨慎升级 `package.json` 中锁定的 `pinia`/`vue`/`@vue/*` 相关包的版本,新版本可能 `uni-app` 没有兼容,造成一些奇怪的 bug +### 配置 PDA 后端地址 + +PDA 默认请求本机 `http://localhost:9099`,仅适用于后端运行在同一设备的本地开发。部署到独立 PDA 或局域网服务器时,在构建环境注入 `VITE_APP_BASE_API`: + +```bash +VITE_APP_BASE_API=http://<服务器地址>:9099 pnpm run build:h5 +``` + +不要把包含真实凭据的环境文件或地址配置提交到仓库。 + +PDA 测试模式、批次授权和失效回退规则请阅读[测试数据批次操作说明](../docs/test-data-batch-operations.md)。PDA 只允许选择后端返回的 ACTIVE 授权批次,退出登录会清除本地批次上下文。 + ### vscode 使用 `vscode` 的开发者,请先安装 [Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) 智能提示与感应插件 diff --git a/shierfeng-fastapi-app/package.json b/shierfeng-fastapi-app/package.json index 75c2e4a..c30cf7b 100644 --- a/shierfeng-fastapi-app/package.json +++ b/shierfeng-fastapi-app/package.json @@ -3,6 +3,7 @@ "version": "1.9.0", "packageManager": "pnpm@10.28.1", "scripts": { + "test:business": "node --test tests/business-contract.test.mjs", "dev": "uni -p mp-weixin", "build": "npm run build:mp-weixin", "dev:app": "uni -p app", diff --git a/shierfeng-fastapi-app/src/api/business/filling.js b/shierfeng-fastapi-app/src/api/business/filling.js new file mode 100644 index 0000000..22782b0 --- /dev/null +++ b/shierfeng-fastapi-app/src/api/business/filling.js @@ -0,0 +1,38 @@ +import request from "@/utils/request"; + +export function listFilling(query) { + return request({ + url: "/business/filling/list", + method: "get", + params: query, + }); +} + +export function getFillingStrainOptions() { + return request({ + url: "/business/filling/strain-options", + method: "get", + }); +} + +export function scanFillingPallet(qrToken) { + return request({ + url: "/business/filling/scan/" + qrToken, + method: "get", + }); +} + +export function getFilling(fillingId) { + return request({ + url: "/business/filling/" + fillingId, + method: "get", + }); +} + +export function addFilling(data) { + return request({ + url: "/business/filling", + method: "post", + data, + }); +} diff --git a/shierfeng-fastapi-app/src/api/business/inbound.js b/shierfeng-fastapi-app/src/api/business/inbound.js new file mode 100644 index 0000000..264d13b --- /dev/null +++ b/shierfeng-fastapi-app/src/api/business/inbound.js @@ -0,0 +1,56 @@ +import request from "@/utils/request"; + +export function listInbound(query) { + return request({ + url: "/business/inbound/list", + method: "get", + params: query, + }); +} + +export function getInboundWarehouseOptions() { + return request({ + url: "/business/inbound/warehouse-options", + method: "get", + }); +} + +export function scanInboundPallet(qrToken, query) { + return request({ + url: "/business/inbound/scan/" + qrToken, + method: "get", + params: query, + }); +} + +export function getInbound(inboundId) { + return request({ + url: "/business/inbound/" + inboundId, + method: "get", + }); +} + +export function addInbound(data) { + return request({ + url: "/business/inbound", + method: "post", + data, + }); +} + +export function updateInbound(data) { + return request({ + url: "/business/inbound", + method: "put", + data, + }); +} + +export function confirmInbound(inboundId, data) { + return request({ + url: "/business/inbound/" + inboundId + "/confirm", + method: "put", + data, + headers: { repeatSubmit: false }, + }); +} diff --git a/shierfeng-fastapi-app/src/api/business/return.js b/shierfeng-fastapi-app/src/api/business/return.js new file mode 100644 index 0000000..e1f29a3 --- /dev/null +++ b/shierfeng-fastapi-app/src/api/business/return.js @@ -0,0 +1,47 @@ +import request from "@/utils/request"; + +export function listReturn(query) { + return request({ + url: "/business/return/list", + method: "get", + params: query, + }); +} + +export function getReturnWarehouseOptions() { + return request({ + url: "/business/return/warehouse-options", + method: "get", + }); +} + +export function scanReturnPallet(qrToken, query) { + return request({ + url: "/business/return/scan/" + qrToken, + method: "get", + params: query, + }); +} + +export function requestReturn(data) { + return request({ + url: "/business/return/request", + method: "post", + data, + }); +} + +export function getReturn(returnId) { + return request({ + url: "/business/return/" + returnId, + method: "get", + }); +} + +export function confirmReturn(returnId, data) { + return request({ + url: "/business/return/" + returnId + "/confirm", + method: "put", + data, + }); +} diff --git a/shierfeng-fastapi-app/src/api/business/shipment.js b/shierfeng-fastapi-app/src/api/business/shipment.js new file mode 100644 index 0000000..c3c9753 --- /dev/null +++ b/shierfeng-fastapi-app/src/api/business/shipment.js @@ -0,0 +1,62 @@ +import request from "@/utils/request"; + +export function listShipment(query) { + return request({ + url: "/business/shipment/list", + method: "get", + params: query, + }); +} + +export function getShipmentWarehouseOptions() { + return request({ + url: "/business/shipment/warehouse-options", + method: "get", + }); +} + +export function getShipmentSiteOptions() { + return request({ + url: "/business/shipment/site-options", + method: "get", + }); +} + +export function scanShipmentPallet(qrToken, query) { + return request({ + url: "/business/shipment/scan/" + qrToken, + method: "get", + params: query, + }); +} + +export function getShipment(shipmentId) { + return request({ + url: "/business/shipment/" + shipmentId, + method: "get", + }); +} + +export function addShipment(data) { + return request({ + url: "/business/shipment", + method: "post", + data, + }); +} + +export function updateShipment(data) { + return request({ + url: "/business/shipment", + method: "put", + data, + }); +} + +export function confirmShipment(shipmentId, data) { + return request({ + url: "/business/shipment/" + shipmentId + "/confirm", + method: "put", + data, + }); +} diff --git a/shierfeng-fastapi-app/src/api/business/usage.js b/shierfeng-fastapi-app/src/api/business/usage.js new file mode 100644 index 0000000..07a25e6 --- /dev/null +++ b/shierfeng-fastapi-app/src/api/business/usage.js @@ -0,0 +1,39 @@ +import request from "@/utils/request"; + +export function listUsage(query) { + return request({ + url: "/business/usage/list", + method: "get", + params: query, + }); +} + +export function getUsageLineOptions(siteId) { + return request({ + url: "/business/usage/line-options", + method: "get", + params: { siteId }, + }); +} + +export function scanUsagePallet(qrToken) { + return request({ + url: "/business/usage/scan/" + qrToken, + method: "get", + }); +} + +export function getUsage(usageId) { + return request({ + url: "/business/usage/" + usageId, + method: "get", + }); +} + +export function addUsage(data) { + return request({ + url: "/business/usage", + method: "post", + data, + }); +} diff --git a/shierfeng-fastapi-app/src/api/system/testBatch.js b/shierfeng-fastapi-app/src/api/system/testBatch.js new file mode 100644 index 0000000..6b800f3 --- /dev/null +++ b/shierfeng-fastapi-app/src/api/system/testBatch.js @@ -0,0 +1,9 @@ +import request from "@/utils/request"; + +// PDA 只读取当前登录用户被授权且仍处于 ACTIVE 状态的批次。 +export function listAvailableTestBatches() { + return request({ + url: "/system/test-batch/options", + method: "get", + }); +} diff --git a/shierfeng-fastapi-app/src/components/business/PalletScanInput.vue b/shierfeng-fastapi-app/src/components/business/PalletScanInput.vue new file mode 100644 index 0000000..031957a --- /dev/null +++ b/shierfeng-fastapi-app/src/components/business/PalletScanInput.vue @@ -0,0 +1,115 @@ + + + diff --git a/shierfeng-fastapi-app/src/components/business/TestBatchBanner.vue b/shierfeng-fastapi-app/src/components/business/TestBatchBanner.vue new file mode 100644 index 0000000..09daf4c --- /dev/null +++ b/shierfeng-fastapi-app/src/components/business/TestBatchBanner.vue @@ -0,0 +1,22 @@ + + + diff --git a/shierfeng-fastapi-app/src/components/business/TestBatchModeSwitch.vue b/shierfeng-fastapi-app/src/components/business/TestBatchModeSwitch.vue new file mode 100644 index 0000000..3e48260 --- /dev/null +++ b/shierfeng-fastapi-app/src/components/business/TestBatchModeSwitch.vue @@ -0,0 +1,153 @@ + + + diff --git a/shierfeng-fastapi-app/src/config.js b/shierfeng-fastapi-app/src/config.js index 658b12d..67a148f 100644 --- a/shierfeng-fastapi-app/src/config.js +++ b/shierfeng-fastapi-app/src/config.js @@ -1,6 +1,7 @@ // 应用全局配置 export default { - baseUrl: "http://localhost:9099", + // PDA 部署到独立设备时由构建环境注入服务器地址;本地开发保留回环地址。 + baseUrl: import.meta.env.VITE_APP_BASE_API || "http://localhost:9099", // 应用信息 appInfo: { // 应用名称 diff --git a/shierfeng-fastapi-app/src/main.ts b/shierfeng-fastapi-app/src/main.ts index 255aa09..2aef405 100644 --- a/shierfeng-fastapi-app/src/main.ts +++ b/shierfeng-fastapi-app/src/main.ts @@ -5,10 +5,24 @@ import store from "./store"; // store import { install } from "./plugins"; // plugins import "./permission"; // permission import { useDict } from "@/utils/dict"; +import { useTestBatchStore } from "./store"; + +let testBatchUnavailableListenerRegistered = false; + +function registerTestBatchUnavailableListener() { + if (testBatchUnavailableListenerRegistered || typeof uni.$on !== "function") { + return; + } + testBatchUnavailableListenerRegistered = true; + uni.$on("test-batch-unavailable", () => { + useTestBatchStore().leaveTestMode(); + }); +} export function createApp() { const app = createSSRApp(App); app.use(store); + registerTestBatchUnavailableListener(); app.config.globalProperties.useDict = useDict; install(app); return { diff --git a/shierfeng-fastapi-app/src/pages.json b/shierfeng-fastapi-app/src/pages.json index c5e305f..eeb1e3c 100644 --- a/shierfeng-fastapi-app/src/pages.json +++ b/shierfeng-fastapi-app/src/pages.json @@ -25,6 +25,36 @@ "navigationBarTitleText": "工作台" } }, + { + "path": "pages/business/inbound/index", + "style": { + "navigationBarTitleText": "仓库入库" + } + }, + { + "path": "pages/business/filling/index", + "style": { + "navigationBarTitleText": "托盘装填" + } + }, + { + "path": "pages/business/shipment/index", + "style": { + "navigationBarTitleText": "发货出库" + } + }, + { + "path": "pages/business/usage/index", + "style": { + "navigationBarTitleText": "现场使用" + } + }, + { + "path": "pages/business/return/index", + "style": { + "navigationBarTitleText": "退回仓库" + } + }, { "path": "pages/mine/index", "style": { diff --git a/shierfeng-fastapi-app/src/pages/business/filling/index.vue b/shierfeng-fastapi-app/src/pages/business/filling/index.vue new file mode 100644 index 0000000..2b9cf5f --- /dev/null +++ b/shierfeng-fastapi-app/src/pages/business/filling/index.vue @@ -0,0 +1,364 @@ + + + diff --git a/shierfeng-fastapi-app/src/pages/business/inbound/index.vue b/shierfeng-fastapi-app/src/pages/business/inbound/index.vue new file mode 100644 index 0000000..00e5f8e --- /dev/null +++ b/shierfeng-fastapi-app/src/pages/business/inbound/index.vue @@ -0,0 +1,486 @@ + + + diff --git a/shierfeng-fastapi-app/src/pages/business/return/index.vue b/shierfeng-fastapi-app/src/pages/business/return/index.vue new file mode 100644 index 0000000..6b078d1 --- /dev/null +++ b/shierfeng-fastapi-app/src/pages/business/return/index.vue @@ -0,0 +1,560 @@ + + + diff --git a/shierfeng-fastapi-app/src/pages/business/shipment/index.vue b/shierfeng-fastapi-app/src/pages/business/shipment/index.vue new file mode 100644 index 0000000..b1d21b6 --- /dev/null +++ b/shierfeng-fastapi-app/src/pages/business/shipment/index.vue @@ -0,0 +1,549 @@ + + + diff --git a/shierfeng-fastapi-app/src/pages/business/usage/index.vue b/shierfeng-fastapi-app/src/pages/business/usage/index.vue new file mode 100644 index 0000000..3455777 --- /dev/null +++ b/shierfeng-fastapi-app/src/pages/business/usage/index.vue @@ -0,0 +1,380 @@ + + + diff --git a/shierfeng-fastapi-app/src/pages/login.vue b/shierfeng-fastapi-app/src/pages/login.vue index 413b8b9..73fd973 100644 --- a/shierfeng-fastapi-app/src/pages/login.vue +++ b/shierfeng-fastapi-app/src/pages/login.vue @@ -135,7 +135,7 @@ const captchaEnabled = ref(true); const register = ref(false); const loginForm = ref({ username: "admin", - password: "admin123", + password: "", code: "", uuid: "", }); diff --git a/shierfeng-fastapi-app/src/pages/work/index.vue b/shierfeng-fastapi-app/src/pages/work/index.vue index 0d8072a..a01d346 100644 --- a/shierfeng-fastapi-app/src/pages/work/index.vue +++ b/shierfeng-fastapi-app/src/pages/work/index.vue @@ -2,6 +2,8 @@ + + + + + + + 现场业务 + + + + + + + + + {{ entry.title }} + + + {{ entry.description }} + + + + + + @@ -202,7 +234,8 @@