├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .hbuilderx └── launch.json ├── LICENSE ├── README.md ├── index.html ├── merge.sh ├── package.json ├── src ├── App.vue ├── base │ ├── AbstractBaseService.ts │ ├── BaseEntity.ts │ └── bill │ │ ├── AbstractBaseBillDetailService.ts │ │ ├── AbstractBaseBillEntity.ts │ │ ├── AbstractBaseBillService.ts │ │ └── detail │ │ └── AbstractBaseBillDetailEntity.ts ├── component │ ├── BillDetail.vue │ ├── TimeCell.vue │ ├── form │ │ └── NumberInput.vue │ └── index.ts ├── config │ ├── AppConfig.ts │ ├── AppForm.ts │ ├── TableAction.ts │ └── TableBillAction.ts ├── env.d.ts ├── hook │ ├── ITableOption.ts │ ├── ITableResult.ts │ ├── bill │ │ ├── IBillTableOption.ts │ │ ├── IBillTableResult.ts │ │ ├── detail │ │ │ ├── IUseBillDetailResult.ts │ │ │ └── useBillDetail.ts │ │ └── useBillTable.ts │ └── useTable.ts ├── main.ts ├── manifest.json ├── model │ ├── asset │ │ ├── device │ │ │ ├── AlarmStatusEnum.ts │ │ │ ├── DeviceEntity.ts │ │ │ ├── DevicePayloadEntity.ts │ │ │ ├── DeviceReportingEnum.ts │ │ │ ├── DeviceService.ts │ │ │ └── DeviceStatusEnum.ts │ │ └── material │ │ │ ├── MaterialEntity.ts │ │ │ ├── MaterialService.ts │ │ │ └── MaterialTypeEnum.ts │ ├── channel │ │ ├── customer │ │ │ ├── CustomerEntity.ts │ │ │ └── CustomerService.ts │ │ ├── purchase │ │ │ ├── PurchaseDetailEntity.ts │ │ │ ├── PurchaseDetailService.ts │ │ │ ├── PurchaseEntity.ts │ │ │ ├── PurchaseService.ts │ │ │ └── PurchaseStatusEnum.ts │ │ ├── purchasePrice │ │ │ ├── PurchasePriceEntity.ts │ │ │ └── PurchasePriceService.ts │ │ ├── sale │ │ │ ├── SaleDetailEntity.ts │ │ │ ├── SaleDetailService.ts │ │ │ ├── SaleEntity.ts │ │ │ ├── SaleService.ts │ │ │ └── SaleStatusEnum.ts │ │ ├── salePrice │ │ │ ├── SalePriceEntity.ts │ │ │ └── SalePriceService.ts │ │ └── supplier │ │ │ ├── SupplierEntity.ts │ │ │ └── SupplierService.ts │ ├── common │ │ ├── BooleanYesNoDictionary.ts │ │ ├── LoginAction.ts │ │ ├── OrderNumberDictionary.ts │ │ └── PublishStatusEnum.ts │ ├── factory │ │ ├── storage │ │ │ ├── StorageEntity.ts │ │ │ └── StorageService.ts │ │ └── structure │ │ │ ├── StructureEntity.ts │ │ │ └── StructureService.ts │ ├── iot │ │ ├── collection │ │ │ ├── CollectionDefault.ts │ │ │ ├── CollectionEntity.ts │ │ │ ├── CollectionGranularityEnum.ts │ │ │ └── CollectionService.ts │ │ └── parameter │ │ │ ├── ParameterEntity.ts │ │ │ ├── ParameterService.ts │ │ │ ├── ParameterSystemEnum.ts │ │ │ └── ParameterTypeEnum.ts │ ├── mes │ │ ├── bom │ │ │ ├── BomDetailEntity.ts │ │ │ ├── BomDetailService.ts │ │ │ ├── BomEntity.ts │ │ │ ├── BomService.ts │ │ │ └── BomTypeEnum.ts │ │ ├── operation │ │ │ ├── OperationEntity.ts │ │ │ └── OperationService.ts │ │ ├── order │ │ │ ├── OrderDetailEntity.ts │ │ │ ├── OrderDetailService.ts │ │ │ ├── OrderEntity.ts │ │ │ ├── OrderService.ts │ │ │ ├── OrderStatusEnum.ts │ │ │ └── OrderTypeEnum.ts │ │ ├── picking │ │ │ ├── PickingDetailEntity.ts │ │ │ ├── PickingDetailService.ts │ │ │ ├── PickingEntity.ts │ │ │ ├── PickingService.ts │ │ │ └── PickingStatusEnum.ts │ │ ├── plan │ │ │ ├── PlanDetailEntity.ts │ │ │ ├── PlanDetailService.ts │ │ │ ├── PlanEntity.ts │ │ │ ├── PlanService.ts │ │ │ ├── PlanStatusEnum.ts │ │ │ └── PlanTypeEnum.ts │ │ └── routing │ │ │ ├── RoutingEntity.ts │ │ │ ├── RoutingService.ts │ │ │ ├── RoutingStatusEnum.ts │ │ │ └── operation │ │ │ ├── RoutingOperationEntity.ts │ │ │ └── RoutingOperationService.ts │ ├── open │ │ ├── app │ │ │ ├── OpenAppArithmeticEnum.ts │ │ │ ├── OpenAppEntity.ts │ │ │ └── OpenAppService.ts │ │ ├── log │ │ │ ├── OpenLogEntity.ts │ │ │ └── OpenLogService.ts │ │ ├── notify │ │ │ ├── NotifyChannelEnum.ts │ │ │ ├── NotifyEntity.ts │ │ │ └── NotifyService.ts │ │ ├── oauth │ │ │ ├── OauthCreateCodeRequest.ts │ │ │ └── OauthScope.ts │ │ └── thirdlogin │ │ │ ├── ThirdLoginPlatform.ts │ │ │ ├── ThirdLoginRequest.ts │ │ │ └── UserThirdLoginEntity.ts │ ├── personnel │ │ ├── department │ │ │ ├── DepartmentEntity.ts │ │ │ └── DepartmentService.ts │ │ ├── role │ │ │ ├── RoleEntity.ts │ │ │ └── RoleService.ts │ │ └── user │ │ │ ├── UserEntity.ts │ │ │ ├── UserGenderEnum.ts │ │ │ └── UserService.ts │ ├── system │ │ ├── coderule │ │ │ ├── CodeRuleEntity.ts │ │ │ ├── CodeRuleField.ts │ │ │ ├── CodeRuleParam.ts │ │ │ ├── CodeRuleService.ts │ │ │ └── SerialNumberUpdateEnum.ts │ │ ├── config │ │ │ ├── ConfigEntity.ts │ │ │ ├── ConfigService.ts │ │ │ └── ConfigType.ts │ │ ├── log │ │ │ ├── LogEntity.ts │ │ │ └── LogService.ts │ │ ├── menu │ │ │ ├── MenuEntity.ts │ │ │ └── MenuService.ts │ │ ├── permission │ │ │ ├── PermissionEntity.ts │ │ │ ├── PermissionService.ts │ │ │ └── PermissionSystemEnum.ts │ │ └── unit │ │ │ ├── UnitEntity.ts │ │ │ └── UnitService.ts │ └── wms │ │ ├── input │ │ ├── InputDetailEntity.ts │ │ ├── InputDetailService.ts │ │ ├── InputEntity.ts │ │ ├── InputService.ts │ │ ├── InputStatusEnum.ts │ │ └── InputTypeEnum.ts │ │ ├── inventory │ │ ├── InventoryEntity.ts │ │ ├── InventoryService.ts │ │ └── InventoryTypeEnum.ts │ │ ├── move │ │ ├── MoveDetailEntity.ts │ │ ├── MoveDetailService.ts │ │ ├── MoveEntity.ts │ │ ├── MoveService.ts │ │ └── MoveStatusEnum.ts │ │ └── output │ │ ├── OutputDetailEntity.ts │ │ ├── OutputDetailService.ts │ │ ├── OutputEntity.ts │ │ ├── OutputService.ts │ │ ├── OutputStatusEnum.ts │ │ └── OutputTypeEnum.ts ├── pages.json ├── shime-uni.d.ts ├── static │ ├── css │ │ └── main.scss │ └── img │ │ ├── add.png │ │ ├── logo.svg │ │ └── tabbar │ │ ├── tabbar-home-active.png │ │ ├── tabbar-home.png │ │ ├── tabbar-message-active.png │ │ ├── tabbar-message.png │ │ ├── tabbar-mine-active.png │ │ ├── tabbar-mine.png │ │ ├── tabbar-more-active.png │ │ └── tabbar-more.png ├── uni.scss └── view │ ├── asset │ ├── device │ │ └── list.vue │ └── material │ │ └── list.vue │ ├── channel │ ├── customer │ │ └── list.vue │ ├── purchase │ │ ├── detail.vue │ │ ├── list.vue │ │ └── test.vue │ ├── sale │ │ └── list.vue │ └── supplier │ │ └── list.vue │ ├── home.vue │ ├── login.vue │ ├── mes │ ├── bom │ │ └── list.vue │ ├── operation │ │ └── list.vue │ ├── order │ │ └── list.vue │ ├── picking │ │ └── list.vue │ ├── plan │ │ └── list.vue │ └── routing │ │ └── list.vue │ ├── message.vue │ ├── setting.vue │ ├── station.vue │ └── wms │ ├── input │ ├── detail.vue │ └── list.vue │ ├── move │ └── list.vue │ └── output │ └── list.vue ├── tsconfig.json ├── unpackage └── res │ └── icons │ ├── 1024x1024.png │ ├── 120x120.png │ ├── 144x144.png │ ├── 152x152.png │ ├── 167x167.png │ ├── 180x180.png │ ├── 192x192.png │ ├── 20x20.png │ ├── 29x29.png │ ├── 40x40.png │ ├── 58x58.png │ ├── 60x60.png │ ├── 72x72.png │ ├── 76x76.png │ ├── 80x80.png │ ├── 87x87.png │ └── 96x96.png ├── update.sh └── vite.config.ts /.eslintignore: -------------------------------------------------------------------------------- 1 | src/airpower/assets 2 | node_modules 3 | dist 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | globals: { 4 | wx: true, 5 | plus: true, 6 | uni: true, 7 | getCurrentPages: true, 8 | UniNamespace: true, 9 | defineEmits: 'readonly', 10 | defineProps: 'readonly', 11 | }, 12 | extends: [ 13 | 'plugin:@typescript-eslint/recommended', 14 | 'plugin:vue/vue3-recommended', 15 | 'airbnb-base', 16 | ], 17 | parserOptions: { 18 | parser: '@typescript-eslint/parser', 19 | ecmaVersion: 2020, 20 | }, 21 | rules: { 22 | indent: ['error', 2, { 23 | SwitchCase: 1, 24 | VariableDeclarator: { 25 | var: 2, let: 2, const: 3, 26 | }, 27 | MemberExpression: 1, 28 | }], 29 | 'import/named': 'off', 30 | 'vue/multi-word-component-names': 'off', 31 | radix: 'off', 32 | 'max-len': 'off', // 强制一行的最大长度 33 | 'import/extensions': 'off', // 不验证导入文件扩展名 34 | 'no-shadow': 'off', // 禁止变量声明与外层作用域的变量同名 35 | 'import/no-cycle': 'error', // 禁止一个模块导入一个有依赖路径的模块回到自己身上 36 | semi: ['error', 'never'], // 不使用分号 37 | eqeqeq: 'warn', // 要求使用 === 和 !== 38 | 'no-param-reassign': 'off', // 允许 function 的参数进行重新赋值 39 | 'import/prefer-default-export': 'off', // 禁用默认输出 40 | 'default-case': 'error', // switch 必须使用 default 41 | 'no-restricted-syntax': 'off', // 禁用特定的语法 42 | 'no-await-in-loop': 'error', // 禁止在循环中出现 await 43 | 'import/no-unresolved': 'off', // 确保导入指向一个可以解析的文件/模块 44 | '@typescript-eslint/no-var-requires': 'off', // 允许require 45 | 'class-methods-use-this': 'off', 46 | }, 47 | } 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | *.local 14 | 15 | # Editor directories and files 16 | .idea 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | 23 | yarn.lock 24 | package-lock.json 25 | 26 | airpower -------------------------------------------------------------------------------- /.hbuilderx/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ 3 | // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 4 | "version": "0.0", 5 | "configurations": [ 6 | { 7 | "app-plus": { 8 | "launchtype": "local" 9 | }, 10 | "default": { 11 | "launchtype": "local" 12 | }, 13 | "type": "uniCloud" 14 | }, 15 | { 16 | "playground": "standard", 17 | "type": "uni-app:app-ios" 18 | }, 19 | { 20 | "openVueDevtools": true, 21 | "type": "uni-app:app-android" 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Hamm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | 7 | 8 | 9 | 10 | 11 |

12 |

13 | @Github @Gitee 14 |

15 | 16 | ## S-PMS介绍(App项目) 17 | 18 | **S-PMS** `(Smart Production Management System)` **智能生产管理系统** ,是一个集成化、智能化的企业级应用软件,它集成了多个核心的生产管理模块,包括 19 | **制造执行系统** `(MES, Manufacturing Execution System)`、**仓库管理系统** `(WMS, Warehouse Management System)`、* 20 | *企业资源计划系统** `(ERP, Enterprise Resource Planning)`、**质量管理系统** `(QMS, Quality Management System)` 以及 * 21 | *物联网管理系统** `(IoTS,Internet of Things System)` 等。 22 | 23 | - **MES (Manufacturing Execution System) 制造执行系统** 24 | ,主要用于车间层的生产活动优化管理,实时监控从订单下达到产品完成的整个生产过程,实现对生产数据的实时采集和分析,以提高生产效率、产品质量和资源利用率。 25 | 26 | - **WMS (Warehouse Management System) 仓库管理系统**,用于全面管理和控制仓库业务流程,包括入库、出库、库存、盘点、批次管理等,实现仓库作业高效、准确、透明。 27 | 28 | - **ERP (Enterprise Resource Planning) 企业资源计划系统**,整合了企业的所有资源,包括财务、采购、销售、生产、库存等各个环节的信息,为企业决策提供及时、准确的数据支持。 29 | 30 | - **QMS (Quality Management System) 质量管理系统**,主要用于质量管理与控制,确保产品和服务满足规定以及客户期望的质量要求,包括质量策划、质量控制、质量保证及质量改进等活动。 31 | 32 | - **IoTS(Internet of Things System) 物联网管理系统**,通过连接各种生产设备和传感器,收集海量实时数据,实现设备远程监控、预防性维护、生产过程智能化控制等功能。 33 | 34 | 通过将这些系统功能一体化整合在 **S-PMS** 中,企业可以实现从采购、生产、仓储到销售全流程的信息化、精细化、智能化管理,有效提升企业的整体运营效率和市场竞争力。 35 | 36 | ## 产品截图 37 | 38 | ... 39 | 40 | ## 开发者指南 41 | 42 | 本仓库为 **S-PMS** 43 | App项目仓库,你可以查看 [开发者指南@Github](https://github.com/s-pms/SPMS-Docs)、[开发者指南@Gitee](https://gitee.com/s-pms/SPMS-Docs) 44 | 等帮助文档。 45 | 46 | ## 联系我们 47 | 48 | **S-PMS** 所有代码均在 **MIT** 开源协议规范下免费提供,你可以放心使用。 49 | 50 | 如果有定制需求,欢迎联系我们: 51 | 52 | Email: admin@hamm.cn 53 | 54 | ## 环境准备 55 | 56 | 我们使用的是 ```Vite``` 构建, 包管理使用的是 ```yarn```, 57 | 请先安装前叙的相关工具后继续接下来的操作 :) 58 | 59 | ### 初始化仓库 60 | 61 | > 建议windows开发者使用 ```git bash``` 不要使用windows自带的拉垮的 ```cmd``` ```powershell``` 62 | > 等。否则接下来的脚本可能出现问题,你只能通过自己手动去操作。 63 | 64 | ```shell 65 | git clone https://github.com/s-pms/SPMS-App.git && 66 | cd SPMS-App && 67 | git clone -b uniapp https://github.com/HammCn/AirPower4T.git airpower 68 | ``` 69 | 70 | ### 启动和打包 71 | 72 | 使用 `HBuilder-X` 导入这个项目,编译即可。 73 | 74 | ### 其他命令 75 | 76 | ```shell 77 | #使用标准commit模板 78 | yarn c 79 | 80 | #更新项目和AirPower 81 | yarn u 82 | 83 | #查看Git格式化日志 84 | yarn l 85 | ``` 86 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /merge.sh: -------------------------------------------------------------------------------- 1 | cd src/airpower && git checkout wechat && git pull && git checkout uniapp && git merge wechat && git push -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "airpower-uniapp", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev:app": "uni -p app", 6 | "dev:app-android": "uni -p app-android", 7 | "dev:app-ios": "uni -p app-ios", 8 | "dev:custom": "uni -p", 9 | "dev:h5": "uni", 10 | "dev:h5:ssr": "uni --ssr", 11 | "dev:mp-alipay": "uni -p mp-alipay", 12 | "dev:mp-baidu": "uni -p mp-baidu", 13 | "dev:mp-jd": "uni -p mp-jd", 14 | "dev:mp-kuaishou": "uni -p mp-kuaishou", 15 | "dev:mp-lark": "uni -p mp-lark", 16 | "dev:mp-qq": "uni -p mp-qq", 17 | "dev:mp-toutiao": "uni -p mp-toutiao", 18 | "dev:mp-weixin": "uni -p mp-weixin", 19 | "dev:quickapp-webview": "uni -p quickapp-webview", 20 | "dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei", 21 | "dev:quickapp-webview-union": "uni -p quickapp-webview-union", 22 | "build:app": "uni build -p app", 23 | "build:app-android": "uni build -p app-android", 24 | "build:app-ios": "uni build -p app-ios", 25 | "build:custom": "uni build -p", 26 | "build:h5": "uni build", 27 | "build:h5:ssr": "uni build --ssr", 28 | "build:mp-alipay": "uni build -p mp-alipay", 29 | "build:mp-baidu": "uni build -p mp-baidu", 30 | "build:mp-jd": "uni build -p mp-jd", 31 | "build:mp-kuaishou": "uni build -p mp-kuaishou", 32 | "build:mp-lark": "uni build -p mp-lark", 33 | "build:mp-qq": "uni build -p mp-qq", 34 | "build:mp-toutiao": "uni build -p mp-toutiao", 35 | "build:mp-weixin": "uni build -p mp-weixin", 36 | "build:quickapp-webview": "uni build -p quickapp-webview", 37 | "build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei", 38 | "build:quickapp-webview-union": "uni build -p quickapp-webview-union", 39 | "type-check": "vue-tsc --noEmit", 40 | "u": "sh update.sh", 41 | "m": "sh merge.sh" 42 | }, 43 | "dependencies": { 44 | "@dcloudio/uni-app": "3.0.0-alpha-4050120250118001", 45 | "@dcloudio/uni-app-plus": "3.0.0-alpha-4050120250118001", 46 | "@dcloudio/uni-components": "3.0.0-alpha-4050120250118001", 47 | "@dcloudio/uni-h5": "3.0.0-alpha-4050120250118001", 48 | "@dcloudio/uni-mp-alipay": "3.0.0-alpha-4050120250118001", 49 | "@dcloudio/uni-mp-baidu": "3.0.0-alpha-4050120250118001", 50 | "@dcloudio/uni-mp-jd": "3.0.0-alpha-4050120250118001", 51 | "@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-4050120250118001", 52 | "@dcloudio/uni-mp-lark": "3.0.0-alpha-4050120250118001", 53 | "@dcloudio/uni-mp-qq": "3.0.0-alpha-4050120250118001", 54 | "@dcloudio/uni-mp-toutiao": "3.0.0-alpha-4050120250118001", 55 | "@dcloudio/uni-mp-weixin": "3.0.0-alpha-4050120250118001", 56 | "@dcloudio/uni-quickapp-webview": "3.0.0-alpha-4050120250118001", 57 | "@dcloudio/uts-darwin-x64": "^3.0.0-alpha-3040820220424005", 58 | "@dcloudio/uvm": "^0.3.1", 59 | "@dcloudio/vite-plugin-uni": "3.0.0-alpha-4050120250118001", 60 | "@types/crypto-js": "^4.2.2", 61 | "@types/js-base64": "^3.3.1", 62 | "@typescript-eslint/eslint-plugin": "^5.60.0", 63 | "@typescript-eslint/parser": "^5.60.0", 64 | "@vitejs/plugin-vue": "^4.2.3", 65 | "alpha": "^1.0.0", 66 | "crypto-js": "^4.1.1", 67 | "eslint": "^8.43.0", 68 | "eslint-config-airbnb-base": "^15.0.0", 69 | "eslint-plugin-import": "^2.27.5", 70 | "eslint-plugin-prettier": "^4.2.1", 71 | "eslint-plugin-vue": "^9.15.0", 72 | "js-base64": "^3.7.7", 73 | "pinia": "^2.3.1", 74 | "sass": "^1.83.4", 75 | "scss": "^0.2.4", 76 | "vite": "6.0.8", 77 | "vue": "^3.5.13", 78 | "vue-i18n": "^9.2.2" 79 | }, 80 | "devDependencies": { 81 | "@dcloudio/types": "^3.4.14", 82 | "@dcloudio/uni-automator": "3.0.0-alpha-4050120250118001", 83 | "@dcloudio/uni-cli-shared": "3.0.0-alpha-4050120250118001", 84 | "@dcloudio/uni-stacktracey": "3.0.0-alpha-4050120250118001", 85 | "@vue/tsconfig": "^0.7.0", 86 | "typescript": "^5.4.5", 87 | "vue-tsc": "^2.2.0" 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /src/base/AbstractBaseService.ts: -------------------------------------------------------------------------------- 1 | import { AirAbstractEntityService } from '@airpower/base/AirAbstractEntityService' 2 | import { AirNotification } from '@airpower/feedback/AirNotification' 3 | import { BaseEntity } from './BaseEntity' 4 | 5 | /** 6 | * # 抽象服务基类 7 | * @author Hamm.cn 8 | */ 9 | export abstract class AbstractBaseService extends AirAbstractEntityService { 10 | /** 11 | * ### 发布实体 12 | * @param entity 实体 13 | */ 14 | async publish(entity: E): Promise { 15 | await this.api('publish') 16 | .post(entity) 17 | AirNotification.success('发布成功') 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/base/BaseEntity.ts: -------------------------------------------------------------------------------- 1 | import { AirEntity } from '@airpower/base/AirEntity' 2 | import { Field, Model } from '@airpower/decorator' 3 | import { PublishStatusEnum } from '@/model/common/PublishStatusEnum' 4 | 5 | /** 6 | * # 数据库实体基类 7 | * @author Hamm.cn 8 | */ 9 | 10 | @Model({ 11 | addChildPermission: 'add', 12 | }) 13 | export class BaseEntity extends AirEntity { 14 | @Field({ 15 | label: '发布状态', 16 | type: Boolean, 17 | dictionary: PublishStatusEnum, 18 | }) 19 | isPublished!: boolean 20 | 21 | @Field({ 22 | label: '创建时间', 23 | type: Number, 24 | }) 25 | createTime!: number 26 | 27 | @Field({ 28 | label: '更新时间', 29 | type: Number, 30 | }) 31 | updateTime!: number 32 | } 33 | -------------------------------------------------------------------------------- /src/base/bill/AbstractBaseBillDetailService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '../AbstractBaseService' 2 | import { AbstractBaseBillDetailEntity } from './detail/AbstractBaseBillDetailEntity' 3 | 4 | /** 5 | * # 单据明细抽象服务基类 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export abstract class AbstractBaseBillDetailService extends AbstractBaseService { 10 | } 11 | -------------------------------------------------------------------------------- /src/base/bill/AbstractBaseBillEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field } from '@airpower/decorator' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | import { IPayload } from '@airpower/interface/IPayload' 4 | import { BaseEntity } from '../BaseEntity' 5 | import { AbstractBaseBillDetailEntity } from './detail/AbstractBaseBillDetailEntity' 6 | 7 | /** 8 | * # 单据基类 9 | * 10 | * @author Hamm.cn 11 | */ 12 | export abstract class AbstractBaseBillEntity< 13 | D extends AbstractBaseBillDetailEntity 14 | > extends BaseEntity implements IPayload { 15 | @Field({ 16 | label: '单据编号', 17 | }) 18 | billCode!: string 19 | 20 | abstract status: number 21 | 22 | /** 23 | * ### 单据明细列表 24 | */ 25 | abstract details: D[] 26 | 27 | @Field({ 28 | label: '驳回原因', 29 | }) 30 | rejectReason!: string 31 | 32 | /** 33 | * ### 审核中的状态 34 | */ 35 | public abstract getAuditingStatus(): AirEnum; 36 | 37 | /** 38 | * ### 已审核的状态 39 | */ 40 | public abstract getAuditedStatus(): AirEnum; 41 | 42 | /** 43 | * ### 已拒绝的状态 44 | */ 45 | public abstract getRejectedStatus(): AirEnum; 46 | 47 | getPayloadLabel(): string { 48 | return this.billCode 49 | } 50 | 51 | /** 52 | * ### 是否可拒绝 53 | */ 54 | canReject() { 55 | return this.getAuditingStatus() 56 | .equalsKey(this.status) 57 | } 58 | 59 | /** 60 | * ### 是否可审核 61 | */ 62 | canAudit() { 63 | return this.getAuditingStatus() 64 | .equalsKey(this.status) 65 | } 66 | 67 | /** 68 | * ### 是否已拒绝 69 | */ 70 | isRejected() { 71 | return this.getRejectedStatus() 72 | .equalsKey(this.status) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/base/bill/AbstractBaseBillService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '../AbstractBaseService' 2 | import { AbstractBaseBillEntity } from './AbstractBaseBillEntity' 3 | import { AbstractBaseBillDetailEntity } from './detail/AbstractBaseBillDetailEntity' 4 | 5 | /** 6 | * # 单据抽象服务基类 7 | * 8 | * @author Hamm.cn 9 | */ 10 | export abstract class AbstractBaseBillService< 11 | D extends AbstractBaseBillDetailEntity, 12 | B extends AbstractBaseBillEntity 13 | > extends AbstractBaseService { 14 | /** 15 | * ### 审核单据 16 | * @param bill 单据 17 | */ 18 | async audit(bill: B): Promise { 19 | await this.api('audit') 20 | .post(bill) 21 | } 22 | 23 | /** 24 | * ### 驳回单据 25 | * @param bill 单据 26 | */ 27 | async reject(bill: B): Promise { 28 | await this.api('reject') 29 | .post(bill) 30 | } 31 | 32 | /** 33 | * ### 完成单据 34 | * @param bill 单据 35 | */ 36 | async setBillFinished(bill: B): Promise { 37 | await this.api('setBillFinished') 38 | .post(bill) 39 | } 40 | 41 | /** 42 | * ### 完成单据所有明细 43 | * @param bill 单据 44 | */ 45 | async setBillDetailsAllFinished(bill: B): Promise { 46 | await this.api('setBillDetailsAllFinished') 47 | .post(bill) 48 | } 49 | 50 | /** 51 | * ### 添加完成数量 52 | * @param detail 单据 53 | */ 54 | async addDetailFinishQuantity(detail: D): Promise { 55 | await this.api('addFinish') 56 | .post(detail) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/base/bill/detail/AbstractBaseBillDetailEntity.ts: -------------------------------------------------------------------------------- 1 | import { BaseEntity } from '@/base/BaseEntity' 2 | 3 | /** 4 | * # 单据明细抽象基类 5 | * 6 | * @author Hamm.cn 7 | */ 8 | export abstract class AbstractBaseBillDetailEntity extends BaseEntity { 9 | /** 10 | * ### 单据ID 11 | */ 12 | billId!: number 13 | 14 | /** 15 | * ### 数量 16 | */ 17 | abstract quantity: number 18 | 19 | /** 20 | * ### 已完成数量 21 | */ 22 | abstract finishQuantity: number 23 | 24 | isFinished!: boolean 25 | } 26 | -------------------------------------------------------------------------------- /src/component/BillDetail.vue: -------------------------------------------------------------------------------- 1 | 2 | 5 | -------------------------------------------------------------------------------- /src/component/TimeCell.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 27 | 28 | 31 | -------------------------------------------------------------------------------- /src/component/form/NumberInput.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 58 | 59 | 71 | -------------------------------------------------------------------------------- /src/component/index.ts: -------------------------------------------------------------------------------- 1 | import BillDetail from './BillDetail.vue' 2 | import TimeCell from './TimeCell.vue' 3 | 4 | export { 5 | BillDetail, 6 | TimeCell, 7 | } 8 | -------------------------------------------------------------------------------- /src/config/AppConfig.ts: -------------------------------------------------------------------------------- 1 | import { ref } from 'vue' 2 | import { UserEntity } from '@/model/personnel/user/UserEntity' 3 | 4 | /** 5 | * # 项目全局配置文件 6 | */ 7 | export class AppConfig { 8 | /** 9 | * # 产品版本号 10 | * --- 11 | * ### 💡 整形 仅用于版本号大小判断 12 | */ 13 | static readonly version = 10000 14 | 15 | /** 16 | * # 产品名称 17 | */ 18 | static readonly productName = '理账狮' 19 | 20 | /** 21 | * # 当前登录用户 22 | */ 23 | static currentUser = ref(new UserEntity()) 24 | 25 | /** 26 | * # 返回可供显示的版本号 27 | * --- 28 | * 💡 如需要判断版本 请直接使用```Config.version``` 29 | */ 30 | static getVersion() { 31 | const versionSlitNumber = 100 32 | let str = 'v' 33 | str += `${parseInt((this.version / (versionSlitNumber ** 2)).toString())}.` 34 | // eslint-disable-next-line no-mixed-operators 35 | str += `${parseInt((this.version % (versionSlitNumber ** 2) / versionSlitNumber).toString())}.` 36 | str += `${parseInt((this.version % (versionSlitNumber ** 2) % versionSlitNumber).toString())}` 37 | return str 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/config/AppForm.ts: -------------------------------------------------------------------------------- 1 | import { AirRouter } from '@airpower/helper/AirRouter' 2 | 3 | export class AppForm { 4 | static async getNumber(title = '请输入', desc = '请输入...', max = Number.MAX_SAFE_INTEGER, min = 0): Promise { 5 | return (await AirRouter.go(`/component/form/NumberInput?title=${title}&desc=${desc}&max=${max}&min=${min}`, {}, 'fade-in', 200)) as number 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/config/TableAction.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | import { AirColor } from '@airpower/enum/AirColor' 3 | 4 | export class TableAction extends AirEnum { 5 | static readonly PUBLISH = new TableAction(11, '发布', AirColor.NORMAL) 6 | } 7 | -------------------------------------------------------------------------------- /src/config/TableBillAction.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | 3 | export class TableBillAction extends AirEnum { 4 | static readonly AUDIT = new TableBillAction(21, '审核') 5 | 6 | static readonly REJECT = new TableBillAction(22, '驳回') 7 | } 8 | -------------------------------------------------------------------------------- /src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import { DefineComponent } from 'vue' 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types 6 | const component: DefineComponent<{}, {}, any> 7 | export default component 8 | } 9 | 10 | interface ImportMetaEnv extends Readonly> { 11 | /** 12 | * # 环境名称 13 | */ 14 | VITE_APP_NAME: string 15 | 16 | /** 17 | * # API根路径 18 | */ 19 | VITE_APP_API_URL: string 20 | 21 | /** 22 | * # 静态资源根路径 23 | */ 24 | VITE_APP_STATIC_URL: string 25 | 26 | /** 27 | * # 是否开发模式 28 | */ 29 | DEV: boolean 30 | 31 | /** 32 | * # 是否生产模式 33 | */ 34 | PROD: boolean 35 | 36 | /** 37 | * # 当前环境模式 38 | */ 39 | MODE: string 40 | } 41 | 42 | interface ImportMeta { 43 | readonly env: ImportMetaEnv 44 | } 45 | -------------------------------------------------------------------------------- /src/hook/ITableOption.ts: -------------------------------------------------------------------------------- 1 | import { IUseTableOption } from '@airpower/interface/hooks/IUseTableOption' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | 4 | export interface ITableOption extends IUseTableOption { 5 | /** 6 | * ### 是否显示发布按钮 7 | */ 8 | showPublish?: boolean 9 | } 10 | -------------------------------------------------------------------------------- /src/hook/ITableResult.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | 3 | import { IUseTableResult } from '@airpower/interface/hooks/IUseTableResult' 4 | import { AbstractBaseService } from '@/base/AbstractBaseService' 5 | import { BaseEntity } from '@/base/BaseEntity' 6 | 7 | /** 8 | * # 表格Hook 9 | * 10 | * @author Hamm.cn 11 | */ 12 | export interface ITableResult< 13 | E extends BaseEntity, 14 | S extends AbstractBaseService 15 | > extends IUseTableResult { 16 | /** 17 | * ### 发布 18 | * @param entity 实体 19 | */ 20 | onPublish: (entity: E) => void 21 | } 22 | -------------------------------------------------------------------------------- /src/hook/bill/IBillTableOption.ts: -------------------------------------------------------------------------------- 1 | import { IUseTableOption } from '@airpower/interface/hooks/IUseTableOption' 2 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 3 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 4 | 5 | export interface IBillTableOption> extends IUseTableOption { 6 | /** 7 | * ### 是否隐藏审核按钮 8 | */ 9 | hideAudit?: boolean 10 | 11 | /** 12 | * ### 是否隐藏驳回按钮 13 | */ 14 | hideReject?: boolean 15 | } 16 | -------------------------------------------------------------------------------- /src/hook/bill/IBillTableResult.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | 3 | import { IUseTableResult } from '@airpower/interface/hooks/IUseTableResult' 4 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 5 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 6 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 7 | 8 | /** 9 | * # 单据表格Hook 10 | * 11 | * @author Hamm.cn 12 | */ 13 | export interface IBillTableResult< 14 | D extends AbstractBaseBillDetailEntity, 15 | B extends AbstractBaseBillEntity, 16 | S extends AbstractBaseBillService 17 | > extends IUseTableResult { 18 | /** 19 | * ### 审核 20 | * @param bill 单据 21 | */ 22 | onAudit: (bill: B) => void 23 | 24 | /** 25 | * ### 驳回 26 | * @param bill 单据 27 | */ 28 | onReject: (bill: B) => void 29 | 30 | /** 31 | * ### 标记单据所有明细已完成 32 | * @param bill 33 | */ 34 | setBillDetailsAllFinished: (bill: B) => void 35 | 36 | /** 37 | * ### 完成单据 38 | * @param bill 39 | */ 40 | setBillFinished: (bill: B) => void 41 | } 42 | -------------------------------------------------------------------------------- /src/hook/bill/detail/IUseBillDetailResult.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { IUseDetailResult } from '@airpower/interface/hooks/IUseDetailResult' 3 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 4 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 5 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 6 | 7 | /** 8 | * # 单据详情Hook 9 | * 10 | * @author Hamm.cn 11 | */ 12 | export interface IUseBillDetailResult, S extends AbstractBaseBillService> extends IUseDetailResult { 13 | 14 | /** 15 | * ### 增加单据详情的完成数量 16 | * @param billDetail 明细 17 | * @param quantity 完成数量 18 | */ 19 | addDetailFinishQuantity: (detail: D, quantity: number) => void 20 | } 21 | -------------------------------------------------------------------------------- /src/hook/bill/detail/useBillDetail.ts: -------------------------------------------------------------------------------- 1 | import { useAirDetail } from '@airpower/hook/useAirDetail' 2 | import { IUseDetailOption } from '@airpower/interface/hooks/IUseDetailOption' 3 | import { ClassConstructor } from '@airpower/type/AirType' 4 | import { AirNotification } from '@airpower/feedback/AirNotification' 5 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 6 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 7 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 8 | import { IUseBillDetailResult } from '@/hook/bill/detail/IUseBillDetailResult' 9 | 10 | export function useBillDetail< 11 | D extends AbstractBaseBillDetailEntity, 12 | B extends AbstractBaseBillEntity, 13 | S extends AbstractBaseBillService 14 | >(entityClass: ClassConstructor, serviceClass: ClassConstructor, option: IUseDetailOption): IUseBillDetailResult { 15 | const result = useAirDetail(entityClass, serviceClass, option) 16 | 17 | async function addDetailFinishQuantity(detail: D, quantity: number) { 18 | const postData = detail.copy().expose('id', 'billId') 19 | postData.quantity = quantity 20 | await result.service.addDetailFinishQuantity(postData) 21 | AirNotification.success('添加完成数量成功') 22 | result.getDetail() 23 | } 24 | 25 | return { 26 | addDetailFinishQuantity, ...result, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/hook/bill/useBillTable.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-use-before-define */ 2 | 3 | import { AirEnum } from '@airpower/base/AirEnum' 4 | import { AirTableAction } from '@airpower/enum/AirTableAction' 5 | import { AirConfirm } from '@airpower/feedback/AirConfirm' 6 | import { ClassConstructor } from '@airpower/type/AirType' 7 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 8 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 9 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 10 | import { TableAction } from '@/config/TableAction' 11 | import { TableBillAction } from '@/config/TableBillAction' 12 | import { useTable } from '../useTable' 13 | import { IBillTableResult } from './IBillTableResult' 14 | import { IBillTableOption } from './IBillTableOption' 15 | 16 | /** 17 | * # 单据的表格Hooks 18 | * @param entityClass 单据类 19 | * @param serviceClass 单据服务类 20 | * @param option (可选) 可选配置项 21 | * @author Hamm.cn 22 | */ 23 | export function useBillTable< 24 | D extends AbstractBaseBillDetailEntity, 25 | B extends AbstractBaseBillEntity, 26 | S extends AbstractBaseBillService 27 | >( 28 | entityClass: ClassConstructor, 29 | serviceClass: ClassConstructor, 30 | option: IBillTableOption = {}, 31 | ): IBillTableResult { 32 | if (!option.actions) { 33 | option.actions = AirTableAction.toArray().concat(TableAction.toArray()).concat(TableBillAction.toArray()) 34 | } 35 | if (option.hideDelete === undefined) { 36 | // 默认隐藏单据的删除 37 | option.hideDelete = true 38 | } 39 | if (option.hideEdit === undefined) { 40 | // 默认隐藏单据的编辑 41 | option.hideEdit = true 42 | } 43 | option.actions = option.actions.filter((item) => { 44 | switch (item.key) { 45 | case TableBillAction.AUDIT.key: 46 | return !option.hideAudit 47 | case TableBillAction.REJECT.key: 48 | return !option.hideReject 49 | default: 50 | return true 51 | } 52 | }) 53 | 54 | const { actionFilter } = option 55 | // 处理actions 56 | option.actionFilter = (actions: AirEnum[], row: B) => { 57 | actions = actions.filter((item) => { 58 | switch (item.key) { 59 | case TableBillAction.AUDIT.key: 60 | if (row.isPublished) { 61 | return false 62 | } 63 | return row.getAuditingStatus().equalsKey(row.status) 64 | case TableBillAction.REJECT.key: 65 | if (row.isPublished) { 66 | return false 67 | } 68 | return row.getAuditingStatus().equalsKey(row.status) 69 | case AirTableAction.EDIT.key: 70 | return !row.getAuditingStatus().equalsKey(row.status) 71 | default: 72 | } 73 | return true 74 | }) 75 | if (actionFilter) { 76 | return actionFilter(actions, row) 77 | } 78 | return actions 79 | } 80 | 81 | const { onActionEvent } = option 82 | option.onActionEvent = (action: AirEnum, bill: B) => { 83 | switch (action.key) { 84 | case TableBillAction.AUDIT.key: 85 | onAudit(bill) 86 | break 87 | case TableBillAction.REJECT.key: 88 | onReject(bill) 89 | break 90 | default: 91 | if (onActionEvent) { 92 | onActionEvent(action, bill) 93 | } 94 | } 95 | } 96 | const result = useTable(entityClass, serviceClass, option) 97 | 98 | /** 99 | * ### 单据审核 100 | * @param bill 单据 101 | */ 102 | async function onAudit(bill: B) { 103 | await AirConfirm.show('审核提醒', `是否确认审核选择的${result.entity.getModelName()}?`) 104 | await result.service.audit(bill) 105 | result.onReloadData() 106 | } 107 | 108 | /** 109 | * ### 单据驳回 110 | * @param bill 单据 111 | */ 112 | async function onReject(bill: B) { 113 | await AirConfirm.show('驳回提醒', `是否确认驳回选择的${result.entity.getModelName()}?`) 114 | bill.rejectReason = 'APP驳回' 115 | await result.service.reject(bill) 116 | result.onReloadData() 117 | } 118 | 119 | /** 120 | * ### 设置单据明细都已完成 121 | * @param bill 单据 122 | */ 123 | async function setBillDetailsAllFinished(bill: B) { 124 | await AirConfirm.show('完成提醒', `是否确认设置${result.entity.getModelName()}已完成?`) 125 | await result.service.setBillDetailsAllFinished(bill) 126 | result.onReloadData() 127 | } 128 | 129 | /** 130 | * ### 设置单据已完成 131 | * @param bill 单据 132 | */ 133 | async function setBillFinished(bill: B) { 134 | await AirConfirm.show('完成提醒', `是否确认设置所有${result.entity.getModelName()}明细都已完成?`) 135 | await result.service.setBillFinished(bill) 136 | result.onReloadData() 137 | } 138 | 139 | return { 140 | setBillFinished, 141 | setBillDetailsAllFinished, 142 | onAudit, 143 | onReject, 144 | ...result, 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/hook/useTable.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-use-before-define */ 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | import { AirTableAction } from '@airpower/enum/AirTableAction' 4 | import { AirConfirm } from '@airpower/feedback/AirConfirm' 5 | import { useAirTable } from '@airpower/hook/useAirTable' 6 | import { ClassConstructor } from '@airpower/type/AirType' 7 | import { AbstractBaseService } from '@/base/AbstractBaseService' 8 | import { BaseEntity } from '@/base/BaseEntity' 9 | import { TableAction } from '@/config/TableAction' 10 | import { ITableResult } from './ITableResult' 11 | import { ITableOption } from './ITableOption' 12 | 13 | /** 14 | * # 单据的表格Hooks 15 | * @param entityClass 单据类 16 | * @param serviceClass 单据服务类 17 | * @param option (可选) 可选配置项 18 | * @author Hamm.cn 19 | */ 20 | export function useTable< 21 | E extends BaseEntity, 22 | S extends AbstractBaseService, 23 | >( 24 | entityClass: ClassConstructor, 25 | serviceClass: ClassConstructor, 26 | option: ITableOption = {}, 27 | ): ITableResult { 28 | if (!option.actions) { 29 | option.actions = option.actions || AirTableAction.toArray().concat(TableAction.toArray()) 30 | } 31 | option.actions = option.actions.filter((item) => { 32 | switch (item.key) { 33 | case TableAction.PUBLISH.key: 34 | return option.showPublish 35 | default: 36 | } 37 | return true 38 | }) 39 | 40 | const { actionFilter } = option 41 | // 处理actions 42 | option.actionFilter = (actions: AirEnum[], row: E) => { 43 | actions = actions.filter((item) => { 44 | switch (item.key) { 45 | case TableAction.PUBLISH.key: 46 | return !row.isPublished 47 | case AirTableAction.EDIT.key: 48 | return !row.isPublished 49 | case AirTableAction.DELETE.key: 50 | return !row.isPublished 51 | default: 52 | } 53 | return true 54 | }) 55 | if (actionFilter) { 56 | return actionFilter(actions, row) 57 | } 58 | return actions 59 | } 60 | const { onActionEvent } = option 61 | option.onActionEvent = (action: AirEnum, bill: E) => { 62 | switch (action.key) { 63 | case TableAction.PUBLISH.key: 64 | onPublish(bill) 65 | break 66 | default: 67 | if (onActionEvent) { 68 | onActionEvent(action, bill) 69 | } 70 | } 71 | } 72 | 73 | const result = useAirTable(entityClass, serviceClass, option) 74 | 75 | /** 76 | * ### 实体发布 77 | * @param entity 实体 78 | */ 79 | async function onPublish(entity: E) { 80 | await AirConfirm.show('确认发布', '发布后将无法再次修改,是否确认?') 81 | await result.service.publish(entity) 82 | result.onReloadData() 83 | } 84 | 85 | return { 86 | onPublish, 87 | ...result, 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import '@airpower/assets/css/airpower.scss' 2 | 3 | import { createSSRApp } from 'vue' 4 | import { AirConfig } from '@airpower/config/AirConfig' 5 | import { AirApi } from '@airpower/config/AirApi' 6 | import App from './App.vue' 7 | import '@/static/css/main.scss' 8 | 9 | const system = uni.getSystemInfoSync() 10 | 11 | if (system.uniPlatform !== 'web') { 12 | const rootUrl = 'http://10.0.0.4:8080/' 13 | 14 | AirConfig.apiUrl = `${rootUrl}` 15 | AirConfig.staticUrl = `${rootUrl}upload/` 16 | } else { 17 | AirConfig.apiUrl = '/api/' 18 | } 19 | 20 | AirConfig.login = () => { 21 | AirApi.redirect('/view/login') 22 | } 23 | 24 | // noinspection JSUnusedGlobalSymbols 25 | export function createApp() { 26 | const app = createSSRApp(App) 27 | 28 | return { 29 | app, 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SPMS", 3 | "appid": "__UNI__EEAF40E", 4 | "description": "SPMS", 5 | "versionName": "1.0.0", 6 | "versionCode": 10000, 7 | "transformPx": false, 8 | "app-plus": { 9 | "safearea" : { 10 | "bottom" : { 11 | "offset" : "none" 12 | } 13 | }, 14 | "usingComponents": true, 15 | "nvueStyleCompiler": "uni-app", 16 | "compilerVersion": 3, 17 | "compatible": { 18 | "ignoreVersion": true 19 | }, 20 | "splashscreen": { 21 | "alwaysShowBeforeRender": true, 22 | "waiting": true, 23 | "autoclose": true, 24 | "delay": 0 25 | }, 26 | "modules": { 27 | "Webview-x5": {}, 28 | "Barcode": {}, 29 | "Camera": {} 30 | }, 31 | "distribute": { 32 | "android": { 33 | "permissions": [ 34 | "", 35 | "", 36 | "", 37 | "", 38 | "", 39 | "", 40 | "", 41 | "", 42 | "", 43 | "", 44 | "", 45 | "", 46 | "", 47 | "", 48 | "" 49 | ], 50 | "abiFilters": [ 51 | "armeabi-v7a", 52 | "arm64-v8a", 53 | "x86" 54 | ], 55 | "schemes": "workersaas", 56 | "minSdkVersion": 21, 57 | "autoSdkPermissions": false 58 | }, 59 | "ios": { 60 | "dSYMs": false, 61 | "privacyDescription": { 62 | "NSPhotoLibraryUsageDescription": "需要选择相册的照片作为用户头像", 63 | "NSPhotoLibraryAddUsageDescription": "", 64 | "NSCameraUsageDescription": "需要拍摄一张照片作为用户头像" 65 | }, 66 | "urltypes": "workersaas", 67 | "idfa": false 68 | }, 69 | "sdkConfigs": { 70 | "ad": {} 71 | }, 72 | "icons": { 73 | "android": { 74 | "hdpi": "unpackage/res/icons/72x72.png", 75 | "xhdpi": "unpackage/res/icons/96x96.png", 76 | "xxhdpi": "unpackage/res/icons/144x144.png", 77 | "xxxhdpi": "unpackage/res/icons/192x192.png" 78 | }, 79 | "ios": { 80 | "appstore": "unpackage/res/icons/1024x1024.png", 81 | "ipad": { 82 | "app": "unpackage/res/icons/76x76.png", 83 | "app@2x": "unpackage/res/icons/152x152.png", 84 | "notification": "unpackage/res/icons/20x20.png", 85 | "notification@2x": "unpackage/res/icons/40x40.png", 86 | "proapp@2x": "unpackage/res/icons/167x167.png", 87 | "settings": "unpackage/res/icons/29x29.png", 88 | "settings@2x": "unpackage/res/icons/58x58.png", 89 | "spotlight": "unpackage/res/icons/40x40.png", 90 | "spotlight@2x": "unpackage/res/icons/80x80.png" 91 | }, 92 | "iphone": { 93 | "app@2x": "unpackage/res/icons/120x120.png", 94 | "app@3x": "unpackage/res/icons/180x180.png", 95 | "notification@2x": "unpackage/res/icons/40x40.png", 96 | "notification@3x": "unpackage/res/icons/60x60.png", 97 | "settings@2x": "unpackage/res/icons/58x58.png", 98 | "settings@3x": "unpackage/res/icons/87x87.png", 99 | "spotlight@2x": "unpackage/res/icons/80x80.png", 100 | "spotlight@3x": "unpackage/res/icons/120x120.png" 101 | } 102 | } 103 | }, 104 | "splashscreen": { 105 | "androidStyle": "common", 106 | "useOriginalMsgbox": false, 107 | "iosStyle": "common" 108 | } 109 | } 110 | }, 111 | "quickapp": {}, 112 | "mp-weixin": { 113 | "appid": "", 114 | "setting": { 115 | "urlCheck": false 116 | }, 117 | "usingComponents": true 118 | }, 119 | "mp-alipay": { 120 | "usingComponents": true 121 | }, 122 | "mp-baidu": { 123 | "usingComponents": true, 124 | "setting": { 125 | "urlCheck": false 126 | } 127 | }, 128 | "mp-toutiao": { 129 | "usingComponents": true, 130 | "setting": { 131 | "urlCheck": false 132 | } 133 | }, 134 | "uniStatistics": { 135 | "enable": false 136 | }, 137 | "vueVersion": "3", 138 | "locale": "zh-Hans", 139 | "fallbackLocale": "zh-Hans", 140 | "mp-qq": { 141 | "setting": { 142 | "urlCheck": false 143 | } 144 | } 145 | } -------------------------------------------------------------------------------- /src/model/asset/device/AlarmStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | export class AlarmStatusEnum extends AirEnum { 5 | static readonly NONE = new AlarmStatusEnum(0, '正常运行', AirColor.SUCCESS) 6 | 7 | static readonly SYSTEM = new AlarmStatusEnum(1, '系统报警', AirColor.DANGER) 8 | 9 | static readonly MANUAL = new AlarmStatusEnum(2, '手动报警', AirColor.WARNING) 10 | } 11 | -------------------------------------------------------------------------------- /src/model/asset/device/DeviceEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { ParameterEntity } from '@/model/iot/parameter/ParameterEntity' 4 | import { DeviceReportingEnum } from '@/model/asset/device/DeviceReportingEnum' 5 | import { DeviceStatusEnum } from '@/model/asset/device/DeviceStatusEnum' 6 | import { AlarmStatusEnum } from '@/model/asset/device/AlarmStatusEnum' 7 | 8 | @Model({ 9 | label: '设备', 10 | }) 11 | export class DeviceEntity extends BaseEntity { 12 | @Field({ 13 | label: '设备名称', 14 | }) 15 | name!: string 16 | 17 | @Field({ 18 | label: '设备编码', 19 | }) 20 | code!: string 21 | 22 | @Field({ 23 | label: 'UUID', 24 | }) 25 | uuid!: string 26 | 27 | @Field({ 28 | label: '开启采集', 29 | dictionary: DeviceReportingEnum, 30 | }) 31 | isReporting!: boolean 32 | 33 | @Field({ 34 | label: '实时产量', 35 | }) 36 | partCount!: string 37 | 38 | @Field({ 39 | label: '运行状态', 40 | dictionary: DeviceStatusEnum, 41 | }) 42 | status!: number 43 | 44 | @Field({ 45 | label: '报警状态', 46 | dictionary: AlarmStatusEnum, 47 | }) 48 | alarm!: number 49 | 50 | @Field({ 51 | label: '采集频率', 52 | }) 53 | rate!: number 54 | 55 | @Field({ 56 | label: '参数', 57 | type: ParameterEntity, 58 | array: true, 59 | }) 60 | parameters: ParameterEntity[] = [] 61 | } 62 | -------------------------------------------------------------------------------- /src/model/asset/device/DevicePayloadEntity.ts: -------------------------------------------------------------------------------- 1 | import { BaseEntity } from '@/base/BaseEntity' 2 | 3 | export class DevicePayloadEntity extends BaseEntity { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/model/asset/device/DeviceReportingEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | import { AirColor } from '@airpower/enum/AirColor' 3 | 4 | /** 5 | * # 设备上报状态 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class DeviceReportingEnum extends AirEnum { 10 | /** 11 | * ### 开启 12 | */ 13 | static readonly ENABLE = new DeviceReportingEnum(true, '开启', AirColor.SUCCESS) 14 | 15 | /** 16 | * ### 关闭 17 | */ 18 | static readonly DISABLE = new DeviceReportingEnum(false, '关闭', AirColor.NORMAL) 19 | } 20 | -------------------------------------------------------------------------------- /src/model/asset/device/DeviceService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { DeviceEntity } from './DeviceEntity' 3 | import { CollectionEntity } from '@/model/iot/collection/CollectionEntity' 4 | 5 | export class DeviceService extends AbstractBaseService { 6 | entityClass = DeviceEntity 7 | 8 | baseUrl = 'device' 9 | 10 | async getCurrentReport(id: number): Promise { 11 | return this.api('getCurrentReport') 12 | .requestArray(new DeviceEntity(id), CollectionEntity) 13 | } 14 | 15 | async getDevicePayloadHistory(item: CollectionEntity): Promise { 16 | return this.api('getDevicePayloadHistory') 17 | .requestArray(item, CollectionEntity) 18 | } 19 | 20 | async getDeviceByUuid(uuid: string): Promise { 21 | const device = new DeviceEntity() 22 | device.uuid = uuid 23 | return this.api('getDeviceConfig') 24 | .request(device, DeviceEntity) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/model/asset/device/DeviceStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | 3 | export class DeviceStatusEnum extends AirEnum { 4 | static readonly UNKNOWN = new DeviceStatusEnum(0, '未知', '#999') 5 | 6 | static readonly ALARM = new DeviceStatusEnum(1, '报警', '#e14027') 7 | 8 | static readonly RUNNING = new DeviceStatusEnum(2, '运行', '#73cc44') 9 | 10 | static readonly FREE = new DeviceStatusEnum(3, '空闲', '#e3d349') 11 | 12 | static readonly DOWN = new DeviceStatusEnum(4, '关机', '#616665') 13 | 14 | static readonly DEBUG = new DeviceStatusEnum(5, '调试', '#1d23ed') 15 | } 16 | -------------------------------------------------------------------------------- /src/model/asset/material/MaterialEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { IPayload } from '@airpower/interface/IPayload' 3 | import { BaseEntity } from '@/base/BaseEntity' 4 | import { UnitEntity } from '@/model/system/unit/UnitEntity' 5 | import { MaterialTypeEnum } from './MaterialTypeEnum' 6 | 7 | @Model({ 8 | label: '物料', 9 | }) 10 | export class MaterialEntity extends BaseEntity implements IPayload { 11 | @Field({ 12 | label: '物料名称', 13 | }) name!: string 14 | 15 | @Field({ 16 | label: '物料编码', 17 | }) code!: string 18 | 19 | @Field({ 20 | label: '物料类型', 21 | dictionary: MaterialTypeEnum, 22 | }) 23 | materialType!: number 24 | 25 | @Field({ 26 | label: '规格型号', 27 | }) 28 | spc!: string 29 | 30 | @Field({ 31 | label: '计量单位', 32 | type: UnitEntity, 33 | alias: 'unitInfo', 34 | }) 35 | unit!: UnitEntity 36 | 37 | @Field({ 38 | label: '采购单价', 39 | type: Number, 40 | }) 41 | purchasePrice!: number 42 | 43 | @Field({ 44 | label: '销售单价', 45 | type: Number, 46 | }) 47 | salePrice!: number 48 | 49 | getPayloadLabel(): string { 50 | return `${this.name}(${this.code})` 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/model/asset/material/MaterialService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { MaterialEntity } from './MaterialEntity' 3 | 4 | export class MaterialService extends AbstractBaseService { 5 | entityClass = MaterialEntity 6 | 7 | baseUrl = 'material' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/asset/material/MaterialTypeEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | import { AirColor } from '@airpower/enum/AirColor' 3 | 4 | export class MaterialTypeEnum extends AirEnum { 5 | static readonly PRODUCT = new MaterialTypeEnum(1, '自产品', AirColor.SUCCESS) 6 | 7 | static readonly PURCHASE = new MaterialTypeEnum(2, '外购品', AirColor.WARNING) 8 | } 9 | -------------------------------------------------------------------------------- /src/model/channel/customer/CustomerEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { IPayload } from '@airpower/interface/IPayload' 3 | import { BaseEntity } from '@/base/BaseEntity' 4 | 5 | @Model({ 6 | label: '客户', 7 | }) 8 | export class CustomerEntity extends BaseEntity implements IPayload { 9 | @Field({ 10 | label: '客户名称', 11 | }) 12 | name!: string 13 | 14 | @Field({ 15 | label: '客户编码', 16 | }) 17 | code!: string 18 | 19 | @Field({ 20 | label: '联系电话', 21 | }) 22 | phone!: string 23 | 24 | getPayloadLabel(): string { 25 | return this.name 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/model/channel/customer/CustomerService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { CustomerEntity } from './CustomerEntity' 3 | 4 | export class CustomerService extends AbstractBaseService { 5 | entityClass = CustomerEntity 6 | 7 | baseUrl = 'customer' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/channel/purchase/PurchaseDetailEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 3 | import { SupplierEntity } from '../supplier/SupplierEntity' 4 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 5 | 6 | @Model({ 7 | label: '采购明细', 8 | }) 9 | export class PurchaseDetailEntity extends AbstractBaseBillDetailEntity { 10 | @Field({ 11 | type: MaterialEntity, 12 | }) 13 | material!: MaterialEntity 14 | 15 | @Field({ 16 | type: SupplierEntity, 17 | }) 18 | supplier!: SupplierEntity 19 | 20 | @Field({ 21 | label: '物料编码', 22 | }) 23 | materialCode!: string 24 | 25 | @Field({ 26 | label: '物料名称', 27 | }) 28 | materialName!: string 29 | 30 | @Field({ 31 | label: '供应商名称', 32 | }) 33 | supplierName!: string 34 | 35 | @Field({ 36 | label: '供应商编码', 37 | }) 38 | supplierCode!: string 39 | 40 | @Field({ 41 | label: '采购单价', 42 | type: Number, 43 | }) 44 | price!: number 45 | 46 | @Field({ 47 | label: '采购数量', 48 | type: Number, 49 | }) 50 | quantity!: number 51 | 52 | @Field({ 53 | label: '已采购数量', 54 | type: Number, 55 | }) 56 | finishQuantity!: number 57 | } 58 | -------------------------------------------------------------------------------- /src/model/channel/purchase/PurchaseDetailService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { PurchaseDetailEntity } from './PurchaseDetailEntity' 3 | 4 | export class PurchaseDetailService extends AbstractBaseService { 5 | entityClass = PurchaseDetailEntity 6 | 7 | baseUrl = 'purchaseDetail' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/channel/purchase/PurchaseEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | import { PurchaseStatusEnum } from './PurchaseStatusEnum' 4 | import { PurchaseDetailEntity } from './PurchaseDetailEntity' 5 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 6 | 7 | @Model({ 8 | label: '采购单', 9 | }) 10 | export class PurchaseEntity extends AbstractBaseBillEntity { 11 | @Field({ 12 | label: '采购单号', 13 | }) 14 | declare billCode: string 15 | 16 | @Field({ 17 | label: '采购事由', 18 | }) 19 | reason!: string 20 | 21 | @Field({ 22 | label: '总金额', 23 | }) 24 | totalPrice!: number 25 | 26 | @Field({ 27 | label: '实际金额', 28 | }) 29 | totalRealPrice!: number 30 | 31 | @Field({ 32 | label: '采购状态', 33 | dictionary: PurchaseStatusEnum, 34 | }) 35 | status!: number 36 | 37 | @Field({ 38 | label: '采购明细', 39 | type: PurchaseDetailEntity, 40 | array: true, 41 | }) 42 | details: PurchaseDetailEntity[] = [] 43 | 44 | public getAuditingStatus(): AirEnum { 45 | return PurchaseStatusEnum.AUDITING 46 | } 47 | 48 | public getAuditedStatus(): AirEnum { 49 | return PurchaseStatusEnum.PURCHASING 50 | } 51 | 52 | public getRejectedStatus(): AirEnum { 53 | return PurchaseStatusEnum.REJECTED 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/model/channel/purchase/PurchaseService.ts: -------------------------------------------------------------------------------- 1 | import { PurchaseDetailEntity } from './PurchaseDetailEntity' 2 | import { PurchaseEntity } from './PurchaseEntity' 3 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 4 | 5 | export class PurchaseService extends AbstractBaseBillService { 6 | entityClass = PurchaseEntity 7 | 8 | baseUrl = 'purchase' 9 | } 10 | -------------------------------------------------------------------------------- /src/model/channel/purchase/PurchaseStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 采购单状态枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class PurchaseStatusEnum extends AirEnum { 10 | static readonly AUDITING = new PurchaseStatusEnum(1, '审核中', AirColor.WARNING) 11 | 12 | static readonly REJECTED = new PurchaseStatusEnum(2, '已驳回', AirColor.DANGER) 13 | 14 | static readonly PURCHASING = new PurchaseStatusEnum(3, '采购中', AirColor.WARNING) 15 | 16 | static readonly INPUTTING = new PurchaseStatusEnum(4, '入库中', AirColor.NORMAL) 17 | 18 | static readonly DONE = new PurchaseStatusEnum(5, '已完成', AirColor.SUCCESS) 19 | } 20 | -------------------------------------------------------------------------------- /src/model/channel/purchasePrice/PurchasePriceEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 4 | import { SupplierEntity } from '../supplier/SupplierEntity' 5 | 6 | @Model({ 7 | label: '采购价', 8 | }) 9 | export class PurchasePriceEntity extends BaseEntity { 10 | @Field({ 11 | type: MaterialEntity, 12 | }) 13 | material!: MaterialEntity 14 | 15 | @Field({ 16 | type: SupplierEntity, 17 | }) 18 | supplier!: SupplierEntity 19 | 20 | @Field({ 21 | label: '物料编码', 22 | }) 23 | materialCode!: string 24 | 25 | @Field({ 26 | label: '物料名称', 27 | }) 28 | materialName!: string 29 | 30 | @Field({ 31 | label: '供应商名称', 32 | }) 33 | supplierName!: string 34 | 35 | @Field({ 36 | label: '供应商编码', 37 | }) 38 | supplierCode!: string 39 | 40 | @Field({ 41 | label: '采购单价', 42 | type: Number, 43 | }) 44 | price!: number 45 | } 46 | -------------------------------------------------------------------------------- /src/model/channel/purchasePrice/PurchasePriceService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { PurchasePriceEntity } from './PurchasePriceEntity' 3 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 4 | import { SupplierEntity } from '../supplier/SupplierEntity' 5 | 6 | export class PurchasePriceService extends AbstractBaseService { 7 | entityClass = PurchasePriceEntity 8 | 9 | baseUrl = 'purchasePrice' 10 | 11 | async getByMaterialAndSupplier(materialId: number, supplierId: number): Promise { 12 | const entity = new PurchasePriceEntity() 13 | entity.material = new MaterialEntity(materialId) 14 | entity.supplier = new SupplierEntity(supplierId) 15 | try { 16 | return this.api('getByMaterialAndSupplier') 17 | .callbackError() 18 | .request(entity, PurchasePriceEntity) 19 | } catch (e) { 20 | return null 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/model/channel/sale/SaleDetailEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 3 | import { CustomerEntity } from '../customer/CustomerEntity' 4 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 5 | 6 | @Model({ 7 | label: '销售明细', 8 | }) 9 | export class SaleDetailEntity extends AbstractBaseBillDetailEntity { 10 | @Field({ 11 | type: MaterialEntity, 12 | }) 13 | material!: MaterialEntity 14 | 15 | @Field({ 16 | label: '物料编码', 17 | }) 18 | materialCode!: string 19 | 20 | @Field({ 21 | label: '物料名称', 22 | }) 23 | materialName!: string 24 | 25 | @Field({ 26 | label: '物料', 27 | type: Number, 28 | }) 29 | materialId!: number 30 | 31 | @Field({ 32 | label: '销售单价', 33 | type: Number, 34 | }) 35 | price!: number 36 | 37 | @Field({ 38 | label: '销售数量', 39 | type: Number, 40 | }) 41 | quantity!: number 42 | 43 | @Field({ 44 | type: Number, 45 | }) 46 | finishQuantity!: number 47 | 48 | @Field({ 49 | type: CustomerEntity, 50 | }) 51 | customer!: CustomerEntity 52 | } 53 | -------------------------------------------------------------------------------- /src/model/channel/sale/SaleDetailService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { SaleDetailEntity } from './SaleDetailEntity' 3 | 4 | export class SaleDetailService extends AbstractBaseService { 5 | entityClass = SaleDetailEntity 6 | 7 | baseUrl = 'saleDetail' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/channel/sale/SaleEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | import { SaleStatusEnum } from './SaleStatusEnum' 4 | import { SaleDetailEntity } from './SaleDetailEntity' 5 | import { CustomerEntity } from '../customer/CustomerEntity' 6 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 7 | 8 | @Model({ 9 | label: '销售单', 10 | }) 11 | export class SaleEntity extends AbstractBaseBillEntity { 12 | @Field({ 13 | label: '销售单号', 14 | }) 15 | declare billCode: string 16 | 17 | @Field({ 18 | label: '销售说明', 19 | }) 20 | reason!: string 21 | 22 | @Field({ 23 | label: '总金额', 24 | }) 25 | totalPrice!: number 26 | 27 | @Field({ 28 | label: '销售状态', 29 | dictionary: SaleStatusEnum, 30 | }) 31 | status!: number 32 | 33 | @Field({ 34 | label: '销售明细', 35 | type: SaleDetailEntity, 36 | array: true, 37 | }) 38 | details: SaleDetailEntity[] = [] 39 | 40 | @Field({ 41 | label: '客户', 42 | type: CustomerEntity, 43 | }) 44 | customer!: CustomerEntity 45 | 46 | getAuditingStatus(): AirEnum { 47 | return SaleStatusEnum.AUDITING 48 | } 49 | 50 | getAuditedStatus(): AirEnum { 51 | return SaleStatusEnum.OUTPUTTING 52 | } 53 | 54 | getRejectedStatus(): AirEnum { 55 | return SaleStatusEnum.REJECTED 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/model/channel/sale/SaleService.ts: -------------------------------------------------------------------------------- 1 | import { SaleEntity } from './SaleEntity' 2 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 3 | import { SaleDetailEntity } from './SaleDetailEntity' 4 | 5 | export class SaleService extends AbstractBaseBillService { 6 | entityClass = SaleEntity 7 | 8 | baseUrl = 'sale' 9 | } 10 | -------------------------------------------------------------------------------- /src/model/channel/sale/SaleStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 销售单状态枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class SaleStatusEnum extends AirEnum { 10 | static readonly AUDITING = new SaleStatusEnum(1, '审核中', AirColor.WARNING) 11 | 12 | static readonly REJECTED = new SaleStatusEnum(2, '已驳回', AirColor.DANGER) 13 | 14 | static readonly OUTPUTTING = new SaleStatusEnum(3, '出库中', AirColor.NORMAL) 15 | 16 | static readonly DONE = new SaleStatusEnum(4, '已完成', AirColor.SUCCESS) 17 | } 18 | -------------------------------------------------------------------------------- /src/model/channel/salePrice/SalePriceEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 4 | import { CustomerEntity } from '../customer/CustomerEntity' 5 | 6 | @Model({ 7 | label: '销售价', 8 | }) 9 | export class SalePriceEntity extends BaseEntity { 10 | @Field({ 11 | type: MaterialEntity, 12 | }) 13 | material!: MaterialEntity 14 | 15 | @Field({ 16 | type: CustomerEntity, 17 | }) 18 | customer!: CustomerEntity 19 | 20 | @Field({ 21 | label: '物料编码', 22 | }) 23 | materialCode!: string 24 | 25 | @Field({ 26 | label: '物料名称', 27 | }) 28 | materialName!: string 29 | 30 | @Field({ 31 | label: '客户编码', 32 | }) 33 | customerName!: string 34 | 35 | @Field({ 36 | label: '客户名称', 37 | }) 38 | customerCode!: string 39 | 40 | @Field({ 41 | label: '物料', 42 | type: Number, 43 | }) 44 | materialId!: number 45 | 46 | @Field({ 47 | label: '销售单价', 48 | type: Number, 49 | }) 50 | price!: number 51 | } 52 | -------------------------------------------------------------------------------- /src/model/channel/salePrice/SalePriceService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { SalePriceEntity } from './SalePriceEntity' 3 | import { CustomerEntity } from '../customer/CustomerEntity' 4 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 5 | 6 | export class SalePriceService extends AbstractBaseService { 7 | entityClass = SalePriceEntity 8 | 9 | baseUrl = 'salePrice' 10 | 11 | async getByMaterialAndCustomer(materialId: number, customerId: number): Promise { 12 | const entity = new SalePriceEntity() 13 | entity.material = new MaterialEntity(materialId) 14 | entity.customer = new CustomerEntity(customerId) 15 | try { 16 | return this.api('getByMaterialAndCustomer') 17 | .callbackError() 18 | .request(entity, SalePriceEntity) 19 | } catch (e) { 20 | return null 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/model/channel/supplier/SupplierEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { IPayload } from '@airpower/interface/IPayload' 3 | import { BaseEntity } from '@/base/BaseEntity' 4 | 5 | @Model({ 6 | label: '供应商', 7 | }) 8 | export class SupplierEntity extends BaseEntity implements IPayload { 9 | @Field({ 10 | label: '供应商名称', 11 | }) 12 | name!: string 13 | 14 | @Field({ 15 | label: '供应商编码', 16 | }) 17 | code!: string 18 | 19 | @Field({ 20 | label: '联系电话', 21 | }) 22 | phone!: string 23 | 24 | getPayloadLabel(): string { 25 | return this.name 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/model/channel/supplier/SupplierService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { SupplierEntity } from './SupplierEntity' 3 | 4 | export class SupplierService extends AbstractBaseService { 5 | entityClass = SupplierEntity 6 | 7 | baseUrl = 'supplier' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/common/BooleanYesNoDictionary.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | export class BooleanYesNoDictionary extends AirEnum { 5 | static readonly YES = new BooleanYesNoDictionary(true, '是', AirColor.SUCCESS) 6 | 7 | static readonly NO = new BooleanYesNoDictionary(false, '否', AirColor.NORMAL) 8 | } 9 | -------------------------------------------------------------------------------- /src/model/common/LoginAction.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | /** 3 | * # 登录方式枚举 4 | * @author Hamm.cn 5 | */ 6 | export enum LoginAction { 7 | /** 8 | * ### 账号密码登录 9 | */ 10 | LOGIN_VIA_PASSWORD = '密码登录', 11 | 12 | /** 13 | * ### 邮箱验证码登录 14 | */ 15 | LOGIN_VIA_EMAIL = '邮箱登录', 16 | 17 | /** 18 | * ### 手机短信验证码登录 19 | */ 20 | LOGIN_VIA_PHONE = '手机登录', 21 | 22 | /** 23 | * ### 扫码登录 24 | */ 25 | LOGIN_VIA_QRCODE = '扫码登录', 26 | 27 | /** 28 | * ### 第三方登录 29 | */ 30 | LOGIN_VIA_THIRD_PARTY = '第三方登录', 31 | 32 | /** 33 | * ### 注册账号 34 | */ 35 | REGISTER_VIA_EMAIL = '注册账号', 36 | } 37 | -------------------------------------------------------------------------------- /src/model/common/OrderNumberDictionary.ts: -------------------------------------------------------------------------------- 1 | import { AirDictionaryArray } from '@airpower/model/extend/AirDictionaryArray' 2 | 3 | export const OrderNumberDictionary = AirDictionaryArray.create( 4 | Array.from({ length: 100 }, (_, i) => i + 1).map((order) => ({ key: order, label: order.toString() })), 5 | ) 6 | -------------------------------------------------------------------------------- /src/model/common/PublishStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | export class PublishStatusEnum extends AirEnum { 5 | static readonly YES = new PublishStatusEnum(true, '已发布', AirColor.SUCCESS) 6 | 7 | static readonly NO = new PublishStatusEnum(false, '待发布', AirColor.NORMAL) 8 | } 9 | -------------------------------------------------------------------------------- /src/model/factory/storage/StorageEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { ITree } from '@airpower/interface/ITree' 3 | import { IPayload } from '@airpower/interface/IPayload' 4 | import { BaseEntity } from '@/base/BaseEntity' 5 | 6 | @Model({ 7 | label: '仓库', 8 | }) 9 | export class StorageEntity extends BaseEntity implements ITree, IPayload { 10 | @Field({ 11 | label: '仓库名称', 12 | }) 13 | name!: string 14 | 15 | @Field({ 16 | label: '仓库编码', 17 | }) 18 | code!: string 19 | 20 | @Field({ 21 | // eslint-disable-next-line no-use-before-define 22 | type: StorageEntity, 23 | array: true, 24 | }) 25 | children!: this[] 26 | 27 | parentId!: number 28 | 29 | @Field({ 30 | label: '所属上级', 31 | // eslint-disable-next-line no-use-before-define 32 | type: StorageEntity, 33 | }) 34 | parent!: this 35 | 36 | getPayloadLabel(): string { 37 | return this.name 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/model/factory/storage/StorageService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { StorageEntity } from './StorageEntity' 3 | 4 | export class StorageService extends AbstractBaseService { 5 | baseUrl = 'storage' 6 | 7 | entityClass = StorageEntity 8 | } 9 | -------------------------------------------------------------------------------- /src/model/factory/structure/StructureEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { IPayload } from '@airpower/interface/IPayload' 3 | import { ITree } from '@airpower/interface/ITree' 4 | import { BaseEntity } from '@/base/BaseEntity' 5 | import { OperationEntity } from '@/model/mes/operation/OperationEntity' 6 | 7 | @Model({ 8 | label: '生产单元', 9 | }) 10 | export class StructureEntity extends BaseEntity implements ITree, IPayload { 11 | @Field({ 12 | label: '生产单元名称', 13 | }) 14 | name!: string 15 | 16 | @Field({ 17 | label: '生产单元编码', 18 | }) 19 | code!: string 20 | 21 | @Field({ 22 | // eslint-disable-next-line no-use-before-define 23 | type: StructureEntity, 24 | array: true, 25 | }) 26 | children!: this[] 27 | 28 | parentId!: number 29 | 30 | @Field({ 31 | label: '所属上级', 32 | // eslint-disable-next-line no-use-before-define 33 | type: StructureEntity, 34 | }) 35 | parent!: this 36 | 37 | @Field({ 38 | type: OperationEntity, 39 | array: true, 40 | label: '可执行工序', 41 | }) 42 | operationList!: OperationEntity[] 43 | 44 | getPayloadLabel(): string { 45 | return this.name 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/model/factory/structure/StructureService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { StructureEntity } from './StructureEntity' 3 | 4 | export class StructureService extends AbstractBaseService { 5 | baseUrl = 'structure' 6 | 7 | entityClass = StructureEntity 8 | } 9 | -------------------------------------------------------------------------------- /src/model/iot/collection/CollectionDefault.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | /** 3 | * # 设备默认采集项 4 | */ 5 | export enum CollectionDefault { 6 | STATUS = 'Status', 7 | ALARM = 'Alarm', 8 | PART_COUNT = 'PartCount' 9 | } 10 | -------------------------------------------------------------------------------- /src/model/iot/collection/CollectionEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { CollectionGranularityEnum } from './CollectionGranularityEnum' 4 | 5 | @Model({ 6 | label: '采集参数', 7 | }) 8 | export class CollectionEntity extends BaseEntity { 9 | @Field({ 10 | label: '参数名称', 11 | }) 12 | code!: string 13 | 14 | @Field({ 15 | label: '参数标题', 16 | }) 17 | label!: string 18 | 19 | @Field({ 20 | label: '参数采集值', 21 | }) 22 | value!: string 23 | 24 | @Field({ 25 | label: '最后变更', 26 | }) 27 | timestamp!: number 28 | 29 | @Field({ 30 | label: 'uuid', 31 | }) 32 | uuid!: string 33 | 34 | @Field({ 35 | label: '颗粒度', 36 | dictionary: CollectionGranularityEnum, 37 | }) 38 | reportGranularity!: number 39 | 40 | intValue!: number 41 | 42 | booleanValue!: boolean 43 | 44 | strValue!: string 45 | 46 | startTime!: number 47 | 48 | endTime!: number 49 | 50 | dataType!: number 51 | } 52 | -------------------------------------------------------------------------------- /src/model/iot/collection/CollectionGranularityEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | 3 | export class CollectionGranularityEnum extends AirEnum { 4 | static ONE_MINUTE = new CollectionGranularityEnum(60, '每分钟') 5 | 6 | static FIVE_MINUTES = new CollectionGranularityEnum(300, '每五分钟') 7 | 8 | static THIRTY_MINUTES = new CollectionGranularityEnum(1800, '每半小时') 9 | 10 | static ONE_HOUR = new CollectionGranularityEnum(3600, '每小时') 11 | 12 | static ONE_DAY = new CollectionGranularityEnum(86400, '每天') 13 | 14 | static ONE_WEEK = new CollectionGranularityEnum(604800, '每周') 15 | 16 | static ONE_MONTH = new CollectionGranularityEnum(2678400, '每月') 17 | } 18 | -------------------------------------------------------------------------------- /src/model/iot/collection/CollectionService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { CollectionEntity } from './CollectionEntity' 3 | 4 | export class CollectionService extends AbstractBaseService { 5 | entityClass = CollectionEntity 6 | 7 | baseUrl = 'collection' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/iot/parameter/ParameterEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { ParameterTypeEnum } from './ParameterTypeEnum' 4 | import { ParameterSystemEnum } from '@/model/iot/parameter/ParameterSystemEnum' 5 | 6 | @Model({ 7 | label: '采集参数', 8 | }) 9 | export class ParameterEntity extends BaseEntity { 10 | @Field({ 11 | label: '参数名称', 12 | }) 13 | code!: string 14 | 15 | @Field({ 16 | label: '参数标题', 17 | }) 18 | label!: string 19 | 20 | @Field({ 21 | label: '数据类型', 22 | dictionary: ParameterTypeEnum, 23 | }) 24 | dataType!: number 25 | 26 | @Field({ 27 | label: '参数类别', 28 | dictionary: ParameterSystemEnum, 29 | }) 30 | isSystem!: boolean 31 | } 32 | -------------------------------------------------------------------------------- /src/model/iot/parameter/ParameterService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { ParameterEntity } from './ParameterEntity' 3 | 4 | export class ParameterService extends AbstractBaseService { 5 | entityClass = ParameterEntity 6 | 7 | baseUrl = 'parameter' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/iot/parameter/ParameterSystemEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | export class ParameterSystemEnum extends AirEnum { 5 | static readonly DEFINE = new ParameterSystemEnum(false, '定义参数', AirColor.NORMAL) 6 | 7 | static readonly SYSTEM = new ParameterSystemEnum(true, '系统参数', AirColor.DANGER) 8 | } 9 | -------------------------------------------------------------------------------- /src/model/iot/parameter/ParameterTypeEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | 3 | export class ParameterTypeEnum extends AirEnum { 4 | static QUANTITY = new ParameterTypeEnum(1, '数字') 5 | 6 | static STATUS = new ParameterTypeEnum(2, '状态') 7 | 8 | static SWITCH = new ParameterTypeEnum(3, '开关') 9 | 10 | static INFORMATION = new ParameterTypeEnum(4, '信息') 11 | } 12 | -------------------------------------------------------------------------------- /src/model/mes/bom/BomDetailEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 3 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 4 | 5 | @Model({ 6 | label: '配方明细', 7 | }) 8 | export class BomDetailEntity extends AbstractBaseBillDetailEntity { 9 | @Field({ 10 | type: MaterialEntity, 11 | }) 12 | material!: MaterialEntity 13 | 14 | @Field({ 15 | label: '物料编码', 16 | }) 17 | materialCode!: string 18 | 19 | @Field({ 20 | label: '物料名称', 21 | }) 22 | materialName!: string 23 | 24 | @Field({ 25 | label: '所需数量', 26 | }) 27 | quantity!: number 28 | 29 | finishQuantity!: number 30 | } 31 | -------------------------------------------------------------------------------- /src/model/mes/bom/BomDetailService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { BomDetailEntity } from './BomDetailEntity' 3 | 4 | export class BomDetailService extends AbstractBaseService { 5 | entityClass = BomDetailEntity 6 | 7 | baseUrl = 'bomDetail' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/mes/bom/BomEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { IPayload } from '@airpower/interface/IPayload' 3 | import { BomDetailEntity } from '@/model/mes/bom/BomDetailEntity' 4 | import { BomTypeEnum } from '@/model/mes/bom/BomTypeEnum' 5 | import { BaseEntity } from '@/base/BaseEntity' 6 | 7 | /** 8 | * # 生产配方 9 | * @author Hamm.cn 10 | */ 11 | 12 | @Model({ 13 | label: '生产配方', 14 | }) 15 | export class BomEntity extends BaseEntity implements IPayload { 16 | @Field({ 17 | label: '配方编码', 18 | }) 19 | code!: string 20 | 21 | @Field({ 22 | label: '配方名称', 23 | }) 24 | name!: string 25 | 26 | @Field({ 27 | label: '配方类型', 28 | dictionary: BomTypeEnum, 29 | }) 30 | type!: number 31 | 32 | @Field({ 33 | label: '配方明细', 34 | type: BomDetailEntity, 35 | array: true, 36 | }) 37 | details: BomDetailEntity[] = [] 38 | 39 | getPayloadLabel(): string { 40 | return this.name 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/model/mes/bom/BomService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { BomEntity } from './BomEntity' 3 | 4 | /** 5 | * # BOM接口服务 6 | * @author Hamm.cn 7 | */ 8 | export class BomService extends AbstractBaseService { 9 | baseUrl = 'bom' 10 | 11 | entityClass = BomEntity 12 | } 13 | -------------------------------------------------------------------------------- /src/model/mes/bom/BomTypeEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 配方类型枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class BomTypeEnum extends AirEnum { 10 | static readonly NORMAL = new BomTypeEnum(1, '普通配方', AirColor.SUCCESS) 11 | 12 | static readonly OPERATION = new BomTypeEnum(2, '工序配方', AirColor.WARNING) 13 | } 14 | -------------------------------------------------------------------------------- /src/model/mes/operation/OperationEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | 4 | /** 5 | * # 工序 6 | * @author Hamm.cn 7 | */ 8 | @Model({ 9 | label: '工序', 10 | }) 11 | export class OperationEntity extends BaseEntity { 12 | @Field({ 13 | label: '工序名称', 14 | type: String, 15 | }) 16 | name!: string 17 | 18 | @Field({ 19 | label: '工序编码', 20 | type: String, 21 | }) 22 | code!: string 23 | } 24 | -------------------------------------------------------------------------------- /src/model/mes/operation/OperationService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { OperationEntity } from './OperationEntity' 3 | 4 | export class OperationService extends AbstractBaseService { 5 | baseUrl = 'operation' 6 | 7 | entityClass = OperationEntity 8 | } 9 | -------------------------------------------------------------------------------- /src/model/mes/order/OrderDetailEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 3 | 4 | @Model({ 5 | label: '订单明细', 6 | }) 7 | export class OrderDetailEntity extends AbstractBaseBillDetailEntity { 8 | quantity!: number 9 | 10 | @Field({ 11 | label: '完成数量', 12 | }) 13 | finishQuantity!: number 14 | 15 | @Field({ 16 | label: '异常数量', 17 | }) 18 | ngQuantity!: number 19 | } 20 | -------------------------------------------------------------------------------- /src/model/mes/order/OrderDetailService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { OrderDetailEntity } from './OrderDetailEntity' 3 | 4 | export class OrderDetailService extends AbstractBaseService { 5 | entityClass = OrderDetailEntity 6 | 7 | baseUrl = 'orderDetail' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/mes/order/OrderEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 4 | import { CustomerEntity } from '@/model/channel/customer/CustomerEntity' 5 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 6 | import { OrderStatusEnum } from './OrderStatusEnum' 7 | import { OrderTypeEnum } from './OrderTypeEnum' 8 | import { OrderDetailEntity } from './OrderDetailEntity' 9 | import { PlanEntity } from '../plan/PlanEntity' 10 | import { RoutingEntity } from '@/model/mes/routing/RoutingEntity' 11 | 12 | @Model({ 13 | label: '生产订单', 14 | }) 15 | export class OrderEntity extends AbstractBaseBillEntity { 16 | @Field({ 17 | label: '生产订单号', 18 | }) 19 | declare billCode: string 20 | 21 | @Field({ 22 | type: MaterialEntity, 23 | }) 24 | material!: MaterialEntity 25 | 26 | @Field({ 27 | label: '物料编码', 28 | }) 29 | materialCode!: string 30 | 31 | @Field({ 32 | label: '物料名称', 33 | }) 34 | materialName!: string 35 | 36 | @Field({ 37 | label: '生产数量', 38 | type: Number, 39 | }) 40 | quantity!: number 41 | 42 | @Field({ 43 | label: '完成数量', 44 | type: Number, 45 | }) 46 | finishQuantity!: number 47 | 48 | @Field({ 49 | label: '异常数量', 50 | type: Number, 51 | }) 52 | ngQuantity!: number 53 | 54 | @Field({ 55 | label: '生产计划号', 56 | }) 57 | planBillCode!: string 58 | 59 | @Field({ 60 | label: '订单状态', 61 | dictionary: OrderStatusEnum, 62 | }) 63 | status!: number 64 | 65 | @Field({ 66 | label: '订单类型', 67 | dictionary: OrderTypeEnum, 68 | }) 69 | type!: number 70 | 71 | @Field({ 72 | label: '开始时间', 73 | }) 74 | startTime!: number 75 | 76 | @Field({ 77 | label: '交付时间', 78 | }) 79 | deliverTime!: number 80 | 81 | @Field({ 82 | label: '完成时间', 83 | }) 84 | finishTime!: number 85 | 86 | @Field({ 87 | label: '订单明细', 88 | type: OrderDetailEntity, 89 | array: true, 90 | }) 91 | details: OrderDetailEntity[] = [] 92 | 93 | @Field({ 94 | label: '客户信息', 95 | type: CustomerEntity, 96 | }) 97 | customer!: CustomerEntity 98 | 99 | @Field({ 100 | label: '生产工艺', 101 | type: RoutingEntity, 102 | }) 103 | routing!: RoutingEntity 104 | 105 | @Field({ 106 | label: '关联计划', 107 | type: PlanEntity, 108 | }) 109 | plan!: PlanEntity 110 | 111 | getAuditingStatus(): AirEnum { 112 | return OrderStatusEnum.AUDITING 113 | } 114 | 115 | getAuditedStatus(): AirEnum { 116 | return OrderStatusEnum.PRODUCING 117 | } 118 | 119 | getRejectedStatus(): AirEnum { 120 | return OrderStatusEnum.REJECTED 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/model/mes/order/OrderService.ts: -------------------------------------------------------------------------------- 1 | import { AirNotification } from '@airpower/feedback/AirNotification' 2 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 3 | import { OrderDetailEntity } from './OrderDetailEntity' 4 | import { OrderEntity } from './OrderEntity' 5 | 6 | export class OrderService extends AbstractBaseBillService { 7 | entityClass = OrderEntity 8 | 9 | baseUrl = 'order' 10 | 11 | async start(order: OrderEntity): Promise { 12 | await this.api('start') 13 | .post(order) 14 | AirNotification.success('订单开始生产成功') 15 | } 16 | 17 | async pause(order: OrderEntity): Promise { 18 | await this.api('pause') 19 | .post(order) 20 | AirNotification.success('订单暂停成功') 21 | } 22 | 23 | async addOrderDetail(order: OrderDetailEntity): Promise { 24 | await this.api('addOrderDetail') 25 | .post(order) 26 | AirNotification.success('订单报工成功') 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/model/mes/order/OrderStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 计划状态枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class OrderStatusEnum extends AirEnum { 10 | static readonly AUDITING = new OrderStatusEnum(1, '审核中', AirColor.WARNING) 11 | 12 | static readonly REJECTED = new OrderStatusEnum(2, '已驳回', AirColor.DANGER) 13 | 14 | static readonly PREPARE = new OrderStatusEnum(3, '准备中', AirColor.WARNING) 15 | 16 | static readonly PRODUCING = new OrderStatusEnum(4, '生产中', AirColor.WARNING) 17 | 18 | static readonly INPUTTING = new OrderStatusEnum(5, '入库中', AirColor.NORMAL) 19 | 20 | static readonly DONE = new OrderStatusEnum(6, '已完成', AirColor.SUCCESS) 21 | 22 | static readonly PAUSED = new OrderStatusEnum(7, '已暂停', AirColor.WARNING) 23 | } 24 | -------------------------------------------------------------------------------- /src/model/mes/order/OrderTypeEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 订单类型枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class OrderTypeEnum extends AirEnum { 10 | static readonly PLAN = new OrderTypeEnum(1, '计划订单', AirColor.SUCCESS) 11 | 12 | static readonly OTHER = new OrderTypeEnum(2, '其他订单', AirColor.WARNING) 13 | } 14 | -------------------------------------------------------------------------------- /src/model/mes/picking/PickingDetailEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 3 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 4 | 5 | @Model({ 6 | label: '领料明细', 7 | }) 8 | export class PickingDetailEntity extends AbstractBaseBillDetailEntity { 9 | @Field({ 10 | type: MaterialEntity, 11 | }) 12 | material!: MaterialEntity 13 | 14 | @Field({ 15 | label: '申领数量', 16 | type: Number, 17 | }) 18 | quantity!: number 19 | 20 | @Field({ 21 | label: '已出库数量', 22 | type: Number, 23 | }) 24 | finishQuantity!: number 25 | } 26 | -------------------------------------------------------------------------------- /src/model/mes/picking/PickingDetailService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { PickingDetailEntity } from './PickingDetailEntity' 3 | 4 | export class PickingDetailService extends AbstractBaseService { 5 | entityClass = PickingDetailEntity 6 | 7 | baseUrl = 'pickingDetail' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/mes/picking/PickingEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | import { PickingStatusEnum } from './PickingStatusEnum' 4 | import { PickingDetailEntity } from './PickingDetailEntity' 5 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 6 | import { StructureEntity } from '@/model/factory/structure/StructureEntity' 7 | 8 | @Model({ 9 | label: '领料单', 10 | }) 11 | export class PickingEntity extends AbstractBaseBillEntity { 12 | @Field({ 13 | label: '申领单号', 14 | }) 15 | declare billCode: string 16 | 17 | @Field({ 18 | label: '申领状态', 19 | dictionary: PickingStatusEnum, 20 | }) 21 | status!: number 22 | 23 | @Field({ 24 | label: '申领明细', 25 | type: PickingDetailEntity, 26 | array: true, 27 | }) 28 | details: PickingDetailEntity[] = [] 29 | 30 | @Field({ 31 | label: '生产单元', 32 | type: StructureEntity, 33 | }) 34 | structure!: StructureEntity 35 | 36 | getAuditingStatus(): AirEnum { 37 | return PickingStatusEnum.AUDITING 38 | } 39 | 40 | getAuditedStatus(): AirEnum { 41 | return PickingStatusEnum.OUTPUTTING 42 | } 43 | 44 | getRejectedStatus(): AirEnum { 45 | return PickingStatusEnum.REJECTED 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/model/mes/picking/PickingService.ts: -------------------------------------------------------------------------------- 1 | import { PickingDetailEntity } from './PickingDetailEntity' 2 | import { PickingEntity } from './PickingEntity' 3 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 4 | 5 | export class PickingService extends AbstractBaseBillService { 6 | entityClass = PickingEntity 7 | 8 | baseUrl = 'picking' 9 | } 10 | -------------------------------------------------------------------------------- /src/model/mes/picking/PickingStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 采购单状态枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class PickingStatusEnum extends AirEnum { 10 | static readonly AUDITING = new PickingStatusEnum(1, '审核中', AirColor.WARNING) 11 | 12 | static readonly REJECTED = new PickingStatusEnum(2, '已驳回', AirColor.DANGER) 13 | 14 | static readonly OUTPUTTING = new PickingStatusEnum(3, '出库中', AirColor.NORMAL) 15 | 16 | static readonly DONE = new PickingStatusEnum(4, '已完成', AirColor.SUCCESS) 17 | } 18 | -------------------------------------------------------------------------------- /src/model/mes/plan/PlanDetailEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 3 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 4 | 5 | @Model({ 6 | label: '计划明细', 7 | }) 8 | export class PlanDetailEntity extends AbstractBaseBillDetailEntity { 9 | @Field({ 10 | type: MaterialEntity, 11 | }) 12 | material!: MaterialEntity 13 | 14 | @Field({ 15 | label: '计划数量', 16 | type: Number, 17 | }) 18 | quantity!: number 19 | 20 | @Field({ 21 | label: '已完成数量', 22 | type: Number, 23 | }) 24 | finishQuantity!: number 25 | } 26 | -------------------------------------------------------------------------------- /src/model/mes/plan/PlanDetailService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { PlanDetailEntity } from './PlanDetailEntity' 3 | 4 | export class PlanDetailService extends AbstractBaseService { 5 | entityClass = PlanDetailEntity 6 | 7 | baseUrl = 'planDetail' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/mes/plan/PlanEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 4 | import { PlanDetailEntity } from './PlanDetailEntity' 5 | import { PlanStatusEnum } from './PlanStatusEnum' 6 | import { CustomerEntity } from '@/model/channel/customer/CustomerEntity' 7 | import { PlanTypeEnum } from './PlanTypeEnum' 8 | 9 | @Model({ 10 | label: '生产计划', 11 | }) 12 | export class PlanEntity extends AbstractBaseBillEntity { 13 | @Field({ 14 | label: '生产计划号', 15 | }) 16 | declare billCode: string 17 | 18 | @Field({ 19 | label: '计划状态', 20 | dictionary: PlanStatusEnum, 21 | }) 22 | status!: number 23 | 24 | @Field({ 25 | label: '计划类型', 26 | dictionary: PlanTypeEnum, 27 | }) 28 | type!: number 29 | 30 | @Field({ 31 | label: '开始时间', 32 | }) 33 | startTime!: number 34 | 35 | @Field({ 36 | label: '交付时间', 37 | }) 38 | deliverTime!: number 39 | 40 | @Field({ 41 | label: '完成时间', 42 | }) 43 | finishTime!: number 44 | 45 | @Field({ 46 | label: '计划明细', 47 | type: PlanDetailEntity, 48 | array: true, 49 | }) 50 | details: PlanDetailEntity[] = [] 51 | 52 | @Field({ 53 | label: '客户信息', 54 | type: CustomerEntity, 55 | }) 56 | customer!: CustomerEntity 57 | 58 | getAuditingStatus(): AirEnum { 59 | return PlanStatusEnum.AUDITING 60 | } 61 | 62 | getAuditedStatus(): AirEnum { 63 | return PlanStatusEnum.PRODUCING 64 | } 65 | 66 | getRejectedStatus(): AirEnum { 67 | return PlanStatusEnum.REJECTED 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/model/mes/plan/PlanService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 2 | import { PlanDetailEntity } from './PlanDetailEntity' 3 | import { PlanEntity } from './PlanEntity' 4 | 5 | export class PlanService extends AbstractBaseBillService { 6 | entityClass = PlanEntity 7 | 8 | baseUrl = 'plan' 9 | } 10 | -------------------------------------------------------------------------------- /src/model/mes/plan/PlanStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 计划状态枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class PlanStatusEnum extends AirEnum { 10 | static readonly AUDITING = new PlanStatusEnum(1, '审核中', AirColor.WARNING) 11 | 12 | static readonly REJECTED = new PlanStatusEnum(2, '已驳回', AirColor.DANGER) 13 | 14 | static readonly PRODUCING = new PlanStatusEnum(3, '生产中', AirColor.NORMAL) 15 | 16 | static readonly DONE = new PlanStatusEnum(4, '已完成', AirColor.SUCCESS) 17 | 18 | static readonly CANCELED = new PlanStatusEnum(5, '已取消', AirColor.NORMAL) 19 | } 20 | -------------------------------------------------------------------------------- /src/model/mes/plan/PlanTypeEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 计划类型枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class PlanTypeEnum extends AirEnum { 10 | static readonly INNER = new PlanTypeEnum(1, '内部计划', AirColor.NORMAL) 11 | 12 | static readonly SALE = new PlanTypeEnum(2, '外销计划', AirColor.SUCCESS) 13 | } 14 | -------------------------------------------------------------------------------- /src/model/mes/routing/RoutingEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { IPayload } from '@airpower/interface/IPayload' 3 | import { BaseEntity } from '@/base/BaseEntity' 4 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 5 | import { BomEntity } from '@/model/mes/bom/BomEntity' 6 | import { RoutingOperationEntity } from '@/model/mes/routing/operation/RoutingOperationEntity' 7 | import { BooleanYesNoDictionary } from '@/model/common/BooleanYesNoDictionary' 8 | 9 | /** 10 | * # 生产工艺 11 | * @author Hamm.cn 12 | */ 13 | @Model({ 14 | label: '生产工艺', 15 | }) 16 | export class RoutingEntity extends BaseEntity implements IPayload { 17 | @Field({ 18 | label: '工艺名称', 19 | type: String, 20 | }) 21 | name!: string 22 | 23 | @Field({ 24 | label: '工艺编码', 25 | type: String, 26 | }) 27 | code!: string 28 | 29 | @Field({ 30 | type: MaterialEntity, 31 | }) 32 | material!: MaterialEntity 33 | 34 | @Field({ 35 | type: BomEntity, 36 | }) 37 | bom!: BomEntity 38 | 39 | @Field({ 40 | type: RoutingOperationEntity, 41 | array: true, 42 | }) 43 | details: RoutingOperationEntity[] = [] 44 | 45 | @Field({ 46 | label: '工艺配方', 47 | type: Boolean, 48 | dictionary: BooleanYesNoDictionary, 49 | }) 50 | isRoutingBom!: boolean 51 | 52 | getPayloadLabel(): string { 53 | return this.name 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/model/mes/routing/RoutingService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { RoutingEntity } from './RoutingEntity' 3 | 4 | export class RoutingService extends AbstractBaseService { 5 | baseUrl = 'routing' 6 | 7 | entityClass = RoutingEntity 8 | } 9 | -------------------------------------------------------------------------------- /src/model/mes/routing/RoutingStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 工艺状态枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class RoutingStatusEnum extends AirEnum { 10 | static readonly AUDITING = new RoutingStatusEnum(1, '审核中', AirColor.WARNING) 11 | 12 | static readonly REJECTED = new RoutingStatusEnum(2, '已驳回', AirColor.DANGER) 13 | 14 | static readonly PUBLISHED = new RoutingStatusEnum(3, '已发布', AirColor.SUCCESS) 15 | } 16 | -------------------------------------------------------------------------------- /src/model/mes/routing/operation/RoutingOperationEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { OperationEntity } from '@/model/mes/operation/OperationEntity' 4 | import { BomEntity } from '@/model/mes/bom/BomEntity' 5 | 6 | /** 7 | * # 工序配置 8 | * @author Hamm.cn 9 | */ 10 | @Model({ 11 | label: '工序配置', 12 | }) 13 | export class RoutingOperationEntity extends BaseEntity { 14 | @Field({ 15 | type: BomEntity, 16 | }) 17 | bom!: BomEntity 18 | 19 | @Field({ 20 | type: OperationEntity, 21 | }) 22 | operation!: OperationEntity 23 | 24 | routingId!: number 25 | 26 | sortNo!: number 27 | 28 | isAutoNext!: boolean 29 | } 30 | -------------------------------------------------------------------------------- /src/model/mes/routing/operation/RoutingOperationService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { RoutingOperationEntity } from '@/model/mes/routing/operation/RoutingOperationEntity' 3 | 4 | export class RoutingOperationService extends AbstractBaseService { 5 | baseUrl = 'routingOperation' 6 | 7 | entityClass = RoutingOperationEntity 8 | } 9 | -------------------------------------------------------------------------------- /src/model/open/app/OpenAppArithmeticEnum.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | 3 | import { AirEnum } from '@airpower/base/AirEnum' 4 | import { AirColor } from '@airpower/enum/AirColor' 5 | 6 | /** 7 | * # 开放应用加密方式 8 | * @author Hamm.cn 9 | */ 10 | export class OpenAppArithmeticEnum extends AirEnum { 11 | static readonly NO = new OpenAppArithmeticEnum(0, '明文', AirColor.NORMAL) 12 | 13 | static readonly AES = new OpenAppArithmeticEnum(1, 'AES', AirColor.WARNING) 14 | 15 | static readonly RSA = new OpenAppArithmeticEnum(2, 'RSA', AirColor.SUCCESS) 16 | } 17 | -------------------------------------------------------------------------------- /src/model/open/app/OpenAppEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { OpenAppArithmeticEnum } from './OpenAppArithmeticEnum' 4 | import { BooleanYesNoDictionary } from '@/model/common/BooleanYesNoDictionary' 5 | 6 | @Model({ 7 | label: '应用', 8 | }) 9 | export class OpenAppEntity extends BaseEntity { 10 | @Field({ 11 | label: '应用名称', 12 | }) appName!: string 13 | 14 | @Field({ 15 | label: '内部应用', 16 | type: Boolean, 17 | dictionary: BooleanYesNoDictionary, 18 | }) 19 | isInternal!: boolean 20 | 21 | @Field({ 22 | label: 'AppKey', 23 | }) appKey!: string 24 | 25 | @Field({ 26 | label: 'AppSecret', 27 | }) appSecret!: string 28 | 29 | @Field({ 30 | label: '加密算法', 31 | dictionary: OpenAppArithmeticEnum, 32 | }) arithmetic!: number 33 | 34 | @Field({ 35 | label: '公钥', 36 | }) publicKey!: string 37 | 38 | @Field({ 39 | label: '私钥', 40 | }) privateKey!: string 41 | 42 | @Field({ 43 | label: '应用地址', 44 | }) url!: string 45 | 46 | @Field({ 47 | label: 'IP白名单', 48 | type: String, 49 | }) 50 | ipWhiteList!: string 51 | } 52 | -------------------------------------------------------------------------------- /src/model/open/app/OpenAppService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { OpenAppEntity } from './OpenAppEntity' 3 | 4 | export class OpenAppService extends AbstractBaseService { 5 | entityClass = OpenAppEntity 6 | 7 | baseUrl = 'openApp' 8 | 9 | /** 10 | * ### 通过应用Key获取一个应用 11 | * @param appKey 应用Key 12 | */ 13 | async getAppByKey(appKey: string): Promise { 14 | const app = new OpenAppEntity() 15 | app.appKey = appKey 16 | return this.api('getByAppKey') 17 | .request(app, OpenAppEntity) 18 | } 19 | 20 | /** 21 | * ### 重置指定应用的秘钥 22 | * @param app 应用 23 | */ 24 | async resetSecret(app: OpenAppEntity): Promise { 25 | const result = await this.api('resetSecret') 26 | .post(app) 27 | return result as unknown as string 28 | } 29 | 30 | /** 31 | * ### 添加并获取秘钥 32 | * @param app 应用 33 | */ 34 | async addAndGetSecret(app: OpenAppEntity): Promise { 35 | const result = await this.api('add') 36 | .post(app) 37 | return result as unknown as string 38 | } 39 | 40 | /** 41 | * ### 重置秘钥对 42 | * @param app 应用 43 | */ 44 | async resetKeyPair(app: OpenAppEntity) { 45 | const result = await this.api('resetKeyPair') 46 | .post(app) 47 | return result as unknown as string 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/model/open/log/OpenLogEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { OpenAppEntity } from '../app/OpenAppEntity' 4 | 5 | export class OpenLogEntity extends BaseEntity { 6 | @Field({ 7 | type: OpenAppEntity, 8 | }) openApp!: OpenAppEntity 9 | 10 | @Field({ 11 | label: '来源IP', 12 | }) ip!: string 13 | 14 | @Field({ 15 | label: '请求地址', 16 | }) url!: string 17 | 18 | @Field({ 19 | label: '请求数据', 20 | }) request!: string 21 | 22 | @Field({ 23 | label: '响应数据', 24 | }) response!: string 25 | 26 | @Field({ 27 | label: '处理时间', 28 | }) mSecond!: string 29 | 30 | @Field({ 31 | label: '请求时间', 32 | }) 33 | declare createTime: number 34 | 35 | @Field({ 36 | label: '响应时间', 37 | }) declare updateTime: number 38 | } 39 | -------------------------------------------------------------------------------- /src/model/open/log/OpenLogService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { OpenLogEntity } from './OpenLogEntity' 3 | 4 | export class OpenLogService extends AbstractBaseService { 5 | entityClass = OpenLogEntity 6 | 7 | baseUrl = 'openLog' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/open/notify/NotifyChannelEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | 3 | /** 4 | * # 通知渠道 5 | * @author Hamm.cn 6 | */ 7 | export class NotifyChannelEnum extends AirEnum { 8 | static readonly WORK_WECHAT = new NotifyChannelEnum(1, '企业微信') 9 | 10 | static readonly FEI_SHU = new NotifyChannelEnum(2, '飞书') 11 | 12 | static readonly DING_TALK = new NotifyChannelEnum(3, '钉钉') 13 | 14 | static readonly EMAIL = new NotifyChannelEnum(4, '邮件') 15 | 16 | static readonly WEB_HOOK = new NotifyChannelEnum(5, 'WebHook') 17 | } 18 | -------------------------------------------------------------------------------- /src/model/open/notify/NotifyEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { NotifyChannelEnum } from '@/model/open/notify/NotifyChannelEnum' 4 | 5 | @Model({ 6 | label: '通知', 7 | }) 8 | export class NotifyEntity extends BaseEntity { 9 | @Field({ 10 | label: '通知场景', 11 | }) 12 | scene !: number 13 | 14 | @Field({ 15 | label: '通知渠道', 16 | dictionary: NotifyChannelEnum, 17 | }) 18 | channel !: number 19 | 20 | @Field({ 21 | label: '通知地址', 22 | }) 23 | url !: string 24 | 25 | @Field({ 26 | label: '通知令牌', 27 | }) 28 | token !: string 29 | 30 | @Field({ 31 | label: '备注信息', 32 | }) 33 | remark!: string 34 | } 35 | -------------------------------------------------------------------------------- /src/model/open/notify/NotifyService.ts: -------------------------------------------------------------------------------- 1 | import { IDictionary } from '@airpower/interface/IDictionary' 2 | import { NotifyEntity } from '@/model/open/notify/NotifyEntity' 3 | import { AbstractBaseService } from '@/base/AbstractBaseService' 4 | 5 | export class NotifyService extends AbstractBaseService { 6 | baseUrl = 'notify' 7 | 8 | entityClass = NotifyEntity 9 | 10 | /** 11 | * ### 获取通知场景 12 | */ 13 | async getSceneList(): Promise { 14 | const result = await this.api('getSceneList') 15 | .post() 16 | return (result as unknown as IDictionary[]) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/model/open/oauth/OauthCreateCodeRequest.ts: -------------------------------------------------------------------------------- 1 | import { AirModel } from '@airpower/base/AirModel' 2 | 3 | /** 4 | * # Oauth 创建授权码 请求 5 | * @author Hamm.cn 6 | */ 7 | export class OauthCreateCodeRequest extends AirModel { 8 | /** 9 | * ### AppKey 10 | */ 11 | appKey!: string 12 | 13 | /** 14 | * ### 授权范围 15 | */ 16 | scope!: string 17 | } 18 | -------------------------------------------------------------------------------- /src/model/open/oauth/OauthScope.ts: -------------------------------------------------------------------------------- 1 | import { AirModel } from '@airpower/base/AirModel' 2 | 3 | /** 4 | * # 授权范围 5 | * @author Hamm.cn 6 | */ 7 | export class OauthScope extends AirModel { 8 | /** 9 | * ### 是否默认 10 | */ 11 | isDefault!: boolean 12 | 13 | /** 14 | * ### 名称 15 | */ 16 | name!: string 17 | 18 | /** 19 | * ### 标题 20 | */ 21 | label!: string 22 | 23 | /** 24 | * ### 描述 25 | */ 26 | description!: string 27 | } 28 | -------------------------------------------------------------------------------- /src/model/open/thirdlogin/ThirdLoginPlatform.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | 3 | /** 4 | * # 第三方登录平台 5 | * @author Hamm.cn 6 | */ 7 | export class ThirdLoginPlatform extends AirEnum { 8 | static readonly WECOM = new ThirdLoginPlatform(1, '企业微信', 'wecom') 9 | .setAppKey('ww4df4e5d397585277') 10 | .setOauthUrl('https://login.work.weixin.qq.com/wwlogin/sso/login?agentid=1000090&login_type=CorpApp&appid=APP_KEY&redirect_uri=REDIRECT_URI&state=STATE') 11 | 12 | static readonly WECHAT = new ThirdLoginPlatform(2, '微信', 'wechat', true) 13 | 14 | static readonly QQ = new ThirdLoginPlatform(3, 'QQ', 'qq', true) 15 | 16 | static readonly WEIBO = new ThirdLoginPlatform(4, '微博', 'weibo', true) 17 | 18 | static readonly DINGTALK = new ThirdLoginPlatform(5, '钉钉', 'dingtalk', true) 19 | 20 | static readonly FEISHU = new ThirdLoginPlatform(6, '飞书', 'feishu', true) 21 | 22 | static readonly GOOGLE = new ThirdLoginPlatform(7, '谷歌', 'google', true) 23 | 24 | static readonly GITHUB = new ThirdLoginPlatform(8, 'GitHub', 'github', true) 25 | 26 | static readonly GITEE = new ThirdLoginPlatform(9, 'Gitee', 'gitee', true) 27 | 28 | static readonly APPLE = new ThirdLoginPlatform(10, '苹果', 'apple', true) 29 | 30 | /** 31 | * ### 标识 32 | */ 33 | flag!: string 34 | 35 | /** 36 | * ### 授权地址 37 | */ 38 | oauthUrl!: string 39 | 40 | /** 41 | * ### 应用标识 42 | */ 43 | appKey!: string 44 | 45 | /** 46 | * ### 宽度 47 | */ 48 | width = 800 49 | 50 | /** 51 | * ### 高度 52 | */ 53 | height = 750 54 | 55 | constructor(key: number, label: string, flag: string, disable = false) { 56 | super(key, label) 57 | this.flag = flag 58 | this.disabled = disable 59 | } 60 | 61 | setWidth(width: number): this { 62 | this.width = width 63 | return this 64 | } 65 | 66 | setHeight(height: number): this { 67 | this.height = height 68 | return this 69 | } 70 | 71 | setAppKey(appKey: string): this { 72 | this.appKey = appKey 73 | return this 74 | } 75 | 76 | setOauthUrl(oauthUrl: string): this { 77 | this.oauthUrl = oauthUrl 78 | return this 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/model/open/thirdlogin/ThirdLoginRequest.ts: -------------------------------------------------------------------------------- 1 | import { AirModel } from '@airpower/base/AirModel' 2 | 3 | /** 4 | * # 第三方登录请求 5 | * @author Hamm.cn 6 | */ 7 | export class ThirdLoginRequest extends AirModel { 8 | code!: string 9 | 10 | platform!: string 11 | } 12 | -------------------------------------------------------------------------------- /src/model/open/thirdlogin/UserThirdLoginEntity.ts: -------------------------------------------------------------------------------- 1 | import { BaseEntity } from '@/base/BaseEntity' 2 | 3 | /** 4 | * # 用户绑定实体 5 | */ 6 | export class UserThirdLoginEntity extends BaseEntity { 7 | /** 8 | * ### 验证码 9 | */ 10 | thirdUserId!: string 11 | 12 | avatar!: string 13 | 14 | nickName!: string 15 | 16 | gender!: number 17 | 18 | platform!: number 19 | } 20 | -------------------------------------------------------------------------------- /src/model/personnel/department/DepartmentEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { ITree } from '@airpower/interface/ITree' 3 | import { BaseEntity } from '@/base/BaseEntity' 4 | 5 | /** 6 | * # 部门 7 | * @author Hamm.cn 8 | */ 9 | @Model({ 10 | label: '菜单', 11 | addChildPermission: 'add', 12 | }) 13 | export class DepartmentEntity extends BaseEntity implements ITree { 14 | @Field({ 15 | label: '部门名称', 16 | }) name!: string 17 | 18 | @Field({ 19 | label: '部门编码', 20 | }) code!: string 21 | 22 | @Field({ 23 | label: '排序编号', 24 | }) orderNo!: number 25 | 26 | @Field({ 27 | label: '父级ID', 28 | type: Number, 29 | }) parentId!: number 30 | 31 | @Field({ 32 | // eslint-disable-next-line no-use-before-define 33 | type: DepartmentEntity, 34 | array: true, 35 | }) children!: this[] 36 | 37 | @Field({ 38 | // eslint-disable-next-line no-use-before-define 39 | type: DepartmentEntity, 40 | }) parent!: this 41 | } 42 | -------------------------------------------------------------------------------- /src/model/personnel/department/DepartmentService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@airpower/airpower-starter/AirPowerWebStarter/src/base/AbstractBaseService' 2 | import { DepartmentEntity } from './DepartmentEntity' 3 | 4 | /** 5 | * # 部门接口服务 6 | * @author Hamm.cn 7 | */ 8 | export class DepartmentService extends AbstractBaseService { 9 | baseUrl = 'department' 10 | 11 | entityClass = DepartmentEntity 12 | } 13 | -------------------------------------------------------------------------------- /src/model/personnel/role/RoleEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { MenuEntity } from '@/model/system/menu/MenuEntity' 4 | import { PermissionEntity } from '@/model/system/permission/PermissionEntity' 5 | 6 | /** 7 | * # 角色 8 | * @author Hamm.cn 9 | */ 10 | 11 | @Model({ 12 | label: '角色', 13 | }) 14 | export class RoleEntity extends BaseEntity { 15 | @Field({ 16 | label: '角色名称', 17 | }) 18 | name!: string 19 | 20 | @Field({ 21 | label: '角色编码', 22 | }) 23 | code!: string 24 | 25 | /** 26 | * ### 菜单列表 27 | */ 28 | @Field({ 29 | type: MenuEntity, 30 | array: true, 31 | }) 32 | menuList!: MenuEntity[] 33 | 34 | /** 35 | * ### 权限列表 36 | */ 37 | @Field({ 38 | type: PermissionEntity, 39 | array: true, 40 | }) permissionList!: PermissionEntity[] 41 | } 42 | -------------------------------------------------------------------------------- /src/model/personnel/role/RoleService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { RoleEntity } from './RoleEntity' 3 | import { MenuEntity } from '@/model/system/menu/MenuEntity' 4 | import { PermissionEntity } from '@/model/system/permission/PermissionEntity' 5 | 6 | /** 7 | * # 角色接口服务 8 | * @author Hamm.cn 9 | */ 10 | export class RoleService extends AbstractBaseService { 11 | baseUrl = 'role' 12 | 13 | entityClass = RoleEntity 14 | 15 | /** 16 | * ### 为角色授权菜单 17 | * @param id 角色ID 18 | * @param menuList 菜单列表 19 | */ 20 | async authorizeMenu(id: number, menuList: MenuEntity[]): Promise { 21 | const role = new RoleEntity(id) 22 | role.menuList = menuList.map((item) => item.copyExposeId()) 23 | await this.api('authorizeMenu') 24 | .post(role) 25 | } 26 | 27 | /** 28 | * ### 为角色授权权限 29 | * @param id 角色ID 30 | * @param permissionList 权限列表 31 | */ 32 | async authorizePermission(id: number, permissionList: PermissionEntity[]): Promise { 33 | const role = new RoleEntity(id) 34 | role.permissionList = permissionList.map((item) => item.copyExposeId()) 35 | await this.api('authorizePermission') 36 | .post(role) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/model/personnel/user/UserEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { RoleEntity } from '../role/RoleEntity' 4 | import { UserGenderEnum } from '@/model/personnel/user/UserGenderEnum' 5 | import { DepartmentEntity } from '@/model/personnel/department/DepartmentEntity' 6 | 7 | /** 8 | * # 用户实体 9 | */ 10 | export class UserEntity extends BaseEntity { 11 | @Field({ 12 | label: '昵称', 13 | }) 14 | nickname!: string 15 | 16 | @Field({ 17 | label: '手机', 18 | }) 19 | phone!: string 20 | 21 | @Field({ 22 | label: '邮箱', 23 | }) 24 | email!: string 25 | 26 | @Field({ 27 | label: '姓名', 28 | }) 29 | realName!: string 30 | 31 | @Field({ 32 | label: '身份证号', 33 | }) 34 | idCard!: string 35 | 36 | @Field({ 37 | label: '头像', 38 | }) 39 | avatar!: string 40 | 41 | @Field({ 42 | label: '密码', 43 | }) 44 | password!: string 45 | 46 | @Field({ 47 | type: RoleEntity, 48 | array: true, 49 | label: '角色', 50 | }) roleList!: RoleEntity[] 51 | 52 | @Field({ 53 | type: RoleEntity, 54 | array: true, 55 | label: '部门', 56 | }) 57 | departmentList!: DepartmentEntity[] 58 | 59 | @Field({ 60 | label: '性别', 61 | dictionary: UserGenderEnum, 62 | }) 63 | gender!: number 64 | 65 | /** 66 | * ### 验证码 67 | */ 68 | code!: string 69 | 70 | @Field({ 71 | label: '个人签名', 72 | }) 73 | bio!: string 74 | } 75 | -------------------------------------------------------------------------------- /src/model/personnel/user/UserGenderEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | 3 | export class UserGenderEnum extends AirEnum { 4 | static MALE = new UserGenderEnum(1, '男') 5 | 6 | static FEMALE = new UserGenderEnum(0, '女') 7 | } 8 | -------------------------------------------------------------------------------- /src/model/personnel/user/UserService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { UserEntity } from '@/model/personnel/user/UserEntity' 3 | import { MenuEntity } from '@/model/system/menu/MenuEntity' 4 | import { OauthScope } from '@/model/open/oauth/OauthScope' 5 | import { OauthCreateCodeRequest } from '@/model/open/oauth/OauthCreateCodeRequest' 6 | import { ThirdLoginRequest } from '@/model/open/thirdlogin/ThirdLoginRequest' 7 | import { UserThirdLoginEntity } from '@/model/open/thirdlogin/UserThirdLoginEntity' 8 | 9 | /** 10 | * # 用户服务接口 11 | */ 12 | export class UserService extends AbstractBaseService { 13 | baseUrl = 'user' 14 | 15 | entityClass = UserEntity 16 | 17 | async logout() { 18 | await this.api('logout') 19 | .post() 20 | } 21 | 22 | /** 23 | * ### App登录 24 | * @param user 用户 25 | */ 26 | async login(user: UserEntity): Promise { 27 | const result = await this.api('login') 28 | .post(user) 29 | return result as unknown as string 30 | } 31 | 32 | /** 33 | * ### 发送验证码 34 | * @param user 用户 35 | */ 36 | async sendEmail(user: UserEntity): Promise { 37 | await this.api('sendEmail') 38 | .post(user) 39 | } 40 | 41 | /** 42 | * ### 邮箱验证码登录 43 | * @param user 用户 44 | */ 45 | async loginViaEmail(user: UserEntity): Promise { 46 | const result = await this.api('loginViaEmail') 47 | .post(user) 48 | return result as unknown as string 49 | } 50 | 51 | /** 52 | * ### 重置密码 53 | * @param user 用户 54 | */ 55 | async resetMyPassword(user: UserEntity): Promise { 56 | await this.api('resetMyPassword') 57 | .post(user) 58 | } 59 | 60 | /** 61 | * ### 修改密码 62 | * @param user 用户 63 | */ 64 | async updateMyPassword(user: UserEntity): Promise { 65 | await this.api('updateMyPassword') 66 | .post(user) 67 | } 68 | 69 | /** 70 | * ### 获取我有权限的菜单列表 71 | */ 72 | async getMyMenuList(): Promise { 73 | return this.api('getMyMenuList') 74 | .requestArray(undefined, MenuEntity) 75 | } 76 | 77 | /** 78 | * ### 获取我的权限列表 79 | */ 80 | async getMyPermissionList(): Promise { 81 | const arr = await this.api('getMyPermissionList') 82 | .post() 83 | return arr as string[] 84 | } 85 | 86 | /** 87 | * ### 获取我的三方账号 88 | */ 89 | async getMyThirdList(): Promise { 90 | return this.api('getMyThirdList') 91 | .requestArray(undefined, UserThirdLoginEntity) 92 | } 93 | 94 | /** 95 | * ### 获取我的个人信息 96 | */ 97 | async getMyInfo(): Promise { 98 | return this.api('getMyInfo') 99 | .request(undefined, UserEntity) 100 | } 101 | 102 | async getScopeList(): Promise { 103 | return this.api('getScopeList', 'oauth2') 104 | .requestArray(undefined, OauthScope) 105 | } 106 | 107 | async authorize(appKey: string, scope: string): Promise { 108 | const postData = new OauthCreateCodeRequest() 109 | postData.appKey = appKey 110 | postData.scope = scope 111 | const code = await this.api('createCode', 'oauth2') 112 | .post(postData) 113 | return code as unknown as string 114 | } 115 | 116 | async callbackCode(platform: string, code: string): Promise { 117 | const postData = new ThirdLoginRequest() 118 | postData.platform = platform 119 | postData.code = code 120 | const result = await this.api('callback', 'oauth2') 121 | .callbackError() 122 | .post(postData) 123 | return result as unknown as string 124 | } 125 | 126 | async thirdBind(platform: string, code: string): Promise { 127 | const postData = new ThirdLoginRequest() 128 | postData.platform = platform 129 | postData.code = code 130 | await this.api('thirdBind', 'oauth2') 131 | .callbackError() 132 | .post(postData) 133 | } 134 | 135 | async unBindThird(data: UserThirdLoginEntity): Promise { 136 | await this.api('unBindThird', 'oauth2') 137 | .callbackError() 138 | .post(data) 139 | } 140 | 141 | async updateMyInfo(user: UserEntity) { 142 | await this.api('updateMyInfo') 143 | .post(user) 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/model/system/coderule/CodeRuleEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { SerialNumberUpdateEnum } from '@/model/system/coderule/SerialNumberUpdateEnum' 4 | 5 | /** 6 | * # 编码规则实体 7 | * 8 | * @author Hamm.cn 9 | */ 10 | @Model({ 11 | permissionPrefix: 'coderule', 12 | label: '编码规则', 13 | }) 14 | export class CodeRuleEntity extends BaseEntity { 15 | @Field({ 16 | label: '编码所属字段', 17 | }) 18 | ruleField!: number 19 | 20 | @Field({ 21 | label: '规则前缀', 22 | }) 23 | prefix!: string 24 | 25 | @Field({ 26 | label: '序列号初始长度', 27 | }) 28 | snLength!: number 29 | 30 | @Field({ 31 | label: '规则模板', 32 | }) 33 | template!: string 34 | 35 | @Field({ 36 | label: '序列号更新', 37 | dictionary: SerialNumberUpdateEnum, 38 | }) 39 | snType!: number 40 | 41 | @Field({ 42 | label: '下一个编码', 43 | }) 44 | nextCode!: string 45 | 46 | @Field({ 47 | type: Number, 48 | }) 49 | currentSn!: number 50 | } 51 | -------------------------------------------------------------------------------- /src/model/system/coderule/CodeRuleField.ts: -------------------------------------------------------------------------------- 1 | import { AirModel } from '@airpower/base/AirModel' 2 | import { Field } from '@airpower/decorator' 3 | 4 | /** 5 | * # 编码规则表格 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class CodeRuleField extends AirModel { 10 | @Field({ 11 | label: '默认前缀', 12 | }) 13 | defaultPrefix!: string 14 | 15 | @Field({ 16 | label: '编码字段名称', 17 | }) 18 | label!: string 19 | 20 | @Field({ 21 | label: '表格ID', 22 | type: Number, 23 | }) 24 | key!: number 25 | } 26 | -------------------------------------------------------------------------------- /src/model/system/coderule/CodeRuleParam.ts: -------------------------------------------------------------------------------- 1 | import { AirModel } from '@airpower/base/AirModel' 2 | import { Field } from '@airpower/decorator' 3 | 4 | /** 5 | * # 编码规则参数 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class CodeRuleParam extends AirModel { 10 | @Field({ 11 | label: '占位符', 12 | }) 13 | label!: string 14 | 15 | @Field({ 16 | label: '参数值', 17 | type: Number, 18 | }) 19 | value!: number 20 | 21 | @Field({ 22 | label: '示例', 23 | }) 24 | demo!: string 25 | 26 | @Field({ 27 | label: '标题', 28 | }) 29 | desc!: string 30 | } 31 | -------------------------------------------------------------------------------- /src/model/system/coderule/CodeRuleService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { CodeRuleEntity } from './CodeRuleEntity' 3 | import { CodeRuleField } from './CodeRuleField' 4 | import { CodeRuleParam } from './CodeRuleParam' 5 | 6 | /** 7 | * # 编码规则服务 8 | * 9 | * @author Hamm.cn 10 | */ 11 | export class CodeRuleService extends AbstractBaseService { 12 | baseUrl = 'coderule' 13 | 14 | entityClass = CodeRuleEntity 15 | 16 | async getFieldList(): Promise { 17 | return this.api('getFieldList') 18 | .requestArray(undefined, CodeRuleField) 19 | } 20 | 21 | async getParamList(): Promise { 22 | return this.api('getParamList') 23 | .requestArray(undefined, CodeRuleParam) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/model/system/coderule/SerialNumberUpdateEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 序列号更新方式字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class SerialNumberUpdateEnum extends AirEnum { 10 | static readonly DAY = new SerialNumberUpdateEnum(1, '每日更新', AirColor.SUCCESS) 11 | 12 | static readonly MONTH = new SerialNumberUpdateEnum(2, '每月更新', AirColor.WARNING) 13 | 14 | static readonly YEAR = new SerialNumberUpdateEnum(3, '每年更新', AirColor.DANGER) 15 | 16 | static readonly NEVER = new SerialNumberUpdateEnum(4, '不更新', AirColor.NORMAL) 17 | } 18 | -------------------------------------------------------------------------------- /src/model/system/config/ConfigEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { ConfigType } from '@/model/system/config/ConfigType' 4 | import { BooleanYesNoDictionary } from '@/model/common/BooleanYesNoDictionary' 5 | 6 | /** 7 | * # 参数配置实体 8 | * 9 | * @author Hamm.cn 10 | */ 11 | @Model({ 12 | label: '配置', 13 | }) 14 | export class ConfigEntity extends BaseEntity { 15 | @Field({ 16 | label: '配置名称', 17 | }) 18 | name!: string 19 | 20 | @Field({ 21 | label: '配置标识', 22 | }) 23 | flag!: string 24 | 25 | @Field({ 26 | label: '配置类型', 27 | dictionary: ConfigType, 28 | }) 29 | type!: number 30 | 31 | @Field({ 32 | label: '系统配置', 33 | type: Boolean, 34 | dictionary: BooleanYesNoDictionary, 35 | }) 36 | isSystem!: boolean 37 | 38 | @Field({ 39 | label: '配置参数', 40 | }) 41 | config!: string 42 | } 43 | -------------------------------------------------------------------------------- /src/model/system/config/ConfigService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { ConfigEntity } from './ConfigEntity' 3 | 4 | /** 5 | * # 系统参数服务 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class ConfigService extends AbstractBaseService { 10 | baseUrl = 'config' 11 | 12 | entityClass = ConfigEntity 13 | } 14 | -------------------------------------------------------------------------------- /src/model/system/config/ConfigType.ts: -------------------------------------------------------------------------------- 1 | import { AirEnum } from '@airpower/base/AirEnum' 2 | import { AirColor } from '@airpower/enum/AirColor' 3 | 4 | export class ConfigType extends AirEnum { 5 | static readonly STRING = new ConfigType(0, '字符串', AirColor.SUCCESS) 6 | 7 | static readonly BOOLEAN = new ConfigType(1, '布尔', AirColor.WARNING) 8 | 9 | static readonly NUMBER = new ConfigType(2, '数字', AirColor.DANGER) 10 | } 11 | -------------------------------------------------------------------------------- /src/model/system/log/LogEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | 4 | @Model({ 5 | label: '日志', 6 | }) 7 | export class LogEntity extends BaseEntity { 8 | @Field({ 9 | label: '动作', 10 | }) 11 | action!: string 12 | 13 | @Field({ 14 | label: '版本号', 15 | }) 16 | version!: number 17 | 18 | @Field({ 19 | label: '平台', 20 | }) 21 | platform!: string 22 | 23 | @Field({ 24 | label: 'IP', 25 | }) 26 | ip!: string 27 | 28 | @Field({ 29 | label: '请求体', 30 | }) 31 | request!: string 32 | 33 | @Field({ 34 | label: '响应数据', 35 | }) 36 | response!: string 37 | 38 | @Field({ 39 | label: '用户ID', 40 | }) 41 | userId!: number 42 | 43 | @Field({ 44 | label: '总耗时', 45 | }) 46 | pendingTime!: number 47 | } 48 | -------------------------------------------------------------------------------- /src/model/system/log/LogService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { LogEntity } from './LogEntity' 3 | 4 | export class LogService extends AbstractBaseService { 5 | entityClass = LogEntity 6 | 7 | baseUrl = 'log' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/system/menu/MenuEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | 4 | /** 5 | * # 菜单 6 | * @author Hamm.cn 7 | */ 8 | @Model({ 9 | label: '菜单', 10 | }) 11 | export class MenuEntity extends BaseEntity { 12 | @Field({ 13 | label: '菜单名称', 14 | }) 15 | name!: string 16 | 17 | @Field({ 18 | label: '菜单路径', 19 | }) 20 | path!: string 21 | 22 | @Field({ 23 | label: '菜单图标', 24 | }) 25 | icon!: string 26 | 27 | @Field({ 28 | label: '组件地址', 29 | }) 30 | component!: string 31 | 32 | @Field({ 33 | label: '排序编号', 34 | type: Number, 35 | }) 36 | orderNo!: number 37 | 38 | /** 39 | * ### 父菜单ID 40 | */ 41 | @Field({ 42 | label: '父级ID', 43 | }) 44 | parentId!: number 45 | 46 | /** 47 | * ### 子菜单列表 48 | */ 49 | @Field({ 50 | // eslint-disable-next-line no-use-before-define 51 | type: MenuEntity, 52 | array: true, 53 | }) 54 | children!: this[] 55 | 56 | /** 57 | * ### 父菜单 58 | */ 59 | @Field({ 60 | // eslint-disable-next-line no-use-before-define 61 | type: MenuEntity, 62 | }) 63 | parent!: this 64 | } 65 | -------------------------------------------------------------------------------- /src/model/system/menu/MenuService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { MenuEntity } from './MenuEntity' 3 | 4 | /** 5 | * # 菜单接口服务 6 | * @author Hamm.cn 7 | */ 8 | export class MenuService extends AbstractBaseService { 9 | baseUrl = 'menu' 10 | 11 | entityClass = MenuEntity 12 | } 13 | -------------------------------------------------------------------------------- /src/model/system/permission/PermissionEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { ITree } from '@airpower/interface/ITree' 3 | import { BaseEntity } from '@/base/BaseEntity' 4 | import { PermissionSystemEnum } from './PermissionSystemEnum' 5 | 6 | /** 7 | * # 权限 8 | * @author Hamm.cn 9 | */ 10 | @Model({ 11 | label: '权限', 12 | }) 13 | export class PermissionEntity extends BaseEntity implements ITree { 14 | @Field({ 15 | label: '权限名称', 16 | }) 17 | name!: string 18 | 19 | @Field({ 20 | label: '权限标识', 21 | }) 22 | identity!: string 23 | 24 | @Field({ 25 | label: '类别', 26 | dictionary: PermissionSystemEnum, 27 | }) 28 | isSystem!: boolean 29 | 30 | @Field({ 31 | label: '父级ID', 32 | }) 33 | parentId!: number 34 | 35 | /** 36 | * ### 子权限列表 37 | */ 38 | @Field({ 39 | // eslint-disable-next-line no-use-before-define 40 | type: PermissionEntity, 41 | array: true, 42 | }) children!: this[] 43 | 44 | /** 45 | * ### 父权限 46 | */ 47 | @Field({ 48 | // eslint-disable-next-line no-use-before-define 49 | type: PermissionEntity, 50 | }) parent!: this 51 | } 52 | -------------------------------------------------------------------------------- /src/model/system/permission/PermissionService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { PermissionEntity } from './PermissionEntity' 3 | 4 | /** 5 | * # 权限接口服务 6 | * @author Hamm.cn 7 | */ 8 | export class PermissionService extends AbstractBaseService { 9 | baseUrl = 'permission' 10 | 11 | entityClass = PermissionEntity 12 | } 13 | -------------------------------------------------------------------------------- /src/model/system/permission/PermissionSystemEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | export class PermissionSystemEnum extends AirEnum { 5 | static NORMAL = new PermissionSystemEnum(false, '普通权限', AirColor.NORMAL) 6 | 7 | static SYSTEM = new PermissionSystemEnum(true, '系统权限', AirColor.DANGER) 8 | } 9 | -------------------------------------------------------------------------------- /src/model/system/unit/UnitEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { IPayload } from '@airpower/interface/IPayload' 3 | import { BaseEntity } from '@/base/BaseEntity' 4 | 5 | @Model({ 6 | label: '计量单位', 7 | }) 8 | export class UnitEntity extends BaseEntity implements IPayload { 9 | @Field({ 10 | label: '单位名称', 11 | }) 12 | name!: string 13 | 14 | @Field({ 15 | label: '单位编码', 16 | }) 17 | code!: string 18 | 19 | getPayloadLabel(): string { 20 | return `${this.name}(${this.code})` 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/model/system/unit/UnitService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { UnitEntity } from './UnitEntity' 3 | 4 | export class UnitService extends AbstractBaseService { 5 | entityClass = UnitEntity 6 | 7 | baseUrl = 'unit' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/wms/input/InputDetailEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 3 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 4 | import { StorageEntity } from '@/model/factory/storage/StorageEntity' 5 | 6 | @Model({ 7 | label: '入库明细', 8 | }) 9 | export class InputDetailEntity extends AbstractBaseBillDetailEntity { 10 | @Field({ 11 | type: StorageEntity, 12 | }) 13 | storage!: StorageEntity 14 | 15 | @Field({ 16 | type: MaterialEntity, 17 | }) 18 | material!: MaterialEntity 19 | 20 | @Field({ 21 | label: '入库数量', 22 | type: Number, 23 | }) 24 | quantity!: number 25 | 26 | @Field({ 27 | label: '已入库数量', 28 | type: Number, 29 | }) 30 | finishQuantity!: number 31 | } 32 | -------------------------------------------------------------------------------- /src/model/wms/input/InputDetailService.ts: -------------------------------------------------------------------------------- 1 | import { InputDetailEntity } from './InputDetailEntity' 2 | import { AbstractBaseBillDetailService } from '@/base/bill/AbstractBaseBillDetailService' 3 | 4 | export class InputDetailService extends AbstractBaseBillDetailService { 5 | entityClass = InputDetailEntity 6 | 7 | baseUrl = 'inputDetail' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/wms/input/InputEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 4 | import { InputDetailEntity } from './InputDetailEntity' 5 | import { InputStatusEnum } from './InputStatusEnum' 6 | import { InputTypeEnum } from './InputTypeEnum' 7 | import { PurchaseEntity } from '@/model/channel/purchase/PurchaseEntity' 8 | import { MoveEntity } from '../move/MoveEntity' 9 | import { OrderEntity } from '@/model/mes/order/OrderEntity' 10 | 11 | @Model({ 12 | label: '入库单', 13 | }) 14 | export class InputEntity extends AbstractBaseBillEntity { 15 | @Field({ 16 | label: '入库单号', 17 | }) 18 | declare billCode: string 19 | 20 | @Field({ 21 | label: '入库类型', 22 | dictionary: InputTypeEnum, 23 | }) 24 | type!: number 25 | 26 | @Field({ 27 | label: '入库状态', 28 | dictionary: InputStatusEnum, 29 | }) 30 | status!: number 31 | 32 | @Field({ 33 | label: '入库明细', 34 | type: InputDetailEntity, 35 | array: true, 36 | }) 37 | details: InputDetailEntity[] = [] 38 | 39 | @Field({ 40 | label: '采购单', 41 | type: PurchaseEntity, 42 | }) 43 | purchase!: PurchaseEntity 44 | 45 | @Field({ 46 | label: '移库单', 47 | type: MoveEntity, 48 | }) 49 | move!: MoveEntity 50 | 51 | @Field({ 52 | label: '生产订单', 53 | type: OrderEntity, 54 | }) 55 | order!: OrderEntity 56 | 57 | getAuditingStatus(): AirEnum { 58 | return InputStatusEnum.AUDITING 59 | } 60 | 61 | getAuditedStatus(): AirEnum { 62 | return InputStatusEnum.INPUTTING 63 | } 64 | 65 | getRejectedStatus(): AirEnum { 66 | return InputStatusEnum.REJECTED 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/model/wms/input/InputService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 2 | import { InputEntity } from './InputEntity' 3 | import { InputDetailEntity } from './InputDetailEntity' 4 | 5 | export class InputService extends AbstractBaseBillService { 6 | entityClass = InputEntity 7 | 8 | baseUrl = 'input' 9 | } 10 | -------------------------------------------------------------------------------- /src/model/wms/input/InputStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 入库状态枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class InputStatusEnum extends AirEnum { 10 | static AUDITING = new InputStatusEnum(1, '审核中', AirColor.WARNING) 11 | 12 | static REJECTED = new InputStatusEnum(2, '已驳回', AirColor.DANGER) 13 | 14 | static INPUTTING = new InputStatusEnum(3, '入库中', AirColor.NORMAL) 15 | 16 | static DONE = new InputStatusEnum(4, '已完成', AirColor.SUCCESS) 17 | } 18 | -------------------------------------------------------------------------------- /src/model/wms/input/InputTypeEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 入库类型枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class InputTypeEnum extends AirEnum { 10 | static readonly NORMAL = new InputTypeEnum(1, '普通入库', AirColor.NORMAL) 11 | 12 | static readonly MOVE = new InputTypeEnum(2, '移动入库', AirColor.NORMAL) 13 | 14 | static readonly PURCHASE = new InputTypeEnum(3, '采购入库', AirColor.WARNING) 15 | 16 | static readonly PRODUCTION = new InputTypeEnum(4, '生产入库', AirColor.SUCCESS) 17 | } 18 | -------------------------------------------------------------------------------- /src/model/wms/inventory/InventoryEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { BaseEntity } from '@/base/BaseEntity' 3 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 4 | import { StorageEntity } from '@/model/factory/storage/StorageEntity' 5 | import { StructureEntity } from '@/model/factory/structure/StructureEntity' 6 | import { InventoryTypeEnum } from '@/model/wms/inventory/InventoryTypeEnum' 7 | 8 | @Model({ 9 | label: '库存', 10 | }) 11 | export class InventoryEntity extends BaseEntity { 12 | @Field({ 13 | label: '库存数量', 14 | }) 15 | quantity!: number 16 | 17 | @Field({ 18 | label: '仓库', 19 | type: StorageEntity, 20 | }) 21 | storage!: StorageEntity 22 | 23 | @Field({ 24 | label: '库存类型', 25 | dictionary: InventoryTypeEnum, 26 | }) 27 | type!: number 28 | 29 | @Field({ 30 | label: '物料信息', 31 | type: MaterialEntity, 32 | }) 33 | material!: MaterialEntity 34 | 35 | @Field({ 36 | label: '生产单元', 37 | type: StructureEntity, 38 | }) 39 | structure!: StructureEntity 40 | } 41 | -------------------------------------------------------------------------------- /src/model/wms/inventory/InventoryService.ts: -------------------------------------------------------------------------------- 1 | import { InventoryEntity } from './InventoryEntity' 2 | import { AbstractBaseService } from '@/base/AbstractBaseService' 3 | 4 | export class InventoryService extends AbstractBaseService { 5 | entityClass = InventoryEntity 6 | 7 | baseUrl = 'inventory' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/wms/inventory/InventoryTypeEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | export class InventoryTypeEnum extends AirEnum { 5 | static readonly STORAGE = new InventoryTypeEnum(1, '按仓库', AirColor.NORMAL) 6 | 7 | static readonly STRUCTURE = new InventoryTypeEnum(2, '按生产单元', AirColor.SUCCESS) 8 | } 9 | -------------------------------------------------------------------------------- /src/model/wms/move/MoveDetailEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 3 | import { InventoryEntity } from '../inventory/InventoryEntity' 4 | 5 | @Model({ 6 | label: '移库明细', 7 | }) 8 | export class MoveDetailEntity extends AbstractBaseBillDetailEntity { 9 | @Field({ 10 | type: InventoryEntity, 11 | }) 12 | inventory!: InventoryEntity 13 | 14 | @Field({ 15 | label: '移动数量', 16 | }) 17 | quantity!: number 18 | 19 | @Field({ 20 | label: '已移动数量', 21 | }) 22 | finishQuantity!: number 23 | } 24 | -------------------------------------------------------------------------------- /src/model/wms/move/MoveDetailService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseService } from '@/base/AbstractBaseService' 2 | import { MoveDetailEntity } from './MoveDetailEntity' 3 | 4 | export class MoveDetailService extends AbstractBaseService { 5 | entityClass = MoveDetailEntity 6 | 7 | baseUrl = 'moveDetail' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/wms/move/MoveEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 4 | import { StorageEntity } from '@/model/factory/storage/StorageEntity' 5 | import { MoveDetailEntity } from './MoveDetailEntity' 6 | import { MoveStatusEnum } from './MoveStatusEnum' 7 | 8 | @Model({ 9 | label: '移库单', 10 | }) 11 | export class MoveEntity extends AbstractBaseBillEntity { 12 | @Field({ 13 | label: '移库单号', 14 | }) 15 | declare billCode: string 16 | 17 | @Field({ 18 | label: '目标仓库', 19 | type: StorageEntity, 20 | }) 21 | storage!: StorageEntity 22 | 23 | @Field({ 24 | label: '移库状态', 25 | dictionary: MoveStatusEnum, 26 | }) 27 | status!: number 28 | 29 | @Field({ 30 | label: '移库明细', 31 | type: MoveDetailEntity, 32 | array: true, 33 | }) 34 | details: MoveDetailEntity[] = [] 35 | 36 | getAuditingStatus(): AirEnum { 37 | return MoveStatusEnum.AUDITING 38 | } 39 | 40 | getAuditedStatus(): AirEnum { 41 | return MoveStatusEnum.MOVING 42 | } 43 | 44 | getRejectedStatus(): AirEnum { 45 | return MoveStatusEnum.REJECTED 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/model/wms/move/MoveService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 2 | import { MoveEntity } from './MoveEntity' 3 | import { MoveDetailEntity } from './MoveDetailEntity' 4 | 5 | export class MoveService extends AbstractBaseBillService { 6 | entityClass = MoveEntity 7 | 8 | baseUrl = 'move' 9 | } 10 | -------------------------------------------------------------------------------- /src/model/wms/move/MoveStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 移库状态枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class MoveStatusEnum extends AirEnum { 10 | static readonly AUDITING = new MoveStatusEnum(1, '审核中', AirColor.WARNING) 11 | 12 | static readonly REJECTED = new MoveStatusEnum(2, '已驳回', AirColor.DANGER) 13 | 14 | static readonly MOVING = new MoveStatusEnum(3, '移动中', AirColor.NORMAL) 15 | 16 | static readonly DONE = new MoveStatusEnum(4, '已完成', AirColor.SUCCESS) 17 | } 18 | -------------------------------------------------------------------------------- /src/model/wms/output/OutputDetailEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AbstractBaseBillDetailEntity } from '@/base/bill/detail/AbstractBaseBillDetailEntity' 3 | import { InventoryEntity } from '../inventory/InventoryEntity' 4 | import { MaterialEntity } from '@/model/asset/material/MaterialEntity' 5 | 6 | @Model({ 7 | label: '出库明细', 8 | }) 9 | export class OutputDetailEntity extends AbstractBaseBillDetailEntity { 10 | @Field({ 11 | type: InventoryEntity, 12 | }) 13 | inventory!: InventoryEntity 14 | 15 | @Field({ 16 | type: MaterialEntity, 17 | }) 18 | material!: MaterialEntity 19 | 20 | @Field({ 21 | label: '出库数量', 22 | }) 23 | quantity!: number 24 | 25 | @Field({ 26 | label: '已出库数量', 27 | }) 28 | finishQuantity!: number 29 | } 30 | -------------------------------------------------------------------------------- /src/model/wms/output/OutputDetailService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseBillDetailService } from '@/base/bill/AbstractBaseBillDetailService' 2 | import { OutputDetailEntity } from './OutputDetailEntity' 3 | 4 | export class OutputDetailService extends AbstractBaseBillDetailService { 5 | entityClass = OutputDetailEntity 6 | 7 | baseUrl = 'outputDetail' 8 | } 9 | -------------------------------------------------------------------------------- /src/model/wms/output/OutputEntity.ts: -------------------------------------------------------------------------------- 1 | import { Field, Model } from '@airpower/decorator' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | import { AbstractBaseBillEntity } from '@/base/bill/AbstractBaseBillEntity' 4 | import { SaleEntity } from '@/model/channel/sale/SaleEntity' 5 | import { OutputDetailEntity } from './OutputDetailEntity' 6 | import { OutputTypeEnum } from './OutputTypeEnum' 7 | import { OutputStatusEnum } from './OutputStatusEnum' 8 | import { MoveEntity } from '../move/MoveEntity' 9 | import { PickingEntity } from '@/model/mes/picking/PickingEntity' 10 | 11 | @Model({ 12 | label: '出库单', 13 | }) 14 | export class OutputEntity extends AbstractBaseBillEntity { 15 | @Field({ 16 | label: '出库单号', 17 | }) 18 | declare billCode: string 19 | 20 | @Field({ 21 | label: '出库类型', 22 | dictionary: OutputTypeEnum, 23 | }) 24 | type!: number 25 | 26 | @Field({ 27 | label: '出库状态', 28 | dictionary: OutputStatusEnum, 29 | }) 30 | status!: number 31 | 32 | @Field({ 33 | label: '出库明细', 34 | type: OutputDetailEntity, 35 | array: true, 36 | }) 37 | details: OutputDetailEntity[] = [] 38 | 39 | @Field({ 40 | label: '采购单', 41 | type: SaleEntity, 42 | }) 43 | sale!: SaleEntity 44 | 45 | @Field({ 46 | label: '移库单', 47 | type: MoveEntity, 48 | }) 49 | move!: MoveEntity 50 | 51 | @Field({ 52 | label: '领料单', 53 | type: PickingEntity, 54 | }) 55 | picking!: PickingEntity 56 | 57 | getAuditingStatus(): AirEnum { 58 | return OutputStatusEnum.AUDITING 59 | } 60 | 61 | getAuditedStatus(): AirEnum { 62 | return OutputStatusEnum.OUTPUTTING 63 | } 64 | 65 | getRejectedStatus(): AirEnum { 66 | return OutputStatusEnum.REJECTED 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/model/wms/output/OutputService.ts: -------------------------------------------------------------------------------- 1 | import { AbstractBaseBillService } from '@/base/bill/AbstractBaseBillService' 2 | import { OutputEntity } from './OutputEntity' 3 | import { OutputDetailEntity } from './OutputDetailEntity' 4 | 5 | export class OutputService extends AbstractBaseBillService { 6 | entityClass = OutputEntity 7 | 8 | baseUrl = 'output' 9 | } 10 | -------------------------------------------------------------------------------- /src/model/wms/output/OutputStatusEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 出库状态枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class OutputStatusEnum extends AirEnum { 10 | static readonly AUDITING = new OutputStatusEnum(1, '审核中', AirColor.WARNING) 11 | 12 | static readonly REJECTED = new OutputStatusEnum(2, '已驳回', AirColor.DANGER) 13 | 14 | static readonly OUTPUTTING = new OutputStatusEnum(3, '出库中', AirColor.NORMAL) 15 | 16 | static readonly DONE = new OutputStatusEnum(4, '已完成', AirColor.SUCCESS) 17 | } 18 | -------------------------------------------------------------------------------- /src/model/wms/output/OutputTypeEnum.ts: -------------------------------------------------------------------------------- 1 | import { AirColor } from '@airpower/enum/AirColor' 2 | import { AirEnum } from '@airpower/base/AirEnum' 3 | 4 | /** 5 | * # 出库类型枚举字典 6 | * 7 | * @author Hamm.cn 8 | */ 9 | export class OutputTypeEnum extends AirEnum { 10 | static readonly NORMAL = new OutputTypeEnum(1, '普通出库', AirColor.WARNING) 11 | 12 | static readonly MOVE = new OutputTypeEnum(2, '移动出库', AirColor.NORMAL) 13 | 14 | static readonly SALE = new OutputTypeEnum(3, '销售出库', AirColor.SUCCESS) 15 | 16 | static readonly PICKING = new OutputTypeEnum(4, '领料出库', AirColor.NORMAL) 17 | } 18 | -------------------------------------------------------------------------------- /src/pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | { 4 | "path": "view/home", 5 | "style": { 6 | "navigationBarTitleText": "首页" 7 | } 8 | }, 9 | { 10 | "path": "view/station", 11 | "style": { 12 | "navigationBarTitleText": "生产" 13 | } 14 | }, 15 | { 16 | "path": "view/message", 17 | "style": { 18 | "navigationBarTitleText": "消息" 19 | } 20 | }, 21 | { 22 | "path": "view/setting", 23 | "style": { 24 | "navigationBarTitleText": "设置", 25 | "enablePullDownRefresh": false 26 | } 27 | }, 28 | { 29 | "path": "view/login", 30 | "style": { 31 | "navigationBarTitleText": "", 32 | "navigationStyle": "custom", 33 | "navigationBarTextStyle": "black", 34 | "enablePullDownRefresh": false 35 | } 36 | }, 37 | { 38 | "path": "component/form/NumberInput", 39 | "style": { 40 | "enablePullDownRefresh": false, 41 | "navigationStyle": "custom", 42 | "backgroundColor": "transparent", 43 | "backgroundColorTop": "transparent", 44 | "backgroundColorBottom": "transparent", 45 | "app-plus": { 46 | "background": "transparent", 47 | "backgroundColor": "rgba(0,0,0,0)", 48 | "popGesture": "none" 49 | } 50 | } 51 | }, 52 | { 53 | "path": "view/asset/material/list", 54 | "style": { 55 | "navigationBarTitleText": "物料列表" 56 | } 57 | }, 58 | { 59 | "path": "view/asset/device/list", 60 | "style": { 61 | "navigationBarTitleText": "设备管理" 62 | } 63 | }, 64 | { 65 | "path": "view/channel/supplier/list", 66 | "style": { 67 | "navigationBarTitleText": "供应商列表" 68 | } 69 | }, 70 | { 71 | "path": "view/channel/customer/list", 72 | "style": { 73 | "navigationBarTitleText": "客户列表" 74 | } 75 | }, 76 | { 77 | "path": "view/channel/purchase/list", 78 | "style": { 79 | "navigationBarTitleText": "采购管理" 80 | } 81 | }, 82 | { 83 | "path": "view/channel/purchase/detail", 84 | "style": { 85 | "navigationBarTitleText": "采购详情" 86 | } 87 | }, 88 | { 89 | "path": "view/channel/purchase/test", 90 | "style": { 91 | "navigationBarTitleText": "测试" 92 | } 93 | }, 94 | { 95 | "path": "view/channel/sale/list", 96 | "style": { 97 | "navigationBarTitleText": "销售管理" 98 | } 99 | }, 100 | { 101 | "path": "view/wms/input/list", 102 | "style": { 103 | "navigationBarTitleText": "入库管理" 104 | } 105 | }, 106 | { 107 | "path": "view/wms/input/detail", 108 | "style": { 109 | "navigationBarTitleText": "入库详情" 110 | } 111 | }, 112 | { 113 | "path": "view/wms/output/list", 114 | "style": { 115 | "navigationBarTitleText": "出库管理" 116 | } 117 | }, 118 | { 119 | "path": "view/wms/move/list", 120 | "style": { 121 | "navigationBarTitleText": "移库管理" 122 | } 123 | }, 124 | { 125 | "path": "view/mes/bom/list", 126 | "style": { 127 | "navigationBarTitleText": "配方管理" 128 | } 129 | }, 130 | { 131 | "path": "view/mes/operation/list", 132 | "style": { 133 | "navigationBarTitleText": "工序管理" 134 | } 135 | }, 136 | { 137 | "path": "view/mes/order/list", 138 | "style": { 139 | "navigationBarTitleText": "订单管理" 140 | } 141 | }, 142 | { 143 | "path": "view/mes/picking/list", 144 | "style": { 145 | "navigationBarTitleText": "物料领取" 146 | } 147 | }, 148 | { 149 | "path": "view/mes/plan/list", 150 | "style": { 151 | "navigationBarTitleText": "生产计划" 152 | } 153 | }, 154 | { 155 | "path": "view/mes/routing/list", 156 | "style": { 157 | "navigationBarTitleText": "生产工艺" 158 | } 159 | } 160 | ], 161 | "tabBar": { 162 | "blurEffect": "light", 163 | "borderStyle": "#eee", 164 | "selectedColor": "#60AC72", 165 | "height": "55", 166 | "fontSize": "12", 167 | "spacing": "5", 168 | "list": [ 169 | { 170 | "iconPath": "static/img/tabbar/tabbar-home.png", 171 | "selectedIconPath": "static/img/tabbar/tabbar-home-active.png", 172 | "pagePath": "view/home", 173 | "text": "首页" 174 | }, 175 | { 176 | "iconPath": "static/img/tabbar/tabbar-more.png", 177 | "selectedIconPath": "static/img/tabbar/tabbar-more-active.png", 178 | "pagePath": "view/station", 179 | "text": "生产" 180 | }, 181 | { 182 | "iconPath": "static/img/tabbar/tabbar-message.png", 183 | "selectedIconPath": "static/img/tabbar/tabbar-message-active.png", 184 | "pagePath": "view/message", 185 | "text": "消息" 186 | }, 187 | { 188 | "iconPath": "static/img/tabbar/tabbar-mine.png", 189 | "selectedIconPath": "static/img/tabbar/tabbar-mine-active.png", 190 | "pagePath": "view/setting", 191 | "text": "设置" 192 | } 193 | ] 194 | }, 195 | "globalStyle": { 196 | "navigationBarTextStyle": "white", 197 | "navigationBarTitleText": "SPMS", 198 | "navigationBarBackgroundColor": "#60AC72", 199 | "backgroundColor": "#f5f5f5", 200 | "backgroundColorTop": "#f5f5f5", 201 | "backgroundColorBottom": "#f5f5f5", 202 | "enablePullDownRefresh": true, 203 | "app-plus": { 204 | "scrollIndicator": "none", 205 | "softinputNavBar": "none", 206 | "safearea": { 207 | "background": "rgba(255,255,255,0.9)", 208 | "bottom": { 209 | "offset": "none" 210 | } 211 | } 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /src/shime-uni.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-undef */ 2 | /* eslint-disable @typescript-eslint/no-empty-interface */ 3 | export { } 4 | 5 | declare module 'vue' { 6 | type Hooks = App.AppInstance & Page.PageInstance; 7 | interface ComponentCustomOptions extends Hooks { } 8 | } 9 | -------------------------------------------------------------------------------- /src/static/css/main.scss: -------------------------------------------------------------------------------- 1 | body { 2 | --primary-color: #60ac72; 3 | --primary-color-bg: #60ac7210; 4 | --danger-color: #f56c6c; 5 | --danger-color-bg: #f56c6c10; 6 | } 7 | 8 | uni-button { 9 | box-sizing: border-box !important; 10 | background-color: var(--primary-color) !important; 11 | color: white !important; 12 | transition: all .3s; 13 | } 14 | 15 | uni-button:after { 16 | border: none !important; 17 | } 18 | 19 | uni-button[type="button"] { 20 | background-color: var(--primary-color-bg) !important; 21 | color: var(--primary-color) !important; 22 | } 23 | 24 | uni-button[type="reset"] { 25 | background-color: var(--danger-color) !important; 26 | } 27 | 28 | uni-button[disabled] { 29 | opacity: 0.6; 30 | } 31 | -------------------------------------------------------------------------------- /src/static/img/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/src/static/img/add.png -------------------------------------------------------------------------------- /src/static/img/tabbar/tabbar-home-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/src/static/img/tabbar/tabbar-home-active.png -------------------------------------------------------------------------------- /src/static/img/tabbar/tabbar-home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/src/static/img/tabbar/tabbar-home.png -------------------------------------------------------------------------------- /src/static/img/tabbar/tabbar-message-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/src/static/img/tabbar/tabbar-message-active.png -------------------------------------------------------------------------------- /src/static/img/tabbar/tabbar-message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/src/static/img/tabbar/tabbar-message.png -------------------------------------------------------------------------------- /src/static/img/tabbar/tabbar-mine-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/src/static/img/tabbar/tabbar-mine-active.png -------------------------------------------------------------------------------- /src/static/img/tabbar/tabbar-mine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/src/static/img/tabbar/tabbar-mine.png -------------------------------------------------------------------------------- /src/static/img/tabbar/tabbar-more-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/src/static/img/tabbar/tabbar-more-active.png -------------------------------------------------------------------------------- /src/static/img/tabbar/tabbar-more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/src/static/img/tabbar/tabbar-more.png -------------------------------------------------------------------------------- /src/uni.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * 这里是uni-app内置的常用样式变量 3 | * 4 | * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量 5 | * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App 6 | * 7 | */ 8 | 9 | /** 10 | * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能 11 | * 12 | * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件 13 | */ 14 | 15 | /* 颜色变量 */ 16 | 17 | /* 行为相关颜色 */ 18 | $uni-color-primary: #2a5c90; 19 | $uni-color-success: #4cd964; 20 | $uni-color-warning: #f0ad4e; 21 | $uni-color-error: #dd524d; 22 | 23 | /* 文字基本颜色 */ 24 | $uni-text-color: #333; // 基本色 25 | $uni-text-color-inverse: #fff; // 反色 26 | $uni-text-color-grey: #999; // 辅助灰色,如加载更多的提示信息 27 | $uni-text-color-placeholder: #808080; 28 | $uni-text-color-disable: #c0c0c0; 29 | 30 | /* 背景颜色 */ 31 | $uni-bg-color: #fff; 32 | $uni-bg-color-grey: #f5f5f5; 33 | $uni-bg-color-hover: #f1f1f1; // 点击状态颜色 34 | $uni-bg-color-mask: rgba(0, 0, 0, 0.4); // 遮罩颜色 35 | 36 | /* 边框颜色 */ 37 | $uni-border-color: #c8c7cc; 38 | 39 | /* 尺寸变量 */ 40 | 41 | /* 文字尺寸 */ 42 | $uni-font-size-sm: 12px; 43 | $uni-font-size-base: 14px; 44 | $uni-font-size-lg: 16; 45 | 46 | /* 图片尺寸 */ 47 | $uni-img-size-sm: 20px; 48 | $uni-img-size-base: 26px; 49 | $uni-img-size-lg: 40px; 50 | 51 | /* Border Radius */ 52 | $uni-border-radius-sm: 2px; 53 | $uni-border-radius-base: 3px; 54 | $uni-border-radius-lg: 6px; 55 | $uni-border-radius-circle: 50%; 56 | 57 | /* 水平间距 */ 58 | $uni-spacing-row-sm: 5px; 59 | $uni-spacing-row-base: 10px; 60 | $uni-spacing-row-lg: 15px; 61 | 62 | /* 垂直间距 */ 63 | $uni-spacing-col-sm: 4px; 64 | $uni-spacing-col-base: 8px; 65 | $uni-spacing-col-lg: 12px; 66 | 67 | /* 透明度 */ 68 | $uni-opacity-disabled: 0.3; // 组件禁用态的透明度 69 | 70 | /* 文章场景相关 */ 71 | $uni-color-title: #2c405a; // 文章标题颜色 72 | $uni-font-size-title: 20px; 73 | $uni-color-subtitle: #555; // 二级标题颜色 74 | $uni-font-size-subtitle: 18px; 75 | $uni-color-paragraph: #3f536e; // 文章段落颜色 76 | $uni-font-size-paragraph: 15px; 77 | -------------------------------------------------------------------------------- /src/view/asset/device/list.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/view/asset/material/list.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/view/channel/customer/list.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/view/channel/purchase/detail.vue: -------------------------------------------------------------------------------- 1 | 54 | 55 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /src/view/channel/purchase/list.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/view/channel/purchase/test.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/view/channel/sale/list.vue: -------------------------------------------------------------------------------- 1 | 31 | 32 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/view/channel/supplier/list.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/view/home.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 66 | 67 | 122 | -------------------------------------------------------------------------------- /src/view/login.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 72 | 73 | 125 | -------------------------------------------------------------------------------- /src/view/mes/bom/list.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/view/mes/operation/list.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/view/mes/order/list.vue: -------------------------------------------------------------------------------- 1 | 51 | 52 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/view/mes/picking/list.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/view/mes/plan/list.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/view/mes/routing/list.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/view/message.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /src/view/setting.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /src/view/station.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /src/view/wms/input/detail.vue: -------------------------------------------------------------------------------- 1 | 138 | 139 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /src/view/wms/input/list.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/view/wms/move/list.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/view/wms/output/list.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.json", 3 | "compilerOptions": { 4 | "ignoreDeprecations": "5.0", 5 | "preserveValueImports": false, 6 | "experimentalDecorators": true, 7 | "emitDecoratorMetadata": true, 8 | "verbatimModuleSyntax": false, 9 | "moduleResolution": "Node", 10 | "esModuleInterop": true, 11 | "sourceMap": true, 12 | "baseUrl": ".", 13 | "paths": { 14 | "@airpower/*": [ 15 | "airpower/*" 16 | ], 17 | "@/*": [ 18 | "src/*" 19 | ] 20 | }, 21 | "lib": [ 22 | "esnext", 23 | "dom" 24 | ], 25 | "types": [ 26 | "@dcloudio/types" 27 | ] 28 | }, 29 | "include": [ 30 | "airpower/**/*.ts", 31 | "airpower/**/*.d.ts", 32 | "airpower/**/*.tsx", 33 | "airpower/**/*.vue", 34 | "src/**/*.ts", 35 | "src/**/*.d.ts", 36 | "src/**/*.tsx", 37 | "src/**/*.vue" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /unpackage/res/icons/1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/1024x1024.png -------------------------------------------------------------------------------- /unpackage/res/icons/120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/120x120.png -------------------------------------------------------------------------------- /unpackage/res/icons/144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/144x144.png -------------------------------------------------------------------------------- /unpackage/res/icons/152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/152x152.png -------------------------------------------------------------------------------- /unpackage/res/icons/167x167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/167x167.png -------------------------------------------------------------------------------- /unpackage/res/icons/180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/180x180.png -------------------------------------------------------------------------------- /unpackage/res/icons/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/192x192.png -------------------------------------------------------------------------------- /unpackage/res/icons/20x20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/20x20.png -------------------------------------------------------------------------------- /unpackage/res/icons/29x29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/29x29.png -------------------------------------------------------------------------------- /unpackage/res/icons/40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/40x40.png -------------------------------------------------------------------------------- /unpackage/res/icons/58x58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/58x58.png -------------------------------------------------------------------------------- /unpackage/res/icons/60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/60x60.png -------------------------------------------------------------------------------- /unpackage/res/icons/72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/72x72.png -------------------------------------------------------------------------------- /unpackage/res/icons/76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/76x76.png -------------------------------------------------------------------------------- /unpackage/res/icons/80x80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/80x80.png -------------------------------------------------------------------------------- /unpackage/res/icons/87x87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/87x87.png -------------------------------------------------------------------------------- /unpackage/res/icons/96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s-pms/SPMS-App/8fd725ba719284a1b581c5c28e720bf7321d6a8d/unpackage/res/icons/96x96.png -------------------------------------------------------------------------------- /update.sh: -------------------------------------------------------------------------------- 1 | git pull && cd src/airpower && git checkout uniapp && git pull && cd ../../ -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import uni from '@dcloudio/vite-plugin-uni' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [uni()], 7 | resolve: { 8 | alias: { 9 | '@airpower': '/airpower/', 10 | '@': '/src/', 11 | }, 12 | }, 13 | build: { 14 | minify: 'terser', 15 | terserOptions: { 16 | keep_classnames: true, 17 | keep_fnames: true, 18 | }, 19 | }, 20 | server: { 21 | open: true, 22 | host: '0.0.0.0', 23 | https: false, 24 | proxy: { 25 | '/api': { 26 | target: 'http://localhost:8080/', 27 | rewrite: (path) => path.replace(/^\/api/, ''), 28 | changeOrigin: true, 29 | }, 30 | '/oauth2': 'http://127.0.0.1:8080', 31 | }, 32 | }, 33 | }) 34 | --------------------------------------------------------------------------------